diff options
Diffstat (limited to 'scene/main/viewport.cpp')
-rw-r--r-- | scene/main/viewport.cpp | 49 |
1 files changed, 25 insertions, 24 deletions
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 1244e0c028..bde68f0b3d 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -492,20 +492,26 @@ void Viewport::_notification(int p_what) { } #endif // _3D_DISABLED } break; + case NOTIFICATION_WM_MOUSE_ENTER: { + gui.mouse_in_window = true; + } break; case NOTIFICATION_WM_MOUSE_EXIT: { + gui.mouse_in_window = false; _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 + _drop_mouse_over(); + // When the mouse exits the window, we want to end mouse_over, but + // not mouse_focus, because, for example, we want to continue + // dragging a scrollbar even if the mouse has left the window. } break; case NOTIFICATION_WM_WINDOW_FOCUS_OUT: { _drop_physics_mouseover(); - if (gui.mouse_focus && !gui.forced_mouse_focus) { _drop_mouse_focus(); } + // When the window focus changes, we want to end mouse_focus, but + // not the mouse_over. Note: The OS will trigger a separate mouse + // exit event if the change in focus results in the mouse exiting + // the window. } break; } } @@ -1447,8 +1453,6 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (mb.is_valid()) { gui.key_event_accepted = false; - Control *over = nullptr; - Point2 mpos = mb->get_position(); gui.last_mouse_pos = mpos; if (mb->is_pressed()) { @@ -1594,6 +1598,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { // 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. + Control *over = nullptr; if (gui.mouse_focus) { over = gui.mouse_focus; } else { @@ -1601,10 +1606,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { } if (gui.mouse_focus_mask == MouseButton::NONE && over != gui.mouse_over) { - if (gui.mouse_over) { - _gui_call_notification(gui.mouse_over, Control::NOTIFICATION_MOUSE_EXIT); - } - + _drop_mouse_over(); _gui_cancel_tooltip(); if (over) { @@ -1625,8 +1627,6 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { gui.last_mouse_pos = mpos; - Control *over = nullptr; - // Drag & drop. if (!gui.drag_attempted && gui.mouse_focus && (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) { gui.drag_accum += mm->get_relative(); @@ -1674,29 +1674,23 @@ void Viewport::_gui_input_event(Ref<InputEvent> 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. + Control *over = nullptr; if (gui.mouse_focus) { over = gui.mouse_focus; - } else { + } else if (gui.mouse_in_window) { over = gui_find_control(mpos); } if (over != gui.mouse_over) { - if (gui.mouse_over) { - _gui_call_notification(gui.mouse_over, Control::NOTIFICATION_MOUSE_EXIT); - } - + _drop_mouse_over(); _gui_cancel_tooltip(); if (over) { _gui_call_notification(over, Control::NOTIFICATION_MOUSE_ENTER); + gui.mouse_over = over; } } - gui.mouse_over = over; - DisplayServer::CursorShape ds_cursor_shape = (DisplayServer::CursorShape)Input::get_singleton()->get_default_cursor_shape(); if (over) { @@ -2183,6 +2177,13 @@ void Viewport::_gui_accept_event() { } } +void Viewport::_drop_mouse_over() { + if (gui.mouse_over) { + _gui_call_notification(gui.mouse_over, Control::NOTIFICATION_MOUSE_EXIT); + gui.mouse_over = nullptr; + } +} + void Viewport::_drop_mouse_focus() { Control *c = gui.mouse_focus; MouseButton mask = gui.mouse_focus_mask; |