1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
ash / wm / window_cycle / window_cycle_event_filter.h [blame]
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_WM_WINDOW_CYCLE_WINDOW_CYCLE_EVENT_FILTER_H_
#define ASH_WM_WINDOW_CYCLE_WINDOW_CYCLE_EVENT_FILTER_H_
#include <optional>
#include "ash/ash_export.h"
#include "ash/wm/window_cycle/window_cycle_controller.h"
#include "base/memory/raw_ptr.h"
#include "base/timer/timer.h"
#include "ui/events/event_handler.h"
#include "ui/gfx/geometry/point.h"
namespace ui {
class GestureEvent;
class KeyEvent;
class MouseEvent;
class ScrollEvent;
} // namespace ui
namespace ash {
// Created by WindowCycleController when cycling through windows. Eats all key
// events and stops cycling when the necessary key sequence is encountered.
// Also allows users to cycle using right/left keys.
class ASH_EXPORT WindowCycleEventFilter : public ui::EventHandler {
public:
// The threshold of performing an action with a touchpad or mouse wheel
// scroll.
static constexpr float kHorizontalThresholdDp = 330.f;
WindowCycleEventFilter();
WindowCycleEventFilter(const WindowCycleEventFilter&) = delete;
WindowCycleEventFilter& operator=(const WindowCycleEventFilter&) = delete;
~WindowCycleEventFilter() override;
// Overridden from ui::EventHandler:
void OnKeyEvent(ui::KeyEvent* event) override;
void OnMouseEvent(ui::MouseEvent* event) override;
void OnScrollEvent(ui::ScrollEvent* event) override;
void OnGestureEvent(ui::GestureEvent* event) override;
private:
// A struct containing the relevant data during a scroll session.
struct ScrollData {
int finger_count = 0;
// Values are cumulative (ex. |scroll_x| is the total x distance moved
// since the scroll began.
float scroll_x = 0.f;
float scroll_y = 0.f;
};
class AltReleaseHandler : public ui::EventHandler {
public:
AltReleaseHandler();
AltReleaseHandler(const AltReleaseHandler&) = delete;
AltReleaseHandler& operator=(const AltReleaseHandler&) = delete;
~AltReleaseHandler() override;
// ui::EventHandler:
void OnKeyEvent(ui::KeyEvent* event) override;
};
// Depending on the values of |event| either repeatedly cycle through windows,
// stop repeatedly cycling through windows, or cycle once.
void HandleTriggerKey(ui::KeyEvent* event);
// Returns whether the window cycle should repeatedly cycle in the
// direction given by |event|.
bool ShouldRepeatKey(ui::KeyEvent* event) const;
// Given |event|, determine if the user has used their mouse, i.e. moved or
// clicked.
void SetHasUserUsedMouse(ui::MouseEvent* event);
// Depending on the properties of |event|, may cycle the window cycle list or
// complete cycling.
void ProcessMouseEvent(ui::MouseEvent* event);
// Depending on the properties of |event|, may continuously scroll the window
// cycle list, move the cycle view's focus ring or complete cycling.
void ProcessGestureEvent(ui::GestureEvent* event);
// Called by ProcessMouseEvent() and OnScrollEvent(). May cycle the window
// cycle list. Returns true if the event has been handled and should not be
// processed further, false otherwise.
bool ProcessEventImpl(int finger_count, float delta_x, float delta_y);
// Based on the given scroll data, determine whether we should cycle the
// window cycle list. Return true if we do cycle the window cycle list,
// otherwise return false.
bool CycleWindowCycleList(int finger_count, float scroll_x, float scroll_y);
// Returns the cycling direction the window cycle should cycle depending on
// the combination of keys being pressed.
WindowCycleController::WindowCyclingDirection GetWindowCyclingDirection(
ui::KeyEvent* event) const;
// Returns the navigation direction to move the focus to.
WindowCycleController::KeyboardNavDirection GetKeyboardNavDirection(
ui::KeyEvent* event) const;
// When the user holds Alt+Tab, this timer is used to send repeated
// cycle commands to WindowCycleController. Note this is not accomplished
// by marking the Alt+Tab accelerator as "repeatable" in the accelerator
// table because we wish to control the repeat interval.
base::RepeatingTimer repeat_timer_;
AltReleaseHandler alt_release_handler_;
// Stores the initial mouse coordinates. Used to determine whether
// |has_user_used_mouse_| when this handles mouse events.
gfx::Point initial_mouse_location_;
// Bool for tracking whether the user has used their mouse. If this is false,
// mouse events should be filtered. This is to prevent the initial mouse
// position from triggering window cycle items' mouse event handlers despite a
// user not moving their mouse. Should be set to true when a user moves their
// mouse enough or clicks/drags/mousewheel scrolls.
// See crbug.com/114375.
bool has_user_used_mouse_ = false;
// Stores the current scroll session data. If it does not exist, there is no
// active scroll session.
std::optional<ScrollData> scroll_data_;
// When a user taps on a preview item it should move the focus ring to it.
// However, the focus ring should not move if the user is scrolling. Store
// |tapped_window_| on tap events and determine whether this is a tap or
// scroll with subsequent events.
raw_ptr<aura::Window> tapped_window_ = nullptr;
// Tracks whether the user is touch scrolling the window cycle list.
bool touch_scrolling_ = false;
};
} // namespace ash
#endif // ASH_WM_WINDOW_CYCLE_WINDOW_CYCLE_EVENT_FILTER_H_