Skip to content

Commit dc0a4a5

Browse files
authored
Merge pull request #1890 from Flamefire/lock-window-size
2 parents 45e8bc0 + 70c42b3 commit dc0a4a5

67 files changed

Lines changed: 1247 additions & 1168 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

data/RTTR/texte/de/keyboardlayout.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ F1:................... (Spiel laden)
2828
F2:................... Spiel speichern
2929
F8:................... Tastaturbelegung anzeigen
3030
F9:................... ReadMe-Datei anzeigen
31+
F10:.................. Einstellungen (UI, ...)
3132
F11:.................. Musik-Spieler
3233
F12:.................. Kontrollfenster
3334

@@ -47,6 +48,6 @@ P:.................... Pause/Fortsetzen (Auch nach GF Sprung)
4748
1-7:.................. Spielerwechsel
4849

4950
------------------------------------------------------------------------
50-
https://www.siedler25.org Copyright (C) 2005-2022 Settlers Freaks
51+
https://www.siedler25.org Copyright (C) 2005-2026 Settlers Freaks
5152
------------------------------------------------------------------------
5253

data/RTTR/texte/keyboardlayout.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ F1:................... (Load game)
2828
F2:................... Save game
2929
F8:................... Readme "Keyboard layout"
3030
F9:................... Readme
31+
F10:.................. Settings (UI, ...)
3132
F11:.................. Musicplayer
3233
F12:.................. Options window
3334

@@ -46,5 +47,5 @@ J:.................... Go to specific GF
4647
P:.................... Pause/Resume (also after GF jump)
4748
1-7:.................. Change to other player
4849
------------------------------------------------------------------------
49-
https://www.siedler25.org Copyright (C) 2005-2022 Settlers Freaks
50+
https://www.siedler25.org Copyright (C) 2005-2026 Settlers Freaks
5051
------------------------------------------------------------------------

extras/videoDrivers/SDL2/VideoSDL2.cpp

Lines changed: 119 additions & 61 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,18 @@
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-
})()
43-
4435
namespace {
36+
37+
/// Check that the (SDL) call returns success or print the error
38+
/// Can be used in conditions: if(CHECK_SDL(SDL_Foo()))
39+
bool CHECK_SDL(int sdlResult)
40+
{
41+
if(sdlResult >= 0)
42+
return true;
43+
VideoSDL2::PrintError();
44+
return false;
45+
}
46+
4547
template<typename T>
4648
struct SDLMemoryDeleter
4749
{
@@ -100,13 +102,9 @@ bool VideoSDL2::Initialize()
100102
rttr::ScopedLeakDisabler _;
101103
// Do not emulate mouse events using touch
102104
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
103-
if(SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
104-
{
105-
PrintError(SDL_GetError());
106-
return false;
107-
}
105+
if(CHECK_SDL(SDL_InitSubSystem(SDL_INIT_VIDEO)))
106+
initialized = true;
108107

109-
initialized = true;
110108
return initialized;
111109
}
112110

@@ -132,7 +130,16 @@ void VideoSDL2::UpdateCurrentSizes()
132130
SetNewSize(VideoMode(w, h), Extent(w2, h2));
133131
}
134132

135-
bool VideoSDL2::CreateScreen(const std::string& title, const VideoMode& size, bool fullscreen)
133+
static VideoMode getDesktopSize(SDL_Window* window, VideoMode fallback)
134+
{
135+
const int display = window ? std::max(0, SDL_GetWindowDisplayIndex(window)) : 0;
136+
SDL_DisplayMode dskSize;
137+
if(CHECK_SDL(SDL_GetDesktopDisplayMode(display, &dskSize)))
138+
return VideoMode(dskSize.w, dskSize.h);
139+
return fallback;
140+
}
141+
142+
bool VideoSDL2::CreateScreen(const std::string& title, const VideoMode size, DisplayMode displayMode)
136143
{
137144
if(!initialized)
138145
return false;
@@ -155,34 +162,45 @@ bool VideoSDL2::CreateScreen(const std::string& title, const VideoMode& size, bo
155162
CHECK_SDL(SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8));
156163
CHECK_SDL(SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1));
157164

158-
int wndPos = SDL_WINDOWPOS_CENTERED;
159-
160-
const auto requestedSize = fullscreen ? FindClosestVideoMode(size) : size;
161-
unsigned commonFlags = SDL_WINDOW_OPENGL;
165+
const int wndPos = SDL_WINDOWPOS_CENTERED;
166+
const unsigned commonFlags = SDL_WINDOW_OPENGL;
162167
// TODO: Fix GUI scaling with High DPI support enabled.
163168
// See https://github.com/Return-To-The-Roots/s25client/issues/1621
164169
// commonFlags |= SDL_WINDOW_ALLOW_HIGHDPI;
165170

166-
window = SDL_CreateWindow(title.c_str(), wndPos, wndPos, requestedSize.width, requestedSize.height,
167-
commonFlags | (fullscreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_RESIZABLE));
168-
169-
// Fallback to non-fullscreen
170-
if(!window && fullscreen)
171+
unsigned windowTypeFlag = 0;
172+
auto requestedSize = size;
173+
if(displayMode == DisplayMode::Fullscreen)
171174
{
172-
window = SDL_CreateWindow(title.c_str(), wndPos, wndPos, requestedSize.width, requestedSize.height,
173-
commonFlags | SDL_WINDOW_RESIZABLE);
174-
}
175+
windowTypeFlag = SDL_WINDOW_FULLSCREEN;
176+
requestedSize = FindClosestVideoMode(size);
177+
} else if(displayMode == DisplayMode::BorderlessWindow)
178+
{
179+
windowTypeFlag = SDL_WINDOW_BORDERLESS;
180+
requestedSize = getDesktopSize(nullptr, size);
181+
} else if(displayMode.resizeable)
182+
windowTypeFlag = SDL_WINDOW_RESIZABLE;
183+
184+
window = SDL_CreateWindow(title.c_str(), wndPos, wndPos, requestedSize.width, requestedSize.height,
185+
commonFlags | windowTypeFlag);
175186

176187
if(!window)
177188
{
178-
PrintError(SDL_GetError());
189+
PrintError();
190+
// Fallback to borderless fullscreen if unable to set resolution
191+
if(displayMode == DisplayMode::Fullscreen)
192+
return CreateScreen(title, size, DisplayMode::BorderlessWindow);
193+
// No borderless -> Resizable window as last fallback to at least show something
194+
if(displayMode == DisplayMode::BorderlessWindow)
195+
return CreateScreen(title, size, DisplayMode::Windowed);
196+
PrintError();
179197
return false;
180198
}
181199

182-
isFullscreen_ = (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) != 0;
200+
UpdateCurrentDisplayMode();
183201
UpdateCurrentSizes();
184202

185-
if(!isFullscreen_)
203+
if(displayMode != DisplayMode::Fullscreen)
186204
MoveWindowToCenter();
187205

188206
SDL_Surface* iconSurf =
@@ -192,7 +210,7 @@ bool VideoSDL2::CreateScreen(const std::string& title, const VideoMode& size, bo
192210
SDL_SetWindowIcon(window, iconSurf);
193211
SDL_FreeSurface(iconSurf);
194212
} else
195-
PrintError(SDL_GetError());
213+
PrintError();
196214

197215
context = SDL_GL_CreateContext(window);
198216

@@ -207,50 +225,67 @@ bool VideoSDL2::CreateScreen(const std::string& title, const VideoMode& size, bo
207225
return true;
208226
}
209227

210-
bool VideoSDL2::ResizeScreen(const VideoMode& newSize, bool fullscreen)
228+
bool VideoSDL2::ResizeScreen(VideoMode newSize, DisplayMode displayMode)
211229
{
212230
if(!initialized)
213231
return false;
214232

215-
if(isFullscreen_ != fullscreen)
233+
bool centerWindow = false;
234+
235+
if(displayMode_ != displayMode)
216236
{
217-
SDL_SetWindowFullscreen(window, fullscreen ? SDL_WINDOW_FULLSCREEN : 0);
218-
isFullscreen_ = (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) != 0;
219-
if(!isFullscreen_)
237+
if(displayMode_ == DisplayMode::Fullscreen || displayMode == DisplayMode::Fullscreen)
220238
{
221-
SDL_SetWindowResizable(window, SDL_TRUE);
222-
MoveWindowToCenter();
239+
if(!CHECK_SDL(
240+
SDL_SetWindowFullscreen(window, (displayMode == DisplayMode::Fullscreen) ? SDL_WINDOW_FULLSCREEN : 0)))
241+
{
242+
if(displayMode == DisplayMode::Fullscreen)
243+
displayMode = DisplayMode::BorderlessWindow;
244+
}
223245
}
224-
}
246+
SDL_SetWindowResizable(window,
247+
static_cast<SDL_bool>(displayMode == DisplayMode::Windowed && displayMode.resizeable));
248+
SDL_SetWindowBordered(window, static_cast<SDL_bool>(displayMode == DisplayMode::Windowed));
225249

250+
UpdateCurrentDisplayMode();
251+
centerWindow = true;
252+
}
253+
if(displayMode_ == DisplayMode::BorderlessWindow)
254+
newSize = getDesktopSize(nullptr, newSize);
226255
if(newSize != GetWindowSize())
227256
{
228-
if(isFullscreen_)
257+
if(displayMode_ == DisplayMode::Fullscreen)
229258
{
230259
auto const targetMode = FindClosestVideoMode(newSize);
231260
SDL_DisplayMode target;
232261
target.w = targetMode.width;
233262
target.h = targetMode.height;
234-
target.format = 0; // don't care
235-
target.refresh_rate = 0; // don't care
236-
target.driverdata = nullptr; // initialize to 0
263+
target.format = 0; // don't care
264+
target.refresh_rate = 0; // don't care
265+
target.driverdata = nullptr;
237266
// Explicitly change the window size to avoid a bug with SDL reporting the wrong size until alt+tab
238267
SDL_SetWindowSize(window, target.w, target.h);
239-
if(SDL_SetWindowDisplayMode(window, &target) < 0)
240-
{
241-
PrintError(SDL_GetError());
268+
if(!CHECK_SDL(SDL_SetWindowDisplayMode(window, &target)))
242269
return false;
243-
}
244270
} else
245271
{
246272
SDL_SetWindowSize(window, newSize.width, newSize.height);
273+
centerWindow = true;
247274
}
248275
UpdateCurrentSizes();
249276
}
277+
if(centerWindow)
278+
MoveWindowToCenter();
279+
250280
return true;
251281
}
252282

253-
void VideoSDL2::PrintError(const std::string& msg) const
283+
void VideoSDL2::PrintError()
284+
{
285+
PrintError(SDL_GetError());
286+
}
287+
288+
void VideoSDL2::PrintError(const std::string& msg)
254289
{
255290
boost::nowide::cerr << msg << std::endl;
256291
}
@@ -308,7 +343,7 @@ bool VideoSDL2::MessageLoop()
308343
{
309344
case SDL_WINDOWEVENT_RESIZED:
310345
{
311-
isFullscreen_ = (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) != 0;
346+
UpdateCurrentDisplayMode();
312347
VideoMode newSize(ev.window.data1, ev.window.data2);
313348
if(newSize != GetWindowSize())
314349
{
@@ -508,23 +543,25 @@ unsigned long VideoSDL2::GetTickCount() const
508543
return SDL_GetTicks();
509544
}
510545

511-
void VideoSDL2::ListVideoModes(std::vector<VideoMode>& video_modes) const
546+
std::vector<VideoMode> VideoSDL2::ListVideoModes() const
512547
{
513548
int display = SDL_GetWindowDisplayIndex(window);
514549
if(display < 0)
515550
display = 0;
551+
std::vector<VideoMode> video_modes;
516552
for(int i = SDL_GetNumDisplayModes(display) - 1; i >= 0; --i)
517553
{
518554
SDL_DisplayMode mode;
519555
if(SDL_GetDisplayMode(display, i, &mode) != 0)
520-
PrintError(SDL_GetError());
556+
PrintError();
521557
else
522558
{
523559
VideoMode vm(mode.w, mode.h);
524560
if(!helpers::contains(video_modes, vm))
525561
video_modes.push_back(vm);
526562
}
527563
}
564+
return video_modes;
528565
}
529566

530567
OpenGL_Loader_Proc VideoSDL2::GetLoaderFunction() const
@@ -565,17 +602,38 @@ void* VideoSDL2::GetMapPointer() const
565602

566603
void VideoSDL2::MoveWindowToCenter()
567604
{
605+
SDL_PumpEvents(); // Let window system run update events/initialization
606+
const int display = window ? std::max(0, SDL_GetWindowDisplayIndex(window)) : 0;
607+
568608
SDL_Rect usableBounds;
569-
CHECK_SDL(SDL_GetDisplayUsableBounds(SDL_GetWindowDisplayIndex(window), &usableBounds));
609+
CHECK_SDL(SDL_GetDisplayUsableBounds(display, &usableBounds));
570610
int top, left, bottom, right;
571-
if(CHECK_SDL(SDL_GetWindowBordersSize(window, &top, &left, &bottom, &right)) != 0)
611+
if(!CHECK_SDL(SDL_GetWindowBordersSize(window, &top, &left, &bottom, &right)))
572612
top = left = bottom = right = 0;
573-
usableBounds.w -= left + right;
574-
usableBounds.h -= top + bottom;
575-
if(usableBounds.w < GetWindowSize().width || usableBounds.h < GetWindowSize().height)
613+
auto wndOuterSize = GetWindowSize();
614+
wndOuterSize.width += left + right;
615+
wndOuterSize.height += top + bottom;
616+
if(usableBounds.w < wndOuterSize.width || usableBounds.h < wndOuterSize.height)
576617
{
577-
SDL_SetWindowSize(window, usableBounds.w, usableBounds.h);
618+
SDL_SetWindowSize(window, usableBounds.w - left - right, usableBounds.h - top - bottom);
578619
UpdateCurrentSizes();
620+
wndOuterSize.width = usableBounds.w;
621+
wndOuterSize.height = usableBounds.h;
579622
}
580-
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
623+
const int x = usableBounds.x + (usableBounds.w - wndOuterSize.width) / 2 + left;
624+
const int y = usableBounds.y + (usableBounds.h - wndOuterSize.height) / 2 + top;
625+
SDL_SetWindowPosition(window, x, y);
626+
}
627+
628+
void VideoSDL2::UpdateCurrentDisplayMode()
629+
{
630+
RTTR_Assert(window);
631+
const auto flags = SDL_GetWindowFlags(window);
632+
if(flags & SDL_WINDOW_FULLSCREEN)
633+
displayMode_ = DisplayMode::Fullscreen;
634+
else if((flags & SDL_WINDOW_BORDERLESS) != 0)
635+
displayMode_ = DisplayMode::BorderlessWindow;
636+
else
637+
displayMode_ = DisplayMode::Windowed;
638+
displayMode_.resizeable = (flags & SDL_WINDOW_RESIZABLE) != 0;
581639
}

extras/videoDrivers/SDL2/VideoSDL2.h

Lines changed: 9 additions & 6 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

@@ -24,8 +24,8 @@ class VideoSDL2 final : public VideoDriver
2424

2525
bool Initialize() override;
2626

27-
bool CreateScreen(const std::string& title, const VideoMode& size, bool fullscreen) override;
28-
bool ResizeScreen(const VideoMode& newSize, bool fullscreen) override;
27+
bool CreateScreen(const std::string& title, VideoMode size, DisplayMode displayMode) override;
28+
bool ResizeScreen(VideoMode newSize, DisplayMode displayMode) override;
2929

3030
void DestroyScreen() override;
3131

@@ -41,8 +41,8 @@ class VideoSDL2 final : public VideoDriver
4141

4242
OpenGL_Loader_Proc GetLoaderFunction() const override;
4343

44-
/// Add supported video modes
45-
void ListVideoModes(std::vector<VideoMode>& video_modes) const override;
44+
/// Get supported video modes
45+
std::vector<VideoMode> ListVideoModes() const override;
4646

4747
/// Set mouse position
4848
void SetMousePos(Position pos) override;
@@ -53,11 +53,14 @@ class VideoSDL2 final : public VideoDriver
5353
/// Get (device-dependent!) window pointer, HWND in Windows
5454
void* GetMapPointer() const override;
5555

56+
static void PrintError();
57+
static void PrintError(const std::string& msg);
58+
5659
private:
57-
void PrintError(const std::string& msg) const;
5860
void HandlePaste();
5961
void UpdateCurrentSizes();
6062
void MoveWindowToCenter();
63+
void UpdateCurrentDisplayMode();
6164

6265
SDL_Window* window;
6366
SDL_GLContext context;

0 commit comments

Comments
 (0)