From 105ad5e875d2c4084525469abc22f894a956776a Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Tue, 28 Jul 2026 15:22:52 -0400 Subject: [PATCH] x11: Register the input context destroyed callback Register the destroyed callback to handle cases where the IC is suddenly no longer valid (e.g. if ibus or fcitx dies). (cherry picked from commit 63bf4c1c79ce656d429c548ea5530c83f508bde7) --- src/video/x11/SDL_x11keyboard.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/video/x11/SDL_x11keyboard.c b/src/video/x11/SDL_x11keyboard.c index 5f86c5667d..f89d98ada6 100644 --- a/src/video/x11/SDL_x11keyboard.c +++ b/src/video/x11/SDL_x11keyboard.c @@ -712,6 +712,12 @@ static void preedit_caret_callback(XIC xic, XPointer client_data, XIMPreeditCare } } +static void ic_destroyed_handler(XIC ic, XPointer clientData, XPointer callData) +{ + SDL_WindowData *data = (SDL_WindowData *)clientData; + data->ic = NULL; +} + void X11_CreateInputContext(SDL_WindowData *data) { #ifdef X_HAVE_UTF8_STRING @@ -719,6 +725,11 @@ void X11_CreateInputContext(SDL_WindowData *data) if (SDL_X11_HAVE_UTF8 && videodata->im) { const char *hint = SDL_GetHint(SDL_HINT_IME_IMPLEMENTED_UI); + + XIMCallback destroyed_callback; + destroyed_callback.client_data = (XPointer)data; + destroyed_callback.callback = (XIMProc)ic_destroyed_handler; + if (hint && SDL_strstr(hint, "composition")) { XIMCallback draw_callback; draw_callback.client_data = (XPointer)data; @@ -747,6 +758,7 @@ void X11_CreateInputContext(SDL_WindowData *data) XNInputStyle, XIMPreeditCallbacks | XIMStatusCallbacks, XNPreeditAttributes, attr, XNClientWindow, data->xwindow, + XNDestroyCallback, &destroyed_callback, NULL); X11_XFree(attr); } @@ -755,6 +767,7 @@ void X11_CreateInputContext(SDL_WindowData *data) data->ic = X11_XCreateIC(videodata->im, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, data->xwindow, + XNDestroyCallback, &destroyed_callback, NULL); } data->xim_spot.x = -1;