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