[M108 Migration][Viewport] Refactors orientation change and sets custom viewport... 53/287953/5
authorv-saha <v.saha@samsung.com>
Wed, 8 Feb 2023 18:47:27 +0000 (00:17 +0530)
committerDae-Hyun Ko <dhyuna.ko@samsung.com>
Sat, 11 Feb 2023 03:23:22 +0000 (03:23 +0000)
Due to additional resize code called during orientation change,
orientation callback was called too early (when screen
dimensions were not set yet).

Even though resize callback was called again from
RenderWidgetHostImpl::WasResized() when all data was set,
orientation events were not dispatched again (due to the fact,
that orientation was changed during first, early call) and
wrong values of screen dimensions were set as final values.

Chromium-efl consists of Evas_Object widgets which appear on top of
webview resulting in overlapping the web page content, for example,
1) virtual keyboard,
2) popup menu picker.

As for 1), EFL allows auto-resizing the window on vk show/hide by using
elm_conformant widget. Because it does not work for TIZEN 3.0 [1]
Browser app manually resizes webview on vk appearance [2].

As for 2), chromium-efl fully implements select picker internally and
app is not aware of it.

This patch overrides GetVisibleViewportSize() and returns smaller
viewport while showing select picker. According to the comment from [3]
this method allows us to define smaller viewport if a portion of the
view is obstructed.

GetVisibleViewportSize() is always called on any size update and result
in sending a new size to the Renderer.

To make <select> element visible, this patch implements:
EWebView::ScrollFocusedNodeIntoView because
RenderWidgetHostViewEfl::ScrollFocusedEditableNode scrolls webview for
editable elements only.

This change fixes WCS TC 195.

Additionally, refactor picker code in EWebView class:
1. Rename ShowPopupMenu -> HandlePopupMenu
   it does not only show picker but also changes viewport.
2. PopupMenuClose and HidePopupMenu return void.
3. PopupMenuClose calls ReleasePopupMenuList as it was already exposed.
4. Get rid of CloseSelectPicker and IsSelectPickerShown as they are
   no longer used.

[1] TSAM-537
[2] virtual gfx::Size GetVisibleViewportSize() const = 0
    src/content/public/browser/render_widget_host_view.h

Reference: https://review.tizen.org/gerrit/278914

Change-Id: I2fc82ebe04d42d6a2ab21b1bb29d04f5037d4306
Signed-off-by: v-saha <v.saha@samsung.com>
16 files changed:
content/browser/web_contents/web_contents_view_aura.cc
content/common/features.gni
content/test/test_page_broadcast.cc
content/test/test_page_broadcast.h
third_party/blink/public/mojom/page/page.mojom
third_party/blink/renderer/core/exported/web_view_impl.cc
third_party/blink/renderer/core/exported/web_view_impl.h
tizen_src/chromium_impl/content/public/browser/web_contents_efl_delegate.h
tizen_src/ewk/efl_integration/browser/selectpicker/popup_menu_item.cc
tizen_src/ewk/efl_integration/browser/selectpicker/popup_menu_item_private.h
tizen_src/ewk/efl_integration/browser/selectpicker/popup_picker.cc
tizen_src/ewk/efl_integration/browser/selectpicker/popup_picker.h
tizen_src/ewk/efl_integration/eweb_view.cc
tizen_src/ewk/efl_integration/eweb_view.h
tizen_src/ewk/efl_integration/web_contents_efl_delegate_ewk.cc
tizen_src/ewk/efl_integration/web_contents_efl_delegate_ewk.h

index 1662f20..fb2b9db 100644 (file)
@@ -1862,7 +1862,16 @@ void WebContentsViewAura::ShowPopupMenu(
     std::vector<blink::mojom::MenuItemPtr> menu_items,
     bool right_aligned,
     bool allow_multiple_selection) {
+#if BUILDFLAG(IS_EFL)
+  if (wcva_helper()) {
+    wcva_helper()->ShowPopupMenu(
+        render_frame_host, std::move(popup_client), bounds, item_height,
+        item_font_size, selected_item, std::move(menu_items), right_aligned,
+        allow_multiple_selection);
+  }
+#else
   NOTIMPLEMENTED() << " show " << menu_items.size() << " menu items";
+#endif
 }
 #endif
 
index 917bae4..cc8c393 100644 (file)
@@ -6,7 +6,7 @@ import("//build/config/chromecast_build.gni")
 
 declare_args() {
   # Whether or not to use external popup menu.
-  use_external_popup_menu = is_android || is_mac
+  use_external_popup_menu = is_android || is_mac || use_efl
 
   # Whether to perform critical memory pressure handling when in foreground (if
   # false, critical memory pressure is treated like moderate pressure in foreground).
index a27492e..41c3473 100644 (file)
@@ -45,6 +45,10 @@ void TestPageBroadcast::UpdateRendererPreferences(
 void TestPageBroadcast::SetHistoryOffsetAndLength(int32_t history_offset,
                                                   int32_t history_length) {}
 
+#if BUILDFLAG(IS_EFL)
+void TestPageBroadcast::ScrollFocusedNodeIntoView() {}
+#endif
+
 void TestPageBroadcast::SetPageBaseBackgroundColor(
     absl::optional<SkColor> color) {}
 
index cf085f5..15977c3 100644 (file)
@@ -33,6 +33,9 @@ class TestPageBroadcast : public blink::mojom::PageBroadcast {
       const blink::RendererPreferences& preferences) override;
   void SetHistoryOffsetAndLength(int32_t history_offset,
                                  int32_t history_length) override;
+#if BUILDFLAG(IS_EFL)
+  void ScrollFocusedNodeIntoView() override;
+#endif
   void SetPageBaseBackgroundColor(absl::optional<SkColor> color) override;
   void CreateRemoteMainFrame(
       const blink::RemoteFrameToken& token,
index 0cfe109..07f3ff8 100644 (file)
@@ -104,6 +104,9 @@ interface PageBroadcast {
   // Set history offset and length.
   SetHistoryOffsetAndLength(int32 offset, int32 length);
 
+  [EnableIf=is_efl]
+  ScrollFocusedNodeIntoView();
+
   // Sent to whole page, but should only be used by the main frame.
   SetPageBaseBackgroundColor(skia.mojom.SkColor? color);
 
index a27515a..79aac67 100644 (file)
@@ -4008,6 +4008,11 @@ void WebViewImpl::SetLongPollingGlobalTimeout(uint64_t timeout) {
     return;
   GetPage()->SetLongPollingGlobalTimeout(timeout);
 }
+
+void WebViewImpl::ScrollFocusedNodeIntoView() {
+  if (Element* element = FocusedElement())
+    element->scrollIntoViewIfNeeded(true /*centerIfNeeded*/);
+}
 #endif
 
 }  // namespace blink
index 9e84b09..8ec6677 100644 (file)
@@ -226,6 +226,7 @@ class CORE_EXPORT WebViewImpl final : public WebView,
   bool PaintSoftBitmap(SkCanvas*, const gfx::Rect&) override;
   bool HasAcceleratedCanvasWithinViewport() const override;
   void SetLongPollingGlobalTimeout(uint64_t timeout) override;
+  void ScrollFocusedNodeIntoView() override;
 #endif
 
   // Functions to add and remove observers for this object.
index dcbe9d2..179a0e8 100644 (file)
@@ -15,6 +15,7 @@
 #include "third_party/blink/public/common/context_menu_data/menu_item_info.h"
 #include "third_party/blink/public/common/input/web_gesture_event.h"
 #include "third_party/blink/public/common/input/web_input_event.h"
+#include "third_party/blink/public/mojom/choosers/popup_menu.mojom.h"
 #include "ui/base/ime/text_input_type.h"
 #include "ui/gfx/geometry/rect.h"
 
@@ -55,7 +56,7 @@ class CONTENT_EXPORT WebContentsEflDelegate {
                              int item_height,
                              double item_font_size,
                              int selected_item,
-                             const std::vector<blink::MenuItemInfo>& items,
+                             std::vector<blink::mojom::MenuItemPtr> items,
                              bool right_aligned,
                              bool allow_multiple_selection) = 0;
   virtual void HidePopupMenu() = 0;
index 1579569..376b9bf 100644 (file)
@@ -7,16 +7,17 @@
 #include "popup_menu_item_private.h"
 #include "base/logging.h"
 
-Popup_Menu_Item::Popup_Menu_Item(const blink::MenuItemInfo& item)
-    : type(static_cast<Popup_Menu_Item_Type>(item.type)),
-      textDirection(item.text_direction),
-      hasTextDirectionOverride(item.has_text_direction_override),
-      isEnabled(item.enabled),
+Popup_Menu_Item::Popup_Menu_Item(blink::mojom::MenuItemPtr item)
+    : type(static_cast<Popup_Menu_Item_Type>(item->type)),
+      textDirection(item->text_direction ? base::i18n::RIGHT_TO_LEFT
+                                         : base::i18n::LEFT_TO_RIGHT),
+      hasTextDirectionOverride(item->has_text_direction_override),
+      isEnabled(item->enabled),
       isLabel(true),
-      isSelected(item.checked),
-      text(base::UTF16ToUTF8(item.label)),
-      toolTip(base::UTF16ToUTF8(item.tool_tip)),
-      accessibilityText(base::UTF16ToUTF8(item.label)) {}
+      isSelected(item->checked),
+      text(item->label.value()),
+      toolTip(item->tool_tip.value()),
+      accessibilityText(item->label.value()) {}
 
 Popup_Menu_Item_Type popup_menu_item_type_get(const Popup_Menu_Item* item) {
   EINA_SAFETY_ON_NULL_RETURN_VAL(item, POPUP_MENU_UNKNOWN);
index dcd4bc6..aba52b1 100644 (file)
@@ -7,7 +7,7 @@
 
 #include "base/i18n/rtl.h"
 #include "popup_menu_item.h"
-#include "third_party/blink/public/common/context_menu_data/menu_item_info.h"
+#include "third_party/blink/public/mojom/choosers/popup_menu.mojom.h"
 
 #include <string>
 
@@ -17,7 +17,7 @@
  */
 class Popup_Menu_Item {
 public:
- explicit Popup_Menu_Item(const blink::MenuItemInfo& menuitem);
+ explicit Popup_Menu_Item(blink::mojom::MenuItemPtr menuitem);
 
  Popup_Menu_Item_Type type;
  base::i18n::TextDirection textDirection;
index b48fcd2..90c0b96 100644 (file)
@@ -3,16 +3,18 @@
 // found in the LICENSE file.
 
 #include "popup_picker.h"
-#include "popup_menu_item.h"
 
-// DJKim : FIXME
-//#include "WebPopupMenuProxyEfl.h"
-#include "eweb_view.h"
-#include "base/path_service.h"
+#include <ecore_x_wayland_wrapper.h>
+
 #include "base/files/file_path.h"
+#include "base/logging.h"
+#include "base/path_service.h"
 #include "common/web_contents_utils.h"
 #include "content/common/paths_efl.h"
-#include "base/logging.h"
+#include "eweb_view.h"
+#include "popup_menu_item.h"
+#include "ui/display/screen.h"
+#include "ui/gfx/geometry/dip_util.h"
 
 #include <Elementary.h>
 #include <libintl.h>
@@ -20,6 +22,7 @@
 #if BUILDFLAG(IS_TIZEN)
 #include <dlfcn.h>
 #include <efl_extension.h>
+
 extern void* EflExtensionHandle;
 #endif
 
@@ -404,6 +407,30 @@ void popup_picker_del(Popup_Picker* picker) {
   delete picker;
 }
 
+void popup_picker_geometry_get(Popup_Picker* picker,
+                               int* x,
+                               int* y,
+                               int* width,
+                               int* height) {
+  int p_x, p_y, p_width, p_height;
+  p_x = p_y = p_width = p_height = 0;
+  edje_object_part_geometry_get(elm_layout_edje_get(picker->container), "bg",
+                                &p_x, &p_y, &p_width, &p_height);
+
+  gfx::Rect scaled_rect = gfx::ToEnclosingRect(gfx::ConvertRectToDips(
+      gfx::Rect(p_x, p_y, p_width, p_height),
+      display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor()));
+
+  if (x)
+    *x = scaled_rect.x();
+  if (y)
+    *y = scaled_rect.y();
+  if (width)
+    *width = scaled_rect.width();
+  if (height)
+    *height = scaled_rect.height();
+}
+
 void popup_picker_update(Evas_Object* parent, Popup_Picker* picker, Eina_List* items, int selectedIndex) {
   // FIXME: A check should be made if the items are changed instead of directly changing them.
   // Another issue is that if the list is scrolled, the old scroll position is not retained as
index 8d5e69a..028954e 100644 (file)
@@ -52,6 +52,11 @@ Popup_Picker* popup_picker_new(EWebView* web_view, Evas_Object* parent, Eina_Lis
 void popup_picker_resize(Popup_Picker* picker);
 void popup_picker_resize(Popup_Picker* picker, int width, int height);
 void popup_picker_del(Popup_Picker* picker);
+void popup_picker_geometry_get(Popup_Picker* picker,
+                               int* x,
+                               int* y,
+                               int* width,
+                               int* height);
 void popup_picker_update(Evas_Object* parent, Popup_Picker* picker, Eina_List* items, int selectedIndex);
 void popupPickerKeyUpCallback(void* data, Evas* e, Evas_Object* obj, void* event_info);
 void listClosed(void *data, Evas_Object *obj, const char *emission, const char *source);
index a52450d..3717f26 100644 (file)
@@ -1074,9 +1074,9 @@ void EWebView::InvokeLoadError(const GURL& url,
   SmartCallback<EWebViewCallbacks::LoadError>().call(&err);
 }
 
-void EWebView::ShowPopupMenu(const std::vector<blink::MenuItemInfo>& items,
-                             int selectedIndex,
-                             bool multiple) {
+void EWebView::HandlePopupMenu(std::vector<blink::mojom::MenuItemPtr> items,
+                               int selectedIndex,
+                               bool multiple) {
   // Request form navigation information as early as possible,
   // given that is renderer will ping-back with actual requested data.
   RenderFrameHostImpl* render_frame_host =
@@ -1088,7 +1088,8 @@ void EWebView::ShowPopupMenu(const std::vector<blink::MenuItemInfo>& items,
   Eina_List* popupItems = 0;
   const size_t size = items.size();
   for (size_t i = 0; i < size; ++i) {
-    popupItems = eina_list_append(popupItems, new Popup_Menu_Item(items[i]));
+    popupItems =
+        eina_list_append(popupItems, new Popup_Menu_Item(std::move(items[i])));
   }
 
   ReleasePopupMenuList();
@@ -1114,18 +1115,23 @@ void EWebView::ShowPopupMenu(const std::vector<blink::MenuItemInfo>& items,
 
   popup_picker_buttons_update(popupPicker_, formNavigation_.position,
                               formNavigation_.count, false);
+
+  // Picker has been shown on top of webview and the page content gets
+  // partially overlapped. Decrease viewport while showing picker.
+  AdjustViewPortHeightToPopupMenu(true /* is_popup_menu_visible */);
+  ScrollFocusedNodeIntoView();
 }
 
-Eina_Bool EWebView::HidePopupMenu() {
+void EWebView::HidePopupMenu() {
   if (!popupPicker_)
-    return false;
+    return;
 
   if (FormIsNavigating())
-    return true;
+    return;
 
+  AdjustViewPortHeightToPopupMenu(false /* is_popup_menu_visible */);
   popup_picker_del(popupPicker_);
   popupPicker_ = 0;
-  return true;
 }
 
 void EWebView::UpdateFormNavigation(int formElementCount,
@@ -1138,14 +1144,6 @@ void EWebView::UpdateFormNavigation(int formElementCount,
   formNavigation_.nextState = nextState;
 }
 
-bool EWebView::IsSelectPickerShown() const {
-  return (popupPicker_ != NULL);
-}
-
-void EWebView::CloseSelectPicker() {
-  listClosed(popupPicker_, 0, 0, 0);
-}
-
 void EWebView::SetFormIsNavigating(bool formIsNavigating) {
   formIsNavigating_ = formIsNavigating;
 }
@@ -1223,32 +1221,10 @@ Eina_Bool EWebView::DidMultipleSelectPopupMenuItem(
   return true;
 }
 
-Eina_Bool EWebView::PopupMenuClose() {
-// DJKim : FIXME
-#if 0
-  if (!impl->popupMenuProxy)
-    return false;
-
-  impl->popupMenuProxy = 0;
-#endif
+void EWebView::PopupMenuClose() {
   HidePopupMenu();
-
-  if (!popupMenuItems_)
-    return false;
-
-  void* item;
-  EINA_LIST_FREE(popupMenuItems_, item)
-  delete static_cast<Popup_Menu_Item*>(item);
-  popupMenuItems_ = 0;
-
-  RenderFrameHostImpl* render_frame_host =
-      static_cast<RenderFrameHostImpl*>(web_contents_->GetPrimaryMainFrame());
-  if (!render_frame_host)
-    return false;
-#if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
-  render_frame_host->DidCancelPopupMenu();
-#endif
-  return true;
+  ReleasePopupMenuList();
+  wcva()->wcva_helper()->DidCancelPopupMenu();
 }
 
 void EWebView::HandleLongPressGesture(
@@ -1343,6 +1319,30 @@ void EWebView::SetScale(double scale_factor) {
       scale_factor);
 }
 
+void EWebView::ScrollFocusedNodeIntoView() {
+  if (RenderViewHost* render_view_host = web_contents_->GetRenderViewHost()) {
+    if (auto& broadcast = static_cast<RenderViewHostImpl*>(render_view_host)
+                              ->GetAssociatedPageBroadcast())
+      broadcast->ScrollFocusedNodeIntoView();
+  }
+}
+
+void EWebView::AdjustViewPortHeightToPopupMenu(bool is_popup_menu_visible) {
+  DCHECK(popupPicker_);
+
+  int picker_height = 0;
+  popup_picker_geometry_get(popupPicker_, 0, 0, 0, &picker_height);
+
+  gfx::Rect rect = rwhva()->offscreen_helper()->GetViewBounds();
+  // FIXME(g.czajkowski): detect the need of resizing viewport.
+  // Checking the position of focused <select> element and do resize only when
+  // the picker overlaps the element will prevent Blink from doing re-layout.
+  // Bug: http://107.108.218.239/bugzilla/show_bug.cgi?id=15488.
+  rwhva()->offscreen_helper()->SetCustomViewportSize(gfx::Size(
+      rect.width(), is_popup_menu_visible ? rect.height() - picker_height
+                                          : rect.height() + picker_height));
+}
+
 bool EWebView::GetScrollPosition(int* x, int* y) const {
   if (!rwhva()) {
     LOG(ERROR) << "rwhva() returns nullptr";
index 08e0c68..704ac99 100755 (executable)
@@ -25,6 +25,8 @@
 #include "content/browser/date_time_chooser_efl.h"
 #include "content/browser/renderer_host/event_with_latency_info.h"
 #include "content/browser/selection/selection_controller_efl.h"
+#include "content/browser/web_contents/web_contents_view_aura.h"
+#include "content/browser/web_contents/web_contents_view_aura_helper_efl.h"
 #include "content/public/browser/context_menu_params.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/quota_permission_context.h"
@@ -50,6 +52,7 @@
 #include "scroll_detector.h"
 #include "third_party/blink/public/common/context_menu_data/menu_item_info.h"
 #include "third_party/blink/public/mojom/choosers/file_chooser.mojom.h"
+#include "third_party/blink/public/mojom/choosers/popup_menu.mojom.h"
 #include "ui/aura/window_tree_host.h"
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/geometry/size.h"
@@ -330,23 +333,21 @@ class EWebView {
   void Find(const char* text, Ewk_Find_Options);
   void InvokeAuthCallbackOnUI(_Ewk_Auth_Challenge* auth_challenge);
   void SetContentSecurityPolicy(const char* policy, Ewk_CSP_Header_Type type);
-  void ShowPopupMenu(const std::vector<blink::MenuItemInfo>& items,
-                     int selectedIndex,
-                     bool multiple);
-  Eina_Bool HidePopupMenu();
+  void HandlePopupMenu(std::vector<blink::mojom::MenuItemPtr> items,
+                       int selectedIndex,
+                       bool multiple);
+  void HidePopupMenu();
   void UpdateFormNavigation(int formElementCount,
                             int currentNodeIndex,
                             bool prevState,
                             bool nextState);
   void FormNavigate(bool direction);
-  bool IsSelectPickerShown() const;
-  void CloseSelectPicker();
   bool FormIsNavigating() const { return formIsNavigating_; }
   void SetFormIsNavigating(bool formIsNavigating);
   Eina_Bool PopupMenuUpdate(Eina_List* items, int selectedIndex);
   Eina_Bool DidSelectPopupMenuItem(int selectedIndex);
   Eina_Bool DidMultipleSelectPopupMenuItem(std::vector<int>& selectedIndices);
-  Eina_Bool PopupMenuClose();
+  void PopupMenuClose();
   void HandleLongPressGesture(const content::ContextMenuParams&);
   void ShowContextMenu(const content::ContextMenuParams&);
   void CancelContextMenu(int request_id);
@@ -619,12 +620,17 @@ class EWebView {
   JavaScriptDialogManagerEfl* GetJavaScriptDialogManagerEfl();
 
   void ReleasePopupMenuList();
+  // Changes viewport without resizing Evas_Object representing webview
+  // and its corresponding RWHV to let Blink renders custom viewport
+  // while showing picker.
+  void AdjustViewPortHeightToPopupMenu(bool is_popup_menu_visible);
 
   void ShowContextMenuInternal(const content::ContextMenuParams&);
 
   void UpdateWebkitPreferencesEfl(content::RenderViewHost*);
 
   void ChangeScroll(int& x, int& y);
+  void ScrollFocusedNodeIntoView();
 
   void GenerateMHTML(Ewk_View_Save_Page_Callback callback,
                      void* user_data,
index 31e1496..f7080df 100644 (file)
@@ -30,10 +30,11 @@ void WebContentsEflDelegateEwk::ShowPopupMenu(
     int item_height,
     double item_font_size,
     int selected_item,
-    const std::vector<blink::MenuItemInfo>& items,
+    std::vector<blink::mojom::MenuItemPtr> items,
     bool right_aligned,
     bool allow_multiple_selection) {
-  web_view_->ShowPopupMenu(items, selected_item, allow_multiple_selection);
+  web_view_->HandlePopupMenu(std::move(items), selected_item,
+                             allow_multiple_selection);
 }
 
 void WebContentsEflDelegateEwk::HidePopupMenu() {
@@ -96,4 +97,4 @@ void WebContentsEflDelegateEwk::OpenDateTimeDialog(
     double dialog_value,
     content::DateTimeChooserEfl* date_time_chooser) {
   web_view_->InputPickerShow(dialog_type, dialog_value, date_time_chooser);
-}
\ No newline at end of file
+}
index 38f8222..16221fd 100644 (file)
@@ -6,6 +6,7 @@
 #define CONTENT_PUBLIC_BROWSER_WEB_CONTENTS_EFL_DELEGATE_EWK_H_
 
 #include "content/public/browser/web_contents_efl_delegate.h"
+#include "third_party/blink/public/mojom/choosers/popup_menu.mojom.h"
 
 class EWebView;
 
@@ -26,7 +27,7 @@ class WebContentsEflDelegateEwk : public content::WebContentsEflDelegate {
                      int item_height,
                      double item_font_size,
                      int selected_item,
-                     const std::vector<blink::MenuItemInfo>& items,
+                     std::vector<blink::mojom::MenuItemPtr> items,
                      bool right_aligned,
                      bool allow_multiple_selection) override;
   void HidePopupMenu() override;