mirror of
				https://github.com/glfw/glfw.git
				synced 2025-10-31 04:32:26 +00:00 
			
		
		
		
	Unlimited mouse button input mode
This adds the GLFW_UNLIMITED_MOUSE_BUTTONS input mode which permits mouse buttons over GLFW_MOUSE_BUTTON_LAST to be reported to the mouse button callback. Closes #2423
This commit is contained in:
		
							parent
							
								
									dc557ecf38
								
							
						
					
					
						commit
						bf945f1213
					
				| @ -121,6 +121,9 @@ information on what to include when reporting a bug. | ||||
| 
 | ||||
| ## Changelog since 3.4 | ||||
| 
 | ||||
|  - Added `GLFW_UNLIMITED_MOUSE_BUTTONS` input mode that allows mouse buttons beyond | ||||
|    the limit of the mouse button tokens to be reported (#2423) | ||||
| 
 | ||||
| 
 | ||||
| ## Contact | ||||
| 
 | ||||
|  | ||||
| @ -492,6 +492,20 @@ a mouse button callback. | ||||
| glfwSetMouseButtonCallback(window, mouse_button_callback); | ||||
| ``` | ||||
| 
 | ||||
| @anchor GLFW_UNLIMITED_MOUSE_BUTTONS | ||||
| To handle all mouse buttons in the callback, instead of only ones with associated | ||||
| [button tokens](@ref buttons), set the @ref GLFW_UNLIMITED_MOUSE_BUTTONS | ||||
| input mode. | ||||
| 
 | ||||
| ```c | ||||
| glfwSetInputMode(window, GLFW_UNLIMITED_MOUSE_BUTTONS, GLFW_TRUE); | ||||
| ``` | ||||
| 
 | ||||
| When this input mode is enabled, GLFW doesn't limit the reported mouse buttons | ||||
| to only those that have an associated button token, for compatibility with | ||||
| earlier versions of GLFW, which never reported any buttons over | ||||
| @ref GLFW_MOUSE_BUTTON_LAST, on which users could have relied on. | ||||
| 
 | ||||
| The callback function receives the [mouse button](@ref buttons), button action | ||||
| and [modifier bits](@ref mods). | ||||
| 
 | ||||
| @ -503,11 +517,16 @@ void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| The mouse button is an integer that can be one of the | ||||
| [mouse button tokens](@ref buttons) or, if the | ||||
| @ref GLFW_UNLIMITED_MOUSE_BUTTONS input mode is set, any other positive value. | ||||
| 
 | ||||
| The action is one of `GLFW_PRESS` or `GLFW_RELEASE`. | ||||
| 
 | ||||
| The last reported state for every [supported mouse button](@ref buttons) is also | ||||
| The last reported state for every [mouse button token](@ref buttons) is also | ||||
| saved in per-window state arrays that can be polled with @ref | ||||
| glfwGetMouseButton. | ||||
| glfwGetMouseButton. This is not effected by the @ref GLFW_UNLIMITED_MOUSE_BUTTONS | ||||
| input mode. | ||||
| 
 | ||||
| ```c | ||||
| int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT); | ||||
| @ -540,7 +559,7 @@ had been processed in the meantime, the state will reset to `GLFW_RELEASE`, | ||||
| otherwise it will remain `GLFW_PRESS`. | ||||
| 
 | ||||
| The `GLFW_MOUSE_BUTTON_LAST` constant holds the highest value of any | ||||
| [supported mouse button](@ref buttons). | ||||
| [mouse button token](@ref buttons). | ||||
| 
 | ||||
| 
 | ||||
| ### Scroll input {#scrolling} | ||||
|  | ||||
							
								
								
									
										11
									
								
								docs/news.md
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								docs/news.md
									
									
									
									
									
								
							| @ -5,6 +5,15 @@ | ||||
| 
 | ||||
| ## New features {#features} | ||||
| 
 | ||||
| ### Unlimited mouse buttons {#unlimited_mouse_buttons} | ||||
| 
 | ||||
| GLFW now has an input mode which allows an unlimited number of mouse buttons to | ||||
| be reported by the mouse buttton callback, rather than just the associated | ||||
| [mouse button tokens](@ref buttons). This allows using mouse buttons with | ||||
| values over 8. For compatibility with older versions, the | ||||
| @ref GLFW_UNLIMITED_MOUSE_BUTTONS input mode needs to be set to make use of | ||||
| this. | ||||
| 
 | ||||
| ## Caveats {#caveats} | ||||
| 
 | ||||
| ## Deprecations {#deprecations} | ||||
| @ -19,6 +28,8 @@ | ||||
| 
 | ||||
| ### New constants {#new_constants} | ||||
| 
 | ||||
| - @ref GLFW_UNLIMITED_MOUSE_BUTTONS | ||||
| 
 | ||||
| ## Release notes for earlier versions {#news_archive} | ||||
| 
 | ||||
| - [Release notes for 3.4](https://www.glfw.org/docs/3.4/news.html) | ||||
|  | ||||
| @ -1149,11 +1149,12 @@ extern "C" { | ||||
| #define GLFW_OPENGL_CORE_PROFILE    0x00032001 | ||||
| #define GLFW_OPENGL_COMPAT_PROFILE  0x00032002 | ||||
| 
 | ||||
| #define GLFW_CURSOR                 0x00033001 | ||||
| #define GLFW_STICKY_KEYS            0x00033002 | ||||
| #define GLFW_STICKY_MOUSE_BUTTONS   0x00033003 | ||||
| #define GLFW_LOCK_KEY_MODS          0x00033004 | ||||
| #define GLFW_RAW_MOUSE_MOTION       0x00033005 | ||||
| #define GLFW_CURSOR                  0x00033001 | ||||
| #define GLFW_STICKY_KEYS             0x00033002 | ||||
| #define GLFW_STICKY_MOUSE_BUTTONS    0x00033003 | ||||
| #define GLFW_LOCK_KEY_MODS           0x00033004 | ||||
| #define GLFW_RAW_MOUSE_MOTION        0x00033005 | ||||
| #define GLFW_UNLIMITED_MOUSE_BUTTONS 0x00033006 | ||||
| 
 | ||||
| #define GLFW_CURSOR_NORMAL          0x00034001 | ||||
| #define GLFW_CURSOR_HIDDEN          0x00034002 | ||||
| @ -4676,8 +4677,8 @@ 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_MOUSE_MOTION. | ||||
|  *  @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS | ||||
|  *  @ref GLFW_RAW_MOUSE_MOTION, or @ref GLFW_UNLIMITED_MOUSE_BUTTONS. | ||||
|  * | ||||
|  *  If the mode is `GLFW_CURSOR`, the value must be one of the following cursor | ||||
|  *  modes: | ||||
| @ -4717,6 +4718,11 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); | ||||
|  *  attempting to set this will emit @ref GLFW_FEATURE_UNAVAILABLE.  Call @ref | ||||
|  *  glfwRawMouseMotionSupported to check for support. | ||||
|  * | ||||
|  *  If the mode is `GLFW_UNLIMITED_MOUSE_BUTTONS`, the value must be either | ||||
|  *  `GLFW_TRUE` to disable the mouse button limit when calling the mouse button | ||||
|  *  callback, or `GLFW_FALSE` to limit the mouse buttons sent to the callback | ||||
|  *  to the mouse button token values up to `GLFW_MOUSE_BUTTON_LAST`. | ||||
|  * | ||||
|  *  @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 | ||||
| @ -4911,8 +4917,11 @@ GLFWAPI int glfwGetKey(GLFWwindow* window, int key); | ||||
|  *  returns `GLFW_PRESS` the first time you call it for a mouse button that was | ||||
|  *  pressed, even if that mouse button has already been released. | ||||
|  * | ||||
|  *  The @ref GLFW_UNLIMITED_MOUSE_BUTTONS input mode does not effect the | ||||
|  *  limit on buttons which can be polled with this function. | ||||
|  * | ||||
|  *  @param[in] window The desired window. | ||||
|  *  @param[in] button The desired [mouse button](@ref buttons). | ||||
|  *  @param[in] button The desired [mouse button token](@ref buttons). | ||||
|  *  @return One of `GLFW_PRESS` or `GLFW_RELEASE`. | ||||
|  * | ||||
|  *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref | ||||
| @ -5288,10 +5297,15 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmods | ||||
|  *  is called when a mouse button is pressed or released. | ||||
|  * | ||||
|  *  When a window loses input focus, it will generate synthetic mouse button | ||||
|  *  release events for all pressed mouse buttons.  You can tell these events | ||||
|  *  from user-generated events by the fact that the synthetic ones are generated | ||||
|  *  after the focus loss event has been processed, i.e. after the | ||||
|  *  [window focus callback](@ref glfwSetWindowFocusCallback) has been called. | ||||
|  *  release events for all pressed mouse buttons with associated button tokens. | ||||
|  *  You can tell these events from user-generated events by the fact that the | ||||
|  *  synthetic ones are generated after the focus loss event has been processed, | ||||
|  *  i.e. after the [window focus callback](@ref glfwSetWindowFocusCallback) has | ||||
|  *  been called. | ||||
|  * | ||||
|  *  The reported `button` value can be higher than `GLFW_MOUSE_BUTTON_LAST` if | ||||
|  *  the button does not have an associated [button token](@ref buttons) and the | ||||
|  *  @ref GLFW_UNLIMITED_MOUSE_BUTTONS input mode is set. | ||||
|  * | ||||
|  *  @param[in] window The window whose callback to set. | ||||
|  *  @param[in] callback The new callback, or `NULL` to remove the currently set | ||||
|  | ||||
							
								
								
									
										22
									
								
								src/input.c
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								src/input.c
									
									
									
									
									
								
							| @ -348,20 +348,22 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods) | ||||
| { | ||||
|     assert(window != NULL); | ||||
|     assert(button >= 0); | ||||
|     assert(button <= GLFW_MOUSE_BUTTON_LAST); | ||||
|     assert(action == GLFW_PRESS || action == GLFW_RELEASE); | ||||
|     assert(mods == (mods & GLFW_MOD_MASK)); | ||||
| 
 | ||||
|     if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST) | ||||
|     if (button < 0 || (!window->disableMouseButtonLimit && button > GLFW_MOUSE_BUTTON_LAST)) | ||||
|         return; | ||||
| 
 | ||||
|     if (!window->lockKeyMods) | ||||
|         mods &= ~(GLFW_MOD_CAPS_LOCK | GLFW_MOD_NUM_LOCK); | ||||
| 
 | ||||
|     if (action == GLFW_RELEASE && window->stickyMouseButtons) | ||||
|         window->mouseButtons[button] = _GLFW_STICK; | ||||
|     else | ||||
|         window->mouseButtons[button] = (char) action; | ||||
|     if (button <= GLFW_MOUSE_BUTTON_LAST) | ||||
|     { | ||||
|         if (action == GLFW_RELEASE && window->stickyMouseButtons) | ||||
|             window->mouseButtons[button] = _GLFW_STICK; | ||||
|         else | ||||
|             window->mouseButtons[button] = (char) action; | ||||
|     } | ||||
| 
 | ||||
|     if (window->callbacks.mouseButton) | ||||
|         window->callbacks.mouseButton((GLFWwindow*) window, button, action, mods); | ||||
| @ -576,6 +578,8 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode) | ||||
|             return window->lockKeyMods; | ||||
|         case GLFW_RAW_MOUSE_MOTION: | ||||
|             return window->rawMouseMotion; | ||||
|         case GLFW_UNLIMITED_MOUSE_BUTTONS: | ||||
|             return window->disableMouseButtonLimit; | ||||
|     } | ||||
| 
 | ||||
|     _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode); | ||||
| @ -683,6 +687,12 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value) | ||||
|             _glfw.platform.setRawMouseMotion(window, value); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         case GLFW_UNLIMITED_MOUSE_BUTTONS: | ||||
|         { | ||||
|             window->disableMouseButtonLimit = value ? GLFW_TRUE : GLFW_FALSE; | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode); | ||||
|  | ||||
| @ -544,6 +544,7 @@ struct _GLFWwindow | ||||
|     GLFWbool            stickyKeys; | ||||
|     GLFWbool            stickyMouseButtons; | ||||
|     GLFWbool            lockKeyMods; | ||||
|     GLFWbool            disableMouseButtonLimit; | ||||
|     int                 cursorMode; | ||||
|     char                mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1]; | ||||
|     char                keys[GLFW_KEY_LAST + 1]; | ||||
|  | ||||
| @ -630,6 +630,7 @@ int main(int argc, char** argv) | ||||
|             glfwTerminate(); | ||||
|             exit(EXIT_FAILURE); | ||||
|         } | ||||
|         glfwSetInputMode(slots[i].window, GLFW_UNLIMITED_MOUSE_BUTTONS, GLFW_TRUE); | ||||
| 
 | ||||
|         glfwSetWindowUserPointer(slots[i].window, slots + i); | ||||
| 
 | ||||
|  | ||||
| @ -78,6 +78,7 @@ int main(int argc, char** argv) | ||||
|         glfwTerminate(); | ||||
|         exit(EXIT_FAILURE); | ||||
|     } | ||||
|     glfwSetInputMode(window, GLFW_UNLIMITED_MOUSE_BUTTONS, GLFW_TRUE); | ||||
| 
 | ||||
|     glfwMakeContextCurrent(window); | ||||
|     gladLoadGL(glfwGetProcAddress); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user