Cache window manipulation calls while an SDL_Window is hidden and replay them when the window is set visible

- SDL_MaximizeWindow, MinimizeWindow, SetFullScreenWindow, etc are not meant to show the window if it isn't currently visible, but on some platforms
  (e.g. Windows) it isn't possible to set this state without also showing the window so cache the flags in a pending_flags field until SDL_ShowWindow is
  called. Then replay the pending flags through ApplyPendingFlags (hoisted out from SDL_FinishWindowCreation).
main
Sam Lantinga 2023-05-19 10:23:16 -07:00
parent 5c019bc97e
commit 4e9cfad558
2 changed files with 51 additions and 3 deletions

View File

@ -78,6 +78,7 @@ struct SDL_Window
int max_w, max_h;
int last_pixel_w, last_pixel_h;
Uint32 flags;
Uint32 pending_flags;
float display_scale;
SDL_bool fullscreen_exclusive; /* The window is currently fullscreen exclusive */
SDL_DisplayID last_fullscreen_exclusive_display; /* The last fullscreen_exclusive display */

View File

@ -1728,10 +1728,8 @@ void SDL_ToggleDragAndDropSupport(void)
}
}
static void SDL_FinishWindowCreation(SDL_Window *window, Uint32 flags)
static void ApplyWindowFlags(SDL_Window *window, Uint32 flags)
{
PrepareDragAndDropSupport(window);
if (flags & SDL_WINDOW_MAXIMIZED) {
SDL_MaximizeWindow(window);
}
@ -1752,6 +1750,12 @@ static void SDL_FinishWindowCreation(SDL_Window *window, Uint32 flags)
if (flags & SDL_WINDOW_KEYBOARD_GRABBED) {
SDL_SetWindowKeyboardGrab(window, SDL_TRUE);
}
}
static void SDL_FinishWindowCreation(SDL_Window *window, Uint32 flags)
{
PrepareDragAndDropSupport(window);
ApplyWindowFlags(window, flags);
if (!(flags & SDL_WINDOW_HIDDEN)) {
SDL_ShowWindow(window);
}
@ -2764,6 +2768,12 @@ int SDL_ShowWindow(SDL_Window *window)
}
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_SHOWN, 0, 0);
/* Set window state if we have pending window flags cached */
if (window->pending_flags) {
ApplyWindowFlags(window, window->pending_flags);
window->pending_flags = 0;
}
/* Restore child windows */
for (child = window->first_child; child != NULL; child = child->next_sibling) {
if (!child->restore_on_show && (child->flags & SDL_WINDOW_HIDDEN)) {
@ -2825,6 +2835,11 @@ int SDL_MaximizeWindow(SDL_Window *window)
return 0;
}
if (window->flags & SDL_WINDOW_HIDDEN) {
window->pending_flags |= SDL_WINDOW_MAXIMIZED;
return 0;
}
/* !!! FIXME: should this check if the window is resizable? */
if (_this->MaximizeWindow) {
@ -2850,6 +2865,11 @@ int SDL_MinimizeWindow(SDL_Window *window)
return 0;
}
if (window->flags & SDL_WINDOW_HIDDEN) {
window->pending_flags |= SDL_WINDOW_MINIMIZED;
return 0;
}
if (!SDL_CanMinimizeWindow(window)) {
return 0;
}
@ -2887,6 +2907,15 @@ int SDL_SetWindowFullscreen(SDL_Window *window, SDL_bool fullscreen)
CHECK_WINDOW_MAGIC(window, -1);
CHECK_WINDOW_NOT_POPUP(window, -1);
if (window->flags & SDL_WINDOW_HIDDEN) {
if (fullscreen) {
window->pending_flags |= SDL_WINDOW_FULLSCREEN;
} else {
window->pending_flags &= ~SDL_WINDOW_FULLSCREEN;
}
return 0;
}
if (flags == (window->flags & SDL_WINDOW_FULLSCREEN)) {
return 0;
}
@ -3164,6 +3193,15 @@ int SDL_SetWindowKeyboardGrab(SDL_Window *window, SDL_bool grabbed)
CHECK_WINDOW_MAGIC(window, -1);
CHECK_WINDOW_NOT_POPUP(window, -1);
if (window->flags & SDL_WINDOW_HIDDEN) {
if (grabbed) {
window->pending_flags |= SDL_WINDOW_KEYBOARD_GRABBED;
} else {
window->pending_flags &= ~SDL_WINDOW_KEYBOARD_GRABBED;
}
return 0;
}
if (!!grabbed == !!(window->flags & SDL_WINDOW_KEYBOARD_GRABBED)) {
return 0;
}
@ -3181,6 +3219,15 @@ int SDL_SetWindowMouseGrab(SDL_Window *window, SDL_bool grabbed)
CHECK_WINDOW_MAGIC(window, -1);
CHECK_WINDOW_NOT_POPUP(window, -1);
if (window->flags & SDL_WINDOW_HIDDEN) {
if (grabbed) {
window->pending_flags |= SDL_WINDOW_MOUSE_GRABBED;
} else {
window->pending_flags &= ~SDL_WINDOW_MOUSE_GRABBED;
}
return 0;
}
if (!!grabbed == !!(window->flags & SDL_WINDOW_MOUSE_GRABBED)) {
return 0;
}