Skip to content

Commit 71cf658

Browse files
falbrechtskirchingerFlamefire
authored andcommitted
Enable non-resizable windows (SDL2 only)
Add a hidden setting to control whether the window is resizable. Fixes #1512
1 parent 6db0673 commit 71cf658

21 files changed

Lines changed: 226 additions & 85 deletions

File tree

extras/videoDrivers/SDL2/VideoSDL2.cpp

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ void VideoSDL2::UpdateCurrentSizes()
132132
SetNewSize(VideoMode(w, h), Extent(w2, h2));
133133
}
134134

135-
bool VideoSDL2::CreateScreen(const std::string& title, const VideoMode& size, bool fullscreen)
135+
bool VideoSDL2::CreateScreen(const std::string& title, const VideoMode& size, DisplayMode displayMode)
136136
{
137137
if(!initialized)
138138
return false;
@@ -155,16 +155,18 @@ bool VideoSDL2::CreateScreen(const std::string& title, const VideoMode& size, bo
155155
CHECK_SDL(SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8));
156156
CHECK_SDL(SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1));
157157

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

166168
window = SDL_CreateWindow(title.c_str(), wndPos, wndPos, requestedSize.width, requestedSize.height,
167-
commonFlags | (fullscreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_RESIZABLE));
169+
commonFlags | fullscreenFlag);
168170

169171
// Fallback to non-fullscreen
170172
if(!window && fullscreen)
@@ -179,10 +181,12 @@ bool VideoSDL2::CreateScreen(const std::string& title, const VideoMode& size, bo
179181
return false;
180182
}
181183

182-
isFullscreen_ = (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) != 0;
184+
const auto flags = SDL_GetWindowFlags(window);
185+
SetFullscreenFlag((flags & SDL_WINDOW_FULLSCREEN) != 0);
186+
SetResizableFlag((flags & SDL_WINDOW_RESIZABLE) != 0);
183187
UpdateCurrentSizes();
184188

185-
if(!isFullscreen_)
189+
if(!IsFullscreen())
186190
MoveWindowToCenter();
187191

188192
SDL_Surface* iconSurf =
@@ -207,25 +211,32 @@ bool VideoSDL2::CreateScreen(const std::string& title, const VideoMode& size, bo
207211
return true;
208212
}
209213

210-
bool VideoSDL2::ResizeScreen(const VideoMode& newSize, bool fullscreen)
214+
bool VideoSDL2::ResizeScreen(const VideoMode& newSize, DisplayMode displayMode)
211215
{
212216
if(!initialized)
213217
return false;
214218

215-
if(isFullscreen_ != fullscreen)
219+
const auto fullscreen = (displayMode & DisplayMode::Fullscreen) != DisplayMode::None;
220+
const auto resizable = (displayMode & DisplayMode::Resizable) != DisplayMode::None;
221+
222+
if(IsFullscreen() != fullscreen)
216223
{
217224
SDL_SetWindowFullscreen(window, fullscreen ? SDL_WINDOW_FULLSCREEN : 0);
218-
isFullscreen_ = (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) != 0;
219-
if(!isFullscreen_)
220-
{
221-
SDL_SetWindowResizable(window, SDL_TRUE);
225+
SetFullscreenFlag((SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) != 0);
226+
if(!IsFullscreen())
222227
MoveWindowToCenter();
223-
}
228+
}
229+
230+
if(displayMode_ != displayMode)
231+
{
232+
if(!IsFullscreen())
233+
SDL_SetWindowResizable(window, static_cast<SDL_bool>(resizable));
234+
SetResizableFlag((SDL_GetWindowFlags(window) & SDL_WINDOW_RESIZABLE) != 0);
224235
}
225236

226237
if(newSize != GetWindowSize())
227238
{
228-
if(isFullscreen_)
239+
if(IsFullscreen())
229240
{
230241
auto const targetMode = FindClosestVideoMode(newSize);
231242
SDL_DisplayMode target;
@@ -247,6 +258,7 @@ bool VideoSDL2::ResizeScreen(const VideoMode& newSize, bool fullscreen)
247258
}
248259
UpdateCurrentSizes();
249260
}
261+
250262
return true;
251263
}
252264

@@ -308,7 +320,7 @@ bool VideoSDL2::MessageLoop()
308320
{
309321
case SDL_WINDOWEVENT_RESIZED:
310322
{
311-
isFullscreen_ = (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) != 0;
323+
SetFullscreenFlag((SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) != 0);
312324
VideoMode newSize(ev.window.data1, ev.window.data2);
313325
if(newSize != GetWindowSize())
314326
{

extras/videoDrivers/SDL2/VideoSDL2.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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, const VideoMode& size, DisplayMode displayMode) override;
28+
bool ResizeScreen(const VideoMode& newSize, DisplayMode displayMode) override;
2929

3030
void DestroyScreen() override;
3131

extras/videoDrivers/WinAPI/WinAPI.cpp

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -139,26 +139,25 @@ void VideoWinAPI::CleanUp()
139139
/**
140140
* Erstellt das Fenster mit entsprechenden Werten.
141141
*
142-
* @param[in] width Breite des Fensters
143-
* @param[in] height Höhe des Fensters
144-
* @param[in] fullscreen Vollbildmodus ja oder nein
142+
* @param[in] width Breite des Fensters
143+
* @param[in] height Höhe des Fensters
144+
* @param[in] displayMode Fullscreen on/off, window resizable?
145145
*
146146
* @return @p true bei Erfolg, @p false bei Fehler
147147
*
148148
* @bug Hardwarecursor ist bei Fenstermodus sichtbar,
149149
* Cursor deaktivieren ist fehlerhaft
150150
*/
151-
bool VideoWinAPI::CreateScreen(const std::string& title, const VideoMode& newSize, bool fullscreen)
151+
bool VideoWinAPI::CreateScreen(const std::string& title, const VideoMode& newSize, DisplayMode displayMode)
152152
{
153153
if(!initialized)
154154
return false;
155155

156-
if(!RegisterAndCreateWindow(title, newSize, fullscreen))
156+
if(!RegisterAndCreateWindow(title, newSize, displayMode))
157157
return false;
158158

159-
if(fullscreen && !MakeFullscreen(GetWindowSize()))
159+
if(bitset::isSet(displayMode, DisplayMode::Fullscreen) && !MakeFullscreen(GetWindowSize()))
160160
return false;
161-
isFullscreen_ = fullscreen;
162161

163162
if(!InitOGL())
164163
return false;
@@ -184,30 +183,31 @@ bool VideoWinAPI::CreateScreen(const std::string& title, const VideoMode& newSiz
184183
*
185184
* @todo Vollbildmodus ggf. wechseln
186185
*/
187-
bool VideoWinAPI::ResizeScreen(const VideoMode& newSize, bool fullscreen)
186+
bool VideoWinAPI::ResizeScreen(const VideoMode& newSize, DisplayMode displayMode)
188187
{
189188
if(!initialized || !isWindowResizable)
190189
return false;
191190

192-
if(isFullscreen_ == fullscreen && newSize == GetWindowSize())
191+
const auto fullscreen = bitset::isSet(displayMode, DisplayMode::Fullscreen);
192+
if(IsFullscreen() == fullscreen && newSize == GetWindowSize())
193193
return true;
194194

195195
ShowWindow(screen, SW_HIDE);
196196

197197
VideoMode windowSize = fullscreen ? FindClosestVideoMode(newSize) : newSize;
198198
// Try to switch full screen first
199-
if(isFullscreen_ && !fullscreen)
199+
if(IsFullscreen() && !fullscreen)
200200
{
201201
if(ChangeDisplaySettings(nullptr, 0) != DISP_CHANGE_SUCCESSFUL)
202202
return false;
203-
} else if(isFullscreen_ || fullscreen)
203+
} else if(IsFullscreen() || fullscreen)
204204
{
205205
if(!MakeFullscreen(windowSize))
206206
return false;
207207
}
208208

209209
// Fensterstyle ggf. ändern
210-
std::pair<DWORD, DWORD> style = GetStyleFlags(isFullscreen_);
210+
std::pair<DWORD, DWORD> style = GetStyleFlags(IsFullscreen());
211211
SetWindowLongPtr(screen, GWL_STYLE, style.first);
212212
SetWindowLongPtr(screen, GWL_EXSTYLE, style.second);
213213

@@ -263,7 +263,7 @@ RECT VideoWinAPI::CalculateWindowRect(bool fullscreen, VideoMode& size) const
263263
return wRect;
264264
}
265265

266-
bool VideoWinAPI::RegisterAndCreateWindow(const std::string& title, const VideoMode& wndSize, bool fullscreen)
266+
bool VideoWinAPI::RegisterAndCreateWindow(const std::string& title, const VideoMode& wndSize, DisplayMode displayMode)
267267
{
268268
std::wstring wTitle = boost::nowide::widen(title);
269269
windowClassName = wTitle.substr(0, wTitle.find(' '));
@@ -285,6 +285,7 @@ bool VideoWinAPI::RegisterAndCreateWindow(const std::string& title, const VideoM
285285
return false;
286286

287287
// Create window
288+
const auto fullscreen = bitset::isSet(displayMode, DisplayMode::Fullscreen);
288289
auto adjWindowSize = fullscreen ? FindClosestVideoMode(wndSize) : wndSize;
289290
RECT wRect = CalculateWindowRect(fullscreen, adjWindowSize);
290291

@@ -415,7 +416,7 @@ void VideoWinAPI::DestroyScreen()
415416

416417
UnregisterClassW(windowClassName.c_str(), GetModuleHandle(nullptr));
417418

418-
isFullscreen_ = false;
419+
displayMode_ = bitset::set(displayMode_, DisplayMode::Fullscreen, false);
419420
}
420421

421422
/**

extras/videoDrivers/WinAPI/WinAPI.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ class VideoWinAPI final : public VideoDriver
3030
bool Initialize() override;
3131

3232
/// Erstellt das Fenster mit entsprechenden Werten.
33-
bool CreateScreen(const std::string& title, const VideoMode& newSize, bool fullscreen) override;
33+
bool CreateScreen(const std::string& title, const VideoMode& newSize, DisplayMode displayMode) override;
3434

3535
/// Erstellt oder verändert das Fenster mit entsprechenden Werten.
36-
bool ResizeScreen(const VideoMode& newSize, bool fullscreen) override;
36+
bool ResizeScreen(const VideoMode& newSize, DisplayMode displayMode) override;
3737

3838
/// Schliesst das Fenster.
3939
void DestroyScreen() override;
@@ -69,7 +69,7 @@ class VideoWinAPI final : public VideoDriver
6969
std::pair<DWORD, DWORD> GetStyleFlags(bool fullscreen) const;
7070
/// Calculate the rect for the window and adjusts the (usable) size if required
7171
RECT CalculateWindowRect(bool fullscreen, VideoMode& size) const;
72-
bool RegisterAndCreateWindow(const std::string& title, const VideoMode& wndSize, bool fullscreen);
72+
bool RegisterAndCreateWindow(const std::string& title, const VideoMode& wndSize, DisplayMode displayMode);
7373
bool InitOGL();
7474
static bool MakeFullscreen(const VideoMode& resolution);
7575

libs/driver/include/driver/VideoDriver.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ class VideoDriver : public IVideoDriver
3232

3333
VideoMode GetWindowSize() const override final { return windowSize_; }
3434
Extent GetRenderSize() const override final { return scaledRenderSize_; }
35-
bool IsFullscreen() const override final { return isFullscreen_; }
35+
DisplayMode GetDisplayMode() const override final { return displayMode_; }
36+
bool IsFullscreen() const override final { return bitset::isSet(displayMode_, DisplayMode::Fullscreen); }
37+
bool IsResizable() const override final { return bitset::isSet(displayMode_, DisplayMode::Fullscreen); }
3638

3739
float getDpiScale() const override final { return dpiScale_; }
3840

@@ -49,11 +51,21 @@ class VideoDriver : public IVideoDriver
4951
VideoMode FindClosestVideoMode(const VideoMode& mode) const;
5052
void SetNewSize(VideoMode windowSize, Extent renderSize);
5153

54+
void SetFullscreenFlag(bool fullscreen)
55+
{
56+
displayMode_ =
57+
fullscreen ? (displayMode_ | DisplayMode::Fullscreen) : (displayMode_ & ~DisplayMode::Fullscreen);
58+
}
59+
void SetResizableFlag(bool resizable)
60+
{
61+
displayMode_ = bitset::set(displayMode_, DisplayMode::Resizable, resizable);
62+
}
63+
5264
VideoDriverLoaderInterface* CallBack; /// Das DriverCallback für Rückmeldungen.
5365
bool initialized; /// Initialisierungsstatus.
5466
MouseCoords mouse_xy; /// Status der Maus.
5567
std::array<bool, 512> keyboard; /// Status der Tastatur;
56-
bool isFullscreen_; /// Vollbild an/aus?
68+
DisplayMode displayMode_; /// Fullscreen/resizable?
5769
private:
5870
// cached as possibly used often
5971
VideoMode windowSize_; ///< Size of the window or fullscreen resolution

libs/driver/include/driver/VideoInterface.h

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,96 @@
99
#include "Point.h"
1010
#include "VideoMode.h"
1111
#include "exportImport.h"
12+
// #include "s25util/enumUtils.h"
1213
#include <string>
14+
#include <type_traits>
1315
#include <vector>
1416

1517
/// Function type for loading OpenGL methods
1618
using OpenGL_Loader_Proc = void* (*)(const char*);
1719

20+
template<typename Enum>
21+
struct IsBitset : std::false_type
22+
{};
23+
24+
template<typename Enum>
25+
using IsValidBitset =
26+
std::integral_constant<bool, IsBitset<Enum>::value && std::is_unsigned<std::underlying_type_t<Enum>>::value>;
27+
28+
template<typename Enum, std::enable_if_t<IsValidBitset<Enum>::value, int> = 0>
29+
constexpr auto operator~(Enum val) noexcept
30+
{
31+
using T = std::underlying_type_t<Enum>;
32+
return Enum(~static_cast<T>(val));
33+
}
34+
35+
template<typename Enum, std::enable_if_t<IsValidBitset<Enum>::value, int> = 0>
36+
constexpr auto operator&(Enum lhs, Enum rhs) noexcept
37+
{
38+
using T = std::underlying_type_t<Enum>;
39+
return Enum(static_cast<T>(lhs) & static_cast<T>(rhs));
40+
}
41+
42+
template<typename Enum, std::enable_if_t<IsValidBitset<Enum>::value, int> = 0>
43+
constexpr auto operator|(Enum lhs, Enum rhs) noexcept
44+
{
45+
using T = std::underlying_type_t<Enum>;
46+
return Enum(static_cast<T>(lhs) | static_cast<T>(rhs));
47+
}
48+
49+
template<typename Enum, std::enable_if_t<IsValidBitset<Enum>::value, int> = 0>
50+
constexpr auto operator^(Enum lhs, Enum rhs) noexcept
51+
{
52+
using T = std::underlying_type_t<Enum>;
53+
return Enum(static_cast<T>(lhs) ^ static_cast<T>(rhs));
54+
}
55+
56+
template<typename Enum, std::enable_if_t<IsValidBitset<Enum>::value, int> = 0>
57+
constexpr auto operator&=(Enum& lhs, Enum rhs) noexcept
58+
{
59+
lhs = lhs & rhs;
60+
return lhs;
61+
}
62+
63+
template<typename Enum, std::enable_if_t<IsValidBitset<Enum>::value, int> = 0>
64+
constexpr auto operator|=(Enum& lhs, Enum rhs) noexcept
65+
{
66+
lhs = lhs | rhs;
67+
return lhs;
68+
}
69+
70+
template<typename Enum, std::enable_if_t<IsValidBitset<Enum>::value, int> = 0>
71+
constexpr auto operator^=(Enum& lhs, Enum rhs) noexcept
72+
{
73+
lhs = lhs ^ rhs;
74+
return lhs;
75+
}
76+
77+
namespace bitset {
78+
template<typename Enum, std::enable_if_t<IsValidBitset<Enum>::value, int> = 0>
79+
constexpr bool isSet(Enum val, Enum flag)
80+
{
81+
return (val & flag) != Enum(0);
82+
}
83+
84+
template<typename Enum, std::enable_if_t<IsValidBitset<Enum>::value, int> = 0>
85+
[[nodiscard]] constexpr Enum set(Enum val, Enum flag, bool state)
86+
{
87+
return state ? (val | flag) : (val & ~flag);
88+
}
89+
} // namespace bitset
90+
91+
enum class DisplayMode : unsigned
92+
{
93+
None,
94+
Fullscreen = (1 << 0),
95+
Resizable = (1 << 1)
96+
};
97+
98+
template<>
99+
struct IsBitset<DisplayMode> : std::true_type
100+
{};
101+
18102
class BOOST_SYMBOL_VISIBLE IVideoDriver
19103
{
20104
public:
@@ -26,9 +110,9 @@ class BOOST_SYMBOL_VISIBLE IVideoDriver
26110
virtual bool Initialize() = 0;
27111

28112
/// Erstellt das Fenster mit entsprechenden Werten.
29-
virtual bool CreateScreen(const std::string& title, const VideoMode& newSize, bool fullscreen) = 0;
113+
virtual bool CreateScreen(const std::string& title, const VideoMode& newSize, DisplayMode displayMode) = 0;
30114

31-
virtual bool ResizeScreen(const VideoMode& newSize, bool fullscreen) = 0;
115+
virtual bool ResizeScreen(const VideoMode& newSize, DisplayMode displayMode) = 0;
32116

33117
/// Schliesst das Fenster.
34118
virtual void DestroyScreen() = 0;
@@ -64,7 +148,9 @@ class BOOST_SYMBOL_VISIBLE IVideoDriver
64148
virtual VideoMode GetWindowSize() const = 0;
65149
/// Get the size of the render region in pixels
66150
virtual Extent GetRenderSize() const = 0;
151+
virtual DisplayMode GetDisplayMode() const = 0;
67152
virtual bool IsFullscreen() const = 0;
153+
virtual bool IsResizable() const = 0;
68154

69155
/// Get the factor required to scale "normal" DPI to the display DPI
70156
virtual float getDpiScale() const = 0;

libs/driver/src/VideoDriver.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ IVideoDriver::~IVideoDriver() = default;
1919
* @param[in] CallBack DriverCallback für Rückmeldungen.
2020
*/
2121
VideoDriver::VideoDriver(VideoDriverLoaderInterface* CallBack)
22-
: CallBack(CallBack), initialized(false), isFullscreen_(false), renderSize_(0, 0), scaledRenderSize_(0, 0),
23-
dpiScale_(1.f), guiScale_(100), autoGuiScale_(false)
22+
: CallBack(CallBack), initialized(false), displayMode_(DisplayMode::Resizable), renderSize_(0, 0),
23+
scaledRenderSize_(0, 0), dpiScale_(1.f), guiScale_(100), autoGuiScale_(false)
2424
{
2525
std::fill(keyboard.begin(), keyboard.end(), false);
2626
}

0 commit comments

Comments
 (0)