Browse Source

Wayland: Fix window hiding

Corrects the protocol violation when creating an xdg_surface from a
wl_surface that already has a buffer due to EGL buffer swaps.

This commit is based on PR #1731 by @ghost, but adapted and altered:
 - The XDG surface and role are now only created when a window is shown
   to prevent application lists from showing command-line applications
   with off-screen-only windows
 - The special case of Wayland+EGL buffer swap is now in the EGL code
   to mirror how X11 is handled
 - Adaption to run-time platform selection and separate credits file

Fixes #1492
Closes #1731
Jason Francis 5 years ago
parent
commit
094aa6d3c7
4 changed files with 20 additions and 21 deletions
  1. 1 0
      CONTRIBUTORS.md
  2. 1 0
      README.md
  3. 9 0
      src/egl_context.c
  4. 9 21
      src/wl_window.c

+ 1 - 0
CONTRIBUTORS.md

@@ -58,6 +58,7 @@ video tutorials.
  - Ahmad Fatoum
  - Felipe Ferreira
  - Michael Fogleman
+ - Jason Francis
  - Gerald Franz
  - Mário Freitas
  - GeO4d

+ 1 - 0
README.md

@@ -281,6 +281,7 @@ information on what to include when reporting a bug.
  - [Wayland] Bugfix: Key repeat could lead to a race condition (#1710)
  - [Wayland] Bugfix: Activating a window would emit two input focus events
  - [Wayland] Bugfix: Disable key repeat mechanism when window loses input focus
+ - [Wayland] Bugfix: Window hiding and showing did not work (#1492,#1731)
  - [POSIX] Removed use of deprecated function `gettimeofday`
  - [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled
  - [WGL] Disabled the DWM swap interval hack for Windows 8 and later (#1072)

+ 9 - 0
src/egl_context.c

@@ -231,6 +231,15 @@ static void swapBuffersEGL(_GLFWwindow* window)
         return;
     }
 
+#if defined(_GLFW_WAYLAND)
+    if (_glfw.platform.platformID == GLFW_PLATFORM_WAYLAND)
+    {
+        // NOTE: Swapping buffers on a hidden window on Wayland makes it visible
+        if (!window->wl.visible)
+            return;
+    }
+#endif
+
     eglSwapBuffers(_glfw.egl.display, window->context.egl.surface);
 }
 

+ 9 - 21
src/wl_window.c

@@ -812,20 +812,6 @@ int _glfwCreateWindowWayland(_GLFWwindow* window,
     if (wndconfig->title)
         window->wl.title = _glfw_strdup(wndconfig->title);
 
-    if (wndconfig->visible)
-    {
-        if (!createXdgSurface(window))
-            return GLFW_FALSE;
-
-        window->wl.visible = GLFW_TRUE;
-    }
-    else
-    {
-        window->wl.xdg.surface = NULL;
-        window->wl.xdg.toplevel = NULL;
-        window->wl.visible = GLFW_FALSE;
-    }
-
     window->wl.currentCursor = NULL;
 
     window->wl.monitors = _glfw_calloc(1, sizeof(_GLFWmonitor*));
@@ -1018,21 +1004,23 @@ void _glfwShowWindowWayland(_GLFWwindow* window)
 {
     if (!window->wl.visible)
     {
-        createXdgSurface(window);
+        // NOTE: The XDG surface and role are created here so command-line applications
+        //       with off-screen windows do not appear in for example the Unity dock
+        if (!window->wl.xdg.toplevel)
+            createXdgSurface(window);
+
         window->wl.visible = GLFW_TRUE;
     }
 }
 
 void _glfwHideWindowWayland(_GLFWwindow* window)
 {
-    if (window->wl.xdg.toplevel)
+    if (window->wl.visible)
     {
-        xdg_toplevel_destroy(window->wl.xdg.toplevel);
-        xdg_surface_destroy(window->wl.xdg.surface);
-        window->wl.xdg.toplevel = NULL;
-        window->wl.xdg.surface = NULL;
+        window->wl.visible = GLFW_FALSE;
+        wl_surface_attach(window->wl.surface, NULL, 0, 0);
+        wl_surface_commit(window->wl.surface);
     }
-    window->wl.visible = GLFW_FALSE;
 }
 
 void _glfwRequestWindowAttentionWayland(_GLFWwindow* window)