diff options
author | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2025-05-28 09:55:55 +0200 |
---|---|---|
committer | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2025-07-02 12:30:38 +0000 |
commit | 98d2b72c031bbd557b3ee59f62014cec542b7793 (patch) | |
tree | 374535597fc6be0e3896b5850f849d893eb3702f | |
parent | 8a882e630fd2a4db3e7df391278f2cd795dac5f6 (diff) | |
download | mana-98d2b72c031bbd557b3ee59f62014cec542b7793.tar.gz mana-98d2b72c031bbd557b3ee59f62014cec542b7793.tar.bz2 mana-98d2b72c031bbd557b3ee59f62014cec542b7793.tar.xz mana-98d2b72c031bbd557b3ee59f62014cec542b7793.zip |
Delay showing of the window to avoid startup flicker
Otherwise, at least on X11, the window is (visibly) re-created once the
SDL renderer is created. Also the window icon can be seen changing on
startup. Showing the window only after all related setup has been
completed avoids this.
On X11 this appears to have the added benefit of putting a "windowed
fullscreen" window on the active screen (in terms of where the mouse is)
rather than always using the primary screen.
On Windows, showing the window only after the initial paint avoids the
window initially appearing with its contents entirely black.
The window is still immediately shown in the following cases:
* In exclusive fullscreen mode, because on Windows this caused the
initial show of a fullscreen window to take much longer and on X11 it
could cause the resolution of the primary screen to be changed while
maximizing the Mana window on the active screen.
* In "windowed fullscreen" mode when the legacy OpenGL renderer is used,
where it was causing an additional flicker on Windows.
-rw-r--r-- | src/openglgraphics.cpp | 1 | ||||
-rw-r--r-- | src/sdlgraphics.cpp | 8 | ||||
-rw-r--r-- | src/sdlgraphics.h | 3 | ||||
-rw-r--r-- | src/video.cpp | 8 |
4 files changed, 16 insertions, 4 deletions
diff --git a/src/openglgraphics.cpp b/src/openglgraphics.cpp index ecd98ea1..180b16ec 100644 --- a/src/openglgraphics.cpp +++ b/src/openglgraphics.cpp @@ -542,6 +542,7 @@ void OpenGLGraphics::drawRescaledImagePattern(const Image *image, void OpenGLGraphics::updateScreen() { SDL_GL_SwapWindow(mWindow); + SDL_ShowWindow(mWindow); /* * glFinish flushes all OpenGL commands and makes sure they have been diff --git a/src/sdlgraphics.cpp b/src/sdlgraphics.cpp index 9256471a..5856d2da 100644 --- a/src/sdlgraphics.cpp +++ b/src/sdlgraphics.cpp @@ -77,11 +77,12 @@ std::unique_ptr<Graphics> SDLGraphics::create(SDL_Window *window, const VideoSet return {}; } - return std::make_unique<SDLGraphics>(renderer); + return std::make_unique<SDLGraphics>(window, renderer); } -SDLGraphics::SDLGraphics(SDL_Renderer *renderer) - : mRenderer(renderer) +SDLGraphics::SDLGraphics(SDL_Window *window, SDL_Renderer *renderer) + : mWindow(window) + , mRenderer(renderer) { Image::setRenderer(mRenderer); @@ -245,6 +246,7 @@ void SDLGraphics::drawRescaledImagePattern(const Image *image, void SDLGraphics::updateScreen() { SDL_RenderPresent(mRenderer); + SDL_ShowWindow(mWindow); } void SDLGraphics::windowToLogical(int windowX, int windowY, diff --git a/src/sdlgraphics.h b/src/sdlgraphics.h index 7cdea414..057fcdc3 100644 --- a/src/sdlgraphics.h +++ b/src/sdlgraphics.h @@ -33,7 +33,7 @@ public: static std::unique_ptr<Graphics> create(SDL_Window *window, const VideoSettings &settings); - SDLGraphics(SDL_Renderer *renderer); + SDLGraphics(SDL_Window *window, SDL_Renderer *renderer); ~SDLGraphics() override; void setVSync(bool sync) override; @@ -83,5 +83,6 @@ protected: void updateClipRect() override; private: + SDL_Window *mWindow = nullptr; SDL_Renderer *mRenderer = nullptr; }; diff --git a/src/video.cpp b/src/video.cpp index 7ab21d12..7bfe9747 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -92,6 +92,10 @@ Graphics *Video::initialize(const VideoSettings &settings) switch (mSettings.windowMode) { case WindowMode::Windowed: + // In windowed mode, the window is initially created hidden, we'll show + // it once we have finished setting it up and done an initial paint to + // avoid startup flicker on X11 and Windows. + windowFlags |= SDL_WINDOW_HIDDEN; break; case WindowMode::Fullscreen: windowFlags |= SDL_WINDOW_FULLSCREEN; @@ -99,6 +103,10 @@ Graphics *Video::initialize(const VideoSettings &settings) break; case WindowMode::WindowedFullscreen: windowFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP; + // On Windows, fullscreen desktop with OpenGL actually flickers worse + // when the window is initially hidden. + if (!mSettings.openGL) + windowFlags |= SDL_WINDOW_HIDDEN; videoMode = "windowed fullscreen"; break; } |