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}")
|
list(APPEND glfw_LIBRARIES "${X11_Xrandr_LIB}")
|
||||||
set(GLFW_PKG_DEPS "${GLFW_PKG_DEPS} xrandr")
|
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)
|
# Check for XInput (high-resolution cursor motion)
|
||||||
if (NOT X11_Xinput_FOUND)
|
if (NOT X11_Xinput_FOUND)
|
||||||
message(FATAL_ERROR "The XInput library and headers were not 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");
|
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_ABOVE");
|
||||||
_glfw.x11.NET_WM_STATE_FULLSCREEN =
|
_glfw.x11.NET_WM_STATE_FULLSCREEN =
|
||||||
getSupportedAtom(supportedAtoms, atomCount, "_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 =
|
_glfw.x11.NET_WM_NAME =
|
||||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_NAME");
|
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_NAME");
|
||||||
_glfw.x11.NET_WM_ICON_NAME =
|
_glfw.x11.NET_WM_ICON_NAME =
|
||||||
@ -533,6 +535,14 @@ static GLboolean initExtensions(void)
|
|||||||
XRRFreeScreenResources(sr);
|
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,
|
if (XQueryExtension(_glfw.x11.display,
|
||||||
"XInputExtension",
|
"XInputExtension",
|
||||||
&_glfw.x11.xi.majorOpcode,
|
&_glfw.x11.xi.majorOpcode,
|
||||||
|
@ -200,18 +200,23 @@ void _glfwRestoreVideoMode(_GLFWmonitor* monitor)
|
|||||||
|
|
||||||
_GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
_GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
||||||
{
|
{
|
||||||
int i, j, size = 0, found = 0;
|
int i, j, k, size = 0, found = 0;
|
||||||
_GLFWmonitor** monitors = NULL;
|
_GLFWmonitor** monitors = NULL;
|
||||||
|
|
||||||
*count = 0;
|
*count = 0;
|
||||||
|
|
||||||
if (_glfw.x11.randr.available)
|
if (_glfw.x11.randr.available)
|
||||||
{
|
{
|
||||||
|
int screenCount = 0;
|
||||||
|
XineramaScreenInfo* screens = NULL;
|
||||||
XRRScreenResources* sr = XRRGetScreenResources(_glfw.x11.display,
|
XRRScreenResources* sr = XRRGetScreenResources(_glfw.x11.display,
|
||||||
_glfw.x11.root);
|
_glfw.x11.root);
|
||||||
RROutput primary = XRRGetOutputPrimary(_glfw.x11.display,
|
RROutput primary = XRRGetOutputPrimary(_glfw.x11.display,
|
||||||
_glfw.x11.root);
|
_glfw.x11.root);
|
||||||
|
|
||||||
|
if (_glfw.x11.xinerama.available)
|
||||||
|
screens = XineramaQueryScreens(_glfw.x11.display, &screenCount);
|
||||||
|
|
||||||
for (i = 0; i < sr->ncrtc; i++)
|
for (i = 0; i < sr->ncrtc; i++)
|
||||||
{
|
{
|
||||||
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display,
|
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display,
|
||||||
@ -240,6 +245,18 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
|||||||
monitors[found]->x11.output = ci->outputs[j];
|
monitors[found]->x11.output = ci->outputs[j];
|
||||||
monitors[found]->x11.crtc = oi->crtc;
|
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);
|
XRRFreeOutputInfo(oi);
|
||||||
|
|
||||||
if (ci->outputs[j] == primary)
|
if (ci->outputs[j] == primary)
|
||||||
@ -253,6 +270,9 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
|||||||
|
|
||||||
XRRFreeScreenResources(sr);
|
XRRFreeScreenResources(sr);
|
||||||
|
|
||||||
|
if (screens)
|
||||||
|
XFree(screens);
|
||||||
|
|
||||||
if (found == 0)
|
if (found == 0)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
@ -48,6 +48,9 @@
|
|||||||
// The Xkb extension provides improved keyboard support
|
// The Xkb extension provides improved keyboard support
|
||||||
#include <X11/XKBlib.h>
|
#include <X11/XKBlib.h>
|
||||||
|
|
||||||
|
// The Xinerama extension provides legacy monitor indices
|
||||||
|
#include <X11/extensions/Xinerama.h>
|
||||||
|
|
||||||
#include "posix_tls.h"
|
#include "posix_tls.h"
|
||||||
|
|
||||||
#if defined(_GLFW_GLX)
|
#if defined(_GLFW_GLX)
|
||||||
@ -130,6 +133,7 @@ typedef struct _GLFWlibraryX11
|
|||||||
Atom NET_WM_STATE_ABOVE;
|
Atom NET_WM_STATE_ABOVE;
|
||||||
Atom NET_WM_STATE_FULLSCREEN;
|
Atom NET_WM_STATE_FULLSCREEN;
|
||||||
Atom NET_WM_BYPASS_COMPOSITOR;
|
Atom NET_WM_BYPASS_COMPOSITOR;
|
||||||
|
Atom NET_WM_FULLSCREEN_MONITORS;
|
||||||
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;
|
||||||
@ -205,6 +209,12 @@ typedef struct _GLFWlibraryX11
|
|||||||
Window source;
|
Window source;
|
||||||
} xdnd;
|
} xdnd;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
GLboolean available;
|
||||||
|
int versionMajor;
|
||||||
|
int versionMinor;
|
||||||
|
} xinerama;
|
||||||
|
|
||||||
} _GLFWlibraryX11;
|
} _GLFWlibraryX11;
|
||||||
|
|
||||||
|
|
||||||
@ -216,6 +226,10 @@ typedef struct _GLFWmonitorX11
|
|||||||
RRCrtc crtc;
|
RRCrtc crtc;
|
||||||
RRMode oldMode;
|
RRMode oldMode;
|
||||||
|
|
||||||
|
// Index of corresponding Xinerama screen,
|
||||||
|
// for EWMH full screen window placement
|
||||||
|
int index;
|
||||||
|
|
||||||
} _GLFWmonitorX11;
|
} _GLFWmonitorX11;
|
||||||
|
|
||||||
|
|
||||||
|
@ -715,6 +715,27 @@ static void enterFullscreenMode(_GLFWwindow* window)
|
|||||||
PropModeReplace, (unsigned char*) &value, 1);
|
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)
|
if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_FULLSCREEN)
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
|
Loading…
Reference in New Issue
Block a user