Wayland: Fix behavior of leaving full screen mode

These changes make GLFW fullscreen more consistent, but unfortunately
also make GLFW even more oblivious to user-initiated XDG shell
fullscreen changes.

Fixes #1995
This commit is contained in:
Camilla Löwy 2022-06-09 21:31:44 +02:00
parent 523fdf50c1
commit ddd087d662
4 changed files with 45 additions and 27 deletions

View File

@ -160,6 +160,7 @@ video tutorials.
- Christopher Pelloux - Christopher Pelloux
- Arturo J. Pérez - Arturo J. Pérez
- Vladimir Perminov - Vladimir Perminov
- Olivier Perret
- Anthony Pesch - Anthony Pesch
- Orson Peters - Orson Peters
- Emmanuel Gil Peyrot - Emmanuel Gil Peyrot

View File

@ -331,6 +331,10 @@ information on what to include when reporting a bug.
- [Wayland] Bugfix: The OSMesa library was not unloaded on termination - [Wayland] Bugfix: The OSMesa library was not unloaded on termination
- [Wayland] Bugfix: `glfwCreateWindow` could emit `GLFW_FEATURE_UNAVAILABLE` - [Wayland] Bugfix: `glfwCreateWindow` could emit `GLFW_FEATURE_UNAVAILABLE`
- [Wayland] Bugfix: Lock key modifier bits were only set when lock keys were pressed - [Wayland] Bugfix: Lock key modifier bits were only set when lock keys were pressed
- [Wayland] Bugfix: A window leaving full screen mode would be iconified (#1995)
- [Wayland] Bugfix: A window leaving full screen mode ignored its desired size
- [Wayland] Bugfix: `glfwSetWindowMonitor` did not update windowed mode size
- [Wayland] Bugfix: `glfwRestoreWindow` would make a full screen window windowed
- [POSIX] Removed use of deprecated function `gettimeofday` - [POSIX] Removed use of deprecated function `gettimeofday`
- [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled - [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled
- [WGL] Disabled the DWM swap interval hack for Windows 8 and later (#1072) - [WGL] Disabled the DWM swap interval hack for Windows 8 and later (#1072)

View File

@ -233,6 +233,7 @@ typedef struct _GLFWwindowWayland
int width, height; int width, height;
GLFWbool visible; GLFWbool visible;
GLFWbool maximized; GLFWbool maximized;
GLFWbool activated;
GLFWbool hovered; GLFWbool hovered;
GLFWbool transparent; GLFWbool transparent;
struct wl_surface* surface; struct wl_surface* surface;
@ -264,8 +265,6 @@ typedef struct _GLFWwindowWayland
struct zwp_idle_inhibitor_v1* idleInhibitor; struct zwp_idle_inhibitor_v1* idleInhibitor;
GLFWbool wasFullscreen;
struct { struct {
GLFWbool serverSide; GLFWbool serverSide;
struct wl_buffer* buffer; struct wl_buffer* buffer;

View File

@ -429,20 +429,35 @@ static void setIdleInhibitor(_GLFWwindow* window, GLFWbool enable)
} }
} }
static void setFullscreen(_GLFWwindow* window, _GLFWmonitor* monitor, // Make the specified window and its video mode active on its monitor
int refreshRate) //
static void acquireMonitor(_GLFWwindow* window)
{ {
if (window->wl.xdg.toplevel) if (window->wl.xdg.toplevel)
{ {
xdg_toplevel_set_fullscreen( xdg_toplevel_set_fullscreen(window->wl.xdg.toplevel,
window->wl.xdg.toplevel, window->monitor->wl.output);
monitor->wl.output);
} }
setIdleInhibitor(window, GLFW_TRUE); setIdleInhibitor(window, GLFW_TRUE);
if (!window->wl.decorations.serverSide) if (!window->wl.decorations.serverSide)
destroyDecorations(window); destroyDecorations(window);
} }
// Remove the window and restore the original video mode
//
static void releaseMonitor(_GLFWwindow* window)
{
if (window->wl.xdg.toplevel)
xdg_toplevel_unset_fullscreen(window->wl.xdg.toplevel);
setIdleInhibitor(window, GLFW_FALSE);
if (!_glfw.wl.decorationManager)
createDecorations(window);
}
static void xdgToplevelHandleConfigure(void* userData, static void xdgToplevelHandleConfigure(void* userData,
struct xdg_toplevel* toplevel, struct xdg_toplevel* toplevel,
int32_t width, int32_t width,
@ -495,16 +510,13 @@ static void xdgToplevelHandleConfigure(void* userData,
_glfwInputWindowDamage(window); _glfwInputWindowDamage(window);
} }
if (window->wl.wasFullscreen && window->autoIconify) if (window->wl.activated && !activated)
{ {
if (!activated || !fullscreen) if (window->monitor && window->autoIconify)
{
_glfwIconifyWindowWayland(window); _glfwIconifyWindowWayland(window);
window->wl.wasFullscreen = GLFW_FALSE;
}
} }
if (fullscreen && activated)
window->wl.wasFullscreen = GLFW_TRUE; window->wl.activated = activated;
} }
static void xdgToplevelHandleClose(void* userData, static void xdgToplevelHandleClose(void* userData,
@ -1896,14 +1908,12 @@ void _glfwRestoreWindowWayland(_GLFWwindow* window)
{ {
if (window->wl.xdg.toplevel) if (window->wl.xdg.toplevel)
{ {
if (window->monitor)
xdg_toplevel_unset_fullscreen(window->wl.xdg.toplevel);
if (window->wl.maximized) if (window->wl.maximized)
xdg_toplevel_unset_maximized(window->wl.xdg.toplevel); xdg_toplevel_unset_maximized(window->wl.xdg.toplevel);
// There is no way to unset minimized, or even to know if we are // There is no way to unset minimized, or even to know if we are
// minimized, so there is nothing to do in this case. // minimized, so there is nothing to do in this case.
} }
_glfwInputWindowMonitor(window, NULL);
window->wl.maximized = GLFW_FALSE; window->wl.maximized = GLFW_FALSE;
} }
@ -1959,19 +1969,23 @@ void _glfwSetWindowMonitorWayland(_GLFWwindow* window,
int width, int height, int width, int height,
int refreshRate) int refreshRate)
{ {
if (monitor) if (window->monitor == monitor)
{ {
setFullscreen(window, monitor, refreshRate); if (!monitor)
} _glfwSetWindowSizeWayland(window, width, height);
else
{ return;
if (window->wl.xdg.toplevel)
xdg_toplevel_unset_fullscreen(window->wl.xdg.toplevel);
setIdleInhibitor(window, GLFW_FALSE);
if (!_glfw.wl.decorationManager)
createDecorations(window);
} }
if (window->monitor)
releaseMonitor(window);
_glfwInputWindowMonitor(window, monitor); _glfwInputWindowMonitor(window, monitor);
if (window->monitor)
acquireMonitor(window);
else
_glfwSetWindowSizeWayland(window, width, height);
} }
GLFWbool _glfwWindowFocusedWayland(_GLFWwindow* window) GLFWbool _glfwWindowFocusedWayland(_GLFWwindow* window)