Commit 79cd8cab08615a656e51b021e0e8397fd869d1a3

Cameron Gutman 2021-01-27T20:41:36

Add default handler for Alt+Tab while keyboard grab is enabled By default, we will minimize the window when we receive Alt+Tab with a full-screen keyboard grabbed window to allow the user to escape the full-screen application. Some applications like remote desktop clients may want to handle Alt+Tab themselves, so provide an opt-out via SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED=0.

diff --git a/include/SDL_hints.h b/include/SDL_hints.h
index bacfe17..5c320dc 100644
--- a/include/SDL_hints.h
+++ b/include/SDL_hints.h
@@ -1587,6 +1587,19 @@ extern "C" {
  */
 #define SDL_HINT_AUDIO_DEVICE_STREAM_NAME "SDL_AUDIO_DEVICE_STREAM_NAME"
 
+/**
+ *  \brief Specify the behavior of Alt+Tab while the keyboard is grabbed.
+ *
+ * By default, SDL emulates Alt+Tab functionality while the keyboard is grabbed
+ * and your window is full-screen. This prevents the user from getting stuck in
+ * your application if you've enabled keyboard grab.
+ *
+ * The variable can be set to the following values:
+ *   "0"       - SDL will not handle Alt+Tab. Your application is responsible
+                 for handling Alt+Tab while the keyboard is grabbed.
+ *   "1"       - SDL will minimize your window when Alt+Tab is pressed (default)
+*/
+#define SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED "SDL_ALLOW_ALT_TAB_WHILE_GRABBED"
 
 /**
  *  \brief Override for SDL_GetPreferredLocales()
diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c
index 356f6f5..c0a541d 100644
--- a/src/events/SDL_keyboard.c
+++ b/src/events/SDL_keyboard.c
@@ -22,6 +22,7 @@
 
 /* General keyboard handling code for SDL */
 
+#include "SDL_hints.h"
 #include "SDL_timer.h"
 #include "SDL_events.h"
 #include "SDL_events_c.h"
@@ -799,6 +800,22 @@ SDL_SendKeyboardKeyInternal(Uint8 source, Uint8 state, SDL_Scancode scancode)
         event.key.windowID = keyboard->focus ? keyboard->focus->id : 0;
         posted = (SDL_PushEvent(&event) > 0);
     }
+
+    /* If the keyboard is grabbed and the grabbed window is in full-screen,
+       minimize the window when we receive Alt+Tab, unless the application
+       has explicitly opted out of this behavior. */
+    if (keycode == SDLK_TAB &&
+        state == SDL_PRESSED &&
+        (keyboard->modstate & KMOD_ALT) &&
+        keyboard->focus &&
+        (keyboard->focus->flags & SDL_WINDOW_KEYBOARD_GRABBED) &&
+        (keyboard->focus->flags & SDL_WINDOW_FULLSCREEN) &&
+        SDL_GetHintBoolean(SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED, SDL_TRUE)) {
+        /* We will temporarily forfeit our grab by minimizing our window, 
+           allowing the user to escape the application */
+        SDL_MinimizeWindow(keyboard->focus);
+    }
+    
     return (posted);
 }