зеркало из https://github.com/mozilla/pjs.git
Bug 757618 - Closing window while in Lion fullscreen mode leaves one on blank screen for 10-15 seconds. r=bgirard
This commit is contained in:
Родитель
48edcefe25
Коммит
af26482d21
|
@ -121,11 +121,15 @@ void nsCocoaWindow::DestroyNativeWindow()
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if (!mWindow)
|
||||
return;
|
||||
|
||||
CleanUpWindowFilter();
|
||||
// We want to unhook the delegate here because we don't want events
|
||||
// sent to it after this object has been destroyed.
|
||||
[mWindow setDelegate:nil];
|
||||
[mWindow close];
|
||||
mWindow = nil;
|
||||
[mDelegate autorelease];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
|
@ -483,11 +487,19 @@ NS_IMETHODIMP nsCocoaWindow::Destroy()
|
|||
nsBaseWidget::Destroy();
|
||||
nsBaseWidget::OnDestroy();
|
||||
|
||||
// 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]);
|
||||
if (mFullScreen) {
|
||||
// On Lion we don't have to mess with the OS chrome when in Full Screen
|
||||
// mode. But we do have to destroy the native window here (and not wait
|
||||
// for that to happen in our destructor). We don't switch away from the
|
||||
// native window's space until the window is destroyed, and otherwise this
|
||||
// might not happen for several seconds (because at least one object
|
||||
// holding a reference to ourselves is usually waiting to be garbage-
|
||||
// collected). See bug 757618.
|
||||
if (mUsesNativeFullScreen) {
|
||||
DestroyNativeWindow();
|
||||
} else if (mWindow) {
|
||||
nsCocoaUtils::HideOSChromeOnScreen(false, [mWindow screen]);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -537,7 +549,7 @@ NS_IMETHODIMP nsCocoaWindow::IsVisible(bool & aState)
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
aState = ([mWindow isVisible] || mSheetNeedsShow);
|
||||
aState = (mWindow && ([mWindow isVisible] || mSheetNeedsShow));
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
@ -545,6 +557,9 @@ NS_IMETHODIMP nsCocoaWindow::IsVisible(bool & aState)
|
|||
|
||||
NS_IMETHODIMP nsCocoaWindow::SetModal(bool aState)
|
||||
{
|
||||
if (!mWindow)
|
||||
return NS_OK;
|
||||
|
||||
// This is used during startup (outside the event loop) when creating
|
||||
// the add-ons compatibility checking dialog and the profile manager UI;
|
||||
// therefore, it needs to provide an autorelease pool to avoid cocoa
|
||||
|
@ -623,6 +638,9 @@ NS_IMETHODIMP nsCocoaWindow::Show(bool bState)
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
if (!mWindow)
|
||||
return NS_OK;
|
||||
|
||||
// We need to re-execute sometimes in order to bring already-visible
|
||||
// windows forward.
|
||||
if (!mSheetNeedsShow && !bState && ![mWindow isVisible])
|
||||
|
@ -880,7 +898,7 @@ nsCocoaWindow::AdjustWindowShadow()
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if (![mWindow isVisible] || ![mWindow hasShadow] ||
|
||||
if (!mWindow || ![mWindow isVisible] || ![mWindow hasShadow] ||
|
||||
[mWindow canBecomeKeyWindow] || [mWindow windowNumber] == -1)
|
||||
return;
|
||||
|
||||
|
@ -899,7 +917,7 @@ nsCocoaWindow::SetUpWindowFilter()
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if (![mWindow isVisible] || [mWindow windowNumber] == -1)
|
||||
if (!mWindow || ![mWindow isVisible] || [mWindow windowNumber] == -1)
|
||||
return;
|
||||
|
||||
CleanUpWindowFilter();
|
||||
|
@ -928,7 +946,7 @@ nsCocoaWindow::SetUpWindowFilter()
|
|||
void
|
||||
nsCocoaWindow::CleanUpWindowFilter()
|
||||
{
|
||||
if (!mWindowFilter || [mWindow windowNumber] == -1)
|
||||
if (!mWindow || !mWindowFilter || [mWindow windowNumber] == -1)
|
||||
return;
|
||||
|
||||
CGSConnection cid = _CGSDefaultConnection();
|
||||
|
@ -965,7 +983,7 @@ nsTransparencyMode nsCocoaWindow::GetTransparencyMode()
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
return [mWindow isOpaque] ? eTransparencyOpaque : eTransparencyTransparent;
|
||||
return (!mWindow || [mWindow isOpaque]) ? eTransparencyOpaque : eTransparencyTransparent;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(eTransparencyOpaque);
|
||||
}
|
||||
|
@ -976,6 +994,9 @@ void nsCocoaWindow::SetTransparencyMode(nsTransparencyMode aMode)
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if (!mWindow)
|
||||
return;
|
||||
|
||||
BOOL isTransparent = aMode == eTransparencyTransparent;
|
||||
BOOL currentTransparency = ![mWindow isOpaque];
|
||||
if (isTransparent != currentTransparency) {
|
||||
|
@ -1078,6 +1099,9 @@ NS_METHOD nsCocoaWindow::SetSizeMode(PRInt32 aMode)
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
if (!mWindow)
|
||||
return NS_OK;
|
||||
|
||||
// mSizeMode will be updated in DispatchSizeModeEvent, which will be called
|
||||
// from a delegate method that handles the state change during one of the
|
||||
// calls below.
|
||||
|
@ -1116,7 +1140,7 @@ NS_IMETHODIMP nsCocoaWindow::HideWindowChrome(bool aShouldHide)
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
if (!mWindowMadeHere ||
|
||||
if (!mWindow || !mWindowMadeHere ||
|
||||
(mWindowType != eWindowType_toplevel && mWindowType != eWindowType_dialog))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -1179,6 +1203,10 @@ NS_METHOD nsCocoaWindow::MakeFullScreen(bool aFullScreen)
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
if (!mWindow) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
@ -1249,6 +1277,11 @@ NS_IMETHODIMP nsCocoaWindow::GetClientBounds(nsIntRect &aRect)
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
if (!mWindow) {
|
||||
aRect = nsCocoaUtils::CocoaRectToGeckoRect(NSZeroRect);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if ([mWindow isKindOfClass:[ToolbarWindow class]] &&
|
||||
[(ToolbarWindow*)mWindow drawsContentsIntoWindowFrame]) {
|
||||
aRect = nsCocoaUtils::CocoaRectToGeckoRect([mWindow frame]);
|
||||
|
@ -1265,14 +1298,17 @@ NS_IMETHODIMP nsCocoaWindow::GetClientBounds(nsIntRect &aRect)
|
|||
void
|
||||
nsCocoaWindow::UpdateBounds()
|
||||
{
|
||||
mBounds = nsCocoaUtils::CocoaRectToGeckoRect([mWindow frame]);
|
||||
NSRect frame = NSZeroRect;
|
||||
if (mWindow)
|
||||
frame = [mWindow frame];
|
||||
mBounds = nsCocoaUtils::CocoaRectToGeckoRect(frame);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsCocoaWindow::GetScreenBounds(nsIntRect &aRect)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
NS_ASSERTION(mBounds == nsCocoaUtils::CocoaRectToGeckoRect([mWindow frame]),
|
||||
NS_ASSERTION(mWindow && mBounds == nsCocoaUtils::CocoaRectToGeckoRect([mWindow frame]),
|
||||
"mBounds out of sync!");
|
||||
|
||||
aRect = mBounds;
|
||||
|
@ -1302,6 +1338,9 @@ NS_IMETHODIMP nsCocoaWindow::SetTitle(const nsAString& aTitle)
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
if (!mWindow)
|
||||
return NS_OK;
|
||||
|
||||
const nsString& strTitle = PromiseFlatString(aTitle);
|
||||
NSString* title = [NSString stringWithCharacters:strTitle.get() length:strTitle.Length()];
|
||||
[mWindow setTitle:title];
|
||||
|
@ -1356,8 +1395,9 @@ NS_IMETHODIMP nsCocoaWindow::GetChildSheet(bool aShown, nsCocoaWindow** _retval)
|
|||
if (NS_SUCCEEDED(child->GetWindowType(type)) && type == eWindowType_sheet) {
|
||||
// if it's a sheet, it must be an nsCocoaWindow
|
||||
nsCocoaWindow* cocoaWindow = static_cast<nsCocoaWindow*>(child);
|
||||
if ((aShown && [cocoaWindow->mWindow isVisible]) ||
|
||||
(!aShown && cocoaWindow->mSheetNeedsShow)) {
|
||||
if (cocoaWindow->mWindow &&
|
||||
((aShown && [cocoaWindow->mWindow isVisible]) ||
|
||||
(!aShown && cocoaWindow->mSheetNeedsShow))) {
|
||||
*_retval = cocoaWindow;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1457,6 +1497,10 @@ nsCocoaWindow::ReportMoveEvent()
|
|||
void
|
||||
nsCocoaWindow::DispatchSizeModeEvent()
|
||||
{
|
||||
if (!mWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsSizeMode newMode = GetWindowSizeMode(mWindow, mFullScreen);
|
||||
|
||||
// Don't dispatch a sizemode event if:
|
||||
|
@ -1501,6 +1545,10 @@ void nsCocoaWindow::SetMenuBar(nsMenuBarX *aMenuBar)
|
|||
{
|
||||
if (mMenuBar)
|
||||
mMenuBar->SetParent(nsnull);
|
||||
if (!mWindow) {
|
||||
mMenuBar = nsnull;
|
||||
return;
|
||||
}
|
||||
mMenuBar = aMenuBar;
|
||||
|
||||
// Only paint for active windows, or paint the hidden window menu bar if no
|
||||
|
@ -1515,6 +1563,9 @@ void nsCocoaWindow::SetMenuBar(nsMenuBarX *aMenuBar)
|
|||
|
||||
NS_IMETHODIMP nsCocoaWindow::SetFocus(bool aState)
|
||||
{
|
||||
if (!mWindow)
|
||||
return NS_OK;
|
||||
|
||||
if (mPopupContentView) {
|
||||
mPopupContentView->SetFocus(aState);
|
||||
}
|
||||
|
@ -1530,7 +1581,10 @@ nsIntPoint nsCocoaWindow::WidgetToScreenOffset()
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
nsIntRect r = nsCocoaUtils::CocoaRectToGeckoRect([mWindow contentRectForFrameRect:[mWindow frame]]);
|
||||
NSRect rect = NSZeroRect;
|
||||
if (mWindow)
|
||||
rect = [mWindow contentRectForFrameRect:[mWindow frame]];
|
||||
nsIntRect r = nsCocoaUtils::CocoaRectToGeckoRect(rect);
|
||||
|
||||
return r.TopLeft();
|
||||
|
||||
|
@ -1553,6 +1607,9 @@ nsIntSize nsCocoaWindow::ClientToWindowSize(const nsIntSize& aClientSize)
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
if (!mWindow)
|
||||
return nsIntSize(0, 0);
|
||||
|
||||
// this is only called for popups currently. If needed, expand this to support
|
||||
// other types of windows
|
||||
if (!IsPopupWithTitleBar())
|
||||
|
@ -1634,6 +1691,9 @@ NS_IMETHODIMP nsCocoaWindow::SetWindowShadowStyle(PRInt32 aStyle)
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
if (!mWindow)
|
||||
return NS_OK;
|
||||
|
||||
mShadowStyle = aStyle;
|
||||
[mWindow setHasShadow:(aStyle != NS_STYLE_WINDOW_SHADOW_NONE)];
|
||||
AdjustWindowShadow();
|
||||
|
@ -1648,7 +1708,8 @@ void nsCocoaWindow::SetShowsToolbarButton(bool aShow)
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
[mWindow setShowsToolbarButton:aShow];
|
||||
if (mWindow)
|
||||
[mWindow setShowsToolbarButton:aShow];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
@ -1657,7 +1718,7 @@ void nsCocoaWindow::SetShowsFullScreenButton(bool aShow)
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if (![mWindow respondsToSelector:@selector(toggleFullScreen:)] ||
|
||||
if (!mWindow || ![mWindow respondsToSelector:@selector(toggleFullScreen:)] ||
|
||||
mUsesNativeFullScreen == aShow) {
|
||||
return;
|
||||
}
|
||||
|
@ -1698,6 +1759,9 @@ NS_IMETHODIMP nsCocoaWindow::SetWindowTitlebarColor(nscolor aColor, bool aActive
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
if (!mWindow)
|
||||
return NS_OK;
|
||||
|
||||
// If they pass a color with a complete transparent alpha component, use the
|
||||
// native titlebar appearance.
|
||||
if (NS_GET_A(aColor) == 0) {
|
||||
|
@ -1733,7 +1797,8 @@ void nsCocoaWindow::SetDrawsInTitlebar(bool aState)
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
[mWindow setDrawsContentsIntoWindowFrame:aState];
|
||||
if (mWindow)
|
||||
[mWindow setDrawsContentsIntoWindowFrame:aState];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
@ -1788,6 +1853,9 @@ NS_IMETHODIMP nsCocoaWindow::EndSecureKeyboardInput()
|
|||
|
||||
void nsCocoaWindow::SetPopupWindowLevel()
|
||||
{
|
||||
if (!mWindow)
|
||||
return;
|
||||
|
||||
// Floating popups are at the floating level and hide when the window is
|
||||
// deactivated.
|
||||
if (mPopupLevel == ePopupLevelFloating) {
|
||||
|
@ -1826,7 +1894,7 @@ bool nsCocoaWindow::IsChildInFailingLeftClickThrough(NSView *aChild)
|
|||
// [ChildView shouldFocusPlugin].
|
||||
bool nsCocoaWindow::ShouldFocusPlugin()
|
||||
{
|
||||
if (IsChildInFailingLeftClickThrough([mWindow contentView]))
|
||||
if (!mWindow || IsChildInFailingLeftClickThrough([mWindow contentView]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
|
Загрузка…
Ссылка в новой задаче