From 44657db3e21faddcf111696d3a05d93046fcea5a Mon Sep 17 00:00:00 2001 From: Meriipu Date: Thu, 6 Aug 2020 15:05:43 +0200 Subject: If the mouse is held on notification_wm_mouse_exit, do not drop focus This fixes a bug where users of the scrollbar had to be very careful not to move the mouse outside the viewport, otherwise the scrollbar would drop its drag-action and stop scrolling until clicked again. The existing behaviour had the side-effect of also dropping the cosmetic highlighting of the scrollbar (in addition to the dragging), for the specific case where the mouse was move outside the window. The previous behaviour did nothing to remove the highlight if the mouse was released (but not moved) inside the viewport. This separate issue with the lingering highlight of the scrollbar (until a mouse-movement action is performed inside the viewport) is fixed in an immediate followup to this commit. Closes bug #39634 --- scene/main/viewport.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index d962171555..08a212d58b 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -814,7 +814,14 @@ void Viewport::_notification(int p_what) { } } break; - case NOTIFICATION_WM_MOUSE_EXIT: + case NOTIFICATION_WM_MOUSE_EXIT: { + _drop_physics_mouseover(); + + // Unlike on loss of focus (NOTIFICATION_WM_WINDOW_FOCUS_OUT), do not + // drop the gui mouseover here, as a scrollbar may be dragged while the + // mouse is outside the window (without the window having lost focus). + // See bug #39634 + } break; case NOTIFICATION_WM_WINDOW_FOCUS_OUT: { _drop_physics_mouseover(); -- cgit v1.2.3 From e8804b9978a4bd2647e1367bc2258a19d73dcc95 Mon Sep 17 00:00:00 2001 From: Meriipu Date: Thu, 6 Aug 2020 15:44:05 +0200 Subject: Make the currently hovered control get updated on mouse-release Previously, when the mouse was released after dragging a scrollbar, its highlight was not dropped (if the mouse cursor was still inside the viewport). This seems to be because the currently hovered control only gets updated when the mouse is moved. This commit fixes the dropping of the cosmetic highlight by running the check for whether the currently hovered control has changed on mouse-clicks, in addition to to the existing mouse-movements. --- scene/main/viewport.cpp | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 08a212d58b..b5cba78fe2 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1801,6 +1801,8 @@ void Viewport::_gui_input_event(Ref p_event) { if (mb.is_valid()) { gui.key_event_accepted = false; + Control *over = nullptr; + Point2 mpos = mb->get_position(); if (mb->is_pressed()) { Size2 pos = mpos; @@ -1955,6 +1957,31 @@ void Viewport::_gui_input_event(Ref p_event) { gui.drag_data=Variant(); //always clear }*/ + // In case the mouse was released after for example dragging a scrollbar, + // check whether the current control is different from the stored one. If + // it is different, rather than wait for it to be updated the next time the + // mouse is moved, notify the control so that it can e.g. drop the highlight. + // This code is duplicated from the mm.is_valid()-case further below. + if (gui.mouse_focus) { + over = gui.mouse_focus; + } else { + over = _gui_find_control(mpos); + } + + if (gui.mouse_focus_mask == 0 && over != gui.mouse_over) { + if (gui.mouse_over) { + _gui_call_notification(gui.mouse_over, Control::NOTIFICATION_MOUSE_EXIT); + } + + _gui_cancel_tooltip(); + + if (over) { + _gui_call_notification(over, Control::NOTIFICATION_MOUSE_ENTER); + } + } + + gui.mouse_over = over; + set_input_as_handled(); } } @@ -2015,10 +2042,11 @@ void Viewport::_gui_input_event(Ref p_event) { } } + // These sections of code are reused in the mb.is_valid() case further up + // for the purpose of notifying controls about potential changes in focus + // when the mousebutton is released. if (gui.mouse_focus) { over = gui.mouse_focus; - //recompute focus_inv_xform again here - } else { over = _gui_find_control(mpos); } -- cgit v1.2.3