| Index: ash/autoclick/autoclick_controller.cc
|
| diff --git a/ash/autoclick/autoclick_controller.cc b/ash/autoclick/autoclick_controller.cc
|
| index b0f715d6805d4348437f396974b93b69c956a892..7779e3d924ff54dcf6f5926126fd31abfc906e95 100644
|
| --- a/ash/autoclick/autoclick_controller.cc
|
| +++ b/ash/autoclick/autoclick_controller.cc
|
| @@ -5,37 +5,22 @@
|
| #include "ash/autoclick/autoclick_controller.h"
|
|
|
| #include "ash/aura/wm_window_aura.h"
|
| +#include "ash/autoclick/common/autoclick_controller_common.h"
|
| +#include "ash/common/shell_window_ids.h"
|
| #include "ash/common/wm/root_window_finder.h"
|
| #include "ash/shell.h"
|
| #include "base/timer/timer.h"
|
| -#include "ui/aura/env.h"
|
| +#include "ui/aura/window_observer.h"
|
| #include "ui/aura/window_tree_host.h"
|
| #include "ui/events/event.h"
|
| -#include "ui/events/event_constants.h"
|
| #include "ui/events/event_handler.h"
|
| #include "ui/events/event_processor.h"
|
| #include "ui/events/event_utils.h"
|
| -#include "ui/gfx/geometry/point.h"
|
| -#include "ui/gfx/geometry/vector2d.h"
|
| +#include "ui/views/widget/widget.h"
|
| #include "ui/wm/core/coordinate_conversion.h"
|
|
|
| namespace ash {
|
|
|
| -namespace {
|
| -
|
| -// The threshold of mouse movement measured in DIP that will
|
| -// initiate a new autoclick.
|
| -const int kMovementThreshold = 20;
|
| -
|
| -bool IsModifierKey(ui::KeyboardCode key_code) {
|
| - return key_code == ui::VKEY_SHIFT || key_code == ui::VKEY_LSHIFT ||
|
| - key_code == ui::VKEY_CONTROL || key_code == ui::VKEY_LCONTROL ||
|
| - key_code == ui::VKEY_RCONTROL || key_code == ui::VKEY_MENU ||
|
| - key_code == ui::VKEY_LMENU || key_code == ui::VKEY_RMENU;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| // static.
|
| base::TimeDelta AutoclickController::GetDefaultAutoclickDelay() {
|
| return base::TimeDelta::FromMilliseconds(int64_t{kDefaultAutoclickDelayMs});
|
| @@ -44,18 +29,18 @@ base::TimeDelta AutoclickController::GetDefaultAutoclickDelay() {
|
| const int AutoclickController::kDefaultAutoclickDelayMs = 1000;
|
|
|
| class AutoclickControllerImpl : public AutoclickController,
|
| - public ui::EventHandler {
|
| + public ui::EventHandler,
|
| + public AutoclickControllerCommon::Delegate,
|
| + public aura::WindowObserver {
|
| public:
|
| AutoclickControllerImpl();
|
| ~AutoclickControllerImpl() override;
|
|
|
| private:
|
| // AutoclickController overrides:
|
| - void SetDelegate(std::unique_ptr<Delegate> delegate) override;
|
| void SetEnabled(bool enabled) override;
|
| bool IsEnabled() const override;
|
| void SetAutoclickDelay(base::TimeDelta delay) override;
|
| - base::TimeDelta GetAutoclickDelay() const override;
|
|
|
| // ui::EventHandler overrides:
|
| void OnMouseEvent(ui::MouseEvent* event) override;
|
| @@ -64,40 +49,36 @@ class AutoclickControllerImpl : public AutoclickController,
|
| void OnGestureEvent(ui::GestureEvent* event) override;
|
| void OnScrollEvent(ui::ScrollEvent* event) override;
|
|
|
| - void StartRingDisplay();
|
| - void StopRingDisplay();
|
| - void ChangeRingDisplayCenter();
|
| + // AutoclickControllerCommon::Delegate overrides:
|
| + std::unique_ptr<views::Widget> CreateAutoclickRingWidget(
|
| + const gfx::Point& event_location) override;
|
| + void UpdateAutoclickRingWidget(views::Widget* widget,
|
| + const gfx::Point& event_location) override;
|
| + void DoAutoclick(const gfx::Point& event_location,
|
| + const int mouse_event_flags) override;
|
|
|
| - void InitClickTimer();
|
| + // aura::WindowObserver overrides:
|
| + void OnWindowDestroying(aura::Window* window) override;
|
|
|
| - void DoAutoclick();
|
| + void SetTapDownTarget(aura::Window* target);
|
|
|
| bool enabled_;
|
| - base::TimeDelta delay_;
|
| - int mouse_event_flags_;
|
| - std::unique_ptr<base::Timer> autoclick_timer_;
|
| - std::unique_ptr<Delegate> delegate_;
|
| - // The position in screen coordinates used to determine
|
| - // the distance the mouse has moved.
|
| - gfx::Point anchor_location_;
|
| - gfx::Point current_mouse_location_;
|
| + // The target window is observed by AutoclickControllerImpl for the duration
|
| + // of a autoclick gesture.
|
| + aura::Window* tap_down_target_;
|
| + std::unique_ptr<AutoclickControllerCommon> autoclick_controller_common_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(AutoclickControllerImpl);
|
| };
|
|
|
| AutoclickControllerImpl::AutoclickControllerImpl()
|
| : enabled_(false),
|
| - delay_(GetDefaultAutoclickDelay()),
|
| - mouse_event_flags_(ui::EF_NONE),
|
| - delegate_(nullptr),
|
| - anchor_location_(-kMovementThreshold, -kMovementThreshold) {
|
| - InitClickTimer();
|
| -}
|
| -
|
| -AutoclickControllerImpl::~AutoclickControllerImpl() {}
|
| + tap_down_target_(nullptr),
|
| + autoclick_controller_common_(
|
| + new AutoclickControllerCommon(GetDefaultAutoclickDelay(), this)) {}
|
|
|
| -void AutoclickControllerImpl::SetDelegate(std::unique_ptr<Delegate> delegate) {
|
| - delegate_ = std::move(delegate);
|
| +AutoclickControllerImpl::~AutoclickControllerImpl() {
|
| + SetTapDownTarget(nullptr);
|
| }
|
|
|
| void AutoclickControllerImpl::SetEnabled(bool enabled) {
|
| @@ -107,7 +88,7 @@ void AutoclickControllerImpl::SetEnabled(bool enabled) {
|
|
|
| if (enabled_) {
|
| Shell::GetInstance()->AddPreTargetHandler(this);
|
| - autoclick_timer_->Stop();
|
| + autoclick_controller_common_->StopAutoclickTimer();
|
| } else {
|
| Shell::GetInstance()->RemovePreTargetHandler(this);
|
| }
|
| @@ -118,118 +99,90 @@ bool AutoclickControllerImpl::IsEnabled() const {
|
| }
|
|
|
| void AutoclickControllerImpl::SetAutoclickDelay(base::TimeDelta delay) {
|
| - delay_ = delay;
|
| - InitClickTimer();
|
| -}
|
| -
|
| -base::TimeDelta AutoclickControllerImpl::GetAutoclickDelay() const {
|
| - return delay_;
|
| -}
|
| -
|
| -void AutoclickControllerImpl::StartRingDisplay() {
|
| - if (delegate_)
|
| - delegate_->StartGesture(delay_, anchor_location_);
|
| -}
|
| -
|
| -void AutoclickControllerImpl::StopRingDisplay() {
|
| - if (delegate_)
|
| - delegate_->StopGesture();
|
| -}
|
| -
|
| -void AutoclickControllerImpl::ChangeRingDisplayCenter() {
|
| - if (delegate_)
|
| - delegate_->SetGestureCenter(current_mouse_location_);
|
| -}
|
| -
|
| -void AutoclickControllerImpl::InitClickTimer() {
|
| - autoclick_timer_.reset(new base::Timer(
|
| - FROM_HERE, delay_,
|
| - base::Bind(&AutoclickControllerImpl::DoAutoclick, base::Unretained(this)),
|
| - false));
|
| + autoclick_controller_common_->SetAutoclickDelay(delay);
|
| }
|
|
|
| void AutoclickControllerImpl::OnMouseEvent(ui::MouseEvent* event) {
|
| - if (event->type() == ui::ET_MOUSE_MOVED &&
|
| - !(event->flags() & ui::EF_IS_SYNTHESIZED)) {
|
| - mouse_event_flags_ = event->flags();
|
| -
|
| - gfx::Point mouse_location = event->location();
|
| - ::wm::ConvertPointToScreen(static_cast<aura::Window*>(event->target()),
|
| - &mouse_location);
|
| -
|
| - // The distance between the mouse location and the anchor location
|
| - // must exceed a certain threshold to initiate a new autoclick countdown.
|
| - // This ensures that mouse jitter caused by poor motor control does not
|
| - // 1. initiate an unwanted autoclick from rest
|
| - // 2. prevent the autoclick from ever occuring when the mouse
|
| - // arrives at the target.
|
| - gfx::Vector2d delta = mouse_location - anchor_location_;
|
| - if (delta.LengthSquared() >= kMovementThreshold * kMovementThreshold) {
|
| - anchor_location_ = mouse_location;
|
| - autoclick_timer_->Reset();
|
| - StartRingDisplay();
|
| - } else if (autoclick_timer_->IsRunning()) {
|
| - current_mouse_location_ = mouse_location;
|
| - ChangeRingDisplayCenter();
|
| - }
|
| - } else if (event->type() == ui::ET_MOUSE_PRESSED) {
|
| - autoclick_timer_->Stop();
|
| - StopRingDisplay();
|
| - } else if (event->type() == ui::ET_MOUSEWHEEL &&
|
| - autoclick_timer_->IsRunning()) {
|
| - autoclick_timer_->Reset();
|
| - StartRingDisplay();
|
| - }
|
| + if (event->type() == ui::ET_MOUSE_PRESSED)
|
| + SetTapDownTarget(nullptr);
|
| + autoclick_controller_common_->HandleMouseEvent(*event);
|
| }
|
|
|
| void AutoclickControllerImpl::OnKeyEvent(ui::KeyEvent* event) {
|
| - int modifier_mask = ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
|
| - ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN |
|
| - ui::EF_IS_EXTENDED_KEY;
|
| - int new_modifiers = event->flags() & modifier_mask;
|
| - mouse_event_flags_ = (mouse_event_flags_ & ~modifier_mask) | new_modifiers;
|
| -
|
| - if (!IsModifierKey(event->key_code())) {
|
| - autoclick_timer_->Stop();
|
| - StopRingDisplay();
|
| - }
|
| + if (!autoclick_controller_common_->IsModifierKey(event->key_code()))
|
| + SetTapDownTarget(nullptr);
|
| + autoclick_controller_common_->HandleKeyEvent(*event);
|
| }
|
|
|
| void AutoclickControllerImpl::OnTouchEvent(ui::TouchEvent* event) {
|
| - autoclick_timer_->Stop();
|
| - StopRingDisplay();
|
| + SetTapDownTarget(nullptr);
|
| + autoclick_controller_common_->HandleTouchEvent(*event);
|
| }
|
|
|
| void AutoclickControllerImpl::OnGestureEvent(ui::GestureEvent* event) {
|
| - autoclick_timer_->Stop();
|
| - StopRingDisplay();
|
| + SetTapDownTarget(nullptr);
|
| + autoclick_controller_common_->HandleGestureEvent(*event);
|
| }
|
|
|
| void AutoclickControllerImpl::OnScrollEvent(ui::ScrollEvent* event) {
|
| - autoclick_timer_->Stop();
|
| - StopRingDisplay();
|
| + SetTapDownTarget(nullptr);
|
| + autoclick_controller_common_->HandleScrollEvent(*event);
|
| +}
|
| +
|
| +std::unique_ptr<views::Widget>
|
| +AutoclickControllerImpl::CreateAutoclickRingWidget(
|
| + const gfx::Point& event_location) {
|
| + aura::Window* target =
|
| + WmWindowAura::GetAuraWindow(ash::wm::GetRootWindowAt(event_location));
|
| + SetTapDownTarget(target);
|
| + aura::Window* root_window = target->GetRootWindow();
|
| + std::unique_ptr<views::Widget> widget(new views::Widget);
|
| + views::Widget::InitParams params;
|
| + params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
|
| + params.accept_events = false;
|
| + params.activatable = views::Widget::InitParams::ACTIVATABLE_NO;
|
| + params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
|
| + params.context = root_window;
|
| + params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
|
| + params.parent =
|
| + Shell::GetContainer(root_window, kShellWindowId_OverlayContainer);
|
| + widget->Init(params);
|
| + widget->SetOpacity(1.f);
|
| + return widget;
|
| +}
|
| +
|
| +void AutoclickControllerImpl::UpdateAutoclickRingWidget(
|
| + views::Widget* widget,
|
| + const gfx::Point& event_location) {
|
| + aura::Window* target =
|
| + WmWindowAura::GetAuraWindow(ash::wm::GetRootWindowAt(event_location));
|
| + SetTapDownTarget(target);
|
| + aura::Window* root_window = target->GetRootWindow();
|
| + if (widget->GetNativeView()->GetRootWindow() != root_window) {
|
| + views::Widget::ReparentNativeView(
|
| + widget->GetNativeView(),
|
| + Shell::GetContainer(root_window, kShellWindowId_OverlayContainer));
|
| + }
|
| }
|
|
|
| -void AutoclickControllerImpl::DoAutoclick() {
|
| - gfx::Point screen_location = aura::Env::GetInstance()->last_mouse_location();
|
| +void AutoclickControllerImpl::DoAutoclick(const gfx::Point& event_location,
|
| + const int mouse_event_flags) {
|
| aura::Window* root_window =
|
| - WmWindowAura::GetAuraWindow(wm::GetRootWindowAt(screen_location));
|
| + WmWindowAura::GetAuraWindow(wm::GetRootWindowAt(event_location));
|
| DCHECK(root_window) << "Root window not found while attempting autoclick.";
|
|
|
| - gfx::Point click_location(screen_location);
|
| - anchor_location_ = click_location;
|
| -
|
| + gfx::Point click_location(event_location);
|
| ::wm::ConvertPointFromScreen(root_window, &click_location);
|
| aura::WindowTreeHost* host = root_window->GetHost();
|
| host->ConvertPointToHost(&click_location);
|
|
|
| ui::MouseEvent press_event(ui::ET_MOUSE_PRESSED, click_location,
|
| click_location, ui::EventTimeForNow(),
|
| - mouse_event_flags_ | ui::EF_LEFT_MOUSE_BUTTON,
|
| + mouse_event_flags | ui::EF_LEFT_MOUSE_BUTTON,
|
| ui::EF_LEFT_MOUSE_BUTTON);
|
| ui::MouseEvent release_event(ui::ET_MOUSE_RELEASED, click_location,
|
| click_location, ui::EventTimeForNow(),
|
| - mouse_event_flags_ | ui::EF_LEFT_MOUSE_BUTTON,
|
| + mouse_event_flags | ui::EF_LEFT_MOUSE_BUTTON,
|
| ui::EF_LEFT_MOUSE_BUTTON);
|
|
|
| ui::EventDispatchDetails details =
|
| @@ -240,6 +193,23 @@ void AutoclickControllerImpl::DoAutoclick() {
|
| return;
|
| }
|
|
|
| +void AutoclickControllerImpl::OnWindowDestroying(aura::Window* window) {
|
| + DCHECK_EQ(tap_down_target_, window);
|
| + autoclick_controller_common_->StopGesture();
|
| + SetTapDownTarget(nullptr);
|
| +}
|
| +
|
| +void AutoclickControllerImpl::SetTapDownTarget(aura::Window* target) {
|
| + if (tap_down_target_ == target)
|
| + return;
|
| +
|
| + if (tap_down_target_)
|
| + tap_down_target_->RemoveObserver(this);
|
| + tap_down_target_ = target;
|
| + if (tap_down_target_)
|
| + tap_down_target_->AddObserver(this);
|
| +}
|
| +
|
| // static.
|
| AutoclickController* AutoclickController::CreateInstance() {
|
| return new AutoclickControllerImpl();
|
|
|