mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 17:52:45 +00:00 
			
		
		
		
	WindowServer: Make message receivers be weak pointers.
This commit is contained in:
		
							parent
							
								
									95cfa49f1b
								
							
						
					
					
						commit
						d77f8ba413
					
				
					 5 changed files with 28 additions and 27 deletions
				
			
		|  | @ -369,7 +369,7 @@ void WSClientConnection::handle_request(WSAPIDidFinishPaintingNotification& requ | ||||||
|     if (!window.has_painted_since_last_resize()) { |     if (!window.has_painted_since_last_resize()) { | ||||||
|         if (window.last_lazy_resize_rect().size() == request.rect().size()) { |         if (window.last_lazy_resize_rect().size() == request.rect().size()) { | ||||||
|             window.set_has_painted_since_last_resize(true); |             window.set_has_painted_since_last_resize(true); | ||||||
|             WSMessageLoop::the().post_message(&window, make<WSResizeEvent>(window.last_lazy_resize_rect(), window.rect())); |             WSMessageLoop::the().post_message(window, make<WSResizeEvent>(window.last_lazy_resize_rect(), window.rect())); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     WSWindowManager::the().invalidate(window, request.rect()); |     WSWindowManager::the().invalidate(window, request.rect()); | ||||||
|  |  | ||||||
|  | @ -60,28 +60,23 @@ int WSMessageLoop::exec() | ||||||
|         Vector<QueuedMessage> messages = move(m_queued_messages); |         Vector<QueuedMessage> messages = move(m_queued_messages); | ||||||
| 
 | 
 | ||||||
|         for (auto& queued_message : messages) { |         for (auto& queued_message : messages) { | ||||||
|             auto* receiver = queued_message.receiver; |             auto* receiver = queued_message.receiver.ptr(); | ||||||
|             auto& message = *queued_message.message; |             auto& message = *queued_message.message; | ||||||
| #ifdef WSEVENTLOOP_DEBUG | #ifdef WSEVENTLOOP_DEBUG | ||||||
|             dbgprintf("WSMessageLoop: receiver{%p} message %u\n", receiver, (unsigned)message.type()); |             dbgprintf("WSMessageLoop: receiver{%p} message %u\n", receiver, (unsigned)message.type()); | ||||||
| #endif | #endif | ||||||
|             if (!receiver) { |             if (receiver) | ||||||
|                 dbgprintf("WSMessage type %u with no receiver :(\n", message.type()); |  | ||||||
|                 ASSERT_NOT_REACHED(); |  | ||||||
|                 return 1; |  | ||||||
|             } else { |  | ||||||
|                 receiver->on_message(message); |                 receiver->on_message(message); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void WSMessageLoop::post_message(WSMessageReceiver* receiver, OwnPtr<WSMessage>&& message) | void WSMessageLoop::post_message(WSMessageReceiver& receiver, OwnPtr<WSMessage>&& message) | ||||||
| { | { | ||||||
| #ifdef WSEVENTLOOP_DEBUG | #ifdef WSEVENTLOOP_DEBUG | ||||||
|     dbgprintf("WSMessageLoop::post_message: {%u} << receiver=%p, message=%p (type=%u)\n", m_queued_messages.size(), receiver, message.ptr(), message->type()); |     dbgprintf("WSMessageLoop::post_message: {%u} << receiver=%p, message=%p (type=%u)\n", m_queued_messages.size(), receiver, message.ptr(), message->type()); | ||||||
| #endif | #endif | ||||||
|     m_queued_messages.append({ receiver, move(message) }); |     m_queued_messages.append({ receiver.make_weak_ptr(), move(message) }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void WSMessageLoop::Timer::reload() | void WSMessageLoop::Timer::reload() | ||||||
|  | @ -263,7 +258,7 @@ void WSMessageLoop::notify_client_disconnected(int client_id) | ||||||
|     auto* client = WSClientConnection::from_client_id(client_id); |     auto* client = WSClientConnection::from_client_id(client_id); | ||||||
|     if (!client) |     if (!client) | ||||||
|         return; |         return; | ||||||
|     post_message(client, make<WSClientDisconnectedNotification>(client_id)); |     post_message(*client, make<WSClientDisconnectedNotification>(client_id)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void WSMessageLoop::on_receive_from_client(int client_id, const WSAPI_ClientMessage& message) | void WSMessageLoop::on_receive_from_client(int client_id, const WSAPI_ClientMessage& message) | ||||||
|  | @ -274,8 +269,7 @@ void WSMessageLoop::on_receive_from_client(int client_id, const WSAPI_ClientMess | ||||||
|         sched_yield(); |         sched_yield(); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|     WSClientConnection* client = WSClientConnection::from_client_id(client_id); |     WSClientConnection& client = *WSClientConnection::from_client_id(client_id); | ||||||
|     ASSERT(client); |  | ||||||
|     switch (message.type) { |     switch (message.type) { | ||||||
|     case WSAPI_ClientMessage::Type::CreateMenubar: |     case WSAPI_ClientMessage::Type::CreateMenubar: | ||||||
|         post_message(client, make<WSAPICreateMenubarRequest>(client_id)); |         post_message(client, make<WSAPICreateMenubarRequest>(client_id)); | ||||||
|  | @ -336,5 +330,7 @@ void WSMessageLoop::on_receive_from_client(int client_id, const WSAPI_ClientMess | ||||||
|     case WSAPI_ClientMessage::Type::SetGlobalCursorTracking: |     case WSAPI_ClientMessage::Type::SetGlobalCursorTracking: | ||||||
|         post_message(client, make<WSAPISetGlobalCursorTrackingRequest>(client_id, message.window_id, message.value)); |         post_message(client, make<WSAPISetGlobalCursorTrackingRequest>(client_id, message.window_id, message.value)); | ||||||
|         break; |         break; | ||||||
|  |     default: | ||||||
|  |         break; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -5,6 +5,7 @@ | ||||||
| #include <AK/OwnPtr.h> | #include <AK/OwnPtr.h> | ||||||
| #include <AK/Vector.h> | #include <AK/Vector.h> | ||||||
| #include <AK/Function.h> | #include <AK/Function.h> | ||||||
|  | #include <AK/WeakPtr.h> | ||||||
| 
 | 
 | ||||||
| class WSMessageReceiver; | class WSMessageReceiver; | ||||||
| struct WSAPI_ClientMessage; | struct WSAPI_ClientMessage; | ||||||
|  | @ -17,7 +18,7 @@ public: | ||||||
| 
 | 
 | ||||||
|     int exec(); |     int exec(); | ||||||
| 
 | 
 | ||||||
|     void post_message(WSMessageReceiver* receiver, OwnPtr<WSMessage>&&); |     void post_message(WSMessageReceiver& receiver, OwnPtr<WSMessage>&&); | ||||||
| 
 | 
 | ||||||
|     static WSMessageLoop& the(); |     static WSMessageLoop& the(); | ||||||
| 
 | 
 | ||||||
|  | @ -36,7 +37,7 @@ private: | ||||||
|     void drain_keyboard(); |     void drain_keyboard(); | ||||||
| 
 | 
 | ||||||
|     struct QueuedMessage { |     struct QueuedMessage { | ||||||
|         WSMessageReceiver* receiver { nullptr }; |         WeakPtr<WSMessageReceiver> receiver; | ||||||
|         OwnPtr<WSMessage> message; |         OwnPtr<WSMessage> message; | ||||||
|     }; |     }; | ||||||
|     Vector<QueuedMessage> m_queued_messages; |     Vector<QueuedMessage> m_queued_messages; | ||||||
|  |  | ||||||
|  | @ -74,7 +74,7 @@ void WSScreen::on_receive_mouse_data(int dx, int dy, bool left_button, bool righ | ||||||
|         buttons |= (unsigned)MouseButton::Right; |         buttons |= (unsigned)MouseButton::Right; | ||||||
|     if (m_cursor_location != prev_location) { |     if (m_cursor_location != prev_location) { | ||||||
|         auto message = make<WSMouseEvent>(WSMessage::MouseMove, m_cursor_location, buttons); |         auto message = make<WSMouseEvent>(WSMessage::MouseMove, m_cursor_location, buttons); | ||||||
|         WSMessageLoop::the().post_message(&WSWindowManager::the(), move(message)); |         WSMessageLoop::the().post_message(WSWindowManager::the(), move(message)); | ||||||
|     } |     } | ||||||
|     bool prev_left_button = m_left_mouse_button_pressed; |     bool prev_left_button = m_left_mouse_button_pressed; | ||||||
|     bool prev_right_button = m_right_mouse_button_pressed; |     bool prev_right_button = m_right_mouse_button_pressed; | ||||||
|  | @ -82,11 +82,11 @@ void WSScreen::on_receive_mouse_data(int dx, int dy, bool left_button, bool righ | ||||||
|     m_right_mouse_button_pressed = right_button; |     m_right_mouse_button_pressed = right_button; | ||||||
|     if (prev_left_button != left_button) { |     if (prev_left_button != left_button) { | ||||||
|         auto message = make<WSMouseEvent>(left_button ? WSMessage::MouseDown : WSMessage::MouseUp, m_cursor_location, buttons, MouseButton::Left); |         auto message = make<WSMouseEvent>(left_button ? WSMessage::MouseDown : WSMessage::MouseUp, m_cursor_location, buttons, MouseButton::Left); | ||||||
|         WSMessageLoop::the().post_message(&WSWindowManager::the(), move(message)); |         WSMessageLoop::the().post_message(WSWindowManager::the(), move(message)); | ||||||
|     } |     } | ||||||
|     if (prev_right_button != right_button) { |     if (prev_right_button != right_button) { | ||||||
|         auto message = make<WSMouseEvent>(right_button ? WSMessage::MouseDown : WSMessage::MouseUp, m_cursor_location, buttons, MouseButton::Right); |         auto message = make<WSMouseEvent>(right_button ? WSMessage::MouseDown : WSMessage::MouseUp, m_cursor_location, buttons, MouseButton::Right); | ||||||
|         WSMessageLoop::the().post_message(&WSWindowManager::the(), move(message)); |         WSMessageLoop::the().post_message(WSWindowManager::the(), move(message)); | ||||||
|     } |     } | ||||||
|     if (m_cursor_location != prev_location || prev_left_button != left_button) |     if (m_cursor_location != prev_location || prev_left_button != left_button) | ||||||
|         WSWindowManager::the().invalidate_cursor(); |         WSWindowManager::the().invalidate_cursor(); | ||||||
|  | @ -98,7 +98,7 @@ void WSScreen::on_receive_keyboard_data(KeyEvent kernel_event) | ||||||
|     message->m_shift = kernel_event.shift(); |     message->m_shift = kernel_event.shift(); | ||||||
|     message->m_ctrl = kernel_event.ctrl(); |     message->m_ctrl = kernel_event.ctrl(); | ||||||
|     message->m_alt = kernel_event.alt(); |     message->m_alt = kernel_event.alt(); | ||||||
|     WSMessageLoop::the().post_message(&WSWindowManager::the(), move(message)); |     WSMessageLoop::the().post_message(WSWindowManager::the(), move(message)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void WSScreen::set_y_offset(int offset) | void WSScreen::set_y_offset(int offset) | ||||||
|  |  | ||||||
|  | @ -502,9 +502,13 @@ void WSWindowManager::start_window_resize(WSWindow& window, WSMouseEvent& event) | ||||||
|     int window_relative_y = event.y() - window_rect.y(); |     int window_relative_y = event.y() - window_rect.y(); | ||||||
|     int hot_area_row = window_relative_y / (window_rect.height() / 3); |     int hot_area_row = window_relative_y / (window_rect.height() / 3); | ||||||
|     int hot_area_column = window_relative_x / (window_rect.width() / 3); |     int hot_area_column = window_relative_x / (window_rect.width() / 3); | ||||||
|  |     ASSERT(hot_area_row >= 0 && hot_area_row <= 2); | ||||||
|  |     ASSERT(hot_area_column >= 0 && hot_area_column <= 2); | ||||||
|     m_resize_direction = direction_for_hot_area[hot_area_row][hot_area_column]; |     m_resize_direction = direction_for_hot_area[hot_area_row][hot_area_column]; | ||||||
|     if (m_resize_direction == ResizeDirection::None) |     if (m_resize_direction == ResizeDirection::None) { | ||||||
|  |         ASSERT(!m_resize_window); | ||||||
|         return; |         return; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
| #ifdef RESIZE_DEBUG | #ifdef RESIZE_DEBUG | ||||||
|     printf("[WM] Begin resizing WSWindow{%p}\n", &window); |     printf("[WM] Begin resizing WSWindow{%p}\n", &window); | ||||||
|  | @ -550,7 +554,7 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& event_ | ||||||
| #ifdef RESIZE_DEBUG | #ifdef RESIZE_DEBUG | ||||||
|             printf("[WM] Finish resizing WSWindow{%p}\n", m_resize_window.ptr()); |             printf("[WM] Finish resizing WSWindow{%p}\n", m_resize_window.ptr()); | ||||||
| #endif | #endif | ||||||
|             WSMessageLoop::the().post_message(m_resize_window.ptr(), make<WSResizeEvent>(m_resize_window->rect(), m_resize_window->rect())); |             WSMessageLoop::the().post_message(*m_resize_window, make<WSResizeEvent>(m_resize_window->rect(), m_resize_window->rect())); | ||||||
|             invalidate(*m_resize_window); |             invalidate(*m_resize_window); | ||||||
|             m_resize_window = nullptr; |             m_resize_window = nullptr; | ||||||
|             return; |             return; | ||||||
|  | @ -633,7 +637,7 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& event_ | ||||||
|                 m_resize_window->set_has_painted_since_last_resize(false); |                 m_resize_window->set_has_painted_since_last_resize(false); | ||||||
|                 dbgprintf("I'm gonna wait for %s\n", new_rect.to_string().characters()); |                 dbgprintf("I'm gonna wait for %s\n", new_rect.to_string().characters()); | ||||||
|                 m_resize_window->set_last_lazy_resize_rect(new_rect); |                 m_resize_window->set_last_lazy_resize_rect(new_rect); | ||||||
|                 WSMessageLoop::the().post_message(m_resize_window.ptr(), make<WSResizeEvent>(old_rect, new_rect)); |                 WSMessageLoop::the().post_message(*m_resize_window, make<WSResizeEvent>(old_rect, new_rect)); | ||||||
|             } |             } | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  | @ -911,12 +915,12 @@ void WSWindowManager::set_active_window(WSWindow* window) | ||||||
|         return; |         return; | ||||||
| 
 | 
 | ||||||
|     if (auto* previously_active_window = m_active_window.ptr()) { |     if (auto* previously_active_window = m_active_window.ptr()) { | ||||||
|         WSMessageLoop::the().post_message(previously_active_window, make<WSMessage>(WSMessage::WindowDeactivated)); |         WSMessageLoop::the().post_message(*previously_active_window, make<WSMessage>(WSMessage::WindowDeactivated)); | ||||||
|         invalidate(*previously_active_window); |         invalidate(*previously_active_window); | ||||||
|     } |     } | ||||||
|     m_active_window = window->make_weak_ptr(); |     m_active_window = window->make_weak_ptr(); | ||||||
|     if (m_active_window) { |     if (m_active_window) { | ||||||
|         WSMessageLoop::the().post_message(m_active_window.ptr(), make<WSMessage>(WSMessage::WindowActivated)); |         WSMessageLoop::the().post_message(*m_active_window, make<WSMessage>(WSMessage::WindowActivated)); | ||||||
|         invalidate(*m_active_window); |         invalidate(*m_active_window); | ||||||
| 
 | 
 | ||||||
|         auto* client = window->client(); |         auto* client = window->client(); | ||||||
|  | @ -931,12 +935,12 @@ void WSWindowManager::set_hovered_window(WSWindow* window) | ||||||
|         return; |         return; | ||||||
| 
 | 
 | ||||||
|     if (m_hovered_window) |     if (m_hovered_window) | ||||||
|         WSMessageLoop::the().post_message(m_hovered_window.ptr(), make<WSMessage>(WSMessage::WindowLeft)); |         WSMessageLoop::the().post_message(*m_hovered_window, make<WSMessage>(WSMessage::WindowLeft)); | ||||||
| 
 | 
 | ||||||
|     m_hovered_window = window ? window->make_weak_ptr() : nullptr; |     m_hovered_window = window ? window->make_weak_ptr() : nullptr; | ||||||
| 
 | 
 | ||||||
|     if (m_hovered_window) |     if (m_hovered_window) | ||||||
|         WSMessageLoop::the().post_message(m_hovered_window.ptr(), make<WSMessage>(WSMessage::WindowEntered)); |         WSMessageLoop::the().post_message(*m_hovered_window, make<WSMessage>(WSMessage::WindowEntered)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void WSWindowManager::invalidate() | void WSWindowManager::invalidate() | ||||||
|  | @ -960,7 +964,7 @@ void WSWindowManager::invalidate(const Rect& a_rect, bool should_schedule_compos | ||||||
|     m_dirty_rects.add(rect); |     m_dirty_rects.add(rect); | ||||||
| 
 | 
 | ||||||
|     if (should_schedule_compose_event && !m_pending_compose_event) { |     if (should_schedule_compose_event && !m_pending_compose_event) { | ||||||
|         WSMessageLoop::the().post_message(this, make<WSMessage>(WSMessage::WM_DeferredCompose)); |         WSMessageLoop::the().post_message(*this, make<WSMessage>(WSMessage::WM_DeferredCompose)); | ||||||
|         m_pending_compose_event = true; |         m_pending_compose_event = true; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling