From Don Burns, add use of Xinerama to ensure full screen goes across all screens.

This commit is contained in:
Robert Osfield 2017-05-12 16:26:07 +01:00
parent d02be06df9
commit 17d39e3db2
2 changed files with 106 additions and 12 deletions

View File

@ -173,14 +173,23 @@ ELSE()
# X11 for everybody else
INCLUDE(FindPkgConfig OPTIONAL)
IF(PKG_CONFIG_FOUND)
PKG_CHECK_MODULES(XRANDR xrandr)
IF(XRANDR_FOUND)
OPTION(OSGVIEWER_USE_XRANDR "Set to ON to enable Xrandr support for GraphicsWindowX11." ON)
ELSE()
SET(OSGVIEWER_USE_XRANDR OFF)
ENDIF()
PKG_CHECK_MODULES(XINERAMA xinerama)
IF(XINERAMA_FOUND)
SET(OSGVIEWER_USE_XINERAMA ON)
ELSE()
SET(OSGVIEWER_USE_XINERAMA OFF)
ENDIF()
ELSE()
SET(OSGVIEWER_USE_XRANDR OFF)
SET(OSGVIEWER_USE_XINERAMA OFF)
ENDIF()
SET(TARGET_H_NO_MODULE_INSTALL
@ -205,6 +214,13 @@ ELSE()
ENDIF()
ENDIF()
IF(OSGVIEWER_USE_XINERAMA)
ADD_DEFINITIONS(-DOSGVIEWER_USE_XINERAMA)
SET(LIB_PRIVATE_HEADERS ${LIB_PRIVATE_HEADERS} ${XINERAMA_INCLUDE_DIRS} )
SET(LIB_EXTRA_LIBS -lXinerama ${LIB_EXTRA_LIBS})
ENDIF()
# X11 on Apple requires X11 library plus OpenGL linking hack on Leopard
IF(APPLE)
# hack for finding the iphone opengl es lib
IF(OSG_BUILD_PLATFORM_IPHONE OR OSG_BUILD_PLATFORM_IPHONE_SIMULATOR)

View File

@ -38,6 +38,10 @@
#include <X11/extensions/Xrandr.h>
#endif
#ifdef OSGVIEWER_USE_XINERAMA
#include <X11/extensions/Xinerama.h>
#endif
#include <unistd.h>
using namespace osgViewer;
@ -382,23 +386,95 @@ bool GraphicsWindowX11::checkAndSendEventFullScreenIfNeeded(Display* display, in
Atom netWMStateAtom = XInternAtom(display, "_NET_WM_STATE", True);
Atom netWMStateFullscreenAtom = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", True);
OSG_NOTICE<<"GraphicsWindowX11::checkAndSendEventFullScreenIfNeeded()"<<std::endl;
if (netWMStateAtom != None && netWMStateFullscreenAtom != None)
{
XEvent xev;
xev.xclient.type = ClientMessage;
xev.xclient.serial = 0;
xev.xclient.send_event = True;
xev.xclient.window = _window;
xev.xclient.message_type = netWMStateAtom;
xev.xclient.format = 32;
xev.xclient.data.l[0] = isFullScreen ? 1 : 0;
xev.xclient.data.l[1] = netWMStateFullscreenAtom;
xev.xclient.data.l[2] = 0;
// set up full screen
{
XEvent xev;
xev.xclient.type = ClientMessage;
xev.xclient.serial = 0;
xev.xclient.send_event = True;
xev.xclient.window = _window;
xev.xclient.message_type = netWMStateAtom;
xev.xclient.format = 32;
xev.xclient.data.l[0] = isFullScreen ? 1 : 0;
xev.xclient.data.l[1] = netWMStateFullscreenAtom;
xev.xclient.data.l[2] = 0;
XSendEvent(display, RootWindow(display, DefaultScreen(display)),
False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
XSendEvent(display, RootWindow(display, DefaultScreen(display)),
False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
}
#ifdef OSGVIEWER_USE_XINERAMA
// Span all monitors
if( isFullScreen && XineramaIsActive( display ) )
{
int numMonitors;
XineramaScreenInfo* xi = XineramaQueryScreens( display, &numMonitors );
enum {
TopMost,
BottomMost,
LeftMost,
RightMost
};
uint32_t span[4] = { 0, 0, 0, 0 };
int32_t minx = 2147483647; // INT_MAX
int32_t maxx = -2147483648; // INT_MIN
int32_t miny = 2147483647; // INT_MAX
int32_t maxy = -2147483648; // INT_MIN
for( int i = 0; i < numMonitors; i++ )
{
if( xi[i].x_org < minx )
{
span[LeftMost] = xi[i].screen_number;
minx = xi[i].x_org;
}
if( xi[i].x_org > maxx )
{
span[RightMost] = xi[i].screen_number;
maxx = xi[i].x_org;
}
if( xi[i].y_org < miny )
{
span[TopMost] = xi[i].screen_number;
miny = xi[i].y_org;
}
if( xi[i].y_org > maxy )
{
span[BottomMost] = xi[i].screen_number;
maxy = xi[i].y_org;
}
}
XFree(xi);
Atom fullmons = XInternAtom(display, "_NET_WM_FULLSCREEN_MONITORS", True);
if( fullmons != None )
{
XEvent xev;
xev.type = ClientMessage;
xev.xclient.window = _window;
xev.xclient.message_type = fullmons;
xev.xclient.format = 32;
xev.xclient.data.l[0] = span[TopMost];
xev.xclient.data.l[1] = span[BottomMost];
xev.xclient.data.l[2] = span[LeftMost];
xev.xclient.data.l[3] = span[RightMost];
xev.xclient.data.l[4] = 0;
XSendEvent( display, DefaultRootWindow(display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
}
}
#endif
return true;
}
return false;
}
@ -1328,6 +1404,7 @@ bool GraphicsWindowX11::checkEvents()
bool isModifier = keyMapGetKey(modMap, key);
if (!isModifier) forceKey(key, eventTime, false);
}
needNewWindowSize = true;
// release modifier keys
for (unsigned int key = 8; key < 256; key++)
@ -1367,6 +1444,7 @@ bool GraphicsWindowX11::checkEvents()
bool isPressed = keyMapGetKey(keyMap, key);
if (!isPressed) forceKey(key, eventTime, false);
}
needNewWindowSize = true;
// press/release modifier keys
for (unsigned int key = 8; key < 256; key++)