Fix captured mouse mode

This commit is contained in:
Hendrik Brucker 2022-02-01 03:49:51 +01:00
parent 2c85f2a8f6
commit c058361a23
5 changed files with 27 additions and 15 deletions

View File

@ -323,20 +323,21 @@ void DisplayServerX11::mouse_set_mode(MouseMode p_mode) {
if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) {
//flush pending motion events
_flush_mouse_motion();
WindowData &main_window = windows[MAIN_WINDOW_ID];
WindowID window_id = windows.has(last_focused_window) ? last_focused_window : MAIN_WINDOW_ID;
WindowData &window = windows[window_id];
if (XGrabPointer(
x11_display, main_window.x11_window, True,
x11_display, window.x11_window, True,
ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
GrabModeAsync, GrabModeAsync, windows[MAIN_WINDOW_ID].x11_window, None, CurrentTime) != GrabSuccess) {
GrabModeAsync, GrabModeAsync, window.x11_window, None, CurrentTime) != GrabSuccess) {
ERR_PRINT("NO GRAB");
}
if (mouse_mode == MOUSE_MODE_CAPTURED) {
center.x = main_window.size.width / 2;
center.y = main_window.size.height / 2;
center.x = window.size.width / 2;
center.y = window.size.height / 2;
XWarpPointer(x11_display, None, main_window.x11_window,
XWarpPointer(x11_display, None, window.x11_window,
0, 0, 0, 0, (int)center.x, (int)center.y);
Input::get_singleton()->set_mouse_position(center);
@ -358,7 +359,8 @@ void DisplayServerX11::mouse_warp_to_position(const Point2i &p_to) {
if (mouse_mode == MOUSE_MODE_CAPTURED) {
last_mouse_pos = p_to;
} else {
XWarpPointer(x11_display, None, windows[MAIN_WINDOW_ID].x11_window,
WindowID window_id = windows.has(last_focused_window) ? last_focused_window : MAIN_WINDOW_ID;
XWarpPointer(x11_display, None, windows[window_id].x11_window,
0, 0, 0, 0, (int)p_to.x, (int)p_to.y);
}
}
@ -3353,7 +3355,7 @@ void DisplayServerX11::process_events() {
DEBUG_LOG_X11("[%u] FocusIn window=%lu (%u), mode='%u' \n", frame, event.xfocus.window, window_id, event.xfocus.mode);
WindowData &wd = windows[window_id];
last_focused_window = window_id;
wd.focused = true;
if (wd.xic) {
@ -3553,9 +3555,9 @@ void DisplayServerX11::process_events() {
// The X11 API requires filtering one-by-one through the motion
// notify events, in order to figure out which event is the one
// generated by warping the mouse pointer.
WindowID focused_window_id = windows.has(last_focused_window) ? last_focused_window : MAIN_WINDOW_ID;
while (true) {
if (mouse_mode == MOUSE_MODE_CAPTURED && event.xmotion.x == windows[MAIN_WINDOW_ID].size.width / 2 && event.xmotion.y == windows[MAIN_WINDOW_ID].size.height / 2) {
if (mouse_mode == MOUSE_MODE_CAPTURED && event.xmotion.x == windows[focused_window_id].size.width / 2 && event.xmotion.y == windows[focused_window_id].size.height / 2) {
//this is likely the warp event since it was warped here
center = Vector2(event.xmotion.x, event.xmotion.y);
break;
@ -3630,9 +3632,8 @@ void DisplayServerX11::process_events() {
// Reset to prevent lingering motion
xi.relative_motion.x = 0;
xi.relative_motion.y = 0;
if (mouse_mode == MOUSE_MODE_CAPTURED) {
pos = Point2i(windows[MAIN_WINDOW_ID].size.width / 2, windows[MAIN_WINDOW_ID].size.height / 2);
pos = Point2i(windows[focused_window_id].size.width / 2, windows[focused_window_id].size.height / 2);
}
Ref<InputEventMouseMotion> mm;

View File

@ -151,6 +151,8 @@ class DisplayServerX11 : public DisplayServer {
Map<WindowID, WindowData> windows;
WindowID last_focused_window = INVALID_WINDOW_ID;
WindowID window_id_counter = MAIN_WINDOW_ID;
WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect);

View File

@ -145,6 +145,8 @@ public:
Map<WindowID, WindowData> windows;
WindowID last_focused_window = INVALID_WINDOW_ID;
WindowID window_id_counter = MAIN_WINDOW_ID;
WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, const Rect2i &p_rect);

View File

@ -321,6 +321,7 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
}
DS_OSX->window_focused = true;
DS_OSX->last_focused_window = window_id;
DS_OSX->_send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_IN);
}
@ -355,6 +356,7 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id];
DS_OSX->window_focused = true;
DS_OSX->last_focused_window = window_id;
DS_OSX->_send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_IN);
}
@ -1913,7 +1915,8 @@ void DisplayServerOSX::mouse_set_mode(MouseMode p_mode) {
return;
}
WindowData &wd = windows[MAIN_WINDOW_ID];
WindowID window_id = windows.has(last_focused_window) ? last_focused_window : MAIN_WINDOW_ID;
WindowData &wd = windows[window_id];
if (p_mode == MOUSE_MODE_CAPTURED) {
// Apple Docs state that the display parameter is not used.
// "This parameter is not used. By default, you may pass kCGDirectMainDisplay."
@ -1972,7 +1975,8 @@ void DisplayServerOSX::mouse_warp_to_position(const Point2i &p_to) {
if (mouse_mode == MOUSE_MODE_CAPTURED) {
last_mouse_pos = p_to;
} else {
WindowData &wd = windows[MAIN_WINDOW_ID];
WindowID window_id = windows.has(last_focused_window) ? last_focused_window : MAIN_WINDOW_ID;
WindowData &wd = windows[window_id];
//local point in window coords
const NSRect contentRect = [wd.window_view frame];

View File

@ -97,7 +97,10 @@ String DisplayServerWindows::get_name() const {
void DisplayServerWindows::_set_mouse_mode_impl(MouseMode p_mode) {
if (windows.has(MAIN_WINDOW_ID) && (p_mode == MOUSE_MODE_CAPTURED || p_mode == MOUSE_MODE_CONFINED || p_mode == MOUSE_MODE_CONFINED_HIDDEN)) {
// Mouse is grabbed (captured or confined).
WindowData &wd = windows[MAIN_WINDOW_ID];
WindowID window_id = windows.has(last_focused_window) ? last_focused_window : MAIN_WINDOW_ID;
WindowData &wd = windows[window_id];
RECT clipRect;
GetClientRect(wd.hWnd, &clipRect);