mirror of
				https://github.com/glfw/glfw.git
				synced 2025-10-31 04:32:26 +00:00 
			
		
		
		
	Wayland: Use a timerfd for key repeat
This commit is contained in:
		
							parent
							
								
									c14a35e21e
								
							
						
					
					
						commit
						90f5edc0b8
					
				| @ -32,6 +32,7 @@ | |||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <sys/mman.h> | #include <sys/mman.h> | ||||||
|  | #include <sys/timerfd.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #include <wayland-client.h> | #include <wayland-client.h> | ||||||
| 
 | 
 | ||||||
| @ -365,6 +366,7 @@ static void keyboardHandleKey(void* data, | |||||||
|     int keyCode; |     int keyCode; | ||||||
|     int action; |     int action; | ||||||
|     _GLFWwindow* window = _glfw.wl.keyboardFocus; |     _GLFWwindow* window = _glfw.wl.keyboardFocus; | ||||||
|  |     struct itimerspec timer = {}; | ||||||
| 
 | 
 | ||||||
|     if (!window) |     if (!window) | ||||||
|         return; |         return; | ||||||
| @ -377,7 +379,20 @@ static void keyboardHandleKey(void* data, | |||||||
|                   _glfw.wl.xkb.modifiers); |                   _glfw.wl.xkb.modifiers); | ||||||
| 
 | 
 | ||||||
|     if (action == GLFW_PRESS) |     if (action == GLFW_PRESS) | ||||||
|  |     { | ||||||
|         inputChar(window, key); |         inputChar(window, key); | ||||||
|  | 
 | ||||||
|  |         if (_glfw.wl.keyboardRepeatRate > 0) | ||||||
|  |         { | ||||||
|  |             _glfw.wl.keyboardLastKey = keyCode; | ||||||
|  |             _glfw.wl.keyboardLastScancode = key; | ||||||
|  |             timer.it_interval.tv_sec = _glfw.wl.keyboardRepeatRate / 1000; | ||||||
|  |             timer.it_interval.tv_nsec = (_glfw.wl.keyboardRepeatRate % 1000) * 1000000; | ||||||
|  |             timer.it_value.tv_sec = _glfw.wl.keyboardRepeatDelay / 1000; | ||||||
|  |             timer.it_value.tv_nsec = (_glfw.wl.keyboardRepeatDelay % 1000) * 1000000; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     timerfd_settime(_glfw.wl.timerfd, 0, &timer, NULL); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void keyboardHandleModifiers(void* data, | static void keyboardHandleModifiers(void* data, | ||||||
| @ -822,6 +837,10 @@ int _glfwPlatformInit(void) | |||||||
| 
 | 
 | ||||||
|     _glfwInitTimerPOSIX(); |     _glfwInitTimerPOSIX(); | ||||||
| 
 | 
 | ||||||
|  |     _glfw.wl.timerfd = -1; | ||||||
|  |     if (_glfw.wl.seatVersion >= 4) | ||||||
|  |         _glfw.wl.timerfd = timerfd_create(CLOCK_MONOTONIC, 0); | ||||||
|  | 
 | ||||||
|     if (_glfw.wl.pointer && _glfw.wl.shm) |     if (_glfw.wl.pointer && _glfw.wl.shm) | ||||||
|     { |     { | ||||||
|         _glfw.wl.cursorTheme = wl_cursor_theme_load(NULL, 32, _glfw.wl.shm); |         _glfw.wl.cursorTheme = wl_cursor_theme_load(NULL, 32, _glfw.wl.shm); | ||||||
|  | |||||||
| @ -208,6 +208,9 @@ typedef struct _GLFWlibraryWayland | |||||||
| 
 | 
 | ||||||
|     int32_t                     keyboardRepeatRate; |     int32_t                     keyboardRepeatRate; | ||||||
|     int32_t                     keyboardRepeatDelay; |     int32_t                     keyboardRepeatDelay; | ||||||
|  |     int                         keyboardLastKey; | ||||||
|  |     int                         keyboardLastScancode; | ||||||
|  |     int                         timerfd; | ||||||
|     short int                   keycodes[256]; |     short int                   keycodes[256]; | ||||||
|     short int                   scancodes[GLFW_KEY_LAST + 1]; |     short int                   scancodes[GLFW_KEY_LAST + 1]; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -35,6 +35,7 @@ | |||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <fcntl.h> | #include <fcntl.h> | ||||||
| #include <sys/mman.h> | #include <sys/mman.h> | ||||||
|  | #include <sys/timerfd.h> | ||||||
| #include <poll.h> | #include <poll.h> | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -442,7 +443,9 @@ handleEvents(int timeout) | |||||||
|     struct wl_display* display = _glfw.wl.display; |     struct wl_display* display = _glfw.wl.display; | ||||||
|     struct pollfd fds[] = { |     struct pollfd fds[] = { | ||||||
|         { wl_display_get_fd(display), POLLIN }, |         { wl_display_get_fd(display), POLLIN }, | ||||||
|  |         { _glfw.wl.timerfd, POLLIN }, | ||||||
|     }; |     }; | ||||||
|  |     char buf[8]; | ||||||
| 
 | 
 | ||||||
|     while (wl_display_prepare_read(display) != 0) |     while (wl_display_prepare_read(display) != 0) | ||||||
|         wl_display_dispatch_pending(display); |         wl_display_dispatch_pending(display); | ||||||
| @ -462,10 +465,27 @@ handleEvents(int timeout) | |||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (poll(fds, 1, timeout) > 0) |     if (poll(fds, 2, timeout) > 0) | ||||||
|     { |     { | ||||||
|         wl_display_read_events(display); |         if (fds[0].revents & POLLIN) | ||||||
|         wl_display_dispatch_pending(display); |         { | ||||||
|  |             wl_display_read_events(display); | ||||||
|  |             wl_display_dispatch_pending(display); | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             wl_display_cancel_read(display); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (fds[1].revents & POLLIN) | ||||||
|  |         { | ||||||
|  |             _glfwInputKey(_glfw.wl.keyboardFocus, _glfw.wl.keyboardLastKey, | ||||||
|  |                           _glfw.wl.keyboardLastScancode, GLFW_REPEAT, | ||||||
|  |                           _glfw.wl.xkb.modifiers); | ||||||
|  | 
 | ||||||
|  |             // Required to mark the fd as clean.
 | ||||||
|  |             read(_glfw.wl.timerfd, &buf, 8); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user