From 69659ade0871e98387c3a371383b53b36d2272e7 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 23 Jun 2011 18:29:35 +0000 Subject: [PATCH] Merged from svn/trunk changeset r12573, Added catch for window manager doesn't set the window size to full screen. --- src/osgViewer/GraphicsWindowX11.cpp | 109 +++++++++++++++++----------- 1 file changed, 66 insertions(+), 43 deletions(-) diff --git a/src/osgViewer/GraphicsWindowX11.cpp b/src/osgViewer/GraphicsWindowX11.cpp index 42f8f8a25..03f7ce4d8 100644 --- a/src/osgViewer/GraphicsWindowX11.cpp +++ b/src/osgViewer/GraphicsWindowX11.cpp @@ -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 #include @@ -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"<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 ); }