SDL: SDL_WINDOW_FULLSCREEN and SDL_WINDOW_FULLSCREEN_DESKTOP are now distinct flags

From e83c54f2712bcbc461d7193e844c4358b2f4be09 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sat, 28 Jan 2023 09:52:31 -0800
Subject: [PATCH] SDL_WINDOW_FULLSCREEN and SDL_WINDOW_FULLSCREEN_DESKTOP are
 now distinct flags

---
 build-scripts/SDL_migration.cocci           |  4 ++
 docs/README-migration.md                    |  1 +
 docs/README-winrt.md                        |  2 +-
 include/SDL3/SDL_oldnames.h                 |  2 +
 include/SDL3/SDL_shape.h                    |  2 +-
 include/SDL3/SDL_video.h                    | 50 ++++++-------
 src/SDL_assert.c                            |  2 +-
 src/core/winrt/SDL_winrtapp_direct3d.cpp    |  2 +-
 src/events/SDL_keyboard.c                   |  4 +-
 src/events/SDL_windowevents.c               |  4 +-
 src/render/direct3d/SDL_render_d3d.c        |  4 +-
 src/test/SDL_test_common.c                  | 28 ++++----
 src/video/SDL_shape.c                       |  2 +-
 src/video/SDL_sysvideo.h                    |  8 +--
 src/video/SDL_video.c                       | 80 +++++++++++----------
 src/video/cocoa/SDL_cocoawindow.m           | 39 +++++-----
 src/video/emscripten/SDL_emscriptenevents.c | 10 ++-
 src/video/emscripten/SDL_emscriptenvideo.c  |  6 +-
 src/video/emscripten/SDL_emscriptenvideo.h  |  2 +-
 src/video/haiku/SDL_bwindow.cc              |  2 +-
 src/video/kmsdrm/SDL_kmsdrmvideo.c          |  2 +-
 src/video/psp/SDL_pspgl.c                   |  2 +-
 src/video/riscos/SDL_riscoswindow.c         |  2 +-
 src/video/uikit/SDL_uikitviewcontroller.m   |  4 +-
 src/video/uikit/SDL_uikitwindow.m           |  4 +-
 src/video/vita/SDL_vitagles.c               |  2 +-
 src/video/wayland/SDL_waylandwindow.c       | 22 +++---
 src/video/windows/SDL_windowsevents.c       |  2 +-
 src/video/windows/SDL_windowswindow.c       | 12 ++--
 src/video/winrt/SDL_winrtvideo.cpp          | 12 ++--
 src/video/x11/SDL_x11events.c               | 10 +--
 src/video/x11/SDL_x11window.c               | 28 +++++---
 test/testautomation_video.c                 |  2 +-
 test/testwm.c                               |  2 +-
 34 files changed, 193 insertions(+), 167 deletions(-)

diff --git a/build-scripts/SDL_migration.cocci b/build-scripts/SDL_migration.cocci
index 5ffb57ac345e..f167a156ae81 100644
--- a/build-scripts/SDL_migration.cocci
+++ b/build-scripts/SDL_migration.cocci
@@ -2326,3 +2326,7 @@ expression e;
 - SDL_GetDisplayDPI
 + SDL_GetDisplayPhysicalDPI
   (...)
+@@
+@@
+- SDL_WINDOW_FULLSCREEN
++ SDL_WINDOW_FULLSCREEN_EXCLUSIVE
diff --git a/docs/README-migration.md b/docs/README-migration.md
index 723a0cda5124..67cadb4bad15 100644
--- a/docs/README-migration.md
+++ b/docs/README-migration.md
@@ -977,6 +977,7 @@ The following functions have been renamed:
 
 SDL_Window id type is named SDL_WindowID
 
+SDL_WINDOW_FULLSCREEN has been renamed SDL_WINDOW_FULLSCREEN_EXCLUSIVE, and SDL_WINDOW_FULLSCREEN_DESKTOP no longer includes the old SDL_WINDOW_FULLSCREEN flag. You can use `(SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN_MASK) != 0` if you want to check for either state.
 
 ## SDL_vulkan.h
 
diff --git a/docs/README-winrt.md b/docs/README-winrt.md
index ffb0ae822629..8f7bbbe3fb45 100644
--- a/docs/README-winrt.md
+++ b/docs/README-winrt.md
@@ -343,7 +343,7 @@ int main(int argc, char **argv)
         return 1;
     } else if (SDL_GetCurrentDisplayMode(0, &mode) != 0) {
         return 1;
-    } else if (SDL_CreateWindowAndRenderer(mode.w, mode.h, SDL_WINDOW_FULLSCREEN, &window, &renderer) != 0) {
+    } else if (SDL_CreateWindowAndRenderer(mode.w, mode.h, SDL_WINDOW_FULLSCREEN_EXCLUSIVE, &window, &renderer) != 0) {
         return 1;
     }
     
diff --git a/include/SDL3/SDL_oldnames.h b/include/SDL3/SDL_oldnames.h
index e1efb021126f..ded0461a5cdf 100644
--- a/include/SDL3/SDL_oldnames.h
+++ b/include/SDL3/SDL_oldnames.h
@@ -415,6 +415,7 @@
 #define SDL_GetDisplayDPI SDL_GetDisplayPhysicalDPI
 #define SDL_GetPointDisplayIndex SDL_GetDisplayIndexForPoint
 #define SDL_GetRectDisplayIndex SDL_GetDisplayIndexForRect
+#define SDL_WINDOW_FULLSCREEN SDL_WINDOW_FULLSCREEN_EXCLUSIVE
 
 #elif !defined(SDL_DISABLE_OLD_NAMES)
 
@@ -795,6 +796,7 @@
 #define SDL_GetDisplayDPI SDL_GetDisplayDPI_renamed_SDL_GetDisplayPhysicalDPI
 #define SDL_GetPointDisplayIndex SDL_GetPointDisplayIndex_renamed_SDL_GetDisplayIndexForPoint
 #define SDL_GetRectDisplayIndex SDL_GetRectDisplayIndex_renamed_SDL_GetDisplayIndexForRect
+#define SDL_WINDOW_FULLSCREEN SDL_WINDOW_FULLSCREEN_renamed_SDL_WINDOW_FULLSCREEN_EXCLUSIVE
 
 #endif /* SDL_ENABLE_OLD_NAMES */
 
diff --git a/include/SDL3/SDL_shape.h b/include/SDL3/SDL_shape.h
index c3e286548bc1..afc5833f01c7 100644
--- a/include/SDL3/SDL_shape.h
+++ b/include/SDL3/SDL_shape.h
@@ -59,7 +59,7 @@ extern "C" {
  *              ::SDL_WINDOW_INPUT_GRABBED, ::SDL_WINDOW_HIDDEN,
  *              ::SDL_WINDOW_RESIZABLE, ::SDL_WINDOW_MAXIMIZED,
  *              ::SDL_WINDOW_MINIMIZED, ::SDL_WINDOW_BORDERLESS is always set,
- *              and ::SDL_WINDOW_FULLSCREEN is always unset.
+ *              and ::SDL_WINDOW_FULLSCREEN_MASK is always unset.
  * \return the window created, or NULL if window creation failed.
  *
  * \since This function is available since SDL 3.0.0.
diff --git a/include/SDL3/SDL_video.h b/include/SDL3/SDL_video.h
index 7d7066b9941b..cefa8c21eb0d 100644
--- a/include/SDL3/SDL_video.h
+++ b/include/SDL3/SDL_video.h
@@ -107,33 +107,35 @@ typedef struct SDL_Window SDL_Window;
  */
 typedef enum
 {
-    SDL_WINDOW_FULLSCREEN = 0x00000001,         /**< fullscreen window */
-    SDL_WINDOW_OPENGL = 0x00000002,             /**< window usable with OpenGL context */
+    SDL_WINDOW_FULLSCREEN_EXCLUSIVE = 0x00000001,   /**< window is in fullscreen exclusive mode */
+    SDL_WINDOW_OPENGL               = 0x00000002,   /**< window usable with OpenGL context */
     /* 0x00000004 was SDL_WINDOW_SHOWN in SDL2, please reserve this bit for sdl2-compat. */
-    SDL_WINDOW_HIDDEN = 0x00000008,             /**< window is not visible */
-    SDL_WINDOW_BORDERLESS = 0x00000010,         /**< no window decoration */
-    SDL_WINDOW_RESIZABLE = 0x00000020,          /**< window can be resized */
-    SDL_WINDOW_MINIMIZED = 0x00000040,          /**< window is minimized */
-    SDL_WINDOW_MAXIMIZED = 0x00000080,          /**< window is maximized */
-    SDL_WINDOW_MOUSE_GRABBED = 0x00000100,      /**< window has grabbed mouse input */
-    SDL_WINDOW_INPUT_FOCUS = 0x00000200,        /**< window has input focus */
-    SDL_WINDOW_MOUSE_FOCUS = 0x00000400,        /**< window has mouse focus */
-    SDL_WINDOW_FULLSCREEN_DESKTOP = ( SDL_WINDOW_FULLSCREEN | 0x00001000 ),
-    SDL_WINDOW_FOREIGN = 0x00000800,            /**< window not created by SDL */
+    SDL_WINDOW_HIDDEN               = 0x00000008,   /**< window is not visible */
+    SDL_WINDOW_BORDERLESS           = 0x00000010,   /**< no window decoration */
+    SDL_WINDOW_RESIZABLE            = 0x00000020,   /**< window can be resized */
+    SDL_WINDOW_MINIMIZED            = 0x00000040,   /**< window is minimized */
+    SDL_WINDOW_MAXIMIZED            = 0x00000080,   /**< window is maximized */
+    SDL_WINDOW_MOUSE_GRABBED        = 0x00000100,   /**< window has grabbed mouse input */
+    SDL_WINDOW_INPUT_FOCUS          = 0x00000200,   /**< window has input focus */
+    SDL_WINDOW_MOUSE_FOCUS          = 0x00000400,   /**< window has mouse focus */
+    SDL_WINDOW_FULLSCREEN_DESKTOP   = 0x00001000,   /**< window is in fullscreen desktop mode */
+    SDL_WINDOW_FOREIGN              = 0x00000800,   /**< window not created by SDL */
     /* 0x00002000 was SDL_WINDOW_ALLOW_HIGHDPI in SDL2, please reserve this bit for sdl2-compat. */
-    SDL_WINDOW_MOUSE_CAPTURE    = 0x00004000,   /**< window has mouse captured (unrelated to MOUSE_GRABBED) */
-    SDL_WINDOW_ALWAYS_ON_TOP    = 0x00008000,   /**< window should always be above others */
-    SDL_WINDOW_SKIP_TASKBAR     = 0x00010000,   /**< window should not be added to the taskbar */
-    SDL_WINDOW_UTILITY          = 0x00020000,   /**< window should be treated as a utility window */
-    SDL_WINDOW_TOOLTIP          = 0x00040000,   /**< window should be treated as a tooltip */
-    SDL_WINDOW_POPUP_MENU       = 0x00080000,   /**< window should be treated as a popup menu */
-    SDL_WINDOW_KEYBOARD_GRABBED = 0x00100000,   /**< window has grabbed keyboard input */
-    SDL_WINDOW_VULKAN           = 0x10000000,   /**< window usable for Vulkan surface */
-    SDL_WINDOW_METAL            = 0x20000000,   /**< window usable for Metal view */
+    SDL_WINDOW_MOUSE_CAPTURE        = 0x00004000,   /**< window has mouse captured (unrelated to MOUSE_GRABBED) */
+    SDL_WINDOW_ALWAYS_ON_TOP        = 0x00008000,   /**< window should always be above others */
+    SDL_WINDOW_SKIP_TASKBAR         = 0x00010000,   /**< window should not be added to the taskbar */
+    SDL_WINDOW_UTILITY              = 0x00020000,   /**< window should be treated as a utility window */
+    SDL_WINDOW_TOOLTIP              = 0x00040000,   /**< window should be treated as a tooltip */
+    SDL_WINDOW_POPUP_MENU           = 0x00080000,   /**< window should be treated as a popup menu */
+    SDL_WINDOW_KEYBOARD_GRABBED     = 0x00100000,   /**< window has grabbed keyboard input */
+    SDL_WINDOW_VULKAN               = 0x10000000,   /**< window usable for Vulkan surface */
+    SDL_WINDOW_METAL                = 0x20000000,   /**< window usable for Metal view */
 
     SDL_WINDOW_INPUT_GRABBED = SDL_WINDOW_MOUSE_GRABBED /**< equivalent to SDL_WINDOW_MOUSE_GRABBED for compatibility */
 } SDL_WindowFlags;
 
+#define SDL_WINDOW_FULLSCREEN_MASK  (SDL_WINDOW_FULLSCREEN_EXCLUSIVE | SDL_WINDOW_FULLSCREEN_DESKTOP)
+
 /**
  *  \brief Used to indicate that you don't care what the window position is.
  */
@@ -646,7 +648,7 @@ extern DECLSPEC Uint32 SDLCALL SDL_GetWindowPixelFormat(SDL_Window *window);
  *
  * `flags` may be any of the following OR'd together:
  *
- * - `SDL_WINDOW_FULLSCREEN`: fullscreen window
+ * - `SDL_WINDOW_FULLSCREEN_EXCLUSIVE`: fullscreen window, switching display mode to the closest fullscreen resolution
  * - `SDL_WINDOW_FULLSCREEN_DESKTOP`: fullscreen window at desktop resolution
  * - `SDL_WINDOW_OPENGL`: window usable with an OpenGL context
  * - `SDL_WINDOW_VULKAN`: window usable with a Vulkan instance
@@ -1157,12 +1159,12 @@ extern DECLSPEC void SDLCALL SDL_RestoreWindow(SDL_Window *window);
 /**
  * Set a window's fullscreen state.
  *
- * `flags` may be `SDL_WINDOW_FULLSCREEN`, for "real" fullscreen with a
+ * `flags` may be `SDL_WINDOW_FULLSCREEN_EXCLUSIVE`, for "real" fullscreen with a
  * videomode change; `SDL_WINDOW_FULLSCREEN_DESKTOP` for "fake" fullscreen
  * that takes the size of the desktop; and 0 for windowed mode.
  *
  * \param window the window to change
- * \param flags `SDL_WINDOW_FULLSCREEN`, `SDL_WINDOW_FULLSCREEN_DESKTOP` or 0
+ * \param flags `SDL_WINDOW_FULLSCREEN_EXCLUSIVE`, `SDL_WINDOW_FULLSCREEN_DESKTOP` or 0
  * \returns 0 on success or a negative error code on failure; call
  *          SDL_GetError() for more information.
  *
diff --git a/src/SDL_assert.c b/src/SDL_assert.c
index a6d903c3d2d1..63452a387257 100644
--- a/src/SDL_assert.c
+++ b/src/SDL_assert.c
@@ -213,7 +213,7 @@ static SDL_AssertState SDLCALL SDL_PromptAssertion(const SDL_AssertData *data, v
     /* Leave fullscreen mode, if possible (scary!) */
     window = SDL_GetFocusWindow();
     if (window) {
-        if (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) {
+        if ((SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN_MASK) != 0) {
             SDL_MinimizeWindow(window);
         } else {
             /* !!! FIXME: ungrab the input if we're not fullscreen? */
diff --git a/src/core/winrt/SDL_winrtapp_direct3d.cpp b/src/core/winrt/SDL_winrtapp_direct3d.cpp
index 01d3a8afa344..15e21d7874da 100644
--- a/src/core/winrt/SDL_winrtapp_direct3d.cpp
+++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp
@@ -150,7 +150,7 @@ static void WINRT_ProcessWindowSizeChange() // TODO: Pass an SDL_Window-identify
                 SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESTORED, 0, 0);
             }
 
-            WINRT_UpdateWindowFlags(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
+            WINRT_UpdateWindowFlags(window, SDL_WINDOW_FULLSCREEN_MASK);
 
             /* The window can move during a resize event, such as when maximizing
                or resizing from a corner */
diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c
index a1186c3ac957..68b59c114235 100644
--- a/src/events/SDL_keyboard.c
+++ b/src/events/SDL_keyboard.c
@@ -930,8 +930,8 @@ static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, SDL_KeyboardFlags flags
         state == SDL_PRESSED &&
         (keyboard->modstate & SDL_KMOD_ALT) &&
         keyboard->focus &&
-        (keyboard->focus->flags & SDL_WINDOW_KEYBOARD_GRABBED) &&
-        (keyboard->focus->flags & SDL_WINDOW_FULLSCREEN) &&
+        (keyboard->focus->flags & SDL_WINDOW_KEYBOARD_GRABBED) != 0 &&
+        (keyboard->focus->flags & SDL_WINDOW_FULLSCREEN_MASK) != 0 &&
         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 */
diff --git a/src/events/SDL_windowevents.c b/src/events/SDL_windowevents.c
index 5e267ea259a5..d6adace54e52 100644
--- a/src/events/SDL_windowevents.c
+++ b/src/events/SDL_windowevents.c
@@ -102,7 +102,7 @@ int SDL_SendWindowEvent(SDL_Window *window, SDL_EventType windowevent,
             SDL_WINDOWPOS_ISUNDEFINED(data2)) {
             return 0;
         }
-        if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
+        if ((window->flags & SDL_WINDOW_FULLSCREEN_MASK) == 0) {
             window->windowed.x = data1;
             window->windowed.y = data2;
         }
@@ -114,7 +114,7 @@ int SDL_SendWindowEvent(SDL_Window *window, SDL_EventType windowevent,
         SDL_OnWindowMoved(window);
         break;
     case SDL_EVENT_WINDOW_RESIZED:
-        if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
+        if ((window->flags & SDL_WINDOW_FULLSCREEN_MASK) == 0) {
             window->windowed.w = data1;
             window->windowed.h = data2;
         }
diff --git a/src/render/direct3d/SDL_render_d3d.c b/src/render/direct3d/SDL_render_d3d.c
index 4aa34eca0046..5d5ee4ed2459 100644
--- a/src/render/direct3d/SDL_render_d3d.c
+++ b/src/render/direct3d/SDL_render_d3d.c
@@ -294,7 +294,7 @@ static int D3D_ActivateRenderer(SDL_Renderer *renderer)
         SDL_GetWindowSizeInPixels(window, &w, &h);
         data->pparams.BackBufferWidth = w;
         data->pparams.BackBufferHeight = h;
-        if (window_flags & SDL_WINDOW_FULLSCREEN && (window_flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) {
+        if ((window_flags & SDL_WINDOW_FULLSCREEN_EXCLUSIVE) != 0) {
             SDL_DisplayMode fullscreen_mode;
             SDL_GetWindowDisplayMode(window, &fullscreen_mode);
             data->pparams.Windowed = FALSE;
@@ -1623,7 +1623,7 @@ D3D_CreateRenderer(SDL_Window *window, Uint32 flags)
     pparams.BackBufferCount = 1;
     pparams.SwapEffect = D3DSWAPEFFECT_DISCARD;
 
-    if (window_flags & SDL_WINDOW_FULLSCREEN && (window_flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) {
+    if ((window_flags & SDL_WINDOW_FULLSCREEN_EXCLUSIVE) != 0) {
         pparams.Windowed = FALSE;
         pparams.BackBufferFormat = PixelFormatToD3DFMT(fullscreen_mode.format);
         pparams.FullScreen_RefreshRateInHz = (UINT)SDL_ceilf(fullscreen_mode.refresh_rate);
diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c
index 8b961ec86c51..4b988f041ffd 100644
--- a/src/test/SDL_test_common.c
+++ b/src/test/SDL_test_common.c
@@ -242,7 +242,7 @@ int SDLTest_CommonArg(SDLTest_CommonState *state, int index)
         return 1;
     }
     if (SDL_strcasecmp(argv[index], "--fullscreen") == 0) {
-        state->window_flags |= SDL_WINDOW_FULLSCREEN;
+        state->window_flags |= SDL_WINDOW_FULLSCREEN_EXCLUSIVE;
         state->num_windows = 1;
         return 1;
     }
@@ -256,7 +256,7 @@ int SDLTest_CommonArg(SDLTest_CommonState *state, int index)
         if (!argv[index] || !SDL_isdigit((unsigned char)*argv[index])) {
             return -1;
         }
-        if (!(state->window_flags & SDL_WINDOW_FULLSCREEN)) {
+        if ((state->window_flags & SDL_WINDOW_FULLSCREEN_MASK) == 0) {
             state->num_windows = SDL_atoi(argv[index]);
         }
         return 2;
@@ -676,8 +676,8 @@ static void SDLTest_PrintDisplayOrientation(char *text, size_t maxlen, SDL_Displ
 static void SDLTest_PrintWindowFlag(char *text, size_t maxlen, Uint32 flag)
 {
     switch (flag) {
-    case SDL_WINDOW_FULLSCREEN:
-        SDL_snprintfcat(text, maxlen, "FULLSCREEN");
+    case SDL_WINDOW_FULLSCREEN_EXCLUSIVE:
+        SDL_snprintfcat(text, maxlen, "FULLSCREEN_EXCLUSIVE");
         break;
     case SDL_WINDOW_OPENGL:
         SDL_snprintfcat(text, maxlen, "OPENGL");
@@ -748,7 +748,7 @@ static void SDLTest_PrintWindowFlag(char *text, size_t maxlen, Uint32 flag)
 static void SDLTest_PrintWindowFlags(char *text, size_t maxlen, Uint32 flags)
 {
     const Uint32 window_flags[] = {
-        SDL_WINDOW_FULLSCREEN,
+        SDL_WINDOW_FULLSCREEN_EXCLUSIVE,
         SDL_WINDOW_OPENGL,
         SDL_WINDOW_HIDDEN,
         SDL_WINDOW_BORDERLESS,
@@ -1730,13 +1730,13 @@ static void FullscreenTo(int index, int windowId)
     SDL_GetDisplayBounds(index, &rect);
 
     flags = SDL_GetWindowFlags(window);
-    if (flags & SDL_WINDOW_FULLSCREEN) {
+    if ((flags & SDL_WINDOW_FULLSCREEN_MASK) != 0) {
         SDL_SetWindowFullscreen(window, 0);
         SDL_Delay(15);
     }
 
     SDL_SetWindowPosition(window, rect.x, rect.y);
-    SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
+    SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_EXCLUSIVE);
 }
 
 void SDLTest_CommonEvent(SDLTest_CommonState *state, SDL_Event *event, int *done)
@@ -2015,10 +2015,10 @@ void SDLTest_CommonEvent(SDLTest_CommonState *state, SDL_Event *event, int *done
                 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
                 if (window) {
                     Uint32 flags = SDL_GetWindowFlags(window);
-                    if (flags & SDL_WINDOW_FULLSCREEN) {
-                        SDL_SetWindowFullscreen(window, SDL_FALSE);
+                    if ((flags & SDL_WINDOW_FULLSCREEN_MASK) != 0) {
+                        SDL_SetWindowFullscreen(window, 0);
                     } else {
-                        SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
+                        SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_EXCLUSIVE);
                     }
                 }
             } else if (withAlt) {
@@ -2026,8 +2026,8 @@ void SDLTest_CommonEvent(SDLTest_CommonState *state, SDL_Event *event, int *done
                 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
                 if (window) {
                     Uint32 flags = SDL_GetWindowFlags(window);
-                    if (flags & SDL_WINDOW_FULLSCREEN) {
-                        SDL_SetWindowFullscreen(window, SDL_FALSE);
+                    if ((flags & SDL_WINDOW_FULLSCREEN_MASK) != 0) {
+                        SDL_SetWindowFullscreen(window, 0);
                     } else {
                         SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
                     }
@@ -2037,8 +2037,8 @@ void SDLTest_CommonEvent(SDLTest_CommonState *state, SDL_Event *event, int *done
                 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
                 if (window) {
                     Uint32 flags = SDL_GetWindowFlags(window);
-                    if ((flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) {
-                        SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
+                    if ((flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0) {
+                        SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_EXCLUSIVE);
                     } else {
                         SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
                     }
diff --git a/src/video/SDL_shape.c b/src/video/SDL_shape.c
index 555418fec7dd..1ecb08ae0d9c 100644
--- a/src/video/SDL_shape.c
+++ b/src/video/SDL_shape.c
@@ -27,7 +27,7 @@ SDL_Window *
 SDL_CreateShapedWindow(const char *title, unsigned int x, unsigned int y, unsigned int w, unsigned int h, Uint32 flags)
 {
     SDL_Window *result = NULL;
-    result = SDL_CreateWindow(title, -1000, -1000, w, h, (flags | SDL_WINDOW_BORDERLESS) & (~SDL_WINDOW_FULLSCREEN) & (~SDL_WINDOW_RESIZABLE));
+    result = SDL_CreateWindow(title, -1000, -1000, w, h, (flags | SDL_WINDOW_BORDERLESS) & (~SDL_WINDOW_FULLSCREEN_MASK) & (~SDL_WINDOW_RESIZABLE));
     if (result != NULL) {
         if (SDL_GetVideoDevice()->shape_driver.CreateShaper == NULL) {
             SDL_DestroyWindow(result);
diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h
index 01bc7ed00fb0..b76b6faeffa8 100644
--- a/src/video/SDL_sysvideo.h
+++ b/src/video/SDL_sysvideo.h
@@ -108,10 +108,10 @@ struct SDL_Window
     SDL_Window *prev;
     SDL_Window *next;
 };
-#define FULLSCREEN_VISIBLE(W)                \
-    (((W)->flags & SDL_WINDOW_FULLSCREEN) && \
-     !((W)->flags & SDL_WINDOW_HIDDEN) &&      \
-     !((W)->flags & SDL_WINDOW_MINIMIZED))
+#define SDL_WINDOW_FULLSCREEN_VISIBLE(W)        \
+    ((((W)->flags & SDL_WINDOW_FULLSCREEN_MASK) != 0) &&   \
+     (((W)->flags & SDL_WINDOW_HIDDEN) == 0) && \
+     (((W)->flags & SDL_WINDOW_MINIMIZED) == 0))
 
 /*
  * Define the SDL display structure.
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index 8d4288d88f5b..3dc6ca9d8f95 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -151,8 +151,6 @@ static VideoBootStrap *bootstrap[] = {
         return retval;                                                  \
     }
 
-#define FULLSCREEN_MASK (SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN)
-
 #if defined(__MACOS__) && defined(SDL_VIDEO_DRIVER_COCOA)
 /* Support for macOS fullscreen spaces */
 extern SDL_bool Cocoa_IsWindowInFullscreenSpace(SDL_Window *window);
@@ -1298,7 +1296,7 @@ int SDL_SetWindowDisplayMode(SDL_Window *window, const SDL_DisplayMode *mode)
         SDL_zero(window->fullscreen_mode);
     }
 
-    if (FULLSCREEN_VISIBLE(window) && (window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) {
+    if (SDL_WINDOW_FULLSCREEN_VISIBLE(window) && (window->flags & SDL_WINDOW_FULLSCREEN_EXCLUSIVE) != 0) {
         SDL_DisplayMode fullscreen_mode;
         if (SDL_GetWindowDisplayMode(window, &fullscreen_mode) == 0) {
             if (SDL_SetDisplayModeForDisplay(SDL_GetDisplayForWindow(window), &fullscreen_mode) == 0) {
@@ -1338,7 +1336,7 @@ int SDL_GetWindowDisplayMode(SDL_Window *window, SDL_DisplayMode *mode)
     display = SDL_GetDisplayForWindow(window);
 
     /* if in desktop size mode, just return the size of the desktop */
-    if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) {
+    if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0) {
         fullscreen_mode = display->desktop_mode;
     } else if (!SDL_GetClosestDisplayModeForDisplay(SDL_GetDisplayForWindow(window),
                                                     &fullscreen_mode,
@@ -1403,16 +1401,20 @@ static int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen)
        do nothing, or else we may trigger an ugly double-transition
      */
     if (SDL_strcmp(_this->name, "cocoa") == 0) { /* don't do this for X11, etc */
-        if (window->is_destroying && (window->last_fullscreen_flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN_DESKTOP) {
+        if (window->is_destroying && (window->last_fullscreen_flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0) {
             return 0;
         }
 
         /* If we're switching between a fullscreen Space and "normal" fullscreen, we need to get back to normal first. */
-        if (fullscreen && ((window->last_fullscreen_flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN_DESKTOP) && ((window->flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN)) {
+        if (fullscreen &&
+            (window->last_fullscreen_flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0 &&
+            (window->flags & SDL_WINDOW_FULLSCREEN_EXCLUSIVE) != 0) {
             if (!Cocoa_SetWindowFullscreenSpace(window, SDL_FALSE)) {
                 return -1;
             }
-        } else if (fullscreen && ((window->last_fullscreen_flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN) && ((window->flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN_DESKTOP)) {
+        } else if (fullscreen &&
+                   (window->last_fullscreen_flags & SDL_WINDOW_FULLSCREEN_EXCLUSIVE) != 0 &&
+                   (window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0) {
             display = SDL_GetDisplayForWindow(window);
             SDL_SetDisplayModeForDisplay(display, NULL);
             if (_this->SetWindowFullscreen) {
@@ -1437,7 +1439,7 @@ static int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen)
        to fullscreen (being active, or not), and figure out a return/error code
        from that.
     */
-    if (fullscreen == !(WINRT_DetectWindowFlags(window) & FULLSCREEN_MASK)) {
+    if (fullscreen == !(WINRT_DetectWindowFlags(window) & SDL_WINDOW_FULLSCREEN_MASK)) {
         /* Uh oh, either:
             1. fullscreen was requested, and we're already windowed
             2. windowed-mode was requested, and we're already fullscreen
@@ -1466,7 +1468,7 @@ static int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen)
 
     /* See if anything needs to be done now */
     if ((display->fullscreen_window == window) == fullscreen) {
-        if ((window->last_fullscreen_flags & FULLSCREEN_MASK) == (window->flags & FULLSCREEN_MASK)) {
+        if ((window->last_fullscreen_flags & SDL_WINDOW_FULLSCREEN_MASK) == (window->flags & SDL_WINDOW_FULLSCREEN_MASK)) {
             return 0;
         }
     }
@@ -1477,7 +1479,7 @@ static int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen)
 
         if (other == window) {
             setDisplayMode = fullscreen;
-        } else if (FULLSCREEN_VISIBLE(other) &&
+        } else if (SDL_WINDOW_FULLSCREEN_VISIBLE(other) &&
                    SDL_GetDisplayForWindow(other) == display) {
             setDisplayMode = SDL_TRUE;
         }
@@ -1495,7 +1497,7 @@ static int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen)
                 }
 
                 /* only do the mode change if we want exclusive fullscreen */
-                if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) {
+                if ((window->flags & SDL_WINDOW_FULLSCREEN_EXCLUSIVE) != 0) {
                     if (SDL_SetDisplayModeForDisplay(display, &fullscreen_mode) < 0) {
                         return -1;
                     }
@@ -1599,7 +1601,7 @@ static void SDL_FinishWindowCreation(SDL_Window *window, Uint32 flags)
     if (flags & SDL_WINDOW_MINIMIZED) {
         SDL_MinimizeWindow(window);
     }
-    if (flags & SDL_WINDOW_FULLSCREEN) {
+    if (flags & SDL_WINDOW_FULLSCREEN_MASK) {
         SDL_SetWindowFullscreen(window, flags);
     }
     if (flags & SDL_WINDOW_MOUSE_GRABBED) {
@@ -1749,7 +1751,7 @@ SDL_Window *SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint
     window->windowed.w = window->w;
     window->windowed.h = window->h;
 
-    if (flags & SDL_WINDOW_FULLSCREEN) {
+    if (flags & SDL_WINDOW_FULLSCREEN_MASK) {
         SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
         int displayIndex;
         SDL_Rect bounds;
@@ -1760,7 +1762,7 @@ SDL_Window *SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint
         /* for real fullscreen we might switch the resolution, so get width and height
          * from closest supported mode and use that instead of current resolution
          */
-        if ((flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP && (bounds.w != w || bounds.h != h)) {
+        if ((flags & SDL_WINDOW_FULLSCREEN_EXCLUSIVE) != 0 && (bounds.w != w || bounds.h != h)) {
             SDL_DisplayMode fullscreen_mode, closest_mode;
             SDL_zero(fullscreen_mode);
             fullscreen_mode.screen_w = w;
@@ -1822,7 +1824,7 @@ SDL_Window *SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint
     SDL_FinishWindowCreation(window, flags);
 
     /* If the window was created fullscreen, make sure the mode code matches */
-    SDL_UpdateFullscreenMode(window, FULLSCREEN_VISIBLE(window));
+    SDL_UpdateFullscreenMode(window, SDL_WINDOW_FULLSCREEN_VISIBLE(window));
 
     return window;
 }
@@ -2201,7 +2203,7 @@ void SDL_SetWindowPosition(SDL_Window *window, int x, int y)
         }
     }
 
-    if ((window->flags & SDL_WINDOW_FULLSCREEN)) {
+    if ((window->flags & SDL_WINDOW_FULLSCREEN_MASK) != 0) {
         if (!SDL_WINDOWPOS_ISUNDEFINED(x)) {
             window->windowed.x = x;
         }
@@ -2227,7 +2229,7 @@ void SDL_GetWindowPosition(SDL_Window *window, int *x, int *y)
     CHECK_WINDOW_MAGIC(window, );
 
     /* Fullscreen windows are always at their display's origin */
-    if (window->flags & SDL_WINDOW_FULLSCREEN) {
+    if ((window->flags & SDL_WINDOW_FULLSCREEN_MASK) != 0) {
         int displayIndex;
 
         if (x) {
@@ -2266,7 +2268,7 @@ void SDL_GetWindowPosition(SDL_Window *window, int *x, int *y)
 void SDL_SetWindowBordered(SDL_Window *window, SDL_bool bordered)
 {
     CHECK_WINDOW_MAGIC(window, );
-    if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
+    if ((window->flags & SDL_WINDOW_FULLSCREEN_MASK) == 0) {
         const int want = (bordered != SDL_FALSE); /* normalize the flag. */
         const int have = ((window->flags & SDL_WINDOW_BORDERLESS) == 0);
         if ((want != have) && (_this->SetWindowBordered)) {
@@ -2283,7 +2285,7 @@ void SDL_SetWindowBordered(SDL_Window *window, SDL_bool bordered)
 void SDL_SetWindowResizable(SDL_Window *window, SDL_bool resizable)
 {
     CHECK_WINDOW_MAGIC(window, );
-    if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
+    if ((window->flags & SDL_WINDOW_FULLSCREEN_MASK) == 0) {
         const int want = (resizable != SDL_FALSE); /* normalize the flag. */
         const int have = ((window->flags & SDL_WINDOW_RESIZABLE) != 0);
         if ((want != have) && (_this->SetWindowResizable)) {
@@ -2300,7 +2302,7 @@ void SDL_SetWindowResizable(SDL_Window *window, SDL_bool resizable)
 void SDL_SetWindowAlwaysOnTop(SDL_Window *window, SDL_bool on_top)
 {
     CHECK_WINDOW_MAGIC(window, );
-    if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
+    if ((window->flags & SDL_WINDOW_FULLSCREEN_MASK) == 0) {
         const int want = (on_top != SDL_FALSE); /* normalize the flag. */
         const int have = ((window->flags & SDL_WINDOW_ALWAYS_ON_TOP) != 0);
         if ((want != have) && (_this->SetWindowAlwaysOnTop)) {
@@ -2344,8 +2346,9 @@ void SDL_SetWindowSize(SDL_Window *window, int w, int h)
     window->windowed.w = w;
     window->windowed.h = h;
 
-    if (window->flags & SDL_WINDOW_FULLSCREEN) {
-        if (FULLSCREEN_VISIBLE(window) && (window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) {
+    if ((window->flags & SDL_WINDOW_FULLSCREEN_MASK) != 0) {
+        if (SDL_WINDOW_FULLSCREEN_VISIBLE(window) &&
+            (window->flags & SDL_WINDOW_FULLSCREEN_EXCLUSIVE) != 0) {
             window->last_full

(Patch may be truncated, please check the link at the top of this post.)