// Check whether the running window manager is EWMH-compliant // static void detectEWMH(void) { 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, XA_WINDOW, (unsigned char**) &windowFromRoot) != 1) { if (windowFromRoot) XFree(windowFromRoot); return; } _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 (_glfwGetWindowPropertyX11(*windowFromRoot, supportingWmCheck, XA_WINDOW, (unsigned char**) &windowFromChild) != 1) { XFree(windowFromRoot); if (windowFromChild) XFree(windowFromChild); return; } _glfwReleaseErrorHandlerX11(); // It should be the ID of that same child window if (*windowFromRoot != *windowFromChild) { XFree(windowFromRoot); XFree(windowFromChild); return; } XFree(windowFromRoot); XFree(windowFromChild); // We are now fairly sure that an EWMH-compliant window manager is running 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); // 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 = getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_ABOVE"); _glfw.x11.NET_WM_STATE_FULLSCREEN = getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_FULLSCREEN"); _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT = getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_MAXIMIZED_VERT"); _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ = getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_MAXIMIZED_HORZ"); _glfw.x11.NET_WM_FULLSCREEN_MONITORS = getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_FULLSCREEN_MONITORS"); _glfw.x11.NET_WM_WINDOW_TYPE = getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE"); _glfw.x11.NET_WM_WINDOW_TYPE_NORMAL = getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE_NORMAL"); _glfw.x11.NET_ACTIVE_WINDOW = getSupportedAtom(supportedAtoms, atomCount, "_NET_ACTIVE_WINDOW"); _glfw.x11.NET_FRAME_EXTENTS = getSupportedAtom(supportedAtoms, atomCount, "_NET_FRAME_EXTENTS"); _glfw.x11.NET_REQUEST_FRAME_EXTENTS = getSupportedAtom(supportedAtoms, atomCount, "_NET_REQUEST_FRAME_EXTENTS"); XFree(supportedAtoms); }
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height) { int areaX = 0, areaY = 0, areaWidth = 0, areaHeight = 0; if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) { XRRScreenResources* sr; XRRCrtcInfo* ci; sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root); ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); areaX = ci->x; areaY = ci->y; const XRRModeInfo* mi = getModeInfo(sr, ci->mode); if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270) { areaWidth = mi->height; areaHeight = mi->width; } else { areaWidth = mi->width; areaHeight = mi->height; } XRRFreeCrtcInfo(ci); XRRFreeScreenResources(sr); } else { areaWidth = DisplayWidth(_glfw.x11.display, _glfw.x11.screen); areaHeight = DisplayHeight(_glfw.x11.display, _glfw.x11.screen); } if (_glfw.x11.NET_WORKAREA && _glfw.x11.NET_CURRENT_DESKTOP) { Atom* extents = NULL; Atom* desktop = NULL; const unsigned long extentCount = _glfwGetWindowPropertyX11(_glfw.x11.root, _glfw.x11.NET_WORKAREA, XA_CARDINAL, (unsigned char**) &extents); if (_glfwGetWindowPropertyX11(_glfw.x11.root, _glfw.x11.NET_CURRENT_DESKTOP, XA_CARDINAL, (unsigned char**) &desktop) > 0) { if (extentCount >= 4 && *desktop < extentCount / 4) { const int globalX = extents[*desktop * 4 + 0]; const int globalY = extents[*desktop * 4 + 1]; const int globalWidth = extents[*desktop * 4 + 2]; const int globalHeight = extents[*desktop * 4 + 3]; if (areaX < globalX) { areaWidth -= globalX - areaX; areaX = globalX; } if (areaY < globalY) { areaHeight -= globalY - areaY; areaY = globalY; } if (areaX + areaWidth > globalX + globalWidth) areaWidth = globalX - areaX + globalWidth; if (areaY + areaHeight > globalY + globalHeight) areaHeight = globalY - areaY + globalHeight; } } if (extents) XFree(extents); if (desktop) XFree(desktop); } if (xpos) *xpos = areaX; if (ypos) *ypos = areaY; if (width) *width = areaWidth; if (height) *height = areaHeight; }