mirror of
https://github.com/glfw/glfw.git
synced 2024-11-10 00:51:47 +00:00
X11: Fix implementation of work area retrieval
This intersects the global work area from _NET_WORKAREA with the monitor viewport. The monitor viewport falls back to the core display dimensions where working RandR is missing. The _NET_WORKAREA query is now checked for success. The _NET_WORKAREA extent array is now indexed by _NET_CURRENT_DESKTOP. The _NET_WORKAREA atom is now checked for availability. Related to #1322.
This commit is contained in:
parent
4f14c1e776
commit
3a2a97f15d
@ -448,6 +448,8 @@ static void detectEWMH(void)
|
|||||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE_NORMAL");
|
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE_NORMAL");
|
||||||
_glfw.x11.NET_WORKAREA =
|
_glfw.x11.NET_WORKAREA =
|
||||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WORKAREA");
|
getSupportedAtom(supportedAtoms, atomCount, "_NET_WORKAREA");
|
||||||
|
_glfw.x11.NET_CURRENT_DESKTOP =
|
||||||
|
getSupportedAtom(supportedAtoms, atomCount, "_NET_CURRENT_DESKTOP");
|
||||||
_glfw.x11.NET_ACTIVE_WINDOW =
|
_glfw.x11.NET_ACTIVE_WINDOW =
|
||||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_ACTIVE_WINDOW");
|
getSupportedAtom(supportedAtoms, atomCount, "_NET_ACTIVE_WINDOW");
|
||||||
_glfw.x11.NET_FRAME_EXTENTS =
|
_glfw.x11.NET_FRAME_EXTENTS =
|
||||||
|
@ -344,25 +344,96 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
|||||||
|
|
||||||
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height)
|
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)
|
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||||
{
|
{
|
||||||
Atom* extents = NULL;
|
XRRScreenResources* sr;
|
||||||
|
XRRCrtcInfo* ci;
|
||||||
|
|
||||||
_glfwGetWindowPropertyX11(_glfw.x11.root,
|
sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||||
_glfw.x11.NET_WORKAREA, XA_CARDINAL,
|
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||||
(unsigned char**) &extents);
|
|
||||||
|
|
||||||
if (xpos)
|
areaX = ci->x;
|
||||||
*xpos = extents[0];
|
areaY = ci->y;
|
||||||
if (ypos)
|
|
||||||
*ypos = extents[1];
|
|
||||||
if (width)
|
|
||||||
*width = extents[2];
|
|
||||||
if (height)
|
|
||||||
*height = extents[3];
|
|
||||||
|
|
||||||
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)
|
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
||||||
|
@ -260,6 +260,7 @@ typedef struct _GLFWlibraryX11
|
|||||||
Atom NET_WM_WINDOW_OPACITY;
|
Atom NET_WM_WINDOW_OPACITY;
|
||||||
Atom NET_WM_CM_Sx;
|
Atom NET_WM_CM_Sx;
|
||||||
Atom NET_WORKAREA;
|
Atom NET_WORKAREA;
|
||||||
|
Atom NET_CURRENT_DESKTOP;
|
||||||
Atom NET_ACTIVE_WINDOW;
|
Atom NET_ACTIVE_WINDOW;
|
||||||
Atom NET_FRAME_EXTENTS;
|
Atom NET_FRAME_EXTENTS;
|
||||||
Atom NET_REQUEST_FRAME_EXTENTS;
|
Atom NET_REQUEST_FRAME_EXTENTS;
|
||||||
|
Loading…
Reference in New Issue
Block a user