Explorar o código

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.
sin-ack %!s(int64=3) %!d(string=hai) anos
pai
achega
cfc9ee6f16

+ 16 - 0
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();
     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;
+}
+
 }
 }

+ 2 - 0
Userland/Libraries/LibGUI/Widget.h

@@ -280,6 +280,8 @@ public:
 
 
     bool has_pending_drop() const;
     bool has_pending_drop() const;
 
 
+    bool is_parent_of(Widget const*) const;
+
 protected:
 protected:
     Widget();
     Widget();
 
 

+ 1 - 1
Userland/Libraries/LibGUI/Window.cpp

@@ -802,7 +802,7 @@ void Window::set_hovered_widget(Widget* widget)
     if (widget == m_hovered_widget)
     if (widget == m_hovered_widget)
         return;
         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>(Event::Leave));
         Core::EventLoop::current().post_event(*m_hovered_widget, make<Event>(Event::Leave));
 
 
     m_hovered_widget = widget;
     m_hovered_widget = widget;