webview_fullscreen.patch 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
  2. From: Cheng Zhao <[email protected]>
  3. Date: Thu, 4 Oct 2018 14:57:02 -0700
  4. Subject: fix: also propagate fullscreen state for outer frame
  5. When entering fullscreen with Element.requestFullscreen in child frames,
  6. the parent frame should also enter fullscreen mode too. Chromium handles
  7. this for iframes, but not for webviews as they are essentially main
  8. frames instead of child frames.
  9. This patch makes webviews propagate the fullscreen state to embedder.It also handles a
  10. DCHECK preventing guest webcontents from becoming the focused webContents.
  11. Note that we also need to manually update embedder's
  12. `api::WebContents::IsFullscreenForTabOrPending` value.
  13. diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
  14. index 33088669c478d5b7f6bbaa7998e14479e539c5cc..17a55006539fa252f607755ec5f3e7ed77350c87 100644
  15. --- a/content/browser/renderer_host/render_frame_host_impl.cc
  16. +++ b/content/browser/renderer_host/render_frame_host_impl.cc
  17. @@ -8710,6 +8710,17 @@ void RenderFrameHostImpl::EnterFullscreen(
  18. }
  19. }
  20. + // Entering fullscreen from webview should also notify its outer frame.
  21. + if (frame_tree_node()->render_manager()->IsMainFrameForInnerDelegate()) {
  22. + RenderFrameProxyHost* outer_proxy =
  23. + frame_tree_node()->render_manager()->GetProxyToOuterDelegate();
  24. + DCHECK(outer_proxy);
  25. + if (outer_proxy->is_render_frame_proxy_live()) {
  26. + outer_proxy->GetAssociatedRemoteFrame()->WillEnterFullscreen(
  27. + options.Clone());
  28. + }
  29. + }
  30. +
  31. // Focus the window if another frame may have delegated the capability.
  32. if (had_fullscreen_token && !GetView()->HasFocus())
  33. GetView()->Focus();
  34. diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
  35. index 08024a20a7c0a227cfaffc77c70874d0a01d6029..b3d5c5522ea1afb0a3d3ce076f5e05f34b4ea488 100644
  36. --- a/content/browser/web_contents/web_contents_impl.cc
  37. +++ b/content/browser/web_contents/web_contents_impl.cc
  38. @@ -4099,21 +4099,25 @@ KeyboardEventProcessingResult WebContentsImpl::PreHandleKeyboardEvent(
  39. const input::NativeWebKeyboardEvent& event) {
  40. OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"),
  41. "WebContentsImpl::PreHandleKeyboardEvent");
  42. - auto* outermost_contents = GetOutermostWebContents();
  43. - // TODO(wjmaclean): Generalize this to forward all key events to the outermost
  44. - // delegate's handler.
  45. - if (outermost_contents != this && IsFullscreen() &&
  46. - event.windows_key_code == ui::VKEY_ESCAPE) {
  47. - // When an inner WebContents has focus and is fullscreen, redirect <esc>
  48. - // key events to the outermost WebContents so it can be handled by that
  49. - // WebContents' delegate.
  50. - if (outermost_contents->PreHandleKeyboardEvent(event) ==
  51. - KeyboardEventProcessingResult::HANDLED) {
  52. +
  53. + auto handled = delegate_ ? delegate_->PreHandleKeyboardEvent(this, event)
  54. + : KeyboardEventProcessingResult::NOT_HANDLED;
  55. +
  56. + if (IsFullscreen() && event.windows_key_code == ui::VKEY_ESCAPE) {
  57. + if (handled == KeyboardEventProcessingResult::HANDLED)
  58. return KeyboardEventProcessingResult::HANDLED;
  59. +
  60. + // When an inner WebContents has focus and is fullscreen, traverse through
  61. + // containing webcontents to any that may handle the escape key.
  62. + while (auto* outer_web_contents = GetOuterWebContents()) {
  63. + auto result = outer_web_contents->PreHandleKeyboardEvent(event);
  64. + if (result == KeyboardEventProcessingResult::HANDLED) {
  65. + return KeyboardEventProcessingResult::HANDLED;
  66. + }
  67. }
  68. }
  69. - return delegate_ ? delegate_->PreHandleKeyboardEvent(this, event)
  70. - : KeyboardEventProcessingResult::NOT_HANDLED;
  71. +
  72. + return handled;
  73. }
  74. bool WebContentsImpl::HandleMouseEvent(const blink::WebMouseEvent& event) {
  75. @@ -4272,7 +4276,7 @@ void WebContentsImpl::EnterFullscreenMode(
  76. OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::EnterFullscreenMode");
  77. DCHECK(CanEnterFullscreenMode(requesting_frame));
  78. DCHECK(requesting_frame->IsActive());
  79. - DCHECK(ContainsOrIsFocusedWebContents());
  80. + DCHECK(ContainsOrIsFocusedWebContents() || IsGuest());
  81. if (base::FeatureList::IsEnabled(
  82. features::kAutomaticFullscreenContentSetting)) {
  83. // Ensure the window is made active to take input focus. The user may have
  84. diff --git a/third_party/blink/renderer/core/fullscreen/fullscreen.cc b/third_party/blink/renderer/core/fullscreen/fullscreen.cc
  85. index ff00c91543259b5361a068e1b3cc409bea8a6db2..e27e8af9dfb9160167087d057f5bb0d49c287270 100644
  86. --- a/third_party/blink/renderer/core/fullscreen/fullscreen.cc
  87. +++ b/third_party/blink/renderer/core/fullscreen/fullscreen.cc
  88. @@ -110,7 +110,7 @@ void FullscreenElementChanged(Document& document,
  89. // is the iframe element for the out-of-process frame that contains the
  90. // fullscreen element. Hence, it must match :-webkit-full-screen-ancestor.
  91. if (new_request_type & FullscreenRequestType::kForCrossProcessDescendant) {
  92. - DCHECK(IsA<HTMLIFrameElement>(new_element));
  93. + // DCHECK(IsA<HTMLIFrameElement>(new_element));
  94. new_element->SetContainsFullScreenElement(true);
  95. }
  96. new_element->SetContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(