SDL: SDL_CreateWindowWithPosition() and SDL_CreateWindowFrom() have been replaced with SDL_CreateWindowWithProperties()

From 229b7b9d50fecd74690321ab7f7fe719565414e3 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Mon, 13 Nov 2023 11:29:30 -0800
Subject: [PATCH] SDL_CreateWindowWithPosition() and SDL_CreateWindowFrom()
 have been replaced with SDL_CreateWindowWithProperties()

This is a more general interface that can be extended in the future as needed.
---
 docs/README-migration.md                   |  11 +-
 include/SDL3/SDL_video.h                   | 206 +++++++-----------
 src/dynapi/SDL_dynapi.sym                  |   3 +-
 src/dynapi/SDL_dynapi_overrides.h          |   3 +-
 src/dynapi/SDL_dynapi_procs.h              |   3 +-
 src/test/SDL_test_common.c                 |  11 +-
 src/video/SDL_sysvideo.h                   |   3 +-
 src/video/SDL_video.c                      | 204 ++++++++----------
 src/video/android/SDL_androidwindow.c      |   2 +-
 src/video/android/SDL_androidwindow.h      |   2 +-
 src/video/cocoa/SDL_cocoavideo.m           |   1 -
 src/video/cocoa/SDL_cocoawindow.h          |   3 +-
 src/video/cocoa/SDL_cocoawindow.m          | 210 +++++++++----------
 src/video/emscripten/SDL_emscriptenvideo.c |   4 +-
 src/video/haiku/SDL_bwindow.cc             |   2 +-
 src/video/haiku/SDL_bwindow.h              |   2 +-
 src/video/kmsdrm/SDL_kmsdrmvideo.c         |   2 +-
 src/video/kmsdrm/SDL_kmsdrmvideo.h         |   2 +-
 src/video/n3ds/SDL_n3dsvideo.c             |   4 +-
 src/video/ngage/SDL_ngagewindow.cpp        |   2 +-
 src/video/ngage/SDL_ngagewindow.h          |   2 +-
 src/video/offscreen/SDL_offscreenwindow.c  |   2 +-
 src/video/offscreen/SDL_offscreenwindow.h  |   2 +-
 src/video/ps2/SDL_ps2video.c               |   2 +-
 src/video/psp/SDL_pspvideo.c               |   2 +-
 src/video/psp/SDL_pspvideo.h               |   2 +-
 src/video/raspberry/SDL_rpivideo.c         |   2 +-
 src/video/raspberry/SDL_rpivideo.h         |   2 +-
 src/video/riscos/SDL_riscoswindow.c        |   2 +-
 src/video/riscos/SDL_riscoswindow.h        |   2 +-
 src/video/uikit/SDL_uikitwindow.h          |   2 +-
 src/video/uikit/SDL_uikitwindow.m          |   2 +-
 src/video/vita/SDL_vitavideo.c             |   2 +-
 src/video/vita/SDL_vitavideo.h             |   2 +-
 src/video/vivante/SDL_vivantevideo.c       |   2 +-
 src/video/vivante/SDL_vivantevideo.h       |   2 +-
 src/video/wayland/SDL_waylandwindow.c      |   2 +-
 src/video/wayland/SDL_waylandwindow.h      |   2 +-
 src/video/windows/SDL_windowsvideo.c       |   1 -
 src/video/windows/SDL_windowswindow.c      | 233 ++++++++++-----------
 src/video/windows/SDL_windowswindow.h      |   4 +-
 src/video/winrt/SDL_winrtvideo.cpp         |   4 +-
 src/video/x11/SDL_x11video.c               |   1 -
 src/video/x11/SDL_x11window.c              |  43 ++--
 src/video/x11/SDL_x11window.h              |   3 +-
 test/testautomation_video.c                |  10 +-
 test/testnative.c                          |   4 +-
 47 files changed, 458 insertions(+), 561 deletions(-)

diff --git a/docs/README-migration.md b/docs/README-migration.md
index d0eda28d593b..eeda40d173bb 100644
--- a/docs/README-migration.md
+++ b/docs/README-migration.md
@@ -559,10 +559,10 @@ The following hints have been removed:
 * SDL_HINT_IME_SUPPORT_EXTENDED_TEXT - the normal text editing event has extended text
 * SDL_HINT_MOUSE_RELATIVE_SCALING - mouse coordinates are no longer automatically scaled by the SDL renderer
 * SDL_HINT_RENDER_LOGICAL_SIZE_MODE - the logical size mode is explicitly set with SDL_SetRenderLogicalPresentation()
-* SDL_HINT_VIDEO_FOREIGN_WINDOW_OPENGL - replaced with the "opengl" property in SDL_CreateWindowFrom()
-* SDL_HINT_VIDEO_FOREIGN_WINDOW_VULKAN - replaced with the "vulkan" property in SDL_CreateWindowFrom()
+* SDL_HINT_VIDEO_FOREIGN_WINDOW_OPENGL - replaced with the "opengl" property in SDL_CreateWindowWithProperties()
+* SDL_HINT_VIDEO_FOREIGN_WINDOW_VULKAN - replaced with the "vulkan" property in SDL_CreateWindowWithProperties()
 * SDL_HINT_VIDEO_HIGHDPI_DISABLED - high DPI support is always enabled
-* SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT - replaced with the "win32.pixel_format_hwnd" in SDL_CreateWindowFrom()
+* SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT - replaced with the "native.win32.pixel_format_hwnd" in SDL_CreateWindowWithProperties()
 * SDL_HINT_VIDEO_X11_FORCE_EGL - use SDL_HINT_VIDEO_FORCE_EGL instead
 * SDL_HINT_VIDEO_X11_XINERAMA - Xinerama no longer supported by the X11 backend
 * SDL_HINT_VIDEO_X11_XVIDMODE - Xvidmode no longer supported by the X11 backend
@@ -1261,9 +1261,7 @@ Rather than iterating over displays using display index, there is a new function
 }

-SDL_CreateWindow() has been simplified and no longer takes a window position. You can use SDL_CreateWindowWithPosition() if you need to set the window position when creating it.

-SDL_CreateWindowFrom() now takes a set of properties that describe the native window and options.
+SDL_CreateWindow() has been simplified and no longer takes a window position. You can use SDL_CreateWindowWithProperties() if you need to set the window position when creating it.

The SDL_WINDOWPOS_UNDEFINED_DISPLAY() and SDL_WINDOWPOS_CENTERED_DISPLAY() macros take a display ID instead of display index. The display ID 0 has a special meaning in this case, and is used to indicate the primary display.

@@ -1332,6 +1330,7 @@ The following functions have been removed:

  • SDL_GetNumVideoDisplays() - replaced with SDL_GetDisplays()
  • SDL_GetWindowData() - use SDL_GetWindowProperties() instead
  • SDL_SetWindowData() - use SDL_GetWindowProperties() instead
    +* SDL_CreateWindowFrom() - use SDL_CreateWindowWithProperties() with “native.*” properties instead

SDL_Window id type is named SDL_WindowID

diff --git a/include/SDL3/SDL_video.h b/include/SDL3/SDL_video.h
index b75ffda4e1e3…3a80cf9633d2 100644
— a/include/SDL3/SDL_video.h
+++ b/include/SDL3/SDL_video.h
@@ -89,42 +89,41 @@ typedef enum
/**

  • The type used to identify a window
    • \sa SDL_CreateWindow()
    • \sa SDL_CreateWindowFrom()
    • \sa SDL_CreateWindowWithPosition()
    • \sa SDL_DestroyWindow()
    • \sa SDL_FlashWindow()
    • \sa SDL_GetWindowFlags()
    • \sa SDL_GetWindowGrab()
    • \sa SDL_GetWindowKeyboardGrab()
    • \sa SDL_GetWindowMouseGrab()
    • \sa SDL_GetWindowPosition()
    • \sa SDL_GetWindowSize()
    • \sa SDL_GetWindowTitle()
    • \sa SDL_HideWindow()
    • \sa SDL_MaximizeWindow()
    • \sa SDL_MinimizeWindow()
    • \sa SDL_RaiseWindow()
    • \sa SDL_RestoreWindow()
    • \sa SDL_SetWindowFullscreen()
    • \sa SDL_SetWindowGrab()
    • \sa SDL_SetWindowKeyboardGrab()
    • \sa SDL_SetWindowMouseGrab()
    • \sa SDL_SetWindowIcon()
    • \sa SDL_SetWindowPosition()
    • \sa SDL_SetWindowSize()
    • \sa SDL_SetWindowBordered()
    • \sa SDL_SetWindowResizable()
    • \sa SDL_SetWindowTitle()
    • \sa SDL_ShowWindow()
    • \sa SDL_ShowWindowSystemMenu()
    • \sa SDL_CreateWindow
    • \sa SDL_CreateWindowWithProperties
    • \sa SDL_DestroyWindow
    • \sa SDL_FlashWindow
    • \sa SDL_GetWindowFlags
    • \sa SDL_GetWindowGrab
    • \sa SDL_GetWindowKeyboardGrab
    • \sa SDL_GetWindowMouseGrab
    • \sa SDL_GetWindowPosition
    • \sa SDL_GetWindowSize
    • \sa SDL_GetWindowTitle
    • \sa SDL_HideWindow
    • \sa SDL_MaximizeWindow
    • \sa SDL_MinimizeWindow
    • \sa SDL_RaiseWindow
    • \sa SDL_RestoreWindow
    • \sa SDL_SetWindowFullscreen
    • \sa SDL_SetWindowGrab
    • \sa SDL_SetWindowKeyboardGrab
    • \sa SDL_SetWindowMouseGrab
    • \sa SDL_SetWindowIcon
    • \sa SDL_SetWindowPosition
    • \sa SDL_SetWindowSize
    • \sa SDL_SetWindowBordered
    • \sa SDL_SetWindowResizable
    • \sa SDL_SetWindowTitle
    • \sa SDL_ShowWindow
    • \sa SDL_ShowWindowSystemMenu
      */
      typedef struct SDL_Window SDL_Window;

/**

  • The flags on a window
    • \sa SDL_GetWindowFlags()
    • \sa SDL_GetWindowFlags
      */
      typedef enum
      {
      @@ -144,8 +143,8 @@ typedef enum
      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_UTILITY = 0x00020000, /**< window should be treated as a utility window, not showing in the task bar and window list */
  • SDL_WINDOW_TOOLTIP = 0x00040000, /**< window should be treated as a tooltip and must be created using SDL_CreatePopupWindow() */
  • SDL_WINDOW_POPUP_MENU = 0x00080000, /**< window should be treated as a popup menu and must be created using SDL_CreatePopupWindow() */
  • 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 */
    @@ -713,11 +712,6 @@ extern DECLSPEC Uint32 SDLCALL SDL_GetWindowPixelFormat(SDL_Window *window);
  • window is created and should be queried again if you get an
  • SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED event.
    • If the window is set fullscreen, the width and height parameters w and
    • h will not be used. However, invalid size parameters (e.g. too large) may
    • still fail. Window size is actually limited to 16384 x 16384 for all
    • platforms at window creation.
    • If the window is created with any of the SDL_WINDOW_OPENGL or
    • SDL_WINDOW_VULKAN flags, then the corresponding LoadLibrary function
    • (SDL_GL_LoadLibrary or SDL_Vulkan_LoadLibrary) is called and the
      @@ -743,79 +737,11 @@ extern DECLSPEC Uint32 SDLCALL SDL_GetWindowPixelFormat(SDL_Window *window);
    • \since This function is available since SDL 3.0.0.
    • \sa SDL_CreatePopupWindow
    • \sa SDL_CreateWindowFrom
    • \sa SDL_CreateWindowWithPosition
    • \sa SDL_CreateWindowWithProperties
    • \sa SDL_DestroyWindow
      */
      extern DECLSPEC SDL_Window *SDLCALL SDL_CreateWindow(const char *title, int w, int h, Uint32 flags);

-/**

    • Create a window with the specified position, dimensions, and flags.
    • flags may be any of the following OR’d together:
      • SDL_WINDOW_FULLSCREEN: fullscreen window at desktop resolution
      • SDL_WINDOW_OPENGL: window usable with an OpenGL context
      • SDL_WINDOW_VULKAN: window usable with a Vulkan instance
      • SDL_WINDOW_METAL: window usable with a Metal instance
      • SDL_WINDOW_HIDDEN: window is not visible
      • SDL_WINDOW_BORDERLESS: no window decoration
      • SDL_WINDOW_RESIZABLE: window can be resized
      • SDL_WINDOW_MINIMIZED: window is minimized
      • SDL_WINDOW_MAXIMIZED: window is maximized
      • SDL_WINDOW_MOUSE_GRABBED: window has grabbed mouse focus
    • The SDL_Window is implicitly shown if SDL_WINDOW_HIDDEN is not set.
    • On Apple’s macOS, you must set the NSHighResolutionCapable Info.plist
    • property to YES, otherwise you will not receive a High-DPI OpenGL canvas.
    • The window pixel size may differ from its window coordinate size if the
    • window is on a high pixel density display. Use SDL_GetWindowSize() to query
    • the client area’s size in window coordinates, and
    • SDL_GetWindowSizeInPixels() or SDL_GetRenderOutputSize() to query the
    • drawable size in pixels. Note that the drawable size can vary after the
    • window is created and should be queried again if you get an
    • SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED event.
    • If the window is set fullscreen, the width and height parameters w and
    • h will not be used. However, invalid size parameters (e.g. too large) may
    • still fail. Window size is actually limited to 16384 x 16384 for all
    • platforms at window creation.
    • If the window is created with any of the SDL_WINDOW_OPENGL or
    • SDL_WINDOW_VULKAN flags, then the corresponding LoadLibrary function
    • (SDL_GL_LoadLibrary or SDL_Vulkan_LoadLibrary) is called and the
    • corresponding UnloadLibrary function is called by SDL_DestroyWindow().
    • If SDL_WINDOW_VULKAN is specified and there isn’t a working Vulkan driver,
    • SDL_CreateWindow() will fail because SDL_Vulkan_LoadLibrary() will fail.
    • If SDL_WINDOW_METAL is specified on an OS that does not support Metal,
    • SDL_CreateWindow() will fail.
    • On non-Apple devices, SDL requires you to either not link to the Vulkan
    • loader or link to a dynamic library version. This limitation may be removed
    • in a future version of SDL.
    • \param title the title of the window, in UTF-8 encoding
    • \param x the x position of the window, or SDL_WINDOWPOS_CENTERED
    • \param y the y position of the window, or SDL_WINDOWPOS_CENTERED
    • \param w the width of the window
    • \param h the height of the window
    • \param flags 0, or one or more SDL_WindowFlags OR’d together
    • \returns the window that was created or NULL on failure; call
    •      SDL_GetError() for more information.
      
    • \since This function is available since SDL 3.0.0.
    • \sa SDL_CreatePopupWindow
    • \sa SDL_CreateWindow
    • \sa SDL_CreateWindowFrom
    • \sa SDL_DestroyWindow
  • */
    -extern DECLSPEC SDL_Window *SDLCALL SDL_CreateWindowWithPosition(const char *title, int x, int y, int w, int h, Uint32 flags);

/**

  • Create a child popup window of the specified parent window.

@@ -824,10 +750,12 @@ extern DECLSPEC SDL_Window *SDLCALL SDL_CreateWindowWithPosition(const char *tit

  • input events. - ‘SDL_WINDOW_POPUP_MENU’: The popup window is a popup menu.
  • The topmost popup menu will implicitly gain the keyboard focus.
    • The following flags are not relevant to popup window creation and will be
    • ignored: - ‘SDL_WINDOW_MINIMIZED’ - ‘SDL_WINDOW_MAXIMIZED’ -
    • ‘SDL_WINDOW_FULLSCREEN’ - ‘SDL_WINDOW_BORDERLESS’ -
    • ‘SDL_WINDOW_SKIP_TASKBAR’
    • The following flags are not relevant to popup window creation and will be ignored:
      • ‘SDL_WINDOW_MINIMIZED’
      • ‘SDL_WINDOW_MAXIMIZED’
      • ‘SDL_WINDOW_FULLSCREEN’
      • ‘SDL_WINDOW_BORDERLESS’
    • The parent parameter must be non-null and a valid window. The parent of
    • a popup window can be either a regular, toplevel window, or another popup
      @@ -862,45 +790,60 @@ extern DECLSPEC SDL_Window *SDLCALL SDL_CreateWindowWithPosition(const char *tit
    • \since This function is available since SDL 3.0.0.
    • \sa SDL_CreateWindow
    • \sa SDL_CreateWindowWithProperties
    • \sa SDL_DestroyWindow
    • \sa SDL_GetWindowParent
      */
      extern DECLSPEC SDL_Window *SDLCALL SDL_CreatePopupWindow(SDL_Window *parent, int offset_x, int offset_y, int w, int h, Uint32 flags);

/**

    • Create an SDL window from properties representing an existing native
    • window.
    • Create a window with the specified properties.
    • These are the supported properties:
      • “always-on-top” (boolean) - true if the window should be always on top
      • “borderless” (boolean) - true if the window has no window decoration
      • “focusable” (boolean) - true if the window should accept keyboard input (defaults true)
      • “fullscreen” (boolean) - true if the window should start in fullscreen mode at desktop resolution
      • “height” (number) - the height of the window
      • “hidden” (boolean) - true if the window should start hidden
      • “high-pixel-density” (boolean) - true if the window uses a high pixel density buffer if possible
      • “maximized” (boolean) - true if the window should start maximized
      • “menu” (boolean) - true if the window is a popup menu
      • “metal” (string) - true if the window will be used with Metal rendering
      • “minimized” (boolean) - true if the window should start minimized
      • “mouse-grabbed” (boolean) - true if the window starts with grabbed mouse focus
      • “opengl” (boolean) - true if the window will be used with OpenGL rendering
      • “parent” (pointer) - an SDL_Window that will be the parent of this window, required for windows with the “toolip” and “menu” properties
      • “resizable” (boolean) - true if the window should be resizable
      • “title” (string) - the title of the window, in UTF-8 encoding
      • “transparent” (string) - true if the window show transparent in the areas with alpha of 0
      • “tooltip” (boolean) - true if the window is a tooltip
      • “utility” (boolean) - true if the window is a utility window, not showing in the task bar and window list
      • “vulkan” (string) - true if the window will be used with Vulkan rendering
      • “width” (number) - the width of the window
      • “x” (number) - the x position of the window, or SDL_WINDOWPOS_CENTERED, defaults to SDL_WINDOWPOS_UNDEFINED. This is relative to the parent for windows with the “parent” property set.
      • “y” (number) - the y position of the window, or SDL_WINDOWPOS_CENTERED, defaults to SDL_WINDOWPOS_UNDEFINED. This is relative to the parent for windows with the “parent” property set.
    • On macOS:
    • “cocoa.window” (pointer) - the (__unsafe_unretained) NSWindow associated with the window
    • “cocoa.view” (pointer) - optional, the (__unsafe_unretained) NSView associated with the window, defaults to [window contentView]
      • “native.cocoa.window” (pointer) - the (__unsafe_unretained) NSWindow associated with the window, if you want to wrap an existing window.
      • “native.cocoa.view” (pointer) - the (__unsafe_unretained) NSView associated with the window, defaults to [window contentView]
    • On Windows:
    • “win32.hwnd” (pointer) - the HWND associated with the window
    • “win32.pixel_format_hwnd” (pointer) - optional, another window to share pixel format with, useful for OpenGL windows
      • “native.win32.hwnd” (pointer) - the HWND associated with the window, if you want to wrap an existing window.
      • “native.win32.pixel_format_hwnd” (pointer) - optional, another window to share pixel format with, useful for OpenGL windows
    • On X11:
    • “x11.window” (number) - the X11 Window associated with the window
      • “native.x11.window” (number) - the X11 Window associated with the window, if you want to wrap an existing window.
    • On all platforms:
    • The SDL_Window is implicitly shown if the “hidden” property is not set.
    • “opengl” (boolean) - optional, true if the window will be used with OpenGL rendering
    • “vulkan” (boolean) - optional, true if the window will be used with Vulkan rendering
    • Windows with the “tooltip” and “menu” properties are popup windows and have the behaviors and guidelines outlined in SDL_CreatePopupWindow().
    • \param props a set of properties describing the native window and options
    • \param props the properties to use
    • \returns the window that was created or NULL on failure; call
    •      SDL_GetError() for more information.
      

@@ -909,7 +852,7 @@ extern DECLSPEC SDL_Window *SDLCALL SDL_CreatePopupWindow(SDL_Window *parent, in

  • \sa SDL_CreateWindow
  • \sa SDL_DestroyWindow
    */
    -extern DECLSPEC SDL_Window *SDLCALL SDL_CreateWindowFrom(SDL_PropertiesID props);
    +extern DECLSPEC SDL_Window *SDLCALL SDL_CreateWindowWithProperties(SDL_PropertiesID props);

/**

  • Get the numeric ID of a window.
    @@ -1912,8 +1855,9 @@ extern DECLSPEC int SDLCALL SDL_FlashWindow(SDL_Window *window, SDL_FlashOperati
  • \since This function is available since SDL 3.0.0.
    • \sa SDL_CreatePopupWindow
    • \sa SDL_CreateWindow
    • \sa SDL_CreateWindowFrom
    • \sa SDL_CreateWindowWithProperties
      */
      extern DECLSPEC void SDLCALL SDL_DestroyWindow(SDL_Window *window);

diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym
index 46c1278c6b65…bb55f404c9a4 100644
— a/src/dynapi/SDL_dynapi.sym
+++ b/src/dynapi/SDL_dynapi.sym
@@ -69,8 +69,7 @@ SDL3_0.0.0 {
SDL_CreateThreadWithStackSize;
SDL_CreateWindow;
SDL_CreateWindowAndRenderer;

  • SDL_CreateWindowFrom;
  • SDL_CreateWindowWithPosition;
  • SDL_CreateWindowWithProperties;
    SDL_CursorVisible;
    SDL_DXGIGetOutputInfo;
    SDL_DelEventWatch;
    diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
    index a476b53fc07d…57e1affe2342 100644
    — a/src/dynapi/SDL_dynapi_overrides.h
    +++ b/src/dynapi/SDL_dynapi_overrides.h
    @@ -93,8 +93,7 @@
    #define SDL_CreateThreadWithStackSize SDL_CreateThreadWithStackSize_REAL
    #define SDL_CreateWindow SDL_CreateWindow_REAL
    #define SDL_CreateWindowAndRenderer SDL_CreateWindowAndRenderer_REAL
    -#define SDL_CreateWindowFrom SDL_CreateWindowFrom_REAL
    -#define SDL_CreateWindowWithPosition SDL_CreateWindowWithPosition_REAL
    +#define SDL_CreateWindowWithProperties SDL_CreateWindowWithProperties_REAL
    #define SDL_CursorVisible SDL_CursorVisible_REAL
    #define SDL_DXGIGetOutputInfo SDL_DXGIGetOutputInfo_REAL
    #define SDL_DelEventWatch SDL_DelEventWatch_REAL
    diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
    index 309249d97f9d…3d8049d023a5 100644
    — a/src/dynapi/SDL_dynapi_procs.h
    +++ b/src/dynapi/SDL_dynapi_procs.h
    @@ -157,8 +157,7 @@ SDL_DYNAPI_PROC(SDL_Texture*,SDL_CreateTexture,(SDL_Renderer a, Uint32 b, int c
    SDL_DYNAPI_PROC(SDL_Texture
    ,SDL_CreateTextureFromSurface,(SDL_Renderer *a, SDL_Surface b),(a,b),return)
    SDL_DYNAPI_PROC(SDL_Window
    ,SDL_CreateWindow,(const char *a, int b, int c, Uint32 d),(a,b,c,d),return)
    SDL_DYNAPI_PROC(int,SDL_CreateWindowAndRenderer,(int a, int b, Uint32 c, SDL_Window **d, SDL_Renderer e),(a,b,c,d,e),return)
    -SDL_DYNAPI_PROC(SDL_Window
    ,SDL_CreateWindowFrom,(SDL_PropertiesID a),(a),return)
    -SDL_DYNAPI_PROC(SDL_Window
    ,SDL_CreateWindowWithPosition,(const char a, int b, int c, int d, int e, Uint32 f),(a,b,c,d,e,f),return)
    +SDL_DYNAPI_PROC(SDL_Window
    ,SDL_CreateWindowWithProperties,(SDL_PropertiesID a),(a),return)
    SDL_DYNAPI_PROC(SDL_bool,SDL_CursorVisible,(void),(),return)
    SDL_DYNAPI_PROC(void,SDL_DelEventWatch,(SDL_EventFilter a, void *b),(a,b),)
    SDL_DYNAPI_PROC(void,SDL_DelHintCallback,(const char *a, SDL_HintCallback b, void *c),(a,b,c),)
    diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c
    index ad14ba4ee80a…aa5639495510 100644
    — a/src/test/SDL_test_common.c
    +++ b/src/test/SDL_test_common.c
    @@ -1347,6 +1347,7 @@ SDL_bool SDLTest_CommonInit(SDLTest_CommonState *state)
    for (i = 0; i < state->num_windows; ++i) {
    char title[1024];
    SDL_Rect r;
  •        SDL_PropertiesID props;
    
           r.x = state->window_x;
           r.y = state->window_y;
    

@@ -1369,7 +1370,15 @@ SDL_bool SDLTest_CommonInit(SDLTest_CommonState *state)
} else {
SDL_strlcpy(title, state->window_title, SDL_arraysize(title));
}

  •        state->windows[i] = SDL_CreateWindowWithPosition(title, r.x, r.y, r.w, r.h, state->window_flags);
    
  •        props = SDL_CreateProperties();
    
  •        SDL_SetStringProperty(props, "title", title);
    
  •        SDL_SetNumberProperty(props, "x", r.x);
    
  •        SDL_SetNumberProperty(props, "y", r.y);
    
  •        SDL_SetNumberProperty(props, "width", r.w);
    
  •        SDL_SetNumberProperty(props, "height", r.h);
    
  •        SDL_SetNumberProperty(props, "flags", state->window_flags);
    
  •        state->windows[i] = SDL_CreateWindowWithProperties(props);
    
  •        SDL_DestroyProperties(props);
           if (!state->windows[i]) {
               SDL_Log("Couldn't create window: %s\n",
                       SDL_GetError());
    

diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h
index cc9597f66330…2dccb30d2b79 100644
— a/src/video/SDL_sysvideo.h
+++ b/src/video/SDL_sysvideo.h
@@ -222,8 +222,7 @@ struct SDL_VideoDevice
/*
* Window functions
*/

  • int (*CreateSDLWindow)(SDL_VideoDevice *_this, SDL_Window *window);
  • int (*CreateSDLWindowFrom)(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID props);
  • int (*CreateSDLWindow)(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props);
    void (*SetWindowTitle)(SDL_VideoDevice *_this, SDL_Window *window);
    int (*SetWindowIcon)(SDL_VideoDevice *_this, SDL_Window *window, SDL_Surface *icon);
    int (*SetWindowPosition)(SDL_VideoDevice *_this, SDL_Window *window);
    diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
    index 712b21e095f7…1e325794a369 100644
    — a/src/video/SDL_video.c
    +++ b/src/video/SDL_video.c
    @@ -1844,9 +1844,59 @@ static int SDL_DllNotSupported(const char *name)
    return SDL_SetError(“No dynamic %s support in current SDL video driver (%s)”, name, _this->name);
    }

-static SDL_Window *SDL_CreateWindowInternal(const char *title, int x, int y, int w, int h, SDL_Window *parent, Uint32 flags)
+static struct {

  • const char *property_name;
  • Uint32 flag;
  • SDL_bool invert_value;
    +} SDL_WindowFlagProperties = {
  • { “always-on-top”, SDL_WINDOW_ALWAYS_ON_TOP, SDL_FALSE },
  • { “borderless”, SDL_WINDOW_BORDERLESS, SDL_FALSE },
  • { “focusable”, SDL_WINDOW_NOT_FOCUSABLE, SDL_TRUE },
  • { “fullscreen”, SDL_WINDOW_FULLSCREEN, SDL_FALSE },
  • { “hidden”, SDL_WINDOW_HIDDEN, SDL_FALSE },
  • { “high-pixel-density”, SDL_WINDOW_HIGH_PIXEL_DENSITY, SDL_FALSE },
  • { “maximized”, SDL_WINDOW_MAXIMIZED, SDL_FALSE },
  • { “menu”, SDL_WINDOW_POPUP_MENU, SDL_FALSE },
  • { “metal”, SDL_WINDOW_METAL, SDL_FALSE },
  • { “minimized”, SDL_WINDOW_MINIMIZED, SDL_FALSE },
  • { “mouse-grabbed”, SDL_WINDOW_MOUSE_GRABBED, SDL_FALSE },
  • { “opengl”, SDL_WINDOW_OPENGL, SDL_FALSE },
  • { “resizable”, SDL_WINDOW_RESIZABLE, SDL_FALSE },
  • { “transparent”, SDL_WINDOW_TRANSPARENT, SDL_FALSE },
  • { “tooltip”, SDL_WINDOW_TOOLTIP, SDL_FALSE },
  • { “utility”, SDL_WINDOW_UTILITY, SDL_FALSE },
  • { “vulkan”, SDL_WINDOW_VULKAN, SDL_FALSE }
    +};

+static Uint32 SDL_GetWindowFlagProperties(SDL_PropertiesID props)
+{

  • unsigned i;
  • Uint32 flags = (Uint32)SDL_GetNumberProperty(props, “flags”, 0);
  • for (i = 0; i < SDL_arraysize(SDL_WindowFlagProperties); ++i) {
  •    if (SDL_WindowFlagProperties[i].invert_value) {
    
  •        if (!SDL_GetBooleanProperty(props, SDL_WindowFlagProperties[i].property_name, SDL_TRUE)) {
    
  •            flags |= SDL_WindowFlagProperties[i].flag;
    
  •        }
    
  •    } else {
    
  •        if (SDL_GetBooleanProperty(props, SDL_WindowFlagProperties[i].property_name, SDL_FALSE)) {
    
  •            flags |= SDL_WindowFlagProperties[i].flag;
    
  •        }
    
  •    }
    
  • }
  • return flags;
    +}

+SDL_Window *SDL_CreateWindowWithProperties(SDL_PropertiesID props)
{
SDL_Window *window;

  • const char *title = SDL_GetStringProperty(props, “title”, NULL);
  • int x = (int)SDL_GetNumberProperty(props, “x”, SDL_WINDOWPOS_UNDEFINED);
  • int y = (int)SDL_GetNumberProperty(props, “y”, SDL_WINDOWPOS_UNDEFINED);
  • int w = (int)SDL_GetNumberProperty(props, “width”, 0);
  • int h = (int)SDL_GetNumberProperty(props, “height”, 0);
  • SDL_Window *parent = SDL_GetProperty(props, “parent”, NULL);
  • Uint32 flags = SDL_GetWindowFlagProperties(props);
    Uint32 type_flags, graphics_flags;
    SDL_bool undefined_x = SDL_FALSE;
    SDL_bool undefined_y = SDL_FALSE;
    @@ -1863,22 +1913,32 @@ static SDL_Window *SDL_CreateWindowInternal(const char *title, int x, int y, int
    }
    }
  • /* Make sure the display list is up to date for window placement */
  • if (_this->RefreshDisplays) {
  •    _this->RefreshDisplays(_this);
    
  • if ((flags & (SDL_WINDOW_TOOLTIP | SDL_WINDOW_POPUP_MENU)) != 0) {
  •    if (!(_this->quirk_flags & VIDEO_DEVICE_QUIRK_HAS_POPUP_WINDOW_SUPPORT)) {
    
  •        SDL_Unsupported();
    
  •        return NULL;
    
  •    }
    
  •    /* Tooltip and popup menu window must specify a parent window */
    
  •    if (!parent || parent->magic != &_this->window_magic) {
    
  •        SDL_SetError("Tooltip and popup menu windows must specify a parent window");
    
  •        return NULL;
    
  •    }
    
  •    /* Remove invalid flags */
    
  •    flags &= ~(SDL_WINDOW_MINIMIZED | SDL_WINDOW_MAXIMIZED | SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS);
    
    }
  • /* ensure no more than one of these flags is set */
  • /* Ensure no more than one of these flags is set */
    type_flags = flags & (SDL_WINDOW_UTILITY | SDL_WINDOW_TOOLTIP | SDL_WINDOW_POPUP_MENU);
    if (type_flags & (type_flags - 1)) {
    SDL_SetError(“Conflicting window type flags specified: 0x%.8x”, (unsigned int)type_flags);
    return NULL;
    }
  • /* Tooltip and popup menu window must specify a parent window */
  • if (!parent && ((type_flags & SDL_WINDOW_TOOLTIP) || (type_flags & SDL_WINDOW_POPUP_MENU))) {
  •    SDL_SetError("Tooltip and popup menu windows must specify a parent window");
    
  •    return NULL;
    
  • /* Make sure the display list is up to date for window placement */

  • if (_this->RefreshDisplays) {

  •    _this->RefreshDisplays(_this);
    

    }

    /* Some platforms can’t create zero-sized windows */
    @@ -1889,14 +1949,6 @@ static SDL_Window *SDL_CreateWindowInternal(const char *title, int x, int y, int
    h = 1;
    }

  • /* Some platforms blow up if the windows are too large. Raise it later? */

  • if (w > 16384) {

  •    w = 16384;
    
  • }

  • if (h > 16384) {

  •    h = 16384;
    
  • }

  • if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISUNDEFINED(y) ||
    SDL_WINDOWPOS_ISCENTERED(x) || SDL_WINDOWPOS_ISCENTERED(y)) {
    SDL_DisplayID displayID = 0;
    @@ -2013,7 +2065,7 @@ static SDL_Window *SDL_CreateWindowInternal(const char *title, int x, int y, int
    parent->first_child = window;
    }

  • if (_this->CreateSDLWindow && _this->CreateSDLWindow(_this, window) < 0) {

  • if (_this->CreateSDLWindow && _this->CreateSDLWindow(_this, window, props) < 0) {
    SDL_DestroyWindow(window);
    return NULL;
    }
    @@ -2057,28 +2109,23 @@ static SDL_Window *SDL_CreateWindowInternal(const char *title, int x, int y, int

SDL_Window *SDL_CreateWindow(const char *title, int w, int h, Uint32 flags)
{

  • return SDL_CreateWindowInternal(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w , h, NULL, flags);
    -}

-SDL_Window *SDL_CreateWindowWithPosition(const char *title, int x, int y, int w, int h, Uint32 flags)
-{

  • return SDL_CreateWindowInternal(title, x, y, w , h, NULL, flags);
  • SDL_Window *window;
  • SDL_PropertiesID props = SDL_CreateProperties();
  • if (title && *title) {
  •    SDL_SetStringProperty(props, "title", title);
    
  • }
  • SDL_SetNumberProperty(props, “width”, w);
  • SDL_SetNumberProperty(props, “height”, h);
  • SDL_SetNumberProperty(props, “flags”, flags);
  • window = SDL_CreateWindowWithProperties(props);
  • SDL_DestroyProperties(props);
  • return window;
    }

SDL_Window *SDL_CreatePopupWindow(SDL_Window *parent, int offset_x, int offset_y, int w, int h, Uint32 flags)
{

  • if (!_this) {
  •    SDL_UninitializedVideo();
    
  •    return NULL;
    
  • }
  • if (!(_this->quirk_flags & VIDEO_DEVICE_QUIRK_HAS_POPUP_WINDOW_SUPPORT)) {
  •    SDL_Unsupported();
    
  •    return NULL;
    
  • }
  • /* Parent must be a valid window */
  • CHECK_WINDOW_MAGIC(parent, NULL);
  • SDL_Window *window;

  • SDL_PropertiesID props = SDL_CreateProperties();

    /* Popups must specify either the tooltip or popup menu window flags */
    if (!(flags & (SDL_WINDOW_TOOLTIP

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