Skip to content

Commit ededb8a

Browse files
committed
Implement full support for borderless windows
Change the bitset to an enum with 3 modes for Fullscreen and window with and without border. Implement those modes in both VideoDrivers. Fixes #1512
1 parent 71cf658 commit ededb8a

24 files changed

Lines changed: 242 additions & 440 deletions

extras/videoDrivers/SDL2/VideoSDL2.cpp

Lines changed: 75 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
// Copyright (C) 2005 - 2025 Settlers Freaks (sf-team at siedler25.org)
1+
// Copyright (C) 2005 - 2026 Settlers Freaks (sf-team at siedler25.org)
22
//
33
// SPDX-License-Identifier: GPL-2.0-or-later
44

55
#include "VideoSDL2.h"
6+
#include "RTTR_Assert.h"
67
#include "driver/Interface.h"
78
#include "driver/VideoDriverLoaderInterface.h"
89
#include "driver/VideoInterface.h"
@@ -31,17 +32,12 @@
3132
# include <gl4esinit.h>
3233
#endif
3334

34-
#define CHECK_SDL(call) \
35-
([&]() -> bool { \
36-
if((call) < 0) \
37-
{ \
38-
PrintError(SDL_GetError()); \
39-
return false; \
40-
} \
41-
return true; \
42-
})()
35+
/// Check that the (SDL) call returns success or print the error
36+
/// Can be used in conditions: if(CHECK_SDL(SDL_Foo()))
37+
#define CHECK_SDL(call) ((call) >= 0 || (PrintError(), false))
4338

4439
namespace {
40+
4541
template<typename T>
4642
struct SDLMemoryDeleter
4743
{
@@ -102,7 +98,7 @@ bool VideoSDL2::Initialize()
10298
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
10399
if(SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
104100
{
105-
PrintError(SDL_GetError());
101+
PrintError();
106102
return false;
107103
}
108104

@@ -156,37 +152,53 @@ bool VideoSDL2::CreateScreen(const std::string& title, const VideoMode& size, Di
156152
CHECK_SDL(SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1));
157153

158154
const int wndPos = SDL_WINDOWPOS_CENTERED;
159-
const auto fullscreen = (displayMode & DisplayMode::Fullscreen) != DisplayMode::None;
160-
const auto resizable = (displayMode & DisplayMode::Resizable) != DisplayMode::None;
155+
const auto fullscreen = displayMode == DisplayMode::Fullscreen;
161156
const auto requestedSize = fullscreen ? FindClosestVideoMode(size) : size;
162-
const unsigned commonFlags = SDL_WINDOW_OPENGL | (resizable ? SDL_WINDOW_RESIZABLE : 0);
163-
const unsigned fullscreenFlag = (fullscreen ? SDL_WINDOW_FULLSCREEN : 0);
157+
const unsigned commonFlags = SDL_WINDOW_OPENGL;
164158
// TODO: Fix GUI scaling with High DPI support enabled.
165159
// See https://github.com/Return-To-The-Roots/s25client/issues/1621
166160
// commonFlags |= SDL_WINDOW_ALLOW_HIGHDPI;
167161

162+
const unsigned windowTypeFlag =
163+
fullscreen ? SDL_WINDOW_FULLSCREEN :
164+
(displayMode == DisplayMode::BorderlessWindow ? SDL_WINDOW_BORDERLESS : SDL_WINDOW_RESIZABLE);
165+
168166
window = SDL_CreateWindow(title.c_str(), wndPos, wndPos, requestedSize.width, requestedSize.height,
169-
commonFlags | fullscreenFlag);
167+
commonFlags | windowTypeFlag);
170168

171-
// Fallback to non-fullscreen
172-
if(!window && fullscreen)
169+
if(!window)
173170
{
174-
window = SDL_CreateWindow(title.c_str(), wndPos, wndPos, requestedSize.width, requestedSize.height,
175-
commonFlags | SDL_WINDOW_RESIZABLE);
171+
PrintError();
172+
// Fallback to borderless fullscreen
173+
if(fullscreen)
174+
{
175+
SDL_DisplayMode dskSize;
176+
if(!CHECK_SDL(SDL_GetDesktopDisplayMode(0, &dskSize)))
177+
{
178+
dskSize.w = size.width;
179+
dskSize.h = size.height;
180+
}
181+
window = SDL_CreateWindow(title.c_str(), wndPos, wndPos, dskSize.w, dskSize.h,
182+
commonFlags | SDL_WINDOW_BORDERLESS);
183+
}
184+
// No borderless -> Resizable
185+
if(!window)
186+
{
187+
window = SDL_CreateWindow(title.c_str(), wndPos, wndPos, size.width, size.height,
188+
commonFlags | SDL_WINDOW_RESIZABLE);
189+
}
176190
}
177191

178192
if(!window)
179193
{
180-
PrintError(SDL_GetError());
194+
PrintError();
181195
return false;
182196
}
183197

184-
const auto flags = SDL_GetWindowFlags(window);
185-
SetFullscreenFlag((flags & SDL_WINDOW_FULLSCREEN) != 0);
186-
SetResizableFlag((flags & SDL_WINDOW_RESIZABLE) != 0);
198+
UpdateCurrentDisplayMode();
187199
UpdateCurrentSizes();
188200

189-
if(!IsFullscreen())
201+
if(displayMode_ != DisplayMode::Fullscreen)
190202
MoveWindowToCenter();
191203

192204
SDL_Surface* iconSurf =
@@ -196,7 +208,7 @@ bool VideoSDL2::CreateScreen(const std::string& title, const VideoMode& size, Di
196208
SDL_SetWindowIcon(window, iconSurf);
197209
SDL_FreeSurface(iconSurf);
198210
} else
199-
PrintError(SDL_GetError());
211+
PrintError();
200212

201213
context = SDL_GL_CreateContext(window);
202214

@@ -216,27 +228,27 @@ bool VideoSDL2::ResizeScreen(const VideoMode& newSize, DisplayMode displayMode)
216228
if(!initialized)
217229
return false;
218230

219-
const auto fullscreen = (displayMode & DisplayMode::Fullscreen) != DisplayMode::None;
220-
const auto resizable = (displayMode & DisplayMode::Resizable) != DisplayMode::None;
221-
222-
if(IsFullscreen() != fullscreen)
223-
{
224-
SDL_SetWindowFullscreen(window, fullscreen ? SDL_WINDOW_FULLSCREEN : 0);
225-
SetFullscreenFlag((SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) != 0);
226-
if(!IsFullscreen())
227-
MoveWindowToCenter();
228-
}
229-
230231
if(displayMode_ != displayMode)
231232
{
232-
if(!IsFullscreen())
233-
SDL_SetWindowResizable(window, static_cast<SDL_bool>(resizable));
234-
SetResizableFlag((SDL_GetWindowFlags(window) & SDL_WINDOW_RESIZABLE) != 0);
235-
}
233+
if(displayMode_ == DisplayMode::Fullscreen || displayMode == DisplayMode::Fullscreen)
234+
{
235+
if(!CHECK_SDL(
236+
SDL_SetWindowFullscreen(window, (displayMode == DisplayMode::Fullscreen) ? SDL_WINDOW_FULLSCREEN : 0)))
237+
{
238+
if(displayMode == DisplayMode::Fullscreen)
239+
displayMode = DisplayMode::BorderlessWindow;
240+
}
241+
}
242+
SDL_SetWindowResizable(window, static_cast<SDL_bool>(displayMode == DisplayMode::Windowed));
243+
SDL_SetWindowBordered(window, static_cast<SDL_bool>(displayMode != DisplayMode::BorderlessWindow));
236244

245+
UpdateCurrentDisplayMode();
246+
if(displayMode_ != DisplayMode::Fullscreen)
247+
MoveWindowToCenter();
248+
}
237249
if(newSize != GetWindowSize())
238250
{
239-
if(IsFullscreen())
251+
if(displayMode_ == DisplayMode::Fullscreen)
240252
{
241253
auto const targetMode = FindClosestVideoMode(newSize);
242254
SDL_DisplayMode target;
@@ -247,22 +259,22 @@ bool VideoSDL2::ResizeScreen(const VideoMode& newSize, DisplayMode displayMode)
247259
target.driverdata = nullptr; // initialize to 0
248260
// Explicitly change the window size to avoid a bug with SDL reporting the wrong size until alt+tab
249261
SDL_SetWindowSize(window, target.w, target.h);
250-
if(SDL_SetWindowDisplayMode(window, &target) < 0)
251-
{
252-
PrintError(SDL_GetError());
262+
if(!CHECK_SDL(SDL_SetWindowDisplayMode(window, &target)))
253263
return false;
254-
}
255264
} else
256-
{
257265
SDL_SetWindowSize(window, newSize.width, newSize.height);
258-
}
259266
UpdateCurrentSizes();
260267
}
261268

262269
return true;
263270
}
264271

265-
void VideoSDL2::PrintError(const std::string& msg) const
272+
void VideoSDL2::PrintError()
273+
{
274+
PrintError(SDL_GetError());
275+
}
276+
277+
void VideoSDL2::PrintError(const std::string& msg)
266278
{
267279
boost::nowide::cerr << msg << std::endl;
268280
}
@@ -320,7 +332,7 @@ bool VideoSDL2::MessageLoop()
320332
{
321333
case SDL_WINDOWEVENT_RESIZED:
322334
{
323-
SetFullscreenFlag((SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) != 0);
335+
UpdateCurrentDisplayMode();
324336
VideoMode newSize(ev.window.data1, ev.window.data2);
325337
if(newSize != GetWindowSize())
326338
{
@@ -515,7 +527,7 @@ void VideoSDL2::ListVideoModes(std::vector<VideoMode>& video_modes) const
515527
{
516528
SDL_DisplayMode mode;
517529
if(SDL_GetDisplayMode(display, i, &mode) != 0)
518-
PrintError(SDL_GetError());
530+
PrintError();
519531
else
520532
{
521533
VideoMode vm(mode.w, mode.h);
@@ -577,3 +589,15 @@ void VideoSDL2::MoveWindowToCenter()
577589
}
578590
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
579591
}
592+
593+
void VideoSDL2::UpdateCurrentDisplayMode()
594+
{
595+
RTTR_Assert(window);
596+
const auto flags = SDL_GetWindowFlags(window);
597+
if(flags & SDL_WINDOW_FULLSCREEN)
598+
displayMode_ = DisplayMode::Fullscreen;
599+
else if((flags & SDL_WINDOW_BORDERLESS) != 0)
600+
displayMode_ = DisplayMode::BorderlessWindow;
601+
else
602+
displayMode_ = DisplayMode::Windowed;
603+
}

extras/videoDrivers/SDL2/VideoSDL2.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2005 - 2021 Settlers Freaks (sf-team at siedler25.org)
1+
// Copyright (C) 2005 - 2026 Settlers Freaks (sf-team at siedler25.org)
22
//
33
// SPDX-License-Identifier: GPL-2.0-or-later
44

@@ -54,10 +54,12 @@ class VideoSDL2 final : public VideoDriver
5454
void* GetMapPointer() const override;
5555

5656
private:
57-
void PrintError(const std::string& msg) const;
57+
static void PrintError();
58+
static void PrintError(const std::string& msg);
5859
void HandlePaste();
5960
void UpdateCurrentSizes();
6061
void MoveWindowToCenter();
62+
void UpdateCurrentDisplayMode();
6163

6264
SDL_Window* window;
6365
SDL_GLContext context;

0 commit comments

Comments
 (0)