Merged from svn/trunk changeset r12573, Added catch for window manager doesn't set the window size to full screen.

This commit is contained in:
Robert Osfield
2011-06-23 18:29:35 +00:00
parent d4e68e5d73
commit 69659ade08

View File

@@ -18,7 +18,6 @@
// TODO:
// implement http://www.opengl.org/registry/specs/OML/glx_swap_method.txt
// Fix toggling of fullscreen to window mode as it does enable window decoration with recent linux window managers
#include <osgViewer/api/X11/GraphicsWindowX11>
#include <osgViewer/api/X11/PixelBufferX11>
@@ -360,6 +359,45 @@ bool GraphicsWindowX11::createVisualInfo()
return _visualInfo != 0;
}
bool GraphicsWindowX11::checkAndSendEventFullScreenIfNeeded(Display* display, int x, int y, int width, int height, bool windowDecoration)
{
osg::GraphicsContext::WindowingSystemInterface *wsi = osg::GraphicsContext::getWindowingSystemInterface();
if (wsi == NULL)
{
OSG_NOTICE << "Error, no WindowSystemInterface available, cannot toggle window fullscreen." << std::endl;
return false;
}
unsigned int screenWidth;
unsigned int screenHeight;
wsi->getScreenResolution(*_traits, screenWidth, screenHeight);
bool isFullScreen = x == 0 && y == 0 && width == (int)screenWidth && height == (int)screenHeight && !windowDecoration;
Atom netWMStateAtom = XInternAtom(display, "_NET_WM_STATE", True);
Atom netWMStateFullscreenAtom = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", True);
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;
XSendEvent(display, RootWindow(display, DefaultScreen(display)),
False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
return true;
}
return false;
}
#define MWM_HINTS_FUNCTIONS (1L << 0)
#define MWM_HINTS_DECORATIONS (1L << 1)
#define MWM_HINTS_INPUT_MODE (1L << 2)
@@ -380,43 +418,6 @@ bool GraphicsWindowX11::createVisualInfo()
#define MWM_FUNC_MAXIMIZE (1L<<4)
#define MWM_FUNC_CLOSE (1L<<5)
bool GraphicsWindowX11::checkAndSendEventFullScreenIfNeeded(Display* display, int x, int y, int width, int height, bool windowDecoration)
{
osg::GraphicsContext::WindowingSystemInterface *wsi = osg::GraphicsContext::getWindowingSystemInterface();
if (wsi == NULL) {
OSG_NOTICE << "Error, no WindowSystemInterface available, cannot toggle window fullscreen." << std::endl;
return false;
}
unsigned int screenWidth;
unsigned int screenHeight;
wsi->getScreenResolution(*_traits, screenWidth, screenHeight);
bool isFullScreen = x == 0 && y == 0 && width == (int)screenWidth && height == (int)screenHeight && !windowDecoration;
Atom netWMStateAtom = XInternAtom(display, "_NET_WM_STATE", True);
Atom netWMStateFullscreenAtom = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", True);
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;
XSendEvent(display, RootWindow(display, DefaultScreen(display)),
False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
return true;
}
return false;
}
bool GraphicsWindowX11::setWindowDecorationImplementation(bool flag)
{
Display* display = getDisplayToUse();
@@ -871,17 +872,24 @@ bool GraphicsWindowX11::createWindow()
int width = _traits->width;
int height = _traits->height;
unsigned int screenWidth;
unsigned int screenHeight;
wsi->getScreenResolution(*_traits, screenWidth, screenHeight);
bool doFullSceenWorkAround = false;
bool isFullScreen = x == 0 && y == 0 && width == (int)screenWidth && height == (int)screenHeight && !_traits->windowDecoration;
if (isFullScreen && !_traits->overrideRedirect)
{
// follows is hack to get around problems with toggling off full screen with modern X11 window
// managers that try to be too clever when toggling off full screen and ignore the window size
// calls made by the OSG when the initial window size is full screen.
unsigned int screenWidth;
unsigned int screenHeight;
wsi->getScreenResolution(*_traits, screenWidth, screenHeight);
bool isFullScreen = x == 0 && y == 0 && width == (int)screenWidth && height == (int)screenHeight && !_traits->windowDecoration;
Atom netWMStateAtom = XInternAtom(_display, "_NET_WM_STATE", True);
Atom netWMStateFullscreenAtom = XInternAtom(_display, "_NET_WM_STATE_FULLSCREEN", True);
if (isFullScreen)
// we have a modern X11 server so assume we need the do the full screen hack.
if (netWMStateAtom != None && netWMStateFullscreenAtom != None)
{
// artifically reduce the initial window size so that the windowing
// system has a size to go back to when toggling off full screen,
@@ -891,6 +899,8 @@ bool GraphicsWindowX11::createWindow()
y = height/4;
width /= 2;
height /= 2;
doFullSceenWorkAround = true;
}
}
@@ -930,6 +940,7 @@ bool GraphicsWindowX11::createWindow()
setWindowDecoration(_traits->windowDecoration);
useCursor(_traits->useCursor);
_deleteWindow = XInternAtom (_display, "WM_DELETE_WINDOW", False);
@@ -945,6 +956,18 @@ bool GraphicsWindowX11::createWindow()
if (_traits->x != watt.x || _traits->y != watt.y
||_traits->width != watt.width || _traits->height != watt.height)
{
if (doFullSceenWorkAround)
{
OSG_INFO<<"Full Screen failed, resizing manually"<<std::endl;
XMoveResizeWindow(_display, _window, _traits->x, _traits->y, _traits->width, _traits->height);
XFlush(_display);
XSync(_display, 0);
XGetWindowAttributes( _display, _window, &watt );
}
resized( watt.x, watt.y, watt.width, watt.height );
}