1
Feature requests / Re: Ability to toggle fullscreen mode during runtime
« on: February 24, 2024, 05:55:56 pm »SFML only ensures its own states, since it can't know of your custom states, as such it's your responsibility to keep track of your own states.Yep, that's why I'm requesting for a feature to toggle fullscreen mode during runtime, because this is the right way to fix this problem. Users shouldn't have to keep track of their OpenGL state.
glfw, SDL and most of the window/OS event management libraries I know are capable of setting a window to fullscreen, I don't understand why SFML can't.
[/quote]
I found this on The Old New Thing and it works as a nice toggle while maintaining all OpenGL state:
void ToggleFullscreen(sf::Window& window, WINDOWPLACEMENT& g_wpPrev)
{
#ifdef WINDOWS
sf::WindowHandle hwnd = window.getSystemHandle();
DWORD dwStyle = GetWindowLong(hwnd, GWL_STYLE);
if (dwStyle & WS_OVERLAPPEDWINDOW) {
MONITORINFO mi = { sizeof(mi) };
if (GetWindowPlacement(hwnd, &g_wpPrev) &&
GetMonitorInfo(MonitorFromWindow(hwnd,
MONITOR_DEFAULTTOPRIMARY), &mi)) {
SetWindowLong(hwnd, GWL_STYLE,
dwStyle & ~WS_OVERLAPPEDWINDOW);
SetWindowPos(hwnd, HWND_TOP,
mi.rcMonitor.left, mi.rcMonitor.top,
mi.rcMonitor.right - mi.rcMonitor.left,
mi.rcMonitor.bottom - mi.rcMonitor.top,
SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
}
}
else {
SetWindowLong(hwnd, GWL_STYLE,
dwStyle | WS_OVERLAPPEDWINDOW);
SetWindowPlacement(hwnd, &g_wpPrev);
SetWindowPos(hwnd, NULL, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
}
#endif
}
{
#ifdef WINDOWS
sf::WindowHandle hwnd = window.getSystemHandle();
DWORD dwStyle = GetWindowLong(hwnd, GWL_STYLE);
if (dwStyle & WS_OVERLAPPEDWINDOW) {
MONITORINFO mi = { sizeof(mi) };
if (GetWindowPlacement(hwnd, &g_wpPrev) &&
GetMonitorInfo(MonitorFromWindow(hwnd,
MONITOR_DEFAULTTOPRIMARY), &mi)) {
SetWindowLong(hwnd, GWL_STYLE,
dwStyle & ~WS_OVERLAPPEDWINDOW);
SetWindowPos(hwnd, HWND_TOP,
mi.rcMonitor.left, mi.rcMonitor.top,
mi.rcMonitor.right - mi.rcMonitor.left,
mi.rcMonitor.bottom - mi.rcMonitor.top,
SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
}
}
else {
SetWindowLong(hwnd, GWL_STYLE,
dwStyle | WS_OVERLAPPEDWINDOW);
SetWindowPlacement(hwnd, &g_wpPrev);
SetWindowPos(hwnd, NULL, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
}
#endif
}
If you couldn't tell, it is Windows only, but it is quite fast. The only additional setup you need is to keep track of a WINDOWPLACEMENT variable and initialize it with
g_wpPrev.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(window.getSystemHandle(), &g_wpPrev);
GetWindowPlacement(window.getSystemHandle(), &g_wpPrev);
after creating your window.