diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 1a6e4c5ba0..ddf0e62ab2 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -153,6 +153,7 @@ typedef enum { VIDEO_DEVICE_QUIRK_MODE_SWITCHING_EMULATED = 0x01, VIDEO_DEVICE_QUIRK_DISABLE_UNSET_FULLSCREEN_ON_MINIMIZE = 0x02, + VIDEO_DEVICE_QUIRK_HANDLES_UNDEFINED_WINDOW_POSITION = 0x04, } DeviceQuirkFlags; struct SDL_VideoDevice diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 431adfde83..82e51b00f5 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -154,12 +154,26 @@ extern SDL_bool Cocoa_SetWindowFullscreenSpace(SDL_Window *window, SDL_bool stat /* Convenience functions for reading driver flags */ static SDL_bool ModeSwitchingEmulated(_THIS) { - return !!(_this->quirk_flags & VIDEO_DEVICE_QUIRK_MODE_SWITCHING_EMULATED); + if (_this->quirk_flags & VIDEO_DEVICE_QUIRK_MODE_SWITCHING_EMULATED) { + return SDL_TRUE; + } + return SDL_FALSE; } static SDL_bool DisableUnsetFullscreenOnMinimize(_THIS) { - return !!(_this->quirk_flags & VIDEO_DEVICE_QUIRK_DISABLE_UNSET_FULLSCREEN_ON_MINIMIZE); + if (_this->quirk_flags & VIDEO_DEVICE_QUIRK_DISABLE_UNSET_FULLSCREEN_ON_MINIMIZE) { + return SDL_TRUE; + } + return SDL_FALSE; +} + +static SDL_bool HandlesUndefinedWindowPosition(_THIS) +{ + if (_this->quirk_flags & VIDEO_DEVICE_QUIRK_HANDLES_UNDEFINED_WINDOW_POSITION) { + return SDL_TRUE; + } + return SDL_FALSE; } /* Support for framebuffer emulation using an accelerated renderer */ @@ -1672,10 +1686,12 @@ SDL_Window *SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint SDL_zero(bounds); SDL_GetDisplayBounds(displayID, &bounds); - if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISCENTERED(x)) { + if (SDL_WINDOWPOS_ISCENTERED(x) || + (SDL_WINDOWPOS_ISUNDEFINED(x) && !HandlesUndefinedWindowPosition(_this))) { x = bounds.x + (bounds.w - w) / 2; } - if (SDL_WINDOWPOS_ISUNDEFINED(y) || SDL_WINDOWPOS_ISCENTERED(y)) { + if (SDL_WINDOWPOS_ISCENTERED(y) || + (SDL_WINDOWPOS_ISUNDEFINED(y) && !HandlesUndefinedWindowPosition(_this))) { y = bounds.y + (bounds.h - h) / 2; } } diff --git a/src/video/windows/SDL_windowsvideo.c b/src/video/windows/SDL_windowsvideo.c index 9cb30d820b..cd297cb2dd 100644 --- a/src/video/windows/SDL_windowsvideo.c +++ b/src/video/windows/SDL_windowsvideo.c @@ -260,6 +260,8 @@ static SDL_VideoDevice *WIN_CreateDevice(void) device->free = WIN_DeleteDevice; + device->quirk_flags = VIDEO_DEVICE_QUIRK_HANDLES_UNDEFINED_WINDOW_POSITION; + return device; } diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c index 06e125cc09..9c45da3827 100644 --- a/src/video/windows/SDL_windowswindow.c +++ b/src/video/windows/SDL_windowswindow.c @@ -490,6 +490,7 @@ int WIN_CreateWindow(_THIS, SDL_Window *window) DWORD style = STYLE_BASIC; int x, y; int w, h; + SDL_bool undefined_position = SDL_FALSE; if (window->flags & SDL_WINDOW_SKIP_TASKBAR) { parent = CreateWindow(SDL_Appname, TEXT(""), STYLE_BASIC, 0, 0, 32, 32, NULL, NULL, SDL_Instance, NULL); @@ -497,12 +498,46 @@ int WIN_CreateWindow(_THIS, SDL_Window *window) style |= GetWindowStyle(window); + /* Make sure we have valid coordinates for the AdjustWindowRect call below */ + x = window->x; + y = window->y; + if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISUNDEFINED(y)) { + SDL_DisplayID displayID = 0; + SDL_Rect bounds; + + if (SDL_WINDOWPOS_ISUNDEFINED(x) && (x & 0xFFFF)) { + displayID = (x & 0xFFFF); + } else if (SDL_WINDOWPOS_ISUNDEFINED(y) && (y & 0xFFFF)) { + displayID = (y & 0xFFFF); + } + if (displayID == 0 || SDL_GetDisplayIndex(displayID) < 0) { + displayID = SDL_GetPrimaryDisplay(); + } + + SDL_zero(bounds); + SDL_GetDisplayBounds(displayID, &bounds); + if (SDL_WINDOWPOS_ISUNDEFINED(x)) { + window->x = window->windowed.x = bounds.x + (bounds.w - window->w) / 2; + } + if (SDL_WINDOWPOS_ISUNDEFINED(y)) { + window->y = window->windowed.y = bounds.y + (bounds.h - window->h) / 2; + } + if (displayID == SDL_GetPrimaryDisplay() && + SDL_WINDOWPOS_ISUNDEFINED(x) && SDL_WINDOWPOS_ISUNDEFINED(y)) { + /* We can use CW_USEDEFAULT for the position */ + undefined_position = SDL_TRUE; + } + } + /* Figure out what the window area will be */ WIN_AdjustWindowRectWithStyle(window, style, FALSE, &x, &y, &w, &h, SDL_FALSE); - hwnd = - CreateWindow(SDL_Appname, TEXT(""), style, x, y, w, h, parent, NULL, - SDL_Instance, NULL); + if (undefined_position) { + x = CW_USEDEFAULT; + y = CW_USEDEFAULT; /* Not actually used */ + } + + hwnd = CreateWindow(SDL_Appname, TEXT(""), style, x, y, w, h, parent, NULL, SDL_Instance, NULL); if (!hwnd) { return WIN_SetError("Couldn't create window"); } @@ -517,6 +552,12 @@ int WIN_CreateWindow(_THIS, SDL_Window *window) return -1; } + if (undefined_position) { + /* Record where the window ended up */ + window->windowed.x = window->x; + window->windowed.y = window->y; + } + /* Inform Windows of the frame change so we can respond to WM_NCCALCSIZE */ SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);