mirror of
https://github.com/RGBCube/serenity
synced 2025-05-22 11:05:07 +00:00
LibGUI: Make event receivers be weak pointers.
This commit is contained in:
parent
9624b54703
commit
95cfa49f1b
4 changed files with 23 additions and 24 deletions
|
@ -85,7 +85,7 @@ int GEventLoop::exec()
|
||||||
}
|
}
|
||||||
Vector<QueuedEvent> events = move(m_queued_events);
|
Vector<QueuedEvent> events = move(m_queued_events);
|
||||||
for (auto& queued_event : events) {
|
for (auto& queued_event : events) {
|
||||||
auto* receiver = queued_event.receiver;
|
auto* receiver = queued_event.receiver.ptr();
|
||||||
auto& event = *queued_event.event;
|
auto& event = *queued_event.event;
|
||||||
#ifdef GEVENTLOOP_DEBUG
|
#ifdef GEVENTLOOP_DEBUG
|
||||||
dbgprintf("GEventLoop: %s{%p} event %u\n", receiver->class_name(), receiver, (unsigned)event.type());
|
dbgprintf("GEventLoop: %s{%p} event %u\n", receiver->class_name(), receiver, (unsigned)event.type());
|
||||||
|
@ -96,9 +96,7 @@ int GEventLoop::exec()
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
dbgprintf("event type %u with no receiver :(\n", event.type());
|
dbgprintf("Event type %u with no receiver :(\n", event.type());
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
receiver->event(event);
|
receiver->event(event);
|
||||||
|
@ -108,12 +106,12 @@ int GEventLoop::exec()
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GEventLoop::post_event(GObject* receiver, OwnPtr<GEvent>&& event)
|
void GEventLoop::post_event(GObject& receiver, OwnPtr<GEvent>&& event)
|
||||||
{
|
{
|
||||||
#ifdef GEVENTLOOP_DEBUG
|
#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
|
#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)
|
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
|
#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);
|
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
|
#endif
|
||||||
post_event(&window, make<GPaintEvent>(event.paint.rect));
|
post_event(window, make<GPaintEvent>(event.paint.rect));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GEventLoop::handle_resize_event(const WSAPI_ServerMessage& event, GWindow& window)
|
void GEventLoop::handle_resize_event(const WSAPI_ServerMessage& event, GWindow& window)
|
||||||
{
|
{
|
||||||
post_event(&window, make<GResizeEvent>(event.window.old_rect.size, event.window.rect.size));
|
post_event(window, make<GResizeEvent>(event.window.old_rect.size, event.window.rect.size));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GEventLoop::handle_window_activation_event(const WSAPI_ServerMessage& event, GWindow& window)
|
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
|
#ifdef GEVENTLOOP_DEBUG
|
||||||
dbgprintf("WID=%x WindowActivation\n", event.window_id);
|
dbgprintf("WID=%x WindowActivation\n", event.window_id);
|
||||||
#endif
|
#endif
|
||||||
post_event(&window, make<GEvent>(event.type == WSAPI_ServerMessage::Type::WindowActivated ? GEvent::WindowBecameActive : GEvent::WindowBecameInactive));
|
post_event(window, make<GEvent>(event.type == WSAPI_ServerMessage::Type::WindowActivated ? GEvent::WindowBecameActive : GEvent::WindowBecameInactive));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GEventLoop::handle_window_close_request_event(const WSAPI_ServerMessage&, GWindow& window)
|
void GEventLoop::handle_window_close_request_event(const WSAPI_ServerMessage&, GWindow& window)
|
||||||
{
|
{
|
||||||
post_event(&window, make<GEvent>(GEvent::WindowCloseRequest));
|
post_event(window, make<GEvent>(GEvent::WindowCloseRequest));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GEventLoop::handle_window_entered_or_left_event(const WSAPI_ServerMessage& message, GWindow& window)
|
void GEventLoop::handle_window_entered_or_left_event(const WSAPI_ServerMessage& message, GWindow& window)
|
||||||
{
|
{
|
||||||
post_event(&window, make<GEvent>(message.type == WSAPI_ServerMessage::Type::WindowEntered ? GEvent::WindowEntered : GEvent::WindowLeft));
|
post_event(window, make<GEvent>(message.type == WSAPI_ServerMessage::Type::WindowEntered ? GEvent::WindowEntered : GEvent::WindowLeft));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GEventLoop::handle_key_event(const WSAPI_ServerMessage& event, GWindow& window)
|
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;
|
key_event->m_shift = event.key.shift;
|
||||||
if (event.key.character != '\0')
|
if (event.key.character != '\0')
|
||||||
key_event->m_text = String(&event.key.character, 1);
|
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)
|
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;
|
case WSAPI_MouseButton::Middle: button = GMouseButton::Middle; break;
|
||||||
default: ASSERT_NOT_REACHED(); break;
|
default: ASSERT_NOT_REACHED(); break;
|
||||||
}
|
}
|
||||||
post_event(&window, make<GMouseEvent>(type, event.mouse.position, event.mouse.buttons, button));
|
post_event(window, make<GMouseEvent>(type, event.mouse.position, event.mouse.buttons, button));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GEventLoop::handle_menu_event(const WSAPI_ServerMessage& event)
|
void GEventLoop::handle_menu_event(const WSAPI_ServerMessage& event)
|
||||||
|
@ -239,7 +237,7 @@ void GEventLoop::wait_for_event()
|
||||||
#ifdef GEVENTLOOP_DEBUG
|
#ifdef GEVENTLOOP_DEBUG
|
||||||
dbgprintf("GEventLoop: Timer %d has expired, sending GTimerEvent to %p\n", timer.timer_id, timer.owner);
|
dbgprintf("GEventLoop: Timer %d has expired, sending GTimerEvent to %p\n", timer.timer_id, timer.owner);
|
||||||
#endif
|
#endif
|
||||||
post_event(timer.owner, make<GTimerEvent>(timer.timer_id));
|
post_event(*timer.owner, make<GTimerEvent>(timer.timer_id));
|
||||||
if (timer.should_reload) {
|
if (timer.should_reload) {
|
||||||
timer.reload();
|
timer.reload();
|
||||||
} else {
|
} else {
|
||||||
|
@ -378,7 +376,7 @@ int GEventLoop::register_timer(GObject& object, int milliseconds, bool should_re
|
||||||
{
|
{
|
||||||
ASSERT(milliseconds >= 0);
|
ASSERT(milliseconds >= 0);
|
||||||
auto timer = make<EventLoopTimer>();
|
auto timer = make<EventLoopTimer>();
|
||||||
timer->owner = &object;
|
timer->owner = object.make_weak_ptr();
|
||||||
timer->interval = milliseconds;
|
timer->interval = milliseconds;
|
||||||
timer->reload();
|
timer->reload();
|
||||||
timer->should_reload = should_reload;
|
timer->should_reload = should_reload;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <AK/HashMap.h>
|
#include <AK/HashMap.h>
|
||||||
#include <AK/OwnPtr.h>
|
#include <AK/OwnPtr.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
|
#include <AK/WeakPtr.h>
|
||||||
#include <WindowServer/WSAPITypes.h>
|
#include <WindowServer/WSAPITypes.h>
|
||||||
|
|
||||||
class GObject;
|
class GObject;
|
||||||
|
@ -18,7 +19,7 @@ public:
|
||||||
|
|
||||||
int exec();
|
int exec();
|
||||||
|
|
||||||
void post_event(GObject* receiver, OwnPtr<GEvent>&&);
|
void post_event(GObject& receiver, OwnPtr<GEvent>&&);
|
||||||
|
|
||||||
static GEventLoop& main();
|
static GEventLoop& main();
|
||||||
|
|
||||||
|
@ -56,7 +57,7 @@ private:
|
||||||
void get_next_timer_expiration(timeval&);
|
void get_next_timer_expiration(timeval&);
|
||||||
|
|
||||||
struct QueuedEvent {
|
struct QueuedEvent {
|
||||||
GObject* receiver { nullptr };
|
WeakPtr<GObject> receiver;
|
||||||
OwnPtr<GEvent> event;
|
OwnPtr<GEvent> event;
|
||||||
};
|
};
|
||||||
Vector<QueuedEvent> m_queued_events;
|
Vector<QueuedEvent> m_queued_events;
|
||||||
|
@ -75,7 +76,7 @@ private:
|
||||||
int interval { 0 };
|
int interval { 0 };
|
||||||
timeval fire_time;
|
timeval fire_time;
|
||||||
bool should_reload { false };
|
bool should_reload { false };
|
||||||
GObject* owner { nullptr };
|
WeakPtr<GObject> owner;
|
||||||
|
|
||||||
void reload();
|
void reload();
|
||||||
bool has_expired() const;
|
bool has_expired() const;
|
||||||
|
|
|
@ -76,6 +76,6 @@ void GObject::stop_timer()
|
||||||
|
|
||||||
void GObject::delete_later()
|
void GObject::delete_later()
|
||||||
{
|
{
|
||||||
GEventLoop::main().post_event(this, make<GEvent>(GEvent::DeferredDestroy));
|
GEventLoop::main().post_event(*this, make<GEvent>(GEvent::DeferredDestroy));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -294,12 +294,12 @@ void GWindow::set_focused_widget(GWidget* widget)
|
||||||
if (m_focused_widget == widget)
|
if (m_focused_widget == widget)
|
||||||
return;
|
return;
|
||||||
if (m_focused_widget) {
|
if (m_focused_widget) {
|
||||||
GEventLoop::main().post_event(m_focused_widget, make<GEvent>(GEvent::FocusOut));
|
GEventLoop::main().post_event(*m_focused_widget, make<GEvent>(GEvent::FocusOut));
|
||||||
m_focused_widget->update();
|
m_focused_widget->update();
|
||||||
}
|
}
|
||||||
m_focused_widget = widget;
|
m_focused_widget = widget;
|
||||||
if (m_focused_widget) {
|
if (m_focused_widget) {
|
||||||
GEventLoop::main().post_event(m_focused_widget, make<GEvent>(GEvent::FocusIn));
|
GEventLoop::main().post_event(*m_focused_widget, make<GEvent>(GEvent::FocusIn));
|
||||||
m_focused_widget->update();
|
m_focused_widget->update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -345,10 +345,10 @@ void GWindow::set_hovered_widget(GWidget* widget)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_hovered_widget)
|
if (m_hovered_widget)
|
||||||
GEventLoop::main().post_event(m_hovered_widget.ptr(), make<GEvent>(GEvent::Leave));
|
GEventLoop::main().post_event(*m_hovered_widget, make<GEvent>(GEvent::Leave));
|
||||||
|
|
||||||
m_hovered_widget = widget ? widget->make_weak_ptr() : nullptr;
|
m_hovered_widget = widget ? widget->make_weak_ptr() : nullptr;
|
||||||
|
|
||||||
if (m_hovered_widget)
|
if (m_hovered_widget)
|
||||||
GEventLoop::main().post_event(m_hovered_widget.ptr(), make<GEvent>(GEvent::Enter));
|
GEventLoop::main().post_event(*m_hovered_widget, make<GEvent>(GEvent::Enter));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue