blob: 7b5620bb1cfe42aab0a93b77c51fa2d5845616d1 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/components/fast_ink/fast_ink_pointer_controller.h"
#include "ui/aura/window.h"
#include "ui/display/screen.h"
#include "ui/events/base_event_utils.h"
#include "ui/views/widget/widget.h"
namespace fast_ink {
namespace {
// The amount of time used to estimate time from VSYNC event to when
// visible light can be noticed by the user.
const int kPresentationDelayMs = 18;
} // namespace
FastInkPointerController::FastInkPointerController()
: presentation_delay_(
base::TimeDelta::FromMilliseconds(kPresentationDelayMs)) {}
FastInkPointerController::~FastInkPointerController() {}
void FastInkPointerController::SetEnabled(bool enabled) {
enabled_ = enabled;
// Not calling DestroyPointerView when disabling, leaving the control over
// the pointer view lifetime to the specific controller implementation.
// For instance, a controller might prefer to keep the pointer view around
// while it is being animated away.
}
bool FastInkPointerController::CanStartNewGesture(ui::TouchEvent* event) {
// 1) The stylus is pressed
// 2) The stylus is moving, but the pointer session has not started yet
// (most likely because the preceding press event was consumed by another
// handler).
return (event->type() == ui::ET_TOUCH_PRESSED ||
(event->type() == ui::ET_TOUCH_MOVED && !GetPointerView()));
}
void FastInkPointerController::OnTouchEvent(ui::TouchEvent* event) {
if (!enabled_)
return;
if (event->pointer_details().pointer_type !=
ui::EventPointerType::POINTER_TYPE_PEN)
return;
if (event->type() != ui::ET_TOUCH_MOVED &&
event->type() != ui::ET_TOUCH_PRESSED &&
event->type() != ui::ET_TOUCH_RELEASED)
return;
// Find the root window that the event was captured on. We never need to
// switch between different root windows because it is not physically possible
// to seamlessly drag a stylus between two displays like it is with a mouse.
aura::Window* root_window =
static_cast<aura::Window*>(event->target())->GetRootWindow();
if (CanStartNewGesture(event)) {
DestroyPointerView();
CreatePointerView(presentation_delay_, root_window);
} else {
views::View* pointer_view = GetPointerView();
if (!pointer_view)
return;
views::Widget* widget = pointer_view->GetWidget();
if (widget->IsClosed() ||
widget->GetNativeWindow()->GetRootWindow() != root_window) {
// The pointer widget is no longer valid, end the current pointer session.
DestroyPointerView();
return;
}
}
UpdatePointerView(event);
event->StopPropagation();
}
} // namespace fast_ink