소스 검색

WindowServer: Make message receivers be weak pointers.

Andreas Kling 6 년 전
부모
커밋
d77f8ba413
5개의 변경된 파일28개의 추가작업 그리고 27개의 파일을 삭제
  1. 1 1
      WindowServer/WSClientConnection.cpp
  2. 8 12
      WindowServer/WSMessageLoop.cpp
  3. 3 2
      WindowServer/WSMessageLoop.h
  4. 4 4
      WindowServer/WSScreen.cpp
  5. 12 8
      WindowServer/WSWindowManager.cpp

+ 1 - 1
WindowServer/WSClientConnection.cpp

@@ -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());

+ 8 - 12
WindowServer/WSMessageLoop.cpp

@@ -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) {
-                dbgprintf("WSMessage type %u with no receiver :(\n", message.type());
-                ASSERT_NOT_REACHED();
-                return 1;
-            } else {
+            if (receiver)
                 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);
-    ASSERT(client);
+    WSClientConnection& client = *WSClientConnection::from_client_id(client_id);
     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;
     }
     }
 }
 }

+ 3 - 2
WindowServer/WSMessageLoop.h

@@ -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;

+ 4 - 4
WindowServer/WSScreen.cpp

@@ -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)

+ 12 - 8
WindowServer/WSWindowManager.cpp

@@ -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;
     }
     }
 }
 }