Bug 639705 (Lion Full Screen) Part 2: Support Lion Full Screen when fullscreenbutton=true [r=josh,mstange]

--HG--
extra : rebase_source : ce2751e4b32cf0d4344b5ca6a642e1e172c04e3b
This commit is contained in:
Paul O’Shannessy 2012-03-20 16:21:14 -07:00
parent 40da322e36
commit 36dd7de41e
2 changed files with 108 additions and 12 deletions

View File

@ -53,6 +53,21 @@ class nsCocoaWindow;
class nsChildView;
class nsMenuBarX;
// If we are using an SDK older than 10.7, define bits we need that are missing
// from it.
#if !defined(MAC_OS_X_VERSION_10_7) || \
MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
enum {
NSWindowCollectionBehaviorFullScreenPrimary = 1 << 7,
};
@interface NSWindow (NewInMacOS107)
- (void)toggleFullScreen:(id)sender;
@end
#endif
typedef struct _nsCocoaWindowList {
_nsCocoaWindowList() : prev(NULL), window(NULL) {}
struct _nsCocoaWindowList *prev;
@ -255,6 +270,7 @@ public:
nsIWidget *aWidget, bool aActivate);
NS_IMETHOD SetSizeMode(PRInt32 aMode);
NS_IMETHOD HideWindowChrome(bool aShouldHide);
void EnteredFullScreen(bool aFullScreen);
NS_IMETHOD MakeFullScreen(bool aFullScreen);
NS_IMETHOD Resize(PRInt32 aWidth,PRInt32 aHeight, bool aRepaint);
NS_IMETHOD Resize(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight, bool aRepaint);
@ -281,6 +297,7 @@ public:
virtual void SetTransparencyMode(nsTransparencyMode aMode);
NS_IMETHOD SetWindowShadowStyle(PRInt32 aStyle);
virtual void SetShowsToolbarButton(bool aShow);
virtual void SetShowsFullScreenButton(bool aShow);
virtual void SetWindowAnimationType(WindowAnimationType aType);
NS_IMETHOD SetWindowTitlebarColor(nscolor aColor, bool aActive);
virtual void SetDrawsInTitlebar(bool aState);
@ -359,6 +376,8 @@ protected:
bool mFullScreen;
bool mModal;
bool mUsesNativeFullScreen; // only true on Lion if SetShowsFullScreenButton(true);
bool mIsAnimationSuppressed;
bool mInReportMoveEvent; // true if in a call to ReportMoveEvent().

View File

@ -140,6 +140,7 @@ nsCocoaWindow::nsCocoaWindow()
, mSheetNeedsShow(false)
, mFullScreen(false)
, mModal(false)
, mUsesNativeFullScreen(false)
, mIsAnimationSuppressed(false)
, mInReportMoveEvent(false)
, mNumModalDescendents(0)
@ -513,7 +514,10 @@ NS_IMETHODIMP nsCocoaWindow::Destroy()
nsBaseWidget::Destroy();
nsBaseWidget::OnDestroy();
if (mFullScreen) {
// On Lion we do not have to mess with the OS chrome when in Full Screen mode. So we
// can simply skip that. When the Window is destroyed, the OS will take care of removing
// the full screen 'Space' that was setup for us.
if (!mUsesNativeFullScreen && mFullScreen) {
nsCocoaUtils::HideOSChromeOnScreen(false, [mWindow screen]);
}
@ -1180,24 +1184,40 @@ NS_IMETHODIMP nsCocoaWindow::HideWindowChrome(bool aShouldHide)
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
void nsCocoaWindow::EnteredFullScreen(bool aFullScreen)
{
mFullScreen = aFullScreen;
DispatchSizeModeEvent();
}
NS_METHOD nsCocoaWindow::MakeFullScreen(bool aFullScreen)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
NS_ASSERTION(mFullScreen != aFullScreen, "Unnecessary MakeFullScreen call");
// We will call into MakeFullScreen redundantly when entering/exiting
// fullscreen mode via OS X controls. When that happens we should just handle
// it gracefully - no need to ASSERT.
if (mFullScreen == aFullScreen) {
return NS_OK;
}
NSDisableScreenUpdates();
// The order here matters. When we exit full screen mode, we need to show the
// Dock first, otherwise the newly-created window won't have its minimize
// button enabled. See bug 526282.
nsCocoaUtils::HideOSChromeOnScreen(aFullScreen, [mWindow screen]);
nsresult rv = nsBaseWidget::MakeFullScreen(aFullScreen);
NSEnableScreenUpdates();
NS_ENSURE_SUCCESS(rv, rv);
if (mUsesNativeFullScreen) {
// Calling toggleFullScreen will result in windowDid(Enter|Exit)FullScreen
// to be called from the OS. We will call EnteredFullScreen from those methods,
// where mFullScreen will be set and a sizemode event will be dispatched.
[mWindow toggleFullScreen:nil];
} else {
NSDisableScreenUpdates();
// The order here matters. When we exit full screen mode, we need to show the
// Dock first, otherwise the newly-created window won't have its minimize
// button enabled. See bug 526282.
nsCocoaUtils::HideOSChromeOnScreen(aFullScreen, [mWindow screen]);
nsresult rv = nsBaseWidget::MakeFullScreen(aFullScreen);
NSEnableScreenUpdates();
NS_ENSURE_SUCCESS(rv, rv);
mFullScreen = aFullScreen;
DispatchSizeModeEvent();
EnteredFullScreen(aFullScreen);
}
return NS_OK;
@ -1642,6 +1662,42 @@ void nsCocoaWindow::SetShowsToolbarButton(bool aShow)
NS_OBJC_END_TRY_ABORT_BLOCK;
}
void nsCocoaWindow::SetShowsFullScreenButton(bool aShow)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
if (![mWindow respondsToSelector:@selector(toggleFullScreen:)] ||
mUsesNativeFullScreen == aShow) {
return;
}
// If the window is currently in fullscreen mode, then we're going to
// transition out first, then set the collection behavior & toggle
// mUsesNativeFullScreen, then transtion back into fullscreen mode. This
// prevents us from getting into a conflicting state with MakeFullScreen
// where mUsesNativeFullScreen would lead us down the wrong path.
bool wasFullScreen = mFullScreen;
if (wasFullScreen) {
MakeFullScreen(false);
}
NSWindowCollectionBehavior newBehavior = [mWindow collectionBehavior];
if (aShow) {
newBehavior |= NSWindowCollectionBehaviorFullScreenPrimary;
} else {
newBehavior &= ~NSWindowCollectionBehaviorFullScreenPrimary;
}
[mWindow setCollectionBehavior:newBehavior];
mUsesNativeFullScreen = aShow;
if (wasFullScreen) {
MakeFullScreen(true);
}
NS_OBJC_END_TRY_ABORT_BLOCK;
}
void nsCocoaWindow::SetWindowAnimationType(nsIWidget::WindowAnimationType aType)
{
mAnimationType = aType;
@ -1875,6 +1931,27 @@ bool nsCocoaWindow::ShouldFocusPlugin()
mGeckoWindow->ReportMoveEvent();
}
// Lion's full screen mode will bypass our internal fullscreen tracking, so
// we need to catch it when we transition and call our own methods, which in
// turn will fire "fullscreen" events.
- (void)windowDidEnterFullScreen:(NSNotification *)notification
{
if (!mGeckoWindow) {
return;
}
mGeckoWindow->EnteredFullScreen(true);
}
- (void)windowDidExitFullScreen:(NSNotification *)notification
{
if (!mGeckoWindow) {
return;
}
mGeckoWindow->EnteredFullScreen(false);
}
- (void)windowDidBecomeMain:(NSNotification *)aNotification
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;