video: Distinguish between explicit fullscreen enter requests and update requests

Video backends that run asynchronously can wind up in a race situation if a mode or position update request queues up a fullscreen enter request while an unprocessed asynchronous leave request is in flight, and the mode switch or position update request is processed after the leave request, causing the window to erroneously return to fullscreen.

Instead of the internal SDL_UpdateFullscreenMode and backend SetWindowFullscreen functions taking a boolean value, use an enum that allows the backends to distinguish between "this is an explicit fullscreen enter/leave request", and "this is an update request to change the mode or position". Communicating the specific intent allows the backend to early-out when required, which prevents windows from erroneously returning to fullscreen due to update requests made after a leave request, and allows for the removal of some internal synchronization previously needed to (attempt to) work around this, which improves overall performance while also increasing robustness.

This is only relevant to the internal functions, and nothing in the public-facing API has been changed.
This commit is contained in:
Frank Praznik 2024-05-25 12:05:19 -04:00
parent fefa47e409
commit 0e1f3b681f
21 changed files with 71 additions and 50 deletions

View File

@ -162,6 +162,14 @@ typedef enum
VIDEO_DEVICE_CAPS_DISABLE_MOUSE_WARP_ON_FULLSCREEN_TRANSITIONS = 0x20
} DeviceCaps;
/* Fullscreen operations */
typedef enum
{
SDL_FULLSCREEN_OP_LEAVE = 0,
SDL_FULLSCREEN_OP_ENTER,
SDL_FULLSCREEN_OP_UPDATE
} SDL_FullscreenOp;
struct SDL_VideoDevice
{
/* * * */
@ -246,7 +254,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);
int (*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_FullscreenOp fullscreen);
void *(*GetWindowICCProfile)(SDL_VideoDevice *_this, SDL_Window *window, size_t *size);
SDL_DisplayID (*GetDisplayForWindow)(SDL_VideoDevice *_this, SDL_Window *window);
int (*SetWindowMouseRect)(SDL_VideoDevice *_this, SDL_Window *window);
@ -535,7 +543,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 int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_FullscreenOp fullscreen, SDL_bool commit);
extern SDL_Window *SDL_GetToplevelForKeyboardFocus(void);
extern SDL_bool SDL_ShouldAllowTopmost(void);

View File

@ -1642,7 +1642,7 @@ static void SDL_RestoreMousePosition(SDL_Window *window)
}
}
int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen, SDL_bool commit)
int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_FullscreenOp fullscreen, SDL_bool commit)
{
SDL_VideoDisplay *display = NULL;
SDL_DisplayMode *mode = NULL;
@ -1718,7 +1718,7 @@ int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen, SDL_bool c
}
}
if (Cocoa_SetWindowFullscreenSpace(window, fullscreen, syncHint)) {
if (Cocoa_SetWindowFullscreenSpace(window, !!fullscreen, syncHint)) {
goto done;
}
}
@ -1732,7 +1732,7 @@ int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen, SDL_bool c
to fullscreen (being active, or not), and figure out a return/error code
from that.
*/
if (fullscreen == !(WINRT_DetectWindowFlags(window) & SDL_WINDOW_FULLSCREEN)) {
if (!!fullscreen == !(WINRT_DetectWindowFlags(window) & SDL_WINDOW_FULLSCREEN)) {
/* Uh oh, either:
1. fullscreen was requested, and we're already windowed
2. windowed-mode was requested, and we're already fullscreen
@ -1781,7 +1781,7 @@ int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen, SDL_bool c
if (commit) {
int ret = 0;
if (_this->SetWindowFullscreen) {
ret = _this->SetWindowFullscreen(_this, window, display, SDL_TRUE);
ret = _this->SetWindowFullscreen(_this, window, display, fullscreen);
} else {
resized = SDL_TRUE;
}
@ -1843,7 +1843,7 @@ int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen, SDL_bool c
if (_this->SetWindowFullscreen) {
SDL_VideoDisplay *full_screen_display = display ? display : SDL_GetVideoDisplayForFullscreenWindow(window);
if (full_screen_display) {
ret = _this->SetWindowFullscreen(_this, window, full_screen_display, SDL_FALSE);
ret = _this->SetWindowFullscreen(_this, window, full_screen_display, SDL_FULLSCREEN_OP_LEAVE);
}
} else {
resized = SDL_TRUE;
@ -1886,7 +1886,7 @@ done:
error:
if (fullscreen) {
/* Something went wrong and the window is no longer fullscreen. */
SDL_UpdateFullscreenMode(window, SDL_FALSE, commit);
SDL_UpdateFullscreenMode(window, SDL_FULLSCREEN_OP_LEAVE, commit);
}
return -1;
}
@ -1912,7 +1912,7 @@ int SDL_SetWindowFullscreenMode(SDL_Window *window, const SDL_DisplayMode *mode)
*/
SDL_copyp(&window->current_fullscreen_mode, &window->requested_fullscreen_mode);
if (SDL_WINDOW_FULLSCREEN_VISIBLE(window)) {
SDL_UpdateFullscreenMode(window, SDL_TRUE, SDL_TRUE);
SDL_UpdateFullscreenMode(window, SDL_FULLSCREEN_OP_UPDATE, SDL_TRUE);
SDL_SyncIfRequired(window);
}
@ -3117,7 +3117,7 @@ int SDL_SetWindowFullscreen(SDL_Window *window, SDL_bool fullscreen)
SDL_copyp(&window->current_fullscreen_mode, &window->requested_fullscreen_mode);
}
ret = SDL_UpdateFullscreenMode(window, fullscreen, SDL_TRUE);
ret = SDL_UpdateFullscreenMode(window, fullscreen ? SDL_FULLSCREEN_OP_ENTER : SDL_FULLSCREEN_OP_LEAVE, SDL_TRUE);
if (!fullscreen || ret != 0) {
/* Clear the current fullscreen mode. */
@ -3578,7 +3578,7 @@ void SDL_OnWindowHidden(SDL_Window *window)
window->pending_flags |= (window->flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_MAXIMIZED));
/* The window is already hidden at this point, so just change the mode back if necessary. */
SDL_UpdateFullscreenMode(window, SDL_FALSE, SDL_FALSE);
SDL_UpdateFullscreenMode(window, SDL_FULLSCREEN_OP_LEAVE, SDL_FALSE);
}
void SDL_OnWindowDisplayChanged(SDL_Window *window)
@ -3603,7 +3603,7 @@ void SDL_OnWindowDisplayChanged(SDL_Window *window)
}
if (SDL_WINDOW_FULLSCREEN_VISIBLE(window)) {
SDL_UpdateFullscreenMode(window, SDL_TRUE, SDL_TRUE);
SDL_UpdateFullscreenMode(window, SDL_FULLSCREEN_OP_UPDATE, SDL_TRUE);
}
}
@ -3646,7 +3646,7 @@ void SDL_OnWindowPixelSizeChanged(SDL_Window *window)
void SDL_OnWindowMinimized(SDL_Window *window)
{
if (window->flags & SDL_WINDOW_FULLSCREEN) {
SDL_UpdateFullscreenMode(window, SDL_FALSE, SDL_FALSE);
SDL_UpdateFullscreenMode(window, SDL_FULLSCREEN_OP_LEAVE, SDL_FALSE);
}
}
@ -3665,7 +3665,7 @@ void SDL_OnWindowRestored(SDL_Window *window)
/*SDL_RaiseWindow(window);*/
if (window->flags & SDL_WINDOW_FULLSCREEN) {
SDL_UpdateFullscreenMode(window, SDL_TRUE, SDL_FALSE);
SDL_UpdateFullscreenMode(window, SDL_FULLSCREEN_OP_ENTER, SDL_FALSE);
}
}
@ -3773,7 +3773,7 @@ void SDL_DestroyWindow(SDL_Window *window)
}
/* Restore video mode, etc. */
SDL_UpdateFullscreenMode(window, SDL_FALSE, SDL_TRUE);
SDL_UpdateFullscreenMode(window, SDL_FULLSCREEN_OP_LEAVE, SDL_TRUE);
if (!(window->flags & SDL_WINDOW_EXTERNAL)) {
SDL_HideWindow(window);
}

View File

@ -105,7 +105,7 @@ void Android_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window)
Android_JNI_SetActivityTitle(window->title);
}
int 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_FullscreenOp fullscreen)
{
SDL_LockMutex(Android_ActivityMutex);

View File

@ -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 int 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_FullscreenOp fullscreen);
extern void Android_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void Android_SetWindowResizable(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool resizable);

View File

@ -169,7 +169,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 int 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_FullscreenOp 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 int Cocoa_SetWindowMouseRect(SDL_VideoDevice *_this, SDL_Window *window);

View File

@ -2601,7 +2601,7 @@ void Cocoa_SetWindowAlwaysOnTop(SDL_VideoDevice *_this, SDL_Window *window, SDL_
}
}
int Cocoa_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
int Cocoa_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_FullscreenOp fullscreen)
{
@autoreleasepool {
SDL_CocoaWindowData *data = (__bridge SDL_CocoaWindowData *)window->driverdata;

View File

@ -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 int 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_FullscreenOp fullscreen);
static void Emscripten_PumpEvents(SDL_VideoDevice *_this);
static void Emscripten_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window);
@ -291,7 +291,7 @@ static void Emscripten_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window)
}
}
static int 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_FullscreenOp fullscreen)
{
SDL_WindowData *data;
int res = -1;

View File

@ -150,10 +150,10 @@ void HAIKU_RestoreWindow(SDL_VideoDevice *_this, SDL_Window * window) {
}
int HAIKU_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window * window,
SDL_VideoDisplay * display, SDL_bool fullscreen) {
SDL_VideoDisplay * display, SDL_FullscreenOp fullscreen) {
/* Haiku tracks all video display information */
BMessage msg(BWIN_FULLSCREEN);
msg.AddBool("fullscreen", fullscreen);
msg.AddBool("fullscreen", !!fullscreen);
_ToBeWin(window)->PostMessage(&msg);
return 0;
}

View File

@ -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 int 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_FullscreenOp fullscreen);
extern int HAIKU_SetWindowMouseGrab(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool grabbed);
extern void HAIKU_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window);

View File

@ -1680,7 +1680,7 @@ void KMSDRM_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window)
KMSDRM_DirtySurfaces(window);
}
}
int 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_FullscreenOp fullscreen)
{
SDL_VideoData *viddata = _this->driverdata;
if (!viddata->vulkan_mode) {

View File

@ -156,7 +156,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);
int 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_FullscreenOp 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);

View File

@ -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 int 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_FullscreenOp fullscreen);
extern void UIKit_UpdatePointerLock(SDL_VideoDevice *_this, SDL_Window *window);
extern void UIKit_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void UIKit_GetWindowSizeInPixels(SDL_VideoDevice *_this, SDL_Window *window, int *w, int *h);

View File

@ -306,7 +306,7 @@ void UIKit_SetWindowBordered(SDL_VideoDevice *_this, SDL_Window *window, SDL_boo
}
}
int 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_FullscreenOp fullscreen)
{
@autoreleasepool {
SDL_SendWindowEvent(window, fullscreen ? SDL_EVENT_WINDOW_ENTER_FULLSCREEN : SDL_EVENT_WINDOW_LEAVE_FULLSCREEN, 0, 0);

View File

@ -527,11 +527,6 @@ static void Wayland_move_window(SDL_Window *window)
if (wind->last_displayID != displays[i]) {
wind->last_displayID = displays[i];
if (wind->shell_surface_type != WAYLAND_SURFACE_XDG_POPUP) {
/* Need to catch up on fullscreen state here, as the video core may try to update
* the fullscreen window, which on Wayland involves a set fullscreen call, which
* can overwrite older pending state.
*/
FlushFullscreenEvents(window);
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_MOVED, display->x, display->y);
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_DISPLAY_CHANGED, wind->last_displayID, 0);
}
@ -598,7 +593,7 @@ static void UpdateWindowFullscreen(SDL_Window *window, SDL_bool fullscreen)
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
SDL_copyp(&window->current_fullscreen_mode, &window->requested_fullscreen_mode);
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_ENTER_FULLSCREEN, 0, 0);
SDL_UpdateFullscreenMode(window, SDL_TRUE, SDL_FALSE);
SDL_UpdateFullscreenMode(window, SDL_FULLSCREEN_OP_ENTER, SDL_FALSE);
/* Set the output for exclusive fullscreen windows when entering fullscreen from a
* compositor event, or if the fullscreen paramaters were changed between the initial
@ -617,7 +612,7 @@ static void UpdateWindowFullscreen(SDL_Window *window, SDL_bool fullscreen)
/* Don't change the fullscreen flags if the window is hidden or being hidden. */
if ((window->flags & SDL_WINDOW_FULLSCREEN) && !window->is_hiding && !(window->flags & SDL_WINDOW_HIDDEN)) {
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_LEAVE_FULLSCREEN, 0, 0);
SDL_UpdateFullscreenMode(window, SDL_FALSE, SDL_FALSE);
SDL_UpdateFullscreenMode(window, SDL_FULLSCREEN_OP_LEAVE, SDL_FALSE);
wind->fullscreen_was_positioned = SDL_FALSE;
/* Send a move event, in case it was deferred while the fullscreen window was moving and
@ -1983,7 +1978,7 @@ int Wayland_FlashWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_FlashOpe
}
int Wayland_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window,
SDL_VideoDisplay *display, SDL_bool fullscreen)
SDL_VideoDisplay *display, SDL_FullscreenOp fullscreen)
{
SDL_WindowData *wind = window->driverdata;
struct wl_output *output = display->driverdata->output;
@ -2006,6 +2001,17 @@ int Wayland_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window,
FlushFullscreenEvents(window);
wind->drop_fullscreen_requests = SDL_FALSE;
/* Nothing to do if the window is not fullscreen, and this isn't an explicit enter request. */
if (!wind->is_fullscreen) {
if (fullscreen == SDL_FULLSCREEN_OP_UPDATE) {
/* Request was out of date; return 1 to signal the video core not to update any state. */
return 1;
} else if (fullscreen == SDL_FULLSCREEN_OP_LEAVE) {
/* Already not fullscreen; nothing to do. */
return 0;
}
}
/* Don't send redundant fullscreen set/unset events. */
if (fullscreen != wind->is_fullscreen) {
wind->fullscreen_was_positioned = fullscreen;
@ -2024,6 +2030,8 @@ int Wayland_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window,
} else {
ConfigureWindowGeometry(window);
CommitLibdecorFrame(window);
return 0;
}
}

View File

@ -177,7 +177,7 @@ extern void Wayland_HideWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void Wayland_RaiseWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern int Wayland_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window,
SDL_VideoDisplay *_display,
SDL_bool fullscreen);
SDL_FullscreenOp fullscreen);
extern void Wayland_MaximizeWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void Wayland_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern int Wayland_SetWindowMouseRect(SDL_VideoDevice *_this, SDL_Window *window);

View File

@ -1208,7 +1208,7 @@ static COLORREF WIN_UpdateBorderColorForHWND(HWND hwnd, COLORREF colorRef)
/**
* Reconfigures the window to fill the given display, if fullscreen is true, otherwise restores the window.
*/
int 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_FullscreenOp fullscreen)
{
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
SDL_DisplayData *displaydata = display->driverdata;

View File

@ -100,7 +100,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 int 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_FullscreenOp 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 int WIN_SetWindowMouseRect(SDL_VideoDevice *_this, SDL_Window *window);

View File

@ -75,7 +75,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 int 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_FullscreenOp fullscreen);
static void WINRT_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window);
/* Misc functions */
@ -745,7 +745,7 @@ void WINRT_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window)
#endif
}
int 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_FullscreenOp fullscreen)
{
#if NTDDI_VERSION >= NTDDI_WIN10
SDL_WindowData *data = window->driverdata;

View File

@ -1697,9 +1697,9 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
* 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);
SDL_UpdateFullscreenMode(data->window, SDL_FULLSCREEN_OP_UPDATE, SDL_TRUE);
} else {
SDL_UpdateFullscreenMode(data->window, SDL_TRUE, SDL_FALSE);
SDL_UpdateFullscreenMode(data->window, SDL_FULLSCREEN_OP_ENTER, SDL_FALSE);
}
}
} else {

View File

@ -1040,7 +1040,7 @@ int X11_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window)
}
X11_UpdateWindowPosition(window, SDL_FALSE);
} else {
SDL_UpdateFullscreenMode(window, SDL_TRUE, SDL_TRUE);
SDL_UpdateFullscreenMode(window, SDL_FULLSCREEN_OP_UPDATE, SDL_TRUE);
}
return 0;
}
@ -1609,7 +1609,7 @@ void X11_RestoreWindow(SDL_VideoDevice *_this, SDL_Window *window)
}
/* This asks the Window Manager to handle fullscreen for us. This is the modern way. */
static int X11_SetWindowFullscreenViaWM(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *_display, SDL_bool fullscreen)
static int X11_SetWindowFullscreenViaWM(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *_display, SDL_FullscreenOp fullscreen)
{
CHECK_WINDOW_DATA(window);
CHECK_DISPLAY_DATA(_display);
@ -1628,9 +1628,14 @@ static int X11_SetWindowFullscreenViaWM(SDL_VideoDevice *_this, SDL_Window *wind
X11_SyncWindow(_this, window);
}
/* Nothing to do */
if (!fullscreen && !(window->flags & SDL_WINDOW_FULLSCREEN)) {
return 0;
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
if (fullscreen == SDL_FULLSCREEN_OP_UPDATE) {
/* Request was out of date; set -1 to signal the video core to undo a mode switch. */
return -1;
} else if (fullscreen == SDL_FULLSCREEN_OP_LEAVE) {
/* Nothing to do. */
return 0;
}
}
if (fullscreen && !(window->flags & SDL_WINDOW_RESIZABLE)) {
@ -1724,7 +1729,7 @@ static int X11_SetWindowFullscreenViaWM(SDL_VideoDevice *_this, SDL_Window *wind
return 1;
}
int X11_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *_display, SDL_bool fullscreen)
int X11_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *_display, SDL_FullscreenOp fullscreen)
{
return X11_SetWindowFullscreenViaWM(_this, window, _display, fullscreen);
}

View File

@ -128,7 +128,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 int 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_FullscreenOp fullscreen);
extern void *X11_GetWindowICCProfile(SDL_VideoDevice *_this, SDL_Window *window, size_t *size);
extern int X11_SetWindowMouseGrab(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool grabbed);
extern int X11_SetWindowKeyboardGrab(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool grabbed);