| Flutter Linux Embedder |

fl_pointer_manager.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter 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 #include "flutter/shell/platform/linux/fl_pointer_manager.h"
6
7 #include "flutter/shell/platform/linux/fl_engine_private.h"
8
9 static constexpr int kMicrosecondsPerMillisecond = 1000;
10
11 struct _FlPointerManager {
12 GObject parent_instance;
13
14 // Engine to send pointer events to.
15 GWeakRef engine;
16
17 // ID to mark events with.
18 FlutterViewId view_id;
19
20 // TRUE if the mouse pointer is inside the view, used for generating missing
21 // add events.
22 gboolean pointer_inside;
23
24 // Pointer button state recorded for sending status updates.
25 int64_t button_state;
26 };
27
28 G_DEFINE_TYPE(FlPointerManager, fl_pointer_manager, G_TYPE_OBJECT);
29
30 // Generates a mouse pointer event if the pointer appears inside the window.
31 static void ensure_pointer_added(FlPointerManager* self,
32 guint event_time,
33 FlutterPointerDeviceKind device_kind,
34 gdouble x,
35 gdouble y) {
36 if (self->pointer_inside) {
37 return;
38 }
39 self->pointer_inside = TRUE;
40
41 g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
42 if (engine == nullptr) {
43 return;
44 }
45
46 fl_engine_send_mouse_pointer_event(
47 engine, self->view_id, kAdd, event_time * kMicrosecondsPerMillisecond, x,
48 y, device_kind, 0, 0, self->button_state);
49 }
50
51 static void fl_pointer_manager_dispose(GObject* object) {
52 FlPointerManager* self = FL_POINTER_MANAGER(object);
53
54 g_weak_ref_clear(&self->engine);
55
56 G_OBJECT_CLASS(fl_pointer_manager_parent_class)->dispose(object);
57 }
58
59 static void fl_pointer_manager_class_init(FlPointerManagerClass* klass) {
60 G_OBJECT_CLASS(klass)->dispose = fl_pointer_manager_dispose;
61 }
62
63 static void fl_pointer_manager_init(FlPointerManager* self) {}
64
65 FlPointerManager* fl_pointer_manager_new(FlutterViewId view_id,
66 FlEngine* engine) {
67 FlPointerManager* self =
68 FL_POINTER_MANAGER(g_object_new(fl_pointer_manager_get_type(), nullptr));
69
70 self->view_id = view_id;
71 g_weak_ref_init(&self->engine, engine);
72
73 return self;
74 }
75
76 gboolean fl_pointer_manager_handle_button_press(
77 FlPointerManager* self,
78 guint event_time,
79 FlutterPointerDeviceKind device_kind,
80 gdouble x,
81 gdouble y,
82 int64_t button) {
83 g_return_val_if_fail(FL_IS_POINTER_MANAGER(self), FALSE);
84
85 ensure_pointer_added(self, event_time, device_kind, x, y);
86
87 // Drop the event if Flutter already thinks the button is down.
88 if ((self->button_state & button) != 0) {
89 return FALSE;
90 }
91
92 int old_button_state = self->button_state;
93 FlutterPointerPhase phase = kMove;
94 self->button_state ^= button;
95 phase = old_button_state == 0 ? kDown : kMove;
96
97 g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
98 if (engine == nullptr) {
99 return FALSE;
100 }
101
102 fl_engine_send_mouse_pointer_event(
103 engine, self->view_id, phase, event_time * kMicrosecondsPerMillisecond, x,
104 y, device_kind, 0, 0, self->button_state);
105
106 return TRUE;
107 }
108
109 gboolean fl_pointer_manager_handle_button_release(
110 FlPointerManager* self,
111 guint event_time,
112 FlutterPointerDeviceKind device_kind,
113 gdouble x,
114 gdouble y,
115 int64_t button) {
116 g_return_val_if_fail(FL_IS_POINTER_MANAGER(self), FALSE);
117
118 // Drop the event if Flutter already thinks the button is up.
119 if ((self->button_state & button) == 0) {
120 return FALSE;
121 }
122
123 FlutterPointerPhase phase = kMove;
124 self->button_state ^= button;
125
126 phase = self->button_state == 0 ? kUp : kMove;
127
128 g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
129 if (engine == nullptr) {
130 return FALSE;
131 }
132
133 fl_engine_send_mouse_pointer_event(
134 engine, self->view_id, phase, event_time * kMicrosecondsPerMillisecond, x,
135 y, device_kind, 0, 0, self->button_state);
136
137 return TRUE;
138 }
139
140 gboolean fl_pointer_manager_handle_motion(FlPointerManager* self,
141 guint event_time,
142 FlutterPointerDeviceKind device_kind,
143 gdouble x,
144 gdouble y) {
145 g_return_val_if_fail(FL_IS_POINTER_MANAGER(self), FALSE);
146
147 g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
148 if (engine == nullptr) {
149 return FALSE;
150 }
151
152 ensure_pointer_added(self, event_time, device_kind, x, y);
153
154 fl_engine_send_mouse_pointer_event(
155 engine, self->view_id, self->button_state != 0 ? kMove : kHover,
156 event_time * kMicrosecondsPerMillisecond, x, y, device_kind, 0, 0,
157 self->button_state);
158
159 return TRUE;
160 }
161
162 gboolean fl_pointer_manager_handle_enter(FlPointerManager* self,
163 guint event_time,
164 FlutterPointerDeviceKind device_kind,
165 gdouble x,
166 gdouble y) {
167 g_return_val_if_fail(FL_IS_POINTER_MANAGER(self), FALSE);
168
169 g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
170 if (engine == nullptr) {
171 return FALSE;
172 }
173
174 ensure_pointer_added(self, event_time, device_kind, x, y);
175
176 return TRUE;
177 }
178
179 gboolean fl_pointer_manager_handle_leave(FlPointerManager* self,
180 guint event_time,
181 FlutterPointerDeviceKind device_kind,
182 gdouble x,
183 gdouble y) {
184 g_return_val_if_fail(FL_IS_POINTER_MANAGER(self), FALSE);
185
186 g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
187 if (engine == nullptr) {
188 return FALSE;
189 }
190
191 // Don't remove pointer while button is down; In case of dragging outside of
192 // window with mouse grab active Gtk will send another leave notify on
193 // release.
194 if (self->pointer_inside && self->button_state == 0) {
195 fl_engine_send_mouse_pointer_event(engine, self->view_id, kRemove,
196 event_time * kMicrosecondsPerMillisecond,
197 x, y, device_kind, 0, 0,
198 self->button_state);
199 self->pointer_inside = FALSE;
200 }
201
202 return TRUE;
203 }
ensure_pointer_added
static void ensure_pointer_added(FlPointerManager *self, guint event_time, FlutterPointerDeviceKind device_kind, gdouble x, gdouble y)
Definition: fl_pointer_manager.cc:31
fl_pointer_manager_init
static void fl_pointer_manager_init(FlPointerManager *self)
Definition: fl_pointer_manager.cc:63
_FlPointerManager::pointer_inside
gboolean pointer_inside
Definition: fl_pointer_manager.cc:22
_FlPointerManager::parent_instance
GObject parent_instance
Definition: fl_pointer_manager.cc:12
fl_pointer_manager_dispose
static void fl_pointer_manager_dispose(GObject *object)
Definition: fl_pointer_manager.cc:51
_FlPointerManager::view_id
FlutterViewId view_id
Definition: fl_pointer_manager.cc:18
fl_pointer_manager.h
_FlPointerManager::button_state
int64_t button_state
Definition: fl_pointer_manager.cc:25
kMicrosecondsPerMillisecond
static constexpr int kMicrosecondsPerMillisecond
Definition: fl_pointer_manager.cc:9
G_DEFINE_TYPE
G_DEFINE_TYPE(FlPointerManager, fl_pointer_manager, G_TYPE_OBJECT)
fl_engine_private.h
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
_FlPointerManager::engine
GWeakRef engine
Definition: fl_pointer_manager.cc:15
fl_pointer_manager_handle_motion
gboolean fl_pointer_manager_handle_motion(FlPointerManager *self, guint event_time, FlutterPointerDeviceKind device_kind, gdouble x, gdouble y)
Definition: fl_pointer_manager.cc:140
fl_pointer_manager_handle_leave
gboolean fl_pointer_manager_handle_leave(FlPointerManager *self, guint event_time, FlutterPointerDeviceKind device_kind, gdouble x, gdouble y)
Definition: fl_pointer_manager.cc:179
fl_pointer_manager_handle_enter
gboolean fl_pointer_manager_handle_enter(FlPointerManager *self, guint event_time, FlutterPointerDeviceKind device_kind, gdouble x, gdouble y)
Definition: fl_pointer_manager.cc:162
_FlPointerManager
Definition: fl_pointer_manager.cc:11
fl_pointer_manager_class_init
static void fl_pointer_manager_class_init(FlPointerManagerClass *klass)
Definition: fl_pointer_manager.cc:59
fl_pointer_manager_handle_button_press
gboolean fl_pointer_manager_handle_button_press(FlPointerManager *self, guint event_time, FlutterPointerDeviceKind device_kind, gdouble x, gdouble y, int64_t button)
Definition: fl_pointer_manager.cc:76
fl_engine_send_mouse_pointer_event
void fl_engine_send_mouse_pointer_event(FlEngine *self, FlutterViewId view_id, FlutterPointerPhase phase, size_t timestamp, double x, double y, FlutterPointerDeviceKind device_kind, double scroll_delta_x, double scroll_delta_y, int64_t buttons)
Definition: fl_engine.cc:918
fl_pointer_manager_handle_button_release
gboolean fl_pointer_manager_handle_button_release(FlPointerManager *self, guint event_time, FlutterPointerDeviceKind device_kind, gdouble x, gdouble y, int64_t button)
Definition: fl_pointer_manager.cc:109
fl_pointer_manager_new
FlPointerManager * fl_pointer_manager_new(FlutterViewId view_id, FlEngine *engine)
Definition: fl_pointer_manager.cc:65