1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EVENT_SOURCE_H_
6 #define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EVENT_SOURCE_H_
7 
8 #include <deque>
9 #include <memory>
10 
11 #include "base/containers/flat_map.h"
12 #include "base/optional.h"
13 #include "base/time/time.h"
14 #include "ui/events/event_constants.h"
15 #include "ui/events/keycodes/dom/dom_code.h"
16 #include "ui/events/platform/platform_event_source.h"
17 #include "ui/events/pointer_details.h"
18 #include "ui/events/types/event_type.h"
19 #include "ui/gfx/geometry/point_f.h"
20 #include "ui/ozone/platform/wayland/host/wayland_event_watcher.h"
21 #include "ui/ozone/platform/wayland/host/wayland_input_method_context.h"
22 #include "ui/ozone/platform/wayland/host/wayland_keyboard.h"
23 #include "ui/ozone/platform/wayland/host/wayland_pointer.h"
24 #include "ui/ozone/platform/wayland/host/wayland_touch.h"
25 #include "ui/ozone/platform/wayland/host/wayland_window_manager.h"
26 #include "ui/ozone/platform/wayland/host/wayland_window_observer.h"
27 
28 struct wl_display;
29 
30 namespace gfx {
31 class Vector2d;
32 }
33 
34 namespace ui {
35 
36 class WaylandWindow;
37 class WaylandWindowManager;
38 
39 // Wayland implementation of ui::PlatformEventSource. It polls for events
40 // through WaylandEventWatcher and centralizes the input and focus handling
41 // logic within Ozone Wayland backend. In order to do so, it also implements the
42 // input objects' delegate interfaces, which are the entry point of event data
43 // coming from input devices, e.g: wl_{keyboard,pointer,touch}, which are then
44 // pre-processed, translated into ui::Event instances and dispatched to the
45 // PlatformEvent system.
46 class WaylandEventSource : public PlatformEventSource,
47                            public WaylandWindowObserver,
48                            public WaylandKeyboard::Delegate,
49                            public WaylandPointer::Delegate,
50                            public WaylandTouch::Delegate {
51  public:
52   WaylandEventSource(wl_display* display, WaylandWindowManager* window_manager);
53   WaylandEventSource(const WaylandEventSource&) = delete;
54   WaylandEventSource& operator=(const WaylandEventSource&) = delete;
55   ~WaylandEventSource() override;
56 
last_pointer_button_pressed()57   int last_pointer_button_pressed() const {
58     return last_pointer_button_pressed_;
59   }
60 
keyboard_modifiers()61   int keyboard_modifiers() const { return keyboard_modifiers_; }
62 
63   // Sets a callback that that shutdowns the browser in case of unrecoverable
64   // error. Called by WaylandEventWatcher.
65   void SetShutdownCb(base::OnceCallback<void()> shutdown_cb);
66 
67   // Starts polling for events from the wayland connection file descriptor.
68   // This method assumes connection is already estabilished and input objects
69   // are already bound and properly initialized.
70   bool StartProcessingEvents();
71   // Stops polling for events from input devices.
72   bool StopProcessingEvents();
73 
74   // Tells if pointer |button| is currently pressed.
75   bool IsPointerButtonPressed(EventFlags button) const;
76 
77   // Allow to explicitly reset pointer flags. Required in cases where the
78   // pointer state is modified by a button pressed event, but the respective
79   // button released event is not delivered (e.g: window moving, drag and drop).
80   void ResetPointerFlags();
81 
82  protected:
83   // WaylandKeyboard::Delegate
84   void OnKeyboardCreated(WaylandKeyboard* keyboard) override;
85   void OnKeyboardDestroyed(WaylandKeyboard* keyboard) override;
86   void OnKeyboardFocusChanged(WaylandWindow* window, bool focused) override;
87   void OnKeyboardModifiersChanged(int modifiers) override;
88   uint32_t OnKeyboardKeyEvent(EventType type,
89                               DomCode dom_code,
90                               bool repeat,
91                               base::TimeTicks timestamp) override;
92 
93   // WaylandPointer::Delegate
94   void OnPointerCreated(WaylandPointer* pointer) override;
95   void OnPointerDestroyed(WaylandPointer* pointer) override;
96   void OnPointerFocusChanged(WaylandWindow* window,
97                              const gfx::PointF& location) override;
98   void OnPointerButtonEvent(EventType evtype,
99                             int changed_button,
100                             WaylandWindow* window = nullptr) override;
101   void OnPointerMotionEvent(const gfx::PointF& location) override;
102   void OnPointerAxisEvent(const gfx::Vector2d& offset) override;
103   void OnPointerFrameEvent() override;
104   void OnPointerAxisSourceEvent(uint32_t axis_source) override;
105   void OnPointerAxisStopEvent(uint32_t axis) override;
106 
107   // WaylandTouch::Delegate
108   void OnTouchCreated(WaylandTouch* touch) override;
109   void OnTouchDestroyed(WaylandTouch* touch) override;
110   void OnTouchPressEvent(WaylandWindow* window,
111                          const gfx::PointF& location,
112                          base::TimeTicks timestamp,
113                          PointerId id) override;
114   void OnTouchReleaseEvent(base::TimeTicks timestamp, PointerId id) override;
115   void OnTouchMotionEvent(const gfx::PointF& location,
116                           base::TimeTicks timestamp,
117                           PointerId id) override;
118   void OnTouchCancelEvent() override;
119 
120  private:
121   struct PointerFrame {
122     uint32_t axis_source = WL_POINTER_AXIS_SOURCE_WHEEL;
123     float dx = 0.0f;
124     float dy = 0.0f;
125     base::TimeDelta dt;
126     bool is_axis_stop = false;
127   };
128   struct TouchPoint;
129 
130   // PlatformEventSource:
131   void OnDispatcherListChanged() override;
132 
133   // WaylandWindowObserver
134   void OnWindowRemoved(WaylandWindow* window) override;
135 
136   void UpdateKeyboardModifiers(int modifier, bool down);
137   void HandleKeyboardFocusChange(WaylandWindow* window, bool focused);
138   void HandlePointerFocusChange(WaylandWindow* window);
139   void HandleTouchFocusChange(WaylandWindow* window,
140                               bool focused,
141                               base::Optional<PointerId> id = base::nullopt);
142   bool ShouldUnsetTouchFocus(WaylandWindow* window, PointerId id);
143 
144   // Computes initial velocity of fling scroll based on recent frames.
145   gfx::Vector2dF ComputeFlingVelocity();
146 
147   WaylandWindowManager* const window_manager_;
148 
149   // Input device objects. Owned by WaylandConnection.
150   WaylandKeyboard* keyboard_ = nullptr;
151   WaylandPointer* pointer_ = nullptr;
152   WaylandTouch* touch_ = nullptr;
153 
154   // Bitmask of EventFlags used to keep track of the the pointer state.
155   int pointer_flags_ = 0;
156 
157   // Bitmask of EventFlags used to keep track of the last changed button.
158   int last_pointer_button_pressed_ = 0;
159 
160   // Bitmask of EventFlags used to keep track of the the keyboard state.
161   int keyboard_modifiers_ = 0;
162 
163   // Last known pointer location.
164   gfx::PointF pointer_location_;
165 
166   // Current frame
167   PointerFrame current_pointer_frame_;
168 
169   // Time of the last pointer frame event.
170   base::TimeTicks last_pointer_frame_time_;
171 
172   // Recent pointer frames to compute fling scroll.
173   // Front is newer, and back is older.
174   std::deque<PointerFrame> recent_pointer_frames_;
175 
176   // The window the pointer is over.
177   WaylandWindow* window_with_pointer_focus_ = nullptr;
178 
179   // Map that keeps track of the current touch points, associating touch IDs to
180   // to the surface/location where they happened.
181   base::flat_map<PointerId, std::unique_ptr<TouchPoint>> touch_points_;
182 
183   std::unique_ptr<WaylandEventWatcher> event_watcher_;
184 };
185 
186 }  // namespace ui
187 #endif  // UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EVENT_SOURCE_H_
188