mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-05-24 16:36:00 +08:00
video: Implement asynchronous windowing
SDL window size, state, and position functions have been considered immediate, with their effects assuming to have taken effect upon successful return of the function. However, several windowing systems handle these requests asynchronously, resulting in the functions blocking until the changes have taken effect, potentially for long periods of time. Additionally, some windowing systems treat these as requests, and can potentially deny or fulfill the request in a manner differently than the application expects, such as not allowing a window to be positioned or sized beyond desktop borders, prohibiting fullscreen, and so on. With these changes, applications can make requests of the window manager that do not block, with the understanding that an associated event will be sent if the request is fulfilled. Currently, size, position, maximize, minimize, and fullscreen calls are handled as asynchronous requests, with events being returned if the request is honored. If the application requires that the change take effect immediately, it can call the new SDL_SyncWindow function, which will attempt to block until the request is fulfilled, or some arbitrary timeout period elapses, the duration of which depends not only on the windowing system, but on the operation requested as well (e.g. a 100ms timeout is fine for most X11 events, but maximizing a window can take considerably longer for some reason). There is also a new hint 'SDL_VIDEO_SYNC_ALL_WINDOW_OPS' that will mimic the old behavior by synchronizing after every window operation with, again, the understanding that using this may result in the associated calls blocking for a relatively long period. The deferred model also results in the window size and position getters not reporting false coordinates anymore, as they only forward what the window manager reports vs allowing applications to set arbitrary values, and fullscreen enter/leave events that were initiated via the window manager update the window state appropriately, where they didn't before. Care was taken to ensure that order of operations is maintained, and that requests are not ignored or dropped. This does require some implicit internal synchronization in the various backends if many requests are made in a short period, as some state and behavior depends on other bits of state that need to be known at that particular point in time, but this isn't something that typical applications will hit, unless they are sending a lot of window state in a short time as the tests do. The automated tests developed to test the previous behavior also resulted in previously undefined behavior being defined and normalized across platforms, particularly when it comes to the sizing and positioning of windows when they are in a fixed-size state, such as maximized or fullscreen. Size and position requests made when the window is not in a movable or resizable state will be deferred until it can be applied, so no requests are lost. These changes fix another long-standing issue with renderers recreating maximized windows, where the original non-maximized size was lost, resulting in the window being restored to the wrong size. All automated video tests pass across all platforms. Overall, the "make a request/get an event" model better reflects how most windowing systems work, and some backends avoid spending significant time blocking while waiting for operations to complete.
This commit is contained in:
committed by
Sam Lantinga
parent
ace385a134
commit
4fd778119b
@@ -1358,6 +1358,21 @@ The following symbols have been renamed:
|
||||
* SDL_WINDOW_ALLOW_HIGHDPI => SDL_WINDOW_HIGH_PIXEL_DENSITY
|
||||
* SDL_WINDOW_INPUT_GRABBED => SDL_WINDOW_MOUSE_GRABBED
|
||||
|
||||
The following window operations are now considered to be asynchronous requests and should not be assumed to succeed unless
|
||||
a corresponding event has been received:
|
||||
* SDL_SetWindowSize() (SDL_EVENT_WINDOW_RESIZED)
|
||||
* SDL_SetWindowPosition() (SDL_EVENT_WINDOW_MOVED)
|
||||
* SDL_MinimizeWindow() (SDL_EVENT_WINDOW_MINIMIZED)
|
||||
* SDL_MaximizeWindow() (SDL_EVENT_WINDOW_MAXIMIZED)
|
||||
* SDL_RestoreWindow() (SDL_EVENT_WINDOW_RESTORED)
|
||||
* SDL_SetWindowFullscreen() (SDL_EVENT_WINDOW_ENTER_FULLSCREEN / SDL_EVENT_WINDOW_LEAVE_FULLSCREEN)
|
||||
|
||||
If it is required that operations be applied immediately after one of the preceeding calls, the `SDL_SyncWindow()` function
|
||||
will attempt to wait until all pending window operations have completed. Be aware that this function can potentially block for
|
||||
long periods of time, as it may have to wait for window animations to complete. Also note that windowing systems can deny or
|
||||
not precisely obey these requests (e.g. windows may not be allowed to be larger than the usable desktop space or placed
|
||||
offscreen), so a corresponding event may never arrive or not contain the expected values.
|
||||
|
||||
## SDL_vulkan.h
|
||||
|
||||
SDL_Vulkan_GetInstanceExtensions() no longer takes a window parameter, and no longer makes the app allocate query/allocate space for the result, instead returning a static const internal string.
|
||||
|
||||
@@ -123,6 +123,8 @@ typedef enum
|
||||
SDL_EVENT_WINDOW_DISPLAY_CHANGED, /**< Window has been moved to display data1 */
|
||||
SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED, /**< Window display scale has been changed */
|
||||
SDL_EVENT_WINDOW_OCCLUDED, /**< The window has been occluded */
|
||||
SDL_EVENT_WINDOW_ENTER_FULLSCREEN, /**< The window has entered fullscreen mode */
|
||||
SDL_EVENT_WINDOW_LEAVE_FULLSCREEN, /**< The window has left fullscreen mode */
|
||||
SDL_EVENT_WINDOW_DESTROYED, /**< The window with the associated ID is being or has been destroyed. If this message is being handled
|
||||
in an event watcher, the window handle is still valid and can still be used to retrieve any userdata
|
||||
associated with the window. Otherwise, the handle has already been destroyed and all resources
|
||||
|
||||
@@ -1795,6 +1795,25 @@ extern "C" {
|
||||
*/
|
||||
#define SDL_HINT_VIDEO_WAYLAND_EMULATE_MOUSE_WARP "SDL_VIDEO_WAYLAND_EMULATE_MOUSE_WARP"
|
||||
|
||||
/**
|
||||
* Set whether all window operations will block until complete.
|
||||
*
|
||||
* Window systems that run asynchronously may not have the results of window operations that resize or move the window
|
||||
* applied immediately upon the return of the requesting function. Setting this hint will cause such operations to block
|
||||
* after every call until the pending operation has completed. Setting this to '1' is the equivalent of calling
|
||||
* SDL_SyncWindow() after every function call.
|
||||
*
|
||||
* Be aware that amount of time spent blocking while waiting for window operations to complete can be quite lengthy, as
|
||||
* animations may have to complete, which can take upwards of multiple seconds in some cases.
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
* "0" - Window operations are non-blocking
|
||||
* "1" - Window operations will block until completed
|
||||
*
|
||||
* By default SDL will run in non-blocking mode
|
||||
*/
|
||||
#define SDL_HINT_VIDEO_SYNC_WINDOW_OPERATIONS "SDL_VIDEO_SYNC_WINDOW_OPERATIONS"
|
||||
|
||||
/**
|
||||
* A variable specifying which shader compiler to preload when using the Chrome ANGLE binaries
|
||||
*
|
||||
|
||||
+133
-8
@@ -630,6 +630,15 @@ extern DECLSPEC float SDLCALL SDL_GetWindowDisplayScale(SDL_Window *window);
|
||||
* change the window size when the window is not fullscreen, use
|
||||
* SDL_SetWindowSize().
|
||||
*
|
||||
* If the window is currently in the fullscreen state, this request is asynchronous
|
||||
* on some windowing systems and the new mode dimensions may not be applied
|
||||
* immediately upon the return of this function. If an immediate change is required,
|
||||
* call SDL_SyncWindow() to block until the changes have taken effect.
|
||||
*
|
||||
* When the new mode takes effect, an SDL_EVENT_WINDOW_RESIZED and/or an
|
||||
* SDL_EVENT_WINDOOW_PIXEL_SIZE_CHANGED event will be emitted with the new
|
||||
* mode dimensions.
|
||||
*
|
||||
* \param window the window to affect
|
||||
* \param mode a pointer to the display mode to use, which can be NULL for
|
||||
* desktop mode, or one of the fullscreen modes returned by
|
||||
@@ -641,6 +650,7 @@ extern DECLSPEC float SDLCALL SDL_GetWindowDisplayScale(SDL_Window *window);
|
||||
*
|
||||
* \sa SDL_GetWindowFullscreenMode
|
||||
* \sa SDL_SetWindowFullscreen
|
||||
* \sa SDL_SyncWindow
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_SetWindowFullscreenMode(SDL_Window *window, const SDL_DisplayMode *mode);
|
||||
|
||||
@@ -1070,7 +1080,27 @@ extern DECLSPEC const char *SDLCALL SDL_GetWindowTitle(SDL_Window *window);
|
||||
extern DECLSPEC int SDLCALL SDL_SetWindowIcon(SDL_Window *window, SDL_Surface *icon);
|
||||
|
||||
/**
|
||||
* Set the position of a window.
|
||||
* Request that the window's position be set.
|
||||
*
|
||||
* If, at the time of this request, the window is in a fixed-size state such as
|
||||
* maximized, this request may be deferred until the window returns to a resizable
|
||||
* state.
|
||||
*
|
||||
* This can be used to reposition fullscreen-desktop windows onto a different display,
|
||||
* however, exclusive fullscreen windows are locked to a specific display and can
|
||||
* only be repositioned programmatically via SDL_SetWindowFullscreenMode().
|
||||
*
|
||||
* On some windowing systems this request is asynchronous and the new coordinates
|
||||
* may not have have been applied immediately upon the return of this function.
|
||||
* If an immediate change is required, call SDL_SyncWindow() to block until the changes
|
||||
* have taken effect.
|
||||
*
|
||||
* When the window position changes, an SDL_EVENT_WINDOW_MOVED event will be
|
||||
* emitted with the window's new coordinates. Note that the new coordinates may
|
||||
* not match the exact coordinates requested, as some windowing systems can restrict
|
||||
* the position of the window in certain scenarios (e.g. constraining the position
|
||||
* so the window is always within desktop bounds). Additionally, as this is just a
|
||||
* request, it can be denied by the windowing system.
|
||||
*
|
||||
* \param window the window to reposition
|
||||
* \param x the x coordinate of the window, or `SDL_WINDOWPOS_CENTERED` or
|
||||
@@ -1083,12 +1113,16 @@ extern DECLSPEC int SDLCALL SDL_SetWindowIcon(SDL_Window *window, SDL_Surface *i
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_GetWindowPosition
|
||||
* \sa SDL_SyncWindow
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_SetWindowPosition(SDL_Window *window, int x, int y);
|
||||
|
||||
/**
|
||||
* Get the position of a window.
|
||||
*
|
||||
* This is the current position of the window as last reported by the windowing
|
||||
* system.
|
||||
*
|
||||
* If you do not need the value for one of the positions a NULL may be passed
|
||||
* in the `x` or `y` parameter.
|
||||
*
|
||||
@@ -1105,10 +1139,28 @@ extern DECLSPEC int SDLCALL SDL_SetWindowPosition(SDL_Window *window, int x, int
|
||||
extern DECLSPEC int SDLCALL SDL_GetWindowPosition(SDL_Window *window, int *x, int *y);
|
||||
|
||||
/**
|
||||
* Set the size of a window's client area.
|
||||
* Request that the size of a window's client area be set.
|
||||
*
|
||||
* This only affects the size of the window when not in fullscreen mode. To
|
||||
* change the fullscreen mode of a window, use SDL_SetWindowFullscreenMode()
|
||||
* NULL can safely be passed as the `w` or `h` parameter if the width or
|
||||
* height value is not desired.
|
||||
*
|
||||
* If, at the time of this request, the window in a fixed-size state, such
|
||||
* as maximized or fullscreen, the request will be deferred until the window
|
||||
* exits this state and becomes resizable again.
|
||||
*
|
||||
* To change the fullscreen mode of a window, use SDL_SetWindowFullscreenMode()
|
||||
*
|
||||
* On some windowing systems, this request is asynchronous and the new window size
|
||||
* may not have have been applied immediately upon the return of this function.
|
||||
* If an immediate change is required, call SDL_SyncWindow() to block until the
|
||||
* changes have taken effect.
|
||||
*
|
||||
* When the window size changes, an SDL_EVENT_WINDOW_RESIZED event will be
|
||||
* emitted with the new window dimensions. Note that the new dimensions may
|
||||
* not match the exact size requested, as some windowing systems can restrict
|
||||
* the window size in certain scenarios (e.g. constraining the size of the content
|
||||
* area to remain within the usable desktop bounds). Additionally, as this is just
|
||||
* a request, it can be denied by the windowing system.
|
||||
*
|
||||
* \param window the window to change
|
||||
* \param w the width of the window, must be > 0
|
||||
@@ -1120,6 +1172,7 @@ extern DECLSPEC int SDLCALL SDL_GetWindowPosition(SDL_Window *window, int *x, in
|
||||
*
|
||||
* \sa SDL_GetWindowSize
|
||||
* \sa SDL_SetWindowFullscreenMode
|
||||
* \sa SDL_SyncWindow
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_SetWindowSize(SDL_Window *window, int w, int h);
|
||||
|
||||
@@ -1363,7 +1416,22 @@ extern DECLSPEC int SDLCALL SDL_HideWindow(SDL_Window *window);
|
||||
extern DECLSPEC int SDLCALL SDL_RaiseWindow(SDL_Window *window);
|
||||
|
||||
/**
|
||||
* Make a window as large as possible.
|
||||
* Request that the window be made as large as possible.
|
||||
*
|
||||
* Non-resizable windows can't be maximized. The window must have the
|
||||
* SDL_WINDOW_RESIZABLE flag set, or this will have no effect.
|
||||
*
|
||||
* On some windowing systems this request is asynchronous and the new window state
|
||||
* may not have have been applied immediately upon the return of this function.
|
||||
* If an immediate change is required, call SDL_SyncWindow() to block until the
|
||||
* changes have taken effect.
|
||||
*
|
||||
* When the window state changes, an SDL_EVENT_WINDOW_MAXIMIZED event will be emitted.
|
||||
* Note that, as this is just a request, the windowing system can deny the state change.
|
||||
*
|
||||
* When maximizing a window, whether the constraints set via SDL_SetWindowMaximumSize()
|
||||
* are honored depends on the policy of the window manager. Win32 and macOS enforce the
|
||||
* constraints when maximizing, while X11 and Wayland window managers may vary.
|
||||
*
|
||||
* \param window the window to maximize
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
@@ -1373,11 +1441,20 @@ extern DECLSPEC int SDLCALL SDL_RaiseWindow(SDL_Window *window);
|
||||
*
|
||||
* \sa SDL_MinimizeWindow
|
||||
* \sa SDL_RestoreWindow
|
||||
* \sa SDL_SyncWindow
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_MaximizeWindow(SDL_Window *window);
|
||||
|
||||
/**
|
||||
* Minimize a window to an iconic representation.
|
||||
* Request that the window be minimized to an iconic representation.
|
||||
*
|
||||
* On some windowing systems this request is asynchronous and the new window state
|
||||
* may not have have been applied immediately upon the return of this function.
|
||||
* If an immediate change is required, call SDL_SyncWindow() to block until the
|
||||
* changes have taken effect.
|
||||
*
|
||||
* When the window state changes, an SDL_EVENT_WINDOW_MINIMIZED event will be emitted.
|
||||
* Note that, as this is just a request, the windowing system can deny the state change.
|
||||
*
|
||||
* \param window the window to minimize
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
@@ -1387,11 +1464,20 @@ extern DECLSPEC int SDLCALL SDL_MaximizeWindow(SDL_Window *window);
|
||||
*
|
||||
* \sa SDL_MaximizeWindow
|
||||
* \sa SDL_RestoreWindow
|
||||
* \sa SDL_SyncWindow
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_MinimizeWindow(SDL_Window *window);
|
||||
|
||||
/**
|
||||
* Restore the size and position of a minimized or maximized window.
|
||||
* Request that the size and position of a minimized or maximized window be restored.
|
||||
*
|
||||
* On some windowing systems this request is asynchronous and the new window state
|
||||
* may not have have been applied immediately upon the return of this function.
|
||||
* If an immediate change is required, call SDL_SyncWindow() to block until the
|
||||
* changes have taken effect.
|
||||
*
|
||||
* When the window state changes, an SDL_EVENT_WINDOW_RESTORED event will be emitted.
|
||||
* Note that, as this is just a request, the windowing system can deny the state change.
|
||||
*
|
||||
* \param window the window to restore
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
@@ -1401,15 +1487,25 @@ extern DECLSPEC int SDLCALL SDL_MinimizeWindow(SDL_Window *window);
|
||||
*
|
||||
* \sa SDL_MaximizeWindow
|
||||
* \sa SDL_MinimizeWindow
|
||||
* \sa SDL_SyncWindow
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_RestoreWindow(SDL_Window *window);
|
||||
|
||||
/**
|
||||
* Set a window's fullscreen state.
|
||||
* Request that the window's fullscreen state be changed.
|
||||
*
|
||||
* By default a window in fullscreen state uses fullscreen desktop mode, but a
|
||||
* specific display mode can be set using SDL_SetWindowFullscreenMode().
|
||||
*
|
||||
* On some windowing systems this request is asynchronous and the new fullscreen
|
||||
* state may not have have been applied immediately upon the return of this function.
|
||||
* If an immediate change is required, call SDL_SyncWindow() to block until the
|
||||
* changes have taken effect.
|
||||
*
|
||||
* When the window state changes, an SDL_EVENT_WINDOW_ENTER_FULLSCREEN or
|
||||
* SDL_EVENT_WINDOW_LEAVE_FULLSCREEN event will be emitted. Note that, as this is
|
||||
* just a request, it can be denied by the windowing system.
|
||||
*
|
||||
* \param window the window to change
|
||||
* \param fullscreen SDL_TRUE for fullscreen mode, SDL_FALSE for windowed mode
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
@@ -1419,9 +1515,38 @@ extern DECLSPEC int SDLCALL SDL_RestoreWindow(SDL_Window *window);
|
||||
*
|
||||
* \sa SDL_GetWindowFullscreenMode
|
||||
* \sa SDL_SetWindowFullscreenMode
|
||||
* \sa SDL_SyncWindow
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_SetWindowFullscreen(SDL_Window *window, SDL_bool fullscreen);
|
||||
|
||||
/**
|
||||
* Block until any pending window state is finalized.
|
||||
*
|
||||
* On asynchronous windowing systems, this acts as a synchronization barrier for
|
||||
* pending window state. It will attempt to wait until any pending window state
|
||||
* has been applied and is guaranteed to return within finite time. Note that for
|
||||
* how long it can potentially block depends on the underlying window system, as
|
||||
* window state changes may involve somewhat lengthy animations that must complete
|
||||
* before the window is in its final requested state.
|
||||
*
|
||||
* On windowing systems where changes are immediate, this does nothing.
|
||||
*
|
||||
* \param window the window for which to wait for the pending state to be applied
|
||||
* \returns 0 on success, a positive value if the operation timed out before the
|
||||
* window was in the requested state, or a negative error code on failure;
|
||||
* call SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_SetWindowSize
|
||||
* \sa SDL_SetWindowPosition
|
||||
* \sa SDL_SetWindowFullscreen
|
||||
* \sa SDL_MinimizeWindow
|
||||
* \sa SDL_MaximizeWindow
|
||||
* \sa SDL_RestoreWindow
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_SyncWindow(SDL_Window *window);
|
||||
|
||||
/**
|
||||
* Return whether the window has a surface associated with it.
|
||||
*
|
||||
|
||||
@@ -962,6 +962,7 @@ SDL3_0.0.0 {
|
||||
SDL_GetTouchDeviceName;
|
||||
SDL_strnstr;
|
||||
SDL_wcsnstr;
|
||||
SDL_SyncWindow;
|
||||
# extra symbols go here (don't modify this line)
|
||||
local: *;
|
||||
};
|
||||
|
||||
@@ -987,3 +987,4 @@
|
||||
#define SDL_GetTouchDeviceName SDL_GetTouchDeviceName_REAL
|
||||
#define SDL_strnstr SDL_strnstr_REAL
|
||||
#define SDL_wcsnstr SDL_wcsnstr_REAL
|
||||
#define SDL_SyncWindow SDL_SyncWindow_REAL
|
||||
|
||||
@@ -1012,3 +1012,4 @@ SDL_DYNAPI_PROC(SDL_TouchID*,SDL_GetTouchDevices,(int *a),(a),return)
|
||||
SDL_DYNAPI_PROC(const char*,SDL_GetTouchDeviceName,(SDL_TouchID a),(a),return)
|
||||
SDL_DYNAPI_PROC(char*,SDL_strnstr,(const char *a, const char *b, size_t c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(wchar_t*,SDL_wcsnstr,(const wchar_t *a, const wchar_t *b, size_t c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_SyncWindow,(SDL_Window *a),(a),return)
|
||||
|
||||
@@ -312,6 +312,8 @@ static void SDL_LogEvent(const SDL_Event *event)
|
||||
SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_DISPLAY_CHANGED);
|
||||
SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED);
|
||||
SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_OCCLUDED);
|
||||
SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_ENTER_FULLSCREEN);
|
||||
SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_LEAVE_FULLSCREEN);
|
||||
SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_DESTROYED);
|
||||
#undef SDL_WINDOWEVENT_CASE
|
||||
|
||||
|
||||
@@ -71,6 +71,11 @@ int SDL_SendWindowEvent(SDL_Window *window, SDL_EventType windowevent,
|
||||
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
|
||||
window->windowed.x = data1;
|
||||
window->windowed.y = data2;
|
||||
|
||||
if (!(window->flags & SDL_WINDOW_MAXIMIZED) && !window->state_not_floating) {
|
||||
window->floating.x = data1;
|
||||
window->floating.y = data2;
|
||||
}
|
||||
}
|
||||
if (data1 == window->x && data2 == window->y) {
|
||||
return 0;
|
||||
@@ -82,6 +87,11 @@ int SDL_SendWindowEvent(SDL_Window *window, SDL_EventType windowevent,
|
||||
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
|
||||
window->windowed.w = data1;
|
||||
window->windowed.h = data2;
|
||||
|
||||
if (!(window->flags & SDL_WINDOW_MAXIMIZED) && !window->state_not_floating) {
|
||||
window->floating.w = data1;
|
||||
window->floating.h = data2;
|
||||
}
|
||||
}
|
||||
if (data1 == window->w && data2 == window->h) {
|
||||
SDL_CheckWindowPixelSizeChanged(window);
|
||||
@@ -153,6 +163,18 @@ int SDL_SendWindowEvent(SDL_Window *window, SDL_EventType windowevent,
|
||||
}
|
||||
window->flags |= SDL_WINDOW_OCCLUDED;
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_ENTER_FULLSCREEN:
|
||||
if (window->flags & SDL_WINDOW_FULLSCREEN) {
|
||||
return 0;
|
||||
}
|
||||
window->flags |= SDL_WINDOW_FULLSCREEN;
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_LEAVE_FULLSCREEN:
|
||||
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
|
||||
return 0;
|
||||
}
|
||||
window->flags &= ~SDL_WINDOW_FULLSCREEN;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1777,6 +1777,7 @@ static SDL_Renderer *GL_CreateRenderer(SDL_Window *window, SDL_PropertiesID crea
|
||||
SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &minor);
|
||||
|
||||
#ifndef SDL_VIDEO_VITA_PVR_OGL
|
||||
SDL_SyncWindow(window);
|
||||
window_flags = SDL_GetWindowFlags(window);
|
||||
if (!(window_flags & SDL_WINDOW_OPENGL) ||
|
||||
profile_mask == SDL_GL_CONTEXT_PROFILE_ES || major != RENDERER_CONTEXT_MAJOR || minor != RENDERER_CONTEXT_MINOR) {
|
||||
|
||||
@@ -2088,6 +2088,7 @@ static SDL_Renderer *GLES2_CreateRenderer(SDL_Window *window, SDL_PropertiesID c
|
||||
goto error;
|
||||
}
|
||||
|
||||
SDL_SyncWindow(window);
|
||||
window_flags = SDL_GetWindowFlags(window);
|
||||
|
||||
/* OpenGL ES 3.0 is a superset of OpenGL ES 2.0 */
|
||||
|
||||
@@ -1744,6 +1744,15 @@ static void SDLTest_PrintEvent(const SDL_Event *event)
|
||||
case SDL_EVENT_WINDOW_OCCLUDED:
|
||||
SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " occluded", event->window.windowID);
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_ENTER_FULLSCREEN:
|
||||
SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " entered fullscreen", event->window.windowID);
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_LEAVE_FULLSCREEN:
|
||||
SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " left fullscreen", event->window.windowID);
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_DESTROYED:
|
||||
SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " destroyed", event->window.windowID);
|
||||
break;
|
||||
case SDL_EVENT_KEY_DOWN:
|
||||
case SDL_EVENT_KEY_UP: {
|
||||
char modstr[64];
|
||||
|
||||
+32
-11
@@ -53,9 +53,27 @@ struct SDL_Window
|
||||
SDL_DisplayID last_fullscreen_exclusive_display; /* The last fullscreen_exclusive display */
|
||||
SDL_DisplayID last_displayID;
|
||||
|
||||
/* Stored position and size for windowed mode */
|
||||
/* Stored position and size for the window in the non-fullscreen state,
|
||||
* including when the window is maximized or tiled.
|
||||
*
|
||||
* This is the size and position to which the window should return when
|
||||
* leaving the fullscreen state.
|
||||
*/
|
||||
SDL_Rect windowed;
|
||||
|
||||
/* Stored position and size for the window in the base 'floating' state;
|
||||
* when not fullscreen, nor in a state such as maximized or tiled.
|
||||
*
|
||||
* This is the size and position to which the window should return when
|
||||
* it's maximized and SDL_RestoreWindow() is called.
|
||||
*/
|
||||
SDL_Rect floating;
|
||||
|
||||
/* Toggle for drivers to indicate that the current window state is
|
||||
* not floating, but may not have any fixed-size flags (e.g. tiled)
|
||||
*/
|
||||
SDL_bool state_not_floating;
|
||||
|
||||
/* Whether or not the initial position was defined */
|
||||
SDL_bool undefined_x;
|
||||
SDL_bool undefined_y;
|
||||
@@ -95,10 +113,9 @@ struct SDL_Window
|
||||
(((W)->flags & SDL_WINDOW_HIDDEN) == 0) && \
|
||||
(((W)->flags & SDL_WINDOW_MINIMIZED) == 0))
|
||||
|
||||
#define SDL_WINDOW_IS_POPUP(W) \
|
||||
((((W)->flags & SDL_WINDOW_TOOLTIP) != 0) || \
|
||||
(((W)->flags & SDL_WINDOW_POPUP_MENU) != 0)) \
|
||||
\
|
||||
#define SDL_WINDOW_IS_POPUP(W) \
|
||||
(((W)->flags & (SDL_WINDOW_TOOLTIP | SDL_WINDOW_POPUP_MENU)) != 0)
|
||||
|
||||
/*
|
||||
* Define the SDL display structure.
|
||||
* This corresponds to physical monitors attached to the system.
|
||||
@@ -128,10 +145,10 @@ struct SDL_VideoDisplay
|
||||
/* Video device flags */
|
||||
typedef enum
|
||||
{
|
||||
VIDEO_DEVICE_QUIRK_MODE_SWITCHING_EMULATED = 0x01,
|
||||
VIDEO_DEVICE_QUIRK_DISABLE_UNSET_FULLSCREEN_ON_MINIMIZE = 0x02,
|
||||
VIDEO_DEVICE_QUIRK_HAS_POPUP_WINDOW_SUPPORT = 0x04,
|
||||
} DeviceQuirkFlags;
|
||||
VIDEO_DEVICE_CAPS_MODE_SWITCHING_EMULATED = 0x01,
|
||||
VIDEO_DEVICE_CAPS_HAS_POPUP_WINDOW_SUPPORT = 0x02,
|
||||
VIDEO_DEVICE_CAPS_SENDS_FULLSCREEN_DIMENSIONS = 0x04
|
||||
} DeviceCaps;
|
||||
|
||||
struct SDL_VideoDevice
|
||||
{
|
||||
@@ -217,7 +234,7 @@ struct SDL_VideoDevice
|
||||
void (*SetWindowBordered)(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool bordered);
|
||||
void (*SetWindowResizable)(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool resizable);
|
||||
void (*SetWindowAlwaysOnTop)(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool on_top);
|
||||
void (*SetWindowFullscreen)(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen);
|
||||
int (*SetWindowFullscreen)(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen);
|
||||
void *(*GetWindowICCProfile)(SDL_VideoDevice *_this, SDL_Window *window, size_t *size);
|
||||
SDL_DisplayID (*GetDisplayForWindow)(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
void (*SetWindowMouseRect)(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
@@ -230,6 +247,7 @@ struct SDL_VideoDevice
|
||||
void (*OnWindowEnter)(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
int (*FlashWindow)(SDL_VideoDevice *_this, SDL_Window *window, SDL_FlashOperation operation);
|
||||
int (*SetWindowFocusable)(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool focusable);
|
||||
int (*SyncWindow)(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
|
||||
/* * * */
|
||||
/*
|
||||
@@ -335,7 +353,7 @@ struct SDL_VideoDevice
|
||||
size_t num_clipboard_mime_types;
|
||||
char *primary_selection_text;
|
||||
SDL_bool setting_display_mode;
|
||||
Uint32 quirk_flags;
|
||||
Uint32 device_caps;
|
||||
SDL_SystemTheme system_theme;
|
||||
|
||||
/* * * */
|
||||
@@ -469,8 +487,10 @@ extern void SDL_ResetFullscreenDisplayModes(SDL_VideoDisplay *display);
|
||||
extern void SDL_SetDesktopDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode);
|
||||
extern void SDL_SetCurrentDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode);
|
||||
extern void SDL_SetDisplayContentScale(SDL_VideoDisplay *display, float scale);
|
||||
extern int SDL_SetDisplayModeForDisplay(SDL_VideoDisplay *display, SDL_DisplayMode *mode);
|
||||
extern SDL_VideoDisplay *SDL_GetVideoDisplay(SDL_DisplayID display);
|
||||
extern SDL_VideoDisplay *SDL_GetVideoDisplayForWindow(SDL_Window *window);
|
||||
extern SDL_VideoDisplay *SDL_GetVideoDisplayForFullscreenWindow(SDL_Window *window);
|
||||
extern int SDL_GetDisplayIndex(SDL_DisplayID displayID);
|
||||
extern SDL_DisplayData *SDL_GetDisplayDriverData(SDL_DisplayID display);
|
||||
extern SDL_DisplayData *SDL_GetDisplayDriverDataForWindow(SDL_Window *window);
|
||||
@@ -499,6 +519,7 @@ extern void SDL_OnWindowFocusGained(SDL_Window *window);
|
||||
extern void SDL_OnWindowFocusLost(SDL_Window *window);
|
||||
extern void SDL_OnWindowDisplayChanged(SDL_Window *window);
|
||||
extern void SDL_UpdateWindowGrab(SDL_Window *window);
|
||||
extern int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen, SDL_bool commit);
|
||||
extern SDL_Window *SDL_GetToplevelForKeyboardFocus(void);
|
||||
|
||||
extern SDL_bool SDL_ShouldAllowTopmost(void);
|
||||
|
||||
+260
-211
File diff suppressed because it is too large
Load Diff
@@ -155,6 +155,8 @@ static SDL_VideoDevice *Android_CreateDevice(void)
|
||||
device->GetClipboardText = Android_GetClipboardText;
|
||||
device->HasClipboardText = Android_HasClipboardText;
|
||||
|
||||
device->device_caps = VIDEO_DEVICE_CAPS_SENDS_FULLSCREEN_DIMENSIONS;
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ void Android_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
Android_JNI_SetActivityTitle(window->title);
|
||||
}
|
||||
|
||||
void Android_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
|
||||
int Android_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
|
||||
{
|
||||
SDL_LockMutex(Android_ActivityMutex);
|
||||
|
||||
@@ -154,6 +154,7 @@ void Android_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL
|
||||
endfunction:
|
||||
|
||||
SDL_UnlockMutex(Android_ActivityMutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Android_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
extern int Android_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props);
|
||||
extern void Android_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void Android_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen);
|
||||
extern int Android_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen);
|
||||
extern void Android_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void Android_SetWindowResizable(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool resizable);
|
||||
|
||||
|
||||
@@ -489,6 +489,8 @@ int Cocoa_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_
|
||||
CGDisplayFadeReservationToken fade_token = kCGDisplayFadeReservationInvalidToken;
|
||||
CGError result = kCGErrorSuccess;
|
||||
|
||||
b_inModeTransition = SDL_TRUE;
|
||||
|
||||
/* Fade to black to hide resolution-switching flicker */
|
||||
if (CGAcquireDisplayFadeReservation(5, &fade_token) == kCGErrorSuccess) {
|
||||
CGDisplayFade(fade_token, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, TRUE);
|
||||
@@ -508,6 +510,8 @@ int Cocoa_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_
|
||||
CGReleaseDisplayFadeReservation(fade_token);
|
||||
}
|
||||
|
||||
b_inModeTransition = SDL_FALSE;
|
||||
|
||||
if (result != kCGErrorSuccess) {
|
||||
CG_SetError("CGDisplaySwitchToMode()", result);
|
||||
return -1;
|
||||
|
||||
@@ -116,6 +116,7 @@ static SDL_VideoDevice *Cocoa_CreateDevice(void)
|
||||
device->AcceptDragAndDrop = Cocoa_AcceptDragAndDrop;
|
||||
device->FlashWindow = Cocoa_FlashWindow;
|
||||
device->SetWindowFocusable = Cocoa_SetWindowFocusable;
|
||||
device->SyncWindow = Cocoa_SyncWindow;
|
||||
|
||||
#ifdef SDL_VIDEO_OPENGL_CGL
|
||||
device->GL_LoadLibrary = Cocoa_GL_LoadLibrary;
|
||||
@@ -171,8 +172,8 @@ static SDL_VideoDevice *Cocoa_CreateDevice(void)
|
||||
|
||||
device->free = Cocoa_DeleteDevice;
|
||||
|
||||
device->quirk_flags = VIDEO_DEVICE_QUIRK_HAS_POPUP_WINDOW_SUPPORT;
|
||||
|
||||
device->device_caps = VIDEO_DEVICE_CAPS_HAS_POPUP_WINDOW_SUPPORT |
|
||||
VIDEO_DEVICE_CAPS_SENDS_FULLSCREEN_DIMENSIONS;
|
||||
return device;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,10 +35,10 @@
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PENDING_OPERATION_NONE,
|
||||
PENDING_OPERATION_ENTER_FULLSCREEN,
|
||||
PENDING_OPERATION_LEAVE_FULLSCREEN,
|
||||
PENDING_OPERATION_MINIMIZE
|
||||
PENDING_OPERATION_NONE = 0x00,
|
||||
PENDING_OPERATION_ENTER_FULLSCREEN = 0x01,
|
||||
PENDING_OPERATION_LEAVE_FULLSCREEN = 0x02,
|
||||
PENDING_OPERATION_MINIMIZE = 0x04
|
||||
} PendingWindowOperation;
|
||||
|
||||
@interface Cocoa_WindowListener : NSResponder <NSWindowDelegate>
|
||||
@@ -54,6 +54,7 @@ typedef enum
|
||||
BOOL inFullscreenTransition;
|
||||
PendingWindowOperation pendingWindowOperation;
|
||||
BOOL isMoving;
|
||||
BOOL isMiniaturizing;
|
||||
NSInteger focusClickPending;
|
||||
float pendingWindowWarpX, pendingWindowWarpY;
|
||||
BOOL isDragAreaRunning;
|
||||
@@ -130,17 +131,23 @@ typedef enum
|
||||
@property(nonatomic) NSView *sdlContentView;
|
||||
@property(nonatomic) NSMutableArray *nscontexts;
|
||||
@property(nonatomic) SDL_bool created;
|
||||
@property(nonatomic) SDL_bool inWindowFullscreenTransition;
|
||||
@property(nonatomic) BOOL in_blocking_transition;
|
||||
@property(nonatomic) BOOL was_zoomed;
|
||||
@property(nonatomic) NSInteger window_number;
|
||||
@property(nonatomic) NSInteger flash_request;
|
||||
@property(nonatomic) SDL_Window *keyboard_focus;
|
||||
@property(nonatomic) Cocoa_WindowListener *listener;
|
||||
@property(nonatomic) SDL_CocoaVideoData *videodata;
|
||||
@property(nonatomic) SDL_bool send_floating_size;
|
||||
@property(nonatomic) SDL_bool send_floating_position;
|
||||
@property(nonatomic) BOOL checking_zoom;
|
||||
#ifdef SDL_VIDEO_OPENGL_EGL
|
||||
@property(nonatomic) EGLSurface egl_surface;
|
||||
#endif
|
||||
@end
|
||||
|
||||
extern SDL_bool b_inModeTransition;
|
||||
|
||||
extern int Cocoa_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props);
|
||||
extern void Cocoa_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern int Cocoa_SetWindowIcon(SDL_VideoDevice *_this, SDL_Window *window, SDL_Surface *icon);
|
||||
@@ -159,7 +166,7 @@ extern void Cocoa_RestoreWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void Cocoa_SetWindowBordered(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool bordered);
|
||||
extern void Cocoa_SetWindowResizable(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool resizable);
|
||||
extern void Cocoa_SetWindowAlwaysOnTop(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool on_top);
|
||||
extern void Cocoa_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen);
|
||||
extern int Cocoa_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen);
|
||||
extern void *Cocoa_GetWindowICCProfile(SDL_VideoDevice *_this, SDL_Window *window, size_t *size);
|
||||
extern SDL_DisplayID Cocoa_GetDisplayForWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void Cocoa_SetWindowMouseRect(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
@@ -169,5 +176,6 @@ extern int Cocoa_SetWindowHitTest(SDL_Window *window, SDL_bool enabled);
|
||||
extern void Cocoa_AcceptDragAndDrop(SDL_Window *window, SDL_bool accept);
|
||||
extern int Cocoa_FlashWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_FlashOperation operation);
|
||||
extern int Cocoa_SetWindowFocusable(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool focusable);
|
||||
extern int Cocoa_SyncWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
|
||||
#endif /* SDL_cocoawindow_h_ */
|
||||
|
||||
+354
-168
File diff suppressed because it is too large
Load Diff
@@ -55,6 +55,17 @@
|
||||
static int DUMMY_VideoInit(SDL_VideoDevice *_this);
|
||||
static void DUMMY_VideoQuit(SDL_VideoDevice *_this);
|
||||
|
||||
static int DUMMY_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
{
|
||||
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_MOVED, window->floating.x, window->floating.y);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void DUMMY_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
{
|
||||
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESIZED, window->floating.w, window->floating.h);
|
||||
}
|
||||
|
||||
/* DUMMY driver bootstrap functions */
|
||||
|
||||
static int DUMMY_Available(const char *enable_hint)
|
||||
@@ -92,6 +103,8 @@ static SDL_VideoDevice *DUMMY_InternalCreateDevice(const char *enable_hint)
|
||||
device->VideoInit = DUMMY_VideoInit;
|
||||
device->VideoQuit = DUMMY_VideoQuit;
|
||||
device->PumpEvents = DUMMY_PumpEvents;
|
||||
device->SetWindowSize = DUMMY_SetWindowSize;
|
||||
device->SetWindowPosition = DUMMY_SetWindowPosition;
|
||||
device->CreateWindowFramebuffer = SDL_DUMMY_CreateWindowFramebuffer;
|
||||
device->UpdateWindowFramebuffer = SDL_DUMMY_UpdateWindowFramebuffer;
|
||||
device->DestroyWindowFramebuffer = SDL_DUMMY_DestroyWindowFramebuffer;
|
||||
|
||||
@@ -843,23 +843,16 @@ static EM_BOOL Emscripten_HandleKeyPress(int eventType, const EmscriptenKeyboard
|
||||
static EM_BOOL Emscripten_HandleFullscreenChange(int eventType, const EmscriptenFullscreenChangeEvent *fullscreenChangeEvent, void *userData)
|
||||
{
|
||||
SDL_WindowData *window_data = userData;
|
||||
SDL_VideoDisplay *display;
|
||||
|
||||
if (fullscreenChangeEvent->isFullscreen) {
|
||||
window_data->window->flags |= window_data->fullscreen_mode_flags;
|
||||
|
||||
SDL_SendWindowEvent(window_data->window, SDL_EVENT_WINDOW_ENTER_FULLSCREEN, 0, 0);
|
||||
window_data->fullscreen_mode_flags = 0;
|
||||
} else {
|
||||
window_data->window->flags &= ~SDL_WINDOW_FULLSCREEN;
|
||||
|
||||
/* reset fullscreen window if the browser left fullscreen */
|
||||
display = SDL_GetVideoDisplayForWindow(window_data->window);
|
||||
|
||||
if (display->fullscreen_window == window_data->window) {
|
||||
display->fullscreen_window = NULL;
|
||||
}
|
||||
SDL_SendWindowEvent(window_data->window, SDL_EVENT_WINDOW_LEAVE_FULLSCREEN, 0, 0);
|
||||
}
|
||||
|
||||
SDL_UpdateFullscreenMode(window_data->window, fullscreenChangeEvent->isFullscreen, SDL_FALSE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ static int Emscripten_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, S
|
||||
static void Emscripten_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
static void Emscripten_GetWindowSizeInPixels(SDL_VideoDevice *_this, SDL_Window *window, int *w, int *h);
|
||||
static void Emscripten_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
static void Emscripten_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen);
|
||||
static int Emscripten_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen);
|
||||
static void Emscripten_PumpEvents(SDL_VideoDevice *_this);
|
||||
static void Emscripten_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
|
||||
@@ -247,12 +247,14 @@ static void Emscripten_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
if (window->flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) {
|
||||
data->pixel_ratio = emscripten_get_device_pixel_ratio();
|
||||
}
|
||||
emscripten_set_canvas_element_size(data->canvas_id, window->w * data->pixel_ratio, window->h * data->pixel_ratio);
|
||||
emscripten_set_canvas_element_size(data->canvas_id, window->floating.w * data->pixel_ratio, window->floating.h * data->pixel_ratio);
|
||||
|
||||
/*scale canvas down*/
|
||||
if (!data->external_size && data->pixel_ratio != 1.0f) {
|
||||
emscripten_set_element_css_size(data->canvas_id, window->w, window->h);
|
||||
emscripten_set_element_css_size(data->canvas_id, window->floating.w, window->floating.h);
|
||||
}
|
||||
|
||||
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESIZED, window->floating.w, window->floating.h);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -284,16 +286,17 @@ static void Emscripten_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
}
|
||||
}
|
||||
|
||||
static void Emscripten_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
|
||||
static int Emscripten_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
|
||||
{
|
||||
SDL_WindowData *data;
|
||||
int res = -1;
|
||||
|
||||
if (window->driverdata) {
|
||||
data = window->driverdata;
|
||||
|
||||
if (fullscreen) {
|
||||
EmscriptenFullscreenStrategy strategy;
|
||||
SDL_bool is_fullscreen_desktop = !window->fullscreen_exclusive;
|
||||
int res;
|
||||
|
||||
strategy.scaleMode = is_fullscreen_desktop ? EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH : EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT;
|
||||
|
||||
@@ -314,12 +317,17 @@ static void Emscripten_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *w
|
||||
data->fullscreen_resize = is_fullscreen_desktop;
|
||||
|
||||
res = emscripten_request_fullscreen_strategy(data->canvas_id, 1, &strategy);
|
||||
if (res != EMSCRIPTEN_RESULT_SUCCESS && res != EMSCRIPTEN_RESULT_DEFERRED) {
|
||||
/* unset flags, fullscreen failed */
|
||||
window->flags &= ~SDL_WINDOW_FULLSCREEN;
|
||||
}
|
||||
} else
|
||||
emscripten_exit_fullscreen();
|
||||
} else {
|
||||
res = emscripten_exit_fullscreen();
|
||||
}
|
||||
}
|
||||
|
||||
if (res == EMSCRIPTEN_RESULT_SUCCESS) {
|
||||
return 0;
|
||||
} else if (res == EMSCRIPTEN_RESULT_DEFERRED) {
|
||||
return 1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -92,17 +92,18 @@ void HAIKU_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window * window) {
|
||||
_ToBeWin(window)->PostMessage(&msg);
|
||||
}
|
||||
|
||||
void HAIKU_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window * window) {
|
||||
int HAIKU_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window * window) {
|
||||
BMessage msg(BWIN_MOVE_WINDOW);
|
||||
msg.AddInt32("window-x", window->x);
|
||||
msg.AddInt32("window-y", window->y);
|
||||
msg.AddInt32("window-x", window->floating.x);
|
||||
msg.AddInt32("window-y", window->floating.y);
|
||||
_ToBeWin(window)->PostMessage(&msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HAIKU_SetWindowSize(SDL_VideoDevice *_this, SDL_Window * window) {
|
||||
BMessage msg(BWIN_RESIZE_WINDOW);
|
||||
msg.AddInt32("window-w", window->w - 1);
|
||||
msg.AddInt32("window-h", window->h - 1);
|
||||
msg.AddInt32("window-w", window->floating.w - 1);
|
||||
msg.AddInt32("window-h", window->floating.h - 1);
|
||||
_ToBeWin(window)->PostMessage(&msg);
|
||||
}
|
||||
|
||||
@@ -148,13 +149,13 @@ void HAIKU_RestoreWindow(SDL_VideoDevice *_this, SDL_Window * window) {
|
||||
_ToBeWin(window)->PostMessage(&msg);
|
||||
}
|
||||
|
||||
void HAIKU_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window * window,
|
||||
int HAIKU_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window * window,
|
||||
SDL_VideoDisplay * display, SDL_bool fullscreen) {
|
||||
/* Haiku tracks all video display information */
|
||||
BMessage msg(BWIN_FULLSCREEN);
|
||||
msg.AddBool("fullscreen", fullscreen);
|
||||
_ToBeWin(window)->PostMessage(&msg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ extern void HAIKU_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void HAIKU_RestoreWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void HAIKU_SetWindowBordered(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool bordered);
|
||||
extern void HAIKU_SetWindowResizable(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool resizable);
|
||||
extern void HAIKU_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen);
|
||||
extern int HAIKU_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen);
|
||||
extern void HAIKU_SetWindowMouseGrab(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool grabbed);
|
||||
extern void HAIKU_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
|
||||
|
||||
@@ -1596,13 +1596,13 @@ void KMSDRM_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
KMSDRM_DirtySurfaces(window);
|
||||
}
|
||||
}
|
||||
void KMSDRM_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
|
||||
|
||||
int KMSDRM_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
|
||||
{
|
||||
SDL_VideoData *viddata = _this->driverdata;
|
||||
if (!viddata->vulkan_mode) {
|
||||
KMSDRM_DirtySurfaces(window);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void KMSDRM_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
{
|
||||
|
||||
@@ -125,7 +125,7 @@ int KMSDRM_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_Properti
|
||||
void KMSDRM_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
int KMSDRM_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
void KMSDRM_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
void KMSDRM_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *_display, SDL_bool fullscreen);
|
||||
int KMSDRM_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *_display, SDL_bool fullscreen);
|
||||
void KMSDRM_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
void KMSDRM_HideWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
void KMSDRM_RaiseWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
|
||||
@@ -86,6 +86,7 @@ static SDL_VideoDevice *OFFSCREEN_CreateDevice(void)
|
||||
/* "Window" */
|
||||
device->CreateSDLWindow = OFFSCREEN_CreateWindow;
|
||||
device->DestroyWindow = OFFSCREEN_DestroyWindow;
|
||||
device->SetWindowSize = OFFSCREEN_SetWindowSize;
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#ifdef SDL_VIDEO_DRIVER_OFFSCREEN
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "../../events/SDL_windowevents_c.h"
|
||||
#include "../SDL_egl_c.h"
|
||||
|
||||
#include "SDL_offscreenwindow.h"
|
||||
@@ -82,4 +83,8 @@ void OFFSCREEN_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
window->driverdata = NULL;
|
||||
}
|
||||
|
||||
void OFFSCREEN_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
{
|
||||
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESIZED, window->floating.w, window->floating.h);
|
||||
}
|
||||
#endif /* SDL_VIDEO_DRIVER_OFFSCREEN */
|
||||
|
||||
@@ -35,5 +35,6 @@ struct SDL_WindowData
|
||||
|
||||
extern int OFFSCREEN_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props);
|
||||
extern void OFFSCREEN_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void OFFSCREEN_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
|
||||
#endif /* SDL_offscreenwindow_h */
|
||||
|
||||
@@ -241,12 +241,11 @@ static void setWindowSize(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
window_impl_t *impl = (window_impl_t *)window->driverdata;
|
||||
int size[2];
|
||||
|
||||
size[0] = window->w;
|
||||
size[1] = window->h;
|
||||
size[0] = window->floating.w;
|
||||
size[1] = window->floating.h;
|
||||
|
||||
screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_SIZE, size);
|
||||
screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_SOURCE_SIZE,
|
||||
size);
|
||||
screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_SOURCE_SIZE, size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -32,7 +32,7 @@ extern void UIKit_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void UIKit_HideWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void UIKit_RaiseWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void UIKit_SetWindowBordered(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool bordered);
|
||||
extern void UIKit_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen);
|
||||
extern int UIKit_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen);
|
||||
extern void UIKit_SetWindowMouseGrab(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool grabbed);
|
||||
extern void UIKit_UpdatePointerLock(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void UIKit_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
|
||||
@@ -309,11 +309,12 @@ void UIKit_SetWindowBordered(SDL_VideoDevice *_this, SDL_Window *window, SDL_boo
|
||||
}
|
||||
}
|
||||
|
||||
void UIKit_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
|
||||
int UIKit_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
|
||||
{
|
||||
@autoreleasepool {
|
||||
UIKit_UpdateWindowBorder(_this, window);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void UIKit_SetWindowMouseGrab(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool grabbed)
|
||||
|
||||
@@ -216,6 +216,7 @@ static SDL_VideoDevice *Wayland_CreateDevice(void)
|
||||
device->FlashWindow = Wayland_FlashWindow;
|
||||
device->HasScreenKeyboardSupport = Wayland_HasScreenKeyboardSupport;
|
||||
device->ShowWindowSystemMenu = Wayland_ShowWindowSystemMenu;
|
||||
device->SyncWindow = Wayland_SyncWindow;
|
||||
|
||||
#ifdef SDL_USE_LIBDBUS
|
||||
if (SDL_SystemTheme_Init())
|
||||
@@ -239,9 +240,9 @@ static SDL_VideoDevice *Wayland_CreateDevice(void)
|
||||
|
||||
device->free = Wayland_DeleteDevice;
|
||||
|
||||
device->quirk_flags = VIDEO_DEVICE_QUIRK_MODE_SWITCHING_EMULATED |
|
||||
VIDEO_DEVICE_QUIRK_DISABLE_UNSET_FULLSCREEN_ON_MINIMIZE |
|
||||
VIDEO_DEVICE_QUIRK_HAS_POPUP_WINDOW_SUPPORT;
|
||||
device->device_caps = VIDEO_DEVICE_CAPS_MODE_SWITCHING_EMULATED |
|
||||
VIDEO_DEVICE_CAPS_HAS_POPUP_WINDOW_SUPPORT |
|
||||
VIDEO_DEVICE_CAPS_SENDS_FULLSCREEN_DIMENSIONS;
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -95,9 +95,6 @@ struct SDL_WindowData
|
||||
struct wp_viewport *draw_viewport;
|
||||
struct wp_fractional_scale_v1 *fractional_scale;
|
||||
|
||||
/* floating dimensions for restoring from maximized and fullscreen */
|
||||
int floating_width, floating_height;
|
||||
|
||||
SDL_AtomicInt swap_interval_ready;
|
||||
|
||||
SDL_DisplayData **outputs;
|
||||
@@ -109,18 +106,27 @@ struct SDL_WindowData
|
||||
float windowed_scale_factor;
|
||||
float pointer_scale_x;
|
||||
float pointer_scale_y;
|
||||
|
||||
struct
|
||||
{
|
||||
int width, height;
|
||||
} pending_size_event;
|
||||
|
||||
int last_configure_width, last_configure_height;
|
||||
int requested_window_width, requested_window_height;
|
||||
int drawable_width, drawable_height;
|
||||
int wl_window_width, wl_window_height;
|
||||
int system_min_required_width;
|
||||
int system_min_required_height;
|
||||
SDL_DisplayID last_displayID;
|
||||
SDL_bool floating;
|
||||
SDL_bool suspended;
|
||||
SDL_bool active;
|
||||
SDL_bool is_fullscreen;
|
||||
SDL_bool in_fullscreen_transition;
|
||||
SDL_bool fullscreen_was_positioned;
|
||||
int fullscreen_deadline_count;
|
||||
SDL_bool floating : 1;
|
||||
SDL_bool suspended : 1;
|
||||
SDL_bool active : 1;
|
||||
SDL_bool is_fullscreen : 1;
|
||||
SDL_bool drop_fullscreen_requests : 1;
|
||||
SDL_bool fullscreen_was_positioned : 1;
|
||||
SDL_bool show_hide_sync_required : 1;
|
||||
|
||||
SDL_HitTestResult hit_test_result;
|
||||
};
|
||||
@@ -128,7 +134,7 @@ struct SDL_WindowData
|
||||
extern void Wayland_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void Wayland_HideWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void Wayland_RaiseWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void Wayland_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window,
|
||||
extern int Wayland_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window,
|
||||
SDL_VideoDisplay *_display,
|
||||
SDL_bool fullscreen);
|
||||
extern void Wayland_MaximizeWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
@@ -153,5 +159,6 @@ extern int Wayland_SuspendScreenSaver(SDL_VideoDevice *_this);
|
||||
|
||||
extern int Wayland_SetWindowHitTest(SDL_Window *window, SDL_bool enabled);
|
||||
extern int Wayland_FlashWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_FlashOperation operation);
|
||||
extern int Wayland_SyncWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
|
||||
#endif /* SDL_waylandwindow_h_ */
|
||||
|
||||
@@ -1009,11 +1009,38 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
#endif /* WM_GETMINMAXINFO */
|
||||
|
||||
case WM_WINDOWPOSCHANGING:
|
||||
{
|
||||
WINDOWPOS *windowpos = (WINDOWPOS*)lParam;
|
||||
|
||||
if (data->expected_resize) {
|
||||
returnCode = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
if (IsIconic(hwnd)) {
|
||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_MINIMIZED, 0, 0);
|
||||
} else if (IsZoomed(hwnd)) {
|
||||
if (data->window->flags & SDL_WINDOW_MINIMIZED) {
|
||||
/* If going from minimized to maximized, send the restored event first. */
|
||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_RESTORED, 0, 0);
|
||||
}
|
||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_MAXIMIZED, 0, 0);
|
||||
} else {
|
||||
SDL_bool was_fixed_size = !!(data->window->flags & (SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED));
|
||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_RESTORED, 0, 0);
|
||||
|
||||
/* Send the stored floating size if moving from a fixed-size to floating state. */
|
||||
if (was_fixed_size && !(data->window->flags & SDL_WINDOW_FULLSCREEN)) {
|
||||
int fx, fy, fw, fh;
|
||||
|
||||
WIN_AdjustWindowRect(data->window, &fx, &fy, &fw, &fh, SDL_WINDOWRECT_FLOATING);
|
||||
windowpos->x = fx;
|
||||
windowpos->y = fy;
|
||||
windowpos->cx = fw;
|
||||
windowpos->cy = fh;
|
||||
windowpos->flags &= ~(SWP_NOSIZE | SWP_NOMOVE);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case WM_WINDOWPOSCHANGED:
|
||||
{
|
||||
@@ -1082,7 +1109,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
for (win = data->window->first_child; win; win = win->next_sibling) {
|
||||
/* Don't update hidden child windows, their relative position doesn't change */
|
||||
if (!(win->flags & SDL_WINDOW_HIDDEN)) {
|
||||
WIN_SetWindowPositionInternal(win, SWP_NOCOPYBITS | SWP_NOACTIVATE);
|
||||
WIN_SetWindowPositionInternal(win, SWP_NOCOPYBITS | SWP_NOACTIVATE, SDL_WINDOWRECT_CURRENT);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
@@ -1112,28 +1139,6 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
KillTimer(hwnd, (UINT_PTR)SDL_IterateMainCallbacks);
|
||||
} break;
|
||||
|
||||
case WM_SIZE:
|
||||
{
|
||||
switch (wParam) {
|
||||
case SIZE_MAXIMIZED:
|
||||
SDL_SendWindowEvent(data->window,
|
||||
SDL_EVENT_WINDOW_RESTORED, 0, 0);
|
||||
SDL_SendWindowEvent(data->window,
|
||||
SDL_EVENT_WINDOW_MAXIMIZED, 0, 0);
|
||||
break;
|
||||
case SIZE_MINIMIZED:
|
||||
SDL_SendWindowEvent(data->window,
|
||||
SDL_EVENT_WINDOW_MINIMIZED, 0, 0);
|
||||
break;
|
||||
case SIZE_RESTORED:
|
||||
SDL_SendWindowEvent(data->window,
|
||||
SDL_EVENT_WINDOW_RESTORED, 0, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
|
||||
case WM_SETCURSOR:
|
||||
{
|
||||
Uint16 hittest;
|
||||
|
||||
@@ -277,7 +277,8 @@ static SDL_VideoDevice *WIN_CreateDevice(void)
|
||||
|
||||
device->free = WIN_DeleteDevice;
|
||||
|
||||
device->quirk_flags = VIDEO_DEVICE_QUIRK_HAS_POPUP_WINDOW_SUPPORT;
|
||||
device->device_caps = VIDEO_DEVICE_CAPS_HAS_POPUP_WINDOW_SUPPORT |
|
||||
VIDEO_DEVICE_CAPS_SENDS_FULLSCREEN_DIMENSIONS;
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ static DWORD GetWindowStyleEx(SDL_Window *window)
|
||||
* Returns arguments to pass to SetWindowPos - the window rect, including frame, in Windows coordinates.
|
||||
* Can be called before we have a HWND.
|
||||
*/
|
||||
static int WIN_AdjustWindowRectWithStyle(SDL_Window *window, DWORD style, BOOL menu, int *x, int *y, int *width, int *height, SDL_bool use_current)
|
||||
static int WIN_AdjustWindowRectWithStyle(SDL_Window *window, DWORD style, BOOL menu, int *x, int *y, int *width, int *height, SDL_WindowRect rect_type)
|
||||
{
|
||||
SDL_VideoData *videodata = SDL_GetVideoDevice() ? SDL_GetVideoDevice()->driverdata : NULL;
|
||||
RECT rect;
|
||||
@@ -163,12 +163,26 @@ static int WIN_AdjustWindowRectWithStyle(SDL_Window *window, DWORD style, BOOL m
|
||||
#endif
|
||||
|
||||
/* Client rect, in points */
|
||||
SDL_RelativeToGlobalForWindow(window,
|
||||
(use_current ? window->x : window->windowed.x),
|
||||
(use_current ? window->y : window->windowed.y),
|
||||
x, y);
|
||||
*width = (use_current ? window->w : window->windowed.w);
|
||||
*height = (use_current ? window->h : window->windowed.h);
|
||||
switch (rect_type) {
|
||||
case SDL_WINDOWRECT_CURRENT:
|
||||
SDL_RelativeToGlobalForWindow(window,window->x, window->y, x, y);
|
||||
*width = window->w;
|
||||
*height = window->h;
|
||||
break;
|
||||
case SDL_WINDOWRECT_WINDOWED:
|
||||
SDL_RelativeToGlobalForWindow(window,window->windowed.x, window->windowed.y, x, y);
|
||||
*width = window->windowed.w;
|
||||
*height = window->windowed.h;
|
||||
break;
|
||||
case SDL_WINDOWRECT_FLOATING:
|
||||
SDL_RelativeToGlobalForWindow(window,window->floating.x, window->floating.y, x, y);
|
||||
*width = window->floating.w;
|
||||
*height = window->floating.h;
|
||||
break;
|
||||
default:
|
||||
/* Should never be here */
|
||||
SDL_assert_release(SDL_FALSE);
|
||||
}
|
||||
|
||||
/* Copy the client size in pixels into this rect structure,
|
||||
which we'll then adjust with AdjustWindowRectEx */
|
||||
@@ -210,16 +224,16 @@ static int WIN_AdjustWindowRectWithStyle(SDL_Window *window, DWORD style, BOOL m
|
||||
|
||||
#ifdef HIGHDPI_DEBUG
|
||||
SDL_Log("WIN_AdjustWindowRectWithStyle: in: %d, %d, %dx%d, returning: %d, %d, %dx%d, used dpi %d for frame calculation",
|
||||
(use_current ? window->x : window->windowed.x),
|
||||
(use_current ? window->y : window->windowed.y),
|
||||
(use_current ? window->w : window->windowed.w),
|
||||
(use_current ? window->h : window->windowed.h),
|
||||
(use_current ? window->requested.x : window->windowed.x),
|
||||
(use_current ? window->requested.y : window->windowed.y),
|
||||
(use_current ? window->requested.w : window->windowed.w),
|
||||
(use_current ? window->requested.h : window->windowed.h),
|
||||
*x, *y, *width, *height, frame_dpi);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void WIN_AdjustWindowRect(SDL_Window *window, int *x, int *y, int *width, int *height, SDL_bool use_current)
|
||||
void WIN_AdjustWindowRect(SDL_Window *window, int *x, int *y, int *width, int *height, SDL_WindowRect rect_type)
|
||||
{
|
||||
SDL_WindowData *data = window->driverdata;
|
||||
HWND hwnd = data->hwnd;
|
||||
@@ -232,10 +246,10 @@ static void WIN_AdjustWindowRect(SDL_Window *window, int *x, int *y, int *width,
|
||||
#else
|
||||
menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL);
|
||||
#endif
|
||||
WIN_AdjustWindowRectWithStyle(window, style, menu, x, y, width, height, use_current);
|
||||
WIN_AdjustWindowRectWithStyle(window, style, menu, x, y, width, height, rect_type);
|
||||
}
|
||||
|
||||
int WIN_SetWindowPositionInternal(SDL_Window *window, UINT flags)
|
||||
int WIN_SetWindowPositionInternal(SDL_Window *window, UINT flags, SDL_WindowRect rect_type)
|
||||
{
|
||||
SDL_Window *child_window;
|
||||
SDL_WindowData *data = window->driverdata;
|
||||
@@ -252,7 +266,7 @@ int WIN_SetWindowPositionInternal(SDL_Window *window, UINT flags)
|
||||
top = HWND_NOTOPMOST;
|
||||
}
|
||||
|
||||
WIN_AdjustWindowRect(window, &x, &y, &w, &h, SDL_TRUE);
|
||||
WIN_AdjustWindowRect(window, &x, &y, &w, &h, rect_type);
|
||||
|
||||
data->expected_resize = SDL_TRUE;
|
||||
if (SetWindowPos(hwnd, top, x, y, w, h, flags) == 0) {
|
||||
@@ -262,7 +276,7 @@ int WIN_SetWindowPositionInternal(SDL_Window *window, UINT flags)
|
||||
|
||||
/* Update any child windows */
|
||||
for (child_window = window->first_child; child_window; child_window = child_window->next_sibling) {
|
||||
if (WIN_SetWindowPositionInternal(child_window, flags) < 0) {
|
||||
if (WIN_SetWindowPositionInternal(child_window, flags, SDL_WINDOWRECT_CURRENT) < 0) {
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
@@ -353,7 +367,7 @@ static int SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, HWND hwnd
|
||||
/* We tried to create a window larger than the desktop and Windows didn't allow it. Override! */
|
||||
int x, y;
|
||||
/* Figure out what the window area will be */
|
||||
WIN_AdjustWindowRect(window, &x, &y, &w, &h, SDL_FALSE);
|
||||
WIN_AdjustWindowRect(window, &x, &y, &w, &h, SDL_WINDOWRECT_FLOATING);
|
||||
data->expected_resize = SDL_TRUE;
|
||||
SetWindowPos(hwnd, NULL, x, y, w, h, data->copybits_flag | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE);
|
||||
data->expected_resize = SDL_FALSE;
|
||||
@@ -518,8 +532,8 @@ static void WIN_ConstrainPopup(SDL_Window *window)
|
||||
SDL_Window *w;
|
||||
SDL_DisplayID displayID;
|
||||
SDL_Rect rect;
|
||||
int abs_x = window->x;
|
||||
int abs_y = window->y;
|
||||
int abs_x = window->floating.x;
|
||||
int abs_y = window->floating.y;
|
||||
int offset_x = 0, offset_y = 0;
|
||||
|
||||
/* Calculate the total offset from the parents */
|
||||
@@ -536,17 +550,17 @@ static void WIN_ConstrainPopup(SDL_Window *window)
|
||||
/* Constrain the popup window to the display of the toplevel parent */
|
||||
displayID = SDL_GetDisplayForWindow(w);
|
||||
SDL_GetDisplayBounds(displayID, &rect);
|
||||
if (abs_x + window->w > rect.x + rect.w) {
|
||||
abs_x -= (abs_x + window->w) - (rect.x + rect.w);
|
||||
if (abs_x + window->floating.w > rect.x + rect.w) {
|
||||
abs_x -= (abs_x + window->floating.w) - (rect.x + rect.w);
|
||||
}
|
||||
if (abs_y + window->h > rect.y + rect.h) {
|
||||
abs_y -= (abs_y + window->h) - (rect.y + rect.h);
|
||||
if (abs_y + window->floating.h > rect.y + rect.h) {
|
||||
abs_y -= (abs_y + window->floating.h) - (rect.y + rect.h);
|
||||
}
|
||||
abs_x = SDL_max(abs_x, rect.x);
|
||||
abs_y = SDL_max(abs_y, rect.y);
|
||||
|
||||
window->x = window->windowed.x = abs_x - offset_x;
|
||||
window->y = window->windowed.y = abs_y - offset_y;
|
||||
window->floating.x = abs_x - offset_x;
|
||||
window->floating.y = abs_y - offset_y;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -590,7 +604,7 @@ int WIN_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesI
|
||||
|
||||
/* Figure out what the window area will be */
|
||||
WIN_ConstrainPopup(window);
|
||||
WIN_AdjustWindowRectWithStyle(window, style, FALSE, &x, &y, &w, &h, SDL_FALSE);
|
||||
WIN_AdjustWindowRectWithStyle(window, style, FALSE, &x, &y, &w, &h, SDL_WINDOWRECT_FLOATING);
|
||||
|
||||
hwnd = CreateWindowEx(styleEx, SDL_Appname, TEXT(""), style,
|
||||
x, y, w, h, parent, NULL, SDL_Instance, NULL);
|
||||
@@ -774,13 +788,25 @@ int WIN_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
/* HighDPI support: removed SWP_NOSIZE. If the move results in a DPI change, we need to allow
|
||||
* the window to resize (e.g. AdjustWindowRectExForDpi frame sizes are different).
|
||||
*/
|
||||
WIN_ConstrainPopup(window);
|
||||
return WIN_SetWindowPositionInternal(window, window->driverdata->copybits_flag | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE);
|
||||
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
|
||||
if (!(window->flags & (SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED))) {
|
||||
WIN_ConstrainPopup(window);
|
||||
return WIN_SetWindowPositionInternal(window,
|
||||
window->driverdata->copybits_flag | SWP_NOZORDER | SWP_NOOWNERZORDER |
|
||||
SWP_NOACTIVATE, SDL_WINDOWRECT_FLOATING);
|
||||
}
|
||||
} else {
|
||||
return SDL_UpdateFullscreenMode(window, SDL_TRUE, SDL_TRUE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WIN_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
{
|
||||
WIN_SetWindowPositionInternal(window, window->driverdata->copybits_flag | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE);
|
||||
if (!(window->flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_MAXIMIZED))) {
|
||||
WIN_SetWindowPositionInternal(window, window->driverdata->copybits_flag | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE, SDL_WINDOWRECT_FLOATING);
|
||||
}
|
||||
}
|
||||
|
||||
int WIN_GetWindowBordersSize(SDL_VideoDevice *_this, SDL_Window *window, int *top, int *left, int *bottom, int *right)
|
||||
@@ -967,14 +993,24 @@ void WIN_RaiseWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
|
||||
void WIN_MaximizeWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
{
|
||||
/* Other platforms refuse to maximize a non-resizable window, and with win32,
|
||||
the OS resizes the window weirdly (covering the taskbar) if you don't have
|
||||
the STYLE_RESIZABLE flag set. So just forbid it for now. */
|
||||
if (window->flags & SDL_WINDOW_RESIZABLE) {
|
||||
SDL_WindowData *data = window->driverdata;
|
||||
HWND hwnd = data->hwnd;
|
||||
SDL_WindowData *data = window->driverdata;
|
||||
HWND hwnd = data->hwnd;
|
||||
data->expected_resize = SDL_TRUE;
|
||||
ShowWindow(hwnd, SW_MAXIMIZE);
|
||||
data->expected_resize = SDL_FALSE;
|
||||
|
||||
/* Clamp the maximized window size to the max window size.
|
||||
* This is automatic if maximizing from the window controls.
|
||||
*/
|
||||
if (window->max_w || window->max_h) {
|
||||
int fx, fy, fw, fh;
|
||||
|
||||
window->windowed.w = window->max_w ? SDL_min(window->w, window->max_w) : window->windowed.w;
|
||||
window->windowed.h = window->max_h ? SDL_min(window->h, window->max_h) : window->windowed.h;
|
||||
WIN_AdjustWindowRect(window, &fx, &fy, &fw, &fh, SDL_WINDOWRECT_WINDOWED);
|
||||
|
||||
data->expected_resize = SDL_TRUE;
|
||||
ShowWindow(hwnd, SW_MAXIMIZE);
|
||||
SetWindowPos(hwnd, HWND_TOP, fx, fy, fw, fh, data->copybits_flag | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOACTIVATE);
|
||||
data->expected_resize = SDL_FALSE;
|
||||
}
|
||||
}
|
||||
@@ -997,7 +1033,7 @@ void WIN_SetWindowBordered(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool
|
||||
|
||||
data->in_border_change = SDL_TRUE;
|
||||
SetWindowLong(hwnd, GWL_STYLE, style);
|
||||
WIN_SetWindowPositionInternal(window, data->copybits_flag | SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE);
|
||||
WIN_SetWindowPositionInternal(window, data->copybits_flag | SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE, SDL_WINDOWRECT_CURRENT);
|
||||
data->in_border_change = SDL_FALSE;
|
||||
}
|
||||
|
||||
@@ -1016,7 +1052,7 @@ void WIN_SetWindowResizable(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool
|
||||
|
||||
void WIN_SetWindowAlwaysOnTop(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool on_top)
|
||||
{
|
||||
WIN_SetWindowPositionInternal(window, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||
WIN_SetWindowPositionInternal(window, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE, SDL_WINDOWRECT_CURRENT);
|
||||
}
|
||||
|
||||
void WIN_RestoreWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
@@ -1031,7 +1067,7 @@ void WIN_RestoreWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
/**
|
||||
* Reconfigures the window to fill the given display, if fullscreen is true, otherwise restores the window.
|
||||
*/
|
||||
void WIN_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
|
||||
int WIN_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
|
||||
{
|
||||
#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
|
||||
SDL_DisplayData *displaydata = display->driverdata;
|
||||
@@ -1043,13 +1079,6 @@ void WIN_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_Vid
|
||||
int x, y;
|
||||
int w, h;
|
||||
|
||||
if (!fullscreen && (window->flags & SDL_WINDOW_FULLSCREEN)) {
|
||||
/* Resizing the window on hide causes problems restoring it in Wine, and it's unnecessary.
|
||||
* Also, Windows would preview the minimized window with the wrong size.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef HIGHDPI_DEBUG
|
||||
SDL_Log("WIN_SetWindowFullscreen: %d", (int)fullscreen);
|
||||
#endif
|
||||
@@ -1060,19 +1089,20 @@ void WIN_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_Vid
|
||||
top = HWND_NOTOPMOST;
|
||||
}
|
||||
|
||||
style = GetWindowLong(hwnd, GWL_STYLE);
|
||||
style &= ~STYLE_MASK;
|
||||
style |= GetWindowStyle(window);
|
||||
|
||||
/* Use GetMonitorInfo instead of WIN_GetDisplayBounds because we want the
|
||||
monitor bounds in Windows coordinates (pixels) rather than SDL coordinates (points). */
|
||||
SDL_zero(minfo);
|
||||
minfo.cbSize = sizeof(MONITORINFO);
|
||||
if (!GetMonitorInfo(displaydata->MonitorHandle, &minfo)) {
|
||||
SDL_SetError("GetMonitorInfo failed");
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_SendWindowEvent(window, fullscreen ? SDL_EVENT_WINDOW_ENTER_FULLSCREEN : SDL_EVENT_WINDOW_LEAVE_FULLSCREEN, 0, 0);
|
||||
style = GetWindowLong(hwnd, GWL_STYLE);
|
||||
style &= ~STYLE_MASK;
|
||||
style |= GetWindowStyle(window);
|
||||
|
||||
if (fullscreen) {
|
||||
x = minfo.rcMonitor.left;
|
||||
y = minfo.rcMonitor.top;
|
||||
@@ -1097,11 +1127,14 @@ void WIN_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_Vid
|
||||
*/
|
||||
if (data->windowed_mode_was_maximized && !data->in_window_deactivation) {
|
||||
style |= WS_MAXIMIZE;
|
||||
data->windowed_mode_was_maximized = SDL_FALSE;
|
||||
}
|
||||
|
||||
menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL);
|
||||
WIN_AdjustWindowRectWithStyle(window, style, menu, &x, &y, &w, &h, SDL_FALSE);
|
||||
WIN_AdjustWindowRectWithStyle(window, style, menu,
|
||||
&x, &y,
|
||||
&w, &h,
|
||||
data->windowed_mode_was_maximized ? SDL_WINDOWRECT_WINDOWED : SDL_WINDOWRECT_FLOATING);
|
||||
data->windowed_mode_was_maximized = SDL_FALSE;
|
||||
}
|
||||
SetWindowLong(hwnd, GWL_STYLE, style);
|
||||
data->expected_resize = SDL_TRUE;
|
||||
@@ -1113,6 +1146,7 @@ void WIN_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_Vid
|
||||
#endif
|
||||
|
||||
#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
|
||||
@@ -1307,7 +1341,7 @@ void WIN_OnWindowEnter(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
}
|
||||
|
||||
if (window->flags & SDL_WINDOW_ALWAYS_ON_TOP) {
|
||||
WIN_SetWindowPositionInternal(window, data->copybits_flag | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||
WIN_SetWindowPositionInternal(window, data->copybits_flag | SWP_NOSIZE | SWP_NOACTIVATE, SDL_WINDOWRECT_CURRENT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,13 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum SDL_WindowRect
|
||||
{
|
||||
SDL_WINDOWRECT_CURRENT,
|
||||
SDL_WINDOWRECT_WINDOWED,
|
||||
SDL_WINDOWRECT_FLOATING
|
||||
} SDL_WindowRect;
|
||||
|
||||
struct SDL_WindowData
|
||||
{
|
||||
SDL_Window *window;
|
||||
@@ -91,7 +98,7 @@ extern void WIN_RestoreWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void WIN_SetWindowBordered(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool bordered);
|
||||
extern void WIN_SetWindowResizable(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool resizable);
|
||||
extern void WIN_SetWindowAlwaysOnTop(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool on_top);
|
||||
extern void WIN_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen);
|
||||
extern int WIN_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen);
|
||||
extern void WIN_UpdateWindowICCProfile(SDL_Window *window, SDL_bool send_event);
|
||||
extern void *WIN_GetWindowICCProfile(SDL_VideoDevice *_this, SDL_Window *window, size_t *size);
|
||||
extern void WIN_SetWindowMouseRect(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
@@ -104,9 +111,10 @@ extern int WIN_SetWindowHitTest(SDL_Window *window, SDL_bool enabled);
|
||||
extern void WIN_AcceptDragAndDrop(SDL_Window *window, SDL_bool accept);
|
||||
extern int WIN_FlashWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_FlashOperation operation);
|
||||
extern void WIN_UpdateDarkModeForHWND(HWND hwnd);
|
||||
extern int WIN_SetWindowPositionInternal(SDL_Window *window, UINT flags);
|
||||
extern int WIN_SetWindowPositionInternal(SDL_Window *window, UINT flags, SDL_WindowRect rect_type);
|
||||
extern void WIN_ShowWindowSystemMenu(SDL_Window *window, int x, int y);
|
||||
extern int WIN_SetWindowFocusable(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool focusable);
|
||||
extern void WIN_AdjustWindowRect(SDL_Window *window, int *x, int *y, int *width, int *height, SDL_WindowRect rect_type);
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -76,7 +76,7 @@ static void WINRT_VideoQuit(SDL_VideoDevice *_this);
|
||||
/* Window functions */
|
||||
static int WINRT_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props);
|
||||
static void WINRT_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
static void WINRT_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen);
|
||||
static int WINRT_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen);
|
||||
static void WINRT_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
|
||||
/* Misc functions */
|
||||
@@ -734,12 +734,14 @@ void WINRT_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
{
|
||||
#if NTDDI_VERSION >= NTDDI_WIN10
|
||||
SDL_WindowData *data = window->driverdata;
|
||||
const Windows::Foundation::Size size((float)window->w, (float)window->h);
|
||||
data->appView->TryResizeView(size); // TODO, WinRT: return failure (to caller?) from TryResizeView()
|
||||
const Windows::Foundation::Size size((float)window->floating.w, (float)window->floating.h);
|
||||
if (data->appView->TryResizeView(size)) {
|
||||
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESIZED, window->floating.w, window->floating.h);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void WINRT_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
|
||||
int WINRT_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
|
||||
{
|
||||
#if NTDDI_VERSION >= NTDDI_WIN10
|
||||
SDL_WindowData *data = window->driverdata;
|
||||
@@ -747,7 +749,7 @@ void WINRT_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_V
|
||||
if (isWindowActive) {
|
||||
if (fullscreen) {
|
||||
if (!data->appView->IsFullScreenMode) {
|
||||
data->appView->TryEnterFullScreenMode(); // TODO, WinRT: return failure (to caller?) from TryEnterFullScreenMode()
|
||||
return data->appView->TryEnterFullScreenMode() ? 0 : -1;
|
||||
}
|
||||
} else {
|
||||
if (data->appView->IsFullScreenMode) {
|
||||
@@ -756,6 +758,8 @@ void WINRT_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_V
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WINRT_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "../../events/SDL_touch_c.h"
|
||||
#include "../../core/linux/SDL_system_theme.h"
|
||||
#include "../../SDL_utils_c.h"
|
||||
#include "../SDL_sysvideo.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1330,8 +1331,7 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
|
||||
int y = xevent->xconfigure.y;
|
||||
|
||||
SDL_GlobalToRelativeForWindow(data->window, x, y, &x, &y);
|
||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_MOVED,
|
||||
x, y);
|
||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_MOVED, x, y);
|
||||
|
||||
#ifdef SDL_USE_IME
|
||||
if (SDL_EventEnabled(SDL_EVENT_TEXT_INPUT)) {
|
||||
@@ -1342,16 +1342,21 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
|
||||
for (w = data->window->first_child; w; w = w->next_sibling) {
|
||||
/* Don't update hidden child windows, their relative position doesn't change */
|
||||
if (!(w->flags & SDL_WINDOW_HIDDEN)) {
|
||||
X11_UpdateWindowPosition(w);
|
||||
X11_UpdateWindowPosition(w, SDL_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (xevent->xconfigure.width != data->last_xconfigure.width ||
|
||||
xevent->xconfigure.height != data->last_xconfigure.height) {
|
||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_RESIZED,
|
||||
xevent->xconfigure.width,
|
||||
xevent->xconfigure.height);
|
||||
if (!data->skip_size_count) {
|
||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_RESIZED,
|
||||
xevent->xconfigure.width,
|
||||
xevent->xconfigure.height);
|
||||
} else {
|
||||
data->skip_size_count--;
|
||||
}
|
||||
}
|
||||
|
||||
data->last_xconfigure = xevent->xconfigure;
|
||||
} break;
|
||||
|
||||
@@ -1621,17 +1626,60 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
|
||||
}
|
||||
}
|
||||
|
||||
if ((changed & SDL_WINDOW_MAXIMIZED) && ((flags & SDL_WINDOW_MAXIMIZED) && !(flags & SDL_WINDOW_MINIMIZED))) {
|
||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_MAXIMIZED, 0, 0);
|
||||
}
|
||||
if ((changed & SDL_WINDOW_MINIMIZED) && (flags & SDL_WINDOW_MINIMIZED)) {
|
||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_MINIMIZED, 0, 0);
|
||||
}
|
||||
if (((changed & SDL_WINDOW_MAXIMIZED) || (changed & SDL_WINDOW_MINIMIZED)) &&
|
||||
(!(flags & SDL_WINDOW_MAXIMIZED) && !(flags & SDL_WINDOW_MINIMIZED))) {
|
||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_RESTORED, 0, 0);
|
||||
}
|
||||
if (!SDL_WINDOW_IS_POPUP(data->window)) {
|
||||
if (changed & SDL_WINDOW_FULLSCREEN) {
|
||||
data->pending_operation &= ~X11_PENDING_OP_FULLSCREEN;
|
||||
|
||||
if (flags & SDL_WINDOW_FULLSCREEN) {
|
||||
if (!(flags & SDL_WINDOW_MINIMIZED)) {
|
||||
const SDL_bool commit = data->requested_fullscreen_mode.displayID == 0 ||
|
||||
SDL_memcmp(&data->window->current_fullscreen_mode, &data->requested_fullscreen_mode, sizeof(SDL_DisplayMode)) != 0;
|
||||
|
||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_ENTER_FULLSCREEN, 0, 0);
|
||||
if (commit) {
|
||||
/* This was initiated by the compositor, or the mode was changed between the request and the window
|
||||
* becoming fullscreen. Switch to the application requested mode if necessary.
|
||||
*/
|
||||
SDL_copyp(&data->window->current_fullscreen_mode, &data->window->requested_fullscreen_mode);
|
||||
SDL_UpdateFullscreenMode(data->window, SDL_TRUE, SDL_TRUE);
|
||||
} else {
|
||||
SDL_UpdateFullscreenMode(data->window, SDL_TRUE, SDL_FALSE);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_LEAVE_FULLSCREEN, 0, 0);
|
||||
SDL_UpdateFullscreenMode(data->window, SDL_FALSE, SDL_TRUE);
|
||||
}
|
||||
|
||||
if (!(data->window->flags & SDL_WINDOW_BORDERLESS)) {
|
||||
/* Skip the first resize event if the borders are being turned on/off. */
|
||||
data->skip_size_count = 1;
|
||||
}
|
||||
}
|
||||
if ((changed & SDL_WINDOW_MAXIMIZED) && ((flags & SDL_WINDOW_MAXIMIZED) && !(flags & SDL_WINDOW_MINIMIZED))) {
|
||||
data->pending_operation &= ~X11_PENDING_OP_MAXIMIZE;
|
||||
if ((changed & SDL_WINDOW_MINIMIZED)) {
|
||||
data->pending_operation &= ~X11_PENDING_OP_RESTORE;
|
||||
/* If coming out of minimized, send a restore event before sending maximized. */
|
||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_RESTORED, 0, 0);
|
||||
}
|
||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_MAXIMIZED, 0, 0);
|
||||
}
|
||||
if ((changed & SDL_WINDOW_MINIMIZED) && (flags & SDL_WINDOW_MINIMIZED)) {
|
||||
data->pending_operation &= ~X11_PENDING_OP_MINIMIZE;
|
||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_MINIMIZED, 0, 0);
|
||||
}
|
||||
if (!(flags & (SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED))) {
|
||||
data->pending_operation &= ~X11_PENDING_OP_RESTORE;
|
||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_RESTORED, 0, 0);
|
||||
|
||||
/* Restore the last known floating state if leaving maximized mode */
|
||||
if (!(flags & SDL_WINDOW_FULLSCREEN)) {
|
||||
X11_XMoveWindow(display, data->xwindow, data->window->floating.x, data->window->floating.y);
|
||||
X11_XResizeWindow(display, data->xwindow, data->window->floating.w, data->window->floating.h);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changed & SDL_WINDOW_OCCLUDED) {
|
||||
SDL_SendWindowEvent(data->window, (flags & SDL_WINDOW_OCCLUDED) ? SDL_EVENT_WINDOW_OCCLUDED : SDL_EVENT_WINDOW_EXPOSED, 0, 0);
|
||||
}
|
||||
@@ -1645,6 +1693,14 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
|
||||
X11_UpdateKeymap(_this, SDL_TRUE);
|
||||
} else if (xevent->xproperty.atom == videodata->_NET_FRAME_EXTENTS) {
|
||||
X11_GetBorderValues(data);
|
||||
if (data->border_top != 0 || data->border_left != 0 || data->border_right != 0 || data->border_bottom != 0) {
|
||||
/* Adjust if the window size changed to accommodate the borders. */
|
||||
if (data->window->flags & SDL_WINDOW_MAXIMIZED) {
|
||||
X11_XResizeWindow(display, data->xwindow, data->window->windowed.w, data->window->windowed.h);
|
||||
} else {
|
||||
X11_XResizeWindow(display, data->xwindow, data->window->floating.w, data->window->floating.h);
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
@@ -1824,6 +1880,22 @@ void X11_PumpEvents(SDL_VideoDevice *_this)
|
||||
XEvent xevent;
|
||||
int i;
|
||||
|
||||
/* Check if a display had the mode changed and is waiting for a window to asynchronously become
|
||||
* fullscreen. If there is no fullscreen window past the elapsed timeout, revert the mode switch.
|
||||
*/
|
||||
for (i = 0; i < _this->num_displays; ++i) {
|
||||
if (_this->displays[i]->driverdata->mode_switch_deadline_ns &&
|
||||
SDL_GetTicksNS() >= _this->displays[i]->driverdata->mode_switch_deadline_ns) {
|
||||
if (_this->displays[i]->fullscreen_window) {
|
||||
_this->displays[i]->driverdata->mode_switch_deadline_ns = 0;
|
||||
} else {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_VIDEO,
|
||||
"Time out elapsed after mode switch on display %" SDL_PRIu32 " with no window becoming fullscreen; reverting", _this->displays[i]->id);
|
||||
SDL_SetDisplayModeForDisplay(_this->displays[i], NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data->last_mode_change_deadline) {
|
||||
if (SDL_GetTicks() >= data->last_mode_change_deadline) {
|
||||
data->last_mode_change_deadline = 0; /* assume we're done. */
|
||||
|
||||
@@ -27,6 +27,11 @@
|
||||
|
||||
/* #define X11MODES_DEBUG */
|
||||
|
||||
/* Timeout and revert mode switches if the timespan has elapsed without the window becoming fullscreen.
|
||||
* 5 seconds seems good from testing.
|
||||
*/
|
||||
#define MODE_SWITCH_TIMEOUT_NS SDL_NS_PER_SECOND * 5
|
||||
|
||||
/* I'm becoming more and more convinced that the application should never
|
||||
* use XRandR, and it's the window manager's responsibility to track and
|
||||
* manage display modes for fullscreen windows. Right now XRandR is completely
|
||||
@@ -903,6 +908,12 @@ int X11_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *sdl_display, SD
|
||||
|
||||
viddata->last_mode_change_deadline = SDL_GetTicks() + (PENDING_FOCUS_TIME * 2);
|
||||
|
||||
if (mode != &sdl_display->desktop_mode) {
|
||||
data->mode_switch_deadline_ns = SDL_GetTicksNS() + MODE_SWITCH_TIMEOUT_NS;
|
||||
} else {
|
||||
data->mode_switch_deadline_ns = 0;
|
||||
}
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_X11_XRANDR
|
||||
if (data->use_xrandr) {
|
||||
Display *display = viddata->display;
|
||||
|
||||
@@ -32,6 +32,8 @@ struct SDL_DisplayData
|
||||
int x;
|
||||
int y;
|
||||
|
||||
Uint64 mode_switch_deadline_ns;
|
||||
|
||||
SDL_bool use_xrandr;
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_X11_XRANDR
|
||||
|
||||
@@ -209,6 +209,7 @@ static SDL_VideoDevice *X11_CreateDevice(void)
|
||||
device->FlashWindow = X11_FlashWindow;
|
||||
device->ShowWindowSystemMenu = X11_ShowWindowSystemMenu;
|
||||
device->SetWindowFocusable = X11_SetWindowFocusable;
|
||||
device->SyncWindow = X11_SyncWindow;
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_X11_XFIXES
|
||||
device->SetWindowMouseRect = X11_SetWindowMouseRect;
|
||||
@@ -274,7 +275,8 @@ static SDL_VideoDevice *X11_CreateDevice(void)
|
||||
device->system_theme = SDL_SystemTheme_Get();
|
||||
#endif
|
||||
|
||||
device->quirk_flags = VIDEO_DEVICE_QUIRK_HAS_POPUP_WINDOW_SUPPORT;
|
||||
device->device_caps = VIDEO_DEVICE_CAPS_HAS_POPUP_WINDOW_SUPPORT |
|
||||
VIDEO_DEVICE_CAPS_SENDS_FULLSCREEN_DIMENSIONS;
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
+208
-217
File diff suppressed because it is too large
Load Diff
@@ -78,6 +78,22 @@ struct SDL_WindowData
|
||||
SDL_bool pointer_barrier_active;
|
||||
PointerBarrier barrier[4];
|
||||
SDL_Rect barrier_rect;
|
||||
|
||||
SDL_Rect expected;
|
||||
SDL_DisplayMode requested_fullscreen_mode;
|
||||
|
||||
enum
|
||||
{
|
||||
X11_PENDING_OP_NONE = 0x00,
|
||||
X11_PENDING_OP_RESTORE = 0x01,
|
||||
X11_PENDING_OP_MINIMIZE = 0x02,
|
||||
X11_PENDING_OP_MAXIMIZE = 0x04,
|
||||
X11_PENDING_OP_FULLSCREEN = 0x08
|
||||
} pending_operation;
|
||||
|
||||
SDL_bool initial_border_adjustment;
|
||||
SDL_bool window_was_maximized;
|
||||
int skip_size_count;
|
||||
#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */
|
||||
SDL_HitTestResult hit_test_result;
|
||||
};
|
||||
@@ -106,7 +122,7 @@ extern void X11_RestoreWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void X11_SetWindowBordered(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool bordered);
|
||||
extern void X11_SetWindowResizable(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool resizable);
|
||||
extern void X11_SetWindowAlwaysOnTop(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool on_top);
|
||||
extern void X11_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen);
|
||||
extern int X11_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen);
|
||||
extern void *X11_GetWindowICCProfile(SDL_VideoDevice *_this, SDL_Window *window, size_t *size);
|
||||
extern void X11_SetWindowMouseGrab(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool grabbed);
|
||||
extern void X11_SetWindowKeyboardGrab(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool grabbed);
|
||||
@@ -115,9 +131,10 @@ extern int X11_SetWindowHitTest(SDL_Window *window, SDL_bool enabled);
|
||||
extern void X11_AcceptDragAndDrop(SDL_Window *window, SDL_bool accept);
|
||||
extern int X11_FlashWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_FlashOperation operation);
|
||||
extern void X11_ShowWindowSystemMenu(SDL_Window *window, int x, int y);
|
||||
extern int X11_SyncWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern int X11_SetWindowFocusable(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool focusable);
|
||||
|
||||
int SDL_X11_SetWindowTitle(Display *display, Window xwindow, char *title);
|
||||
void X11_UpdateWindowPosition(SDL_Window *window);
|
||||
void X11_UpdateWindowPosition(SDL_Window *window, SDL_bool use_current_position);
|
||||
|
||||
#endif /* SDL_x11window_h_ */
|
||||
|
||||
+484
-30
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user