Bug 1160014 part 5 - Implement fullscreen transition on Mac. r=smichaud

--HG--
extra : source : 3ff3e6db3475b98f9b873d01f70f6b12bce1d44d
This commit is contained in:
Xidorn Quan 2015-07-24 09:45:00 +10:00
parent 2b769d805b
commit 76b36e0a05
2 changed files with 92 additions and 0 deletions

View File

@ -285,7 +285,13 @@ public:
nsIWidget *aWidget, bool aActivate) override;
NS_IMETHOD SetSizeMode(int32_t aMode) override;
NS_IMETHOD HideWindowChrome(bool aShouldHide) override;
void EnteredFullScreen(bool aFullScreen, bool aNativeMode = true);
virtual bool PrepareForFullscreenTransition(nsISupports** aData) override;
virtual void PerformFullscreenTransition(FullscreenTransitionStage aStage,
uint16_t aDuration,
nsISupports* aData,
nsIRunnable* aCallback) override;
NS_IMETHOD MakeFullScreen(
bool aFullScreen, nsIScreen* aTargetScreen = nullptr) override final;
NS_IMETHOD MakeFullScreenWithNativeTransition(

View File

@ -1,4 +1,5 @@
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -33,6 +34,7 @@
#include "nsIScreenManager.h"
#include "nsIWidgetListener.h"
#include "nsIPresShell.h"
#include "nsScreenCocoa.h"
#include "gfxPlatform.h"
#include "qcms.h"
@ -1265,6 +1267,90 @@ NS_IMETHODIMP nsCocoaWindow::HideWindowChrome(bool aShouldHide)
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
class FullscreenTransitionData : public nsISupports
{
public:
NS_DECL_ISUPPORTS
explicit FullscreenTransitionData(NSWindow* aWindow)
: mTransitionWindow(aWindow) { }
NSWindow* mTransitionWindow;
private:
virtual ~FullscreenTransitionData()
{
[mTransitionWindow close];
}
};
NS_IMPL_ISUPPORTS0(FullscreenTransitionData)
@interface FullscreenTransitionDelegate : NSObject <NSAnimationDelegate>
{
@public
nsIRunnable* mCallback;
}
@end
@implementation FullscreenTransitionDelegate
- (void)animationDidEnd:(NSAnimation *)animation
{
[animation setDelegate:nil];
[self autorelease];
// The caller should have added ref for us.
NS_DispatchToMainThread(already_AddRefed<nsIRunnable>(mCallback));
}
@end
/* virtual */ bool
nsCocoaWindow::PrepareForFullscreenTransition(nsISupports** aData)
{
nsCOMPtr<nsIScreen> widgetScreen = GetWidgetScreen();
nsScreenCocoa* screen = static_cast<nsScreenCocoa*>(widgetScreen.get());
NSScreen* cocoaScreen = screen->CocoaScreen();
NSWindow* win =
[[NSWindow alloc] initWithContentRect:[cocoaScreen frame]
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:YES];
[win setBackgroundColor:[NSColor blackColor]];
[win setAlphaValue:0];
[win setIgnoresMouseEvents:YES];
[win setLevel:NSScreenSaverWindowLevel];
[win makeKeyAndOrderFront:nil];
auto data = new FullscreenTransitionData(win);
*aData = data;
NS_ADDREF(data);
return true;
}
/* virtual */ void
nsCocoaWindow::PerformFullscreenTransition(FullscreenTransitionStage aStage,
uint16_t aDuration,
nsISupports* aData,
nsIRunnable* aCallback)
{
auto data = static_cast<FullscreenTransitionData*>(aData);
FullscreenTransitionDelegate* delegate =
[[FullscreenTransitionDelegate alloc] init];
// Storing already_AddRefed directly could cause static checking fail.
delegate->mCallback = nsCOMPtr<nsIRunnable>(aCallback).forget().take();
NSDictionary* dict = @{
NSViewAnimationTargetKey: data->mTransitionWindow,
NSViewAnimationEffectKey: aStage == eBeforeFullscreenToggle ?
NSViewAnimationFadeInEffect : NSViewAnimationFadeOutEffect
};
NSAnimation* animation =
[[[NSViewAnimation alloc] initWithViewAnimations:@[dict]] autorelease];
[animation setDelegate:delegate];
[animation setDuration:aDuration / 1000.0];
[animation startAnimation];
}
void nsCocoaWindow::EnteredFullScreen(bool aFullScreen, bool aNativeMode)
{
mInFullScreenTransition = false;