From 238508fc0a7ba48b5cf6f987830ce666ea06157a Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 26 Apr 2018 08:31:52 +0530 Subject: [PATCH] Update glfw from upstream Proper cross-platform fix for issue of mouse cursor not being restored over un-focused windows. --- glfw/cocoa_window.m | 50 +++++++++------- glfw/glfw.py | 4 +- glfw/glfw3.h | 4 +- glfw/init.c | 56 ++++++++---------- glfw/input.c | 6 +- glfw/win32_platform.h | 2 + glfw/win32_window.c | 130 +++++++++++++++++++++++------------------- glfw/x11_init.c | 53 ++++++++++++----- glfw/x11_platform.h | 11 ++-- glfw/x11_window.c | 118 +++++++++++++++++++++----------------- 10 files changed, 241 insertions(+), 193 deletions(-) diff --git a/glfw/cocoa_window.m b/glfw/cocoa_window.m index decd437db..e9b16daf5 100644 --- a/glfw/cocoa_window.m +++ b/glfw/cocoa_window.m @@ -128,6 +128,32 @@ static void updateCursorImage(_GLFWwindow* window) hideCursor(window); } +// Apply chosen cursor mode to a focused window +// +static void updateCursorMode(_GLFWwindow* window) +{ + if (window->cursorMode == GLFW_CURSOR_DISABLED) + { + _glfw.ns.disabledCursorWindow = window; + _glfwPlatformGetCursorPos(window, + &_glfw.ns.restoreCursorPosX, + &_glfw.ns.restoreCursorPosY); + centerCursor(window); + CGAssociateMouseAndMouseCursorPosition(false); + } + else if (_glfw.ns.disabledCursorWindow == window) + { + _glfw.ns.disabledCursorWindow = NULL; + CGAssociateMouseAndMouseCursorPosition(true); + _glfwPlatformSetCursorPos(window, + _glfw.ns.restoreCursorPosX, + _glfw.ns.restoreCursorPosY); + } + + if (cursorInClientArea(window)) + updateCursorImage(window); +} + // Transforms the specified y-coordinate between the CG display and NS screen // coordinate systems // @@ -423,7 +449,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; centerCursor(window); _glfwInputWindowFocus(window, GLFW_TRUE); - _glfwPlatformSetCursorMode(window, window->cursorMode); + updateCursorMode(window); } - (void)windowDidResignKey:(NSNotification *)notification @@ -1813,26 +1839,8 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) { - if (mode == GLFW_CURSOR_DISABLED) - { - _glfw.ns.disabledCursorWindow = window; - _glfwPlatformGetCursorPos(window, - &_glfw.ns.restoreCursorPosX, - &_glfw.ns.restoreCursorPosY); - centerCursor(window); - CGAssociateMouseAndMouseCursorPosition(false); - } - else if (_glfw.ns.disabledCursorWindow == window) - { - _glfw.ns.disabledCursorWindow = NULL; - CGAssociateMouseAndMouseCursorPosition(true); - _glfwPlatformSetCursorPos(window, - _glfw.ns.restoreCursorPosX, - _glfw.ns.restoreCursorPosY); - } - - if (cursorInClientArea(window)) - updateCursorImage(window); + if (_glfwPlatformWindowFocused(window)) + updateCursorMode(window); } const char* _glfwPlatformGetScancodeName(int scancode) diff --git a/glfw/glfw.py b/glfw/glfw.py index 7446dff6c..b37de3286 100755 --- a/glfw/glfw.py +++ b/glfw/glfw.py @@ -50,7 +50,7 @@ def init_env(env, pkg_config, at_least_version, module='x11'): at_least_version('xkbcommon', 0, 5) if module == 'x11': - for dep in 'x11 xrandr xinerama xcursor xkbcommon xkbcommon-x11'.split(): + for dep in 'x11 xrandr xinerama xcursor xkbcommon xkbcommon-x11 x11-xcb'.split(): ans.cflags.extend(pkg_config(dep, '--cflags-only-I')) ans.ldpaths.extend(pkg_config(dep, '--libs')) @@ -101,7 +101,7 @@ def collect_source_information(): ).group(1).strip().split() ) - wayland_protocols = re.search('WaylandProtocols\s+(\S+)\s+', mraw).group(1) + wayland_protocols = re.search(r'WaylandProtocols\s+(\S+)\s+', mraw).group(1) wayland_protocols = list(map(int, wayland_protocols.split('.'))) ans = { 'common': dict(extract_sources('common')), diff --git a/glfw/glfw3.h b/glfw/glfw3.h index 6aea7ddca..8e1df2f32 100644 --- a/glfw/glfw3.h +++ b/glfw/glfw3.h @@ -4582,7 +4582,7 @@ GLFWAPI const char* glfwGetJoystickGUID(int jid); * This function may be called from the joystick callback, even for a joystick * that is being disconnected. * - * @param[in] joystick The joystick whose pointer to set. + * @param[in] jid The joystick whose pointer to set. * @param[in] pointer The new value. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. @@ -4607,7 +4607,7 @@ GLFWAPI void glfwSetJoystickUserPointer(int jid, void* pointer); * This function may be called from the joystick callback, even for a joystick * that is being disconnected. * - * @param[in] joystick The joystick whose pointer to return. + * @param[in] jid The joystick whose pointer to return. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * diff --git a/glfw/init.c b/glfw/init.c index 4ed929511..9e670d423 100644 --- a/glfw/init.c +++ b/glfw/init.c @@ -57,37 +57,6 @@ static _GLFWinitconfig _glfwInitHints = } }; -// Returns a generic string representation of the specified error -// -static const char* getErrorString(int code) -{ - switch (code) - { - case GLFW_NOT_INITIALIZED: - return "The GLFW library is not initialized"; - case GLFW_NO_CURRENT_CONTEXT: - return "There is no current context"; - case GLFW_INVALID_ENUM: - return "Invalid argument for enum parameter"; - case GLFW_INVALID_VALUE: - return "Invalid value for parameter"; - case GLFW_OUT_OF_MEMORY: - return "Out of memory"; - case GLFW_API_UNAVAILABLE: - return "The requested API is unavailable"; - case GLFW_VERSION_UNAVAILABLE: - return "The requested API version is unavailable"; - case GLFW_PLATFORM_ERROR: - return "An undocumented platform-specific error occurred"; - case GLFW_FORMAT_UNAVAILABLE: - return "The requested format is unavailable"; - case GLFW_NO_WINDOW_CONTEXT: - return "The specified window has no context"; - default: - return "ERROR: UNKNOWN GLFW ERROR"; - } -} - // Terminate the library // static void terminate(void) @@ -173,7 +142,30 @@ void _glfwInputError(int code, const char* format, ...) description[sizeof(description) - 1] = '\0'; } else - strcpy(description, getErrorString(code)); + { + if (code == GLFW_NOT_INITIALIZED) + strcpy(description, "The GLFW library is not initialized"); + else if (code == GLFW_NO_CURRENT_CONTEXT) + strcpy(description, "There is no current context"); + else if (code == GLFW_INVALID_ENUM) + strcpy(description, "Invalid argument for enum parameter"); + else if (code == GLFW_INVALID_VALUE) + strcpy(description, "Invalid value for parameter"); + else if (code == GLFW_OUT_OF_MEMORY) + strcpy(description, "Out of memory"); + else if (code == GLFW_API_UNAVAILABLE) + strcpy(description, "The requested API is unavailable"); + else if (code == GLFW_VERSION_UNAVAILABLE) + strcpy(description, "The requested API version is unavailable"); + else if (code == GLFW_PLATFORM_ERROR) + strcpy(description, "A platform-specific error occurred"); + else if (code == GLFW_FORMAT_UNAVAILABLE) + strcpy(description, "The requested format is unavailable"); + else if (code == GLFW_NO_WINDOW_CONTEXT) + strcpy(description, "The specified window has no context"); + else + strcpy(description, "ERROR: UNKNOWN GLFW ERROR"); + } if (_glfw.initialized) { diff --git a/glfw/input.c b/glfw/input.c index 0a1b1f0f8..2d48810ac 100644 --- a/glfw/input.c +++ b/glfw/input.c @@ -619,11 +619,7 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value) _glfwPlatformGetCursorPos(window, &window->virtualCursorPosX, &window->virtualCursorPosY); - -#ifdef __APPLE__ - if (_glfwPlatformWindowFocused(window)) -#endif - _glfwPlatformSetCursorMode(window, value); + _glfwPlatformSetCursorMode(window, value); } else if (mode == GLFW_STICKY_KEYS) { diff --git a/glfw/win32_platform.h b/glfw/win32_platform.h index 607ac13ae..9a669215f 100644 --- a/glfw/win32_platform.h +++ b/glfw/win32_platform.h @@ -120,6 +120,8 @@ typedef struct HRGN hRgnBlur; BOOL fTransitionOnMaximized; } DWM_BLURBEHIND; +#else + #include #endif /*Windows Vista*/ #ifndef DPI_ENUMS_DECLARED diff --git a/glfw/win32_window.c b/glfw/win32_window.c index 9dfe94ff6..3480d1149 100644 --- a/glfw/win32_window.c +++ b/glfw/win32_window.c @@ -235,26 +235,6 @@ static void centerCursor(_GLFWwindow* window) _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0); } -// Returns whether the cursor is in the client area of the specified window -// -static GLFWbool cursorInClientArea(_GLFWwindow* window) -{ - RECT area; - POINT pos; - - if (!GetCursorPos(&pos)) - return GLFW_FALSE; - - if (WindowFromPoint(pos) != window->win32.handle) - return GLFW_FALSE; - - GetClientRect(window->win32.handle, &area); - ClientToScreen(window->win32.handle, (POINT*) &area.left); - ClientToScreen(window->win32.handle, (POINT*) &area.right); - - return PtInRect(&area, pos); -} - // Updates the cursor image according to its cursor mode // static void updateCursorImage(_GLFWwindow* window) @@ -286,6 +266,67 @@ static void updateClipRect(_GLFWwindow* window) ClipCursor(NULL); } +// Apply disabled cursor mode to a focused window +// +static void disableCursor(_GLFWwindow* window) +{ + const RAWINPUTDEVICE rid = { 0x01, 0x02, 0, window->win32.handle }; + + _glfw.win32.disabledCursorWindow = window; + _glfwPlatformGetCursorPos(window, + &_glfw.win32.restoreCursorPosX, + &_glfw.win32.restoreCursorPosY); + updateCursorImage(window); + centerCursor(window); + updateClipRect(window); + + if (!RegisterRawInputDevices(&rid, 1, sizeof(rid))) + { + _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, + "Win32: Failed to register raw input device"); + } +} + +// Exit disabled cursor mode for the specified window +// +static void enableCursor(_GLFWwindow* window) +{ + const RAWINPUTDEVICE rid = { 0x01, 0x02, RIDEV_REMOVE, NULL }; + + _glfw.win32.disabledCursorWindow = NULL; + updateClipRect(NULL); + _glfwPlatformSetCursorPos(window, + _glfw.win32.restoreCursorPosX, + _glfw.win32.restoreCursorPosY); + updateCursorImage(window); + + if (!RegisterRawInputDevices(&rid, 1, sizeof(rid))) + { + _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, + "Win32: Failed to remove raw input device"); + } +} + +// Returns whether the cursor is in the client area of the specified window +// +static GLFWbool cursorInClientArea(_GLFWwindow* window) +{ + RECT area; + POINT pos; + + if (!GetCursorPos(&pos)) + return GLFW_FALSE; + + if (WindowFromPoint(pos) != window->win32.handle) + return GLFW_FALSE; + + GetClientRect(window->win32.handle, &area); + ClientToScreen(window->win32.handle, (POINT*) &area.left); + ClientToScreen(window->win32.handle, (POINT*) &area.right); + + return PtInRect(&area, pos); +} + // Update native window styles to match attributes // static void updateWindowStyles(const _GLFWwindow* window) @@ -575,7 +616,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, if (lParam == 0 && window->win32.frameAction) { if (window->cursorMode == GLFW_CURSOR_DISABLED) - _glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED); + disableCursor(window); window->win32.frameAction = GLFW_FALSE; } @@ -593,7 +634,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, break; if (window->cursorMode == GLFW_CURSOR_DISABLED) - _glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED); + disableCursor(window); return 0; } @@ -601,7 +642,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, case WM_KILLFOCUS: { if (window->cursorMode == GLFW_CURSOR_DISABLED) - _glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL); + enableCursor(window); if (window->monitor && window->autoIconify) _glfwPlatformIconifyWindow(window); @@ -857,10 +898,10 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, case WM_ENTERSIZEMOVE: case WM_ENTERMENULOOP: { - // HACK: Postpone cursor disabling while the user is moving or - // resizing the window or using the menu + // HACK: Enable the cursor while the user is moving or + // resizing the window or using the window menu if (window->cursorMode == GLFW_CURSOR_DISABLED) - _glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL); + enableCursor(window); break; } @@ -871,7 +912,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, // HACK: Disable the cursor once the user is done moving or // resizing the window or using the menu if (window->cursorMode == GLFW_CURSOR_DISABLED) - _glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED); + disableCursor(window); break; } @@ -1777,39 +1818,12 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) { if (mode == GLFW_CURSOR_DISABLED) { - const RAWINPUTDEVICE rid = { 0x01, 0x02, 0, window->win32.handle }; - - _glfw.win32.disabledCursorWindow = window; - _glfwPlatformGetCursorPos(window, - &_glfw.win32.restoreCursorPosX, - &_glfw.win32.restoreCursorPosY); - centerCursor(window); - updateClipRect(window); - - if (!RegisterRawInputDevices(&rid, 1, sizeof(rid))) - { - _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, - "Win32: Failed to register raw input device"); - } + if (_glfwPlatformWindowFocused(window)) + disableCursor(window); } else if (_glfw.win32.disabledCursorWindow == window) - { - const RAWINPUTDEVICE rid = { 0x01, 0x02, RIDEV_REMOVE, NULL }; - - _glfw.win32.disabledCursorWindow = NULL; - updateClipRect(NULL); - _glfwPlatformSetCursorPos(window, - _glfw.win32.restoreCursorPosX, - _glfw.win32.restoreCursorPosY); - - if (!RegisterRawInputDevices(&rid, 1, sizeof(rid))) - { - _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, - "Win32: Failed to remove raw input device"); - } - } - - if (cursorInClientArea(window)) + enableCursor(window); + else if (cursorInClientArea(window)) updateCursorImage(window); } diff --git a/glfw/x11_init.c b/glfw/x11_init.c index cde6569d7..89fcb7d4c 100644 --- a/glfw/x11_init.c +++ b/glfw/x11_init.c @@ -166,7 +166,11 @@ static GLFWbool initExtensions(void) &_glfw.x11.vidmode.errorBase); } +#if defined(__CYGWIN__) + _glfw.x11.xi.handle = _glfw_dlopen("libXi-6.so"); +#else _glfw.x11.xi.handle = _glfw_dlopen("libXi.so.6"); +#endif if (_glfw.x11.xi.handle) { _glfw.x11.xi.QueryVersion = (PFN_XIQueryVersion) @@ -192,7 +196,11 @@ static GLFWbool initExtensions(void) } } +#if defined(__CYGWIN__) + _glfw.x11.randr.handle = _glfw_dlopen("libXrandr-2.so"); +#else _glfw.x11.randr.handle = _glfw_dlopen("libXrandr.so.2"); +#endif if (_glfw.x11.randr.handle) { _glfw.x11.randr.AllocGamma = (PFN_XRRAllocGamma) @@ -280,7 +288,11 @@ static GLFWbool initExtensions(void) RROutputChangeNotifyMask); } +#if defined(__CYGWIN__) + _glfw.x11.xcursor.handle = _glfw_dlopen("libXcursor-1.so"); +#else _glfw.x11.xcursor.handle = _glfw_dlopen("libXcursor.so.1"); +#endif if (_glfw.x11.xcursor.handle) { _glfw.x11.xcursor.ImageCreate = (PFN_XcursorImageCreate) @@ -291,7 +303,11 @@ static GLFWbool initExtensions(void) _glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageLoadCursor"); } +#if defined(__CYGWIN__) + _glfw.x11.xinerama.handle = _glfw_dlopen("libXinerama-1.so"); +#else _glfw.x11.xinerama.handle = _glfw_dlopen("libXinerama.so.1"); +#endif if (_glfw.x11.xinerama.handle) { _glfw.x11.xinerama.IsActive = (PFN_XineramaIsActive) @@ -310,16 +326,11 @@ static GLFWbool initExtensions(void) } } - _glfw.x11.x11xcb.handle = _glfw_dlopen("libX11-xcb.so.1"); - if (!_glfw.x11.x11xcb.handle) - { - _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to load libX11-xcb"); - return GLFW_FALSE; - } - _glfw.x11.x11xcb.GetXCBConnection = (PFN_XGetXCBConnection) - _glfw_dlsym(_glfw.x11.x11xcb.handle, "XGetXCBConnection"); - +#if defined(__CYGWIN__) + _glfw.x11.xrender.handle = _glfw_dlopen("libXrender-1.so"); +#else _glfw.x11.xrender.handle = _glfw_dlopen("libXrender.so.1"); +#endif if (_glfw.x11.xrender.handle) { _glfw.x11.xrender.QueryExtension = (PFN_XRenderQueryExtension) @@ -659,12 +670,6 @@ void _glfwPlatformTerminate(void) _glfw.x11.display = NULL; } - if (_glfw.x11.x11xcb.handle) - { - _glfw_dlclose(_glfw.x11.x11xcb.handle); - _glfw.x11.x11xcb.handle = NULL; - } - if (_glfw.x11.xcursor.handle) { _glfw_dlclose(_glfw.x11.xcursor.handle); @@ -683,6 +688,24 @@ void _glfwPlatformTerminate(void) _glfw.x11.xinerama.handle = NULL; } + if (_glfw.x11.xrender.handle) + { + _glfw_dlclose(_glfw.x11.xrender.handle); + _glfw.x11.xrender.handle = NULL; + } + + if (_glfw.x11.vidmode.handle) + { + _glfw_dlclose(_glfw.x11.vidmode.handle); + _glfw.x11.vidmode.handle = NULL; + } + + if (_glfw.x11.xi.handle) + { + _glfw_dlclose(_glfw.x11.xi.handle); + _glfw.x11.xi.handle = NULL; + } + // NOTE: These need to be unloaded after XCloseDisplay, as they register // cleanup callbacks that get called by that function _glfwTerminateEGL(); diff --git a/glfw/x11_platform.h b/glfw/x11_platform.h index 64177170e..05ac35dcf 100644 --- a/glfw/x11_platform.h +++ b/glfw/x11_platform.h @@ -35,6 +35,9 @@ #include #include +// The xcb library is needed to work with libxkb +#include + // The XRandR extension provides mode setting and gamma control #include @@ -47,6 +50,7 @@ // The XInput extension provides raw mouse motion input #include +// The libxkb library is used for improved keyboard support #include "xkb_glfw.h" typedef XRRCrtcGamma* (* PFN_XRRAllocGamma)(int); @@ -99,8 +103,6 @@ typedef XineramaScreenInfo* (* PFN_XineramaQueryScreens)(Display*,int*); #define XineramaQueryScreens _glfw.x11.xinerama.QueryScreens typedef struct xcb_connection_t xcb_connection_t; -typedef xcb_connection_t* (* PFN_XGetXCBConnection)(Display*); -#define XGetXCBConnection _glfw.x11.x11xcb.GetXCBConnection typedef Bool (* PFN_XF86VidModeQueryExtension)(Display*,int*,int*); typedef Bool (* PFN_XF86VidModeGetGammaRamp)(Display*,int,int,unsigned short*,unsigned short*,unsigned short*); @@ -341,11 +343,6 @@ typedef struct _GLFWlibraryX11 PFN_XineramaQueryScreens QueryScreens; } xinerama; - struct { - void* handle; - PFN_XGetXCBConnection GetXCBConnection; - } x11xcb; - struct { GLFWbool available; void* handle; diff --git a/glfw/x11_window.c b/glfw/x11_window.c index 47f68bd27..63ad189fd 100644 --- a/glfw/x11_window.c +++ b/glfw/x11_window.c @@ -535,6 +535,61 @@ static void updateCursorImage(_GLFWwindow* window) } } +// Apply disabled cursor mode to a focused window +// +static void disableCursor(_GLFWwindow* window) +{ + if (_glfw.x11.xi.available) + { + XIEventMask em; + unsigned char mask[XIMaskLen(XI_RawMotion)] = { 0 }; + + em.deviceid = XIAllMasterDevices; + em.mask_len = sizeof(mask); + em.mask = mask; + XISetMask(mask, XI_RawMotion); + + XISelectEvents(_glfw.x11.display, _glfw.x11.root, &em, 1); + } + + _glfw.x11.disabledCursorWindow = window; + _glfwPlatformGetCursorPos(window, + &_glfw.x11.restoreCursorPosX, + &_glfw.x11.restoreCursorPosY); + updateCursorImage(window); + centerCursor(window); + XGrabPointer(_glfw.x11.display, window->x11.handle, True, + ButtonPressMask | ButtonReleaseMask | PointerMotionMask, + GrabModeAsync, GrabModeAsync, + window->x11.handle, + _glfw.x11.hiddenCursorHandle, + CurrentTime); +} + +// Exit disabled cursor mode for the specified window +// +static void enableCursor(_GLFWwindow* window) +{ + if (_glfw.x11.xi.available) + { + XIEventMask em; + unsigned char mask[] = { 0 }; + + em.deviceid = XIAllMasterDevices; + em.mask_len = sizeof(mask); + em.mask = mask; + + XISelectEvents(_glfw.x11.display, _glfw.x11.root, &em, 1); + } + + _glfw.x11.disabledCursorWindow = NULL; + XUngrabPointer(_glfw.x11.display, CurrentTime); + _glfwPlatformSetCursorPos(window, + _glfw.x11.restoreCursorPosX, + _glfw.x11.restoreCursorPosY); + updateCursorImage(window); +} + // Create the X11 window (and its colormap) // static GLFWbool createNativeWindow(_GLFWwindow* window, @@ -1306,7 +1361,7 @@ static void processEvent(XEvent *event) // HACK: This is a workaround for WMs (KWM, Fluxbox) that otherwise // ignore the defined cursor for hidden cursor mode if (window->cursorMode == GLFW_CURSOR_HIDDEN) - _glfwPlatformSetCursorMode(window, GLFW_CURSOR_HIDDEN); + updateCursorImage(window); _glfwInputCursorEnter(window, GLFW_TRUE); return; @@ -1599,7 +1654,7 @@ static void processEvent(XEvent *event) case FocusIn: { if (window->cursorMode == GLFW_CURSOR_DISABLED) - _glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED); + disableCursor(window); if (event->xfocus.mode == NotifyGrab || event->xfocus.mode == NotifyUngrab) @@ -1616,7 +1671,7 @@ static void processEvent(XEvent *event) case FocusOut: { if (window->cursorMode == GLFW_CURSOR_DISABLED) - _glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL); + enableCursor(window); if (event->xfocus.mode == NotifyGrab || event->xfocus.mode == NotifyUngrab) @@ -2575,53 +2630,14 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) { if (mode == GLFW_CURSOR_DISABLED) { - if (_glfw.x11.xi.available) - { - XIEventMask em; - unsigned char mask[XIMaskLen(XI_RawMotion)] = { 0 }; - - em.deviceid = XIAllMasterDevices; - em.mask_len = sizeof(mask); - em.mask = mask; - XISetMask(mask, XI_RawMotion); - - XISelectEvents(_glfw.x11.display, _glfw.x11.root, &em, 1); - } - - _glfw.x11.disabledCursorWindow = window; - _glfwPlatformGetCursorPos(window, - &_glfw.x11.restoreCursorPosX, - &_glfw.x11.restoreCursorPosY); - centerCursor(window); - XGrabPointer(_glfw.x11.display, window->x11.handle, True, - ButtonPressMask | ButtonReleaseMask | PointerMotionMask, - GrabModeAsync, GrabModeAsync, - window->x11.handle, - _glfw.x11.hiddenCursorHandle, - CurrentTime); + if (_glfwPlatformWindowFocused(window)) + disableCursor(window); } else if (_glfw.x11.disabledCursorWindow == window) - { - if (_glfw.x11.xi.available) - { - XIEventMask em; - unsigned char mask[] = { 0 }; + enableCursor(window); + else + updateCursorImage(window); - em.deviceid = XIAllMasterDevices; - em.mask_len = sizeof(mask); - em.mask = mask; - - XISelectEvents(_glfw.x11.display, _glfw.x11.root, &em, 1); - } - - _glfw.x11.disabledCursorWindow = NULL; - XUngrabPointer(_glfw.x11.display, CurrentTime); - _glfwPlatformSetCursorPos(window, - _glfw.x11.restoreCursorPosX, - _glfw.x11.restoreCursorPosY); - } - - updateCursorImage(window); XFlush(_glfw.x11.display); } @@ -2704,7 +2720,7 @@ void _glfwPlatformGetRequiredInstanceExtensions(char** extensions) if (!_glfw.vk.KHR_surface) return; - if (!_glfw.vk.KHR_xcb_surface || !_glfw.x11.x11xcb.handle) + if (!_glfw.vk.KHR_xcb_surface) { if (!_glfw.vk.KHR_xlib_surface) return; @@ -2714,7 +2730,7 @@ void _glfwPlatformGetRequiredInstanceExtensions(char** extensions) // NOTE: VK_KHR_xcb_surface is preferred due to some early ICDs exposing but // not correctly implementing VK_KHR_xlib_surface - if (_glfw.vk.KHR_xcb_surface && _glfw.x11.x11xcb.handle) + if (_glfw.vk.KHR_xcb_surface) extensions[1] = "VK_KHR_xcb_surface"; else extensions[1] = "VK_KHR_xlib_surface"; @@ -2727,7 +2743,7 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, VisualID visualID = XVisualIDFromVisual(DefaultVisual(_glfw.x11.display, _glfw.x11.screen)); - if (_glfw.vk.KHR_xcb_surface && _glfw.x11.x11xcb.handle) + if (_glfw.vk.KHR_xcb_surface) { PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR vkGetPhysicalDeviceXcbPresentationSupportKHR = @@ -2778,7 +2794,7 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface) { - if (_glfw.vk.KHR_xcb_surface && _glfw.x11.x11xcb.handle) + if (_glfw.vk.KHR_xcb_surface) { VkResult err; VkXcbSurfaceCreateInfoKHR sci;