mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 12:51:06 +00:00
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:
parent
b22b618764
commit
5df475dc34
@ -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]
|
||||
|
@ -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.");
|
||||
});
|
@ -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 =
|
||||
|
@ -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>
|
@ -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]
|
||||
|
@ -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);
|
||||
|
@ -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().
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user