Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit b949d71

Browse files
authored
Map mouse pointer type on Linux (#52418)
Before all mouse clicks were set to `PointerDeviceKind.mouse` on Linux. Now use the proper type according to the source `GdkEvent`. Fixes flutter/flutter#147277
1 parent baaed31 commit b949d71

File tree

8 files changed

+61
-18
lines changed

8 files changed

+61
-18
lines changed

shell/platform/linux/fl_engine.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,7 @@ void fl_engine_send_mouse_pointer_event(FlEngine* self,
792792
size_t timestamp,
793793
double x,
794794
double y,
795+
FlutterPointerDeviceKind device_kind,
795796
double scroll_delta_x,
796797
double scroll_delta_y,
797798
int64_t buttons) {
@@ -812,7 +813,7 @@ void fl_engine_send_mouse_pointer_event(FlEngine* self,
812813
}
813814
fl_event.scroll_delta_x = scroll_delta_x;
814815
fl_event.scroll_delta_y = scroll_delta_y;
815-
fl_event.device_kind = kFlutterPointerDeviceKindMouse;
816+
fl_event.device_kind = device_kind;
816817
fl_event.buttons = buttons;
817818
fl_event.device = kMousePointerDeviceId;
818819
// TODO(dkwingsmt): Assign the correct view ID once the Linux embedder

shell/platform/linux/fl_engine_private.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ void fl_engine_send_window_state_event(FlEngine* engine,
188188
* @timestamp: time when event occurred in microseconds.
189189
* @x: x location of mouse cursor.
190190
* @y: y location of mouse cursor.
191+
* @device_kind: kind of pointing device.
191192
* @scroll_delta_x: x offset of scroll.
192193
* @scroll_delta_y: y offset of scroll.
193194
* @buttons: buttons that are pressed.
@@ -199,6 +200,7 @@ void fl_engine_send_mouse_pointer_event(FlEngine* engine,
199200
size_t timestamp,
200201
double x,
201202
double y,
203+
FlutterPointerDeviceKind device_kind,
202204
double scroll_delta_x,
203205
double scroll_delta_y,
204206
int64_t buttons);

shell/platform/linux/fl_engine_test.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,9 @@ TEST(FlEngineTest, MousePointer) {
7070
g_autoptr(GError) error = nullptr;
7171
EXPECT_TRUE(fl_engine_start(engine, &error));
7272
EXPECT_EQ(error, nullptr);
73-
fl_engine_send_mouse_pointer_event(engine, kDown, 1234567890, 800, 600, 1.2,
74-
-3.4, kFlutterPointerButtonMouseSecondary);
73+
fl_engine_send_mouse_pointer_event(engine, kDown, 1234567890, 800, 600,
74+
kFlutterPointerDeviceKindMouse, 1.2, -3.4,
75+
kFlutterPointerButtonMouseSecondary);
7576

7677
EXPECT_TRUE(called);
7778
}

shell/platform/linux/fl_scrolling_manager.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,8 @@ void fl_scrolling_manager_handle_scroll_event(FlScrollingManager* self,
143143
this is a discrete scroll event */
144144
,
145145
event_time * kMicrosecondsPerMillisecond, event_x * scale_factor,
146-
event_y * scale_factor, scroll_delta_x, scroll_delta_y, 0);
146+
event_y * scale_factor, kFlutterPointerDeviceKindMouse, scroll_delta_x,
147+
scroll_delta_y, 0);
147148
}
148149
}
149150

shell/platform/linux/fl_scrolling_manager_test.cc

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ typedef std::function<void(FlutterPointerPhase phase,
1313
size_t timestamp,
1414
double x,
1515
double y,
16+
FlutterPointerDeviceKind device_kind,
1617
double scroll_delta_x,
1718
double scroll_delta_y,
1819
int64_t buttons)>
@@ -32,6 +33,7 @@ typedef struct {
3233
size_t timestamp;
3334
double x;
3435
double y;
36+
FlutterPointerDeviceKind device_kind;
3537
double scroll_delta_x;
3638
double scroll_delta_y;
3739
int64_t buttons;
@@ -114,13 +116,14 @@ static void fl_mock_view_send_mouse_pointer_event(
114116
size_t timestamp,
115117
double x,
116118
double y,
119+
FlutterPointerDeviceKind device_kind,
117120
double scroll_delta_x,
118121
double scroll_delta_y,
119122
int64_t buttons) {
120123
FlMockScrollingViewDelegatePrivate* priv =
121124
FL_MOCK_SCROLLING_VIEW_DELEGATE_GET_PRIVATE(delegate);
122-
priv->mouse_handler(phase, timestamp, x, y, scroll_delta_x, scroll_delta_y,
123-
buttons);
125+
priv->mouse_handler(phase, timestamp, x, y, device_kind, scroll_delta_x,
126+
scroll_delta_y, buttons);
124127
}
125128

126129
static void fl_mock_view_send_pointer_pan_zoom_event(
@@ -182,7 +185,8 @@ class ScrollingTester {
182185
fl_mock_scrolling_view_set_mouse_handler(
183186
view_,
184187
[](FlutterPointerPhase phase, size_t timestamp, double x, double y,
185-
double scroll_delta_x, double scroll_delta_y, int64_t buttons) {
188+
FlutterPointerDeviceKind device_kind, double scroll_delta_x,
189+
double scroll_delta_y, int64_t buttons) {
186190
// do nothing
187191
});
188192
fl_mock_scrolling_view_set_pan_zoom_handler(
@@ -204,13 +208,15 @@ class ScrollingTester {
204208
std::vector<MousePointerEventRecord>& storage) {
205209
fl_mock_scrolling_view_set_mouse_handler(
206210
view_, [&storage](FlutterPointerPhase phase, size_t timestamp, double x,
207-
double y, double scroll_delta_x,
208-
double scroll_delta_y, int64_t buttons) {
211+
double y, FlutterPointerDeviceKind device_kind,
212+
double scroll_delta_x, double scroll_delta_y,
213+
int64_t buttons) {
209214
storage.push_back(MousePointerEventRecord{
210215
.phase = phase,
211216
.timestamp = timestamp,
212217
.x = x,
213218
.y = y,
219+
.device_kind = device_kind,
214220
.scroll_delta_x = scroll_delta_x,
215221
.scroll_delta_y = scroll_delta_y,
216222
.buttons = buttons,
@@ -278,6 +284,7 @@ TEST(FlScrollingManagerTest, DiscreteDirectionional) {
278284
EXPECT_EQ(mouse_records.size(), 1u);
279285
EXPECT_EQ(mouse_records[0].x, 4.0);
280286
EXPECT_EQ(mouse_records[0].y, 8.0);
287+
EXPECT_EQ(mouse_records[0].device_kind, kFlutterPointerDeviceKindMouse);
281288
EXPECT_EQ(mouse_records[0].timestamp,
282289
1000lu); // Milliseconds -> Microseconds
283290
EXPECT_EQ(mouse_records[0].scroll_delta_x, 0);
@@ -288,6 +295,7 @@ TEST(FlScrollingManagerTest, DiscreteDirectionional) {
288295
EXPECT_EQ(mouse_records.size(), 2u);
289296
EXPECT_EQ(mouse_records[1].x, 4.0);
290297
EXPECT_EQ(mouse_records[1].y, 8.0);
298+
EXPECT_EQ(mouse_records[1].device_kind, kFlutterPointerDeviceKindMouse);
291299
EXPECT_EQ(mouse_records[1].timestamp,
292300
1000lu); // Milliseconds -> Microseconds
293301
EXPECT_EQ(mouse_records[1].scroll_delta_x, 0);
@@ -298,6 +306,7 @@ TEST(FlScrollingManagerTest, DiscreteDirectionional) {
298306
EXPECT_EQ(mouse_records.size(), 3u);
299307
EXPECT_EQ(mouse_records[2].x, 4.0);
300308
EXPECT_EQ(mouse_records[2].y, 8.0);
309+
EXPECT_EQ(mouse_records[2].device_kind, kFlutterPointerDeviceKindMouse);
301310
EXPECT_EQ(mouse_records[2].timestamp,
302311
1000lu); // Milliseconds -> Microseconds
303312
EXPECT_EQ(mouse_records[2].scroll_delta_x, 53 * -1.0);
@@ -308,6 +317,7 @@ TEST(FlScrollingManagerTest, DiscreteDirectionional) {
308317
EXPECT_EQ(mouse_records.size(), 4u);
309318
EXPECT_EQ(mouse_records[3].x, 4.0);
310319
EXPECT_EQ(mouse_records[3].y, 8.0);
320+
EXPECT_EQ(mouse_records[3].device_kind, kFlutterPointerDeviceKindMouse);
311321
EXPECT_EQ(mouse_records[3].timestamp,
312322
1000lu); // Milliseconds -> Microseconds
313323
EXPECT_EQ(mouse_records[3].scroll_delta_x, 53 * 1.0);
@@ -335,6 +345,7 @@ TEST(FlScrollingManagerTest, DiscreteScrolling) {
335345
EXPECT_EQ(mouse_records.size(), 1u);
336346
EXPECT_EQ(mouse_records[0].x, 4.0);
337347
EXPECT_EQ(mouse_records[0].y, 8.0);
348+
EXPECT_EQ(mouse_records[0].device_kind, kFlutterPointerDeviceKindMouse);
338349
EXPECT_EQ(mouse_records[0].timestamp,
339350
1000lu); // Milliseconds -> Microseconds
340351
EXPECT_EQ(mouse_records[0].scroll_delta_x, 53 * 1.0);

shell/platform/linux/fl_scrolling_view_delegate.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@ void fl_scrolling_view_delegate_send_mouse_pointer_event(
1717
size_t timestamp,
1818
double x,
1919
double y,
20+
FlutterPointerDeviceKind device_kind,
2021
double scroll_delta_x,
2122
double scroll_delta_y,
2223
int64_t buttons) {
2324
g_return_if_fail(FL_IS_SCROLLING_VIEW_DELEGATE(self));
2425

2526
FL_SCROLLING_VIEW_DELEGATE_GET_IFACE(self)->send_mouse_pointer_event(
26-
self, phase, timestamp, x, y, scroll_delta_x, scroll_delta_y, buttons);
27+
self, phase, timestamp, x, y, device_kind, scroll_delta_x, scroll_delta_y,
28+
buttons);
2729
}
2830
void fl_scrolling_view_delegate_send_pointer_pan_zoom_event(
2931
FlScrollingViewDelegate* self,

shell/platform/linux/fl_scrolling_view_delegate.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ struct _FlScrollingViewDelegateInterface {
3838
size_t timestamp,
3939
double x,
4040
double y,
41+
FlutterPointerDeviceKind device_kind,
4142
double scroll_delta_x,
4243
double scroll_delta_y,
4344
int64_t buttons);
@@ -59,6 +60,7 @@ void fl_scrolling_view_delegate_send_mouse_pointer_event(
5960
size_t timestamp,
6061
double x,
6162
double y,
63+
FlutterPointerDeviceKind device_kind,
6264
double scroll_delta_x,
6365
double scroll_delta_y,
6466
int64_t buttons);

shell/platform/linux/fl_view.cc

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,25 @@ static void init_scrolling(FlView* self) {
132132
fl_scrolling_manager_new(FL_SCROLLING_VIEW_DELEGATE(self));
133133
}
134134

135+
static FlutterPointerDeviceKind get_device_kind(GdkEvent* event) {
136+
GdkDevice* device = gdk_event_get_source_device(event);
137+
GdkInputSource source = gdk_device_get_source(device);
138+
switch (source) {
139+
case GDK_SOURCE_PEN:
140+
case GDK_SOURCE_ERASER:
141+
case GDK_SOURCE_CURSOR:
142+
case GDK_SOURCE_TABLET_PAD:
143+
return kFlutterPointerDeviceKindStylus;
144+
case GDK_SOURCE_TOUCHSCREEN:
145+
return kFlutterPointerDeviceKindTouch;
146+
case GDK_SOURCE_TOUCHPAD: // trackpad device type is reserved for gestures
147+
case GDK_SOURCE_TRACKPOINT:
148+
case GDK_SOURCE_KEYBOARD:
149+
case GDK_SOURCE_MOUSE:
150+
return kFlutterPointerDeviceKindMouse;
151+
}
152+
}
153+
135154
// Converts a GDK button event into a Flutter event and sends it to the engine.
136155
static gboolean send_pointer_button_event(FlView* self, GdkEvent* event) {
137156
guint event_time = gdk_event_get_time(event);
@@ -188,7 +207,8 @@ static gboolean send_pointer_button_event(FlView* self, GdkEvent* event) {
188207
event_state, event_time);
189208
fl_engine_send_mouse_pointer_event(
190209
self->engine, phase, event_time * kMicrosecondsPerMillisecond,
191-
event_x * scale_factor, event_y * scale_factor, 0, 0, self->button_state);
210+
event_x * scale_factor, event_y * scale_factor,
211+
get_device_kind((GdkEvent*)event), 0, 0, self->button_state);
192212

193213
return TRUE;
194214
}
@@ -205,7 +225,8 @@ static void check_pointer_inside(FlView* self, GdkEvent* event) {
205225
fl_engine_send_mouse_pointer_event(
206226
self->engine, kAdd,
207227
gdk_event_get_time(event) * kMicrosecondsPerMillisecond,
208-
x * scale_factor, y * scale_factor, 0, 0, self->button_state);
228+
x * scale_factor, y * scale_factor, get_device_kind(event), 0, 0,
229+
self->button_state);
209230
}
210231
}
211232
}
@@ -326,13 +347,14 @@ static void fl_view_scrolling_delegate_iface_init(
326347
FlScrollingViewDelegateInterface* iface) {
327348
iface->send_mouse_pointer_event =
328349
[](FlScrollingViewDelegate* view_delegate, FlutterPointerPhase phase,
329-
size_t timestamp, double x, double y, double scroll_delta_x,
350+
size_t timestamp, double x, double y,
351+
FlutterPointerDeviceKind device_kind, double scroll_delta_x,
330352
double scroll_delta_y, int64_t buttons) {
331353
FlView* self = FL_VIEW(view_delegate);
332354
if (self->engine != nullptr) {
333355
fl_engine_send_mouse_pointer_event(self->engine, phase, timestamp, x,
334-
y, scroll_delta_x, scroll_delta_y,
335-
buttons);
356+
y, device_kind, scroll_delta_x,
357+
scroll_delta_y, buttons);
336358
}
337359
};
338360
iface->send_pointer_pan_zoom_event =
@@ -419,7 +441,8 @@ static gboolean motion_notify_event_cb(FlView* self,
419441
fl_engine_send_mouse_pointer_event(
420442
self->engine, self->button_state != 0 ? kMove : kHover,
421443
event_time * kMicrosecondsPerMillisecond, event_x * scale_factor,
422-
event_y * scale_factor, 0, 0, self->button_state);
444+
event_y * scale_factor, get_device_kind((GdkEvent*)event), 0, 0,
445+
self->button_state);
423446

424447
return TRUE;
425448
}
@@ -462,8 +485,8 @@ static gboolean leave_notify_event_cb(FlView* self,
462485
gint scale_factor = gtk_widget_get_scale_factor(GTK_WIDGET(self));
463486
fl_engine_send_mouse_pointer_event(
464487
self->engine, kRemove, event_time * kMicrosecondsPerMillisecond,
465-
event_x * scale_factor, event_y * scale_factor, 0, 0,
466-
self->button_state);
488+
event_x * scale_factor, event_y * scale_factor,
489+
get_device_kind((GdkEvent*)event), 0, 0, self->button_state);
467490
self->pointer_inside = FALSE;
468491
}
469492

0 commit comments

Comments
 (0)