From b408b05d7d26ec47638b6c6353ebfc4dc164c3e2 Mon Sep 17 00:00:00 2001 From: Markus Sauermann <6299227+Sauermann@users.noreply.github.com> Date: Thu, 13 Jul 2023 23:23:08 +0200 Subject: [PATCH] Fix physics passive hovering for some cases When the parent `SubViewportContainer` ignores mouse with `MOUSE_FILTER_IGNORE` and also when the mouse is over a `Control`-node, then the `SubViewport` shouldn't create mouse-move-events for passive hovering. --- scene/main/viewport.cpp | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 71bef56ebb..e0e18f8ef3 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -689,17 +689,26 @@ void Viewport::_process_picking() { PhysicsDirectSpaceState2D *ss2d = PhysicsServer2D::get_singleton()->space_get_direct_state(find_world_2d()->get_space()); - bool has_mouse_event = false; - for (const Ref &e : physics_picking_events) { - Ref m = e; - if (m.is_valid()) { - has_mouse_event = true; - break; + SubViewportContainer *parent_svc = Object::cast_to(get_parent()); + bool parent_ignore_mouse = (parent_svc && parent_svc->get_mouse_filter() == Control::MOUSE_FILTER_IGNORE); + bool create_passive_hover_event = true; + if (gui.mouse_over || parent_ignore_mouse) { + // When the mouse is over a Control node, passive hovering would cause input events for Colliders, that are behind Control nodes. + // When parent SubViewportContainer ignores mouse, that setting should be respected. + create_passive_hover_event = false; + } else { + for (const Ref &e : physics_picking_events) { + Ref m = e; + if (m.is_valid()) { + // A mouse event exists, so passive hovering isn't necessary. + create_passive_hover_event = false; + break; + } } } - if (!has_mouse_event) { - // If no mouse event exists, create a motion one. This is necessary because objects or camera may have moved. + if (create_passive_hover_event) { + // Create a mouse motion event. This is necessary because objects or camera may have moved. // While this extra event is sent, it is checked if both camera and last object and last ID did not move. // If nothing changed, the event is discarded to avoid flooding with unnecessary motion events every frame. Ref mm;