-
Notifications
You must be signed in to change notification settings - Fork 39
Description
Hi!
I have a minimalist program that uses SDL2 to create a window, and display key down event.
This program work fine with SDL2 and SDL3 library, but has a strange behavior with sdl2-compat, with the circumflex key.
I am using an azerty keyboard (https://en.wikipedia.org/wiki/AZERTY)
In SDL2, with "legacy" version (2.30.0 2.30.8, 2.32.0, 2.32.4) if I push any keyboard key (including circumflex), the event key down is directly displayed (I push A then ^):
version SDL Version: 2.32.4 (Compiled: 2.32.54)
Event 97
Event 1073741824
If I do this on SDL3, same behavior, everything is ok, including the circumflex key. (I push A then ^)
We compiled against SDL version 3.2.10 ...
But we are linking against SDL version 3.2.10.
Press keys on the keyboard. Press ESC or close the window to quit.
Key pressed: key = 97
Key pressed: key = 1073741871
But If I use sdl2-comptat, the circumflex key event is not send.
version SDL Version: 2.30.54 (Compiled: 2.32.54)
Event 97
and the lastest conpat version:
version SDL Version: 2.32.54 (Compiled: 2.32.54)
Event 97
Am I missing something? Is there a HINT that has changed this behavior?
Here it is in sdl2:
#include <SDL2/SDL.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
#define MAX_TEXT_LENGTH 1024
int main(int argc, char *argv[]) {
SDL_version compiled;
SDL_version linked;
SDL_GetVersion(&linked);
SDL_VERSION(&compiled);
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
printf("SDL_Init Error: %s\n", SDL_GetError());
return 1;
}
char sdlVersionText[128];
snprintf(sdlVersionText, sizeof(sdlVersionText), "SDL Version: %d.%d.%d (Compiled: %d.%d.%d)",
linked.major, linked.minor, linked.patch,
compiled.major, compiled.minor, compiled.patch);
printf("version %s\n", sdlVersionText);
SDL_Window *win = SDL_CreateWindow("Key Display", 100, 100, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN);
if (!win) {
printf("SDL_CreateWindow Error: %s\n", SDL_GetError());
SDL_Quit();
return 1;
}
SDL_Renderer *ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (!ren) {
printf("SDL_CreateRenderer Error: %s\n", SDL_GetError());
SDL_DestroyWindow(win);
SDL_Quit();
return 1;
}
bool quit = false;
SDL_Event e;
while (!quit) {
while (SDL_PollEvent(&e)) {
if (e.type == SDL_QUIT) {
quit = true;
} else if (e.type == SDL_KEYDOWN) {
printf("Event %d\n", e.key.keysym.sym);
}
}
SDL_RenderClear(ren);
SDL_RenderPresent(ren);
}
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
SDL_Quit();
return 0;
}
The sdl3 code:
#include <SDL3/SDL.h>
#include <stdio.h>
#include <stdbool.h>
int main(int argc, char *argv[]) {
const int compiled = SDL_VERSION; /* hardcoded number from SDL headers */
const int linked = SDL_GetVersion(); /* reported by linked SDL library */
SDL_Log("We compiled against SDL version %d.%d.%d ...\n",
SDL_VERSIONNUM_MAJOR(compiled),
SDL_VERSIONNUM_MINOR(compiled),
SDL_VERSIONNUM_MICRO(compiled));
SDL_Log("But we are linking against SDL version %d.%d.%d.\n",
SDL_VERSIONNUM_MAJOR(linked),
SDL_VERSIONNUM_MINOR(linked),
SDL_VERSIONNUM_MICRO(linked));
if (SDL_Init(SDL_INIT_VIDEO) == 0) {
SDL_Log("SDL_Init Error: %s\n", SDL_GetError());
return 1;
}
SDL_Window *window = SDL_CreateWindow(
"SDL3 KeySym Example",
800, 600,
SDL_WINDOW_OPENGL
);
if (!window) {
SDL_Log("SDL_CreateWindow Error: %s\n", SDL_GetError());
SDL_Quit();
return 1;
}
bool running = true;
SDL_Event event;
printf("Press keys on the keyboard. Press ESC or close the window to quit.\n");
while (running) {
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_EVENT_QUIT:
running = false;
break;
case SDL_EVENT_KEY_DOWN:
printf("Key pressed: key = %d\n",
event.key.key);
break;
default:
break;
}
}
SDL_Delay(10); // reduce CPU usage
}
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
Activity
cgutman commentedon Apr 20, 2025
This change is due to a combination of SDL3's improved X11 IME support and the fact that SDL2 (but not SDL3) enables text input (read: IME input) by default.
Because the circumflex key is a dead key used to compose accented characters, this is not delivered to the app as a normal key press. It is consumed by the IME which then waits for the next character to accent. You will get a
SDL_EVENT_TEXT_INPUT
for the accented character once you press another letter on the keyboard.For SDL2 apps, you should call
SDL_StopTextInput()
after initializing the video subsystem if you want to receive all keypresses without any IME interference. On SDL3, text input is disabled by default, so this is why you get events for dead keys by default.Now with all that said, the Wayland driver on SDL3 actually sends both the
SDL_EVENT_KEY_DOWN
andSDL_EVENT_TEXT_INPUT
events in this scenario, which I think is the safer option (and what SDL2 did). I created a PR to change the X11 driver to do the same.serpilliere commentedon Apr 21, 2025
Hi @cgutman,
I just tested the
SDL_StopTextInput
, and everything is ok: Thanks for this!Thank you for the fix to mimic wayland @cgutman !
Can I close the issue or wait for the PR merge?
cgutman commentedon Apr 22, 2025
Let's keep this open until we decide if we want to change SDL3's X11 behavior to match Wayland and SDL2.