diff options
author | dec05eba <dec05eba@protonmail.com> | 2021-11-17 09:42:11 +0100 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2021-11-17 09:42:11 +0100 |
commit | a14eb65e82d226fe8b33ca23d29eeba02066357d (patch) | |
tree | bbdb92dd8105e81a34fea601df851a3c25b03b76 /src | |
parent | ff24e4c604479fdcedfacca35af3bb4810683c68 (diff) |
Window: implement function to disable key repeat
Diffstat (limited to 'src')
-rw-r--r-- | src/mgl.c | 2 | ||||
-rw-r--r-- | src/window/window.c | 27 |
2 files changed, 27 insertions, 2 deletions
@@ -1,5 +1,6 @@ #include "../include/mgl/mgl.h" #include <X11/Xutil.h> +#include <X11/XKBlib.h> #include <stdio.h> #ifndef NDEBUG #include <stdlib.h> @@ -67,6 +68,7 @@ int mgl_init(void) { prev_xerror = XSetErrorHandler(ignore_xerror); prev_xioerror = XSetIOErrorHandler(ignore_xioerror); + XkbSetDetectableAutoRepeat(context.connection, True, NULL); context.wm_delete_window_atom = XInternAtom(context.connection, "WM_DELETE_WINDOW", False); if(!context.wm_delete_window_atom) { diff --git a/src/window/window.c b/src/window/window.c index 3dbb81f..c6dab51 100644 --- a/src/window/window.c +++ b/src/window/window.c @@ -61,6 +61,8 @@ typedef struct { Atom incr_atom; Cursor default_cursor; Cursor invisible_cursor; + unsigned int prev_keycode_pressed; + bool key_was_released; /* Used to stack text event on top of key press/release events and other text events. For example pressing a key should give the user both key press and text events @@ -89,6 +91,9 @@ static int x11_context_init(x11_context *self) { self->default_cursor = None; self->invisible_cursor = None; + self->prev_keycode_pressed = 0; + self->key_was_released = false; + self->default_cursor = XCreateFontCursor(context->connection, XC_arrow); if(!self->default_cursor) { x11_context_deinit(self); @@ -226,6 +231,7 @@ static int mgl_window_init(mgl_window *self, const char *title, const mgl_window self->context = NULL; self->open = false; self->focused = false; + self->key_repeat_enabled = true; self->frame_time_limit = 0.0; mgl_clock_init(&self->frame_timer); self->clipboard_string = NULL; @@ -495,6 +501,7 @@ static void mgl_window_handle_text_event(mgl_window *self, XEvent *xev) { text_event.text.size = clen; memcpy(text_event.text.str, &buf[i], clen); text_event.text.str[clen] = '\0'; + /* Text may contain multiple codepoints so they need to separated into multiple events */ if(!x11_context_append_event(x11_context, &text_event)) break; @@ -502,17 +509,29 @@ static void mgl_window_handle_text_event(mgl_window *self, XEvent *xev) { } } -/* Returns true if processed */ static void mgl_window_on_receive_event(mgl_window *self, XEvent *xev, mgl_event *event, mgl_context *context) { - /* TODO: Handle wm_delete_window event */ switch(xev->type) { case KeyPress: { + x11_context *x11_context = self->context; + + if(!self->key_repeat_enabled && xev->xkey.keycode == x11_context->prev_keycode_pressed && !x11_context->key_was_released) { + event->type = MGL_EVENT_UNKNOWN; + return; + } + + x11_context->prev_keycode_pressed = xev->xkey.keycode; + x11_context->key_was_released = false; + event->type = MGL_EVENT_KEY_PRESSED; mgl_window_handle_key_event(self, &xev->xkey, event, context, true); mgl_window_handle_text_event(self, xev); return; } case KeyRelease: { + x11_context *x11_context = self->context; + if(xev->xkey.keycode == x11_context->prev_keycode_pressed) + x11_context->key_was_released = true; + event->type = MGL_EVENT_KEY_RELEASED; mgl_window_handle_key_event(self, &xev->xkey, event, context, false); return; @@ -891,3 +910,7 @@ bool mgl_window_get_clipboard(mgl_window *self, char **str, size_t *size) { /* Timed out waiting for clipboard */ return false; } + +void mgl_window_set_key_repeat_enabled(mgl_window *self, bool enabled) { + self->key_repeat_enabled = enabled; +} |