Commit acb5a6e0 authored by Mike Wasserman's avatar Mike Wasserman Committed by Commit Bot

mash: Make TouchSelectionControllerClientAura use ui::EventObserver

Close touch selection ui in Mash on events outside the browser window.
(global pre-target handlers are not supported in window service clients)
This follows and refines the new pattern in TouchSelectionControllerImpl.

Bug: 896973, 884394
Test: Text touch selection ui hides as expected in Views and Content.
Change-Id: Iedba63a7ce5d5f70f9763cf540d26ee69cee5f28
Reviewed-on: https://chromium-review.googlesource.com/c/1292274
Commit-Queue: Michael Wasserman <msw@chromium.org>
Reviewed-by: default avatarDave Tapuska <dtapuska@chromium.org>
Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Cr-Commit-Position: refs/heads/master@{#602084}
parent bdc6f771
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "ui/aura/env.h" #include "ui/aura/env.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/base/clipboard/clipboard.h" #include "ui/base/clipboard/clipboard.h"
#include "ui/events/event_observer.h"
#include "ui/gfx/geometry/point_conversions.h" #include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/geometry/size_conversions.h" #include "ui/gfx/geometry/size_conversions.h"
#include "ui/strings/grit/ui_strings.h" #include "ui/strings/grit/ui_strings.h"
...@@ -47,78 +48,58 @@ gfx::Rect ConvertRectToScreen(aura::Window* window, const gfx::RectF& rect) { ...@@ -47,78 +48,58 @@ gfx::Rect ConvertRectToScreen(aura::Window* window, const gfx::RectF& rect) {
} // namespace } // namespace
// A pre-target event handler for aura::Env which deactivates touch selection on // An aura::Env event observer that hides touch selection ui on mouse and
// mouse and keyboard events. // keyboard events, including those targeting windows outside the client.
class TouchSelectionControllerClientAura::EnvPreTargetHandler class TouchSelectionControllerClientAura::EnvEventObserver
: public ui::EventHandler { : public ui::EventObserver {
public: public:
EnvPreTargetHandler(ui::TouchSelectionController* selection_controller, EnvEventObserver(ui::TouchSelectionController* selection_controller,
aura::Window* window);
~EnvPreTargetHandler() override;
private:
// EventHandler:
void OnKeyEvent(ui::KeyEvent* event) override;
void OnMouseEvent(ui::MouseEvent* event) override;
void OnScrollEvent(ui::ScrollEvent* event) override;
ui::TouchSelectionController* selection_controller_;
aura::Window* window_;
DISALLOW_COPY_AND_ASSIGN(EnvPreTargetHandler);
};
TouchSelectionControllerClientAura::EnvPreTargetHandler::EnvPreTargetHandler(
ui::TouchSelectionController* selection_controller,
aura::Window* window) aura::Window* window)
: selection_controller_(selection_controller), window_(window) { : selection_controller_(selection_controller), window_(window) {
aura::Env::GetInstance()->AddPreTargetHandler(this); // Observe certain event types sent to any event target, to hide this ui.
} aura::Env* env = aura::Env::GetInstance();
std::set<ui::EventType> types = {ui::ET_MOUSE_PRESSED, ui::ET_MOUSE_MOVED,
TouchSelectionControllerClientAura::EnvPreTargetHandler:: ui::ET_KEY_PRESSED, ui::ET_MOUSEWHEEL};
~EnvPreTargetHandler() { env->AddEventObserver(this, env, types);
aura::Env::GetInstance()->RemovePreTargetHandler(this); }
}
void TouchSelectionControllerClientAura::EnvPreTargetHandler::OnKeyEvent(
ui::KeyEvent* event) {
DCHECK_NE(ui::TouchSelectionController::INACTIVE,
selection_controller_->active_status());
selection_controller_->HideAndDisallowShowingAutomatically(); ~EnvEventObserver() override {
} aura::Env::GetInstance()->RemoveEventObserver(this);
}
void TouchSelectionControllerClientAura::EnvPreTargetHandler::OnMouseEvent( private:
ui::MouseEvent* event) { // ui::EventObserver:
void OnEvent(const ui::Event& event) override {
DCHECK_NE(ui::TouchSelectionController::INACTIVE, DCHECK_NE(ui::TouchSelectionController::INACTIVE,
selection_controller_->active_status()); selection_controller_->active_status());
// Avoid adjusting the handles on synthesized or events if (event.IsMouseEvent()) {
// generated from touch as this can clear an active selection // Check IsMouseEventsEnabled, except on Mus, where it's disabled on touch
// generated by the pen. // events in this client, but not re-enabled on mouse events elsewhere.
if (event->flags() & (ui::EF_IS_SYNTHESIZED | ui::EF_FROM_TOUCH)) auto* cursor = aura::client::GetCursorClient(window_->GetRootWindow());
if (cursor && !cursor->IsMouseEventsEnabled() &&
aura::Env::GetInstance()->mode() != aura::Env::Mode::MUS) {
return; return;
}
// Don't hide handles for pen input. // Windows OS unhandled WM_POINTER* may be redispatched as WM_MOUSE*.
if (event->pointer_details().pointer_type == // Avoid adjusting the handles on synthesized events or events generated
ui::EventPointerType::POINTER_TYPE_PEN) // from touch as this can clear an active selection generated by the pen.
if ((event.flags() & (ui::EF_IS_SYNTHESIZED | ui::EF_FROM_TOUCH)) ||
event.AsMouseEvent()->pointer_details().pointer_type ==
ui::EventPointerType::POINTER_TYPE_PEN) {
return; return;
}
}
// If mouse events are not enabled, this mouse event is synthesized from a
// touch event in which case we don't want to deactivate touch selection.
aura::client::CursorClient* cursor_client =
aura::client::GetCursorClient(window_->GetRootWindow());
if (!cursor_client || cursor_client->IsMouseEventsEnabled())
selection_controller_->HideAndDisallowShowingAutomatically(); selection_controller_->HideAndDisallowShowingAutomatically();
} }
void TouchSelectionControllerClientAura::EnvPreTargetHandler::OnScrollEvent( ui::TouchSelectionController* selection_controller_;
ui::ScrollEvent* event) { aura::Window* window_;
DCHECK_NE(ui::TouchSelectionController::INACTIVE,
selection_controller_->active_status());
selection_controller_->HideAndDisallowShowingAutomatically(); DISALLOW_COPY_AND_ASSIGN(EnvEventObserver);
} };
TouchSelectionControllerClientAura::TouchSelectionControllerClientAura( TouchSelectionControllerClientAura::TouchSelectionControllerClientAura(
RenderWidgetHostViewAura* rwhva) RenderWidgetHostViewAura* rwhva)
...@@ -382,12 +363,12 @@ void TouchSelectionControllerClientAura::OnSelectionEvent( ...@@ -382,12 +363,12 @@ void TouchSelectionControllerClientAura::OnSelectionEvent(
FALLTHROUGH; FALLTHROUGH;
case ui::INSERTION_HANDLE_SHOWN: case ui::INSERTION_HANDLE_SHOWN:
UpdateQuickMenu(); UpdateQuickMenu();
env_pre_target_handler_.reset(new EnvPreTargetHandler( env_event_observer_ = std::make_unique<EnvEventObserver>(
rwhva_->selection_controller(), rwhva_->GetNativeView())); rwhva_->selection_controller(), rwhva_->GetNativeView());
break; break;
case ui::SELECTION_HANDLES_CLEARED: case ui::SELECTION_HANDLES_CLEARED:
case ui::INSERTION_HANDLE_CLEARED: case ui::INSERTION_HANDLE_CLEARED:
env_pre_target_handler_.reset(); env_event_observer_.reset();
quick_menu_requested_ = false; quick_menu_requested_ = false;
UpdateQuickMenu(); UpdateQuickMenu();
break; break;
......
...@@ -70,7 +70,7 @@ class CONTENT_EXPORT TouchSelectionControllerClientAura ...@@ -70,7 +70,7 @@ class CONTENT_EXPORT TouchSelectionControllerClientAura
private: private:
friend class TestTouchSelectionControllerClientAura; friend class TestTouchSelectionControllerClientAura;
class EnvPreTargetHandler; class EnvEventObserver;
bool IsQuickMenuAvailable() const; bool IsQuickMenuAvailable() const;
void ShowQuickMenu(); void ShowQuickMenu();
...@@ -133,9 +133,8 @@ class CONTENT_EXPORT TouchSelectionControllerClientAura ...@@ -133,9 +133,8 @@ class CONTENT_EXPORT TouchSelectionControllerClientAura
bool show_quick_menu_immediately_for_test_; bool show_quick_menu_immediately_for_test_;
// A pre-target event handler for aura::Env which deactivates touch selection // An event observer that deactivates touch selection on certain input events.
// on mouse and keyboard events. std::unique_ptr<EnvEventObserver> env_event_observer_;
std::unique_ptr<EnvPreTargetHandler> env_pre_target_handler_;
DISALLOW_COPY_AND_ASSIGN(TouchSelectionControllerClientAura); DISALLOW_COPY_AND_ASSIGN(TouchSelectionControllerClientAura);
}; };
......
...@@ -418,7 +418,7 @@ TouchSelectionControllerImpl::TouchSelectionControllerImpl( ...@@ -418,7 +418,7 @@ TouchSelectionControllerImpl::TouchSelectionControllerImpl(
if (client_widget_) if (client_widget_)
client_widget_->AddObserver(this); client_widget_->AddObserver(this);
// Observe certain event types sent to other event targets, to hide this ui. // Observe certain event types sent to any event target, to hide this ui.
aura::Env* env = aura::Env::GetInstance(); aura::Env* env = aura::Env::GetInstance();
std::set<ui::EventType> types = {ui::ET_MOUSE_PRESSED, ui::ET_MOUSE_MOVED, std::set<ui::EventType> types = {ui::ET_MOUSE_PRESSED, ui::ET_MOUSE_MOVED,
ui::ET_KEY_PRESSED, ui::ET_MOUSEWHEEL}; ui::ET_KEY_PRESSED, ui::ET_MOUSEWHEEL};
...@@ -628,22 +628,27 @@ void TouchSelectionControllerImpl::OnWidgetBoundsChanged( ...@@ -628,22 +628,27 @@ void TouchSelectionControllerImpl::OnWidgetBoundsChanged(
} }
void TouchSelectionControllerImpl::OnEvent(const ui::Event& event) { void TouchSelectionControllerImpl::OnEvent(const ui::Event& event) {
if (event.IsKeyEvent() || event.IsScrollEvent()) {
client_view_->DestroyTouchSelection();
return;
}
if (event.IsMouseEvent()) { if (event.IsMouseEvent()) {
aura::client::CursorClient* cursor_client = aura::client::GetCursorClient( // Check IsMouseEventsEnabled, except on Mus, where it's disabled on touch
// events in this client, but not re-enabled on mouse events elsewhere.
auto* cursor = aura::client::GetCursorClient(
client_view_->GetNativeView()->GetRootWindow()); client_view_->GetNativeView()->GetRootWindow());
// Disregard IsMouseEventsEnabled on Mus, it is disabled on touch events in if (cursor && !cursor->IsMouseEventsEnabled() &&
// this client, but not re-enabled when mouse events are sent elsewhere. aura::Env::GetInstance()->mode() != aura::Env::Mode::MUS) {
if ((cursor_client && cursor_client->IsMouseEventsEnabled()) || return;
aura::Env::GetInstance()->mode() == aura::Env::Mode::MUS) {
client_view_->DestroyTouchSelection();
} }
// Windows OS unhandled WM_POINTER* may be redispatched as WM_MOUSE*.
// Avoid adjusting the handles on synthesized events or events generated
// from touch as this can clear an active selection generated by the pen.
if ((event.flags() & (ui::EF_IS_SYNTHESIZED | ui::EF_FROM_TOUCH)) ||
event.AsMouseEvent()->pointer_details().pointer_type ==
ui::EventPointerType::POINTER_TYPE_PEN) {
return; return;
} }
}
client_view_->DestroyTouchSelection();
} }
void TouchSelectionControllerImpl::QuickMenuTimerFired() { void TouchSelectionControllerImpl::QuickMenuTimerFired() {
......
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