Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix unfocused windows can't be dragged #95606

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions platform/windows/display_server_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,12 @@ void DisplayServerWindows::_set_mouse_mode_impl(MouseMode p_mode) {
}
} else {
// Mouse is free to move around (not captured or confined).
ReleaseCapture();
// When the user is moving a window, it's important to not ReleaseCapture because it will cause
// the window movement to stop and if the user tries to move the Windows when it's not activated,
// it will prevent the window movement. It's probably impossible to move the Window while it's captured anyway.
if (!_has_moving_window()) {
ReleaseCapture();
}
ClipCursor(nullptr);

_register_raw_input_devices(INVALID_WINDOW_ID);
Expand Down Expand Up @@ -187,6 +192,15 @@ DisplayServer::WindowID DisplayServerWindows::_get_focused_window_or_popup() con
return last_focused_window;
}

bool DisplayServerWindows::_has_moving_window() const {
for (const KeyValue<WindowID, WindowData> &E : windows) {
if (E.value.move_timer_id) {
return true;
}
}
return false;
}

void DisplayServerWindows::_register_raw_input_devices(WindowID p_target_window) {
use_raw_input = true;

Expand Down Expand Up @@ -4912,6 +4926,9 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
case WM_EXITSIZEMOVE: {
KillTimer(windows[window_id].hWnd, windows[window_id].move_timer_id);
windows[window_id].move_timer_id = 0;
// Reset the correct mouse mode because we couldn't call ReleaseCapture in
// _set_mouse_mode_impl while in _process_activate_event (because the user was moving a window).
_set_mouse_mode_impl(mouse_mode);
} break;
case WM_TIMER: {
if (wParam == windows[window_id].move_timer_id) {
Expand Down Expand Up @@ -5137,7 +5154,13 @@ void DisplayServerWindows::_process_activate_event(WindowID p_window_id) {
Input::get_singleton()->release_pressed_events();
track_mouse_leave_event(wd.hWnd);
// Release capture unconditionally because it can be set due to dragging, in addition to captured mode.
ReleaseCapture();
// When the user is moving a window, it's important to not ReleaseCapture because it will cause
// the window movement to stop and if the user tries to move the Windows when it's not activated,
// it will prevent the window movement. If we are here and a window is moving, it's because we had multiple
// opened windows in the editor and we are definitively not in a middle of dragging.
if (!_has_moving_window()) {
ReleaseCapture();
}
wd.window_focused = false;
_send_window_event(wd, WINDOW_EVENT_FOCUS_OUT);
}
Expand Down
1 change: 1 addition & 0 deletions platform/windows/display_server_windows.h
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,7 @@ class DisplayServerWindows : public DisplayServer {
void _set_mouse_mode_impl(MouseMode p_mode);
WindowID _get_focused_window_or_popup() const;
void _register_raw_input_devices(WindowID p_target_window);
bool _has_moving_window() const;

void _process_activate_event(WindowID p_window_id);
void _process_key_events();
Expand Down
Loading