summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <bjorn@lindeijer.nl>2025-05-28 09:55:55 +0200
committerThorbjørn Lindeijer <bjorn@lindeijer.nl>2025-07-02 12:30:38 +0000
commit98d2b72c031bbd557b3ee59f62014cec542b7793 (patch)
tree374535597fc6be0e3896b5850f849d893eb3702f
parent8a882e630fd2a4db3e7df391278f2cd795dac5f6 (diff)
downloadmana-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.cpp1
-rw-r--r--src/sdlgraphics.cpp8
-rw-r--r--src/sdlgraphics.h3
-rw-r--r--src/video.cpp8
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;
}