diff --git a/src/osgViewer/GraphicsWindowX11.cpp b/src/osgViewer/GraphicsWindowX11.cpp index c95b2f399..1f18e5d9d 100644 --- a/src/osgViewer/GraphicsWindowX11.cpp +++ b/src/osgViewer/GraphicsWindowX11.cpp @@ -396,8 +396,7 @@ bool GraphicsWindowX11::checkAndSendEventFullScreenIfNeeded(Display* display, in 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); + Atom netWMStateFullscreenAtom = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", True); if (netWMStateAtom != None && netWMStateFullscreenAtom != None) { XEvent xev; @@ -439,28 +438,34 @@ bool GraphicsWindowX11::setWindowDecorationImplementation(bool flag) if( (atom = XInternAtom( display, "_MOTIF_WM_HINTS", 0 )) != None ) { - wmHints.flags = 0; - wmHints.functions = MWM_FUNC_ALL; - wmHints.decorations = MWM_DECOR_ALL; - wmHints.inputMode = 0; - wmHints.status = 0; - - if (!flag) + if (flag) { - wmHints.flags = MWM_HINTS_DECORATIONS; - wmHints.decorations = 0; + wmHints.flags = MWM_HINTS_DECORATIONS | MWM_HINTS_FUNCTIONS; + wmHints.functions = MWM_FUNC_ALL; + wmHints.decorations = MWM_DECOR_ALL; + wmHints.inputMode = 0; + wmHints.status = 0; + + // if traits says not resize we want to set the functions to exlude MWM_FUNC_RESIZE, + // but this bitmask needs to be set if the MWM_FUNC_ALL bit is already set in order to toggle it off. + if (_traits.valid() && !_traits->supportsResize) wmHints.functions = wmHints.functions | MWM_FUNC_RESIZE; + } else { - wmHints.flags |= MWM_HINTS_FUNCTIONS; - if (_traits.valid() && !_traits->supportsResize) wmHints.functions |= MWM_FUNC_RESIZE; + wmHints.flags = MWM_HINTS_DECORATIONS; + wmHints.functions = 0; + wmHints.decorations = 0; + wmHints.inputMode = 0; + wmHints.status = 0; } + XChangeProperty( display, _window, atom, atom, 32, PropModeReplace, (unsigned char *)&wmHints, 5 ); result = true; } else { - OSG_NOTICE<<"Error: GraphicsWindowX11::setBorder(" << flag << ") - couldn't change decorations." << std::endl; + OSG_NOTICE<<"Error: GraphicsWindowX11::setWindowDecorationImplementation(" << flag << ") - couldn't change decorations." << std::endl; result = false; } @@ -479,13 +484,13 @@ bool GraphicsWindowX11::setWindowRectangleImplementation(int x, int y, int width Display* display = getDisplayToUse(); + checkAndSendEventFullScreenIfNeeded(display, x, y, width, height, _traits->windowDecoration); + XMoveResizeWindow(display, _window, x, y, width, height); XFlush(display); XSync(display, 0); - - checkAndSendEventFullScreenIfNeeded(display, x, y, width, height, _traits->windowDecoration); - + // add usleep here to give window manager a chance to handle the request, if // we don't add this sleep then any X11 calls right afterwards can produce // X11 errors. @@ -854,10 +859,45 @@ bool GraphicsWindowX11::createWindow() OSG_INFO<<"Setting override redirect"<x; + int y = _traits->y; + int width = _traits->width; + int height = _traits->height; + + { + // 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; + + if (isFullScreen) + { + // artifically reduce the initial window size so that the windowing + // system has a size to go back to when toggling off full screen, + // we don't have to worry about the window being initially smaller as the + // setWindowDecoration(..) implementation with enable full screen for us + x = width/4; + y = height/4; + width /= 2; + height /= 2; + } + } + _window = XCreateWindow( _display, _parent, - _traits->x, - _traits->y, - _traits->width, _traits->height, 0, + x, + y, + width, height, 0, _visualInfo->depth, InputOutput, _visualInfo->visual, mask, &swatt );