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 
6 
8 
9 static constexpr int kMicrosecondsPerMillisecond = 1000;
10 
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 
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 
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 
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 
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 
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 
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