Skip to content

Commit

Permalink
Linux: Use a hash table to map cursors (#19561)
Browse files Browse the repository at this point in the history
Refactors the process of looking up system mouse cursor value, so that instead of a linear search it uses a hash table.
  • Loading branch information
dkwingsmt committed Jul 13, 2020
1 parent 1e02bfd commit 7a95e32
Showing 1 changed file with 42 additions and 21 deletions.
63 changes: 42 additions & 21 deletions shell/platform/linux/fl_mouse_cursor_plugin.cc
Expand Up @@ -14,16 +14,47 @@ static constexpr char kBadArgumentsError[] = "Bad Arguments";
static constexpr char kActivateSystemCursorMethod[] = "activateSystemCursor";
static constexpr char kKindKey[] = "kind";

static constexpr char kFallbackCursor[] = "default";

struct _FlMouseCursorPlugin {
GObject parent_instance;

FlMethodChannel* channel;

FlView* view;

GHashTable* system_cursor_table;
};

G_DEFINE_TYPE(FlMouseCursorPlugin, fl_mouse_cursor_plugin, G_TYPE_OBJECT)

// Insert a new entry into a hashtable from strings to strings.
//
// Returns whether the newly added value was already in the hash table or not.
static bool define_system_cursor(GHashTable* table,
const gchar* key,
const gchar* value) {
return g_hash_table_insert(
table, reinterpret_cast<gpointer>(const_cast<gchar*>(key)),
reinterpret_cast<gpointer>(const_cast<gchar*>(value)));
}

// Populate the hash table so that it maps from Flutter's cursor kinds to GTK's
// cursor values.
//
// The table must have been created as a hashtable from strings to strings.
static void populate_system_cursor_table(GHashTable* table) {
// The following mapping must be kept in sync with Flutter framework's
// mouse_cursor.dart.
define_system_cursor(table, "none", "none");
define_system_cursor(table, "click", "pointer");
define_system_cursor(table, "text", "text");
define_system_cursor(table, "forbidden", "not-allowed");
define_system_cursor(table, "grab", "grabbing");
define_system_cursor(table, "resizeLeftRight", "ew-resize");
define_system_cursor(table, "resizeUpDown", "ns-resize");
}

// Sets the mouse cursor.
FlMethodResponse* activate_system_cursor(FlMouseCursorPlugin* self,
FlValue* args) {
Expand All @@ -37,27 +68,15 @@ FlMethodResponse* activate_system_cursor(FlMouseCursorPlugin* self,
if (fl_value_get_type(kind_value) == FL_VALUE_TYPE_STRING)
kind = fl_value_get_string(kind_value);

const gchar* cursor_name = nullptr;
if (g_strcmp0(kind, "none") == 0)
cursor_name = "none";
else if (g_strcmp0(kind, "basic") == 0)
cursor_name = "default";
else if (g_strcmp0(kind, "click") == 0)
cursor_name = "pointer";
else if (g_strcmp0(kind, "text") == 0)
cursor_name = "text";
else if (g_strcmp0(kind, "forbidden") == 0)
cursor_name = "not-allowed";
else if (g_strcmp0(kind, "grab") == 0)
cursor_name = "grab";
else if (g_strcmp0(kind, "grabbing") == 0)
cursor_name = "grabbing";
else if (g_strcmp0(kind, "resizeLeftRight") == 0)
cursor_name = "ew-resize";
else if (g_strcmp0(kind, "resizeUpDown") == 0)
cursor_name = "ns-resize";
else
cursor_name = "default";
if (self->system_cursor_table == nullptr) {
self->system_cursor_table = g_hash_table_new(g_str_hash, g_str_equal);
populate_system_cursor_table(self->system_cursor_table);
}

const gchar* cursor_name = reinterpret_cast<const gchar*>(
g_hash_table_lookup(self->system_cursor_table, kind));
if (cursor_name == nullptr)
cursor_name = kFallbackCursor;

GdkWindow* window =
gtk_widget_get_window(gtk_widget_get_toplevel(GTK_WIDGET(self->view)));
Expand Down Expand Up @@ -102,6 +121,8 @@ static void fl_mouse_cursor_plugin_dispose(GObject* object) {
self->view = nullptr;
}

g_clear_pointer(&self->system_cursor_table, g_hash_table_unref);

G_OBJECT_CLASS(fl_mouse_cursor_plugin_parent_class)->dispose(object);
}

Expand Down

0 comments on commit 7a95e32

Please sign in to comment.