SDL: x11: Register the input context destroyed callback

From 63bf4c1c79ce656d429c548ea5530c83f508bde7 Mon Sep 17 00:00:00 2001
From: Frank Praznik <[EMAIL REDACTED]>
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).
---
 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 5f86c5667dc74..f89d98ada6d12 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;