diff --git a/glfw/x11_init.c b/glfw/x11_init.c index bb88c588f..1a1b6e9de 100644 --- a/glfw/x11_init.c +++ b/glfw/x11_init.c @@ -62,18 +62,12 @@ 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)) { @@ -82,10 +76,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)) { @@ -95,7 +91,7 @@ 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); @@ -107,18 +103,20 @@ static void detectEWMH(void) XFree(windowFromChild); // We are now fairly sure that an EWMH-compliant window manager is 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, + Atom* supportedAtoms = NULL; + const unsigned long atomCount = _glfwGetWindowPropertyX11(_glfw.x11.root, + _glfw.x11.NET_SUPPORTED, XA_ATOM, (unsigned char**) &supportedAtoms); + if (!supportedAtoms) + return; // 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 = @@ -148,8 +146,7 @@ static void detectEWMH(void) _glfw.x11.NET_REQUEST_FRAME_EXTENTS = getSupportedAtom(supportedAtoms, atomCount, "_NET_REQUEST_FRAME_EXTENTS"); - if (supportedAtoms) - XFree(supportedAtoms); + XFree(supportedAtoms); } // Look for and initialize supported X11 extensions @@ -387,9 +384,6 @@ static bool initExtensions(void) if (!glfw_xkb_update_x11_keyboard_id(&_glfw.x11.xkb)) return false; if (!glfw_xkb_compile_keymap(&_glfw.x11.xkb, NULL)) return false; - // 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); @@ -433,6 +427,10 @@ static bool 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 = @@ -457,6 +455,9 @@ static bool 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 true; } diff --git a/glfw/x11_platform.h b/glfw/x11_platform.h index cf9c2d113..26441235b 100644 --- a/glfw/x11_platform.h +++ b/glfw/x11_platform.h @@ -227,6 +227,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; @@ -425,4 +427,3 @@ void _glfwInputErrorX11(int error, const char* message); void _glfwGetSystemContentScaleX11(float* xscale, float* yscale, bool bypass_cache); void _glfwPushSelectionToManagerX11(void); -