diff options
author | Boris Astardzhiev <boris.astardzhiev@gmail.com> | 2020-02-15 08:57:48 -0500 |
---|---|---|
committer | Alexander Schwinn <alexxcons@xfce.org> | 2020-02-16 21:02:53 +0100 |
commit | 27254aae7fe6b1311497001e1c2c4fc8076823b6 (patch) | |
tree | 1ccefdb8f41062309e3744c4a03cc2784a530992 /src/xfdesktop-icon-view.c | |
parent | eec0c9b2ca7227b65184e2840f2c3e99aa8678b3 (diff) | |
download | xfdesktop-27254aae7fe6b1311497001e1c2c4fc8076823b6.tar.gz |
Added type-ahead find for Desktop icons (Bug #11149)
Co-authored-by: Alexander Schwinn <alexxcons@xfce.org>
Diffstat (limited to 'src/xfdesktop-icon-view.c')
-rw-r--r-- | src/xfdesktop-icon-view.c | 65 |
1 files changed, 64 insertions, 1 deletions
diff --git a/src/xfdesktop-icon-view.c b/src/xfdesktop-icon-view.c index b665cc10..cf1fab1f 100644 --- a/src/xfdesktop-icon-view.c +++ b/src/xfdesktop-icon-view.c @@ -1072,17 +1072,80 @@ xfdesktop_icon_view_button_release(GtkWidget *widget, } static gboolean +xfdesktop_icon_view_select_icon_from_list_by_key(XfdesktopIconView *icon_view, + GdkEventKey *evt, + GList *icon_list) +{ + XfdesktopIcon *icon = NULL; + const gchar *label; + gunichar lchar, kchar; + GList *l; + + /* Do it case-insensitive */ + kchar = g_unichar_tolower(gdk_keyval_to_unicode(evt->keyval)); + for(l = icon_list; l; l = l->next) { + icon = (XfdesktopIcon *)l->data; + label = xfdesktop_icon_peek_label(icon); + if(label && g_utf8_validate(label, g_utf8_strlen(label, -1), NULL) == TRUE) { + lchar = g_unichar_tolower(g_utf8_get_char(label)); + if(lchar == kchar) { + icon_view->priv->cursor = icon; + xfdesktop_icon_view_select_item(icon_view, icon); + return TRUE; + } + } + } + + return FALSE; +} + +static void +xfdesktop_icon_view_type_ahead_find_icon(XfdesktopIconView *icon_view, + GdkEventKey *evt) +{ + GList *icon_list_p_current_cursor; + gboolean icon_selected = FALSE; + + xfdesktop_icon_view_unselect_all(icon_view); + + /* If we have a cursor, we try to select the next matching item after the cursor */ + if(icon_view->priv->cursor != NULL) { + icon_list_p_current_cursor = g_list_find(icon_view->priv->icons, icon_view->priv->cursor); + icon_selected = xfdesktop_icon_view_select_icon_from_list_by_key(icon_view, evt, + g_list_next(icon_list_p_current_cursor)); + } + + /* still nothing is selected, select first icon from the beginning of the list */ + if(icon_selected == FALSE) { + xfdesktop_icon_view_select_icon_from_list_by_key(icon_view, + evt, + icon_view->priv->icons); + } +} + +static gboolean xfdesktop_icon_view_key_press(GtkWidget *widget, GdkEventKey *evt, gpointer user_data) { XfdesktopIconView *icon_view = XFDESKTOP_ICON_VIEW(user_data); + gboolean ret = FALSE; DBG("entering"); /* since we're NO_WINDOW, events don't get delivered to us normally, * so we have to activate the bindings manually */ - return gtk_bindings_activate_event(G_OBJECT(icon_view), evt); + ret = gtk_bindings_activate_event(G_OBJECT(icon_view), evt); + if(ret == FALSE) { + /* Binding not found, now inspect the pressed character. + * Let's try to find an icon starting with this character and make + * the icon selected. */ + guint32 unicode = gdk_keyval_to_unicode(evt->keyval); + if(unicode && g_unichar_isgraph(unicode) == TRUE) + xfdesktop_icon_view_type_ahead_find_icon(icon_view, evt); + } + + return ret; } static gboolean |