SDL2 fullscreen apps w/ window decorations fight for mode change
Greetings,
when an SDL2 application with flags = SDL_WINDOW_FULLSCREEN (and in particular when the requested resolution != desktop resolution) is started, the desktop flickers. Depending on how fast the application is able to react to events, two outcomes can follow:
- the application and desktop keep changing video mode rapidly, back and forth. This situation can be recovered only by killing the application
- the application flickers a random number of times until it settles
To be noted that the default initialization for the window in SDL2 sets it up decorated. By passing SDL_WINDOW_BORDERLESS to SDL_CreateWindow's flags, the issue doesn't reproduce. Eg:
SDL_CreateWindow("SDLTest", 0, 0, WIDTH, HEIGHT, SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS );
Tested under ubuntu 20.04 x64 w/ gnome-flashback:
Package: metacity
Version: 1:3.36.1-1 (baseline focal pacakge, affected)
Version: 3.34.1 (compiled, working fine)
By bisecting the commits between the two versions, I ended up into this changeset, which is the root cause of the issue:
7a7aaa338b89c0c66122958e7c6cb56322e73371 is the first bad commit
commit 7a7aaa338b89c0c66122958e7c6cb56322e73371
Author: Alberts Muktupāvels <alberts.muktupavels@gmail.com>
Date: Fri Feb 28 19:35:32 2020 +0200
window: remove frame from fullscreen windows
src/core/window.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/src/core/window.c b/src/core/window.c
index b745cdd3..963e23a9 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -6963,16 +6963,14 @@ recalc_window_features (MetaWindow *window)
window->has_fullscreen_func = FALSE;
}
- /* We leave fullscreen windows decorated, just push the frame outside
- * the screen. This avoids flickering to unparent them.
- *
- * Note that setting has_resize_func = FALSE here must come after the
+ /* Note that setting has_resize_func = FALSE here must come after the
* above code that may disable fullscreen, because if the window
* is not resizable purely due to fullscreen, we don't want to
* disable fullscreen mode.
*/
if (window->fullscreen)
{
+ window->decorated = FALSE;
window->has_shade_func = FALSE;
window->has_move_func = FALSE;
window->has_resize_func = FALSE;
I'm not able to assess whether this should be fixed in SDL (either only or as well, since I fail to see the reason for decorated fullscreen windows), but I think this change introduces a regression (in particular with a conspicuous set of sdl-based games/apps). An ad-interim solution consists in removing the decorations when switching to fullscreen.
A minimal SDL2 fullscreen application is attached as test to reproduce the issue:
compile with:
clang $(sdl2-config --cflags) -c -o sdltest.o sdltest.c
clang -o sdltest sdltest.o $(sdl2-config --libs)