From b34eeebe60ed1c69702621faf21cb4a61f0d6d7c Mon Sep 17 00:00:00 2001 From: v-saha Date: Mon, 13 Feb 2023 23:14:37 +0530 Subject: [PATCH] [M108 Migration][Text Selection] Selection handles & Caret Selection On longpress handles are to be displayed, migrate the handler and caret related patches. Expose WebNode::is_text_node in ContextMenuParameters, add is_caret_mode_forced_ to selection controller. References: https://review.tizen.org/gerrit/281232 Change-Id: I8450c9c91745f7000a9b1395ff6999aca878ba05 Signed-off-by: v-saha --- .../context_menu_data/context_menu_mojom_traits.cc | 3 + .../context_menu_params_builder.cc | 3 + .../untrustworthy_context_menu_params.cc | 3 + .../common/context_menu_data/context_menu_data.h | 7 + .../context_menu_data/context_menu_mojom_traits.h | 6 + .../untrustworthy_context_menu_params.h | 5 + .../public/mojom/context_menu/context_menu.mojom | 4 + .../renderer/core/page/context_menu_controller.cc | 4 + tizen_src/chromium_impl/content/BUILD.gn | 2 + .../rwhv_aura_offscreen_helper_efl.cc | 44 ++++ .../renderer_host/rwhv_aura_offscreen_helper_efl.h | 4 + .../content/browser/selection/selection_box_efl.cc | 34 +-- .../content/browser/selection/selection_box_efl.h | 9 +- .../browser/selection/selection_controller_efl.cc | 229 +++++++++++++-------- .../browser/selection/selection_controller_efl.h | 61 ++++-- .../browser/selection/selection_handle_efl.cc | 168 ++++++++------- .../browser/selection/selection_handle_efl.h | 16 +- .../browser/selection/selection_magnifier_efl.cc | 79 ++++--- .../browser/selection/selection_magnifier_efl.h | 6 +- .../chromium_impl/edje_resources/MainLayout.edc | 26 +++ .../browser/autofill_popup_view_efl.cc | 23 ++- .../browser/autofill_popup_view_efl.h | 4 + .../efl_integration/context_menu_controller_efl.cc | 51 +++-- tizen_src/ewk/efl_integration/eweb_view.cc | 44 ++-- tizen_src/ewk/efl_integration/eweb_view.h | 3 + 25 files changed, 552 insertions(+), 286 deletions(-) diff --git a/third_party/blink/common/context_menu_data/context_menu_mojom_traits.cc b/third_party/blink/common/context_menu_data/context_menu_mojom_traits.cc index 67e46bd..a26b986 100644 --- a/third_party/blink/common/context_menu_data/context_menu_mojom_traits.cc +++ b/third_party/blink/common/context_menu_data/context_menu_mojom_traits.cc @@ -59,6 +59,9 @@ bool StructTraitsmedia_flags = data.media_flags(); out->spellcheck_enabled = data.spellcheck_enabled(); out->is_editable = data.is_editable(); +#if BUILDFLAG(IS_EFL) + out->is_text_node = data.is_text_node(); +#endif out->writing_direction_default = data.writing_direction_default(); out->writing_direction_left_to_right = data.writing_direction_left_to_right(); out->writing_direction_right_to_left = data.writing_direction_right_to_left(); diff --git a/third_party/blink/common/context_menu_data/context_menu_params_builder.cc b/third_party/blink/common/context_menu_data/context_menu_params_builder.cc index 9c364c0..e257944 100644 --- a/third_party/blink/common/context_menu_data/context_menu_params_builder.cc +++ b/third_party/blink/common/context_menu_data/context_menu_params_builder.cc @@ -55,6 +55,9 @@ UntrustworthyContextMenuParams ContextMenuParamsBuilder::Build( params.misspelled_word = data.misspelled_word; params.spellcheck_enabled = data.is_spell_checking_enabled; params.is_editable = data.is_editable; +#if BUILDFLAG(IS_EFL) + params.is_text_node = data.is_text_node; +#endif params.writing_direction_default = data.writing_direction_default; params.writing_direction_left_to_right = data.writing_direction_left_to_right; params.writing_direction_right_to_left = data.writing_direction_right_to_left; diff --git a/third_party/blink/common/context_menu_data/untrustworthy_context_menu_params.cc b/third_party/blink/common/context_menu_data/untrustworthy_context_menu_params.cc index e670762..5ede70a 100644 --- a/third_party/blink/common/context_menu_data/untrustworthy_context_menu_params.cc +++ b/third_party/blink/common/context_menu_data/untrustworthy_context_menu_params.cc @@ -62,6 +62,9 @@ void UntrustworthyContextMenuParams::Assign( dictionary_suggestions = other.dictionary_suggestions; spellcheck_enabled = other.spellcheck_enabled; is_editable = other.is_editable; +#if BUILDFLAG(IS_EFL) + is_text_node = other.is_text_node; +#endif writing_direction_default = other.writing_direction_default; writing_direction_left_to_right = other.writing_direction_left_to_right; writing_direction_right_to_left = other.writing_direction_right_to_left; diff --git a/third_party/blink/public/common/context_menu_data/context_menu_data.h b/third_party/blink/public/common/context_menu_data/context_menu_data.h index dd207b4..611b3a8 100644 --- a/third_party/blink/public/common/context_menu_data/context_menu_data.h +++ b/third_party/blink/public/common/context_menu_data/context_menu_data.h @@ -117,6 +117,10 @@ struct ContextMenuData { // Whether context is editable. bool is_editable; +#if BUILDFLAG(IS_EFL) + bool is_text_node; +#endif + // If this node is an input field, the type of that field. blink::mojom::ContextMenuDataInputFieldType input_field_type; @@ -171,6 +175,9 @@ struct ContextMenuData { media_flags(kMediaNone), is_spell_checking_enabled(false), is_editable(false), +#if BUILDFLAG(IS_EFL) + is_text_node(false), +#endif writing_direction_default(kCheckableMenuItemDisabled), writing_direction_left_to_right(kCheckableMenuItemEnabled), writing_direction_right_to_left(kCheckableMenuItemEnabled), diff --git a/third_party/blink/public/common/context_menu_data/context_menu_mojom_traits.h b/third_party/blink/public/common/context_menu_data/context_menu_mojom_traits.h index 9e555d1..40c94c4 100644 --- a/third_party/blink/public/common/context_menu_data/context_menu_mojom_traits.h +++ b/third_party/blink/public/common/context_menu_data/context_menu_mojom_traits.h @@ -115,6 +115,12 @@ struct BLINK_COMMON_EXPORT return r.is_editable; } +#if BUILDFLAG(IS_EFL) + static bool is_text_node(const blink::UntrustworthyContextMenuParams& r) { + return r.is_text_node; + } +#endif + static int writing_direction_default( const blink::UntrustworthyContextMenuParams& r) { return r.writing_direction_default; diff --git a/third_party/blink/public/common/context_menu_data/untrustworthy_context_menu_params.h b/third_party/blink/public/common/context_menu_data/untrustworthy_context_menu_params.h index 6f706a3..99a5b3a 100644 --- a/third_party/blink/public/common/context_menu_data/untrustworthy_context_menu_params.h +++ b/third_party/blink/public/common/context_menu_data/untrustworthy_context_menu_params.h @@ -103,6 +103,11 @@ struct BLINK_COMMON_EXPORT UntrustworthyContextMenuParams { // Whether context is editable. bool is_editable; +#if BUILDFLAG(IS_EFL) + // Whether node context menu was invoked on is a text node. + bool is_text_node; +#endif + // Writing direction menu items. int writing_direction_default; int writing_direction_left_to_right; diff --git a/third_party/blink/public/mojom/context_menu/context_menu.mojom b/third_party/blink/public/mojom/context_menu/context_menu.mojom index 1c4d187..0aaa56f 100644 --- a/third_party/blink/public/mojom/context_menu/context_menu.mojom +++ b/third_party/blink/public/mojom/context_menu/context_menu.mojom @@ -167,6 +167,10 @@ struct UntrustworthyContextMenuParams { // Whether context is editable. bool is_editable; + // Whether element is text + [EnableIf=is_efl] + bool is_text_node; + // Writing direction menu items. int32 writing_direction_default; int32 writing_direction_left_to_right; diff --git a/third_party/blink/renderer/core/page/context_menu_controller.cc b/third_party/blink/renderer/core/page/context_menu_controller.cc index 5501389..2d90e7e 100644 --- a/third_party/blink/renderer/core/page/context_menu_controller.cc +++ b/third_party/blink/renderer/core/page/context_menu_controller.cc @@ -686,6 +686,10 @@ bool ContextMenuController::ShowContextMenu(LocalFrame* frame, } } +#if BUILDFLAG(IS_EFL) + data.is_text_node = result.InnerNode()->IsTextNode(); +#endif + if (result.IsContentEditable()) { data.is_editable = true; SpellChecker& spell_checker = selected_frame->GetSpellChecker(); diff --git a/tizen_src/chromium_impl/content/BUILD.gn b/tizen_src/chromium_impl/content/BUILD.gn index 62198de..70ce612 100644 --- a/tizen_src/chromium_impl/content/BUILD.gn +++ b/tizen_src/chromium_impl/content/BUILD.gn @@ -5,6 +5,8 @@ static_library("android_content_detection") { set_sources_assignment_filter([]) sources = [ + "//content/renderer/android/disambiguation_popup_helper.cc", + "//content/renderer/android/disambiguation_popup_helper.h", "//content/renderer/android/renderer_date_time_picker.cc", "//content/renderer/android/renderer_date_time_picker.h", ] diff --git a/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_offscreen_helper_efl.cc b/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_offscreen_helper_efl.cc index aea5901..1e436c2 100644 --- a/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_offscreen_helper_efl.cc +++ b/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_offscreen_helper_efl.cc @@ -549,6 +549,10 @@ void RWHVAuraOffscreenHelperEfl::OnFocusIn(void* data, static_cast(data); thiz->FocusRWHVA(); + if (IsMobileProfile() && thiz->GetSelectionController()) { + thiz->GetSelectionController()->ShowHandleAndContextMenuIfRequired(); + } + if (!thiz->on_focus_in_callback_.is_null()) thiz->on_focus_in_callback_.Run(); } @@ -568,6 +572,10 @@ void RWHVAuraOffscreenHelperEfl::OnFocusOut(void* data, if (focused_window) focused_window->LostFocus(); + if (IsMobileProfile() && thiz->GetSelectionController()) { + thiz->GetSelectionController()->HideHandleAndContextMenu(); + } + if (!thiz->on_focus_out_callback_.is_null()) thiz->on_focus_out_callback_.Run(); } @@ -1053,6 +1061,42 @@ void RWHVAuraOffscreenHelperEfl::TextInputStateChanged( } } +void RWHVAuraOffscreenHelperEfl::MoveCaret(const gfx::Point& point) { + if (auto* delegate = rwhv_aura_->host()->delegate()) { + delegate->MoveCaret(gfx::Point(point.x() / device_scale_factor_, + point.y() / device_scale_factor_)); + } +} + +void RWHVAuraOffscreenHelperEfl::SelectClosestWord( + const gfx::Point& touch_point) { + int view_x, view_y; + EvasToBlinkCords(touch_point.x(), touch_point.y(), &view_x, &view_y); + +#if !defined(EWK_BRINGUP) // FIXME: m67 bringup + // FIXME: The SelectClosestWord function was removed by + // commit 9720a4494c8bcd24d1f496feec5cfac7582103d2 in s-chromium + // It will be fixed by webview team. + // FIXME: http://suprem.sec.samsung.net/jira/browse/TWF-2122 + Send(new ViewMsg_SelectClosestWord(host_->GetRoutingID(), view_x, view_y)); +#endif // EWK_BRINGUP +} + +bool RWHVAuraOffscreenHelperEfl::HasSelectableText() { + // If the last character of textarea is '\n', We can assume an extra '\n'. + // Actually when you insert line break by ENTER key, '\n\n' is stored in + // textarea. And If you press delete key, only a '\n' character will be stored + // although there is no visible and selectable character in textarea. That's + // why we should check whether selection_text contains only one line break. + // Bug: http://suprem.sec.samsung.net/jira/browse/TSAM-2230 + // + // Please see below commit for more information. + // https://codereview.chromium.org/1785603002 + std::u16string selection_text = rwhv_aura_->GetSelectedText(); + return !selection_text.empty() && + base::UTF16ToUTF8(selection_text).compare("\n") != 0; +} + void RWHVAuraOffscreenHelperEfl::FocusedNodeChanged( bool editable #if BUILDFLAG(IS_TIZEN_TV) diff --git a/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_offscreen_helper_efl.h b/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_offscreen_helper_efl.h index e93b196..3d47eb6 100644 --- a/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_offscreen_helper_efl.h +++ b/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_offscreen_helper_efl.h @@ -145,6 +145,10 @@ class CONTENT_EXPORT RWHVAuraOffscreenHelperEfl { bool IsFocusedNodeContentEditable() const { return is_content_editable_; } + void MoveCaret(const gfx::Point& point); + void SelectClosestWord(const gfx::Point& touch_point); + bool HasSelectableText(); + private: static void OnParentViewResize(void* data, Evas*, Evas_Object*, void*); static void EvasObjectImagePixelsGetCallback(void*, Evas_Object*); diff --git a/tizen_src/chromium_impl/content/browser/selection/selection_box_efl.cc b/tizen_src/chromium_impl/content/browser/selection/selection_box_efl.cc index f3af92d..c5a5eed 100644 --- a/tizen_src/chromium_impl/content/browser/selection/selection_box_efl.cc +++ b/tizen_src/chromium_impl/content/browser/selection/selection_box_efl.cc @@ -5,17 +5,20 @@ #include "selection_box_efl.h" #include "base/trace_event/trace_event.h" +#include "content/browser/renderer_host/render_widget_host_view_aura.h" namespace content { -SelectionBoxEfl::SelectionBoxEfl(Evas_Object* parent_view) - : status_(false), - is_anchor_first_(false), - context_params_(new ContextMenuParams()), - parent_view_(parent_view) { - context_params_->has_image_contents = false; +SelectionBoxEfl::SelectionBoxEfl(RenderWidgetHostViewAura* rwhva) + : status_(false), + is_anchor_first_(false), + context_params_(new ContextMenuParams()), + rwhva_(rwhva) { + context_params_->has_image_contents = false; } +SelectionBoxEfl::~SelectionBoxEfl() = default; + void SelectionBoxEfl::UpdateSelectStringData(const std::u16string& text) { context_params_->selection_text = text; } @@ -37,14 +40,12 @@ bool SelectionBoxEfl::UpdateRectData(const gfx::Rect& left_rect, const gfx::Rect left_rect_ = left_rect; right_rect_ = right_rect; - // Display point of context Menu - Evas_Coord x, y; - evas_object_geometry_get(parent_view_, &x, &y, 0, 0); //context params suppose to be global - related to evas not the web view - ret |= (context_params_->x != (left_rect_.x() + x)); - ret |= (context_params_->y != (left_rect_.y() + y)); - context_params_->x = left_rect_.x() + x; - context_params_->y = left_rect_.y() + y; + gfx::Rect view_bounds = rwhva_->offscreen_helper()->GetViewBoundsInPix(); + ret |= (context_params_->x != (left_rect_.x() + (view_bounds.x()))); + ret |= (context_params_->y != (left_rect_.y() + view_bounds.y())); + context_params_->x = left_rect_.x() + view_bounds.x(); + context_params_->y = left_rect_.y() + view_bounds.y(); return ret; } @@ -54,12 +55,13 @@ bool SelectionBoxEfl::IsInEditField() const { } void SelectionBoxEfl::SetStatus(bool enable) { - bool invokeCbAtEnd = status_ != enable; + bool invoke_cb_at_end = status_ != enable; status_ = enable; // invoke CB only if mode actually changed - if (invokeCbAtEnd && parent_view_) - evas_object_smart_callback_call(parent_view_, "textselection,mode", &status_); + if (invoke_cb_at_end && rwhva_->offscreen_helper()->ewk_view()) + evas_object_smart_callback_call(rwhva_->offscreen_helper()->ewk_view(), + "textselection,mode", &status_); } } diff --git a/tizen_src/chromium_impl/content/browser/selection/selection_box_efl.h b/tizen_src/chromium_impl/content/browser/selection/selection_box_efl.h index f238587..aa4c8de 100644 --- a/tizen_src/chromium_impl/content/browser/selection/selection_box_efl.h +++ b/tizen_src/chromium_impl/content/browser/selection/selection_box_efl.h @@ -15,12 +15,17 @@ class EWebView; namespace content { +class RenderWidgetHostViewAura; // Hold the data related to drwaing the selection handlers // and context menu. Also stores all the data required for selection // controlling class SelectionBoxEfl { public: - SelectionBoxEfl(Evas_Object* parent_view); + explicit SelectionBoxEfl(RenderWidgetHostViewAura* rwhva); + ~SelectionBoxEfl(); + + SelectionBoxEfl(const SelectionBoxEfl&) = delete; + SelectionBoxEfl& operator=(const SelectionBoxEfl&) = delete; void SetStatus(bool enable); bool GetStatus() const { return status_; } @@ -52,7 +57,7 @@ class SelectionBoxEfl { // Contains the menu item data for which context needs to be populated std::unique_ptr context_params_; - Evas_Object* parent_view_; + RenderWidgetHostViewAura* rwhva_; }; } diff --git a/tizen_src/chromium_impl/content/browser/selection/selection_controller_efl.cc b/tizen_src/chromium_impl/content/browser/selection/selection_controller_efl.cc index b8368ef..fd9168e 100644 --- a/tizen_src/chromium_impl/content/browser/selection/selection_controller_efl.cc +++ b/tizen_src/chromium_impl/content/browser/selection/selection_controller_efl.cc @@ -4,11 +4,12 @@ #include "selection_controller_efl.h" -#include +#include #include "base/trace_event/trace_event.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/renderer_host/render_widget_host_impl.h" +#include "content/browser/renderer_host/render_widget_host_view_aura.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/browser/web_contents/web_contents_impl_efl.h" #include "content/public/browser/context_menu_params.h" @@ -40,33 +41,39 @@ gfx::Vector2dF ComputeLineOffsetFromBottom(const gfx::SelectionBound& bound) { return line_offset; } -SelectionControllerEfl::SelectionControllerEfl(Evas_Object* parent_view, WebContents& web_contents) - : parent_view_(parent_view), - controls_temporarily_hidden_(false), - selection_change_reason_(Reason::Irrelevant), - long_mouse_press_(false), - selection_data_(new SelectionBoxEfl(parent_view)), - start_handle_(new SelectionHandleEfl(*this, SelectionHandleEfl::HANDLE_TYPE_LEFT, parent_view)), - end_handle_(new SelectionHandleEfl(*this, SelectionHandleEfl::HANDLE_TYPE_RIGHT, parent_view)), - input_handle_(new SelectionHandleEfl(*this, SelectionHandleEfl::HANDLE_TYPE_INPUT, parent_view)), - magnifier_(new SelectionMagnifierEfl(this, web_contents)), - is_selection_visible_(false), - handle_being_dragged_(false), - selection_on_empty_form_control_(false), - web_contents_(web_contents), - selection_mode_(None) { - evas_object_event_callback_add(parent_view_, EVAS_CALLBACK_MOVE, &EvasParentViewMoveCallback, this); +content::WebContents* SelectionControllerEfl::web_contents() const { + return rwhva_->offscreen_helper()->GetWebContents(); +} + +SelectionControllerEfl::SelectionControllerEfl(RenderWidgetHostViewAura* rwhva) + : rwhva_(rwhva), + selection_data_(new SelectionBoxEfl(rwhva)), + start_handle_( + new SelectionHandleEfl(*this, SelectionHandleEfl::HANDLE_TYPE_LEFT)), + end_handle_( + new SelectionHandleEfl(*this, SelectionHandleEfl::HANDLE_TYPE_RIGHT)), + input_handle_( + new SelectionHandleEfl(*this, SelectionHandleEfl::HANDLE_TYPE_INPUT)), + magnifier_(new SelectionMagnifierEfl(this)), + selection_mode_(None) { + evas_object_event_callback_add(rwhva_->offscreen_helper()->content_image(), + EVAS_CALLBACK_MOVE, + &EvasParentViewMoveCallback, this); #if BUILDFLAG(IS_TIZEN) vconf_notify_key_changed(VCONFKEY_LANGSET, PlatformLanguageChanged, this); #endif } SelectionControllerEfl::~SelectionControllerEfl() { + if (ecore_events_filter_) + ecore_event_filter_del(ecore_events_filter_); if (GetSelectionStatus()) ClearSelectionViaEWebView(); HideHandleAndContextMenu(); - evas_object_event_callback_del(parent_view_, EVAS_CALLBACK_MOVE, &EvasParentViewMoveCallback); + evas_object_event_callback_del(rwhva_->offscreen_helper()->content_image(), + EVAS_CALLBACK_MOVE, + &EvasParentViewMoveCallback); } void SelectionControllerEfl::SetSelectionStatus(bool enable) { @@ -114,15 +121,10 @@ void SelectionControllerEfl::SetControlsTemporarilyHidden(bool value) { "controls are hidden:", value); if (controls_temporarily_hidden_ == value) return; -#if !defined(USE_AURA) - RenderWidgetHostViewEfl* rwhv = static_cast( - web_contents_.GetRenderWidgetHostView()); - CHECK(rwhv); // Make sure to show selection controls only when no finger // is left touching the screen. - if (!value && rwhv->PointerStatePointerCount()) + if (!value && rwhva_->event_handler()->pointer_state().GetPointerCount()) return; -#endif controls_temporarily_hidden_ = value; if (value) { Clear(); @@ -157,18 +159,30 @@ void SelectionControllerEfl::OnSelectionChanged( truncated_end = gfx::ToEnclosingRect( gfx::ConvertRectToPixels(truncated_end, device_scale_factor)); + if (handle_being_dragged_ && + dragging_handle_->Type() != SelectionHandleEfl::HANDLE_TYPE_INPUT) { + dragging_handle_->MoveObject(selection_data_->GetIsAnchorFirst() + ? truncated_end.bottom_right() + : truncated_start.bottom_left()); + } + bool finger_down = handle_being_dragged_ || long_mouse_press_; bool show = (selection_change_reason_ != Reason::Irrelevant) && !finger_down; UpdateSelectionDataAndShow( truncated_start, truncated_end, show); selection_change_reason_ = Reason::Irrelevant; + + // In case of the selected text contains only line break and no other + // characters, we should use caret selection mode. + if (GetSelectionEditable() && !handle_being_dragged_ && + rwhva_->GetSelectedText() == (u"\n")) { + rwhva_->offscreen_helper()->MoveCaret( + selection_data_->GetLeftRect().origin()); + is_caret_mode_forced_ = true; + } } void SelectionControllerEfl::OnTextInputStateChanged() { -#if !defined(USE_AURA) - RenderWidgetHostViewEfl* rwhv = static_cast( - web_contents_.GetRenderWidgetHostView()); - CHECK(rwhv); // In order to confirm if a long press gesture is ongoing, // we just needed to check "long_mouse_press_". // However, when long press happens on a link or image, @@ -176,7 +190,8 @@ void SelectionControllerEfl::OnTextInputStateChanged() { // although finger is still down. // To compensate this, add an extra check asking from the engine // if a finger is still touching down. - bool is_touch_down = rwhv->PointerStatePointerCount() > 0; + bool is_touch_down = + rwhva_->event_handler()->pointer_state().GetPointerCount() > 0; // If on an editable field and in caret selection mode, only // show the large handle if: @@ -185,12 +200,12 @@ void SelectionControllerEfl::OnTextInputStateChanged() { // handling "tap" gesture. bool finger_down = handle_being_dragged_ || long_mouse_press_ || is_touch_down; - if (GetSelectionEditable() && !finger_down && !controls_temporarily_hidden_ && + if (GetSelectionEditable() && GetCaretSelectionStatus() && !finger_down && + !controls_temporarily_hidden_ && selection_change_reason_ == Reason::Irrelevant) { HideHandleAndContextMenu(); ClearSelection(); } -#endif } void SelectionControllerEfl::UpdateSelectionData(const std::u16string& text) { @@ -198,17 +213,14 @@ void SelectionControllerEfl::UpdateSelectionData(const std::u16string& text) { } bool SelectionControllerEfl::ClearSelectionViaEWebView() { - if (!GetSelectionStatus() || !web_contents_.GetRenderViewHost() || - web_contents_.IsBeingDestroyed()) { + if (!GetSelectionStatus() || !web_contents()->GetRenderViewHost() || + web_contents()->IsBeingDestroyed()) { return false; } - // RenderWidgetHostImpl* rwhi = static_cast( - // web_contents_.GetRenderViewHost()->GetWidget()); - // rwhi->ExecuteEditCommand("Unselect", ""); - RenderWidgetHostDelegate* host_delegate = - RenderWidgetHostImpl::From(web_contents_.GetRenderViewHost()->GetWidget()) + RenderWidgetHostImpl::From( + web_contents()->GetRenderViewHost()->GetWidget()) ->delegate(); if (host_delegate) { host_delegate->ExecuteEditCommand("Unselect", absl::nullopt); @@ -221,6 +233,14 @@ void SelectionControllerEfl::SetSelectionMode(enum SelectionMode mode) { selection_mode_ = mode; } +void SelectionControllerEfl::ToggleCaretAfterSelection() { + if (!GetCaretSelectionStatus() && GetSelectionEditable()) { + rwhva_->offscreen_helper()->MoveCaret( + selection_data_->GetRightRect().origin()); + ClearSelection(); + } +} + void SelectionControllerEfl::DetermineSelectionMode( const gfx::Rect& left_rect, const gfx::Rect& right_rect) { @@ -286,8 +306,8 @@ void SelectionControllerEfl::ShowHandleAndContextMenuIfRequired( return; } - bool is_any_handle_visible = start_selection_.visible() || - end_selection_.visible(); + bool is_selection_range_visible = + start_selection_.visible() || end_selection_.visible(); // Is in edit field and no text is selected. show only single handle if (selection_data_->IsInEditField() && left == right) { @@ -296,7 +316,7 @@ void SelectionControllerEfl::ShowHandleAndContextMenuIfRequired( CHECK(start_selection_ == end_selection_); - if (GetCaretSelectionStatus() && is_any_handle_visible) { + if (GetCaretSelectionStatus() && is_selection_range_visible) { gfx::Rect left = selection_data_->GetLeftRect(); input_handle_->SetBasePosition(gfx::Point(left.x(), left.y())); input_handle_->Move(left.bottom_right()); @@ -305,10 +325,11 @@ void SelectionControllerEfl::ShowHandleAndContextMenuIfRequired( start_handle_->Hide(); end_handle_->Hide(); - bool show_context_menu = is_any_handle_visible && - effective_reason != Reason::ScrollOrZoomGestureEnded && - effective_reason != Reason::Tap && - effective_reason != Reason::Irrelevant; + bool show_context_menu = + IsAnyHandleVisible() && + effective_reason != Reason::ScrollOrZoomGestureEnded && + effective_reason != Reason::Tap && + effective_reason != Reason::Irrelevant; if (!handle_being_dragged_ && show_context_menu) ShowContextMenu(); @@ -346,8 +367,9 @@ void SelectionControllerEfl::ShowHandleAndContextMenuIfRequired( // Do not show the context menu during selection extend and // offscreen selection. if (!handle_being_dragged_ && effective_reason != Reason::Irrelevant && - is_any_handle_visible) + IsAnyHandleVisible()) { ShowContextMenu(); + } } void SelectionControllerEfl::ShowContextMenu() { @@ -401,14 +423,43 @@ void SelectionControllerEfl::Clear() { input_handle_->Hide(); } -void SelectionControllerEfl::HandleDragBeginNotification(SelectionHandleEfl* handle) { +Eina_Bool SelectionControllerEfl::EcoreEventFilterCallback(void* user_data, + void* /*loop_data*/, + int type, + void* event_info) { + if (type == ECORE_EVENT_MOUSE_MOVE) { + auto controller = static_cast(user_data); + if (!controller || !controller->dragged_handle_) + return ECORE_CALLBACK_PASS_ON; + + auto event = static_cast(event_info); + controller->dragged_handle_->UpdatePosition(gfx::Point(event->x, event->y)); + return ECORE_CALLBACK_CANCEL; + } + + return ECORE_CALLBACK_PASS_ON; +} + +void SelectionControllerEfl::HandleDragBeginNotification( + SelectionHandleEfl* handle) { + selection_change_reason_ = Reason::HandleDragged; + dragged_handle_ = handle; + ecore_events_filter_ = + ecore_event_filter_add(nullptr, EcoreEventFilterCallback, nullptr, this); + + if (!ecore_events_filter_) { + LOG(ERROR) << __PRETTY_FUNCTION__ + << " : Unable to create ecore events filter"; + } + // Hide context menu on mouse down CancelContextMenu(0); handle_being_dragged_ = true; Evas_Coord x, y; - evas_object_geometry_get(parent_view_, &x, &y, 0, 0); + evas_object_geometry_get(rwhva_->offscreen_helper()->content_image(), &x, &y, + 0, 0); gfx::Point magnifier_point( handle->GetBasePosition().x() + x, handle->GetBasePosition().y() + y); @@ -448,33 +499,29 @@ void SelectionControllerEfl::HandleDragBeginNotification(SelectionHandleEfl* han base += base_offset; extent += extent_offset; - WebContentsImpl* wci = static_cast(&web_contents_); + WebContentsImpl* wci = static_cast(web_contents()); wci->SelectRange(gfx::ToFlooredPoint(base), gfx::ToFlooredPoint(extent)); } void SelectionControllerEfl::HandleDragUpdateNotification(SelectionHandleEfl* handle) { + if (!rwhva_) + return; // FIXME : Check the text Direction later - Evas_Coord x, y; - evas_object_geometry_get(parent_view_, &x, &y, 0, 0); + gfx::Rect view_bounds = rwhva_->offscreen_helper()->GetViewBoundsInPix(); selection_change_reason_ = Reason::HandleDragged; gfx::Point magnifier_point; - magnifier_point.set_x(handle->GetBasePosition().x() + x); - magnifier_point.set_y(handle->GetBasePosition().y() + y); + magnifier_point.set_x(handle->GetBasePosition().x() + view_bounds.x()); + magnifier_point.set_y(handle->GetBasePosition().y() + view_bounds.y()); magnifier_->UpdateLocation(magnifier_point); magnifier_->Move(magnifier_point); switch (handle->Type()) { -#if !defined(USE_AURA) case SelectionHandleEfl::HANDLE_TYPE_INPUT: { - RenderWidgetHostViewEfl* rwhv = - static_cast(web_contents_.GetRenderWidgetHostView()); - if (rwhv) - rwhv->MoveCaret(handle->GetBasePosition()); + rwhva_->offscreen_helper()->MoveCaret(handle->GetBasePosition()); return; } -#endif case SelectionHandleEfl::HANDLE_TYPE_LEFT: case SelectionHandleEfl::HANDLE_TYPE_RIGHT: { float device_scale_factor = @@ -488,7 +535,7 @@ void SelectionControllerEfl::HandleDragUpdateNotification(SelectionHandleEfl* ha : ComputeLineOffsetFromBottom(end_selection_); extent += line_offset; - WebContentsImpl* wci = static_cast(&web_contents_); + WebContentsImpl* wci = static_cast(web_contents()); wci->MoveRangeSelectionExtent(gfx::ToFlooredPoint(extent)); return; } @@ -496,6 +543,12 @@ void SelectionControllerEfl::HandleDragUpdateNotification(SelectionHandleEfl* ha } void SelectionControllerEfl::HandleDragEndNotification() { + dragged_handle_ = nullptr; + + if (ecore_events_filter_) + ecore_event_filter_del(ecore_events_filter_); + ecore_events_filter_ = nullptr; + selection_change_reason_ = Reason::Irrelevant; magnifier_->Hide(); start_handle_->SetBasePosition(selection_data_->GetLeftRect().bottom_left()); @@ -535,7 +588,9 @@ void SelectionControllerEfl::HandleGesture(blink::WebGestureEvent& event) { } } -void SelectionControllerEfl::HandlePostponedGesture(int x, int y, ui::EventType type) { +void SelectionControllerEfl::HandlePostponedGesture(int x, + int y, + ui::EventType type) { DVLOG(0) << "HandlePostponedGesture :: " << type; #if !defined(USE_AURA) RenderWidgetHostViewEfl* rwhv = @@ -583,14 +638,13 @@ bool SelectionControllerEfl::HandleLongPressEvent( #endif SetSelectionStatus(true); SetSelectionEditable(true); + if (selection_mode_ == None) + SetSelectionMode(Caret); HandleLongPressEventPrivate(touch_point); return true; - } else if (params.link_url.is_empty() && params.src_url.is_empty() -#if !defined(EWK_BRINGUP) // FIXME: m67 bringup - && params.is_text_node) { -#else - ) { -#endif + } else if (params.link_url.is_empty() && params.src_url.is_empty() && + params.is_text_node || + !params.selection_text.empty()) { // If user is long pressing on a content with // -webkit-user-select: none, we should bail and not enter // selection neither show magnigier class or context menu. @@ -618,31 +672,18 @@ bool SelectionControllerEfl::HandleLongPressEvent( return true; } -void SelectionControllerEfl::HandleLongPressEventPrivate(const gfx::Point& touch_point) { +void SelectionControllerEfl::HandleLongPressEventPrivate( + const gfx::Point& touch_point) { Clear(); - Evas_Coord x, y; - evas_object_geometry_get(parent_view_, &x, &y, 0, 0); - magnifier_->HandleLongPress(gfx::Point(touch_point.x() + x, - touch_point.y() + y)); + gfx::Rect view_bounds = rwhva_->offscreen_helper()->GetViewBoundsInPix(); + magnifier_->HandleLongPress(gfx::Point(touch_point.x() + view_bounds.x(), + touch_point.y() + view_bounds.y())); } void SelectionControllerEfl::HandleLongPressMoveEvent(const gfx::Point& touch_point) { -#if !defined(USE_AURA) - RenderWidgetHostViewEfl* rwhv = - static_cast(web_contents_.GetRenderWidgetHostView()); - Clear(); - selection_change_reason_ = Reason::LongPressMoved; - if (selection_data_->IsInEditField()) { - Evas_Coord x, y; - evas_object_geometry_get(parent_view_, &x, &y, 0, 0); - if (rwhv) - rwhv->MoveCaret(gfx::Point(touch_point.x() - x, touch_point.y() - y)); - } else{ - if (rwhv) - rwhv->SelectClosestWord(touch_point); - } -#endif + if (rwhva_) + rwhva_->offscreen_helper()->SelectClosestWord(touch_point); } void SelectionControllerEfl::HandleLongPressEndEvent() { @@ -652,14 +693,12 @@ void SelectionControllerEfl::HandleLongPressEndEvent() { } void SelectionControllerEfl::PostHandleTapGesture(bool is_content_editable) { - HideHandleAndContextMenu(); if (is_content_editable) { DVLOG(1) << "PostHandleTapGesture :: Editable"; SetSelectionStatus(true); SetSelectionEditable(true); selection_change_reason_ = Reason::Tap; } else { - ClearSelectionViaEWebView(); SetSelectionEditable(false); } } @@ -695,6 +734,7 @@ bool SelectionControllerEfl::IsSelectionValid(const gfx::Rect& left_rect, void SelectionControllerEfl::ClearSelection() { TRACE_EVENT0("selection,efl", __PRETTY_FUNCTION__); Clear(); + CancelContextMenu(0); SetSelectionStatus(false); SetSelectionEditable(false); SetSelectionMode(None); @@ -719,7 +759,8 @@ void SelectionControllerEfl::ChangeContextMenuPosition(gfx::Point& position, int int handleHeight, webViewX, webViewY, webViewWidth, webViewHeight; gfx::Rect imeRect; edje_object_part_geometry_get(input_handle_->evas_object(), "handle", 0, 0, 0, &handleHeight); - evas_object_geometry_get(GetParentView(), &webViewX, &webViewY, &webViewWidth, &webViewHeight); + evas_object_geometry_get(rwhva_->offscreen_helper()->content_image(), + &webViewX, &webViewY, &webViewWidth, &webViewHeight); gfx::Rect viewportRect = gfx::Rect(webViewX, webViewY, webViewWidth, webViewHeight); #if !defined(USE_AURA) RenderWidgetHostViewEfl* rwhv = @@ -846,6 +887,14 @@ void SelectionControllerEfl::ChangeContextMenuPosition(gfx::Point& position, int return; } +gfx::Rect SelectionControllerEfl::GetVisibleViewportRect() const { + if (custom_visible_view_rect_.IsEmpty()) + return rwhva_->offscreen_helper()->GetViewBoundsInPix(); + + return gfx::IntersectRects(rwhva_->offscreen_helper()->GetViewBoundsInPix(), + custom_visible_view_rect_); +} + bool SelectionControllerEfl::TextSelectionDown(int x, int y) { /* * According to webkit-efl textSelectionDown is used on long press gesture, we already diff --git a/tizen_src/chromium_impl/content/browser/selection/selection_controller_efl.h b/tizen_src/chromium_impl/content/browser/selection/selection_controller_efl.h index bfebbbd..7f34758 100644 --- a/tizen_src/chromium_impl/content/browser/selection/selection_controller_efl.h +++ b/tizen_src/chromium_impl/content/browser/selection/selection_controller_efl.h @@ -25,6 +25,7 @@ #include namespace content { +class RenderWidgetHostViewAura; class WebContents; class WebContentsImpl; @@ -46,9 +47,12 @@ class CONTENT_EXPORT SelectionControllerEfl { }; public: - explicit SelectionControllerEfl(Evas_Object* parent_view, WebContents& web_contents); + explicit SelectionControllerEfl(RenderWidgetHostViewAura* rwhva); ~SelectionControllerEfl(); + SelectionControllerEfl(const SelectionControllerEfl&) = delete; + SelectionControllerEfl& operator=(const SelectionControllerEfl&) = delete; + // Functions that handle long press, long press move and release bool HandleLongPressEvent(const gfx::Point& touch_point, const content::ContextMenuParams& params); @@ -86,7 +90,6 @@ class CONTENT_EXPORT SelectionControllerEfl { // Clears the selection and hides context menu and handles void ClearSelection(); bool ClearSelectionViaEWebView(); - Evas_Object* GetParentView() const { return parent_view_; } void HideHandles(); void HideHandleAndContextMenu(); bool IsAnyHandleVisible() const; @@ -120,6 +123,7 @@ class CONTENT_EXPORT SelectionControllerEfl { LongPressEnded, Tap, RequestedByContextMenu, + CaretModeForced, Irrelevant, }; void SetWaitsForRendererSelectionChanges( @@ -129,6 +133,20 @@ class CONTENT_EXPORT SelectionControllerEfl { void HandlePostponedGesture(int x, int y, ui::EventType type); void HandleGesture(blink::WebGestureEvent& event); + gfx::Rect GetVisibleViewportRect() const; + + bool IsCaretModeForced() const { return is_caret_mode_forced_; } + void SetCustomVisibleViewRect(const gfx::Rect& custom_visible_view_rect) { + custom_visible_view_rect_ = custom_visible_view_rect; + } + + void ToggleCaretAfterSelection(); + void ShowHandleAndContextMenuIfRequired( + Reason explicit_reason = Reason::Irrelevant); + + RenderWidgetHostViewAura* rwhva() const { return rwhva_; } + content::WebContents* web_contents() const; + private: enum SelectionMode { None = 0, @@ -145,16 +163,18 @@ class CONTENT_EXPORT SelectionControllerEfl { void HandleLongPressEventPrivate(const gfx::Point& touch_point); - void ShowHandleAndContextMenuIfRequired(Reason explicit_reason = Reason::Irrelevant); - void Clear(); bool IsSelectionValid(const gfx::Rect& left_rect, const gfx::Rect& right_rect); void ShowContextMenu(); void CancelContextMenu(int request_id); - static void EvasParentViewMoveCallback(void *data, Evas *e, Evas_Object *obj, void *event_info) - { reinterpret_cast(data)->OnParentParentViewMove(); } + static void EvasParentViewMoveCallback(void* data, + Evas* e, + Evas_Object* obj, + void* event_info) { + reinterpret_cast(data)->OnParentParentViewMove(); + } #if BUILDFLAG(IS_TIZEN) static void PlatformLanguageChanged(keynode_t* keynode, void* data); @@ -162,20 +182,26 @@ class CONTENT_EXPORT SelectionControllerEfl { void OnParentParentViewMove(); - Evas_Object* parent_view_; + static Eina_Bool EcoreEventFilterCallback(void* user_data, + void* loop_data, + int type, + void* event_info); + // Is required to send back selction points and range extenstion co-ordinates + RenderWidgetHostViewAura* rwhva_; // Saves state so that selection controls are temporarily hidden due // to scrolling or zooming. - bool controls_temporarily_hidden_; + bool controls_temporarily_hidden_ = false; // Cache the reason of why browser has requested a text selection // change to the renderer. At the next composited selection update // the cache is handled and reset. - Reason selection_change_reason_; + Reason selection_change_reason_ = Reason::Irrelevant; - // Saves state so that handlers and context menu is not shown when seletion change event occurs. - bool long_mouse_press_; + // Saves state so that handlers and context menu is not shown when seletion + // change event occurs. + bool long_mouse_press_ = false; // Saves the data that are required to draw handle and context menu std::unique_ptr selection_data_; @@ -198,13 +224,18 @@ class CONTENT_EXPORT SelectionControllerEfl { // Helper pointer to the stationary handle (during dragging). SelectionHandleEfl* stationary_handle_; - bool is_selection_visible_; + gfx::Rect custom_visible_view_rect_; + + bool is_selection_visible_ = false; + + bool handle_being_dragged_ = false; - bool handle_being_dragged_; + bool is_caret_mode_forced_ = false; + bool selection_on_empty_form_control_ = false; - bool selection_on_empty_form_control_; + Ecore_Event_Filter* ecore_events_filter_ = nullptr; - WebContents& web_contents_; + SelectionHandleEfl* dragged_handle_ = nullptr; enum SelectionMode selection_mode_; gfx::SelectionBound start_selection_; diff --git a/tizen_src/chromium_impl/content/browser/selection/selection_handle_efl.cc b/tizen_src/chromium_impl/content/browser/selection/selection_handle_efl.cc index efb40d3..d095ff3 100644 --- a/tizen_src/chromium_impl/content/browser/selection/selection_handle_efl.cc +++ b/tizen_src/chromium_impl/content/browser/selection/selection_handle_efl.cc @@ -11,7 +11,9 @@ #include "base/files/file_path.h" #include "base/path_service.h" #include "base/trace_event/trace_event.h" +#include "content/browser/renderer_host/render_widget_host_view_aura.h" #include "content/browser/selection/selection_controller_efl.h" +#include "content/browser/web_contents/web_contents_impl.h" #include "content/common/paths_efl.h" namespace content { @@ -35,13 +37,14 @@ static const char* GetEdjeObjectGroupPath(SelectionHandleEfl::HandleType type) { } } -SelectionHandleEfl::SelectionHandleEfl(SelectionControllerEfl& controller, HandleType type, Evas_Object* parent) - : controller_(controller), - pressed_(false), - is_top_(false), - handle_type_(type) { - - Evas* evas = evas_object_evas_get(parent); +SelectionHandleEfl::SelectionHandleEfl(SelectionControllerEfl& controller, + HandleType type) + : controller_(controller), + pressed_(false), + is_top_(false), + handle_type_(type) { + Evas* evas = evas_object_evas_get( + controller_.rwhva()->offscreen_helper()->content_image()); handle_ = edje_object_add(evas); base::FilePath edj_dir; @@ -57,7 +60,12 @@ SelectionHandleEfl::SelectionHandleEfl(SelectionControllerEfl& controller, Handl edje_object_signal_emit(handle_, "edje,focus,in", "edje"); edje_object_signal_emit(handle_, "elm,state,bottom", "elm"); - evas_object_smart_member_add(handle_, parent); + Evas_Object* main_layout_ = + static_cast( + controller_.rwhva()->offscreen_helper()->GetWebContents()) + ->GetEflNativeView(); + Evas_Object* smart_parent = evas_object_smart_parent_get(main_layout_); + evas_object_smart_member_add(handle_, smart_parent); evas_object_propagate_events_set(handle_, false); evas_object_event_callback_add(handle_, EVAS_CALLBACK_MOUSE_DOWN, OnMouseDown, this); @@ -67,11 +75,13 @@ SelectionHandleEfl::SelectionHandleEfl(SelectionControllerEfl& controller, Handl SelectionHandleEfl::~SelectionHandleEfl() { evas_object_event_callback_del(handle_, EVAS_CALLBACK_MOUSE_DOWN, OnMouseDown); evas_object_event_callback_del(handle_, EVAS_CALLBACK_MOUSE_UP, OnMouseUp); + evas_object_smart_member_del(handle_); evas_object_del(handle_); } void SelectionHandleEfl::Show() { evas_object_show(handle_); + evas_object_raise(handle_); } void SelectionHandleEfl::Hide() { @@ -79,13 +89,18 @@ void SelectionHandleEfl::Hide() { } bool SelectionHandleEfl::IsVisible() const { - return evas_object_visible_get(handle_); + int handle_x, handle_y; + evas_object_geometry_get(handle_, &handle_x, &handle_y, nullptr, nullptr); + + auto view_rect = controller_.GetVisibleViewportRect(); + + return evas_object_visible_get(handle_) && + view_rect.Contains(handle_x, handle_y); } void SelectionHandleEfl::Move(const gfx::Point& point) { - if (!pressed_) { + if (!pressed_) ChangeObjectDirection(CalculateDirection(point)); - } if (handle_type_ == HANDLE_TYPE_INPUT) MoveInputHandle(point); @@ -108,32 +123,21 @@ void SelectionHandleEfl::OnMouseDown(void* data, Evas*, Evas_Object*, void* even Evas_Event_Mouse_Down* event = static_cast(event_info); SelectionHandleEfl* handle = static_cast(data); handle->pressed_ = true; - evas_object_event_callback_add(handle->handle_, EVAS_CALLBACK_MOUSE_MOVE, - OnMouseMove, handle); //Save the diff_point between touch point and base point of the handle handle->diff_point_.SetPoint(event->canvas.x - handle->base_point_.x(), event->canvas.y - handle->base_point_.y()); - Evas_Coord x, y; - evas_object_geometry_get(handle->evas_object(), &x, &y, 0, 0); - handle->handle_position_at_touch_down_ = gfx::Point(x, y); - handle->touch_down_position_ = gfx::Point(event->canvas.x, event->canvas.y); - handle->controller_.HandleDragBeginNotification(handle); } -void SelectionHandleEfl::OnMouseMove(void* data, Evas*, Evas_Object*, void* event_info) { - Evas_Event_Mouse_Move* event = static_cast(event_info); - SelectionHandleEfl* handle = static_cast(data); - handle->current_touch_point_.SetPoint(event->cur.canvas.x, event->cur.canvas.y); - ecore_job_add(UpdateMouseMove, handle); +void SelectionHandleEfl::UpdatePosition(const gfx::Point& position) { + current_touch_point_ = position; + ecore_job_add(UpdateMouseMove, this); } void SelectionHandleEfl::OnMouseUp(void* data, Evas*, Evas_Object*, void* /* event_info */) { SelectionHandleEfl* handle = static_cast(data); handle->pressed_ = false; - evas_object_event_callback_del(handle->handle_, EVAS_CALLBACK_MOUSE_MOVE, OnMouseMove); - handle->controller_.HandleDragEndNotification(); } @@ -150,31 +154,23 @@ void SelectionHandleEfl::UpdateMouseMove(void* data) { int delta_y = handle->current_touch_point_.y() - handle->diff_point_.y(); handle->base_point_.SetPoint(delta_x, delta_y); - gfx::Vector2d diff = handle->current_touch_point_ - handle->touch_down_position_; - if (handle->handle_type_ != HANDLE_TYPE_INPUT) { - // We call MoveObject with evas coordinates relative to - // the webview canvas. So we need to ignore the parent - // view offset calculation. - handle->MoveObject(handle->handle_position_at_touch_down_ + diff, - true /*ignore_parent_view_offset*/); - } - handle->controller_.HandleDragUpdateNotification(handle); } SelectionHandleEfl::HandleDirection SelectionHandleEfl::CalculateDirection( const gfx::Point& point) const { - bool reverse_horizontally = false, reverse_vertically = false; - Evas_Coord x, y, deviceWidth, deviceHeight; + bool reverse_horizontally = false, reverse_vertically = false; int handleHeight; - edje_object_part_geometry_get(handle_, "handle", 0, 0, 0, &handleHeight); - evas_object_geometry_get(controller_.GetParentView(), - &x, &y, &deviceWidth, &deviceHeight); - gfx::Point conv_point(point.x() + x, point.y() + y); - gfx::Rect reverse_direction_rect = gfx::Rect(x + kReverseMargin, - y, deviceWidth - 2 * kReverseMargin, deviceHeight - handleHeight); + auto visible_viewport_rect = controller_.GetVisibleViewportRect(); + gfx::Point conv_point(point.x() + visible_viewport_rect.x(), + point.y() + visible_viewport_rect.y()); + + gfx::Rect reverse_direction_rect = gfx::Rect( + visible_viewport_rect.x() + kReverseMargin, visible_viewport_rect.y(), + visible_viewport_rect.width() - 2 * kReverseMargin, + visible_viewport_rect.height() - handleHeight); if (!reverse_direction_rect.Contains(conv_point)) { if (conv_point.x() <= reverse_direction_rect.x() || @@ -188,29 +184,27 @@ SelectionHandleEfl::HandleDirection SelectionHandleEfl::CalculateDirection( } if (handle_type_ != HANDLE_TYPE_INPUT) { - if (reverse_vertically) { - if (reverse_horizontally) { - return DirectionTopReverse; - } else { - return DirectionBottomReverse; - } - } else { - if (reverse_horizontally) { - return DirectionTopNormal; - } else { - return DirectionBottomNormal; - } - } + if (reverse_vertically) { + if (reverse_horizontally) + return DirectionTopReverse; + else + return DirectionBottomReverse; + } else { + if (reverse_horizontally) + return DirectionTopNormal; + else + return DirectionBottomNormal; + } } else { // Input handle can only be rotated horizontally - if (reverse_horizontally) { + if (reverse_horizontally) return DirectionTopNormal; - } else { + else return DirectionBottomNormal; - } } NOTREACHED(); + return DirectionBottomNormal; } void SelectionHandleEfl::ChangeObjectDirection(HandleDirection direction) { @@ -244,20 +238,23 @@ void SelectionHandleEfl::ChangeObjectDirection(HandleDirection direction) { else edje_object_signal_emit(handle_, "elm,state,top,reversed", "elm"); break; - } + } switch (handle_type_) { case HANDLE_TYPE_LEFT: - evas_object_smart_callback_call(controller_.GetParentView(), - "selection,handle,left,direction", &direction); + evas_object_smart_callback_call( + controller_.rwhva()->offscreen_helper()->ewk_view(), + "selection,handle,left,direction", &direction); break; case HANDLE_TYPE_RIGHT: - evas_object_smart_callback_call(controller_.GetParentView(), - "selection,handle,right,direction", &direction); + evas_object_smart_callback_call( + controller_.rwhva()->offscreen_helper()->ewk_view(), + "selection,handle,right,direction", &direction); break; case HANDLE_TYPE_INPUT: - evas_object_smart_callback_call(controller_.GetParentView(), - "selection,handle,large,direction", &direction); + evas_object_smart_callback_call( + controller_.rwhva()->offscreen_helper()->ewk_view(), + "selection,handle,large,direction", &direction); break; } } @@ -279,17 +276,38 @@ gfx::Rect SelectionHandleEfl::GetSelectionRect() const { } void SelectionHandleEfl::MoveObject(const gfx::Point& point, bool ignore_parent_view_offset) { - Evas_Coord x = 0, y = 0; - if (!ignore_parent_view_offset) - evas_object_geometry_get(controller_.GetParentView(), &x, &y, - 0, 0); - - if (handle_type_ == HANDLE_TYPE_INPUT && IsTop()) { - evas_object_move(handle_, point.x() + x, - point.y() + y - controller_.GetLeftRect().height()); - } else { - evas_object_move(handle_, point.x() + x, point.y() + y); + gfx::Rect view_bounds = + controller_.rwhva()->offscreen_helper()->GetViewBoundsInPix(); + int handle_x = point.x() + view_bounds.x(); + int handle_y = point.y() + view_bounds.y(); + + if (IsTop()) { + if (handle_type_ == HANDLE_TYPE_RIGHT) + handle_y -= controller_.GetRightRect().height(); + else + handle_y -= controller_.GetLeftRect().height(); + } + + // Prevent selection handles from moving out of visible webview. + if (handle_type_ != HANDLE_TYPE_INPUT) { + const gfx::Rect& viewport_rect = controller_.GetVisibleViewportRect(); + int viewport_rect_x = viewport_rect.x(); + int viewport_rect_y = viewport_rect.y(); + int viewport_rect_w = viewport_rect.width(); + int viewport_rect_h = viewport_rect.height(); + + if (handle_y < viewport_rect_y) + handle_y = viewport_rect_y; + else if (handle_y > viewport_rect_h + viewport_rect_y) + handle_y = viewport_rect_h + viewport_rect_y; + + if (handle_x < viewport_rect_x) + handle_x = viewport_rect_x; + else if (handle_x > viewport_rect_w + viewport_rect_x) + handle_x = viewport_rect_w + viewport_rect_x; } + + evas_object_move(handle_, handle_x, handle_y); } } // namespace content diff --git a/tizen_src/chromium_impl/content/browser/selection/selection_handle_efl.h b/tizen_src/chromium_impl/content/browser/selection/selection_handle_efl.h index e7efbb2..a886fbf 100644 --- a/tizen_src/chromium_impl/content/browser/selection/selection_handle_efl.h +++ b/tizen_src/chromium_impl/content/browser/selection/selection_handle_efl.h @@ -41,7 +41,7 @@ class SelectionHandleEfl { DirectionNone, }; - SelectionHandleEfl(SelectionControllerEfl& controller, HandleType type, Evas_Object* parent); + SelectionHandleEfl(SelectionControllerEfl& controller, HandleType type); ~SelectionHandleEfl(); void Show(); void Hide(); @@ -54,9 +54,12 @@ class SelectionHandleEfl { HandleType Type() const { return handle_type_; } + void UpdatePosition(const gfx::Point& position); + void MoveObject(const gfx::Point& point, + bool ignore_parent_view_offset = false); + private: static void OnMouseDown(void* data, Evas*, Evas_Object*, void* event_info); - static void OnMouseMove(void* data, Evas*, Evas_Object*, void* event_info); static void OnMouseUp(void* data, Evas*, Evas_Object*, void* event_info); static void UpdateMouseMove(void* data); @@ -66,7 +69,6 @@ class SelectionHandleEfl { HandleDirection CalculateDirection(const gfx::Point&) const; void ChangeObjectDirection(HandleDirection direction); gfx::Rect GetSelectionRect() const; - void MoveObject(const gfx::Point& point, bool ignore_parent_view_offset = false); // This point is one which will be used during extending selection // it is in web view coordinates @@ -79,14 +81,6 @@ class SelectionHandleEfl { // This save the gap between the touch point and base point when OnMouseDown is called gfx::Point diff_point_; - // Saves the original handle position at the time it started - // being dragged. - gfx::Point handle_position_at_touch_down_; - - // Saves the original touch down position when a handle is grabbed. - // It is later used to calculate the movement offset. - gfx::Point touch_down_position_; - // Parent to send back mouse events SelectionControllerEfl& controller_; diff --git a/tizen_src/chromium_impl/content/browser/selection/selection_magnifier_efl.cc b/tizen_src/chromium_impl/content/browser/selection/selection_magnifier_efl.cc index a3db66be..7574dda 100644 --- a/tizen_src/chromium_impl/content/browser/selection/selection_magnifier_efl.cc +++ b/tizen_src/chromium_impl/content/browser/selection/selection_magnifier_efl.cc @@ -8,10 +8,10 @@ #include "base/files/file_path.h" #include "base/path_service.h" +#include "content/browser/renderer_host/render_widget_host_view_aura.h" #include "content/browser/selection/selection_controller_efl.h" #include "content/common/paths_efl.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/web_contents.h" namespace content { @@ -20,21 +20,15 @@ const int kHeightOffset = 60; const float kZoomScale = 0.66; SelectionMagnifierEfl::SelectionMagnifierEfl( - content::SelectionControllerEfl* controller, - content::WebContents& web_contents) - : controller_(controller), - web_contents_(web_contents), - content_image_(0), - shown_(false) { - Evas_Object* top_widget = static_cast(controller-> - GetParentView()); - + content::SelectionControllerEfl* controller) + : controller_(controller), content_image_(0), shown_(false) { base::FilePath edj_dir; base::FilePath magnifier_edj; base::PathService::Get(PathsEfl::EDJE_RESOURCE_DIR, &edj_dir); magnifier_edj = edj_dir.Append(FILE_PATH_LITERAL("Magnifier.edj")); - container_ = elm_layout_add(top_widget); + container_ = + elm_layout_add(controller_->rwhva()->offscreen_helper()->content_image()); elm_layout_file_set(container_, magnifier_edj.AsUTF8Unsafe().c_str(), "magnifier"); edje_object_part_geometry_get(elm_layout_edje_get(container_), "bg", 0, 0, &width_, &height_); } @@ -50,14 +44,12 @@ SelectionMagnifierEfl::~SelectionMagnifierEfl() { } void SelectionMagnifierEfl::HandleLongPress(const gfx::Point& touch_point) { - evas_object_event_callback_add(controller_->GetParentView(), - EVAS_CALLBACK_MOUSE_MOVE, - OnAnimatorMove, - this); - evas_object_event_callback_add(controller_->GetParentView(), - EVAS_CALLBACK_MOUSE_UP, - OnAnimatorUp, - this); + evas_object_event_callback_add( + controller_->rwhva()->offscreen_helper()->content_image(), + EVAS_CALLBACK_MOUSE_MOVE, OnAnimatorMove, this); + evas_object_event_callback_add( + controller_->rwhva()->offscreen_helper()->content_image(), + EVAS_CALLBACK_MOUSE_UP, OnAnimatorUp, this); // Call OnAnimatorMove here, so that the magnifier widget // gets properly placed. Other calls to it are expected to // happen as a react to finger/mouse movements. @@ -66,12 +58,12 @@ void SelectionMagnifierEfl::HandleLongPress(const gfx::Point& touch_point) { } void SelectionMagnifierEfl::DisconnectCallbacks() { - evas_object_event_callback_del(controller_->GetParentView(), - EVAS_CALLBACK_MOUSE_MOVE, - OnAnimatorMove); - evas_object_event_callback_del(controller_->GetParentView(), - EVAS_CALLBACK_MOUSE_UP, - OnAnimatorUp); + evas_object_event_callback_del( + controller_->rwhva()->offscreen_helper()->content_image(), + EVAS_CALLBACK_MOUSE_MOVE, OnAnimatorMove); + evas_object_event_callback_del( + controller_->rwhva()->offscreen_helper()->content_image(), + EVAS_CALLBACK_MOUSE_UP, OnAnimatorUp); } void SelectionMagnifierEfl::OnAnimatorMove(void* data, Evas*, Evas_Object*, void*) { @@ -84,9 +76,10 @@ void SelectionMagnifierEfl::OnAnimatorMove(void* data, Evas*, Evas_Object*, void void SelectionMagnifierEfl::OnAnimatorMove() { Evas_Coord_Point point; - evas_pointer_canvas_xy_get(evas_object_evas_get(controller_->GetParentView()), - &point.x, - &point.y); + evas_pointer_canvas_xy_get( + evas_object_evas_get( + controller_->rwhva()->offscreen_helper()->content_image()), + &point.x, &point.y); gfx::Point display_point(point.x, point.y); controller_->HandleLongPressMoveEvent(display_point); UpdateLocation(display_point); @@ -133,11 +126,9 @@ void SelectionMagnifierEfl::MagnifierGetSnapshotCb(Evas_Object* image, void SelectionMagnifierEfl::UpdateLocation(const gfx::Point& location) { int device_x, device_y, device_width, device_height; - evas_object_geometry_get(controller_->GetParentView(), - &device_x, - &device_y, - &device_width, - &device_height); + evas_object_geometry_get( + controller_->rwhva()->offscreen_helper()->content_image(), &device_x, + &device_y, &device_width, &device_height); int zoomedWidth = width_ * kZoomScale; int zoomedHeight = height_ * kZoomScale; @@ -177,11 +168,9 @@ void SelectionMagnifierEfl::UpdateLocation(const gfx::Point& location) { void SelectionMagnifierEfl::Move(const gfx::Point& location) { int device_x, device_y, device_width, device_height; - evas_object_geometry_get(controller_->GetParentView(), - &device_x, - &device_y, - &device_width, - &device_height); + evas_object_geometry_get( + controller_->rwhva()->offscreen_helper()->content_image(), &device_x, + &device_y, &device_width, &device_height); int magnifier_x = location.x(); int magnifier_y = location.y() - height_ - kHeightOffset; @@ -208,8 +197,11 @@ void SelectionMagnifierEfl::Show() { if (rwhv) rwhv->set_magnifier(true); #endif - if (controller_->GetParentView()) - evas_object_smart_callback_call(controller_->GetParentView(), "magnifier,show", NULL); + if (controller_->rwhva()->offscreen_helper()->ewk_view()) { + evas_object_smart_callback_call( + controller_->rwhva()->offscreen_helper()->ewk_view(), "magnifier,show", + nullptr); + } } void SelectionMagnifierEfl::Hide() { @@ -222,8 +214,11 @@ void SelectionMagnifierEfl::Hide() { if (rwhv) rwhv->set_magnifier(false); #endif - if (controller_->GetParentView()) - evas_object_smart_callback_call(controller_->GetParentView(), "magnifier,hide", NULL); + if (controller_->rwhva()->offscreen_helper()->ewk_view()) { + evas_object_smart_callback_call( + controller_->rwhva()->offscreen_helper()->ewk_view(), "magnifier,hide", + nullptr); + } } } diff --git a/tizen_src/chromium_impl/content/browser/selection/selection_magnifier_efl.h b/tizen_src/chromium_impl/content/browser/selection/selection_magnifier_efl.h index f84bff4..b80129d 100644 --- a/tizen_src/chromium_impl/content/browser/selection/selection_magnifier_efl.h +++ b/tizen_src/chromium_impl/content/browser/selection/selection_magnifier_efl.h @@ -15,12 +15,10 @@ namespace content { class SelectionControllerEfl; -class WebContents; class SelectionMagnifierEfl { public: - SelectionMagnifierEfl(content::SelectionControllerEfl* controller, - WebContents& web_contents); + SelectionMagnifierEfl(content::SelectionControllerEfl* controller); ~SelectionMagnifierEfl(); void HandleLongPress(const gfx::Point& touch_point); @@ -42,8 +40,6 @@ class SelectionMagnifierEfl { // Parent to send back mouse events SelectionControllerEfl* controller_; - WebContents& web_contents_; - // Magnifier Evas_Object* container_; diff --git a/tizen_src/chromium_impl/edje_resources/MainLayout.edc b/tizen_src/chromium_impl/edje_resources/MainLayout.edc index 3c4c1ac..d560283 100644 --- a/tizen_src/chromium_impl/edje_resources/MainLayout.edc +++ b/tizen_src/chromium_impl/edje_resources/MainLayout.edc @@ -15,6 +15,32 @@ collections { base_scale: 2.0; rel2 { relative: 1.0 1.0; } } } + part { + name: "autofill_popup"; + type: SWALLOW; + scale: 1; + description { + state: "default" 0.0; + visible: 1; + fixed: 1 1; + align: 0.0 0.0; + rel1 { relative: 0.0 0.0; to:"content";} + rel2 { relative: 1.0 1.0; to:"content";} + } + } + part { + name: "context_menu_popup"; + type: SWALLOW; + scale: 1; + description { + state: "default" 0.0; + visible: 1; + fixed: 1 1; + align: 0.0 0.0; + rel1 { relative: 0.0 0.0; to:"content";} + rel2 { relative: 1.0 1.0; to:"content";} + } + } } } } diff --git a/tizen_src/ewk/efl_integration/browser/autofill_popup_view_efl.cc b/tizen_src/ewk/efl_integration/browser/autofill_popup_view_efl.cc index 2d36be4..3a221bf 100644 --- a/tizen_src/ewk/efl_integration/browser/autofill_popup_view_efl.cc +++ b/tizen_src/ewk/efl_integration/browser/autofill_popup_view_efl.cc @@ -10,6 +10,7 @@ #include "base/strings/utf_string_conversions.h" #include "components/autofill/core/browser/ui/popup_item_ids.h" #include "content/browser/renderer_host/render_widget_host_view_aura.h" +#include "content/browser/web_contents/web_contents_impl.h" #include "content/common/paths_efl.h" #include "eweb_view.h" #include "tizen/system_info.h" @@ -41,13 +42,21 @@ AutofillPopupViewEfl::AutofillPopupViewEfl(EWebView* view) autofill_list_(nullptr), password_popup_(nullptr), selected_line_(-1) { - Evas_Object* widgetWin_ = elm_object_top_widget_get( - elm_object_parent_widget_get(view->evas_object())); - if (!widgetWin_) - widgetWin_ = view->evas_object(); - autofill_popup_ = elm_layout_add(widgetWin_); + auto native_view = + static_cast(&(webview_->web_contents())) + ->GetEflNativeView(); + if (!autofill_popup_) return; + auto smart_parent = evas_object_smart_parent_get(native_view); + if (!smart_parent) { + LOG(ERROR) << "Unable to get smart parent from native view"; + evas_object_del(autofill_popup_); + autofill_popup_ = nullptr; + return; + } + evas_object_smart_member_add(autofill_popup_, smart_parent); + elm_object_part_content_set(smart_parent, "autofill_popup", autofill_popup_); base::FilePath edj_dir; base::FilePath autofill_edj; base::PathService::Get(PathsEfl::EDJE_RESOURCE_DIR, &edj_dir); @@ -60,8 +69,10 @@ AutofillPopupViewEfl::AutofillPopupViewEfl(EWebView* view) AutofillPopupViewEfl::~AutofillPopupViewEfl() { - if (autofill_popup_) + if (autofill_popup_) { + evas_object_smart_member_del(autofill_popup_); evas_object_del(autofill_popup_); + } if (password_popup_) evas_object_del(password_popup_); } diff --git a/tizen_src/ewk/efl_integration/browser/autofill_popup_view_efl.h b/tizen_src/ewk/efl_integration/browser/autofill_popup_view_efl.h index c7b4fd1..52255e9 100644 --- a/tizen_src/ewk/efl_integration/browser/autofill_popup_view_efl.h +++ b/tizen_src/ewk/efl_integration/browser/autofill_popup_view_efl.h @@ -26,6 +26,10 @@ namespace gfx { class RectF; } +namespace content { +class WebContentsImpl; +} + namespace autofill { class AutofillPopupViewEfl { diff --git a/tizen_src/ewk/efl_integration/context_menu_controller_efl.cc b/tizen_src/ewk/efl_integration/context_menu_controller_efl.cc index ce3b6c8..4570b01 100644 --- a/tizen_src/ewk/efl_integration/context_menu_controller_efl.cc +++ b/tizen_src/ewk/efl_integration/context_menu_controller_efl.cc @@ -12,6 +12,7 @@ #include "base/strings/utf_string_conversions.h" #include "browser_context_efl.h" #include "common/web_contents_utils.h" +#include "content/browser/renderer_host/render_widget_host_view_aura.h" #include "content/browser/selection/selection_controller_efl.h" #include "content/common/paths_efl.h" #include "content/public/browser/browser_thread.h" @@ -207,16 +208,18 @@ void ContextMenuControllerEfl::GetProposedContextMenu() { params_.link_url.spec(), params_.link_url.spec()); } -#if !defined(EWK_BRINGUP) - RenderWidgetHostViewEfl* rwhv = static_cast(web_contents_.GetRenderWidgetHostView()); + RenderWidgetHostViewAura* rwhva = static_cast( + web_contents_.GetRenderWidgetHostView()); if ((params_.media_type != ContextMenuDataMediaType::kImage && !params_.selection_text.empty()) || - (params_.is_editable && (rwhv && !rwhv->IsLastAvailableTextEmpty()))) { + (params_.is_editable && + (rwhva && rwhva->offscreen_helper()->HasSelectableText()))) { AddItemToProposedList(EWK_CONTEXT_MENU_ITEM_TYPE_ACTION, EWK_CONTEXT_MENU_ITEM_TAG_SELECT_WORD, std::string(dgettext("WebKit", "IDS_WEBVIEW_OPT_SELECT_ABB"))); AddItemToProposedList(EWK_CONTEXT_MENU_ITEM_TYPE_ACTION, EWK_CONTEXT_MENU_ITEM_TAG_SELECT_ALL, std::string(dgettext("WebKit", "IDS_WEBVIEW_OPT_SELECT_ALL_ABB"))); } +#if !defined(EWK_BRINGUP) if (params_.is_draggable) { AddItemToProposedList(EWK_CONTEXT_MENU_ITEM_TYPE_ACTION, EWK_CONTEXT_MENU_ITEM_TAG_DRAG, std::string(dgettext("WebKit", "IDS_WEBVIEW_OPT_DRAG_AND_DROP"))); @@ -260,6 +263,15 @@ bool ContextMenuControllerEfl::CreateContextMenu() { if (!popup_) return false; + auto smart_parent = evas_object_smart_parent_get(native_view_); + if (!smart_parent) { + LOG(ERROR) << "Unable to get smart parent from native view"; + evas_object_del(popup_); + popup_ = nullptr; + return false; + } + evas_object_smart_member_add(popup_, smart_parent); + elm_object_part_content_set(smart_parent, "context_menu_popup", popup_); evas_object_data_set(popup_, "ContextMenuContollerEfl", this); @@ -382,8 +394,14 @@ bool ContextMenuControllerEfl::CreateContextMenu() { void ContextMenuControllerEfl::ContextMenuHWBackKey(void* data, Evas_Object* obj, void* event_info) { - ContextMenuControllerEfl* menu_controller = static_cast(data); + auto menu_controller = static_cast(data); if (menu_controller) { + auto selection_controller = + menu_controller->webview_->GetSelectionController(); + + if (selection_controller) + selection_controller->ToggleCaretAfterSelection(); + menu_controller->HideContextMenu(); evas_object_data_del(obj, "ContextEfl"); } @@ -494,16 +512,19 @@ bool ContextMenuControllerEfl::ShowContextMenu() { } web_contents_.Focus(); } else { + evas_object_smart_callback_add(popup_, "block,clicked", + BlockClickedCallback, this); + } + #if BUILDFLAG(IS_TIZEN) eext_object_event_callback_add(popup_, EEXT_CALLBACK_BACK, ContextMenuHWBackKey, this); // Workaround. After context menu shows up, there is "unfocused" event fired. // evas_object_smart_callback_add(popup_, "unfocused", ContextMenuHWBackKey, this); evas_object_focus_set(popup_, EINA_TRUE); #endif - evas_object_smart_callback_add(popup_, "block,clicked", BlockClickedCallback, this); - } - evas_object_show(popup_); - return true; + evas_object_show(popup_); + evas_object_raise(popup_); + return true; } void ContextMenuControllerEfl::HideSelectionHandle() { @@ -969,23 +990,28 @@ void ContextMenuControllerEfl::MenuItemSelected(ContextMenuItemEfl* menu_item) void ContextMenuControllerEfl::HideContextMenu() { if (popup_) { + evas_object_event_callback_del(popup_, EVAS_CALLBACK_RESIZE, + ContextMenuPopupResize); evas_object_del(popup_); - popup_ = NULL; + popup_ = nullptr; } _context_menu_resized = false; - if (menu_items_) { + if (IsMobileProfile()) { +#if !defined(EWK_BRINGUP) + context_menu_status_ = HIDDEN; +#endif + } else if (menu_items_) { void* data; EINA_LIST_FREE(menu_items_, data) { _Ewk_Context_Menu_Item *item = static_cast<_Ewk_Context_Menu_Item*> (data); delete item; } - menu_items_ = NULL; + menu_items_ = nullptr; } } - void ContextMenuControllerEfl::SetPopupSize(int width, int height) { if (save_fail_dialog_) save_fail_dialog_->SetPopupSize(width, height); @@ -1005,6 +1031,7 @@ void ContextMenuControllerEfl::DeletePopup() { if (popup_) { evas_object_data_set(popup_, "ContextMenuContollerEfl", 0); + evas_object_smart_member_del(popup_); evas_object_del(popup_); popup_ = 0; } diff --git a/tizen_src/ewk/efl_integration/eweb_view.cc b/tizen_src/ewk/efl_integration/eweb_view.cc index cfa4506..b6bc1a0 100644 --- a/tizen_src/ewk/efl_integration/eweb_view.cc +++ b/tizen_src/ewk/efl_integration/eweb_view.cc @@ -111,6 +111,10 @@ const char kReplaceWith[] = "_"; static const char* kRendererCrashedHTMLMessage = "

Renderer process has crashed!

"; +// "visible,content,changed" is an email-app specific signal which informs +// that the web view is only partially visible. +static const char* kVisibleContentChangedSignalName = "visible,content,changed"; + inline void SetDefaultStringIfNull(const char*& variable, const char* default_string) { if (!variable) { @@ -268,6 +272,15 @@ void EWebView::OnViewFocusOut(void* data, Evas*, Evas_Object*, void*) { view->SetFocus(EINA_FALSE); } +void EWebView::VisibleContentChangedCallback(void* user_data, + Evas_Object* /*object*/, + void* event_info) { + auto view = static_cast(user_data); + auto rect = static_cast(event_info); + view->GetSelectionController()->SetCustomVisibleViewRect( + gfx::Rect(rect->x, rect->y, rect->w, rect->h)); +} + EWebView::EWebView(Ewk_Context* context, Evas_Object* object) : context_(context), evas_object_(object), @@ -283,10 +296,14 @@ EWebView::EWebView(Ewk_Context* context, Evas_Object* object) y_delta_(0.0), is_initialized_(false) { if (evas_object_) { - evas_object_event_callback_add(evas_object_, EVAS_CALLBACK_FOCUS_IN, - OnViewFocusIn, this); - evas_object_event_callback_add(evas_object_, EVAS_CALLBACK_FOCUS_OUT, - OnViewFocusOut, this); + evas_object_smart_callback_add(evas_object_, + kVisibleContentChangedSignalName, + VisibleContentChangedCallback, this); + + evas_object_event_callback_add(evas_object_, EVAS_CALLBACK_FOCUS_IN, + OnViewFocusIn, this); + evas_object_event_callback_add(evas_object_, EVAS_CALLBACK_FOCUS_OUT, + OnViewFocusOut, this); } } @@ -407,6 +424,9 @@ EWebView::~EWebView() { OnViewFocusIn); evas_object_event_callback_del(evas_object_, EVAS_CALLBACK_FOCUS_OUT, OnViewFocusOut); + evas_object_smart_callback_del(evas_object_, + kVisibleContentChangedSignalName, + VisibleContentChangedCallback); } } @@ -1348,10 +1368,8 @@ void EWebView::GetScrollSize(int* width, int* height) { } void EWebView::MoveCaret(const gfx::Point& point) { -#if !defined(USE_AURA) - if (rwhv()) - rwhv()->MoveCaret(point); -#endif + if (rwhva()) + rwhva()->offscreen_helper()->MoveCaret(point); } SelectionControllerEfl* EWebView::GetSelectionController() const { @@ -1507,17 +1525,19 @@ _Ewk_Hit_Test* EWebView::RequestHitTestDataAtBlinkCoords( void EWebView::EvasToBlinkCords(int x, int y, int* view_x, int* view_y) { DCHECK(display::Screen::GetScreen()); - Evas_Coord tmpX, tmpY; - evas_object_geometry_get(evas_object_, &tmpX, &tmpY, NULL, NULL); + if (!rwhva()) + return; + + gfx::Rect view_bounds = rwhva()->offscreen_helper()->GetViewBoundsInPix(); if (view_x) { - *view_x = x - tmpX; + *view_x = x - view_bounds.x(); *view_x /= display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor(); } if (view_y) { - *view_y = y - tmpY; + *view_y = y - view_bounds.y(); *view_y /= display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor(); } diff --git a/tizen_src/ewk/efl_integration/eweb_view.h b/tizen_src/ewk/efl_integration/eweb_view.h index 27fb2af..e85a825 100644 --- a/tizen_src/ewk/efl_integration/eweb_view.h +++ b/tizen_src/ewk/efl_integration/eweb_view.h @@ -715,6 +715,9 @@ class EWebView { static void OnViewFocusIn(void* data, Evas*, Evas_Object*, void*); static void OnViewFocusOut(void* data, Evas*, Evas_Object*, void*); + static void VisibleContentChangedCallback(void* user_data, + Evas_Object* object, + void* event_info); scoped_refptr evas_event_handler_; scoped_refptr context_; -- 2.7.4