diff --git a/src/x11_init.c b/src/x11_init.c index f1e72614..6c951c04 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -448,6 +448,8 @@ static void detectEWMH(void) getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE_NORMAL"); _glfw.x11.NET_WORKAREA = getSupportedAtom(supportedAtoms, atomCount, "_NET_WORKAREA"); + _glfw.x11.NET_CURRENT_DESKTOP = + getSupportedAtom(supportedAtoms, atomCount, "_NET_CURRENT_DESKTOP"); _glfw.x11.NET_ACTIVE_WINDOW = getSupportedAtom(supportedAtoms, atomCount, "_NET_ACTIVE_WINDOW"); _glfw.x11.NET_FRAME_EXTENTS = diff --git a/src/x11_monitor.c b/src/x11_monitor.c index 6c166e7c..61d1dd70 100644 --- a/src/x11_monitor.c +++ b/src/x11_monitor.c @@ -344,25 +344,96 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, 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) { - Atom* extents = NULL; + XRRScreenResources* sr; + XRRCrtcInfo* ci; - _glfwGetWindowPropertyX11(_glfw.x11.root, - _glfw.x11.NET_WORKAREA, XA_CARDINAL, - (unsigned char**) &extents); + sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root); + ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); - if (xpos) - *xpos = extents[0]; - if (ypos) - *ypos = extents[1]; - if (width) - *width = extents[2]; - if (height) - *height = extents[3]; + areaX = ci->x; + areaY = ci->y; - XFree(extents); + 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; } GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) diff --git a/src/x11_platform.h b/src/x11_platform.h index 153daee1..f9e7194c 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -260,6 +260,7 @@ typedef struct _GLFWlibraryX11 Atom NET_WM_WINDOW_OPACITY; Atom NET_WM_CM_Sx; Atom NET_WORKAREA; + Atom NET_CURRENT_DESKTOP; Atom NET_ACTIVE_WINDOW; Atom NET_FRAME_EXTENTS; Atom NET_REQUEST_FRAME_EXTENTS;