SDL: x11: Register the input context destroyed callback (105ad)

From 105ad5e875d2c4084525469abc22f894a956776a 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).

(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 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;