summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorTor Lillqvist <tml@collabora.com>2018-05-23 23:21:21 +0300
committerTor Lillqvist <tml@collabora.com>2018-05-24 15:39:30 +0200
commit4b42fd7e9516fbbd8a92d97680524f32dd260fb2 (patch)
treec2e4035874ca686e9ad4ec044fd744b539759af0 /vcl
parent3259f917545abcb8f325c42db3a81e0b9d4ad7fe (diff)
tdf#115284: Unify LibreOffice and system full-screen concepts on macOS
Also tdf#76476, and probably more. Make it so that when a window is in full-screen mode from LibreOffice's point of view, it is also full-screen from the system's point of view, and vice versa. All three ways to enter and leave full-screen mode can now be used with the same end result: The Ctrl-Cmd-F shortcut, the "View > Full Screen" menu entry, and the green bubble on the title bar. Don't disable/deactivate/etc menus while in full-screen mode. The menu auto-hides so there is no harm in having it function normally. Don't display the floating toolbar with a single "Full Screen" button in it as the way to leave full-screen mode. Instead, the same three ways that can be used to enter full-screen mode work to leave it, too. Sadly I could not figure out a way to set a window properly to full-screen at the point where a document window is created and set to be the same size as that kind of document window was the previous time it was open in LibreOffice. Thus don't save state for full-screen windows as we can't properly restore them. At least not for macOS. It is not good to just restore them as non-full-screened but still at the size they had when full-screen. One irritating glitch remains, and I was unable to fix that properly: I now prevent closing the document window that is in full-screen mode. Otherwise, if it is closed, the full-screen mode remains even if no window is open there; the desktop is completely black. Moving the cursor to the top edge, the LibreOffice menu is there, though. I tried to fix that but with no fully satisfying result. (Some attempts even lead to crashes, so just disabling closing is better than crashing at least.) Change-Id: Id909077ef9de9f19d48c8b9ad10d748a65b2417f Reviewed-on: https://gerrit.libreoffice.org/54760 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Tor Lillqvist <tml@collabora.com>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/inc/osx/salframe.h2
-rw-r--r--vcl/osx/salframe.cxx118
-rw-r--r--vcl/osx/salframeview.mm28
-rw-r--r--vcl/osx/vclnsapp.mm2
4 files changed, 53 insertions, 97 deletions
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 ];