Commit e4ea9092 authored by Thomas Lukaszewicz's avatar Thomas Lukaszewicz Committed by Commit Bot

Updated ownership semantics in TouchSelectionControllerImpl

Removed the need for set_owned_by_client() in EditingHandleView.

Fixed ownership semantics for the Widget holding EditingHandleViews
to eliminate the use of WIDGET_OWNS_NATIVE_WIDGET. Currently this
ownership model is aimed primarily at enabling easier testing and is
in the process of being removed.

Bug: 1044687
Change-Id: I51861ca2d9f2a505d86f92fe208868a562f585b0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2218502
Commit-Queue: Thomas Lukaszewicz <tluk@chromium.org>
Reviewed-by: default avatarMohsen Izadi <mohsen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#774690}
parent f8442b2d
...@@ -71,21 +71,6 @@ constexpr int kSelectionHandleBarMinHeight = 5; ...@@ -71,21 +71,6 @@ constexpr int kSelectionHandleBarMinHeight = 5;
// boundaries. // boundaries.
constexpr int kSelectionHandleBarBottomAllowance = 3; constexpr int kSelectionHandleBarBottomAllowance = 3;
// Creates a widget to host SelectionHandleView.
views::Widget* CreateTouchSelectionPopupWidget(
gfx::NativeView parent,
views::WidgetDelegate* widget_delegate) {
views::Widget* widget = new views::Widget;
views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent;
params.shadow_type = views::Widget::InitParams::ShadowType::kNone;
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.parent = parent;
params.delegate = widget_delegate;
widget->Init(std::move(params));
return widget;
}
gfx::Image* GetCenterHandleImage() { gfx::Image* GetCenterHandleImage() {
static gfx::Image* handle_image = nullptr; static gfx::Image* handle_image = nullptr;
if (!handle_image) { if (!handle_image) {
...@@ -209,8 +194,7 @@ namespace views { ...@@ -209,8 +194,7 @@ namespace views {
using EditingHandleView = TouchSelectionControllerImpl::EditingHandleView; using EditingHandleView = TouchSelectionControllerImpl::EditingHandleView;
// A View that displays the text selection handle. // A View that displays the text selection handle.
class TouchSelectionControllerImpl::EditingHandleView class TouchSelectionControllerImpl::EditingHandleView : public View {
: public WidgetDelegateView {
public: public:
EditingHandleView(TouchSelectionControllerImpl* controller, EditingHandleView(TouchSelectionControllerImpl* controller,
gfx::NativeView parent, gfx::NativeView parent,
...@@ -218,28 +202,33 @@ class TouchSelectionControllerImpl::EditingHandleView ...@@ -218,28 +202,33 @@ class TouchSelectionControllerImpl::EditingHandleView
: controller_(controller), : controller_(controller),
image_(GetCenterHandleImage()), image_(GetCenterHandleImage()),
is_cursor_handle_(is_cursor_handle), is_cursor_handle_(is_cursor_handle),
draw_invisible_(false) { draw_invisible_(false),
widget_.reset(CreateTouchSelectionPopupWidget(parent, this)); widget_(new views::Widget) {
// Create a widget to host EditingHandleView.
views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent;
params.shadow_type = views::Widget::InitParams::ShadowType::kNone;
params.parent = parent;
widget_->Init(std::move(params));
widget_->GetNativeWindow()->SetEventTargeter(
std::make_unique<aura::WindowTargeter>());
widget_->SetContentsView(this);
}
targeter_ = new aura::WindowTargeter(); EditingHandleView(const EditingHandleView&) = delete;
aura::Window* window = widget_->GetNativeWindow(); EditingHandleView& operator=(const EditingHandleView&) = delete;
window->SetEventTargeter(std::unique_ptr<aura::WindowTargeter>(targeter_)); ~EditingHandleView() override = default;
// We are owned by the TouchSelectionControllerImpl. void CloseHandleWidget() {
set_owned_by_client(); SetWidgetVisible(false);
widget_->CloseNow();
} }
~EditingHandleView() override { SetWidgetVisible(false); }
gfx::SelectionBound::Type selection_bound_type() { gfx::SelectionBound::Type selection_bound_type() {
return selection_bound_.type(); return selection_bound_.type();
} }
// WidgetDelegateView:
void DeleteDelegate() override {
// We are owned and deleted by TouchSelectionControllerImpl.
}
// View: // View:
void OnPaint(gfx::Canvas* canvas) override { void OnPaint(gfx::Canvas* canvas) override {
if (draw_invisible_) if (draw_invisible_)
...@@ -340,7 +329,10 @@ class TouchSelectionControllerImpl::EditingHandleView ...@@ -340,7 +329,10 @@ class TouchSelectionControllerImpl::EditingHandleView
const gfx::Insets insets( const gfx::Insets insets(
selection_bound_.GetHeight() + kSelectionHandleVerticalVisualOffset, 0, selection_bound_.GetHeight() + kSelectionHandleVerticalVisualOffset, 0,
0, 0); 0, 0);
targeter_->SetInsets(insets, insets);
// Shifts the hit-test target below the apparent bounds to make dragging
// easier.
widget_->GetNativeWindow()->targeter()->SetInsets(insets, insets);
} }
void SetDrawInvisible(bool draw_invisible) { void SetDrawInvisible(bool draw_invisible) {
...@@ -351,15 +343,8 @@ class TouchSelectionControllerImpl::EditingHandleView ...@@ -351,15 +343,8 @@ class TouchSelectionControllerImpl::EditingHandleView
} }
private: private:
std::unique_ptr<Widget> widget_;
TouchSelectionControllerImpl* controller_; TouchSelectionControllerImpl* controller_;
// A WindowTargeter that shifts the hit-test target below the apparent bounds
// to make dragging easier. The |widget_|'s NativeWindow takes ownership over
// the |targeter_| but since the |widget_|'s lifetime is known to this class,
// it can safely access the |targeter_|.
aura::WindowTargeter* targeter_;
// In local coordinates // In local coordinates
gfx::SelectionBound selection_bound_; gfx::SelectionBound selection_bound_;
gfx::Image* image_; gfx::Image* image_;
...@@ -379,7 +364,8 @@ class TouchSelectionControllerImpl::EditingHandleView ...@@ -379,7 +364,8 @@ class TouchSelectionControllerImpl::EditingHandleView
// handle. // handle.
bool draw_invisible_; bool draw_invisible_;
DISALLOW_COPY_AND_ASSIGN(EditingHandleView); // Owning widget.
Widget* widget_ = nullptr;
}; };
TouchSelectionControllerImpl::TouchSelectionControllerImpl( TouchSelectionControllerImpl::TouchSelectionControllerImpl(
...@@ -412,6 +398,10 @@ TouchSelectionControllerImpl::~TouchSelectionControllerImpl() { ...@@ -412,6 +398,10 @@ TouchSelectionControllerImpl::~TouchSelectionControllerImpl() {
aura::Env::GetInstance()->RemoveEventObserver(this); aura::Env::GetInstance()->RemoveEventObserver(this);
if (client_widget_) if (client_widget_)
client_widget_->RemoveObserver(this); client_widget_->RemoveObserver(this);
// Close the owning Widgets to clean up the EditingHandleViews.
selection_handle_1_->CloseHandleWidget();
selection_handle_2_->CloseHandleWidget();
cursor_handle_->CloseHandleWidget();
} }
void TouchSelectionControllerImpl::SelectionChanged() { void TouchSelectionControllerImpl::SelectionChanged() {
...@@ -466,11 +456,11 @@ void TouchSelectionControllerImpl::SelectionChanged() { ...@@ -466,11 +456,11 @@ void TouchSelectionControllerImpl::SelectionChanged() {
// TODO(varunjain): Fix this: crbug.com/269003 // TODO(varunjain): Fix this: crbug.com/269003
dragging_handle_->SetDrawInvisible(!ShouldShowHandleFor(focus)); dragging_handle_->SetDrawInvisible(!ShouldShowHandleFor(focus));
if (dragging_handle_ != cursor_handle_.get()) { if (dragging_handle_ != cursor_handle_) {
// The non-dragging-handle might have recently become visible. // The non-dragging-handle might have recently become visible.
EditingHandleView* non_dragging_handle = selection_handle_1_.get(); EditingHandleView* non_dragging_handle = selection_handle_1_;
if (dragging_handle_ == selection_handle_1_.get()) { if (dragging_handle_ == selection_handle_1_) {
non_dragging_handle = selection_handle_2_.get(); non_dragging_handle = selection_handle_2_;
// if handle 1 is being dragged, it is corresponding to the end of // if handle 1 is being dragged, it is corresponding to the end of
// selection and the other handle to the start of selection. // selection and the other handle to the start of selection.
selection_bound_1_ = screen_bound_focus; selection_bound_1_ = screen_bound_focus;
...@@ -488,15 +478,13 @@ void TouchSelectionControllerImpl::SelectionChanged() { ...@@ -488,15 +478,13 @@ void TouchSelectionControllerImpl::SelectionChanged() {
screen_bound_anchor.edge_end() == screen_bound_focus.edge_end()) { screen_bound_anchor.edge_end() == screen_bound_focus.edge_end()) {
selection_handle_1_->SetWidgetVisible(false); selection_handle_1_->SetWidgetVisible(false);
selection_handle_2_->SetWidgetVisible(false); selection_handle_2_->SetWidgetVisible(false);
SetHandleBound(cursor_handle_.get(), anchor, screen_bound_anchor_clipped); SetHandleBound(cursor_handle_, anchor, screen_bound_anchor_clipped);
return; return;
} }
cursor_handle_->SetWidgetVisible(false); cursor_handle_->SetWidgetVisible(false);
SetHandleBound(selection_handle_1_.get(), anchor, SetHandleBound(selection_handle_1_, anchor, screen_bound_anchor_clipped);
screen_bound_anchor_clipped); SetHandleBound(selection_handle_2_, focus, screen_bound_focus_clipped);
SetHandleBound(selection_handle_2_.get(), focus,
screen_bound_focus_clipped);
} }
} }
...@@ -522,15 +510,15 @@ void TouchSelectionControllerImpl::SelectionHandleDragged( ...@@ -522,15 +510,15 @@ void TouchSelectionControllerImpl::SelectionHandleDragged(
gfx::Point drag_pos_in_client = drag_pos; gfx::Point drag_pos_in_client = drag_pos;
ConvertPointToClientView(dragging_handle_, &drag_pos_in_client); ConvertPointToClientView(dragging_handle_, &drag_pos_in_client);
if (dragging_handle_ == cursor_handle_.get()) { if (dragging_handle_ == cursor_handle_) {
client_view_->MoveCaretTo(drag_pos_in_client); client_view_->MoveCaretTo(drag_pos_in_client);
return; return;
} }
// Find the stationary selection handle. // Find the stationary selection handle.
gfx::SelectionBound anchor_bound = gfx::SelectionBound anchor_bound = selection_handle_1_ == dragging_handle_
selection_handle_1_.get() == dragging_handle_ ? selection_bound_2_ ? selection_bound_2_
: selection_bound_1_; : selection_bound_1_;
// Find selection end points in client_view's coordinate system. // Find selection end points in client_view's coordinate system.
gfx::Point p2 = anchor_bound.edge_start_rounded(); gfx::Point p2 = anchor_bound.edge_start_rounded();
...@@ -729,12 +717,12 @@ gfx::Rect TouchSelectionControllerImpl::GetExpectedHandleBounds( ...@@ -729,12 +717,12 @@ gfx::Rect TouchSelectionControllerImpl::GetExpectedHandleBounds(
return GetSelectionWidgetBounds(bound); return GetSelectionWidgetBounds(bound);
} }
WidgetDelegateView* TouchSelectionControllerImpl::GetHandle1View() { View* TouchSelectionControllerImpl::GetHandle1View() {
return selection_handle_1_.get(); return selection_handle_1_;
} }
WidgetDelegateView* TouchSelectionControllerImpl::GetHandle2View() { View* TouchSelectionControllerImpl::GetHandle2View() {
return selection_handle_2_.get(); return selection_handle_2_;
} }
} // namespace views } // namespace views
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include "ui/views/widget/widget_observer.h" #include "ui/views/widget/widget_observer.h"
namespace views { namespace views {
class WidgetDelegateView;
// Touch specific implementation of TouchEditingControllerDeprecated. // Touch specific implementation of TouchEditingControllerDeprecated.
// Responsible for displaying selection handles and menu elements relevant in a // Responsible for displaying selection handles and menu elements relevant in a
...@@ -34,6 +33,9 @@ class VIEWS_EXPORT TouchSelectionControllerImpl ...@@ -34,6 +33,9 @@ class VIEWS_EXPORT TouchSelectionControllerImpl
// Use ui::TouchEditingControllerFactory::Create() instead. // Use ui::TouchEditingControllerFactory::Create() instead.
explicit TouchSelectionControllerImpl(ui::TouchEditable* client_view); explicit TouchSelectionControllerImpl(ui::TouchEditable* client_view);
TouchSelectionControllerImpl(const TouchSelectionControllerImpl&) = delete;
TouchSelectionControllerImpl& operator=(const TouchSelectionControllerImpl&) =
delete;
~TouchSelectionControllerImpl() override; ~TouchSelectionControllerImpl() override;
// ui::TouchEditingControllerDeprecated: // ui::TouchEditingControllerDeprecated:
...@@ -106,14 +108,16 @@ class VIEWS_EXPORT TouchSelectionControllerImpl ...@@ -106,14 +108,16 @@ class VIEWS_EXPORT TouchSelectionControllerImpl
bool IsSelectionHandle2Visible(); bool IsSelectionHandle2Visible();
bool IsCursorHandleVisible(); bool IsCursorHandleVisible();
gfx::Rect GetExpectedHandleBounds(const gfx::SelectionBound& bound); gfx::Rect GetExpectedHandleBounds(const gfx::SelectionBound& bound);
WidgetDelegateView* GetHandle1View(); View* GetHandle1View();
WidgetDelegateView* GetHandle2View(); View* GetHandle2View();
ui::TouchEditable* client_view_; ui::TouchEditable* client_view_;
Widget* client_widget_ = nullptr; Widget* client_widget_ = nullptr;
std::unique_ptr<EditingHandleView> selection_handle_1_; // Non-owning pointers to EditingHandleViews. These views are owned by their
std::unique_ptr<EditingHandleView> selection_handle_2_; // Widget and cleaned up when their Widget closes.
std::unique_ptr<EditingHandleView> cursor_handle_; EditingHandleView* selection_handle_1_;
EditingHandleView* selection_handle_2_;
EditingHandleView* cursor_handle_;
bool command_executed_ = false; bool command_executed_ = false;
base::TimeTicks selection_start_time_; base::TimeTicks selection_start_time_;
...@@ -136,8 +140,6 @@ class VIEWS_EXPORT TouchSelectionControllerImpl ...@@ -136,8 +140,6 @@ class VIEWS_EXPORT TouchSelectionControllerImpl
// Selection bounds, clipped to client view's boundaries. // Selection bounds, clipped to client view's boundaries.
gfx::SelectionBound selection_bound_1_clipped_; gfx::SelectionBound selection_bound_1_clipped_;
gfx::SelectionBound selection_bound_2_clipped_; gfx::SelectionBound selection_bound_2_clipped_;
DISALLOW_COPY_AND_ASSIGN(TouchSelectionControllerImpl);
}; };
} // namespace views } // namespace views
......
...@@ -147,7 +147,7 @@ class TouchSelectionControllerImplTest : public ViewsTestBase { ...@@ -147,7 +147,7 @@ class TouchSelectionControllerImplTest : public ViewsTestBase {
void SimulateSelectionHandleDrag(gfx::Vector2d v, int selection_handle) { void SimulateSelectionHandleDrag(gfx::Vector2d v, int selection_handle) {
TouchSelectionControllerImpl* controller = GetSelectionController(); TouchSelectionControllerImpl* controller = GetSelectionController();
views::WidgetDelegateView* handle = nullptr; views::View* handle = nullptr;
if (selection_handle == 1) if (selection_handle == 1)
handle = controller->GetHandle1View(); handle = controller->GetHandle1View();
else else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment