Wayland: Clean up key repeat logic

(cherry picked from commit 9180923ea0)
This commit is contained in:
Camilla Löwy 2022-07-13 21:32:30 +02:00
parent a8d543f1f8
commit 1acd67eeb6
3 changed files with 32 additions and 29 deletions

View File

@ -314,7 +314,7 @@ int _glfwPlatformInit(void)
int cursorSize; int cursorSize;
// These must be set before any failure checks // These must be set before any failure checks
_glfw.wl.timerfd = -1; _glfw.wl.keyRepeatTimerfd = -1;
_glfw.wl.cursorTimerfd = -1; _glfw.wl.cursorTimerfd = -1;
_glfw.wl.cursor.handle = _glfw_dlopen("libwayland-cursor.so.0"); _glfw.wl.cursor.handle = _glfw_dlopen("libwayland-cursor.so.0");
@ -435,7 +435,10 @@ int _glfwPlatformInit(void)
#ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION #ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION
if (_glfw.wl.seatVersion >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) if (_glfw.wl.seatVersion >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
_glfw.wl.timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); {
_glfw.wl.keyRepeatTimerfd =
timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
}
#endif #endif
if (!_glfw.wl.wmBase) if (!_glfw.wl.wmBase)
@ -571,8 +574,8 @@ void _glfwPlatformTerminate(void)
wl_display_disconnect(_glfw.wl.display); wl_display_disconnect(_glfw.wl.display);
} }
if (_glfw.wl.timerfd >= 0) if (_glfw.wl.keyRepeatTimerfd >= 0)
close(_glfw.wl.timerfd); close(_glfw.wl.keyRepeatTimerfd);
if (_glfw.wl.cursorTimerfd >= 0) if (_glfw.wl.cursorTimerfd >= 0)
close(_glfw.wl.cursorTimerfd); close(_glfw.wl.cursorTimerfd);

View File

@ -270,12 +270,12 @@ typedef struct _GLFWlibraryWayland
uint32_t serial; uint32_t serial;
uint32_t pointerEnterSerial; uint32_t pointerEnterSerial;
int32_t keyboardRepeatRate; int keyRepeatTimerfd;
int32_t keyboardRepeatDelay; int32_t keyRepeatRate;
int keyboardLastKey; int32_t keyRepeatDelay;
int keyboardLastScancode; int keyRepeatScancode;
char* clipboardString; char* clipboardString;
int timerfd;
short int keycodes[256]; short int keycodes[256];
short int scancodes[GLFW_KEY_LAST + 1]; short int scancodes[GLFW_KEY_LAST + 1];
char keynames[GLFW_KEY_LAST + 1][5]; char keynames[GLFW_KEY_LAST + 1][5];

View File

@ -892,7 +892,7 @@ static xkb_keysym_t composeSymbol(xkb_keysym_t sym)
} }
} }
GLFWbool inputText(_GLFWwindow* window, uint32_t scancode) void inputText(_GLFWwindow* window, uint32_t scancode)
{ {
const xkb_keysym_t* keysyms; const xkb_keysym_t* keysyms;
const xkb_keycode_t keycode = scancode + 8; const xkb_keycode_t keycode = scancode + 8;
@ -908,8 +908,6 @@ GLFWbool inputText(_GLFWwindow* window, uint32_t scancode)
_glfwInputChar(window, codepoint, mods, plain); _glfwInputChar(window, codepoint, mods, plain);
} }
} }
return xkb_keymap_key_repeats(_glfw.wl.xkb.keymap, keycode);
} }
static void handleEvents(double* timeout) static void handleEvents(double* timeout)
@ -918,7 +916,7 @@ static void handleEvents(double* timeout)
struct pollfd fds[] = struct pollfd fds[] =
{ {
{ wl_display_get_fd(_glfw.wl.display), POLLIN }, { wl_display_get_fd(_glfw.wl.display), POLLIN },
{ _glfw.wl.timerfd, POLLIN }, { _glfw.wl.keyRepeatTimerfd, POLLIN },
{ _glfw.wl.cursorTimerfd, POLLIN }, { _glfw.wl.cursorTimerfd, POLLIN },
}; };
@ -962,16 +960,16 @@ static void handleEvents(double* timeout)
{ {
uint64_t repeats; uint64_t repeats;
if (read(_glfw.wl.timerfd, &repeats, sizeof(repeats)) == 8) if (read(_glfw.wl.keyRepeatTimerfd, &repeats, sizeof(repeats)) == 8)
{ {
for (uint64_t i = 0; i < repeats; i++) for (uint64_t i = 0; i < repeats; i++)
{ {
_glfwInputKey(_glfw.wl.keyboardFocus, _glfwInputKey(_glfw.wl.keyboardFocus,
_glfw.wl.keyboardLastKey, translateKey(_glfw.wl.keyRepeatScancode),
_glfw.wl.keyboardLastScancode, _glfw.wl.keyRepeatScancode,
GLFW_PRESS, GLFW_PRESS,
_glfw.wl.xkb.modifiers); _glfw.wl.xkb.modifiers);
inputText(_glfw.wl.keyboardFocus, _glfw.wl.keyboardLastScancode); inputText(_glfw.wl.keyboardFocus, _glfw.wl.keyRepeatScancode);
} }
event = GLFW_TRUE; event = GLFW_TRUE;
@ -1490,7 +1488,7 @@ static void keyboardHandleLeave(void* userData,
return; return;
struct itimerspec timer = {0}; struct itimerspec timer = {0};
timerfd_settime(_glfw.wl.timerfd, 0, &timer, NULL); timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL);
_glfw.wl.serial = serial; _glfw.wl.serial = serial;
_glfw.wl.keyboardFocus = NULL; _glfw.wl.keyboardFocus = NULL;
@ -1519,23 +1517,25 @@ static void keyboardHandleKey(void* userData,
if (action == GLFW_PRESS) if (action == GLFW_PRESS)
{ {
const GLFWbool shouldRepeat = inputText(window, scancode); inputText(window, scancode);
if (shouldRepeat && _glfw.wl.keyboardRepeatRate > 0) const xkb_keycode_t keycode = scancode + 8;
if (xkb_keymap_key_repeats(_glfw.wl.xkb.keymap, keycode) &&
_glfw.wl.keyRepeatRate > 0)
{ {
_glfw.wl.keyboardLastKey = key; _glfw.wl.keyRepeatScancode = scancode;
_glfw.wl.keyboardLastScancode = scancode; if (_glfw.wl.keyRepeatRate > 1)
if (_glfw.wl.keyboardRepeatRate > 1) timer.it_interval.tv_nsec = 1000000000 / _glfw.wl.keyRepeatRate;
timer.it_interval.tv_nsec = 1000000000 / _glfw.wl.keyboardRepeatRate;
else else
timer.it_interval.tv_sec = 1; timer.it_interval.tv_sec = 1;
timer.it_value.tv_sec = _glfw.wl.keyboardRepeatDelay / 1000; timer.it_value.tv_sec = _glfw.wl.keyRepeatDelay / 1000;
timer.it_value.tv_nsec = (_glfw.wl.keyboardRepeatDelay % 1000) * 1000000; timer.it_value.tv_nsec = (_glfw.wl.keyRepeatDelay % 1000) * 1000000;
} }
} }
timerfd_settime(_glfw.wl.timerfd, 0, &timer, NULL); timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL);
} }
static void keyboardHandleModifiers(void* userData, static void keyboardHandleModifiers(void* userData,
@ -1595,8 +1595,8 @@ static void keyboardHandleRepeatInfo(void* userData,
if (keyboard != _glfw.wl.keyboard) if (keyboard != _glfw.wl.keyboard)
return; return;
_glfw.wl.keyboardRepeatRate = rate; _glfw.wl.keyRepeatRate = rate;
_glfw.wl.keyboardRepeatDelay = delay; _glfw.wl.keyRepeatDelay = delay;
} }
#endif #endif