SDL: Enable events for external X11 windows

From c7093858569969d07c641765c4f17c4c12b2d208 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sun, 4 Aug 2024 08:22:35 -0700
Subject: [PATCH] Enable events for external X11 windows

Fixes https://github.com/libsdl-org/SDL/issues/3825
Fixes https://github.com/libsdl-org/SDL/issues/5142
Fixes https://github.com/libsdl-org/SDL/issues/9503
---
 src/video/x11/SDL_x11window.c | 68 ++++++++++++++++++++---------------
 1 file changed, 39 insertions(+), 29 deletions(-)

diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c
index 3fe3cd588141c..d0cd1b558d789 100644
--- a/src/video/x11/SDL_x11window.c
+++ b/src/video/x11/SDL_x11window.c
@@ -421,6 +421,42 @@ static int SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, Window w)
     return 0;
 }
 
+static void SetupWindowInput(SDL_VideoDevice *_this, SDL_Window *window)
+{
+    long fevent = 0;
+    SDL_WindowData *data = window->internal;
+    Window xwindow = data->xwindow;
+
+#ifdef X_HAVE_UTF8_STRING
+    if (SDL_X11_HAVE_UTF8 && data->ic) {
+        X11_XGetICValues(data->ic, XNFilterEvents, &fevent, NULL);
+    }
+#endif
+
+    X11_Xinput2SelectTouch(_this, window);
+
+    {
+        unsigned int x11_keyboard_events = KeyPressMask | KeyReleaseMask;
+        unsigned int x11_pointer_events = ButtonPressMask | ButtonReleaseMask | PointerMotionMask;
+
+        X11_Xinput2SelectMouseAndKeyboard(_this, window);
+
+        /* If XInput2 can handle pointer and keyboard events, we don't track them here */
+        if (data->xinput2_keyboard_enabled) {
+            x11_keyboard_events = 0;
+        }
+        if (data->xinput2_mouse_enabled) {
+            x11_pointer_events = 0;
+        }
+
+        X11_XSelectInput(data->videodata->display, xwindow,
+                         (FocusChangeMask | EnterWindowMask | LeaveWindowMask | ExposureMask |
+                          x11_keyboard_events | x11_pointer_events |
+                          PropertyChangeMask | StructureNotifyMask |
+                          KeymapStateMask | fevent));
+    }
+}
+
 static void SetWindowBordered(Display *display, int screen, Window window, SDL_bool border)
 {
     /*
@@ -461,6 +497,8 @@ int X11_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesI
         if (SetupWindowData(_this, window, w) < 0) {
             return -1;
         }
+
+        SetupWindowInput(_this, window);
         return 0;
     }
 
@@ -486,7 +524,6 @@ int X11_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesI
     const char *wintype_name = NULL;
     long compositor = 1;
     Atom _NET_WM_PID;
-    long fevent = 0;
     const char *hint = NULL;
     int win_x, win_y;
     SDL_bool undefined_position = SDL_FALSE;
@@ -783,12 +820,6 @@ int X11_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesI
     }
 #endif
 
-#ifdef X_HAVE_UTF8_STRING
-    if (SDL_X11_HAVE_UTF8 && windowdata->ic) {
-        X11_XGetICValues(windowdata->ic, XNFilterEvents, &fevent, NULL);
-    }
-#endif
-
 #ifdef SDL_VIDEO_DRIVER_X11_XSHAPE
     /* Tooltips do not receive input */
     if (window->flags & SDL_WINDOW_TOOLTIP) {
@@ -798,28 +829,7 @@ int X11_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesI
     }
 #endif
 
-    X11_Xinput2SelectTouch(_this, window);
-
-    {
-        unsigned int x11_keyboard_events = KeyPressMask | KeyReleaseMask;
-        unsigned int x11_pointer_events = ButtonPressMask | ButtonReleaseMask | PointerMotionMask;
-
-        X11_Xinput2SelectMouseAndKeyboard(_this, window);
-
-        /* If XInput2 can handle pointer and keyboard events, we don't track them here */
-        if (windowdata->xinput2_keyboard_enabled) {
-            x11_keyboard_events = 0;
-        }
-        if (windowdata->xinput2_mouse_enabled) {
-            x11_pointer_events = 0;
-        }
-
-        X11_XSelectInput(display, w,
-                         (FocusChangeMask | EnterWindowMask | LeaveWindowMask | ExposureMask |
-                          x11_keyboard_events | x11_pointer_events |
-                          PropertyChangeMask | StructureNotifyMask |
-                          KeymapStateMask | fevent));
-    }
+    SetupWindowInput(_this, window);
 
     /* For _ICC_PROFILE. */
     X11_XSelectInput(display, RootWindow(display, screen), PropertyChangeMask);