Added support for _NET_WM_FULLSCREEN_MONITORS.
This allows EWMH full screen windows to correctly cover monitors that overlap other monitors, such as an Oculus Rift mapped onto a section of a larger monitor. Fixes #175.
This commit is contained in:
parent
2488c67798
commit
4918514eaf
@ -222,6 +222,15 @@ if (_GLFW_X11)
|
||||
list(APPEND glfw_LIBRARIES "${X11_Xrandr_LIB}")
|
||||
set(GLFW_PKG_DEPS "${GLFW_PKG_DEPS} xrandr")
|
||||
|
||||
# Check for Xinerama (legacy multi-monitor support)
|
||||
if (NOT X11_Xinerama_FOUND)
|
||||
message(FATAL_ERROR "The Xinerama library and headers were not found")
|
||||
endif()
|
||||
|
||||
list(APPEND glfw_INCLUDE_DIRS "${X11_Xinerama_INCLUDE_PATH}")
|
||||
list(APPEND glfw_LIBRARIES "${X11_Xinerama_LIB}")
|
||||
set(GLFW_PKG_DEPS "${GLFW_PKG_DEPS} xinerama")
|
||||
|
||||
# Check for XInput (high-resolution cursor motion)
|
||||
if (NOT X11_Xinput_FOUND)
|
||||
message(FATAL_ERROR "The XInput library and headers were not found")
|
||||
|
@ -447,6 +447,8 @@ static void detectEWMH(void)
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_ABOVE");
|
||||
_glfw.x11.NET_WM_STATE_FULLSCREEN =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_FULLSCREEN");
|
||||
_glfw.x11.NET_WM_FULLSCREEN_MONITORS =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_FULLSCREEN_MONITORS");
|
||||
_glfw.x11.NET_WM_NAME =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_NAME");
|
||||
_glfw.x11.NET_WM_ICON_NAME =
|
||||
@ -533,6 +535,14 @@ static GLboolean initExtensions(void)
|
||||
XRRFreeScreenResources(sr);
|
||||
}
|
||||
|
||||
if (XineramaQueryExtension(_glfw.x11.display,
|
||||
&_glfw.x11.xinerama.versionMajor,
|
||||
&_glfw.x11.xinerama.versionMinor))
|
||||
{
|
||||
if (XineramaIsActive(_glfw.x11.display))
|
||||
_glfw.x11.xinerama.available = GL_TRUE;
|
||||
}
|
||||
|
||||
if (XQueryExtension(_glfw.x11.display,
|
||||
"XInputExtension",
|
||||
&_glfw.x11.xi.majorOpcode,
|
||||
|
@ -200,18 +200,23 @@ void _glfwRestoreVideoMode(_GLFWmonitor* monitor)
|
||||
|
||||
_GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
||||
{
|
||||
int i, j, size = 0, found = 0;
|
||||
int i, j, k, size = 0, found = 0;
|
||||
_GLFWmonitor** monitors = NULL;
|
||||
|
||||
*count = 0;
|
||||
|
||||
if (_glfw.x11.randr.available)
|
||||
{
|
||||
int screenCount = 0;
|
||||
XineramaScreenInfo* screens = NULL;
|
||||
XRRScreenResources* sr = XRRGetScreenResources(_glfw.x11.display,
|
||||
_glfw.x11.root);
|
||||
RROutput primary = XRRGetOutputPrimary(_glfw.x11.display,
|
||||
_glfw.x11.root);
|
||||
|
||||
if (_glfw.x11.xinerama.available)
|
||||
screens = XineramaQueryScreens(_glfw.x11.display, &screenCount);
|
||||
|
||||
for (i = 0; i < sr->ncrtc; i++)
|
||||
{
|
||||
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display,
|
||||
@ -240,6 +245,18 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
||||
monitors[found]->x11.output = ci->outputs[j];
|
||||
monitors[found]->x11.crtc = oi->crtc;
|
||||
|
||||
for (k = 0; k < screenCount; k++)
|
||||
{
|
||||
if (screens[k].x_org == ci->x &&
|
||||
screens[k].y_org == ci->y &&
|
||||
screens[k].width == ci->width &&
|
||||
screens[k].height == ci->height)
|
||||
{
|
||||
monitors[found]->x11.index = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
XRRFreeOutputInfo(oi);
|
||||
|
||||
if (ci->outputs[j] == primary)
|
||||
@ -253,6 +270,9 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
||||
|
||||
XRRFreeScreenResources(sr);
|
||||
|
||||
if (screens)
|
||||
XFree(screens);
|
||||
|
||||
if (found == 0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
|
@ -48,6 +48,9 @@
|
||||
// The Xkb extension provides improved keyboard support
|
||||
#include <X11/XKBlib.h>
|
||||
|
||||
// The Xinerama extension provides legacy monitor indices
|
||||
#include <X11/extensions/Xinerama.h>
|
||||
|
||||
#include "posix_tls.h"
|
||||
|
||||
#if defined(_GLFW_GLX)
|
||||
@ -130,6 +133,7 @@ typedef struct _GLFWlibraryX11
|
||||
Atom NET_WM_STATE_ABOVE;
|
||||
Atom NET_WM_STATE_FULLSCREEN;
|
||||
Atom NET_WM_BYPASS_COMPOSITOR;
|
||||
Atom NET_WM_FULLSCREEN_MONITORS;
|
||||
Atom NET_ACTIVE_WINDOW;
|
||||
Atom NET_FRAME_EXTENTS;
|
||||
Atom NET_REQUEST_FRAME_EXTENTS;
|
||||
@ -205,6 +209,12 @@ typedef struct _GLFWlibraryX11
|
||||
Window source;
|
||||
} xdnd;
|
||||
|
||||
struct {
|
||||
GLboolean available;
|
||||
int versionMajor;
|
||||
int versionMinor;
|
||||
} xinerama;
|
||||
|
||||
} _GLFWlibraryX11;
|
||||
|
||||
|
||||
@ -216,6 +226,10 @@ typedef struct _GLFWmonitorX11
|
||||
RRCrtc crtc;
|
||||
RRMode oldMode;
|
||||
|
||||
// Index of corresponding Xinerama screen,
|
||||
// for EWMH full screen window placement
|
||||
int index;
|
||||
|
||||
} _GLFWmonitorX11;
|
||||
|
||||
|
||||
|
@ -715,6 +715,27 @@ static void enterFullscreenMode(_GLFWwindow* window)
|
||||
PropModeReplace, (unsigned char*) &value, 1);
|
||||
}
|
||||
|
||||
if (_glfw.x11.xinerama.available && _glfw.x11.NET_WM_FULLSCREEN_MONITORS)
|
||||
{
|
||||
XEvent event;
|
||||
memset(&event, 0, sizeof(event));
|
||||
|
||||
event.type = ClientMessage;
|
||||
event.xclient.window = window->x11.handle;
|
||||
event.xclient.format = 32; // Data is 32-bit longs
|
||||
event.xclient.message_type = _glfw.x11.NET_WM_FULLSCREEN_MONITORS;
|
||||
event.xclient.data.l[0] = window->monitor->x11.index;
|
||||
event.xclient.data.l[1] = window->monitor->x11.index;
|
||||
event.xclient.data.l[2] = window->monitor->x11.index;
|
||||
event.xclient.data.l[3] = window->monitor->x11.index;
|
||||
|
||||
XSendEvent(_glfw.x11.display,
|
||||
_glfw.x11.root,
|
||||
False,
|
||||
SubstructureNotifyMask | SubstructureRedirectMask,
|
||||
&event);
|
||||
}
|
||||
|
||||
if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_FULLSCREEN)
|
||||
{
|
||||
int x, y;
|
||||
|
Loading…
Reference in New Issue
Block a user