Browse Source

Added SDL_WINDOWEVENT_TAKE_FOCUS.

This is for corner cases where a multi-window app is activated and wants to
make a decision about where focus should go.

This patch came from Unreal Engine 4's fork of SDL, compliments of Epic Games.
Ryan C. Gordon 9 years ago
parent
commit
dc532c70e8

+ 2 - 1
include/SDL_video.h

@@ -161,7 +161,8 @@ typedef enum
     SDL_WINDOWEVENT_FOCUS_GAINED,   /**< Window has gained keyboard focus */
     SDL_WINDOWEVENT_FOCUS_LOST,     /**< Window has lost keyboard focus */
     SDL_WINDOWEVENT_CLOSE,          /**< The window manager requests that the window be closed */
-    SDL_WINDOWEVENT_HIT_TEST        /** Window had a hit test that wasn't SDL_HITTEST_NORMAL. */
+    SDL_WINDOWEVENT_TAKE_FOCUS,     /**< Window is being offered a focus (should SetWindowInputFocus() on itself or a subwindow, or ignore) */
+    SDL_WINDOWEVENT_HIT_TEST        /**< Window had a hit test that wasn't SDL_HITTEST_NORMAL. */
 } SDL_WindowEventID;
 
 /**

+ 10 - 0
src/video/x11/SDL_x11events.c

@@ -979,6 +979,16 @@ X11_DispatchEvent(_THIS)
                 SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_CLOSE, 0, 0);
                 break;
             }
+            else if ((xevent.xclient.message_type == videodata->WM_PROTOCOLS) &&
+                (xevent.xclient.format == 32) &&
+                (xevent.xclient.data.l[0] == videodata->WM_TAKE_FOCUS)) {
+
+#ifdef DEBUG_XEVENTS
+                printf("window %p: WM_TAKE_FOCUS\n", data);
+#endif
+                SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_TAKE_FOCUS, 0, 0);
+                break;
+            }
         }
         break;
 

+ 1 - 0
src/video/x11/SDL_x11video.c

@@ -395,6 +395,7 @@ X11_VideoInit(_THIS)
 #define GET_ATOM(X) data->X = X11_XInternAtom(data->display, #X, False)
     GET_ATOM(WM_PROTOCOLS);
     GET_ATOM(WM_DELETE_WINDOW);
+    GET_ATOM(WM_TAKE_FOCUS);
     GET_ATOM(_NET_WM_STATE);
     GET_ATOM(_NET_WM_STATE_HIDDEN);
     GET_ATOM(_NET_WM_STATE_FOCUSED);

+ 1 - 0
src/video/x11/SDL_x11video.h

@@ -89,6 +89,7 @@ typedef struct SDL_VideoData
     /* Useful atoms */
     Atom WM_PROTOCOLS;
     Atom WM_DELETE_WINDOW;
+    Atom WM_TAKE_FOCUS;
     Atom _NET_WM_STATE;
     Atom _NET_WM_STATE_HIDDEN;
     Atom _NET_WM_STATE_FOCUSED;

+ 5 - 6
src/video/x11/SDL_x11window.c

@@ -574,18 +574,17 @@ X11_CreateWindow(_THIS, SDL_Window * window)
                     (unsigned char *)&compositor, 1);
 
     {
-        Atom protocols[2];
+        Atom protocols[3];
         int proto_count = 0;
         const char *ping_hint;
 
-        protocols[proto_count] = data->WM_DELETE_WINDOW; /* Allow window to be deleted by the WM */
-        proto_count++;
-        
+        protocols[proto_count++] = data->WM_DELETE_WINDOW; /* Allow window to be deleted by the WM */
+        protocols[proto_count++] = data->WM_TAKE_FOCUS; /* Since we will want to set input focus explicitly */
+
         ping_hint = SDL_GetHint(SDL_HINT_VIDEO_X11_NET_WM_PING);
         /* Default to using ping if there is no hint */
         if (!ping_hint || SDL_atoi(ping_hint)) {
-            protocols[proto_count] = data->_NET_WM_PING; /* Respond so WM knows we're alive */
-            proto_count++;
+            protocols[proto_count++] = data->_NET_WM_PING; /* Respond so WM knows we're alive */
         }
 
         SDL_assert(proto_count <= sizeof(protocols) / sizeof(protocols[0]));