From e276f6731eba3b1ac7a159cb5e962d931ab53682 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Camilla=20L=C3=B6wy?= <elmindreda@elmindreda.org>
Date: Tue, 4 Jun 2019 16:52:40 +0200
Subject: [PATCH] X11: Clean up EWMH feature detection

The EWMH feature detection atoms are now named and loaded the same way
as other X11 atoms.  Detection is now performed after all
non-conditional atoms have been loaded.  The EWMH detection now has
hopefully more readable comments.

(cherry picked from commit fad9896d38922222cdd28608cfc27c3761b3d90b)
---
 src/x11_init.c     | 55 +++++++++++++++++++++++-----------------------
 src/x11_platform.h |  2 ++
 2 files changed, 30 insertions(+), 27 deletions(-)

diff --git a/src/x11_init.c b/src/x11_init.c
index 6d92bbd9..77f543cb 100644
--- a/src/x11_init.c
+++ b/src/x11_init.c
@@ -371,18 +371,11 @@ static Atom getSupportedAtom(Atom* supportedAtoms,
 //
 static void detectEWMH(void)
 {
+    // First we read the _NET_SUPPORTING_WM_CHECK property on the root window
+
     Window* windowFromRoot = NULL;
-    Window* windowFromChild = NULL;
-
-    // First we need a couple of atoms
-    const Atom supportingWmCheck =
-        XInternAtom(_glfw.x11.display, "_NET_SUPPORTING_WM_CHECK", False);
-    const Atom wmSupported =
-        XInternAtom(_glfw.x11.display, "_NET_SUPPORTED", False);
-
-    // Then we look for the _NET_SUPPORTING_WM_CHECK property of the root window
     if (!_glfwGetWindowPropertyX11(_glfw.x11.root,
-                                   supportingWmCheck,
+                                   _glfw.x11.NET_SUPPORTING_WM_CHECK,
                                    XA_WINDOW,
                                    (unsigned char**) &windowFromRoot))
     {
@@ -391,10 +384,12 @@ static void detectEWMH(void)
 
     _glfwGrabErrorHandlerX11();
 
-    // It should be the ID of a child window (of the root)
-    // Then we look for the same property on the child window
+    // If it exists, it should be the XID of a top-level window
+    // Then we look for the same property on that window
+
+    Window* windowFromChild = NULL;
     if (!_glfwGetWindowPropertyX11(*windowFromRoot,
-                                   supportingWmCheck,
+                                   _glfw.x11.NET_SUPPORTING_WM_CHECK,
                                    XA_WINDOW,
                                    (unsigned char**) &windowFromChild))
     {
@@ -404,7 +399,8 @@ static void detectEWMH(void)
 
     _glfwReleaseErrorHandlerX11();
 
-    // It should be the ID of that same child window
+    // If the property exists, it should contain the XID of the window
+
     if (*windowFromRoot != *windowFromChild)
     {
         XFree(windowFromRoot);
@@ -415,19 +411,20 @@ static void detectEWMH(void)
     XFree(windowFromRoot);
     XFree(windowFromChild);
 
-    // We are now fairly sure that an EWMH-compliant window manager is running
+    // We are now fairly sure that an EWMH-compliant WM is currently running
+    // We can now start querying the WM about what features it supports by
+    // looking in the _NET_SUPPORTED property on the root window
+    // It should contain a list of supported EWMH protocol and state atoms
 
-    Atom* supportedAtoms;
-    unsigned long atomCount;
-
-    // Now we need to check the _NET_SUPPORTED property of the root window
-    // It should be a list of supported WM protocol and state atoms
-    atomCount = _glfwGetWindowPropertyX11(_glfw.x11.root,
-                                          wmSupported,
-                                          XA_ATOM,
-                                          (unsigned char**) &supportedAtoms);
+    Atom* supportedAtoms = NULL;
+    const unsigned long atomCount =
+        _glfwGetWindowPropertyX11(_glfw.x11.root,
+                                  _glfw.x11.NET_SUPPORTED,
+                                  XA_ATOM,
+                                  (unsigned char**) &supportedAtoms);
 
     // See which of the atoms we support that are supported by the WM
+
     _glfw.x11.NET_WM_STATE =
         getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE");
     _glfw.x11.NET_WM_STATE_ABOVE =
@@ -707,9 +704,6 @@ static GLFWbool initExtensions(void)
     // the keyboard mapping.
     createKeyTables();
 
-    // Detect whether an EWMH-conformant window manager is running
-    detectEWMH();
-
     // String format atoms
     _glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False);
     _glfw.x11.UTF8_STRING = XInternAtom(_glfw.x11.display, "UTF8_STRING", False);
@@ -753,6 +747,10 @@ static GLFWbool initExtensions(void)
         XInternAtom(_glfw.x11.display, "WM_STATE", False);
     _glfw.x11.WM_DELETE_WINDOW =
         XInternAtom(_glfw.x11.display, "WM_DELETE_WINDOW", False);
+    _glfw.x11.NET_SUPPORTED =
+        XInternAtom(_glfw.x11.display, "_NET_SUPPORTED", False);
+    _glfw.x11.NET_SUPPORTING_WM_CHECK =
+        XInternAtom(_glfw.x11.display, "_NET_SUPPORTING_WM_CHECK", False);
     _glfw.x11.NET_WM_ICON =
         XInternAtom(_glfw.x11.display, "_NET_WM_ICON", False);
     _glfw.x11.NET_WM_PING =
@@ -777,6 +775,9 @@ static GLFWbool initExtensions(void)
         _glfw.x11.NET_WM_CM_Sx = XInternAtom(_glfw.x11.display, name, False);
     }
 
+    // Detect whether an EWMH-conformant window manager is running
+    detectEWMH();
+
     return GLFW_TRUE;
 }
 
diff --git a/src/x11_platform.h b/src/x11_platform.h
index 3b2b2b22..9fffa78e 100644
--- a/src/x11_platform.h
+++ b/src/x11_platform.h
@@ -239,6 +239,8 @@ typedef struct _GLFWlibraryX11
     _GLFWwindow*    disabledCursorWindow;
 
     // Window manager atoms
+    Atom            NET_SUPPORTED;
+    Atom            NET_SUPPORTING_WM_CHECK;
     Atom            WM_PROTOCOLS;
     Atom            WM_STATE;
     Atom            WM_DELETE_WINDOW;