|
@@ -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;
|