From c1452e73091412ba0bb72306329e1912df2ba513 Mon Sep 17 00:00:00 2001 From: Tor Lillqvist Date: Wed, 30 May 2018 11:37:19 +0300 Subject: tdf#117872: Revert "tdf#115284: Unify LibreOffice and system full-screen..." Instead, never participate in the macOS system full-screen mode. There is just too much complexity involved, and the way LibreOffice works really isn't prepared for the concept of windows having the option from a system point of view to being full-screenable or not. This means that the green bubble in window title bars changes from being a (system) full-screen toggle to being a maximize/restore toggle. Sure, the "maximize" concept also probably can be confused with LibreOffice's own full-screen concept. For instance, the Start Centre window is not expecting to be made full-screen. Still, when you from the Start Centre open a Writer document, it is the *same* window that is re-used as the Writer window, and then suddenly should be prepared to handle going full-screen. Also, it is up to each separate kind of document window whether it can be made full-screen (from the LibreOffice point of view) or not. Writer windows can, but Impress windows can't, for example. The View>Full Screen menu entry is added separately each case. Maybe I will come back to this mess later, or not. Anybody else is welcome to have a go, too, of course. This reverts commit 4b42fd7e9516fbbd8a92d97680524f32dd260fb2. Change-Id: I6983481cbd30c0e5190c450483b1246006c80632 Reviewed-on: https://gerrit.libreoffice.org/55049 Reviewed-by: Tor Lillqvist Tested-by: Tor Lillqvist --- framework/inc/helper/persistentwindowstate.hxx | 2 - framework/source/dispatch/closedispatcher.cxx | 17 +--- framework/source/helper/persistentwindowstate.cxx | 29 +----- sfx2/source/view/viewfrm.cxx | 17 +--- vcl/inc/osx/salframe.h | 2 + vcl/osx/salframe.cxx | 118 +++++++++++++++------- vcl/osx/salframeview.mm | 34 ++++--- vcl/osx/vclnsapp.mm | 2 +- 8 files changed, 108 insertions(+), 113 deletions(-) diff --git a/framework/inc/helper/persistentwindowstate.hxx b/framework/inc/helper/persistentwindowstate.hxx index f9062d4344c4..e6b5c47d8c72 100644 --- a/framework/inc/helper/persistentwindowstate.hxx +++ b/framework/inc/helper/persistentwindowstate.hxx @@ -119,8 +119,6 @@ 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 1fc959734168..ed79058194ab 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; fill-column: 100 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * @@ -38,7 +38,6 @@ #include #include #include -#include #include using namespace com::sun::star; @@ -177,20 +176,6 @@ 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(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 e20a152a19d2..ecec7f39d63c 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; fill-column: 100 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * @@ -125,11 +125,6 @@ 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); } @@ -204,28 +199,6 @@ 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 pWindow = VCLUnoHelper::GetWindow(xWindow); - if ( pWindow && pWindow->IsSystemWindow() ) - { - WindowStateData aWSD; - aWSD.SetMask(WindowStateMask::All); - static_cast(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 5221205801ea..8fe2079492c5 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; fill-column: 100 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * @@ -146,11 +146,7 @@ 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 } @@ -2714,10 +2710,7 @@ 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() ) @@ -2731,11 +2724,10 @@ 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() ) { @@ -2749,11 +2741,8 @@ 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 c615690946f4..c2b53e270648 100644 --- a/vcl/inc/osx/salframe.h +++ b/vcl/inc/osx/salframe.h @@ -38,6 +38,7 @@ #include class AquaSalGraphics; +class AquaSalFrame; class AquaSalTimer; class AquaSalInstance; class AquaSalMenu; @@ -60,6 +61,7 @@ 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 567660285e4e..31159f8545c0 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; fill-column: 100 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * @@ -24,7 +24,6 @@ #include -#include #include #include #include @@ -215,6 +214,10 @@ SAL_WNODEPRECATED_DECLARATIONS_POP [mpNSWindow setDelegate: static_cast >(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]; @@ -569,26 +572,11 @@ 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 */ - else if( pState->mnState == WindowStateState::Maximized ) + if( pState->mnState == WindowStateState::Maximized ) { if(! [mpNSWindow isZoomed]) [mpNSWindow zoom: NSApp]; @@ -650,9 +638,7 @@ bool AquaSalFrame::GetWindowState( SalFrameState* pState ) pState->mnWidth = long(aStateRect.size.width); pState->mnHeight = long(aStateRect.size.height); - if( mbFullScreen ) - pState->mnState = WindowStateState::FullScreen; - else if( [mpNSWindow isMiniaturized] ) + if( [mpNSWindow isMiniaturized] ) pState->mnState = WindowStateState::Minimized; else if( ! [mpNSWindow isZoomed] ) pState->mnState = WindowStateState::Normal; @@ -704,7 +690,7 @@ void AquaSalFrame::ShowFullScreen( bool bFullScreen, sal_Int32 nDisplay ) if ( !mpNSWindow ) return; - SAL_INFO("vcl.osx", "AquaSalFrame::ShowFullScreen: mbFullScreen=" << mbFullScreen << ", bFullScreen=" << bFullScreen); + SAL_INFO("vcl.osx", OSL_THIS_FUNC << ": mbFullScreen=" << mbFullScreen << ", bFullScreen=" << bFullScreen); if( mbFullScreen == bFullScreen ) return; @@ -713,23 +699,84 @@ void AquaSalFrame::ShowFullScreen( bool bFullScreen, sal_Int32 nDisplay ) mbFullScreen = bFullScreen; - NSUInteger nCurrentSystemStyle = [mpNSWindow styleMask]; - if( ((nCurrentSystemStyle & NSWindowStyleMaskFullScreen) && !mbFullScreen) - || (!(nCurrentSystemStyle & NSWindowStyleMaskFullScreen) && mbFullScreen) ) + if( bFullScreen ) { - SAL_INFO("vcl.osx", "Calling toggleFullScreen"); - [mpNSWindow toggleFullScreen:nil]; - } + // 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); - UpdateFrameGeometry(); + NSRect aNewContentRect = NSZeroRect; + // get correct screen + NSScreen* pScreen = nil; + NSArray* pScreens = [NSScreen screens]; + if( pScreens ) + { + if( nDisplay >= 0 && static_cast(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]; - if( mbShown ) + 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 ); + } + else { - CallCallback( SalEvent::MoveResize, nullptr ); + { + [mpNSWindow setFrame: maFullScreenRect display: mbShown ? YES : NO]; + } + UpdateFrameGeometry(); + if( mbShown ) + CallCallback( SalEvent::MoveResize, nullptr ); + + // show the dock and the menubar + [NSMenu setMenuBarVisible:YES]; + } + if( mbShown ) // trigger filling our backbuffer SendPaintEvent(); - } } void AquaSalFrame::StartPresentation( bool bStart ) @@ -1513,12 +1560,7 @@ void AquaSalFrame::UpdateFrameGeometry() } NSRect aFrameRect = [mpNSWindow frame]; - NSRect aContentRect; - - if (mbFullScreen) - aContentRect = [NSWindow contentRectForFrameRect: aFrameRect styleMask: 0]; - else - aContentRect = [NSWindow contentRectForFrameRect: aFrameRect styleMask: mnStyleMask]; + NSRect aContentRect = [NSWindow contentRectForFrameRect: aFrameRect styleMask: mnStyleMask]; NSRect aTrackRect = { NSZeroPoint, aContentRect.size }; diff --git a/vcl/osx/salframeview.mm b/vcl/osx/salframeview.mm index 7b670f835695..769170f206b5 100644 --- a/vcl/osx/salframeview.mm +++ b/vcl/osx/salframeview.mm @@ -19,7 +19,6 @@ #include -#include #include #include @@ -178,12 +177,25 @@ static AquaSalFrame* getMouseContainerFrame() [pNSWindow useOptimizedDrawing: YES]; // OSX recommendation when there are no overlapping subviews within the receiver #endif - // 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); + // Disallow full-screen mode on macOS >= 10.11 where it is enabled by default. We don't want it + // for now as it will just be confused with LibreOffice's home-grown full-screen concept, with + // which it has nothing to do, and one can get into all kinds of weird states by using them + // intermixedly. - [pNSWindow setCollectionBehavior: (bAllowFullScreen ? NSWindowCollectionBehaviorFullScreenPrimary : NSWindowCollectionBehaviorFullScreenAuxiliary)]; + // Ideally we should use the system full-screen mode and adapt the code for the home-grown thing + // to be in sync with that instead. (And we would then not need the button to get out of + // full-screen mode, as the normal way to get out of it is to either click on the green bubble + // again, or invoke the keyboard command again.) + + // (Confusingly, at the moment the home-grown full-screen mode is bound to Cmd+Shift+F, which is + // the keyboard command normally used in apps to get in and out of the system full-screen mode.) + + // Disabling system full-screen mode makes the green button on the title bar (on macOS >= 10.11) + // show a plus sign instead, and clicking it becomes identical to double-clicking the title bar, + // i.e. it maximizes / unmaximises the window. Sure, that state can also be confused with LO's + // home-grown full-screen mode. Oh well. + + [pNSWindow setCollectionBehavior: NSWindowCollectionBehaviorFullScreenNone]; // Disable window restoration until we support it directly [pNSWindow setRestorable: NO]; @@ -361,10 +373,7 @@ static AquaSalFrame* getMouseContainerFrame() if( !mpFrame || !AquaSalFrame::isAlive( mpFrame)) return; - - if ( !mpFrame->mbFullScreen ) - comphelper::dispatchCommand( ".uno:FullScreen", {} ); - + mpFrame->mbFullScreen = true; (void)pNotification; } @@ -374,10 +383,7 @@ static AquaSalFrame* getMouseContainerFrame() if( !mpFrame || !AquaSalFrame::isAlive( mpFrame)) return; - - if ( mpFrame->mbFullScreen ) - comphelper::dispatchCommand( ".uno:FullScreen", {} ); - + mpFrame->mbFullScreen = false; (void)pNotification; } diff --git a/vcl/osx/vclnsapp.mm b/vcl/osx/vclnsapp.mm index a3e5396d902e..f60b478a185f 100644 --- a/vcl/osx/vclnsapp.mm +++ b/vcl/osx/vclnsapp.mm @@ -145,7 +145,7 @@ SAL_WNODEPRECATED_DECLARATIONS_PUSH // and swallows the event wholesale NSMenu* pMainMenu = [NSApp mainMenu]; if( ! bHandled && - (pMainMenu == nullptr || ! ( [pMainMenu performKeyEquivalent: pEvent] || [NSMenu menuBarVisible] ) ) ) + (pMainMenu == nullptr || ! [NSMenu menuBarVisible] || ! [pMainMenu performKeyEquivalent: pEvent]) ) { [[pKeyWin contentView] keyDown: pEvent]; bHandled = GetSalData()->maKeyEventAnswer[ pEvent ]; -- cgit v1.2.3