Bug 1276537 part 1 - Make resizable window on macOS always show full screen button. r=spohl

Differential Revision: https://phabricator.services.mozilla.com/D74833
This commit is contained in:
Xidorn Quan 2020-05-15 06:19:14 +00:00
Родитель 80d3b6bc61
Коммит 58b03accf4
6 изменённых файлов: 80 добавлений и 97 удалений

Просмотреть файл

@ -30,20 +30,36 @@ var timeoutID;
var eventOffsetX = 2;
var eventOffsetY = 2;
let sizemodeChanged = false;
let fullscreenChanged = false;
let childHasFocused = false;
function openFullscreenWindow() {
win = window.docShell.rootTreeItem.domWindow
.openDialog("bug665540_window.xhtml", "_blank", "resizable=yes,chrome", window);
win.addEventListener("sizemodechange",
function() {
info("sizemodechange. windowState = " + win.windowState + " fullScreen = " + win.fullScreen);
});
win.addEventListener("fullscreen",
function() {
info("fullscreen event. windowState = " + win.windowState + " fullScreen = " + win.fullScreen);
});
info("win.windowState = " + win.windowState);
info("win.fullScreen = " + win.fullScreen);
// size mode and full screen may change asynchronously after child gets focused.
if (win.windowState == win.STATE_FULLSCREEN) {
sizemodeChanged = true;
} else {
win.addEventListener("sizemodechange", () => {
info("sizemodechange. windowState = " + win.windowState + " fullScreen = " + win.fullScreen);
sizemodeChanged = true;
tryStart();
}, { once: true });
}
if (win.fullScreen) {
fullscreenChanged = true;
} else {
win.addEventListener("fullscreen", () => {
info("fullscreen event. windowState = " + win.windowState + " fullScreen = " + win.fullScreen);
fullscreenChanged = true;
tryStart();
}, { once: true });
}
// Close our window if the test times out so that it doesn't interfere
// with later tests.
timeoutID = setTimeout(function () {
@ -54,9 +70,15 @@ function openFullscreenWindow() {
}
function childFocused() {
ok(win.fullScreen, "window should be fullscreen");
is(win.windowState, win.STATE_FULLSCREEN,
"window state should be fullscreen");
info("child focused. windowState = " + win.windowState + " fullScreen = " + win.fullScreen);
childHasFocused = true;
tryStart();
}
function tryStart() {
if (!sizemodeChanged || !fullscreenChanged || !childHasFocused) {
return;
}
// The select doesn't open if the mouse click is fired too soon
// (on X11 at least).

Просмотреть файл

@ -27,7 +27,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1104916
});
// Chrome test run tests in iframe, and fullscreen is disabled by default.
// So run the test in a separate window.
window.open("display_mode.html", "display_mode", "width=500,height=500");
window.open("display_mode.html", "display_mode", "width=500,height=500,resizable");
}
</script>
</head>

Просмотреть файл

@ -27,7 +27,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1256084
});
// Chrome test run tests in iframe, and fullscreen is disabled by default.
// So run the test in a separate window.
window.open("display_mode_reflow.html", "display_mode_reflow", "width=500,height=500");
window.open("display_mode_reflow.html", "display_mode_reflow", "width=500,height=500,resizable");
}
</script>
</head>

Просмотреть файл

@ -302,7 +302,6 @@ class nsCocoaWindow final : public nsBaseWidget, public nsPIWidgetCocoa {
virtual void SetWindowTransform(const mozilla::gfx::Matrix& aTransform) override;
virtual void SetWindowMouseTransparent(bool aIsTransparent) override;
virtual void SetShowsToolbarButton(bool aShow) override;
virtual void SetShowsFullScreenButton(bool aShow) override;
virtual void SetWindowAnimationType(WindowAnimationType aType) override;
virtual void SetDrawsTitle(bool aDrawTitle) override;
virtual void SetUseBrightTitlebarForeground(bool aBrightForeground) override;
@ -387,8 +386,6 @@ class nsCocoaWindow final : public nsBaseWidget, public nsPIWidgetCocoa {
bool mModal;
bool mFakeModal;
// Only true on 10.7+ if SetShowsFullScreenButton(true) is called.
bool mSupportsNativeFullScreen;
// 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;

Просмотреть файл

@ -158,7 +158,6 @@ nsCocoaWindow::nsCocoaWindow()
mInFullScreenTransition(false),
mModal(false),
mFakeModal(false),
mSupportsNativeFullScreen(false),
mInNativeFullScreenMode(false),
mIsAnimationSuppressed(false),
mInReportMoveEvent(false),
@ -494,12 +493,15 @@ nsresult nsCocoaWindow::CreateNativeWindow(const NSRect& aRect, nsBorderStyle aB
[mWindow setOpaque:YES];
}
NSWindowCollectionBehavior newBehavior = [mWindow collectionBehavior];
if (mAlwaysOnTop) {
[mWindow setLevel:NSFloatingWindowLevel];
NSWindowCollectionBehavior newBehavior = [mWindow collectionBehavior];
newBehavior |= NSWindowCollectionBehaviorCanJoinAllSpaces;
[mWindow setCollectionBehavior:newBehavior];
}
if ((features & NSResizableWindowMask)) {
newBehavior |= NSWindowCollectionBehaviorFullScreenPrimary;
}
[mWindow setCollectionBehavior:newBehavior];
[mWindow setContentMinSize:NSMakeSize(60, 60)];
[mWindow disableCursorRects];
@ -1578,10 +1580,6 @@ void nsCocoaWindow::UpdateFullscreenState(bool aFullScreen, bool aNativeMode) {
inline bool nsCocoaWindow::ShouldToggleNativeFullscreen(bool aFullScreen,
bool aUseSystemTransition) {
if (!mSupportsNativeFullScreen) {
// If we cannot use native fullscreen, don't touch it.
return false;
}
if (mInNativeFullScreenMode) {
// If we are using native fullscreen, go ahead to exit it.
return true;
@ -1621,14 +1619,6 @@ nsresult nsCocoaWindow::DoMakeFullScreen(bool aFullScreen, bool aUseSystemTransi
mInFullScreenTransition = true;
if (ShouldToggleNativeFullscreen(aFullScreen, aUseSystemTransition)) {
// If we're using native fullscreen mode and our native window is invisible,
// our attempt to go into fullscreen mode will fail with an assertion in
// system code, without [WindowDelegate windowDidFailToEnterFullScreen:]
// ever getting called. To pre-empt this we bail here. See bug 752294.
if (aFullScreen && ![mWindow isVisible]) {
EnteredFullScreen(false);
return NS_OK;
}
MOZ_ASSERT(mInNativeFullScreenMode != aFullScreen,
"We shouldn't have been in native fullscreen.");
// Calling toggleFullScreen will result in windowDid(FailTo)?(Enter|Exit)FullScreen
@ -2307,41 +2297,6 @@ void nsCocoaWindow::SetShowsToolbarButton(bool aShow) {
NS_OBJC_END_TRY_ABORT_BLOCK;
}
void nsCocoaWindow::SetShowsFullScreenButton(bool aShow) {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
if (!mWindow || ![mWindow respondsToSelector:@selector(toggleFullScreen:)] ||
mSupportsNativeFullScreen == aShow) {
return;
}
// If the window is currently in fullscreen mode, then we're going to
// transition out first, then set the collection behavior & toggle
// mSupportsNativeFullScreen, then transtion back into fullscreen mode. This
// prevents us from getting into a conflicting state with MakeFullScreen
// where mSupportsNativeFullScreen would lead us down the wrong path.
bool wasFullScreen = mInFullScreenMode;
if (wasFullScreen) {
MakeFullScreen(false);
}
NSWindowCollectionBehavior newBehavior = [mWindow collectionBehavior];
if (aShow) {
newBehavior |= NSWindowCollectionBehaviorFullScreenPrimary;
} else {
newBehavior &= ~NSWindowCollectionBehaviorFullScreenPrimary;
}
[mWindow setCollectionBehavior:newBehavior];
mSupportsNativeFullScreen = aShow;
if (wasFullScreen) {
MakeFullScreen(true);
}
NS_OBJC_END_TRY_ABORT_BLOCK;
}
void nsCocoaWindow::SetWindowAnimationType(nsIWidget::WindowAnimationType aType) {
mAnimationType = aType;
}

Просмотреть файл

@ -27,41 +27,50 @@ function isnot(aLeft, aRight, aMessage)
window.arguments[0].SimpleTest.isnot(aLeft, aRight, aMessage);
}
function executeSoon(aFct)
{
window.arguments[0].SimpleTest.executeSoon(aFct);
function executeSoon() {
return new Promise(resolve => {
window.arguments[0].SimpleTest.executeSoon(resolve);
});
}
function start() {
window.onfocus = function () {
window.onfocus = null;
var oldOuterWidth = window.outerWidth, oldOuterHeight = window.outerHeight;
var oldInnerWidth = window.innerWidth, oldInnerHeight = window.innerHeight;
document.documentElement.setAttribute("drawintitlebar", "true");
function waitForEvent(obj, name) {
return new Promise(resolve => {
obj.addEventListener(name, resolve, { once: true });
});
}
executeSoon(function() {
is(window.outerWidth, oldOuterWidth, "drawintitlebar shouldn't change the window's outerWidth");
is(window.outerHeight, oldOuterHeight, "drawintitlebar shouldn't change the window's outerHeight");
is(window.innerWidth, oldOuterWidth, "if drawintitlebar is set, innerWidth and outerWidth should be the same");
is(window.innerHeight, oldOuterHeight, "if drawintitlebar is set, innerHeight and outerHeight should be the same");
window.fullScreen = true;
window.fullScreen = false;
is(window.outerWidth, oldOuterWidth, "wrong outerWidth after fullscreen mode");
is(window.outerHeight, oldOuterHeight, "wrong outerHeight after fullscreen mode");
is(window.innerWidth, oldOuterWidth, "wrong innerWidth after fullscreen mode");
is(window.innerHeight, oldOuterHeight, "wrong innerHeight after fullscreen mode");
document.documentElement.removeAttribute("drawintitlebar");
async function start() {
await waitForEvent(window, "focus");
var oldOuterWidth = window.outerWidth, oldOuterHeight = window.outerHeight;
var oldInnerWidth = window.innerWidth, oldInnerHeight = window.innerHeight;
document.documentElement.setAttribute("drawintitlebar", "true");
executeSoon(function() {
is(window.outerWidth, oldOuterWidth, "wrong outerWidth after removing drawintitlebar");
is(window.outerHeight, oldOuterHeight, "wrong outerHeight after removing drawintitlebar");
is(window.innerWidth, oldInnerWidth, "wrong innerWidth after removing drawintitlebar");
is(window.innerHeight, oldInnerHeight, "wrong innerHeight after removing drawintitlebar");
window.arguments[0].SimpleTest.finish();
window.close();
});
});
}
await executeSoon();
is(window.outerWidth, oldOuterWidth, "drawintitlebar shouldn't change the window's outerWidth");
is(window.outerHeight, oldOuterHeight, "drawintitlebar shouldn't change the window's outerHeight");
is(window.innerWidth, oldOuterWidth, "if drawintitlebar is set, innerWidth and outerWidth should be the same");
is(window.innerHeight, oldOuterHeight, "if drawintitlebar is set, innerHeight and outerHeight should be the same");
// Wait for going full screen and back.
let sizemodeChange = waitForEvent(window, "sizemodechange");
window.fullScreen = true;
await sizemodeChange;
sizemodeChange = waitForEvent(window, "sizemodechange");
window.fullScreen = false;
await sizemodeChange;
is(window.outerWidth, oldOuterWidth, "wrong outerWidth after fullscreen mode");
is(window.outerHeight, oldOuterHeight, "wrong outerHeight after fullscreen mode");
is(window.innerWidth, oldOuterWidth, "wrong innerWidth after fullscreen mode");
is(window.innerHeight, oldOuterHeight, "wrong innerHeight after fullscreen mode");
document.documentElement.removeAttribute("drawintitlebar");
await executeSoon();
is(window.outerWidth, oldOuterWidth, "wrong outerWidth after removing drawintitlebar");
is(window.outerHeight, oldOuterHeight, "wrong outerHeight after removing drawintitlebar");
is(window.innerWidth, oldInnerWidth, "wrong innerWidth after removing drawintitlebar");
is(window.innerHeight, oldInnerHeight, "wrong innerHeight after removing drawintitlebar");
window.arguments[0].SimpleTest.finish();
window.close();
}