diff --git a/README.md b/README.md index 5f7045ab..382b5b5d 100644 --- a/README.md +++ b/README.md @@ -158,6 +158,8 @@ information on what to include when reporting a bug. per-joystick user pointers - Added `glfwGetX11SelectionString` and `glfwSetX11SelectionString` functions for accessing X11 primary selection (#894,#1056) +- Added `glfwRawMouseMotionSupported` function for querying raw motion support + (#125,#1400,#1401) - Added headless [OSMesa](http://mesa3d.org/osmesa.html) backend (#850) - Added definition of `GLAPIENTRY` to public header - Added `GLFW_TRANSPARENT_FRAMEBUFFER` window hint and attribute for controlling @@ -171,6 +173,8 @@ information on what to include when reporting a bug. (#676,#1115) - Added `GLFW_JOYSTICK_HAT_BUTTONS` init hint (#889) - Added `GLFW_LOCK_KEY_MODS` input mode and `GLFW_MOD_*_LOCK` mod bits (#946) +- Added `GLFW_RAW_MOUSE_MOTION` input mode for selecting raw motion input + (#125,#1400,#1401) - Added macOS specific `GLFW_COCOA_RETINA_FRAMEBUFFER` window hint - Added macOS specific `GLFW_COCOA_FRAME_NAME` window hint (#195) - Added macOS specific `GLFW_COCOA_GRAPHICS_SWITCHING` window hint (#377,#935) @@ -182,7 +186,6 @@ information on what to include when reporting a bug. - Added `GLFW_OSMESA_CONTEXT_API` for creating OpenGL contexts with [OSMesa](https://www.mesa3d.org/osmesa.html) (#281) - Added `GenerateMappings.cmake` script for updating gamepad mappings -- Added `GLFW_RAW_INPUT` input mode and `glfwRawInputSupported` function (#1401) - Made `glfwCreateWindowSurface` emit an error when the window has a context (#1194,#1205) - Deprecated window parameter of clipboard string functions @@ -203,7 +206,6 @@ information on what to include when reporting a bug. - Bugfix: The gamma ramp generated by `glfwSetGamma` did not use the monitor ramp size (#1387,#1388) - [Win32] Added system error strings to relevant GLFW error descriptions (#733) -- [Win32] Moved to `WM_INPUT` for disabled cursor mode motion input (#125) - [Win32] Removed XInput circular deadzone from joystick axis data (#1045) - [Win32] Bugfix: Undecorated windows could not be iconified by the user (#861) - [Win32] Bugfix: Deadzone logic could underflow with some controllers (#910) @@ -233,7 +235,6 @@ information on what to include when reporting a bug. - [Win32] Bugfix: A title bar would be drawn over undecorated windows in some circumstances (#1383) - [Win32] Bugfix: Standard cursors were not per-monitor DPI aware (#1431) -- [X11] Moved to XI2 `XI_RawMotion` for disable cursor mode motion input (#125) - [X11] Replaced `_GLFW_HAS_XF86VM` compile-time option with dynamic loading - [X11] Bugfix: `glfwGetVideoMode` would segfault on Cygwin/X - [X11] Bugfix: Dynamic X11 library loading did not use full sonames (#941) @@ -437,6 +438,7 @@ skills. - Cyril Pichard - Keith Pitt - Stanislav Podgorskiy + - Nathan Poirier - Alexandre Pretyman - przemekmirek - Philip Rideout @@ -490,7 +492,6 @@ skills. - Santi Zupancic - Jonas Ådahl - Lasse Öörni - - Nathan Poirier - All the unmentioned and anonymous contributors in the GLFW community, for bug reports, patches, feedback, testing and encouragement diff --git a/docs/input.dox b/docs/input.dox index 159fb454..a438a18e 100644 --- a/docs/input.dox +++ b/docs/input.dox @@ -233,7 +233,7 @@ arguments can always be passed unmodified to this function. @section input_mouse Mouse input -Mouse input comes in many forms, including cursor motion, button presses and +Mouse input comes in many forms, including mouse motion, button presses and scrolling offsets. The cursor appearance can also be changed, either to a custom image or a standard cursor shape from the system theme. @@ -308,6 +308,31 @@ glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); @endcode +@anchor GLFW_RAW_MOUSE_MOTION +@subsection raw_mouse_motion Raw mouse motion + +When the cursor is disabled, raw (unscaled and unaccelerated) mouse motion can +be enabled if available. + +Raw mouse motion is closer to the actual motion of the mouse across a surface. +It is not affected by the scaling and acceleration applied to the motion of the +desktop cursor. That processing is suitable for a cursor while raw motion is +better for controlling for example a 3D camera. Because of this, raw mouse +motion is only provided when the cursor is disabled. + +Call @ref glfwRawMouseMotionSupported to check if the current machine provides +raw motion and set the `GLFW_RAW_MOUSE_MOTION` input mode to enable it. It is +disabled by default. + +@code +if (glfwRawMouseMotionSupported()) + glfwSetInputMode(window, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE); +@endcode + +If supported, raw mouse motion can be enabled or disabled per-window and at any +time but it will only be provided when the cursor is disabled. + + @subsection cursor_object Cursor objects GLFW supports creating both custom and system theme cursor images, encapsulated diff --git a/docs/news.dox b/docs/news.dox index 43f384ea..65812e71 100644 --- a/docs/news.dox +++ b/docs/news.dox @@ -135,8 +135,10 @@ attribute corresponds to the [cursor enter/leave](@ref cursor_enter) event. @subsection news_33_rawmotion Support for raw mouse motion -GLFW now uses raw (unscaled and unaccelerated) mouse motion in disabled cursor -mode on platforms where this is available, specifically Windows and X11. +GLFW now supports raw (unscaled and unaccelerated) mouse motion in disabled +cursor mode with the [GLFW_RAW_MOUSE_MOTION](@ref GLFW_RAW_MOUSE_MOTION) input +mode. Call @ref glfwRawMouseMotionSupported to check if the current machine +supports raw mouse motion. @subsection news_33_moltenvk Support for Vulkan on macOS via MoltenVK diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 9c0eaa88..57d5c9c0 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -1002,7 +1002,7 @@ extern "C" { #define GLFW_STICKY_KEYS 0x00033002 #define GLFW_STICKY_MOUSE_BUTTONS 0x00033003 #define GLFW_LOCK_KEY_MODS 0x00033004 -#define GLFW_RAW_INPUT 0x00033005 +#define GLFW_RAW_MOUSE_MOTION 0x00033005 #define GLFW_CURSOR_NORMAL 0x00034001 #define GLFW_CURSOR_HIDDEN 0x00034002 @@ -3814,11 +3814,12 @@ GLFWAPI void glfwPostEmptyEvent(void); * This function returns the value of an input option for the specified window. * The mode must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS, * @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS or - * @ref GLFW_RAW_INPUT. + * @ref GLFW_RAW_MOUSE_MOTION. * * @param[in] window The window to query. * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`, - * `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS` or `GLFW_RAW_INPUT`. + * `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS` or + * `GLFW_RAW_MOUSE_MOTION`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_INVALID_ENUM. @@ -3838,7 +3839,7 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); * This function sets an input mode option for the specified window. The mode * must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS, * @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS or - * @ref GLFW_RAW_INPUT. + * @ref GLFW_RAW_MOUSE_MOTION. * * If the mode is `GLFW_CURSOR`, the value must be one of the following cursor * modes: @@ -3870,14 +3871,16 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); * GLFW_MOD_CAPS_LOCK bit set when the event was generated with Caps Lock on, * and the @ref GLFW_MOD_NUM_LOCK bit when Num Lock was on. * - * If the mode is `GLFW_RAW_INPUT`, the value must be either `GLFW_TRUE` to - * enable the use of raw input, or `GLFW_FALSE` to disable it. If enabled and - * supported by the machine, the program will retrieve high-definition mouse - * movement when cursor is grabbed. + * If the mode is `GLFW_RAW_MOUSE_MOTION`, the value must be either `GLFW_TRUE` + * to enable raw (unscaled and unaccelerated) mouse motion when the cursor is + * disabled, or `GLFW_FALSE` to disable it. If raw motion is not supported, + * attempting to set this will emit @ref GLFW_PLATFORM_ERROR. Call @ref + * glfwRawMouseMotionSupported to check for support. * * @param[in] window The window whose input mode to set. * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`, - * `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS` or `GLFW_RAW_INPUT`. + * `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS` or + * `GLFW_RAW_MOUSE_MOTION`. * @param[in] value The new value of the specified input mode. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref @@ -3893,37 +3896,34 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); */ GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value); -/*! @brief Returns whether the raw input is supported. +/*! @brief Returns whether raw mouse motion is supported. * - * This function returns whether the raw input is supported by the current - * machine. + * This function returns whether raw mouse motion is supported on the current + * system. This status does not change after GLFW has been initialized so you + * only need to check this once. If you attempt to enable raw motion on + * a system that does not support it, @ref GLFW_PLATFORM_ERROR will be emitted. * - * Raw input allow to retrieve high-definition movement from mouse. - * Input from a high-definition mouse is much more precise than that from a - * standard mouse. But often, they cannot be obtained through standard - * platforms API which transform mouse movement using their own improvements - * (like pointer acceleration). Platform's improvements are ideal for pointer - * control but it is not so good for moving a first-person camera. For this - * reason when the cursor of a window is grabbed by setting @ref GLFW_CURSOR - * to @ref GLFW_CURSOR_DISABLED, raw input is used. + * Raw mouse motion is closer to the actual motion of the mouse across + * a surface. It is not affected by the scaling and acceleration applied to + * the motion of the desktop cursor. That processing is suitable for a cursor + * while raw motion is better for controlling for example a 3D camera. Because + * of this, raw mouse motion is only provided when the cursor is disabled. * - * The use of raw input can be disabled using @ref glfwSetInputMode with - * @ref GLFW_RAW_INPUT mode. - * - * @return `GLFW_TRUE` if high-definition mouse movement is supported, or - * `GLFW_FALSE` otherwise. + * @return `GLFW_TRUE` if raw mouse motion is supported on the current machine, + * or `GLFW_FALSE` otherwise. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * - * @thread_safety This function may be called from any thread. + * @thread_safety This function must only be called from the main thread. * + * @sa @ref raw_mouse_motion * @sa @ref glfwSetInputMode * * @since Added in version 3.3. * * @ingroup input */ -GLFWAPI int glfwRawInputSupported(void); +GLFWAPI int glfwRawMouseMotionSupported(void); /*! @brief Returns the layout-specific name of the specified printable key. * diff --git a/src/cocoa_window.m b/src/cocoa_window.m index e3e20de7..9bea2f27 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -1297,12 +1297,11 @@ void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity) [window->ns.object setAlphaValue:opacity]; } -void _glfwPlatformSetRawInput(_GLFWwindow *window, GLFWbool enabled) +void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled) { - window->useRawInput = enabled; } -GLFWbool _glfwPlatformRawInputSupported(void) +GLFWbool _glfwPlatformRawMouseMotionSupported(void) { return GLFW_FALSE; } diff --git a/src/input.c b/src/input.c index ef14fad5..b5e11542 100644 --- a/src/input.c +++ b/src/input.c @@ -463,6 +463,7 @@ void _glfwCenterCursorInContentArea(_GLFWwindow* window) _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0); } + ////////////////////////////////////////////////////////////////////////// ////// GLFW public API ////// ////////////////////////////////////////////////////////////////////////// @@ -484,8 +485,8 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode) return window->stickyMouseButtons; case GLFW_LOCK_KEY_MODS: return window->lockKeyMods; - case GLFW_RAW_INPUT: - return window->useRawInput; + case GLFW_RAW_MOUSE_MOTION: + return window->rawMouseMotion; } _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode); @@ -562,17 +563,33 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value) window->stickyMouseButtons = value; } else if (mode == GLFW_LOCK_KEY_MODS) + { window->lockKeyMods = value ? GLFW_TRUE : GLFW_FALSE; - else if (mode == GLFW_RAW_INPUT) - _glfwPlatformSetRawInput(window, value ? GLFW_TRUE : GLFW_FALSE); + } + else if (mode == GLFW_RAW_MOUSE_MOTION) + { + if (!_glfwPlatformRawMouseMotionSupported()) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Raw mouse motion is not supported on this system"); + return; + } + + value = value ? GLFW_TRUE : GLFW_FALSE; + if (window->rawMouseMotion == value) + return; + + window->rawMouseMotion = value; + _glfwPlatformSetRawMouseMotion(window, value); + } else _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode); } -GLFWAPI int glfwRawInputSupported(void) +GLFWAPI int glfwRawMouseMotionSupported(void) { - _GLFW_REQUIRE_INIT_OR_RETURN(0); - return _glfwPlatformRawInputSupported(); + _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); + return _glfwPlatformRawMouseMotionSupported(); } GLFWAPI const char* glfwGetKeyName(int key, int scancode) diff --git a/src/internal.h b/src/internal.h index 65d77cc1..abba5baf 100644 --- a/src/internal.h +++ b/src/internal.h @@ -390,7 +390,7 @@ struct _GLFWwindow char keys[GLFW_KEY_LAST + 1]; // Virtual cursor position when cursor is disabled double virtualCursorPosX, virtualCursorPosY; - GLFWbool useRawInput; + GLFWbool rawMouseMotion; _GLFWcontext context; @@ -597,8 +597,8 @@ const char* _glfwPlatformGetVersionString(void); void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos); void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos); void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode); -void _glfwPlatformSetRawInput(_GLFWwindow *window, GLFWbool enabled); -GLFWbool _glfwPlatformRawInputSupported(void); +void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled); +GLFWbool _glfwPlatformRawMouseMotionSupported(void); int _glfwPlatformCreateCursor(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot); int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape); diff --git a/src/null_window.c b/src/null_window.c index cb976310..8dc92cb7 100644 --- a/src/null_window.c +++ b/src/null_window.c @@ -196,12 +196,11 @@ void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity) { } -void _glfwPlatformSetRawInput(_GLFWwindow *window, GLFWbool enabled) +void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled) { - window->useRawInput = enabled; } -GLFWbool _glfwPlatformRawInputSupported(void) +GLFWbool _glfwPlatformRawMouseMotionSupported(void) { return GLFW_FALSE; } diff --git a/src/win32_window.c b/src/win32_window.c index ec010f7e..728b6e07 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -267,12 +267,36 @@ static void updateClipRect(_GLFWwindow* window) ClipCursor(NULL); } +// Enables WM_INPUT messages for the mouse for the specified window +// +static void enableRawMouseMotion(_GLFWwindow* window) +{ + const RAWINPUTDEVICE rid = { 0x01, 0x02, 0, window->win32.handle }; + + if (!RegisterRawInputDevices(&rid, 1, sizeof(rid))) + { + _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, + "Win32: Failed to register raw input device"); + } +} + +// Disables WM_INPUT messages for the mouse +// +static void disableRawMouseMotion(_GLFWwindow* window) +{ + const RAWINPUTDEVICE rid = { 0x01, 0x02, RIDEV_REMOVE, NULL }; + + if (!RegisterRawInputDevices(&rid, 1, sizeof(rid))) + { + _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, + "Win32: Failed to remove raw input device"); + } +} + // 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, @@ -281,18 +305,16 @@ static void disableCursor(_GLFWwindow* window) _glfwCenterCursorInContentArea(window); updateClipRect(window); - if (window->useRawInput && !RegisterRawInputDevices(&rid, 1, sizeof(rid))) - { - _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, - "Win32: Failed to register raw input device"); - } + if (window->rawMouseMotion) + enableRawMouseMotion(window); } // Exit disabled cursor mode for the specified window // static void enableCursor(_GLFWwindow* window) { - const RAWINPUTDEVICE rid = { 0x01, 0x02, RIDEV_REMOVE, NULL }; + if (window->rawMouseMotion) + disableRawMouseMotion(window); _glfw.win32.disabledCursorWindow = NULL; updateClipRect(NULL); @@ -300,12 +322,6 @@ static void enableCursor(_GLFWwindow* window) _glfw.win32.restoreCursorPosX, _glfw.win32.restoreCursorPosY); updateCursorImage(window); - - if (window->useRawInput && !RegisterRawInputDevices(&rid, 1, sizeof(rid))) - { - _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, - "Win32: Failed to remove raw input device"); - } } // Returns whether the cursor is in the content area of the specified window @@ -817,11 +833,14 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, // Disabled cursor motion input is provided by WM_INPUT if (window->cursorMode == GLFW_CURSOR_DISABLED) { - if (_glfw.win32.disabledCursorWindow != window || window->useRawInput) - break; - const int dx = x - window->win32.lastCursorPosX; const int dy = y - window->win32.lastCursorPosY; + + if (_glfw.win32.disabledCursorWindow != window) + break; + if (window->rawMouseMotion) + break; + _glfwInputCursorPos(window, window->virtualCursorPosX + dx, window->virtualCursorPosY + dy); @@ -855,8 +874,9 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, RAWINPUT* data; int dx, dy; - // Only process input when disabled cursor mode is applied - if (_glfw.win32.disabledCursorWindow != window || !window->useRawInput) + if (_glfw.win32.disabledCursorWindow != window) + break; + if (!window->rawMouseMotion) break; GetRawInputData(ri, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); @@ -1854,20 +1874,18 @@ void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity) } } -void _glfwPlatformSetRawInput(_GLFWwindow *window, GLFWbool enabled) +void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled) { - if (window->useRawInput != enabled) - { - int update = (_glfw.win32.disabledCursorWindow == window); - if (update) - enableCursor(window); - window->useRawInput = enabled; - if (update) - disableCursor(window); - } + if (_glfw.win32.disabledCursorWindow != window) + return; + + if (enabled) + enableRawMouseMotion(window); + else + disableRawMouseMotion(window); } -GLFWbool _glfwPlatformRawInputSupported(void) +GLFWbool _glfwPlatformRawMouseMotionSupported(void) { return GLFW_TRUE; } diff --git a/src/window.c b/src/window.c index f8cb030e..91c323fb 100644 --- a/src/window.c +++ b/src/window.c @@ -202,7 +202,6 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, window->floating = wndconfig.floating; window->focusOnShow = wndconfig.focusOnShow; window->cursorMode = GLFW_CURSOR_NORMAL; - window->useRawInput = GLFW_TRUE; window->minwidth = GLFW_DONT_CARE; window->minheight = GLFW_DONT_CARE; diff --git a/src/wl_window.c b/src/wl_window.c index 42645be5..7c029944 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1318,12 +1318,11 @@ void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity) { } -void _glfwPlatformSetRawInput(_GLFWwindow *window, GLFWbool enabled) +void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled) { - window->useRawInput = enabled; } -GLFWbool _glfwPlatformRawInputSupported(void) +GLFWbool _glfwPlatformRawMouseMotionSupported(void) { return GLFW_FALSE; } diff --git a/src/x11_window.c b/src/x11_window.c index 9e25fda3..92a137f4 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -522,22 +522,41 @@ static void updateCursorImage(_GLFWwindow* window) } } +// Enable XI2 raw mouse motion events +// +static void enableRawMouseMotion(_GLFWwindow* window) +{ + 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); +} + +// Disable XI2 raw mouse motion events +// +static void disableRawMouseMotion(_GLFWwindow* window) +{ + 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); +} + // Apply disabled cursor mode to a focused window // static void disableCursor(_GLFWwindow* window) { - if (_glfw.x11.xi.available && window->useRawInput) - { - 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); - } + if (window->rawMouseMotion) + enableRawMouseMotion(window); _glfw.x11.disabledCursorWindow = window; _glfwPlatformGetCursorPos(window, @@ -557,17 +576,8 @@ static void disableCursor(_GLFWwindow* window) // static void enableCursor(_GLFWwindow* window) { - if (_glfw.x11.xi.available && window->useRawInput) - { - 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); - } + if (window->rawMouseMotion) + disableRawMouseMotion(window); _glfw.x11.disabledCursorWindow = NULL; XUngrabPointer(_glfw.x11.display, CurrentTime); @@ -1183,7 +1193,7 @@ static void processEvent(XEvent *event) _GLFWwindow* window = _glfw.x11.disabledCursorWindow; if (window && - window->useRawInput && + window->rawMouseMotion && event->xcookie.extension == _glfw.x11.xi.majorOpcode && XGetEventData(_glfw.x11.display, &event->xcookie) && event->xcookie.evtype == XI_RawMotion) @@ -1484,7 +1494,7 @@ static void processEvent(XEvent *event) { if (_glfw.x11.disabledCursorWindow != window) return; - if (_glfw.x11.xi.available && window->useRawInput) + if (window->rawMouseMotion) return; const int dx = x - window->x11.lastCursorPosX; @@ -2653,20 +2663,21 @@ void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity) PropModeReplace, (unsigned char*) &value, 1); } -void _glfwPlatformSetRawInput(_GLFWwindow *window, GLFWbool enabled) +void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled) { - if (window->useRawInput != enabled) - { - int update = (_glfw.x11.disabledCursorWindow == window && _glfw.x11.xi.available); - if (update) - enableCursor(window); - window->useRawInput = enabled; - if (update) - disableCursor(window); - } + if (!_glfw.x11.xi.available) + return; + + if (_glfw.x11.disabledCursorWindow != window) + return; + + if (enabled) + enableRawMouseMotion(window); + else + disableRawMouseMotion(window); } -GLFWbool _glfwPlatformRawInputSupported(void) +GLFWbool _glfwPlatformRawMouseMotionSupported(void) { return _glfw.x11.xi.available; } diff --git a/tests/cursor.c b/tests/cursor.c index a64c0bf8..68d3069f 100644 --- a/tests/cursor.c +++ b/tests/cursor.c @@ -164,14 +164,17 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action, break; case GLFW_KEY_R: - if (glfwGetInputMode(window, GLFW_RAW_INPUT)) + if (!glfwRawMouseMotionSupported()) + break; + + if (glfwGetInputMode(window, GLFW_RAW_MOUSE_MOTION)) { - glfwSetInputMode(window, GLFW_RAW_INPUT, GLFW_FALSE); + glfwSetInputMode(window, GLFW_RAW_MOUSE_MOTION, GLFW_FALSE); printf("(( raw input is disabled ))\n"); } else { - glfwSetInputMode(window, GLFW_RAW_INPUT, GLFW_TRUE); + glfwSetInputMode(window, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE); printf("(( raw input is enabled ))\n"); } break;