With Wayland, SDL2 SDL_KEYUP/SDLKEYDOWN values are completely garbled which makes apps unusable [reproduction steps inside]
I tested this on the PinePhone with postmarketOS and phosh 0.4.1.
In Wayland mode, SDL2's keyboard events seem to be somehow messed up with squeekboard right now. This basically makes all apps using SDL2 relying on SDL_KEYUP/SDL_KEYDOWN events (which should be the vast majority of them) unusable. The SDL_TEXTINPUT events are fine, but most SDL2 apps need both.
Here is a minimal test app you can compile yourself with gcc -o ./testapp ./main.c -lSDL2
(no problem to compile it right on the phone, should be quick):
main.c
:
#include <SDL2/SDL.h>
#include <signal.h>
volatile _Atomic int sigterm_received = 0;
volatile _Atomic int sigint_received = 0;
void handle_sigterm(int signum) {
sigterm_received = 1;
}
void handle_sigint(int signum) {
sigint_received = 1;
}
int main(int argc, const char **argv) {
signal(SIGTERM, handle_sigterm);
signal(SIGINT, handle_sigint);
printf("testapp: verbose: running SDL_Init()\n");
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_EVENTS|SDL_INIT_TIMER) < 0) {
fprintf(stderr, "testapp: error: SDL_Init() failed\n");
return 1;
}
printf("testapp: verbose: opening window\n");
SDL_Window *window = SDL_CreateWindow(
"testapp", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
512, 512, SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI |
SDL_WINDOW_OPENGL
);
if (!window) {
fprintf(stderr, "testapp: error: SDL_CreateWindow() failed\n");
return 1;
}
printf("testapp: verbose: entering event loop\n");
int windowclosed = 0;
while (!sigterm_received && !sigint_received && !windowclosed) {
SDL_Event e;
while (SDL_PollEvent(&e) > 0) {
switch (e.type) {
case SDL_QUIT: {
windowclosed = 1;
break;
}
case SDL_WINDOWEVENT: {
if (e.window.event ==
SDL_WINDOWEVENT_CLOSE) {
windowclosed = 1;
break;
}
break;
}
case SDL_KEYDOWN: {
printf(
"testapp: verbose: "
"SDL_KEYDOWN: keysym.sym=%d\n",
(int)e.key.keysym.sym
);
break;
}
}
}
SDL_Surface *srf = SDL_GetWindowSurface(window);
SDL_FillRect(
srf, NULL, SDL_MapRGB(srf->format, 255, 200, 220)
);
SDL_UpdateWindowSurface(window);
SDL_Delay(100);
}
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
Launch it via: SDL_VIDEODRIVER=wayland ./testapp
Here is the output when I press the C key on squeekboard three times, then on my bluetooth keyboard press the C key three times:
$ SDL_VIDEODRIVER=wayland ./testapp
testapp: verbose: running SDL_Init()
testapp: verbose: opening window
testapp: verbose: entering event loop
testapp: verbose: SDL_KEYDOWN: keysym.sym=1073742106
testapp: verbose: SDL_KEYDOWN: keysym.sym=1073742106
testapp: verbose: SDL_KEYDOWN: keysym.sym=1073742106
testapp: verbose: SDL_KEYDOWN: keysym.sym=99
testapp: verbose: SDL_KEYDOWN: keysym.sym=99
testapp: verbose: SDL_KEYDOWN: keysym.sym=99
From SDL2/SDL_Keycode.h
, here is what key.keysym.sym
should be for the C key:
typedef enum
{
...
SDLK_c = 'c',
...
} SDL_KeyCode;
The ascii code for 'c'
is 99, so the squeekboard-triggered value of 1073742106
is complete garbage.
While the X11 mode works, it has broken touch events, no high dpi, and probably isn't worth fixing while the Wayland mode is.