mirror of
https://github.com/glfw/glfw.git
synced 2025-10-04 05:36:35 +00:00
Add option to toggle between fullscreen and window mode on Win32
This commit is contained in:
parent
d030b88c86
commit
061c273da6
@ -614,6 +614,7 @@ extern "C" {
|
||||
#define GLFW_DECORATED 0x00020005
|
||||
#define GLFW_AUTO_ICONIFY 0x00020006
|
||||
#define GLFW_FLOATING 0x00020007
|
||||
#define GLFW_FULLSCREEN 0x00020008
|
||||
|
||||
#define GLFW_RED_BITS 0x00021001
|
||||
#define GLFW_GREEN_BITS 0x00021002
|
||||
@ -2101,6 +2102,18 @@ GLFWAPI void glfwShowWindow(GLFWwindow* window);
|
||||
*/
|
||||
GLFWAPI void glfwHideWindow(GLFWwindow* window);
|
||||
|
||||
/*! @brief Toggles between fullscreen and windowed mode on the specified window.
|
||||
*
|
||||
* The functions enters fullscreen mode if the specified window was previously
|
||||
* in windowed mode. If the window is already in fullscreen mode, the fuctions restores
|
||||
* the monitor video mode and the specified window switches back to windowed mode.
|
||||
*
|
||||
* @param[in] window The window to toggle his mode.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
GLFWAPI void glfwToggleWindowFullscreen(GLFWwindow* window);
|
||||
|
||||
/*! @brief Returns the monitor that the window uses for full screen mode.
|
||||
*
|
||||
* This function returns the handle of the monitor that the specified window is
|
||||
|
@ -178,6 +178,7 @@ struct _GLFWwndconfig
|
||||
GLFWbool focused;
|
||||
GLFWbool autoIconify;
|
||||
GLFWbool floating;
|
||||
GLFWbool fullscreen;
|
||||
_GLFWmonitor* monitor;
|
||||
};
|
||||
|
||||
@ -245,6 +246,7 @@ struct _GLFWwindow
|
||||
GLFWbool autoIconify;
|
||||
GLFWbool floating;
|
||||
GLFWbool closed;
|
||||
GLFWbool fullscreen;
|
||||
void* userPointer;
|
||||
GLFWvidmode videoMode;
|
||||
_GLFWmonitor* monitor;
|
||||
@ -584,6 +586,11 @@ void _glfwPlatformUnhideWindow(_GLFWwindow* window);
|
||||
*/
|
||||
void _glfwPlatformHideWindow(_GLFWwindow* window);
|
||||
|
||||
/*! @copydoc glfwToggleWindowFullscreen
|
||||
* @ingroup platform
|
||||
*/
|
||||
void _glfwPlatformToggleWindowFullscreen(_GLFWwindow* window);
|
||||
|
||||
/*! @brief Returns whether the window is focused.
|
||||
* @ingroup platform
|
||||
*/
|
||||
|
@ -600,7 +600,7 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
|
||||
void _glfwPlatformSwapBuffers(_GLFWwindow* window)
|
||||
{
|
||||
// HACK: Use DwmFlush when desktop composition is enabled
|
||||
if (_glfwIsCompositionEnabled() && !window->monitor)
|
||||
if (_glfwIsCompositionEnabled() && !window->fullscreen)
|
||||
{
|
||||
int count = abs(window->wgl.interval);
|
||||
while (count--)
|
||||
@ -618,7 +618,7 @@ void _glfwPlatformSwapInterval(int interval)
|
||||
|
||||
// HACK: Disable WGL swap interval when desktop composition is enabled to
|
||||
// avoid interfering with DWM vsync
|
||||
if (_glfwIsCompositionEnabled() && !window->monitor)
|
||||
if (_glfwIsCompositionEnabled() && !window->fullscreen)
|
||||
interval = 0;
|
||||
|
||||
if (window->wgl.EXT_swap_control)
|
||||
|
@ -44,7 +44,7 @@ static DWORD getWindowStyle(const _GLFWwindow* window)
|
||||
{
|
||||
DWORD style = WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
|
||||
|
||||
if (window->decorated && !window->monitor)
|
||||
if (window->decorated && !window->fullscreen)
|
||||
{
|
||||
style |= WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
|
||||
|
||||
@ -63,7 +63,7 @@ static DWORD getWindowExStyle(const _GLFWwindow* window)
|
||||
{
|
||||
DWORD style = WS_EX_APPWINDOW;
|
||||
|
||||
if (window->decorated && !window->monitor)
|
||||
if (window->decorated && !window->fullscreen)
|
||||
style |= WS_EX_WINDOWEDGE;
|
||||
|
||||
return style;
|
||||
@ -224,15 +224,24 @@ static int translateKey(WPARAM wParam, LPARAM lParam)
|
||||
return _glfw.win32.publicKeys[HIWORD(lParam) & 0x1FF];
|
||||
}
|
||||
|
||||
static void updateWindowStyle(_GLFWwindow* window)
|
||||
{
|
||||
SetWindowLongPtr(window->win32.handle, GWL_EXSTYLE, getWindowExStyle(window));
|
||||
SetWindowLongPtr(window->win32.handle, GWL_STYLE, getWindowStyle(window));
|
||||
|
||||
_glfwPlatformShowWindow(window);
|
||||
}
|
||||
|
||||
// Enter full screen mode
|
||||
//
|
||||
static GLFWbool enterFullscreenMode(_GLFWwindow* window)
|
||||
{
|
||||
GLFWvidmode mode;
|
||||
GLFWbool status;
|
||||
int xpos, ypos;
|
||||
|
||||
status = _glfwSetVideoMode(window->monitor, &window->videoMode);
|
||||
window->fullscreen = _glfwSetVideoMode(window->monitor, &window->videoMode);
|
||||
|
||||
updateWindowStyle(window);
|
||||
|
||||
_glfwPlatformGetVideoMode(window->monitor, &mode);
|
||||
_glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos);
|
||||
@ -240,7 +249,7 @@ static GLFWbool enterFullscreenMode(_GLFWwindow* window)
|
||||
SetWindowPos(window->win32.handle, HWND_TOPMOST,
|
||||
xpos, ypos, mode.width, mode.height, SWP_NOCOPYBITS);
|
||||
|
||||
return status;
|
||||
return window->fullscreen;
|
||||
}
|
||||
|
||||
// Leave full screen mode
|
||||
@ -248,6 +257,10 @@ static GLFWbool enterFullscreenMode(_GLFWwindow* window)
|
||||
static void leaveFullscreenMode(_GLFWwindow* window)
|
||||
{
|
||||
_glfwRestoreVideoMode(window->monitor);
|
||||
|
||||
window->fullscreen = GLFW_FALSE;
|
||||
|
||||
updateWindowStyle(window);
|
||||
}
|
||||
|
||||
// Window callback function (handles window events)
|
||||
@ -280,7 +293,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL);
|
||||
|
||||
if (window->monitor && window->autoIconify)
|
||||
if (window->fullscreen && window->autoIconify)
|
||||
_glfwPlatformIconifyWindow(window);
|
||||
|
||||
_glfwInputWindowFocus(window, GLFW_FALSE);
|
||||
@ -294,7 +307,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
case SC_SCREENSAVE:
|
||||
case SC_MONITORPOWER:
|
||||
{
|
||||
if (window->monitor)
|
||||
if (window->fullscreen)
|
||||
{
|
||||
// We are running in full screen mode, so disallow
|
||||
// screen saver and screen blanking
|
||||
@ -508,16 +521,23 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
if (!window->win32.iconified && wParam == SIZE_MINIMIZED)
|
||||
{
|
||||
window->win32.iconified = GLFW_TRUE;
|
||||
if (window->monitor)
|
||||
|
||||
if (window->fullscreen)
|
||||
leaveFullscreenMode(window);
|
||||
|
||||
// We don't really toggle fullscreen,
|
||||
// just temporally restore monitor video mode
|
||||
window->fullscreen = GLFW_TRUE;
|
||||
|
||||
_glfwInputWindowIconify(window, GLFW_TRUE);
|
||||
}
|
||||
else if (window->win32.iconified &&
|
||||
(wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED))
|
||||
{
|
||||
window->win32.iconified = GLFW_FALSE;
|
||||
if (window->monitor)
|
||||
|
||||
// check if we should go back to fullscreen mode
|
||||
if (window->fullscreen)
|
||||
enterFullscreenMode(window);
|
||||
|
||||
_glfwInputWindowIconify(window, GLFW_FALSE);
|
||||
@ -673,7 +693,7 @@ static GLFWbool createWindow(_GLFWwindow* window,
|
||||
int xpos, ypos, fullWidth, fullHeight;
|
||||
WCHAR* wideTitle;
|
||||
|
||||
if (wndconfig->monitor)
|
||||
if (wndconfig->fullscreen)
|
||||
{
|
||||
GLFWvidmode mode;
|
||||
|
||||
@ -732,7 +752,7 @@ static GLFWbool createWindow(_GLFWwindow* window,
|
||||
WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL);
|
||||
}
|
||||
|
||||
if (wndconfig->floating && !wndconfig->monitor)
|
||||
if (wndconfig->floating && !wndconfig->fullscreen)
|
||||
{
|
||||
SetWindowPos(window->win32.handle,
|
||||
HWND_TOPMOST,
|
||||
@ -869,16 +889,11 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (window->monitor)
|
||||
if (wndconfig->fullscreen)
|
||||
{
|
||||
// the following function calls ShowWindow
|
||||
// which sends WM_SETFOCUS to windowProc()
|
||||
// Which then enters fullscreen mode if autoIconify is enabled (win32_window.c : line 283)
|
||||
_glfwPlatformShowWindow(window);
|
||||
if (!window->autoIconify) { // add this to prevent entering full screen mode twice when autoIconify == true
|
||||
if (!enterFullscreenMode(window))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
if (!enterFullscreenMode(window))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
@ -886,7 +901,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
|
||||
void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||
{
|
||||
if (window->monitor)
|
||||
if (window->fullscreen)
|
||||
leaveFullscreenMode(window);
|
||||
|
||||
destroyWindow(window);
|
||||
@ -939,7 +954,7 @@ void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
|
||||
|
||||
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
|
||||
{
|
||||
if (window->monitor)
|
||||
if (window->fullscreen)
|
||||
enterFullscreenMode(window);
|
||||
else
|
||||
{
|
||||
@ -1032,20 +1047,7 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window)
|
||||
ShowWindow(window->win32.handle, SW_RESTORE);
|
||||
}
|
||||
|
||||
void _glfwPlatformShowWindow(_GLFWwindow* window)
|
||||
{
|
||||
ShowWindow(window->win32.handle, SW_SHOW);
|
||||
|
||||
// Consider separating the following function calls to a different function?
|
||||
// e.g. RequestFocus(_GLFWwindow* window) (any of these might fail)
|
||||
BringWindowToTop(window->win32.handle);
|
||||
SetForegroundWindow(window->win32.handle);
|
||||
SetFocus(window->win32.handle);
|
||||
}
|
||||
|
||||
/* one example of separation */
|
||||
|
||||
int _glfwPlatformGrabFocus(_GLFWwindow* window)
|
||||
int WindowGrabFocus(_GLFWwindow* window)
|
||||
{
|
||||
if (!BringWindowToTop(window->win32.handle))
|
||||
return GLFW_FALSE;
|
||||
@ -1056,11 +1058,11 @@ int _glfwPlatformGrabFocus(_GLFWwindow* window)
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
void _glfwPlatformRequestFocus(_GLFWwindow* window)
|
||||
void WindowRequestFocus(_GLFWwindow* window)
|
||||
{
|
||||
// The following can be used to flash the taskbar icon
|
||||
// if any of the focus related functions fail
|
||||
if (!_glfwPlatformGrabFocus(window)) {
|
||||
if (!WindowGrabFocus(window)) {
|
||||
// create a taskbar notification ("flash")
|
||||
FLASHWINFO info;
|
||||
info.cbSize = sizeof(FLASHWINFO);
|
||||
@ -1073,6 +1075,13 @@ void _glfwPlatformRequestFocus(_GLFWwindow* window)
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwPlatformShowWindow(_GLFWwindow* window)
|
||||
{
|
||||
ShowWindow(window->win32.handle, SW_SHOW);
|
||||
WindowRequestFocus(window);
|
||||
}
|
||||
|
||||
|
||||
void _glfwPlatformUnhideWindow(_GLFWwindow* window)
|
||||
{
|
||||
ShowWindow(window->win32.handle, SW_SHOW);
|
||||
@ -1083,6 +1092,15 @@ void _glfwPlatformHideWindow(_GLFWwindow* window)
|
||||
ShowWindow(window->win32.handle, SW_HIDE);
|
||||
}
|
||||
|
||||
void _glfwPlatformToggleWindowFullscreen(_GLFWwindow* window)
|
||||
{
|
||||
if (window->fullscreen) {
|
||||
leaveFullscreenMode(window);
|
||||
} else {
|
||||
enterFullscreenMode(window);
|
||||
}
|
||||
}
|
||||
|
||||
int _glfwPlatformWindowFocused(_GLFWwindow* window)
|
||||
{
|
||||
return window->win32.handle == GetActiveWindow();
|
||||
|
37
src/window.c
37
src/window.c
@ -139,10 +139,10 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
|
||||
wndconfig.width = width;
|
||||
wndconfig.height = height;
|
||||
wndconfig.title = title;
|
||||
wndconfig.monitor = (_GLFWmonitor*) monitor;
|
||||
wndconfig.monitor = (_GLFWmonitor*) (monitor ? monitor : glfwGetPrimaryMonitor());
|
||||
ctxconfig.share = (_GLFWwindow*) share;
|
||||
|
||||
if (wndconfig.monitor)
|
||||
if (wndconfig.fullscreen)
|
||||
{
|
||||
wndconfig.resizable = GLFW_TRUE;
|
||||
wndconfig.visible = GLFW_TRUE;
|
||||
@ -208,7 +208,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
|
||||
// Restore the previously current context (or NULL)
|
||||
_glfwPlatformMakeContextCurrent(previous);
|
||||
|
||||
if (wndconfig.monitor)
|
||||
if (wndconfig.fullscreen)
|
||||
{
|
||||
int width, height;
|
||||
_glfwPlatformGetWindowSize(window, &width, &height);
|
||||
@ -249,6 +249,7 @@ void glfwDefaultWindowHints(void)
|
||||
_glfw.hints.window.decorated = GLFW_TRUE;
|
||||
_glfw.hints.window.focused = GLFW_TRUE;
|
||||
_glfw.hints.window.autoIconify = GLFW_TRUE;
|
||||
_glfw.hints.window.fullscreen = GLFW_FALSE;
|
||||
|
||||
// The default is 24 bits of color, 24 bits of depth and 8 bits of stencil,
|
||||
// double buffered
|
||||
@ -324,6 +325,9 @@ GLFWAPI void glfwWindowHint(int target, int hint)
|
||||
case GLFW_FOCUSED:
|
||||
_glfw.hints.window.focused = hint ? GLFW_TRUE : GLFW_FALSE;
|
||||
break;
|
||||
case GLFW_FULLSCREEN:
|
||||
_glfw.hints.window.fullscreen = hint ? GLFW_TRUE : GLFW_FALSE;
|
||||
break;
|
||||
case GLFW_AUTO_ICONIFY:
|
||||
_glfw.hints.window.autoIconify = hint ? GLFW_TRUE : GLFW_FALSE;
|
||||
break;
|
||||
@ -443,7 +447,7 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos)
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
if (window->monitor)
|
||||
if (window->fullscreen)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE,
|
||||
"Full screen windows cannot be moved");
|
||||
@ -472,7 +476,7 @@ GLFWAPI void glfwSetWindowSize(GLFWwindow* handle, int width, int height)
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
if (window->monitor)
|
||||
if (window->fullscreen)
|
||||
{
|
||||
window->videoMode.width = width;
|
||||
window->videoMode.height = height;
|
||||
@ -489,7 +493,7 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* handle,
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
if (window->monitor || !window->resizable)
|
||||
if (window->fullscreen || !window->resizable)
|
||||
return;
|
||||
|
||||
_glfwPlatformSetWindowSizeLimits(window,
|
||||
@ -503,7 +507,7 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom)
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
if (window->monitor || !window->resizable)
|
||||
if (window->fullscreen || !window->resizable)
|
||||
return;
|
||||
|
||||
if (!denom)
|
||||
@ -567,8 +571,8 @@ GLFWAPI void glfwShowWindow(GLFWwindow* handle)
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
if (window->monitor)
|
||||
return;
|
||||
if (window->fullscreen)
|
||||
_glfwPlatformToggleWindowFullscreen(window);
|
||||
|
||||
_glfwPlatformShowWindow(window);
|
||||
}
|
||||
@ -579,12 +583,21 @@ GLFWAPI void glfwHideWindow(GLFWwindow* handle)
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
if (window->monitor)
|
||||
return;
|
||||
if (window->fullscreen)
|
||||
_glfwPlatformToggleWindowFullscreen(window);
|
||||
|
||||
_glfwPlatformHideWindow(window);
|
||||
}
|
||||
|
||||
GLFWAPI void glfwToggleWindowFullscreen(GLFWwindow* handle)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
_glfwPlatformToggleWindowFullscreen(window);
|
||||
}
|
||||
|
||||
GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
@ -605,6 +618,8 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
|
||||
return window->decorated;
|
||||
case GLFW_FLOATING:
|
||||
return window->floating;
|
||||
case GLFW_FULLSCREEN:
|
||||
return window->fullscreen;
|
||||
case GLFW_CLIENT_API:
|
||||
return window->context.api;
|
||||
case GLFW_CONTEXT_VERSION_MAJOR:
|
||||
|
Loading…
Reference in New Issue
Block a user