зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1708324 - [Fission] Full screen button for YouTube video embedded on Reddit doesn't work r=spohl
During fullscreen transitions on Mac, ignore occlusion events caused by the widget DOM fullscreen transition effect which uses a temporary window. Add a test that attempts to enter fullscreen from a non-focused window. This test is to ensure the fix (and future fixes) do not regress the focus requirement for fullscreen. Differential Revision: https://phabricator.services.mozilla.com/D115046
This commit is contained in:
Родитель
30aa92212a
Коммит
e84c0b8236
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Focus test - child window</title>
|
||||
<script type="application/javascript" src="file_fullscreen-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
function enterFullscreen() {
|
||||
addFullscreenErrorContinuation(() => { opener.enteredFullscreen(false); });
|
||||
|
||||
addFullscreenChangeContinuation("enter", () => {
|
||||
opener.enteredFullscreen(true);
|
||||
});
|
||||
|
||||
document.body.requestFullscreen();
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,67 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
|
||||
Test that a fullscreen request fails if the window is not focused.
|
||||
|
||||
Open window1, open window2, focus window2, and then attempt to fullscreen
|
||||
window1 while it is not focused. The fullscreen attempt should be rejected
|
||||
because the window is not focused.
|
||||
|
||||
-->
|
||||
<head>
|
||||
<title>Test fullscreen request is blocked when window is not focused</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>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
function ok(condition, msg) {
|
||||
opener.ok(condition, "[focus] " + msg);
|
||||
}
|
||||
|
||||
var window1, window2;
|
||||
|
||||
function openWindow() {
|
||||
var w = window.open("file_fullscreen-focus-inner.html", "",
|
||||
"width=500,height=500");
|
||||
return w;
|
||||
}
|
||||
|
||||
function begin() {
|
||||
window1 = openWindow();
|
||||
window1.focus();
|
||||
|
||||
SimpleTest.waitForFocus(function(){
|
||||
window2 = openWindow();
|
||||
window2.focus();
|
||||
|
||||
SimpleTest.waitForFocus(function(){
|
||||
// Now that window2 is focused, attempt to fullscreen window1.
|
||||
// This should fail.
|
||||
window1.enterFullscreen("one");
|
||||
}, window2);
|
||||
|
||||
}, window1);
|
||||
}
|
||||
|
||||
async function enteredFullscreen(enteredSuccessfully) {
|
||||
ok(!enteredSuccessfully, "window1 did not enter fullscreen");
|
||||
|
||||
if (enteredSuccessfully) {
|
||||
await window1.document.exitFullscreen()
|
||||
}
|
||||
|
||||
window1.close();
|
||||
window2.close();
|
||||
opener.nextTest();
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
<div id="full-screen-element"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -451,6 +451,8 @@ support-files =
|
|||
file_fullscreen-event-order.html
|
||||
file_fullscreen-featurePolicy.html
|
||||
file_fullscreen-featurePolicy-inner.html
|
||||
file_fullscreen-focus.html
|
||||
file_fullscreen-focus-inner.html
|
||||
file_fullscreen-hidden.html
|
||||
file_fullscreen-lenient-setters.html
|
||||
file_fullscreen-multiple-inner.html
|
||||
|
|
|
@ -36,6 +36,7 @@ var gTestWindows = [
|
|||
{ test: "file_fullscreen-denied.html" },
|
||||
{ test: "file_fullscreen-api.html" },
|
||||
{ test: "file_fullscreen-hidden.html" },
|
||||
{ test: "file_fullscreen-focus.html" },
|
||||
{ test: "file_fullscreen-svg-element.html" },
|
||||
{ test: "file_fullscreen-navigation.html" },
|
||||
{ test: "file_fullscreen-scrollbar.html" },
|
||||
|
|
|
@ -265,6 +265,7 @@ class nsCocoaWindow final : public nsBaseWidget, public nsPIWidgetCocoa {
|
|||
virtual bool PrepareForFullscreenTransition(nsISupports** aData) override;
|
||||
virtual void PerformFullscreenTransition(FullscreenTransitionStage aStage, uint16_t aDuration,
|
||||
nsISupports* aData, nsIRunnable* aCallback) override;
|
||||
virtual void CleanupFullscreenTransition() override;
|
||||
nsresult MakeFullScreen(bool aFullScreen, nsIScreen* aTargetScreen = nullptr) final;
|
||||
nsresult MakeFullScreenWithNativeTransition(bool aFullScreen,
|
||||
nsIScreen* aTargetScreen = nullptr) final;
|
||||
|
@ -409,6 +410,12 @@ class nsCocoaWindow final : public nsBaseWidget, public nsPIWidgetCocoa {
|
|||
bool mInFullScreenMode;
|
||||
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
|
||||
// contexts are permitted to enter DOM fullscreen.
|
||||
int mIgnoreOcclusionCount;
|
||||
|
||||
bool mModal;
|
||||
bool mFakeModal;
|
||||
|
||||
|
|
|
@ -136,6 +136,7 @@ nsCocoaWindow::nsCocoaWindow()
|
|||
mSheetNeedsShow(false),
|
||||
mInFullScreenMode(false),
|
||||
mInFullScreenTransition(false),
|
||||
mIgnoreOcclusionCount(0),
|
||||
mModal(false),
|
||||
mFakeModal(false),
|
||||
mInNativeFullScreenMode(false),
|
||||
|
@ -1516,6 +1517,17 @@ static bool AlwaysUsesNativeFullScreen() {
|
|||
if (AlwaysUsesNativeFullScreen()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Our fullscreen transition creates a new window occluding this window.
|
||||
// That triggers an occlusion event which can cause DOM fullscreen requests
|
||||
// to fail due to the context not being focused at the time the focus check
|
||||
// is performed in the child process. Until the transition is cleaned up in
|
||||
// CleanupFullscreenTransition(), ignore occlusion events for this window.
|
||||
// If this method is changed to return false, the transition will not be
|
||||
// performed and mIgnoreOcclusionCount should not be incremented.
|
||||
MOZ_ASSERT(mIgnoreOcclusionCount >= 0);
|
||||
mIgnoreOcclusionCount++;
|
||||
|
||||
nsCOMPtr<nsIScreen> widgetScreen = GetWidgetScreen();
|
||||
NSScreen* cocoaScreen = ScreenHelperCocoa::CocoaScreenForScreen(widgetScreen);
|
||||
|
||||
|
@ -1535,6 +1547,11 @@ static bool AlwaysUsesNativeFullScreen() {
|
|||
return true;
|
||||
}
|
||||
|
||||
/* virtual */ void nsCocoaWindow::CleanupFullscreenTransition() {
|
||||
MOZ_ASSERT(mIgnoreOcclusionCount > 0);
|
||||
mIgnoreOcclusionCount--;
|
||||
}
|
||||
|
||||
/* virtual */ void nsCocoaWindow::PerformFullscreenTransition(FullscreenTransitionStage aStage,
|
||||
uint16_t aDuration,
|
||||
nsISupports* aData,
|
||||
|
@ -2048,6 +2065,11 @@ void nsCocoaWindow::DispatchOcclusionEvent() {
|
|||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mIgnoreOcclusionCount >= 0);
|
||||
if (newOcclusionState && mIgnoreOcclusionCount > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
mIsFullyOccluded = newOcclusionState;
|
||||
if (mWidgetListener) {
|
||||
mWidgetListener->OcclusionStateChanged(mIsFullyOccluded);
|
||||
|
|
Загрузка…
Ссылка в новой задаче