Skip to content

Commit

Permalink
Map pointer type on Linux
Browse files Browse the repository at this point in the history
  • Loading branch information
moffatman committed Apr 27, 2024
1 parent 8639505 commit 6b52610
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 19 deletions.
3 changes: 2 additions & 1 deletion shell/platform/linux/fl_engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,7 @@ void fl_engine_send_mouse_pointer_event(FlEngine* self,
size_t timestamp,
double x,
double y,
FlutterPointerDeviceKind device_kind,
double scroll_delta_x,
double scroll_delta_y,
int64_t buttons) {
Expand All @@ -732,7 +733,7 @@ void fl_engine_send_mouse_pointer_event(FlEngine* self,
}
fl_event.scroll_delta_x = scroll_delta_x;
fl_event.scroll_delta_y = scroll_delta_y;
fl_event.device_kind = kFlutterPointerDeviceKindMouse;
fl_event.device_kind = device_kind;
fl_event.buttons = buttons;
fl_event.device = kMousePointerDeviceId;
self->embedder_api.SendPointerEvent(self->engine, &fl_event, 1);
Expand Down
2 changes: 2 additions & 0 deletions shell/platform/linux/fl_engine_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ void fl_engine_send_window_metrics_event(FlEngine* engine,
* @timestamp: time when event occurred in microseconds.
* @x: x location of mouse cursor.
* @y: y location of mouse cursor.
* @device_kind: kind of pointing device.
* @scroll_delta_x: x offset of scroll.
* @scroll_delta_y: y offset of scroll.
* @buttons: buttons that are pressed.
Expand All @@ -185,6 +186,7 @@ void fl_engine_send_mouse_pointer_event(FlEngine* engine,
size_t timestamp,
double x,
double y,
FlutterPointerDeviceKind device_kind,
double scroll_delta_x,
double scroll_delta_y,
int64_t buttons);
Expand Down
5 changes: 3 additions & 2 deletions shell/platform/linux/fl_engine_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,9 @@ TEST(FlEngineTest, MousePointer) {
g_autoptr(GError) error = nullptr;
EXPECT_TRUE(fl_engine_start(engine, &error));
EXPECT_EQ(error, nullptr);
fl_engine_send_mouse_pointer_event(engine, kDown, 1234567890, 800, 600, 1.2,
-3.4, kFlutterPointerButtonMouseSecondary);
fl_engine_send_mouse_pointer_event(engine, kDown, 1234567890, 800, 600,
kFlutterPointerDeviceKindMouse, 1.2, -3.4,
kFlutterPointerButtonMouseSecondary);

EXPECT_TRUE(called);
}
Expand Down
3 changes: 2 additions & 1 deletion shell/platform/linux/fl_scrolling_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ void fl_scrolling_manager_handle_scroll_event(FlScrollingManager* self,
this is a discrete scroll event */
,
event->time * kMicrosecondsPerMillisecond, event->x * scale_factor,
event->y * scale_factor, scroll_delta_x, scroll_delta_y, 0);
event->y * scale_factor, kFlutterPointerDeviceKindMouse, scroll_delta_x,
scroll_delta_y, 0);
}
}

Expand Down
21 changes: 16 additions & 5 deletions shell/platform/linux/fl_scrolling_manager_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ typedef std::function<void(FlutterPointerPhase phase,
size_t timestamp,
double x,
double y,
FlutterPointerDeviceKind device_kind,
double scroll_delta_x,
double scroll_delta_y,
int64_t buttons)>
Expand All @@ -32,6 +33,7 @@ typedef struct {
size_t timestamp;
double x;
double y;
FlutterPointerDeviceKind device_kind;
double scroll_delta_x;
double scroll_delta_y;
int64_t buttons;
Expand Down Expand Up @@ -95,12 +97,13 @@ static void fl_mock_view_send_mouse_pointer_event(
size_t timestamp,
double x,
double y,
FlutterPointerDeviceKind device_kind,
double scroll_delta_x,
double scroll_delta_y,
int64_t buttons) {
FlMockScrollingViewDelegate* self = FL_MOCK_SCROLLING_VIEW_DELEGATE(delegate);
self->mouse_handler(phase, timestamp, x, y, scroll_delta_x, scroll_delta_y,
buttons);
self->mouse_handler(phase, timestamp, x, y, device_kind, scroll_delta_x,
scroll_delta_y, buttons);
}

static void fl_mock_view_send_pointer_pan_zoom_event(
Expand Down Expand Up @@ -155,7 +158,8 @@ class ScrollingTester {
fl_mock_scrolling_view_set_mouse_handler(
view_,
[](FlutterPointerPhase phase, size_t timestamp, double x, double y,
double scroll_delta_x, double scroll_delta_y, int64_t buttons) {
FlutterPointerDeviceKind device_kind, double scroll_delta_x,
double scroll_delta_y, int64_t buttons) {
// do nothing
});
fl_mock_scrolling_view_set_pan_zoom_handler(
Expand All @@ -177,13 +181,15 @@ class ScrollingTester {
std::vector<MousePointerEventRecord>& storage) {
fl_mock_scrolling_view_set_mouse_handler(
view_, [&storage](FlutterPointerPhase phase, size_t timestamp, double x,
double y, double scroll_delta_x,
double scroll_delta_y, int64_t buttons) {
double y, FlutterPointerDeviceKind device_kind,
double scroll_delta_x, double scroll_delta_y,
int64_t buttons) {
storage.push_back(MousePointerEventRecord{
.phase = phase,
.timestamp = timestamp,
.x = x,
.y = y,
.device_kind = device_kind,
.scroll_delta_x = scroll_delta_x,
.scroll_delta_y = scroll_delta_y,
.buttons = buttons,
Expand Down Expand Up @@ -249,6 +255,7 @@ TEST(FlScrollingManagerTest, DiscreteDirectionional) {
EXPECT_EQ(mouse_records.size(), 1u);
EXPECT_EQ(mouse_records[0].x, 4.0);
EXPECT_EQ(mouse_records[0].y, 8.0);
EXPECT_EQ(mouse_records[0].device_kind, kFlutterPointerDeviceKindMouse);
EXPECT_EQ(mouse_records[0].timestamp,
1000lu); // Milliseconds -> Microseconds
EXPECT_EQ(mouse_records[0].scroll_delta_x, 0);
Expand All @@ -259,6 +266,7 @@ TEST(FlScrollingManagerTest, DiscreteDirectionional) {
EXPECT_EQ(mouse_records.size(), 2u);
EXPECT_EQ(mouse_records[1].x, 4.0);
EXPECT_EQ(mouse_records[1].y, 8.0);
EXPECT_EQ(mouse_records[1].device_kind, kFlutterPointerDeviceKindMouse);
EXPECT_EQ(mouse_records[1].timestamp,
1000lu); // Milliseconds -> Microseconds
EXPECT_EQ(mouse_records[1].scroll_delta_x, 0);
Expand All @@ -269,6 +277,7 @@ TEST(FlScrollingManagerTest, DiscreteDirectionional) {
EXPECT_EQ(mouse_records.size(), 3u);
EXPECT_EQ(mouse_records[2].x, 4.0);
EXPECT_EQ(mouse_records[2].y, 8.0);
EXPECT_EQ(mouse_records[2].device_kind, kFlutterPointerDeviceKindMouse);
EXPECT_EQ(mouse_records[2].timestamp,
1000lu); // Milliseconds -> Microseconds
EXPECT_EQ(mouse_records[2].scroll_delta_x, 53 * -1.0);
Expand All @@ -279,6 +288,7 @@ TEST(FlScrollingManagerTest, DiscreteDirectionional) {
EXPECT_EQ(mouse_records.size(), 4u);
EXPECT_EQ(mouse_records[3].x, 4.0);
EXPECT_EQ(mouse_records[3].y, 8.0);
EXPECT_EQ(mouse_records[3].device_kind, kFlutterPointerDeviceKindMouse);
EXPECT_EQ(mouse_records[3].timestamp,
1000lu); // Milliseconds -> Microseconds
EXPECT_EQ(mouse_records[3].scroll_delta_x, 53 * 1.0);
Expand All @@ -305,6 +315,7 @@ TEST(FlScrollingManagerTest, DiscreteScrolling) {
EXPECT_EQ(mouse_records.size(), 1u);
EXPECT_EQ(mouse_records[0].x, 4.0);
EXPECT_EQ(mouse_records[0].y, 8.0);
EXPECT_EQ(mouse_records[0].device_kind, kFlutterPointerDeviceKindMouse);
EXPECT_EQ(mouse_records[0].timestamp,
1000lu); // Milliseconds -> Microseconds
EXPECT_EQ(mouse_records[0].scroll_delta_x, 53 * 1.0);
Expand Down
4 changes: 3 additions & 1 deletion shell/platform/linux/fl_scrolling_view_delegate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ void fl_scrolling_view_delegate_send_mouse_pointer_event(
size_t timestamp,
double x,
double y,
FlutterPointerDeviceKind device_kind,
double scroll_delta_x,
double scroll_delta_y,
int64_t buttons) {
g_return_if_fail(FL_IS_SCROLLING_VIEW_DELEGATE(self));

FL_SCROLLING_VIEW_DELEGATE_GET_IFACE(self)->send_mouse_pointer_event(
self, phase, timestamp, x, y, scroll_delta_x, scroll_delta_y, buttons);
self, phase, timestamp, x, y, device_kind, scroll_delta_x, scroll_delta_y,
buttons);
}
void fl_scrolling_view_delegate_send_pointer_pan_zoom_event(
FlScrollingViewDelegate* self,
Expand Down
2 changes: 2 additions & 0 deletions shell/platform/linux/fl_scrolling_view_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ struct _FlScrollingViewDelegateInterface {
size_t timestamp,
double x,
double y,
FlutterPointerDeviceKind device_kind,
double scroll_delta_x,
double scroll_delta_y,
int64_t buttons);
Expand All @@ -59,6 +60,7 @@ void fl_scrolling_view_delegate_send_mouse_pointer_event(
size_t timestamp,
double x,
double y,
FlutterPointerDeviceKind device_kind,
double scroll_delta_x,
double scroll_delta_y,
int64_t buttons);
Expand Down
40 changes: 31 additions & 9 deletions shell/platform/linux/fl_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,25 @@ static void init_scrolling(FlView* self) {
fl_scrolling_manager_new(FL_SCROLLING_VIEW_DELEGATE(self));
}

static FlutterPointerDeviceKind get_device_kind(GdkEvent* event) {
GdkDevice* device = gdk_event_get_source_device(event);
GdkInputSource source = gdk_device_get_source(device);
switch (source) {
case GDK_SOURCE_PEN:
case GDK_SOURCE_ERASER:
case GDK_SOURCE_CURSOR:
case GDK_SOURCE_TABLET_PAD:
return kFlutterPointerDeviceKindStylus;
case GDK_SOURCE_TOUCHSCREEN:
return kFlutterPointerDeviceKindTouch;
case GDK_SOURCE_TOUCHPAD: // trackpad device type is reserved for gestures
case GDK_SOURCE_TRACKPOINT:
case GDK_SOURCE_KEYBOARD:
case GDK_SOURCE_MOUSE:
return kFlutterPointerDeviceKindMouse;
}
}

// Converts a GDK button event into a Flutter event and sends it to the engine.
static gboolean send_pointer_button_event(FlView* self, GdkEventButton* event) {
int64_t button;
Expand Down Expand Up @@ -160,8 +179,8 @@ static gboolean send_pointer_button_event(FlView* self, GdkEventButton* event) {
event->y * scale_factor);
fl_engine_send_mouse_pointer_event(
self->engine, phase, event->time * kMicrosecondsPerMillisecond,
event->x * scale_factor, event->y * scale_factor, 0, 0,
self->button_state);
event->x * scale_factor, event->y * scale_factor,
get_device_kind((GdkEvent*)event), 0, 0, self->button_state);

return TRUE;
}
Expand All @@ -178,7 +197,8 @@ static void check_pointer_inside(FlView* view, GdkEvent* event) {
fl_engine_send_mouse_pointer_event(
view->engine, kAdd,
gdk_event_get_time(event) * kMicrosecondsPerMillisecond,
x * scale_factor, y * scale_factor, 0, 0, view->button_state);
x * scale_factor, y * scale_factor, get_device_kind(event), 0, 0,
view->button_state);
}
}
}
Expand Down Expand Up @@ -311,13 +331,14 @@ static void fl_view_scrolling_delegate_iface_init(
FlScrollingViewDelegateInterface* iface) {
iface->send_mouse_pointer_event =
[](FlScrollingViewDelegate* view_delegate, FlutterPointerPhase phase,
size_t timestamp, double x, double y, double scroll_delta_x,
size_t timestamp, double x, double y,
FlutterPointerDeviceKind device_kind, double scroll_delta_x,
double scroll_delta_y, int64_t buttons) {
FlView* self = FL_VIEW(view_delegate);
if (self->engine != nullptr) {
fl_engine_send_mouse_pointer_event(self->engine, phase, timestamp, x,
y, scroll_delta_x, scroll_delta_y,
buttons);
y, device_kind, scroll_delta_x,
scroll_delta_y, buttons);
}
};
iface->send_pointer_pan_zoom_event =
Expand Down Expand Up @@ -384,7 +405,8 @@ static gboolean motion_notify_event_cb(GtkWidget* widget,
fl_engine_send_mouse_pointer_event(
view->engine, view->button_state != 0 ? kMove : kHover,
event->time * kMicrosecondsPerMillisecond, event->x * scale_factor,
event->y * scale_factor, 0, 0, view->button_state);
event->y * scale_factor, get_device_kind((GdkEvent*)event), 0, 0,
view->button_state);

return TRUE;
}
Expand Down Expand Up @@ -417,8 +439,8 @@ static gboolean leave_notify_event_cb(GtkWidget* widget,
gint scale_factor = gtk_widget_get_scale_factor(GTK_WIDGET(view));
fl_engine_send_mouse_pointer_event(
view->engine, kRemove, event->time * kMicrosecondsPerMillisecond,
event->x * scale_factor, event->y * scale_factor, 0, 0,
view->button_state);
event->x * scale_factor, event->y * scale_factor,
get_device_kind((GdkEvent*)event), 0, 0, view->button_state);
view->pointer_inside = FALSE;
}

Expand Down

0 comments on commit 6b52610

Please sign in to comment.