Commit ff7eba83 authored by chinsenj's avatar chinsenj Committed by Commit Bot

cros: Add touch selection to window cycle list (alt+tab).

As an ongoing effort to make the window cycle list more interactive,
this CL makes it so users can select and confirm a selection by tapping
a preview item in the window cycle list.

Test: InteractiveWindowCycleControllerTest.TapSelect
Bug: 1067327
Change-Id: Ice8cbcfe0e1886a15169f50eaf3172e96acb03e7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2367497
Commit-Queue: Jeremy Chinsen <chinsenj@chromium.org>
Reviewed-by: default avatarXiaoqian Dai <xdai@chromium.org>
Cr-Commit-Position: refs/heads/master@{#801625}
parent 627a9bf4
......@@ -129,7 +129,7 @@ void WindowCycleController::StepToWindow(aura::Window* window) {
window_cycle_list_->StepToWindow(window);
}
bool WindowCycleController::IsEventInCycleView(ui::MouseEvent* event) {
bool WindowCycleController::IsEventInCycleView(ui::LocatedEvent* event) {
return window_cycle_list_ && window_cycle_list_->IsEventInCycleView(event);
}
......
......@@ -17,7 +17,7 @@ class Window;
}
namespace ui {
class MouseEvent;
class LocatedEvent;
}
namespace ash {
......@@ -64,7 +64,7 @@ class ASH_EXPORT WindowCycleController {
void StepToWindow(aura::Window* window);
// Checks whether |event| occurs within the cycle view.
bool IsEventInCycleView(ui::MouseEvent* event);
bool IsEventInCycleView(ui::LocatedEvent* event);
// Returns the WindowCycleList.
const WindowCycleList* window_cycle_list() const {
......
......@@ -973,6 +973,30 @@ TEST_F(InteractiveWindowCycleControllerTest, KeysConfirmSelection) {
EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
}
// When a user taps on an item, it should cycle to it, complete cycling and
// activate the tapped item.
TEST_F(InteractiveWindowCycleControllerTest, TapSelect) {
std::unique_ptr<Window> w0 = CreateTestWindow();
std::unique_ptr<Window> w1 = CreateTestWindow();
std::unique_ptr<Window> w2 = CreateTestWindow();
ui::test::EventGenerator* generator = GetEventGenerator();
WindowCycleController* controller = Shell::Get()->window_cycle_controller();
// Start cycle and tap third item.
// Starting order of windows in cycle list is [2,1,0].
controller->StartCycling();
generator->GestureTapAt(
GetWindowCycleItemViews()[2]->GetBoundsInScreen().CenterPoint());
EXPECT_TRUE(wm::IsActiveWindow(w0.get()));
// Start cycle and tap second item.
// Starting order of windows in cycle list is [0,2,1].
controller->StartCycling();
generator->GestureTapAt(
GetWindowCycleItemViews()[1]->GetBoundsInScreen().CenterPoint());
EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
}
// Tests that frame throttling starts and ends accordingly when window cycling
// starts and ends.
TEST_F(WindowCycleControllerTest, FrameThrottling) {
......
......@@ -117,6 +117,25 @@ void WindowCycleEventFilter::OnMouseEvent(ui::MouseEvent* event) {
}
}
void WindowCycleEventFilter::OnGestureEvent(ui::GestureEvent* event) {
if (features::IsInteractiveWindowCycleListEnabled() &&
Shell::Get()->window_cycle_controller()->IsEventInCycleView(event)) {
return;
}
// Prevent any form of tap from doing anything while the Alt+Tab UI is active.
if (event->type() == ui::ET_GESTURE_TAP ||
event->type() == ui::ET_GESTURE_DOUBLE_TAP ||
event->type() == ui::ET_GESTURE_TAP_CANCEL ||
event->type() == ui::ET_GESTURE_TAP_DOWN ||
event->type() == ui::ET_GESTURE_TAP_UNCONFIRMED ||
event->type() == ui::ET_GESTURE_TWO_FINGER_TAP ||
event->type() == ui::ET_GESTURE_LONG_PRESS ||
event->type() == ui::ET_GESTURE_LONG_TAP) {
event->StopPropagation();
}
}
WindowCycleEventFilter::AltReleaseHandler::AltReleaseHandler() = default;
WindowCycleEventFilter::AltReleaseHandler::~AltReleaseHandler() = default;
......
......@@ -24,6 +24,7 @@ class ASH_EXPORT WindowCycleEventFilter : public ui::EventHandler {
// Overridden from ui::EventHandler:
void OnKeyEvent(ui::KeyEvent* event) override;
void OnMouseEvent(ui::MouseEvent* event) override;
void OnGestureEvent(ui::GestureEvent* event) override;
private:
class AltReleaseHandler : public ui::EventHandler {
......
......@@ -11,6 +11,7 @@
#include "ash/accessibility/accessibility_controller_impl.h"
#include "ash/app_list/app_list_controller_impl.h"
#include "ash/frame_throttler/frame_throttling_controller.h"
#include "ash/public/cpp/ash_features.h"
#include "ash/public/cpp/metrics_util.h"
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/public/cpp/window_properties.h"
......@@ -38,6 +39,7 @@
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
#include "ui/wm/core/window_animations.h"
#include "ui/wm/core/coordinate_conversion.h"
namespace ash {
......@@ -147,6 +149,23 @@ class WindowCycleItemView : public WindowMiniView {
return true;
}
void OnGestureEvent(ui::GestureEvent* event) override {
switch (event->type()) {
case ui::ET_GESTURE_TAP:
case ui::ET_GESTURE_LONG_PRESS:
case ui::ET_GESTURE_LONG_TAP:
case ui::ET_GESTURE_TWO_FINGER_TAP: {
WindowCycleController* controller =
Shell::Get()->window_cycle_controller();
controller->StepToWindow(source_window());
controller->CompleteCycling();
break;
}
default:
break;
}
}
private:
// WindowMiniView:
gfx::Size GetPreviewViewSize() const override {
......@@ -545,9 +564,12 @@ void WindowCycleList::StepToWindow(aura::Window* window) {
Step(target_index - current_index_);
}
bool WindowCycleList::IsEventInCycleView(ui::MouseEvent* event) {
return cycle_view_->GetBoundsInScreen().Contains(
display::Screen::GetScreen()->GetCursorScreenPoint());
bool WindowCycleList::IsEventInCycleView(ui::LocatedEvent* event) {
aura::Window* target = static_cast<aura::Window*>(event->target());
aura::Window* event_root = target->GetRootWindow();
gfx::Point event_screen_point = event->root_location();
wm::ConvertPointToScreen(event_root, &event_screen_point);
return cycle_view_->GetBoundsInScreen().Contains(event_screen_point);
}
// static
......
......@@ -49,7 +49,7 @@ class ASH_EXPORT WindowCycleList : public aura::WindowObserver,
void StepToWindow(aura::Window* window);
// Checks whether |event| occurs within the cycle view.
bool IsEventInCycleView(ui::MouseEvent* event);
bool IsEventInCycleView(ui::LocatedEvent* event);
void set_user_did_accept(bool user_did_accept) {
user_did_accept_ = user_did_accept;
......
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