mirror of
https://github.com/glfw/glfw.git
synced 2024-11-23 02:25:10 +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