From 95cfa49f1b3da114f0147e3082f46ab7770e6c02 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Tue, 26 Feb 2019 00:51:49 +0100 Subject: LibGUI: Make event receivers be weak pointers. --- LibGUI/GEventLoop.cpp | 30 ++++++++++++++---------------- LibGUI/GEventLoop.h | 7 ++++--- LibGUI/GObject.cpp | 2 +- LibGUI/GWindow.cpp | 8 ++++---- 4 files changed, 23 insertions(+), 24 deletions(-) diff --git a/LibGUI/GEventLoop.cpp b/LibGUI/GEventLoop.cpp index 2765fc9d2f..2e0a2ba4c9 100644 --- a/LibGUI/GEventLoop.cpp +++ b/LibGUI/GEventLoop.cpp @@ -85,7 +85,7 @@ int GEventLoop::exec() } Vector events = move(m_queued_events); for (auto& queued_event : events) { - auto* receiver = queued_event.receiver; + auto* receiver = queued_event.receiver.ptr(); auto& event = *queued_event.event; #ifdef GEVENTLOOP_DEBUG dbgprintf("GEventLoop: %s{%p} event %u\n", receiver->class_name(), receiver, (unsigned)event.type()); @@ -96,9 +96,7 @@ int GEventLoop::exec() ASSERT_NOT_REACHED(); return 0; default: - dbgprintf("event type %u with no receiver :(\n", event.type()); - ASSERT_NOT_REACHED(); - return 1; + dbgprintf("Event type %u with no receiver :(\n", event.type()); } } else { receiver->event(event); @@ -108,12 +106,12 @@ int GEventLoop::exec() ASSERT_NOT_REACHED(); } -void GEventLoop::post_event(GObject* receiver, OwnPtr&& event) +void GEventLoop::post_event(GObject& receiver, OwnPtr&& event) { #ifdef GEVENTLOOP_DEBUG - dbgprintf("GEventLoop::post_event: {%u} << receiver=%p, event=%p\n", m_queued_events.size(), receiver, event.ptr()); + dbgprintf("GEventLoop::post_event: {%u} << receiver=%p, event=%p\n", m_queued_events.size(), &receiver, event.ptr()); #endif - m_queued_events.append({ receiver, move(event) }); + m_queued_events.append({ receiver.make_weak_ptr(), move(event) }); } void GEventLoop::handle_paint_event(const WSAPI_ServerMessage& event, GWindow& window) @@ -121,12 +119,12 @@ void GEventLoop::handle_paint_event(const WSAPI_ServerMessage& event, GWindow& w #ifdef GEVENTLOOP_DEBUG dbgprintf("WID=%x Paint [%d,%d %dx%d]\n", event.window_id, event.paint.rect.location.x, event.paint.rect.location.y, event.paint.rect.size.width, event.paint.rect.size.height); #endif - post_event(&window, make(event.paint.rect)); + post_event(window, make(event.paint.rect)); } void GEventLoop::handle_resize_event(const WSAPI_ServerMessage& event, GWindow& window) { - post_event(&window, make(event.window.old_rect.size, event.window.rect.size)); + post_event(window, make(event.window.old_rect.size, event.window.rect.size)); } void GEventLoop::handle_window_activation_event(const WSAPI_ServerMessage& event, GWindow& window) @@ -134,17 +132,17 @@ void GEventLoop::handle_window_activation_event(const WSAPI_ServerMessage& event #ifdef GEVENTLOOP_DEBUG dbgprintf("WID=%x WindowActivation\n", event.window_id); #endif - post_event(&window, make(event.type == WSAPI_ServerMessage::Type::WindowActivated ? GEvent::WindowBecameActive : GEvent::WindowBecameInactive)); + post_event(window, make(event.type == WSAPI_ServerMessage::Type::WindowActivated ? GEvent::WindowBecameActive : GEvent::WindowBecameInactive)); } void GEventLoop::handle_window_close_request_event(const WSAPI_ServerMessage&, GWindow& window) { - post_event(&window, make(GEvent::WindowCloseRequest)); + post_event(window, make(GEvent::WindowCloseRequest)); } void GEventLoop::handle_window_entered_or_left_event(const WSAPI_ServerMessage& message, GWindow& window) { - post_event(&window, make(message.type == WSAPI_ServerMessage::Type::WindowEntered ? GEvent::WindowEntered : GEvent::WindowLeft)); + post_event(window, make(message.type == WSAPI_ServerMessage::Type::WindowEntered ? GEvent::WindowEntered : GEvent::WindowLeft)); } void GEventLoop::handle_key_event(const WSAPI_ServerMessage& event, GWindow& window) @@ -158,7 +156,7 @@ void GEventLoop::handle_key_event(const WSAPI_ServerMessage& event, GWindow& win key_event->m_shift = event.key.shift; if (event.key.character != '\0') key_event->m_text = String(&event.key.character, 1); - post_event(&window, move(key_event)); + post_event(window, move(key_event)); } void GEventLoop::handle_mouse_event(const WSAPI_ServerMessage& event, GWindow& window) @@ -181,7 +179,7 @@ void GEventLoop::handle_mouse_event(const WSAPI_ServerMessage& event, GWindow& w case WSAPI_MouseButton::Middle: button = GMouseButton::Middle; break; default: ASSERT_NOT_REACHED(); break; } - post_event(&window, make(type, event.mouse.position, event.mouse.buttons, button)); + post_event(window, make(type, event.mouse.position, event.mouse.buttons, button)); } void GEventLoop::handle_menu_event(const WSAPI_ServerMessage& event) @@ -239,7 +237,7 @@ void GEventLoop::wait_for_event() #ifdef GEVENTLOOP_DEBUG dbgprintf("GEventLoop: Timer %d has expired, sending GTimerEvent to %p\n", timer.timer_id, timer.owner); #endif - post_event(timer.owner, make(timer.timer_id)); + post_event(*timer.owner, make(timer.timer_id)); if (timer.should_reload) { timer.reload(); } else { @@ -378,7 +376,7 @@ int GEventLoop::register_timer(GObject& object, int milliseconds, bool should_re { ASSERT(milliseconds >= 0); auto timer = make(); - timer->owner = &object; + timer->owner = object.make_weak_ptr(); timer->interval = milliseconds; timer->reload(); timer->should_reload = should_reload; diff --git a/LibGUI/GEventLoop.h b/LibGUI/GEventLoop.h index b0d66cdafa..152c8b52f9 100644 --- a/LibGUI/GEventLoop.h +++ b/LibGUI/GEventLoop.h @@ -5,6 +5,7 @@ #include #include #include +#include #include class GObject; @@ -18,7 +19,7 @@ public: int exec(); - void post_event(GObject* receiver, OwnPtr&&); + void post_event(GObject& receiver, OwnPtr&&); static GEventLoop& main(); @@ -56,7 +57,7 @@ private: void get_next_timer_expiration(timeval&); struct QueuedEvent { - GObject* receiver { nullptr }; + WeakPtr receiver; OwnPtr event; }; Vector m_queued_events; @@ -75,7 +76,7 @@ private: int interval { 0 }; timeval fire_time; bool should_reload { false }; - GObject* owner { nullptr }; + WeakPtr owner; void reload(); bool has_expired() const; diff --git a/LibGUI/GObject.cpp b/LibGUI/GObject.cpp index f033ec86dc..d50e7bdcd9 100644 --- a/LibGUI/GObject.cpp +++ b/LibGUI/GObject.cpp @@ -76,6 +76,6 @@ void GObject::stop_timer() void GObject::delete_later() { - GEventLoop::main().post_event(this, make(GEvent::DeferredDestroy)); + GEventLoop::main().post_event(*this, make(GEvent::DeferredDestroy)); } diff --git a/LibGUI/GWindow.cpp b/LibGUI/GWindow.cpp index 18d08c1c84..02826f2c2e 100644 --- a/LibGUI/GWindow.cpp +++ b/LibGUI/GWindow.cpp @@ -294,12 +294,12 @@ void GWindow::set_focused_widget(GWidget* widget) if (m_focused_widget == widget) return; if (m_focused_widget) { - GEventLoop::main().post_event(m_focused_widget, make(GEvent::FocusOut)); + GEventLoop::main().post_event(*m_focused_widget, make(GEvent::FocusOut)); m_focused_widget->update(); } m_focused_widget = widget; if (m_focused_widget) { - GEventLoop::main().post_event(m_focused_widget, make(GEvent::FocusIn)); + GEventLoop::main().post_event(*m_focused_widget, make(GEvent::FocusIn)); m_focused_widget->update(); } } @@ -345,10 +345,10 @@ void GWindow::set_hovered_widget(GWidget* widget) return; if (m_hovered_widget) - GEventLoop::main().post_event(m_hovered_widget.ptr(), make(GEvent::Leave)); + GEventLoop::main().post_event(*m_hovered_widget, make(GEvent::Leave)); m_hovered_widget = widget ? widget->make_weak_ptr() : nullptr; if (m_hovered_widget) - GEventLoop::main().post_event(m_hovered_widget.ptr(), make(GEvent::Enter)); + GEventLoop::main().post_event(*m_hovered_widget, make(GEvent::Enter)); } -- cgit v1.2.3