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 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
|
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EVENT_SOURCE_H_
#define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EVENT_SOURCE_H_
#include <deque>
#include <memory>
#include <optional>
#include <ostream>
#include "base/containers/flat_map.h"
#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "ui/events/event.h"
#include "ui/events/event_constants.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/platform/platform_event_source.h"
#include "ui/events/pointer_details.h"
#include "ui/events/types/event_type.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/ozone/platform/wayland/common/wayland_util.h"
#include "ui/ozone/platform/wayland/host/wayland_input_method_context.h"
#include "ui/ozone/platform/wayland/host/wayland_keyboard.h"
#include "ui/ozone/platform/wayland/host/wayland_pointer.h"
#include "ui/ozone/platform/wayland/host/wayland_touch.h"
#include "ui/ozone/platform/wayland/host/wayland_window_observer.h"
#include "ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures.h"
#include "ui/ozone/platform/wayland/host/wayland_zwp_relative_pointer_manager.h"
struct wl_display;
namespace gfx {
class Vector2dF;
}
namespace ui {
class WaylandConnection;
class WaylandWindow;
class WaylandWindowManager;
class WaylandEventWatcher;
// Wayland implementation of ui::PlatformEventSource. It polls for events
// through WaylandEventWatcher and centralizes the input and focus handling
// logic within Ozone Wayland backend. In order to do so, it also implements the
// input objects' delegate interfaces, which are the entry point of event data
// coming from input devices, e.g: wl_{keyboard,pointer,touch}, which are then
// pre-processed, translated into ui::Event instances and dispatched to the
// PlatformEvent system.
class WaylandEventSource : public PlatformEventSource,
public WaylandWindowObserver,
public WaylandKeyboard::Delegate,
public WaylandPointer::Delegate,
public WaylandTouch::Delegate,
public WaylandZwpPointerGestures::Delegate,
public WaylandZwpRelativePointerManager::Delegate {
public:
static void ConvertEventToTarget(EventTarget* new_target,
LocatedEvent* event);
WaylandEventSource(wl_display* display,
wl_event_queue* event_queue,
WaylandWindowManager* window_manager,
WaylandConnection* connection,
bool use_threaded_polling = false);
WaylandEventSource(const WaylandEventSource&) = delete;
WaylandEventSource& operator=(const WaylandEventSource&) = delete;
~WaylandEventSource() override;
int last_pointer_button_pressed() const {
return last_pointer_button_pressed_;
}
int keyboard_modifiers() const { return keyboard_modifiers_; }
// Sets a callback that that shutdowns the browser in case of unrecoverable
// error. Called by WaylandEventWatcher.
void SetShutdownCb(base::OnceCallback<void()> shutdown_cb);
// Starts polling for events from the wayland connection file descriptor.
// This method assumes connection is already established and input objects
// are already bound and properly initialized.
void StartProcessingEvents();
// Forwards the call to WaylandEventWatcher, which calls
// wl_display_roundtrip_queue.
void RoundTripQueue();
void DumpState(std::ostream& out) const;
void ResetStateForTesting() override;
// WaylandKeyboard::Delegate
void OnKeyboardFocusChanged(WaylandWindow* window, bool focused) override;
void OnKeyboardModifiersChanged(int modifiers) override;
uint32_t OnKeyboardKeyEvent(EventType type,
DomCode dom_code,
bool repeat,
std::optional<uint32_t> serial,
base::TimeTicks timestamp,
int device_id,
WaylandKeyboard::KeyEventKind kind) override;
void OnSynthesizedKeyPressEvent(WaylandWindow* window,
DomCode dom_code,
base::TimeTicks timestamp) override;
// WaylandPointer::Delegate
void OnPointerFocusChanged(WaylandWindow* window,
const gfx::PointF& location,
base::TimeTicks timestamp,
wl::EventDispatchPolicy dispatch_policy) override;
void OnPointerButtonEvent(EventType evtype,
int changed_button,
base::TimeTicks timestamp,
WaylandWindow* window,
wl::EventDispatchPolicy dispatch_policy,
bool allow_release_of_unpressed_button,
bool is_synthesized) override;
void OnPointerMotionEvent(const gfx::PointF& location,
base::TimeTicks timestamp,
wl::EventDispatchPolicy dispatch_policy,
bool is_synthesized) override;
void OnPointerAxisEvent(const gfx::Vector2dF& offset,
std::optional<base::TimeTicks> timestamp,
bool is_high_resolution) override;
void OnPointerFrameEvent() override;
void OnPointerAxisSourceEvent(uint32_t axis_source) override;
void OnPointerAxisStopEvent(uint32_t axis,
base::TimeTicks timestamp) override;
const gfx::PointF& GetPointerLocation() const override;
bool IsPointerButtonPressed(EventFlags button) const override;
void ReleasePressedPointerButtons(WaylandWindow* window,
base::TimeTicks timestamp) override;
// WaylandTouch::Delegate
void OnTouchPressEvent(WaylandWindow* window,
const gfx::PointF& location,
base::TimeTicks timestamp,
PointerId id,
wl::EventDispatchPolicy dispatch_policy) override;
void OnTouchReleaseEvent(base::TimeTicks timestamp,
PointerId id,
wl::EventDispatchPolicy dispatch_policy,
bool is_synthesized) override;
void OnTouchMotionEvent(const gfx::PointF& location,
base::TimeTicks timestamp,
PointerId id,
wl::EventDispatchPolicy dispatch_policy,
bool is_synthesized) override;
void OnTouchCancelEvent() override;
void OnTouchFrame() override;
void OnTouchFocusChanged(WaylandWindow* window) override;
std::vector<PointerId> GetActiveTouchPointIds() override;
const WaylandWindow* GetTouchTarget(PointerId id) const override;
// WaylandZwpPointerGesture::Delegate:
void OnPinchEvent(EventType event_type,
const gfx::Vector2dF& delta,
base::TimeTicks timestamp,
int device_id,
std::optional<float> scale_delta) override;
void OnHoldEvent(EventType event_type,
uint32_t finger_count,
base::TimeTicks timestamp,
int device_id,
wl::EventDispatchPolicy dispatch_policy) override;
// WaylandZwpRelativePointerManager::Delegate:
void SetRelativePointerMotionEnabled(bool enabled) override;
void OnRelativePointerMotion(const gfx::Vector2dF& delta,
base::TimeTicks timestamp) override;
private:
struct PointerScrollData {
PointerScrollData();
PointerScrollData(const PointerScrollData& other);
PointerScrollData(PointerScrollData&&);
~PointerScrollData();
PointerScrollData& operator=(const PointerScrollData&);
PointerScrollData& operator=(PointerScrollData&&);
std::optional<uint32_t> axis_source;
float dx = 0.0f;
float dy = 0.0f;
base::TimeDelta dt;
bool is_axis_stop = false;
bool is_high_resolution = false;
std::optional<base::TimeTicks> timestamp;
void DumpState(std::ostream& out) const;
};
struct FrameData {
FrameData(const Event& event, base::OnceCallback<void()> completion_cb);
FrameData(const FrameData& other) = delete;
FrameData(FrameData&&) = delete;
~FrameData();
std::unique_ptr<Event> event;
base::OnceCallback<void()> completion_cb;
void DumpState(std::ostream& out) const;
};
// PlatformEventSource:
void OnDispatcherListChanged() override;
// WaylandWindowObserver:
void OnWindowRemoved(WaylandWindow* window) override;
void HandleTouchFocusChange(WaylandWindow* window,
bool focused,
std::optional<PointerId> id = std::nullopt);
bool ShouldUnsetTouchFocus(WaylandWindow* window, PointerId id);
// Computes initial velocity of fling scroll based on recent frames.
// The fling velocity is computed the same way as in libgestures.
gfx::Vector2dF ComputeFlingVelocity();
// Wrap up method to support async pointer down/up event processing.
void OnPointerButtonEventInternal(WaylandWindow* window, EventType type);
// Wrap up method to support async touch release processing.
void OnTouchReleaseInternal(PointerId id);
// Ensure a valid instance of the PointerScrollData class member.
void EnsurePointerScrollData(const std::optional<base::TimeTicks>& timestamp);
void ProcessPointerScrollData();
// Set the target to the event, then dispatch the event.
void SetTargetAndDispatchEvent(Event* event, EventTarget* target);
// Find and set the target for the touch event, then dispatch the event.
void SetTouchTargetAndDispatchTouchEvent(TouchEvent* event);
const raw_ptr<WaylandWindowManager> window_manager_;
const raw_ptr<WaylandConnection> connection_;
// Bitmask of EventFlags used to keep track of the the pointer state.
int pointer_flags_ = 0;
// Bitmask of EventFlags used to keep track of the last changed button.
int last_pointer_button_pressed_ = 0;
// Bitmask of EventFlags used to keep track of the the keyboard state.
// See ui/events/event_constants.h for examples and details.
int keyboard_modifiers_ = 0;
// Last known pointer location.
gfx::PointF pointer_location_;
// Last known relative pointer location (used for pointer lock).
std::optional<gfx::PointF> relative_pointer_location_;
// Accumulates the scroll data within a pointer frame internal.
std::optional<PointerScrollData> pointer_scroll_data_;
// Latest set of pointer scroll data to compute fling scroll.
// Front is newer, and back is older.
std::deque<PointerScrollData> pointer_scroll_data_set_;
// Time of the last pointer frame event.
base::TimeTicks last_pointer_frame_time_;
// Order set of touch events to be dispatching on the next
// wl_touch::frame event.
std::deque<std::unique_ptr<FrameData>> touch_frames_;
// Order set of pointer events to be dispatching on the next
// wl_pointer::frame event.
std::deque<std::unique_ptr<FrameData>> pointer_frames_;
// Status of fling.
bool is_fling_active_ = false;
// Map that keeps track of the current touch points, associating touch IDs to
// to the surface/location where they happened.
struct TouchPoint;
base::flat_map<PointerId, std::unique_ptr<TouchPoint>> touch_points_;
std::unique_ptr<WaylandEventWatcher> event_watcher_;
};
} // namespace ui
#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EVENT_SOURCE_H_
|