# HG changeset patch # User Philipp Lohmann [pl] <Philipp.Lohmann@Sun.COM> # Date 1271777499 -7200 # Node ID a03d0eb91d8d7a0febae6505ebf7caf6f4350491 # Parent a3caa2c60ac10fa77a881c07d291e000b60738d4 ooo321gsl05: #i107249# update fullscreen handling diff -r a3caa2c60ac1 -r a03d0eb91d8d vcl/unx/gtk/window/gtkframe.cxx --- a/vcl/unx/gtk/window/gtkframe.cxx Fri Mar 26 16:57:56 2010 +0100 +++ b/vcl/unx/gtk/window/gtkframe.cxx Tue Apr 20 17:31:39 2010 +0200 @@ -688,9 +688,9 @@ pHints->input = bAccept ? True : False; XSetWMHints( pDisplay, aWindow, pHints ); XFree( pHints ); - + if (GetX11SalData()->GetDisplay()->getWMAdaptor()->getWindowManagerName().EqualsAscii("compiz")) - return; + return; /* remove WM_TAKE_FOCUS protocol; this would usually be the * right thing, but gtk handles it internally whereas we @@ -837,7 +837,8 @@ eType = GDK_WINDOW_TYPE_HINT_UTILITY; } - if( (nStyle & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN ) ) + if( (nStyle & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN ) + && getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) { eType = GDK_WINDOW_TYPE_HINT_TOOLBAR; gtk_window_set_keep_above( GTK_WINDOW(m_pWindow), true ); @@ -1297,7 +1298,8 @@ { if( m_pWindow ) { - if( m_pParent && (m_pParent->m_nStyle & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN) ) + if( m_pParent && (m_pParent->m_nStyle & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN) + && getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) gtk_window_set_keep_above( GTK_WINDOW(m_pWindow), bVisible ); if( bVisible ) { @@ -1458,6 +1460,12 @@ aHints |= GDK_HINT_MAX_SIZE; } } + if( m_bFullscreen ) + { + aGeo.max_width = m_aMaxSize.Width(); + aGeo.max_height = m_aMaxSize.Height(); + aHints |= GDK_HINT_MAX_SIZE; + } if( aHints ) gtk_window_set_geometry_hints( GTK_WINDOW(m_pWindow), NULL, @@ -1809,8 +1817,6 @@ { m_aRestorePosSize = Rectangle( Point( maGeometry.nX, maGeometry.nY ), Size( maGeometry.nWidth, maGeometry.nHeight ) ); - // workaround different window managers have different opinions about - // _NET_WM_STATE_FULLSCREEN (Metacity <-> KWin) bool bVisible = GTK_WIDGET_MAPPED(m_pWindow); if( bVisible ) Show( FALSE ); @@ -1827,12 +1833,22 @@ gtk_window_move( GTK_WINDOW(m_pWindow), maGeometry.nX = aNewPosSize.Left(), maGeometry.nY = aNewPosSize.Top() ); + // #i110881# for the benefit of compiz set a max size here + // else setting to fullscreen fails for unknown reasons + m_aMaxSize.Width() = aNewPosSize.GetWidth()+100; + m_aMaxSize.Height() = aNewPosSize.GetHeight()+100; + // workaround different legacy version window managers have different opinions about + // _NET_WM_STATE_FULLSCREEN (Metacity <-> KWin) + if( ! getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) + gtk_window_fullscreen( GTK_WINDOW( m_pWindow ) ); if( bVisible ) Show( TRUE ); } else { bool bVisible = GTK_WIDGET_MAPPED(m_pWindow); + if( ! getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) + gtk_window_unfullscreen( GTK_WINDOW(m_pWindow) ); if( bVisible ) Show( FALSE ); m_nStyle &= ~SAL_FRAME_STYLE_PARTIAL_FULLSCREEN; @@ -1855,8 +1871,11 @@ { if( bFullScreen ) { - if( !(m_nStyle & SAL_FRAME_STYLE_SIZEABLE) ) - gtk_window_set_resizable( GTK_WINDOW(m_pWindow), TRUE ); + if( getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) + { + if( !(m_nStyle & SAL_FRAME_STYLE_SIZEABLE) ) + gtk_window_set_resizable( GTK_WINDOW(m_pWindow), TRUE ); + } gtk_window_fullscreen( GTK_WINDOW(m_pWindow) ); moveToScreen( nScreen ); Size aScreenSize = pDisp->GetScreenSize( m_nScreen ); @@ -1868,8 +1887,11 @@ else { gtk_window_unfullscreen( GTK_WINDOW(m_pWindow) ); - if( !(m_nStyle & SAL_FRAME_STYLE_SIZEABLE) ) - gtk_window_set_resizable( GTK_WINDOW(m_pWindow), FALSE ); + if( getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) + { + if( !(m_nStyle & SAL_FRAME_STYLE_SIZEABLE) ) + gtk_window_set_resizable( GTK_WINDOW(m_pWindow), FALSE ); + } moveToScreen( nScreen ); } } @@ -3171,6 +3193,15 @@ } pThis->m_nState = pEvent->window_state.new_window_state; + #if OSL_DEBUG_LEVEL > 1 + if( (pEvent->window_state.changed_mask & GDK_WINDOW_STATE_FULLSCREEN) ) + { + fprintf( stderr, "window %p %s full screen state\n", + pThis, + (pEvent->window_state.new_window_state & GDK_WINDOW_STATE_FULLSCREEN) ? "enters" : "leaves"); + } + #endif + return FALSE; } diff -r a3caa2c60ac1 -r a03d0eb91d8d vcl/unx/inc/wmadaptor.hxx --- a/vcl/unx/inc/wmadaptor.hxx Fri Mar 26 16:57:56 2010 +0100 +++ b/vcl/unx/inc/wmadaptor.hxx Tue Apr 20 17:31:39 2010 +0200 @@ -160,6 +160,7 @@ m_aWMWorkAreas; bool m_bTransientBehaviour; bool m_bEnableAlwaysOnTopWorks; + bool m_bLegacyPartialFullscreen; int m_nWinGravity; int m_nInitWinGravity; @@ -231,6 +232,15 @@ */ virtual void showFullScreen( X11SalFrame* pFrame, bool bFullScreen ) const; /* + * tell whether legacy partial full screen handling is necessary + * see #i107249#: NET_WM_STATE_FULLSCREEN is not well defined, but de facto + * modern WM's interpret it the "right" way, namely they make "full screen" + * taking twin view or Xinerama into accound and honor the positioning hints + * to see which screen actually was meant to use for fullscreen. + */ + bool isLegacyPartialFullscreen() const + { return m_bLegacyPartialFullscreen; } + /* * set window struts */ virtual void setFrameStruts( X11SalFrame*pFrame, diff -r a3caa2c60ac1 -r a03d0eb91d8d vcl/unx/source/app/wmadaptor.cxx --- a/vcl/unx/source/app/wmadaptor.cxx Fri Mar 26 16:57:56 2010 +0100 +++ b/vcl/unx/source/app/wmadaptor.cxx Tue Apr 20 17:31:39 2010 +0200 @@ -233,6 +233,7 @@ m_pSalDisplay( pDisplay ), m_bTransientBehaviour( true ), m_bEnableAlwaysOnTopWorks( false ), + m_bLegacyPartialFullscreen( false ), m_nWinGravity( StaticGravity ), m_nInitWinGravity( StaticGravity ) { @@ -909,6 +910,40 @@ XFree( pProperty ); pProperty = NULL; } + // if this is metacity, check for version to enable a legacy workaround + if( m_aWMName.EqualsAscii( "Metacity" ) ) + { + int nVersionMajor = 0, nVersionMinor = 0; + Atom nVersionAtom = XInternAtom( m_pDisplay, "_METACITY_VERSION", True ); + if( nVersionAtom ) + { + if( XGetWindowProperty( m_pDisplay, + aWMChild, + nVersionAtom, + 0, 256, + False, + m_aWMAtoms[ UTF8_STRING ], + &aRealType, + &nFormat, + &nItems, + &nBytesLeft, + &pProperty ) == 0 + && nItems != 0 + ) + { + String aMetaVersion( (sal_Char*)pProperty, nItems, RTL_TEXTENCODING_UTF8 ); + nVersionMajor = aMetaVersion.GetToken( 0, '.' ).ToInt32(); + nVersionMinor = aMetaVersion.GetToken( 1, '.' ).ToInt32(); + } + if( pProperty ) + { + XFree( pProperty ); + pProperty = NULL; + } + } + if( nVersionMajor < 2 || (nVersionMajor == 2 && nVersionMinor < 12) ) + m_bLegacyPartialFullscreen = true; + } } } else if( pProperty ) diff -r a3caa2c60ac1 -r a03d0eb91d8d vcl/unx/source/window/salframe.cxx --- a/vcl/unx/source/window/salframe.cxx Fri Mar 26 16:57:56 2010 +0100 +++ b/vcl/unx/source/window/salframe.cxx Tue Apr 20 17:31:39 2010 +0200 @@ -549,6 +549,14 @@ pHints->win_gravity = GetDisplay()->getWMAdaptor()->getPositionWinGravity(); pHints->x = 0; pHints->y = 0; + if( mbFullScreen ) + { + pHints->flags |= PMaxSize | PMinSize; + pHints->max_width = w+100; + pHints->max_height = h+100; + pHints->min_width = w; + pHints->min_height = h; + } XSetWMNormalHints( GetXDisplay(), GetShellWindow(), pHints ); @@ -605,7 +613,8 @@ eType = WMAdaptor::windowType_Utility; if( nStyle_ & SAL_FRAME_STYLE_OWNERDRAWDECORATION ) eType = WMAdaptor::windowType_Toolbar; - if( nStyle_ & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN ) + if( (nStyle_ & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN) + && GetDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) eType = WMAdaptor::windowType_Dock; GetDisplay()->getWMAdaptor()-> @@ -1130,7 +1139,7 @@ // even though transient frames should be kept above their parent // this does not necessarily hold true for DOCK type windows // so artificially set ABOVE and remove it again on hide - if( mpParent && (mpParent->nStyle_ & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN ) ) + if( mpParent && (mpParent->nStyle_ & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN ) && pDisplay_->getWMAdaptor()->isLegacyPartialFullscreen()) pDisplay_->getWMAdaptor()->enableAlwaysOnTop( this, bVisible ); bMapped_ = bVisible; @@ -1322,11 +1331,6 @@ } else { -#if OSL_DEBUG_LEVEL > 1 - if( nStyle_ & SAL_FRAME_STYLE_OWNERDRAWDECORATION ) - fprintf( stderr, "hide on ownerdraw\n" ); -#endif - if( getInputContext() ) getInputContext()->Unmap( this ); @@ -1579,7 +1583,7 @@ { if( nStyle_ & SAL_FRAME_STYLE_PLUG ) return; - + // relative positioning in X11SalFrame::SetPosSize Rectangle aPosSize( Point( maGeometry.nX, maGeometry.nY ), Size( maGeometry.nWidth, maGeometry.nHeight ) ); aPosSize.Justify(); @@ -1616,6 +1620,7 @@ } else SetPosSize( aPosSize ); + bDefaultPosition_ = False; } @@ -2042,6 +2047,12 @@ pHints->y = values.y; pHints->win_gravity = pDisplay_->getWMAdaptor()->getPositionWinGravity(); } + if( mbFullScreen ) + { + pHints->max_width = 10000; + pHints->max_height = 10000; + pHints->flags |= PMaxSize; + } XSetWMNormalHints( GetXDisplay(), GetShellWindow(), pHints ); @@ -2199,28 +2210,15 @@ maGeometry.nWidth = aRect.GetWidth(); maGeometry.nHeight = aRect.GetHeight(); mbMaximizedHorz = mbMaximizedVert = false; + mbFullScreen = true; createNewWindow( None, m_nScreen ); - GetDisplay()->getWMAdaptor()->enableAlwaysOnTop( this, true ); - #if 0 - // this would give additional intent to the window - // manager to force the positioning of the window; - // alas all other windows will be expunged from that - // region, leaving us in a pity state afterwards - Size aScreenSize = pDisplay_->GetScreenSize( m_nScreen ); - pDisplay_->getWMAdaptor()->setFrameStruts( this, - aRect.Left(), aRect.Top(), - aScreenSize.Width() - aRect.Right(), - aScreenSize.Height() - aRect.Bottom(), - aRect.Left(), aRect.Right(), - aRect.Top(), aRect.Bottom(), - aRect.Left(), aRect.Right(), - aRect.Top(), aRect.Bottom() - ); - #endif - + if( GetDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) + GetDisplay()->getWMAdaptor()->enableAlwaysOnTop( this, true ); + else + GetDisplay()->getWMAdaptor()->showFullScreen( this, true ); if( bVisible ) Show(TRUE); - mbFullScreen = true; + } else {