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

Commit 7a95e32

Browse files
authored
Linux: Use a hash table to map cursors (#19561)
Refactors the process of looking up system mouse cursor value, so that instead of a linear search it uses a hash table.
1 parent 1e02bfd commit 7a95e32

File tree

1 file changed

+42
-21
lines changed

1 file changed

+42
-21
lines changed

shell/platform/linux/fl_mouse_cursor_plugin.cc

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,47 @@ static constexpr char kBadArgumentsError[] = "Bad Arguments";
1414
static constexpr char kActivateSystemCursorMethod[] = "activateSystemCursor";
1515
static constexpr char kKindKey[] = "kind";
1616

17+
static constexpr char kFallbackCursor[] = "default";
18+
1719
struct _FlMouseCursorPlugin {
1820
GObject parent_instance;
1921

2022
FlMethodChannel* channel;
2123

2224
FlView* view;
25+
26+
GHashTable* system_cursor_table;
2327
};
2428

2529
G_DEFINE_TYPE(FlMouseCursorPlugin, fl_mouse_cursor_plugin, G_TYPE_OBJECT)
2630

31+
// Insert a new entry into a hashtable from strings to strings.
32+
//
33+
// Returns whether the newly added value was already in the hash table or not.
34+
static bool define_system_cursor(GHashTable* table,
35+
const gchar* key,
36+
const gchar* value) {
37+
return g_hash_table_insert(
38+
table, reinterpret_cast<gpointer>(const_cast<gchar*>(key)),
39+
reinterpret_cast<gpointer>(const_cast<gchar*>(value)));
40+
}
41+
42+
// Populate the hash table so that it maps from Flutter's cursor kinds to GTK's
43+
// cursor values.
44+
//
45+
// The table must have been created as a hashtable from strings to strings.
46+
static void populate_system_cursor_table(GHashTable* table) {
47+
// The following mapping must be kept in sync with Flutter framework's
48+
// mouse_cursor.dart.
49+
define_system_cursor(table, "none", "none");
50+
define_system_cursor(table, "click", "pointer");
51+
define_system_cursor(table, "text", "text");
52+
define_system_cursor(table, "forbidden", "not-allowed");
53+
define_system_cursor(table, "grab", "grabbing");
54+
define_system_cursor(table, "resizeLeftRight", "ew-resize");
55+
define_system_cursor(table, "resizeUpDown", "ns-resize");
56+
}
57+
2758
// Sets the mouse cursor.
2859
FlMethodResponse* activate_system_cursor(FlMouseCursorPlugin* self,
2960
FlValue* args) {
@@ -37,27 +68,15 @@ FlMethodResponse* activate_system_cursor(FlMouseCursorPlugin* self,
3768
if (fl_value_get_type(kind_value) == FL_VALUE_TYPE_STRING)
3869
kind = fl_value_get_string(kind_value);
3970

40-
const gchar* cursor_name = nullptr;
41-
if (g_strcmp0(kind, "none") == 0)
42-
cursor_name = "none";
43-
else if (g_strcmp0(kind, "basic") == 0)
44-
cursor_name = "default";
45-
else if (g_strcmp0(kind, "click") == 0)
46-
cursor_name = "pointer";
47-
else if (g_strcmp0(kind, "text") == 0)
48-
cursor_name = "text";
49-
else if (g_strcmp0(kind, "forbidden") == 0)
50-
cursor_name = "not-allowed";
51-
else if (g_strcmp0(kind, "grab") == 0)
52-
cursor_name = "grab";
53-
else if (g_strcmp0(kind, "grabbing") == 0)
54-
cursor_name = "grabbing";
55-
else if (g_strcmp0(kind, "resizeLeftRight") == 0)
56-
cursor_name = "ew-resize";
57-
else if (g_strcmp0(kind, "resizeUpDown") == 0)
58-
cursor_name = "ns-resize";
59-
else
60-
cursor_name = "default";
71+
if (self->system_cursor_table == nullptr) {
72+
self->system_cursor_table = g_hash_table_new(g_str_hash, g_str_equal);
73+
populate_system_cursor_table(self->system_cursor_table);
74+
}
75+
76+
const gchar* cursor_name = reinterpret_cast<const gchar*>(
77+
g_hash_table_lookup(self->system_cursor_table, kind));
78+
if (cursor_name == nullptr)
79+
cursor_name = kFallbackCursor;
6180

6281
GdkWindow* window =
6382
gtk_widget_get_window(gtk_widget_get_toplevel(GTK_WIDGET(self->view)));
@@ -102,6 +121,8 @@ static void fl_mouse_cursor_plugin_dispose(GObject* object) {
102121
self->view = nullptr;
103122
}
104123

124+
g_clear_pointer(&self->system_cursor_table, g_hash_table_unref);
125+
105126
G_OBJECT_CLASS(fl_mouse_cursor_plugin_parent_class)->dispose(object);
106127
}
107128

0 commit comments

Comments
 (0)