From cfc9ee6f16b9c4d2b246bb2832dd436637cbeaad Mon Sep 17 00:00:00 2001 From: sin-ack Date: Sun, 25 Jul 2021 21:09:54 +0000 Subject: [PATCH] LibGUI: Only dispatch Leave if the now-hovered widget isn't a child Without this change, when the mouse starts hovering over a child widget, the parent would receive a Leave event despite the parent widget not losing mouse hover. --- Userland/Libraries/LibGUI/Widget.cpp | 16 ++++++++++++++++ Userland/Libraries/LibGUI/Widget.h | 2 ++ Userland/Libraries/LibGUI/Window.cpp | 2 +- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/Userland/Libraries/LibGUI/Widget.cpp b/Userland/Libraries/LibGUI/Widget.cpp index e69eb1209b..fbdd8e2cac 100644 --- a/Userland/Libraries/LibGUI/Widget.cpp +++ b/Userland/Libraries/LibGUI/Widget.cpp @@ -1138,4 +1138,20 @@ bool Widget::is_visible_for_timer_purposes() const return is_visible() && Object::is_visible_for_timer_purposes(); } +bool Widget::is_parent_of(Widget const* widget) const +{ + if (widget == nullptr) + return false; + + Widget const* current_widget = widget->parent_widget(); + + while (current_widget != nullptr) { + if (current_widget == this) + return true; + current_widget = current_widget->parent_widget(); + } + + return false; +} + } diff --git a/Userland/Libraries/LibGUI/Widget.h b/Userland/Libraries/LibGUI/Widget.h index a46a735e89..4a5f4ef8f4 100644 --- a/Userland/Libraries/LibGUI/Widget.h +++ b/Userland/Libraries/LibGUI/Widget.h @@ -280,6 +280,8 @@ public: bool has_pending_drop() const; + bool is_parent_of(Widget const*) const; + protected: Widget(); diff --git a/Userland/Libraries/LibGUI/Window.cpp b/Userland/Libraries/LibGUI/Window.cpp index 781dcd8636..910e04fc0a 100644 --- a/Userland/Libraries/LibGUI/Window.cpp +++ b/Userland/Libraries/LibGUI/Window.cpp @@ -802,7 +802,7 @@ void Window::set_hovered_widget(Widget* widget) if (widget == m_hovered_widget) return; - if (m_hovered_widget) + if (m_hovered_widget && !m_hovered_widget->is_parent_of(widget)) Core::EventLoop::current().post_event(*m_hovered_widget, make(Event::Leave)); m_hovered_widget = widget;