--- thunar-tree-view.c 2014-11-07 03:34:15.179243886 +0000 +++ thunar-tree-view_new.c 2014-11-07 03:33:45.859244862 +0000 @@ -97,6 +97,8 @@ GdkEventButton *event); static gboolean thunar_tree_view_button_release_event (GtkWidget *widget, GdkEventButton *event); +static gboolean thunar_tree_view_key_press_event (GtkWidget *widget, + GdkEventKey *event); static void thunar_tree_view_drag_data_received (GtkWidget *widget, GdkDragContext *context, gint x, @@ -432,6 +434,9 @@ gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); gtk_tree_selection_set_select_function (selection, thunar_tree_view_selection_func, view, NULL); + /* custom keyboard handler for better navigation */ + g_signal_connect (GTK_WIDGET (view), "key_press_event", G_CALLBACK (thunar_tree_view_key_press_event), NULL); + /* enable drop support for the tree view */ gtk_drag_dest_set (GTK_WIDGET (view), 0, drop_targets, G_N_ELEMENTS (drop_targets), GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_MOVE); @@ -763,6 +768,66 @@ return (*GTK_WIDGET_CLASS (thunar_tree_view_parent_class)->button_release_event) (widget, event); } +static gboolean +thunar_tree_view_key_press_event(GtkWidget *widget, + GdkEventKey *event) +{ + ThunarTreeView *tree_view = THUNAR_TREE_VIEW (widget); + + /* Get path of currently highlighted item */ + GtkTreePath *path; + GtkTreeViewColumn *column; + gtk_tree_view_get_cursor(GTK_TREE_VIEW (tree_view), &path, &column); + + /* This will be the final return value, + TRUE if we want to swallow the keystroke */ + gboolean stopPropagation = FALSE; + + switch (event->keyval) + { + case GDK_KEY_Left: + /* If branch is expanded then collapse it */ + if (gtk_tree_view_row_expanded (GTK_TREE_VIEW (tree_view), path)) + { + gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree_view), path); + } + /* Else if branch is already collapsed then move to parent + (if there is one) */ + else + { + if (gtk_tree_path_get_depth(path) > 1) + { + if (gtk_tree_path_up(path)) + { + gtk_tree_view_set_cursor(GTK_TREE_VIEW (tree_view), path, NULL, FALSE); + } + } + } + + stopPropagation = TRUE; + break; + + case GDK_KEY_Right: + /* If branch is not expanded then expand it */ + if (!gtk_tree_view_row_expanded (GTK_TREE_VIEW (tree_view), path)) + { + gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE); + } + /* Else if branch is already expanded then move to first child */ + else + { + gtk_tree_path_down(path); + gtk_tree_view_set_cursor(GTK_TREE_VIEW (tree_view), path, NULL, FALSE); + } + + stopPropagation = TRUE; + break; + } + + gtk_tree_path_free(path); + + return stopPropagation; +} static void