From d42a94dddeb86d349c050c2ee59b135bd6c8245c Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Fri, 25 Aug 2023 20:11:58 +0200 Subject: [PATCH] fix: webview exiting fullscreen presentation mode (#39616) --- patches/chromium/.patches | 1 - ...uest_webcontents_to_enter_fullscreen.patch | 20 ------ ...board_hides_on_input_blur_in_webview.patch | 4 +- patches/chromium/webview_fullscreen.patch | 67 ++++++++++++++++++- 4 files changed, 68 insertions(+), 24 deletions(-) delete mode 100644 patches/chromium/fix_allow_guest_webcontents_to_enter_fullscreen.patch diff --git a/patches/chromium/.patches b/patches/chromium/.patches index 74222f67cf1e..f4fd471526b5 100644 --- a/patches/chromium/.patches +++ b/patches/chromium/.patches @@ -98,7 +98,6 @@ make_gtk_getlibgtk_public.patch build_disable_print_content_analysis.patch custom_protocols_plzserviceworker.patch feat_filter_out_non-shareable_windows_in_the_current_application_in.patch -fix_allow_guest_webcontents_to_enter_fullscreen.patch disable_freezing_flags_after_init_in_node.patch short-circuit_permissions_checks_in_mediastreamdevicescontroller.patch chore_add_electron_deps_to_gitignores.patch diff --git a/patches/chromium/fix_allow_guest_webcontents_to_enter_fullscreen.patch b/patches/chromium/fix_allow_guest_webcontents_to_enter_fullscreen.patch deleted file mode 100644 index b8d1d532f01e..000000000000 --- a/patches/chromium/fix_allow_guest_webcontents_to_enter_fullscreen.patch +++ /dev/null @@ -1,20 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Samuel Attard -Date: Mon, 6 Jun 2022 14:25:15 -0700 -Subject: fix: allow guest webcontents to enter fullscreen - -This can be upstreamed, a guest webcontents can't technically become the focused webContents. This DCHECK should allow all guest webContents to request fullscreen entrance. - -diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc -index 8d5a0e6aa6ea3a0965ed6abb76368d1f8e3ea91e..36cd52f18c83adc007d6f896a4136a93f0fa1c83 100644 ---- a/content/browser/web_contents/web_contents_impl.cc -+++ b/content/browser/web_contents/web_contents_impl.cc -@@ -3715,7 +3715,7 @@ void WebContentsImpl::EnterFullscreenMode( - OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::EnterFullscreenMode"); - DCHECK(CanEnterFullscreenMode(requesting_frame, options)); - DCHECK(requesting_frame->IsActive()); -- DCHECK(ContainsOrIsFocusedWebContents()); -+ DCHECK(ContainsOrIsFocusedWebContents() || IsGuest()); - - // When WebView is the `delegate_` we can end up with VisualProperties changes - // synchronously. Notify the view ahead so it can handle the transition. diff --git a/patches/chromium/fix_on-screen-keyboard_hides_on_input_blur_in_webview.patch b/patches/chromium/fix_on-screen-keyboard_hides_on_input_blur_in_webview.patch index 50865be8220d..5b87c9786df7 100644 --- a/patches/chromium/fix_on-screen-keyboard_hides_on_input_blur_in_webview.patch +++ b/patches/chromium/fix_on-screen-keyboard_hides_on_input_blur_in_webview.patch @@ -45,10 +45,10 @@ index 1e9dcbb9f0a5e401a50d63be490755bc3eeaa1a3..1e2e0a321df6fe9dea4401ed327c9373 // RenderFrameMetadataProvider::Observer implementation. void OnRenderFrameMetadataChangedBeforeActivation( diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc -index 36cd52f18c83adc007d6f896a4136a93f0fa1c83..99f6e45fe48449c2dbe88514648a4d907999e282 100644 +index 61d985829d54e2f98351f39d1b58e5702f10fa79..6ee703fc50459901068c364a3a0ccd3a60ce28bb 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc -@@ -8319,7 +8319,7 @@ void WebContentsImpl::OnFocusedElementChangedInFrame( +@@ -8323,7 +8323,7 @@ void WebContentsImpl::OnFocusedElementChangedInFrame( "WebContentsImpl::OnFocusedElementChangedInFrame", "render_frame_host", frame); RenderWidgetHostViewBase* root_view = diff --git a/patches/chromium/webview_fullscreen.patch b/patches/chromium/webview_fullscreen.patch index e6b29891ec74..0803c94e747b 100644 --- a/patches/chromium/webview_fullscreen.patch +++ b/patches/chromium/webview_fullscreen.patch @@ -8,7 +8,8 @@ the parent frame should also enter fullscreen mode too. Chromium handles this for iframes, but not for webviews as they are essentially main frames instead of child frames. -This patch makes webviews propagate the fullscreen state to embedder. +This patch makes webviews propagate the fullscreen state to embedder.It also handles a +DCHECK preventing guest webcontents from becoming the focused webContents. Note that we also need to manually update embedder's `api::WebContents::IsFullscreenForTabOrPending` value. @@ -35,3 +36,67 @@ index 01eb116b51037bff5da7a87d119b78387f5e72c6..7ab5609215ce352b2595b4953e1b9ca0 // Focus the window if another frame may have delegated the capability. if (had_fullscreen_token && !GetView()->HasFocus()) GetView()->Focus(); +diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc +index 8d5a0e6aa6ea3a0965ed6abb76368d1f8e3ea91e..61d985829d54e2f98351f39d1b58e5702f10fa79 100644 +--- a/content/browser/web_contents/web_contents_impl.cc ++++ b/content/browser/web_contents/web_contents_impl.cc +@@ -3569,21 +3569,25 @@ KeyboardEventProcessingResult WebContentsImpl::PreHandleKeyboardEvent( + const NativeWebKeyboardEvent& event) { + OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"), + "WebContentsImpl::PreHandleKeyboardEvent"); +- auto* outermost_contents = GetOutermostWebContents(); +- // TODO(wjmaclean): Generalize this to forward all key events to the outermost +- // delegate's handler. +- if (outermost_contents != this && IsFullscreen() && +- event.windows_key_code == ui::VKEY_ESCAPE) { +- // When an inner WebContents has focus and is fullscreen, redirect +- // key events to the outermost WebContents so it can be handled by that +- // WebContents' delegate. +- if (outermost_contents->PreHandleKeyboardEvent(event) == +- KeyboardEventProcessingResult::HANDLED) { ++ ++ auto handled = delegate_ ? delegate_->PreHandleKeyboardEvent(this, event) ++ : KeyboardEventProcessingResult::NOT_HANDLED; ++ ++ if (IsFullscreen() && event.windows_key_code == ui::VKEY_ESCAPE) { ++ if (handled == KeyboardEventProcessingResult::HANDLED) + return KeyboardEventProcessingResult::HANDLED; ++ ++ // When an inner WebContents has focus and is fullscreen, traverse through ++ // containing webcontents to any that may handle the escape key. ++ while (auto* outer_web_contents = GetOuterWebContents()) { ++ auto result = outer_web_contents->PreHandleKeyboardEvent(event); ++ if (result == KeyboardEventProcessingResult::HANDLED) { ++ return KeyboardEventProcessingResult::HANDLED; ++ } + } + } +- return delegate_ ? delegate_->PreHandleKeyboardEvent(this, event) +- : KeyboardEventProcessingResult::NOT_HANDLED; ++ ++ return handled; + } + + bool WebContentsImpl::HandleMouseEvent(const blink::WebMouseEvent& event) { +@@ -3715,7 +3719,7 @@ void WebContentsImpl::EnterFullscreenMode( + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::EnterFullscreenMode"); + DCHECK(CanEnterFullscreenMode(requesting_frame, options)); + DCHECK(requesting_frame->IsActive()); +- DCHECK(ContainsOrIsFocusedWebContents()); ++ DCHECK(ContainsOrIsFocusedWebContents() || IsGuest()); + + // When WebView is the `delegate_` we can end up with VisualProperties changes + // synchronously. Notify the view ahead so it can handle the transition. +diff --git a/third_party/blink/renderer/core/fullscreen/fullscreen.cc b/third_party/blink/renderer/core/fullscreen/fullscreen.cc +index f58ade7ed652ea0d97c123dc78715c049cb5e500..6619207f2f8731a7d8e88d6c1613e77ca4abc558 100644 +--- a/third_party/blink/renderer/core/fullscreen/fullscreen.cc ++++ b/third_party/blink/renderer/core/fullscreen/fullscreen.cc +@@ -99,7 +99,7 @@ void FullscreenElementChanged(Document& document, + // is the iframe element for the out-of-process frame that contains the + // fullscreen element. Hence, it must match :-webkit-full-screen-ancestor. + if (new_request_type & FullscreenRequestType::kForCrossProcessDescendant) { +- DCHECK(IsA(new_element)); ++ // DCHECK(IsA(new_element)); + new_element->SetContainsFullScreenElement(true); + } + new_element->SetContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(