From 1495774a066cb027a3d96cf7d489185fdc429df3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deuc=D0=B5?= <shurd@sasktel.net> Date: Fri, 19 Mar 2021 13:56:29 -0400 Subject: [PATCH] Fix AltGr with SDL2 This is pretty insane since SDL2 completely ignores the keysym value of the X11 keyboard event, so here's what we do... 1) When there's a keypress that includes right-alt, store the sym/mod 2) When we get text input, if it's the same as we would get if ALT wasn't pressed for the last keydown, parse through the mapping (ie: handle ALT keys) 3) If it's different, use that (gets AltGr modified value) I get that AltGr is hard in a cross-platform way, but just pretending it doesn't exist at all for key input is a very weird choice. --- src/conio/sdl_con.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/conio/sdl_con.c b/src/conio/sdl_con.c index e585781acb..74e822bc27 100644 --- a/src/conio/sdl_con.c +++ b/src/conio/sdl_con.c @@ -795,6 +795,8 @@ void sdl_video_event_thread(void *data) SDL_Event ev; int old_w, old_h; int block_text = 0; + static SDL_Keycode last_sym = SDLK_UNKNOWN; + static Uint16 last_mod = 0; pthread_mutex_lock(&vstatlock); old_w = cvstat.winwidth; @@ -816,6 +818,8 @@ void sdl_video_event_thread(void *data) else { switch (ev.type) { case SDL_KEYDOWN: /* Keypress */ + last_mod = ev.key.keysym.mod; + last_sym = ev.key.keysym.sym; if ((ev.key.keysym.mod & (KMOD_CTRL|KMOD_ALT|KMOD_GUI)) && !(ev.key.keysym.mod & KMOD_MODE)) { block_text = 1; if ((ev.key.keysym.mod & KMOD_ALT) && @@ -878,6 +882,10 @@ void sdl_video_event_thread(void *data) break; } } + if (ev.key.keysym.mod & KMOD_RALT) { // Possible AltGr, let textinput sort it out... + block_text = 0; + break; + } if ((ev.key.keysym.mod & KMOD_SHIFT) && (ev.key.keysym.sym == '\t')) block_text = 1; if (block_text || ev.key.keysym.sym < 0 || ev.key.keysym.sym > 127) { @@ -897,10 +905,17 @@ void sdl_video_event_thread(void *data) } break; case SDL_TEXTINPUT: - if (!block_text) - sdl_add_keys((uint8_t *)ev.text.text); + if (!block_text) { + unsigned int charcode = sdl_get_char_code(last_sym, last_mod & ~(KMOD_ALT)); + // If the key is exactly what we would expect, use sdl_get_char_code() + if (*(uint8_t *)ev.text.text == charcode) + sdl_add_key(sdl_get_char_code(last_sym, last_mod)); + else + sdl_add_keys((uint8_t *)ev.text.text); + } break; case SDL_KEYUP: + last_mod = ev.key.keysym.mod; if (!(ev.key.keysym.mod & (KMOD_CTRL|KMOD_ALT|KMOD_GUI))) block_text = 0; break; -- GitLab