diff options
-rw-r--r-- | framework/inc/helper/persistentwindowstate.hxx | 2 | ||||
-rw-r--r-- | framework/source/dispatch/closedispatcher.cxx | 17 | ||||
-rw-r--r-- | framework/source/helper/persistentwindowstate.cxx | 29 | ||||
-rw-r--r-- | sfx2/source/view/viewfrm.cxx | 17 | ||||
-rw-r--r-- | vcl/inc/osx/salframe.h | 2 | ||||
-rw-r--r-- | vcl/osx/salframe.cxx | 118 | ||||
-rw-r--r-- | vcl/osx/salframeview.mm | 28 | ||||
-rw-r--r-- | vcl/osx/vclnsapp.mm | 2 |
8 files changed, 113 insertions, 102 deletions
diff --git a/framework/inc/helper/persistentwindowstate.hxx b/framework/inc/helper/persistentwindowstate.hxx index e6b5c47d8c72..f9062d4344c4 100644 --- a/framework/inc/helper/persistentwindowstate.hxx +++ b/framework/inc/helper/persistentwindowstate.hxx @@ -119,6 +119,8 @@ class PersistentWindowState : public ::cppu::WeakImplHelper< static OUString implst_getWindowStateFromConfig(const css::uno::Reference< css::uno::XComponentContext >& rxContext , const OUString& sModuleName); + static bool implst_isWindowFullScreen(const css::uno::Reference< css::awt::XWindow >& xWindow); + /** @short retrieve the window state from the container window. @param xWindow diff --git a/framework/source/dispatch/closedispatcher.cxx b/framework/source/dispatch/closedispatcher.cxx index ed79058194ab..1fc959734168 100644 --- a/framework/source/dispatch/closedispatcher.cxx +++ b/framework/source/dispatch/closedispatcher.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -38,6 +38,7 @@ #include <vcl/window.hxx> #include <vcl/svapp.hxx> #include <vcl/syswin.hxx> +#include <vcl/wrkwin.hxx> #include <unotools/moduleoptions.hxx> using namespace com::sun::star; @@ -176,6 +177,20 @@ void SAL_CALL CloseDispatcher::dispatchWithNotification(const css::util::URL& return; } +#ifdef MACOSX + // FIXME: In full-screen mode, if we call ShowFullScreenMode(false) here, it leads to a crash + // later, so disallow closing for now. And yes, if we don't allow closing a window that is in + // full-screen mode, the menu entry should be greyed out then, too. But doing that looks + // insanely hard, too. I am so tempted to just abort this and instead just don't even try to + // support the system full-screen mode. + if (m_pSysWindow) + { + WorkWindow *pWorkWindow = dynamic_cast<WorkWindow*>(m_pSysWindow.get()); + if (pWorkWindow && pWorkWindow->IsFullScreenMode()) + return; + } +#endif + if (m_pSysWindow && m_pSysWindow->GetCloseHdl().IsSet()) { // The closing frame has its own close handler. Call it instead. diff --git a/framework/source/helper/persistentwindowstate.cxx b/framework/source/helper/persistentwindowstate.cxx index ecec7f39d63c..e20a152a19d2 100644 --- a/framework/source/helper/persistentwindowstate.cxx +++ b/framework/source/helper/persistentwindowstate.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -125,6 +125,11 @@ void SAL_CALL PersistentWindowState::frameAction(const css::frame::FrameActionEv case css::frame::FrameAction_COMPONENT_DETACHING : { + // FIXME: Hack: Don't save state for full-screen windows. We can't properly restore + // them anyway. + if (implst_isWindowFullScreen(xWindow)) + break; + OUString sWindowState = PersistentWindowState::implst_getWindowStateFromWindow(xWindow); PersistentWindowState::implst_setWindowStateOnConfig(xContext, sModuleName, sWindowState); } @@ -199,6 +204,28 @@ void PersistentWindowState::implst_setWindowStateOnConfig( {} } +bool PersistentWindowState::implst_isWindowFullScreen(const css::uno::Reference< css::awt::XWindow >& xWindow) +{ + bool bRetval = false; + + if (xWindow.is()) + { + SolarMutexGuard aSolarGuard; + + VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(xWindow); + if ( pWindow && pWindow->IsSystemWindow() ) + { + WindowStateData aWSD; + aWSD.SetMask(WindowStateMask::All); + static_cast<SystemWindow*>(pWindow.get())->GetWindowStateData(aWSD); + if (aWSD.GetState() & WindowStateState::FullScreen) + bRetval = true; + } + } + + return bRetval; +} + OUString PersistentWindowState::implst_getWindowStateFromWindow(const css::uno::Reference< css::awt::XWindow >& xWindow) { OUString sWindowState; diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx index 8fe2079492c5..5221205801ea 100644 --- a/sfx2/source/view/viewfrm.cxx +++ b/sfx2/source/view/viewfrm.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -146,7 +146,11 @@ void SfxViewFrame::InitInterface_Impl() GetStaticInterface()->RegisterChildWindow(SID_BROWSER); GetStaticInterface()->RegisterChildWindow(SID_RECORDING_FLOATWINDOW); #if HAVE_FEATURE_DESKTOP +#ifndef MACOSX + // No floating toolbar to exit full-screen mode on macOS please; there is a system way to do it + // and that is what we want. GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_FULLSCREEN, SfxVisibilityFlags::FullScreen, ToolbarId::FullScreenToolbox); +#endif GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_APPLICATION, SfxVisibilityFlags::Standard, ToolbarId::EnvToolbox); #endif } @@ -2710,7 +2714,10 @@ void SfxViewFrame::MiscExec_Impl( SfxRequest& rReq ) css::uno::Reference< css::frame::XFrame > xFrame( GetFrame().GetFrameInterface(), css::uno::UNO_QUERY); - +#ifndef MACOSX + // On macOS we don't deactivate the menu bar in system full-screen mode, which + // is how we implement the LibreOffice full-screen mode. The menu bar auto-hides + // in the full-screen mode. Reference< css::beans::XPropertySet > xPropSet( xFrame, UNO_QUERY ); Reference< css::frame::XLayoutManager > xLayoutManager; if ( xPropSet.is() ) @@ -2724,10 +2731,11 @@ void SfxViewFrame::MiscExec_Impl( SfxRequest& rReq ) { } } - +#endif bool bNewFullScreenMode = pItem ? pItem->GetValue() : !pWork->IsFullScreenMode(); if ( bNewFullScreenMode != pWork->IsFullScreenMode() ) { +#ifndef MACOSX Reference< css::beans::XPropertySet > xLMPropSet( xLayoutManager, UNO_QUERY ); if ( xLMPropSet.is() ) { @@ -2741,8 +2749,11 @@ void SfxViewFrame::MiscExec_Impl( SfxRequest& rReq ) { } } +#endif pWork->ShowFullScreenMode( bNewFullScreenMode ); +#ifndef MACOSX pWork->SetMenuBarMode( bNewFullScreenMode ? MenuBarMode::Hide : MenuBarMode::Normal ); +#endif GetFrame().GetWorkWindow_Impl()->SetFullScreen_Impl( bNewFullScreenMode ); if ( !pItem ) rReq.AppendItem( SfxBoolItem( SID_WIN_FULLSCREEN, bNewFullScreenMode ) ); diff --git a/vcl/inc/osx/salframe.h b/vcl/inc/osx/salframe.h index c2b53e270648..c615690946f4 100644 --- a/vcl/inc/osx/salframe.h +++ b/vcl/inc/osx/salframe.h @@ -38,7 +38,6 @@ #include <stdexcept> class AquaSalGraphics; -class AquaSalFrame; class AquaSalTimer; class AquaSalInstance; class AquaSalMenu; @@ -61,7 +60,6 @@ public: int mnMinHeight; // min. client height in pixels int mnMaxWidth; // max. client width in pixels int mnMaxHeight; // max. client height in pixels - NSRect maFullScreenRect; // old window size when in FullScreen bool mbGraphics; // is Graphics used? bool mbFullScreen; // is Window in FullScreen? bool mbShown; diff --git a/vcl/osx/salframe.cxx b/vcl/osx/salframe.cxx index 31159f8545c0..567660285e4e 100644 --- a/vcl/osx/salframe.cxx +++ b/vcl/osx/salframe.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -24,6 +24,7 @@ #include <osl/file.h> +#include <comphelper/dispatchcommand.hxx> #include <vcl/svapp.hxx> #include <vcl/window.hxx> #include <vcl/syswin.hxx> @@ -214,10 +215,6 @@ SAL_WNODEPRECATED_DECLARATIONS_POP [mpNSWindow setDelegate: static_cast<id<NSWindowDelegate> >(mpNSWindow)]; - if( [mpNSWindow respondsToSelector: @selector(setRestorable:)]) - { - objc_msgSend(mpNSWindow, @selector(setRestorable:), NO); - } const NSRect aRect = { NSZeroPoint, NSMakeSize( maGeometry.nWidth, maGeometry.nHeight )}; mnTrackingRectTag = [mpNSView addTrackingRect: aRect owner: mpNSView userData: nil assumeInside: NO]; @@ -572,11 +569,26 @@ void AquaSalFrame::SetWindowState( const SalFrameState* pState ) else if( [mpNSWindow isMiniaturized] ) [mpNSWindow deminiaturize: NSApp]; + if ( pState->mnState == WindowStateState::FullScreen ) + { + if (!mbFullScreen) + { + // FIXME: What to do here? This doesn't work, the window does not go full-screen: + // comphelper::dispatchCommand( ".uno:FullScreen", {} ); + + // And neither does this, the window goes full-screen but the View:Full Screen menu + // entry is not checked. + // ShowFullScreen( true, 0 ); + + // If this is fixed, then the "FIXME: Hack:" in PersistentWindowState::frameAction() + // can be dropped. + } + } /* ZOOMED is not really maximized (actually it toggles between a user set size and the program specified one), but comes closest since the default behavior is "maximized" if the user did not intervene */ - if( pState->mnState == WindowStateState::Maximized ) + else if( pState->mnState == WindowStateState::Maximized ) { if(! [mpNSWindow isZoomed]) [mpNSWindow zoom: NSApp]; @@ -638,7 +650,9 @@ bool AquaSalFrame::GetWindowState( SalFrameState* pState ) pState->mnWidth = long(aStateRect.size.width); pState->mnHeight = long(aStateRect.size.height); - if( [mpNSWindow isMiniaturized] ) + if( mbFullScreen ) + pState->mnState = WindowStateState::FullScreen; + else if( [mpNSWindow isMiniaturized] ) pState->mnState = WindowStateState::Minimized; else if( ! [mpNSWindow isZoomed] ) pState->mnState = WindowStateState::Normal; @@ -690,7 +704,7 @@ void AquaSalFrame::ShowFullScreen( bool bFullScreen, sal_Int32 nDisplay ) if ( !mpNSWindow ) return; - SAL_INFO("vcl.osx", OSL_THIS_FUNC << ": mbFullScreen=" << mbFullScreen << ", bFullScreen=" << bFullScreen); + SAL_INFO("vcl.osx", "AquaSalFrame::ShowFullScreen: mbFullScreen=" << mbFullScreen << ", bFullScreen=" << bFullScreen); if( mbFullScreen == bFullScreen ) return; @@ -699,84 +713,23 @@ void AquaSalFrame::ShowFullScreen( bool bFullScreen, sal_Int32 nDisplay ) mbFullScreen = bFullScreen; - if( bFullScreen ) + NSUInteger nCurrentSystemStyle = [mpNSWindow styleMask]; + if( ((nCurrentSystemStyle & NSWindowStyleMaskFullScreen) && !mbFullScreen) + || (!(nCurrentSystemStyle & NSWindowStyleMaskFullScreen) && mbFullScreen) ) { - // hide the dock and the menubar if we are on the menu screen - // which is always on index 0 according to documentation - bool bHideMenu = (nDisplay == 0); - - NSRect aNewContentRect = NSZeroRect; - // get correct screen - NSScreen* pScreen = nil; - NSArray* pScreens = [NSScreen screens]; - if( pScreens ) - { - if( nDisplay >= 0 && static_cast<unsigned int>(nDisplay) < [pScreens count] ) - pScreen = [pScreens objectAtIndex: nDisplay]; - else - { - // this means span all screens - bHideMenu = true; - NSEnumerator* pEnum = [pScreens objectEnumerator]; - while( (pScreen = [pEnum nextObject]) != nil ) - { - NSRect aScreenRect = [pScreen frame]; - if( aScreenRect.origin.x < aNewContentRect.origin.x ) - { - aNewContentRect.size.width += aNewContentRect.origin.x - aScreenRect.origin.x; - aNewContentRect.origin.x = aScreenRect.origin.x; - } - if( aScreenRect.origin.y < aNewContentRect.origin.y ) - { - aNewContentRect.size.height += aNewContentRect.origin.y - aScreenRect.origin.y; - aNewContentRect.origin.y = aScreenRect.origin.y; - } - if( aScreenRect.origin.x + aScreenRect.size.width > aNewContentRect.origin.x + aNewContentRect.size.width ) - aNewContentRect.size.width = aScreenRect.origin.x + aScreenRect.size.width - aNewContentRect.origin.x; - if( aScreenRect.origin.y + aScreenRect.size.height > aNewContentRect.origin.y + aNewContentRect.size.height ) - aNewContentRect.size.height = aScreenRect.origin.y + aScreenRect.size.height - aNewContentRect.origin.y; - } - } - } - if( aNewContentRect.size.width == 0 && aNewContentRect.size.height == 0 ) - { - if( pScreen == nil ) - pScreen = [mpNSWindow screen]; - if( pScreen == nil ) - pScreen = [NSScreen mainScreen]; - - aNewContentRect = [pScreen frame]; - } - - if( bHideMenu ) - [NSMenu setMenuBarVisible:NO]; - - maFullScreenRect = [mpNSWindow frame]; - { - [mpNSWindow setFrame: [NSWindow frameRectForContentRect: aNewContentRect styleMask: mnStyleMask] display: mbShown ? YES : NO]; - } - - UpdateFrameGeometry(); - - if( mbShown ) - CallCallback( SalEvent::MoveResize, nullptr ); + SAL_INFO("vcl.osx", "Calling toggleFullScreen"); + [mpNSWindow toggleFullScreen:nil]; } - else - { - { - [mpNSWindow setFrame: maFullScreenRect display: mbShown ? YES : NO]; - } - UpdateFrameGeometry(); - if( mbShown ) - CallCallback( SalEvent::MoveResize, nullptr ); + UpdateFrameGeometry(); - // show the dock and the menubar - [NSMenu setMenuBarVisible:YES]; - } if( mbShown ) + { + CallCallback( SalEvent::MoveResize, nullptr ); + // trigger filling our backbuffer SendPaintEvent(); + } } void AquaSalFrame::StartPresentation( bool bStart ) @@ -1560,7 +1513,12 @@ void AquaSalFrame::UpdateFrameGeometry() } NSRect aFrameRect = [mpNSWindow frame]; - NSRect aContentRect = [NSWindow contentRectForFrameRect: aFrameRect styleMask: mnStyleMask]; + NSRect aContentRect; + + if (mbFullScreen) + aContentRect = [NSWindow contentRectForFrameRect: aFrameRect styleMask: 0]; + else + aContentRect = [NSWindow contentRectForFrameRect: aFrameRect styleMask: mnStyleMask]; NSRect aTrackRect = { NSZeroPoint, aContentRect.size }; diff --git a/vcl/osx/salframeview.mm b/vcl/osx/salframeview.mm index e1d85a4fd64f..ca9d44d7ff39 100644 --- a/vcl/osx/salframeview.mm +++ b/vcl/osx/salframeview.mm @@ -19,6 +19,7 @@ #include <sal/config.h> +#include <comphelper/dispatchcommand.hxx> #include <sal/macros.h> #include <tools/helpers.hxx> @@ -198,22 +199,15 @@ static AquaSalFrame* getMouseContainerFrame() [pNSWindow useOptimizedDrawing: YES]; // OSX recommendation when there are no overlapping subviews within the receiver #endif - // enable OSX>=10.7 fullscreen options if available and useful + // Enable fullscreen options if available and useful bool bAllowFullScreen = (SalFrameStyleFlags::NONE == (mpFrame->mnStyle & (SalFrameStyleFlags::DIALOG | SalFrameStyleFlags::TOOLTIP | SalFrameStyleFlags::SYSTEMCHILD | SalFrameStyleFlags::FLOAT | SalFrameStyleFlags::TOOLWINDOW | SalFrameStyleFlags::INTRO))); bAllowFullScreen &= (SalFrameStyleFlags::NONE == (~mpFrame->mnStyle & SalFrameStyleFlags::SIZEABLE)); bAllowFullScreen &= (mpFrame->mpParent == nullptr); - const SEL setCollectionBehavior = @selector(setCollectionBehavior:); - if( bAllowFullScreen && [pNSWindow respondsToSelector: setCollectionBehavior]) - { - const int bMode= (bAllowFullScreen ? NSWindowCollectionBehaviorFullScreenPrimary : NSWindowCollectionBehaviorFullScreenAuxiliary); - [pNSWindow performSelector:setCollectionBehavior withObject:reinterpret_cast<id>(static_cast<intptr_t>(bMode))]; - } - // disable OSX>=10.7 window restoration until we support it directly - const SEL setRestorable = @selector(setRestorable:); - if( [pNSWindow respondsToSelector: setRestorable]) { - [pNSWindow performSelector:setRestorable withObject:reinterpret_cast<id>(NO)]; - } + [pNSWindow setCollectionBehavior: (bAllowFullScreen ? NSWindowCollectionBehaviorFullScreenPrimary : NSWindowCollectionBehaviorFullScreenAuxiliary)]; + + // Disable window restoration until we support it directly + [pNSWindow setRestorable: NO]; return static_cast<SalFrameWindow *>(pNSWindow); } @@ -388,7 +382,10 @@ static AquaSalFrame* getMouseContainerFrame() if( !mpFrame || !AquaSalFrame::isAlive( mpFrame)) return; - mpFrame->mbFullScreen = true; + + if ( !mpFrame->mbFullScreen ) + comphelper::dispatchCommand( ".uno:FullScreen", {} ); + (void)pNotification; } @@ -398,7 +395,10 @@ static AquaSalFrame* getMouseContainerFrame() if( !mpFrame || !AquaSalFrame::isAlive( mpFrame)) return; - mpFrame->mbFullScreen = false; + + if ( mpFrame->mbFullScreen ) + comphelper::dispatchCommand( ".uno:FullScreen", {} ); + (void)pNotification; } diff --git a/vcl/osx/vclnsapp.mm b/vcl/osx/vclnsapp.mm index 4fc869f01919..4edf177d9b6b 100644 --- a/vcl/osx/vclnsapp.mm +++ b/vcl/osx/vclnsapp.mm @@ -161,7 +161,7 @@ SAL_WNODEPRECATED_DECLARATIONS_PUSH // and swallows the event wholesale NSMenu* pMainMenu = [NSApp mainMenu]; if( ! bHandled && - (pMainMenu == nullptr || ! [NSMenu menuBarVisible] || ! [pMainMenu performKeyEquivalent: pEvent]) ) + (pMainMenu == nullptr || ! ( [pMainMenu performKeyEquivalent: pEvent] || [NSMenu menuBarVisible] ) ) ) { [[pKeyWin contentView] keyDown: pEvent]; bHandled = GetSalData()->maKeyEventAnswer[ pEvent ]; |