From 6f4b15e60d5d0cbd1f8be8810bc83e58cc1c4ba0 Mon Sep 17 00:00:00 2001 From: Edgar Chen Date: Tue, 4 Jun 2024 23:38:45 +0000 Subject: [PATCH] Bug 1883396 - Exit fullscreen when two Escape keyup events occur in a short time; r=smaug Differential Revision: https://phabricator.services.mozilla.com/D209667 --- layout/base/PresShell.cpp | 30 +++++++++++++++++++----- layout/base/PresShell.h | 4 ++++ modules/libpref/init/StaticPrefList.yaml | 7 ++++++ 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp index c184b74e2d8a..6e588cff05c8 100644 --- a/layout/base/PresShell.cpp +++ b/layout/base/PresShell.cpp @@ -8669,12 +8669,30 @@ void PresShell::EventHandler::MaybeHandleKeyboardEventBeforeDispatch( // The event listeners in chrome can prevent this ESC behavior by // calling prevent default on the preceding keydown/press events. - if (!mPresShell->mIsLastChromeOnlyEscapeKeyConsumed && - aKeyboardEvent->mMessage == eKeyUp) { - // ESC key released while in DOM fullscreen mode. - // Fully exit all browser windows and documents from - // fullscreen mode. - Document::AsyncExitFullscreen(nullptr); + if (aKeyboardEvent->mMessage == eKeyUp) { + bool shouldExitFullscreen = + !mPresShell->mIsLastChromeOnlyEscapeKeyConsumed; + if (!shouldExitFullscreen) { + if (mPresShell->mLastConsumedEscapeKeyUpForFullscreen && + (aKeyboardEvent->mTimeStamp - + mPresShell->mLastConsumedEscapeKeyUpForFullscreen) <= + TimeDuration::FromMilliseconds( + StaticPrefs:: + dom_fullscreen_force_exit_on_multiple_escape_interval())) { + shouldExitFullscreen = true; + mPresShell->mLastConsumedEscapeKeyUpForFullscreen = TimeStamp(); + } else { + mPresShell->mLastConsumedEscapeKeyUpForFullscreen = + aKeyboardEvent->mTimeStamp; + } + } + + if (shouldExitFullscreen) { + // ESC key released while in DOM fullscreen mode. + // Fully exit all browser windows and documents from + // fullscreen mode. + Document::AsyncExitFullscreen(nullptr); + } } } diff --git a/layout/base/PresShell.h b/layout/base/PresShell.h index 1f710a5897b6..97ef601287d0 100644 --- a/layout/base/PresShell.h +++ b/layout/base/PresShell.h @@ -3221,6 +3221,10 @@ class PresShell final : public nsStubDocumentObserver, bool mProcessingReflowCommands : 1; bool mPendingDidDoReflow : 1; + // The last TimeStamp when the keyup event did not exit fullscreen because it + // was consumed. + TimeStamp mLastConsumedEscapeKeyUpForFullscreen; + struct CapturingContentInfo final { CapturingContentInfo() : mRemoteTarget(nullptr), diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index 93186cde494d..09b1be36a8c6 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -2703,6 +2703,13 @@ value: false mirror: always +# The interval in milliseconds between two Escape key events where the second +# key event will exit fullscreen, even if it is consumed. +- name: dom.fullscreen.force_exit_on_multiple_escape_interval + type: uint32_t + value: 500 + mirror: always + # Whether the Gamepad API is enabled - name: dom.gamepad.enabled type: bool