Fix differences between Windows and linuxbsd Display Server

Fix that Windows receive WINDOW_EVENT_MOUSE_EXIT on startup.

When moving the mouse cursor from one window to a different one, make sure that the first window receives the WINDOW_EVENT_MOUSE_EXIT event before the second window receives the WINDOW_EVENT_MOUSE_ENTER event.

Send Mouse-Move events also for Windows, that are currently not focused.

For determining the currently hovered window, consider not just the currently focused window, but also other windows.

Send mouse move events to focused window instead of hovered window.
This commit is contained in:
Markus Sauermann 2022-10-26 11:37:45 +02:00
parent 9ffa86357d
commit 4bd601d82a
2 changed files with 35 additions and 13 deletions

View file

@ -2444,10 +2444,12 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
return 0; // Jump back.
}
case WM_MOUSELEAVE: {
old_invalid = true;
windows[window_id].mouse_outside = true;
if (window_mouseover_id == window_id) {
old_invalid = true;
window_mouseover_id = INVALID_WINDOW_ID;
_send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_EXIT);
_send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_EXIT);
}
} break;
case WM_INPUT: {
@ -2678,17 +2680,21 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
}
if (windows[window_id].mouse_outside) {
if (window_mouseover_id != window_id) {
// Mouse enter.
if (mouse_mode != MOUSE_MODE_CAPTURED) {
if (window_mouseover_id != INVALID_WINDOW_ID) {
// Leave previous window.
_send_window_event(windows[window_mouseover_id], WINDOW_EVENT_MOUSE_EXIT);
}
_send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_ENTER);
}
CursorShape c = cursor_shape;
cursor_shape = CURSOR_MAX;
cursor_set_shape(c);
windows[window_id].mouse_outside = false;
window_mouseover_id = window_id;
// Once-off notification, must call again.
track_mouse_leave_event(hWnd);
@ -2779,17 +2785,29 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
}
if (windows[window_id].mouse_outside) {
DisplayServer::WindowID over_id = get_window_at_screen_position(mouse_get_position());
if (!Rect2(window_get_position(over_id), Point2(windows[over_id].width, windows[over_id].height)).has_point(mouse_get_position())) {
// Don't consider the windowborder as part of the window.
over_id = INVALID_WINDOW_ID;
}
if (window_mouseover_id != over_id) {
// Mouse enter.
if (mouse_mode != MOUSE_MODE_CAPTURED) {
_send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_ENTER);
if (window_mouseover_id != INVALID_WINDOW_ID) {
// Leave previous window.
_send_window_event(windows[window_mouseover_id], WINDOW_EVENT_MOUSE_EXIT);
}
if (over_id != INVALID_WINDOW_ID) {
_send_window_event(windows[over_id], WINDOW_EVENT_MOUSE_ENTER);
}
}
CursorShape c = cursor_shape;
cursor_shape = CURSOR_MAX;
cursor_set_shape(c);
windows[window_id].mouse_outside = false;
window_mouseover_id = over_id;
// Once-off notification, must call again.
track_mouse_leave_event(hWnd);
@ -2800,9 +2818,13 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
break;
}
DisplayServer::WindowID receiving_window_id = _get_focused_window_or_popup();
if (receiving_window_id == INVALID_WINDOW_ID) {
receiving_window_id = window_id;
}
Ref<InputEventMouseMotion> mm;
mm.instantiate();
mm->set_window_id(window_id);
mm->set_window_id(receiving_window_id);
mm->set_ctrl_pressed((wParam & MK_CONTROL) != 0);
mm->set_shift_pressed((wParam & MK_SHIFT) != 0);
mm->set_alt_pressed(alt_mem);
@ -2859,9 +2881,8 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
mm->set_relative(Vector2(mm->get_position() - Vector2(old_x, old_y)));
old_x = mm->get_position().x;
old_y = mm->get_position().y;
if (windows[window_id].window_has_focus || window_get_active_popup() == window_id) {
Input::get_singleton()->parse_input_event(mm);
}
Input::get_singleton()->parse_input_event(mm);
} break;
case WM_LBUTTONDOWN:

View file

@ -323,6 +323,8 @@ class DisplayServerWindows : public DisplayServer {
LPARAM lParam;
};
WindowID window_mouseover_id = INVALID_WINDOW_ID;
KeyEvent key_event_buffer[KEY_EVENT_BUFFER_SIZE];
int key_event_pos;
@ -398,7 +400,6 @@ class DisplayServerWindows : public DisplayServer {
Size2 window_rect;
Point2 last_pos;
bool mouse_outside = true;
ObjectID instance_id;