Backed out 3 changesets (bug 1631735) for causing assertion failures in xpfe/appshell/AppWindow.cpp

Backed out changeset 1c7dffec620f (bug 1631735)
Backed out changeset 4a7049e0f50d (bug 1631735)
Backed out changeset 0ae84866d35d (bug 1631735)
This commit is contained in:
Sandor Molnar 2023-03-03 04:27:11 +02:00
parent b22b618764
commit 5df475dc34
9 changed files with 138 additions and 481 deletions

View File

@ -14,11 +14,6 @@ support-files = fullscreen.html FullscreenFrame.sys.mjs
support-files = fullscreen.html fullscreen_frame.html
[browser_fullscreen_enterInUrlbar.js]
skip-if = (os == 'mac') || (os == 'linux') # Bug 1648649
[browser_fullscreen_from_minimize.js]
skip-if =
os == 'linux' # Bug 1818795
fail-if =
os == 'win' # Bug 1818796
[browser_fullscreen_newtab.js]
[browser_fullscreen_permissions_prompt.js]
[browser_fullscreen_warning.js]

View File

@ -1,72 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// This test checks whether fullscreen windows can transition to minimized windows,
// and back again. This is sometimes not directly supported by the OS widgets. For
// example, in macOS, the minimize button is greyed-out in the title bar of
// fullscreen windows, making this transition impossible for users to initiate.
// Still, web APIs do allow arbitrary combinations of window calls, and this test
// exercises some of those combinations.
add_task(async function() {
registerCleanupFunction(function() {
window.restore();
});
// We reuse these variables to create new promises for each transition.
let promiseSizeModeChange;
let promiseFullscreen;
ok(!window.fullScreen, "Window should be normal at start of test.");
// Get to fullscreen.
info("Requesting fullscreen.");
promiseFullscreen = document.documentElement.requestFullscreen();
await promiseFullscreen;
ok(window.fullScreen, "Window should be fullscreen before being minimized.");
// Transition between fullscreen and minimize states.
info("Requesting minimize on a fullscreen window.");
promiseSizeModeChange = BrowserTestUtils.waitForEvent(
window,
"sizemodechange"
);
window.minimize();
await promiseSizeModeChange;
is(
window.windowState,
window.STATE_MINIMIZED,
"Window should be minimized after fullscreen."
);
// Whether or not the previous transition worked, restore the window
// and then minimize it.
if (window.windowState != window.STATE_NORMAL) {
info("Restoring window.");
promiseSizeModeChange = BrowserTestUtils.waitForEvent(
window,
"sizemodechange"
);
window.restore();
await promiseSizeModeChange;
is(window.windowState, window.STATE_NORMAL, "Window should be normal.");
}
info("Requesting minimize on a normal window.");
promiseSizeModeChange = BrowserTestUtils.waitForEvent(
window,
"sizemodechange"
);
window.minimize();
await promiseSizeModeChange;
is(
window.windowState,
window.STATE_MINIMIZED,
"Window should be minimized before fullscreen."
);
info("Requesting fullscreen on a minimized window.");
promiseFullscreen = document.documentElement.requestFullscreen();
await promiseFullscreen;
ok(window.fullScreen, "Window should be fullscreen after being minimized.");
});

View File

@ -404,7 +404,7 @@ skip-if =
os == "win" && !debug
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
[browser_windowactivation.js]
skip-if =
skip-if =
verify
os == "linux" && debug # Bug 1678774
support-files =

View File

@ -1,78 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
Open one window, focus it and enter fullscreen, then exit fullscreen.
-->
<head>
<title>Simple Fullscreen Enter and Exit Test</title>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="file_fullscreen-utils.js"></script>
</head>
<body>
<div id="fullscreen-div"><p>Fullscreen div</p></div>
<script type="application/javascript">
function ok(condition, msg) {
opener.ok(condition, "[single] " + msg);
}
function is(value, expected, msg) {
opener.is(value, expected, "[single] " + msg);
}
function isnot(value, unexpected, msg) {
opener.isnot(value, unexpected, "[single] " + msg);
}
function info(msg) {
opener.info("[single] " + msg);
}
function windowResized() {
info(`Window resized to width: ${window.innerWidth}, height: ${window.innerHeight}.`);
}
async function begin() {
window.addEventListener('resize', windowResized);
info(`Starting window width: ${window.innerWidth}, height: ${window.innerHeight}.`);
let windowedWidth = window.innerWidth;
let windowedHeight = window.innerHeight;
info("Requesting fullscreen.");
let entryPromise = document.getElementById('fullscreen-div').requestFullscreen()
info("Fullscreen requested, waiting for promise to resolve.");
await entryPromise;
info("element.requestFullscreen() promise resolved.");
info(`Fullscreen window width: ${window.innerWidth}, height: ${window.innerHeight}.`);
isnot(document.fullscreenElement, null, "document.fullscreenElement should exist.");
ok(window.fullScreen, "window.fullScreen");
isnot(windowedWidth, window.innerWidth, "window width should be changed.");
isnot(windowedHeight, window.innerHeight, "window height should be changed.");
info("Requesting fullscreen exit.");
let exitPromise = document.exitFullscreen()
info("Fullscreen exit requested, waiting for promise to resolve.");
await exitPromise;
info("document.exitFullscreen() promise resolved.");
info(`Restored window width: ${window.innerWidth}, height: ${window.innerHeight}.`);
is(document.fullscreenElement, null, "document.fullscreenElement should be null.");
ok(!window.fullScreen, "window.fullScreen should be false.");
is(window.innerWidth, windowedWidth, "window width should be restored.");
is(window.innerHeight, windowedHeight, "window height should be restored.");
opener.nextTest();
}
</script>
</pre>
</body>
</html>

View File

@ -1,8 +1,8 @@
[DEFAULT]
tags = fullscreen
support-files =
file_fullscreen-api-race.html
file_fullscreen-api.html
file_fullscreen-api-race.html
file_fullscreen-async.html
file_fullscreen-backdrop.html
file_fullscreen-denied-inner.html
@ -27,7 +27,6 @@ support-files =
file_fullscreen-scrollbar.html
file_fullscreen-selector.html
file_fullscreen-shadowdom.html
file_fullscreen-single.html
file_fullscreen-sub-iframe.html
file_fullscreen-svg-element.html
file_fullscreen-table.html
@ -35,13 +34,14 @@ support-files =
file_fullscreen-utils.js
file_fullscreen-with-full-zoom.html
[test_fullscreen-api-race.html]
skip-if = toolkit == 'android' # same as test_fullscreen-api.html, 1356570
os == "mac" && debug
[test_fullscreen-api.html]
allow_xul_xbl = true # XUL is used in file_fullscreen-api.html
skip-if =
toolkit == 'android'
os == 'mac' && bits == 64 && debug # Bug 1579623
[test_fullscreen-api-race.html]
skip-if = toolkit == 'android' # same as test_fullscreen-api.html, 1356570
verify && debug && os == 'mac'
os == "mac" && debug
[test_fullscreen_meta_viewport.html]
[test_fullscreen_modal.html]

View File

@ -28,7 +28,6 @@ SimpleTest.requestFlakyTimeout("untriaged");
// run in an iframe, which by default will not have the allowfullscreen
// attribute set, so full-screen won't work.
var gTestWindows = [
{ test: "file_fullscreen-single.html" },
{ test: "file_fullscreen-multiple.html",
prefs: [["full-screen-api.exit-on.windowRaise", false],
["full-screen-api.exit-on.windowOpen", false]] },
@ -73,7 +72,6 @@ function nextTest() {
info("main window focused, starting next test");
SimpleTest.executeSoon(runNextTest);
}, {once: true});
info("testWindow.close()");
testWindow.close();
} else {
SimpleTest.executeSoon(runNextTest);

View File

@ -16,7 +16,6 @@
#include "nsCocoaUtils.h"
#include "nsTouchBar.h"
#include <dlfcn.h>
#include <queue>
class nsCocoaWindow;
class nsChildView;
@ -263,6 +262,8 @@ class nsCocoaWindow final : public nsBaseWidget, public nsPIWidgetCocoa {
virtual void SuppressAnimation(bool aSuppress) override;
virtual void HideWindowChrome(bool aShouldHide) override;
void WillEnterFullScreen(bool aFullScreen);
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;
@ -361,25 +362,6 @@ class nsCocoaWindow final : public nsBaseWidget, public nsPIWidgetCocoa {
const ScrollableLayerGuid& aGuid) override;
void StopAsyncAutoscroll(const ScrollableLayerGuid& aGuid) override;
// Class method versions of NSWindow/Delegate callbacks which need to
// access object state.
void CocoaWindowWillEnterFullscreen(bool aFullscreen);
void CocoaWindowDidFailFullscreen(bool aAttemptedFullscreen);
void CocoaWindowDidResize();
void CocoaSendToplevelActivateEvents();
void CocoaSendToplevelDeactivateEvents();
enum class TransitionType {
Windowed,
Fullscreen,
EmulatedFullscreen,
Miniaturize,
Deminiaturize,
Zoom,
};
void FinishCurrentTransition();
void FinishCurrentTransitionIfMatching(const TransitionType& aTransition);
protected:
virtual ~nsCocoaWindow();
@ -393,6 +375,7 @@ class nsCocoaWindow final : public nsBaseWidget, public nsPIWidgetCocoa {
void DoResize(double aX, double aY, double aWidth, double aHeight, bool aRepaint,
bool aConstrainToCurrentScreen);
inline bool ShouldToggleNativeFullscreen(bool aFullScreen, bool aUseSystemTransition);
void UpdateFullscreenState(bool aFullScreen, bool aNativeMode);
nsresult DoMakeFullScreen(bool aFullScreen, bool aUseSystemTransition);
@ -422,27 +405,8 @@ class nsCocoaWindow final : public nsBaseWidget, public nsPIWidgetCocoa {
// this is used for sibling sheet contention only
nsSizeMode mSizeMode;
bool mInFullScreenMode;
// Whether we are currently using native fullscreen. It could be false because
// we are in the emulated fullscreen where we do not use the native fullscreen.
bool mInNativeFullScreenMode;
mozilla::Maybe<TransitionType> mTransitionCurrent;
std::queue<TransitionType> mTransitionsPending;
// Whether we are treating the next resize as the start of a fullscreen transition.
// If we are, which direction are we going: Fullscreen or Windowed.
mozilla::Maybe<TransitionType> mUpdateFullscreenOnResize;
bool IsInTransition() { return mTransitionCurrent.isSome(); }
void QueueTransition(const TransitionType& aTransition);
void ProcessTransitions();
bool mInProcessTransitions = false;
// While running an emulated fullscreen transition, we want to suppress sending
// size mode events due to window resizing. We fix it up at the end when the
// transition is complete.
bool mSuppressSizeModeEvents = false;
bool mInFullScreenTransition; // true from the request to enter/exit fullscreen
// (MakeFullScreen() call) to EnteredFullScreen()
// Ignore occlusion events caused by displaying the temporary fullscreen
// window during the fullscreen transition animation because only focused
@ -452,6 +416,10 @@ class nsCocoaWindow final : public nsBaseWidget, public nsPIWidgetCocoa {
bool mModal;
bool mFakeModal;
// Whether we are currently using native fullscreen. It could be false because
// we are in the DOM fullscreen where we do not use the native fullscreen.
bool mInNativeFullScreenMode;
bool mIsAnimationSuppressed;
bool mInReportMoveEvent; // true if in a call to ReportMoveEvent().

View File

@ -139,10 +139,11 @@ nsCocoaWindow::nsCocoaWindow()
mSheetNeedsShow(false),
mSizeMode(nsSizeMode_Normal),
mInFullScreenMode(false),
mInNativeFullScreenMode(false),
mInFullScreenTransition(false),
mIgnoreOcclusionCount(0),
mModal(false),
mFakeModal(false),
mInNativeFullScreenMode(false),
mIsAnimationSuppressed(false),
mInReportMoveEvent(false),
mInResize(false),
@ -1255,15 +1256,32 @@ void nsCocoaWindow::Move(double aX, double aY) {
}
void nsCocoaWindow::SetSizeMode(nsSizeMode aMode) {
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
if (!mWindow) return;
// 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.
nsSizeMode previousMode = mSizeMode;
if (aMode == nsSizeMode_Normal) {
QueueTransition(TransitionType::Windowed);
if ([mWindow isMiniaturized])
[mWindow deminiaturize:nil];
else if (previousMode == nsSizeMode_Maximized && [mWindow isZoomed])
[mWindow zoom:nil];
else if (previousMode == nsSizeMode_Fullscreen)
MakeFullScreen(false);
} else if (aMode == nsSizeMode_Minimized) {
QueueTransition(TransitionType::Miniaturize);
if (![mWindow isMiniaturized]) [mWindow miniaturize:nil];
} else if (aMode == nsSizeMode_Maximized) {
QueueTransition(TransitionType::Zoom);
if ([mWindow isMiniaturized]) [mWindow deminiaturize:nil];
if (![mWindow isZoomed]) [mWindow zoom:nil];
} else if (aMode == nsSizeMode_Fullscreen) {
MakeFullScreen(true);
if (!mInFullScreenMode) MakeFullScreen(true);
}
NS_OBJC_END_TRY_IGNORE_BLOCK;
}
// The (work)space switching implementation below was inspired by Phoenix:
@ -1621,33 +1639,18 @@ static bool AlwaysUsesNativeFullScreen() {
[mFullscreenTransitionAnimation startAnimation];
}
void nsCocoaWindow::CocoaWindowWillEnterFullscreen(bool aFullscreen) {
MOZ_ASSERT(mUpdateFullscreenOnResize.isNothing());
// Ensure that we update our fullscreen state as early as possible, when the resize
// happens.
mUpdateFullscreenOnResize =
Some(aFullscreen ? TransitionType::Fullscreen : TransitionType::Windowed);
void nsCocoaWindow::WillEnterFullScreen(bool aFullScreen) {
if (mWidgetListener) {
mWidgetListener->FullscreenWillChange(aFullscreen);
mWidgetListener->FullscreenWillChange(aFullScreen);
}
// Update the state to full screen when we are entering, so that we switch to
// full screen view as soon as possible.
UpdateFullscreenState(aFullScreen, true);
}
void nsCocoaWindow::CocoaWindowDidFailFullscreen(bool aAttemptedFullscreen) {
if (mWidgetListener) {
mWidgetListener->FullscreenWillChange(!aAttemptedFullscreen);
}
// If we already updated our fullscreen state due to a resize, we need to update it again.
if (mUpdateFullscreenOnResize.isNothing()) {
UpdateFullscreenState(!aAttemptedFullscreen, true);
ReportSizeEvent();
}
TransitionType transition =
aAttemptedFullscreen ? TransitionType::Fullscreen : TransitionType::Windowed;
FinishCurrentTransitionIfMatching(transition);
void nsCocoaWindow::EnteredFullScreen(bool aFullScreen, bool aNativeMode) {
mInFullScreenTransition = false;
UpdateFullscreenState(aFullScreen, aNativeMode);
}
void nsCocoaWindow::UpdateFullscreenState(bool aFullScreen, bool aNativeMode) {
@ -1668,6 +1671,29 @@ void nsCocoaWindow::UpdateFullscreenState(bool aFullScreen, bool aNativeMode) {
}
}
inline bool nsCocoaWindow::ShouldToggleNativeFullscreen(bool aFullScreen,
bool aUseSystemTransition) {
// First check if this window supports entering native fullscreen.
// This is set based on the macnativefullscreen attribute on the window's
// document element.
NSWindowCollectionBehavior colBehavior = [mWindow collectionBehavior];
if (!(colBehavior & NSWindowCollectionBehaviorFullScreenPrimary)) {
return false;
}
if (mInNativeFullScreenMode) {
// If we are using native fullscreen, go ahead to exit it.
return true;
}
if (!aUseSystemTransition) {
// If we do not want the system fullscreen transition,
// don't use the native fullscreen.
return false;
}
// If we are using native fullscreen, we should have returned earlier.
return aFullScreen;
}
nsresult nsCocoaWindow::MakeFullScreen(bool aFullScreen) {
return DoMakeFullScreen(aFullScreen, AlwaysUsesNativeFullScreen());
}
@ -1677,196 +1703,45 @@ nsresult nsCocoaWindow::MakeFullScreenWithNativeTransition(bool aFullScreen) {
}
nsresult nsCocoaWindow::DoMakeFullScreen(bool aFullScreen, bool aUseSystemTransition) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
if (!mWindow) {
return NS_OK;
}
// Figure out what type of transition is being requested.
TransitionType transition = TransitionType::Windowed;
if (aFullScreen) {
// Decide whether to use fullscreen or emulated fullscreen.
transition = (aUseSystemTransition &&
(mWindow.collectionBehavior & NSWindowCollectionBehaviorFullScreenPrimary))
? TransitionType::Fullscreen
: TransitionType::EmulatedFullscreen;
// 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 (mInFullScreenMode == aFullScreen) {
return NS_OK;
}
mInFullScreenTransition = true;
if (ShouldToggleNativeFullscreen(aFullScreen, aUseSystemTransition)) {
MOZ_ASSERT(mInNativeFullScreenMode != aFullScreen,
"We shouldn't have been in native fullscreen.");
// Calling toggleFullScreen will result in windowDid(FailTo)?(Enter|Exit)FullScreen
// to be called from the OS. We will call EnteredFullScreen from those methods,
// where mInFullScreenMode will be set and a sizemode event will be dispatched.
[mWindow toggleFullScreen:nil];
} else {
if (mWidgetListener) {
mWidgetListener->FullscreenWillChange(aFullScreen);
}
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);
nsBaseWidget::InfallibleMakeFullScreen(aFullScreen);
NSEnableScreenUpdates();
EnteredFullScreen(aFullScreen, /* aNativeMode */ false);
}
QueueTransition(transition);
return NS_OK;
}
void nsCocoaWindow::QueueTransition(const TransitionType& aTransition) {
mTransitionsPending.push(aTransition);
ProcessTransitions();
}
void nsCocoaWindow::ProcessTransitions() {
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK
if (mInProcessTransitions) {
return;
}
mInProcessTransitions = true;
// Start a loop that will continue as long as we have transitions to process
// and we aren't waiting on an asynchronous transition to complete. Any
// transition that starts something async will `continue` this loop to exit.
while (!mTransitionsPending.empty() && !IsInTransition()) {
TransitionType nextTransition = mTransitionsPending.front();
// We have to check for some incompatible transition states, and if we find one,
// instead perform an alternative transition and leave the queue untouched. If
// we add one of these transitions, we suppress size mode events because we don't
// want to confuse listeners who are expecting to receive exactly one event when
// the requested transition has completed. The mSuppressSizeModeEvents flag is
// cleared in FinishCurrentTransitionIfMatching.
switch (nextTransition) {
case TransitionType::Fullscreen:
case TransitionType::EmulatedFullscreen:
case TransitionType::Windowed:
case TransitionType::Zoom:
// These can't handle miniaturized windows, so deminiaturize first.
if (mWindow.miniaturized) {
// Anything other than Windowed will be confused by the size mode event
// posted by deminiaturization.
if (nextTransition != TransitionType::Windowed) {
mSuppressSizeModeEvents = true;
}
mTransitionCurrent = Some(TransitionType::Deminiaturize);
}
break;
case TransitionType::Miniaturize:
// This can't handle fullscreen, so go to windowed first.
if (mInFullScreenMode) {
mSuppressSizeModeEvents = true;
mTransitionCurrent = Some(TransitionType::Windowed);
}
break;
default:
break;
}
// If mTransitionCurrent is still empty, then we use the nextTransition and pop
// the queue.
if (mTransitionCurrent.isNothing()) {
mTransitionCurrent = Some(nextTransition);
mTransitionsPending.pop();
}
switch (*mTransitionCurrent) {
case TransitionType::Fullscreen: {
if (!mInFullScreenMode) {
// This triggers an async animation, so continue.
[mWindow toggleFullScreen:nil];
continue;
}
break;
}
case TransitionType::EmulatedFullscreen: {
if (!mInFullScreenMode) {
// This can be done synchronously.
if (mWidgetListener) {
mWidgetListener->FullscreenWillChange(true);
}
NSDisableScreenUpdates();
mSuppressSizeModeEvents = true;
// 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(true);
nsBaseWidget::InfallibleMakeFullScreen(true);
mSuppressSizeModeEvents = false;
NSEnableScreenUpdates();
UpdateFullscreenState(true, false);
}
break;
}
case TransitionType::Windowed: {
if (mInFullScreenMode) {
if (mInNativeFullScreenMode) {
// This triggers an async animation, so continue.
[mWindow toggleFullScreen:nil];
continue;
} else {
// This can be done synchronously.
if (mWidgetListener) {
mWidgetListener->FullscreenWillChange(false);
}
NSDisableScreenUpdates();
mSuppressSizeModeEvents = true;
// 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(false);
nsBaseWidget::InfallibleMakeFullScreen(false);
mSuppressSizeModeEvents = false;
NSEnableScreenUpdates();
UpdateFullscreenState(false, false);
}
} else if (mWindow.zoomed) {
[mWindow zoom:nil];
}
break;
}
case TransitionType::Miniaturize:
if (!mWindow.miniaturized) {
// This triggers an async animation, so continue.
[mWindow miniaturize:nil];
continue;
}
break;
case TransitionType::Deminiaturize:
if (mWindow.miniaturized) {
// This triggers an async animation, so continue.
[mWindow deminiaturize:nil];
continue;
}
break;
case TransitionType::Zoom:
if (!mWindow.zoomed) {
[mWindow zoom:nil];
}
break;
default:
break;
}
mTransitionCurrent.reset();
}
mInProcessTransitions = false;
NS_OBJC_END_TRY_IGNORE_BLOCK;
}
void nsCocoaWindow::FinishCurrentTransition() {
mTransitionCurrent.reset();
mSuppressSizeModeEvents = false;
ProcessTransitions();
}
void nsCocoaWindow::FinishCurrentTransitionIfMatching(const TransitionType& aTransition) {
// We've just finished some transition activity, and we're not sure whether it was
// triggered programmatically, or by the user. If it matches our current transition,
// then assume it was triggered programmatically and we can clean up that transition
// and start processing transitions again.
if (mTransitionCurrent.isSome() && (*mTransitionCurrent == aTransition)) {
// This matches our current transition. Since this function is called from
// nsWindowDelegate transition callbacks, we want to make sure those callbacks are
// all the way done before we start processing more transitions. To accomplish
// this, we dispatch our cleanup to happen on the next event loop. Doing this will
// ensure that any async native transition methods we call (like toggleFullscreen)
// will succeed.
NS_DispatchToCurrentThread(NewRunnableMethod("FinishCurrentTransition", this,
&nsCocoaWindow::FinishCurrentTransition));
}
NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
}
// Coordinates are desktop pixels
@ -2221,12 +2096,12 @@ void nsCocoaWindow::DispatchSizeModeEvent() {
return;
}
if (mSuppressSizeModeEvents) {
return;
}
nsSizeMode newMode = GetWindowSizeMode(mWindow, mInFullScreenMode);
if (mSizeMode == newMode) {
// Don't dispatch a sizemode event if:
// 1. the window is transitioning to fullscreen
// 2. the new sizemode is the same as the current sizemode
if (mInFullScreenTransition || mSizeMode == newMode) {
return;
}
@ -2263,6 +2138,7 @@ void nsCocoaWindow::ReportSizeEvent() {
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
UpdateBounds();
if (mWidgetListener) {
LayoutDeviceIntRect innerBounds = GetClientBounds();
mWidgetListener->WindowResized(this, innerBounds.width, innerBounds.height);
@ -2789,50 +2665,19 @@ already_AddRefed<nsIWidget> nsIWidget::CreateChildWindow() {
- (NSSize)windowWillResize:(NSWindow*)sender toSize:(NSSize)proposedFrameSize {
RollUpPopups();
return proposedFrameSize;
}
void nsCocoaWindow::CocoaSendToplevelActivateEvents() {
if (mWidgetListener) {
mWidgetListener->WindowActivated();
}
}
void nsCocoaWindow::CocoaSendToplevelDeactivateEvents() {
if (mWidgetListener) {
mWidgetListener->WindowDeactivated();
}
}
void nsCocoaWindow::CocoaWindowDidResize() {
// It's important to update our bounds before we trigger any listeners. This
// ensures that our bounds are correct when GetScreenBounds is called.
UpdateBounds();
if (mUpdateFullscreenOnResize.isSome()) {
// Act as if the native fullscreen transition is complete, doing everything other
// than actually clearing the transition state, which will happen when one of the
// appropriate windowDid delegate methods is called.
bool toFullscreen = (*mUpdateFullscreenOnResize == TransitionType::Fullscreen);
mUpdateFullscreenOnResize.reset();
UpdateFullscreenState(toFullscreen, true);
ReportSizeEvent();
return;
}
// Resizing might have changed our zoom state.
DispatchSizeModeEvent();
ReportSizeEvent();
}
- (void)windowDidResize:(NSNotification*)aNotification {
BaseWindow* window = [aNotification object];
[window updateTrackingArea];
if (!mGeckoWindow) return;
mGeckoWindow->CocoaWindowDidResize();
// Resizing might have changed our zoom state.
mGeckoWindow->DispatchSizeModeEvent();
mGeckoWindow->ReportSizeEvent();
}
- (void)windowDidChangeScreen:(NSNotification*)aNotification {
@ -2869,13 +2714,20 @@ void nsCocoaWindow::CocoaWindowDidResize() {
if (!mGeckoWindow) {
return;
}
mGeckoWindow->CocoaWindowWillEnterFullscreen(true);
mGeckoWindow->WillEnterFullScreen(true);
}
// 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);
// On Yosemite, the NSThemeFrame class has two new properties --
// titlebarView (an NSTitlebarView object) and titlebarContainerView (an
// NSTitlebarContainerView object). These are used to display the titlebar
@ -2898,40 +2750,38 @@ void nsCocoaWindow::CocoaWindowDidResize() {
if ([titlebarContainerView respondsToSelector:@selector(setTransparent:)]) {
[titlebarContainerView setTransparent:NO];
}
if (!mGeckoWindow) {
return;
}
mGeckoWindow->FinishCurrentTransitionIfMatching(nsCocoaWindow::TransitionType::Fullscreen);
}
- (void)windowWillExitFullScreen:(NSNotification*)notification {
if (!mGeckoWindow) {
return;
}
mGeckoWindow->CocoaWindowWillEnterFullscreen(false);
mGeckoWindow->WillEnterFullScreen(false);
}
- (void)windowDidExitFullScreen:(NSNotification*)notification {
if (!mGeckoWindow) {
return;
}
mGeckoWindow->FinishCurrentTransitionIfMatching(nsCocoaWindow::TransitionType::Windowed);
mGeckoWindow->EnteredFullScreen(false);
}
- (void)windowDidFailToEnterFullScreen:(NSWindow*)window {
if (!mGeckoWindow) {
return;
}
mGeckoWindow->CocoaWindowDidFailFullscreen(true);
mGeckoWindow->EnteredFullScreen(false);
}
- (void)windowDidFailToExitFullScreen:(NSWindow*)window {
if (!mGeckoWindow) {
return;
}
mGeckoWindow->CocoaWindowDidFailFullscreen(false);
mGeckoWindow->EnteredFullScreen(true);
}
- (void)windowDidBecomeMain:(NSNotification*)aNotification {
@ -3033,19 +2883,11 @@ void nsCocoaWindow::CocoaWindowDidResize() {
}
- (void)windowDidMiniaturize:(NSNotification*)aNotification {
if (!mGeckoWindow) {
return;
}
mGeckoWindow->DispatchSizeModeEvent();
mGeckoWindow->FinishCurrentTransitionIfMatching(nsCocoaWindow::TransitionType::Miniaturize);
if (mGeckoWindow) mGeckoWindow->DispatchSizeModeEvent();
}
- (void)windowDidDeminiaturize:(NSNotification*)aNotification {
if (!mGeckoWindow) {
return;
}
mGeckoWindow->DispatchSizeModeEvent();
mGeckoWindow->FinishCurrentTransitionIfMatching(nsCocoaWindow::TransitionType::Deminiaturize);
if (mGeckoWindow) mGeckoWindow->DispatchSizeModeEvent();
}
- (BOOL)windowShouldZoom:(NSWindow*)window toFrame:(NSRect)proposedFrame {
@ -3114,15 +2956,20 @@ void nsCocoaWindow::CocoaWindowDidResize() {
- (void)sendToplevelActivateEvents {
if (!mToplevelActiveState && mGeckoWindow) {
mGeckoWindow->CocoaSendToplevelActivateEvents();
nsIWidgetListener* listener = mGeckoWindow->GetWidgetListener();
if (listener) {
listener->WindowActivated();
}
mToplevelActiveState = true;
}
}
- (void)sendToplevelDeactivateEvents {
if (mToplevelActiveState && mGeckoWindow) {
mGeckoWindow->CocoaSendToplevelDeactivateEvents();
nsIWidgetListener* listener = mGeckoWindow->GetWidgetListener();
if (listener) {
listener->WindowDeactivated();
}
mToplevelActiveState = false;
}
}

View File

@ -24,9 +24,8 @@ const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
let gWindow = null;
const kIsLinux = navigator.platform.includes("Lin");
const kIsMacOS = navigator.platform.includes("Mac");
// On Linux and macOS sizemode changes might be async.
const kAsyncChanges = kIsLinux || kIsMacOS;
// On Linux sizemode changes might be async.
const kAsyncChanges = kIsLinux;
let gSizeModeDidChange = false;
let gSizeModeDidChangeTo = 0;