@@ -599,22 +599,67 @@ action_split_view_same_location_callback (GtkAction *action,
599599 }
600600}
601601
602+ /* Focus the first selectable row in the sidebar tree view so that keyboard
603+ * navigation works immediately after switching sidebar type.
604+ * Detects whether the first row is a non-selectable heading (Places style,
605+ * which has group headers as parent rows) or a real directory entry (Tree
606+ * style) and picks "0:0" or "0" accordingly. */
607+ static gboolean
608+ focus_sidebar_idle (NemoWindow * window )
609+ {
610+ if (window -> details -> sidebar == NULL ) {
611+ return G_SOURCE_REMOVE ;
612+ }
613+
614+ GList * children = gtk_container_get_children (GTK_CONTAINER (window -> details -> sidebar ));
615+ for (GList * l = children ; l != NULL ; l = l -> next ) {
616+ GtkWidget * child = GTK_WIDGET (l -> data );
617+ if (GTK_IS_SCROLLED_WINDOW (child )) {
618+ GtkWidget * inner = gtk_bin_get_child (GTK_BIN (child ));
619+ if (GTK_IS_TREE_VIEW (inner )) {
620+ GtkTreeView * tv = GTK_TREE_VIEW (inner );
621+ GtkTreeModel * model = gtk_tree_view_get_model (tv );
622+ GtkTreeIter iter , child_iter ;
623+ const gchar * path_str = "0" ;
624+
625+ /* If the first row has children it is a heading (Places),
626+ * so select the first child row instead. */
627+ if (model != NULL &&
628+ gtk_tree_model_get_iter_first (model , & iter ) &&
629+ gtk_tree_model_iter_children (model , & child_iter , & iter )) {
630+ path_str = "0:0" ;
631+ }
632+
633+ GtkTreePath * path = gtk_tree_path_new_from_string (path_str );
634+ gtk_tree_view_set_cursor (tv , path , NULL , FALSE);
635+ gtk_widget_grab_focus (GTK_WIDGET (tv ));
636+ gtk_tree_path_free (path );
637+ break ;
638+ }
639+ }
640+ }
641+ g_list_free (children );
642+ return G_SOURCE_REMOVE ;
643+ }
644+
602645static void
603646action_show_places_callback (GtkAction * action ,
604647 gpointer user_data )
605648{
606649 NemoWindow * window = NEMO_WINDOW (user_data );
650+ nemo_window_show_sidebar (window );
607651 nemo_window_set_sidebar_id (window , NEMO_WINDOW_SIDEBAR_PLACES );
608- nemo_window_set_show_sidebar ( window , TRUE );
652+ g_idle_add (( GSourceFunc ) focus_sidebar_idle , window );
609653}
610654
611655static void
612656action_show_treeview_callback (GtkAction * action ,
613657 gpointer user_data )
614658{
615659 NemoWindow * window = NEMO_WINDOW (user_data );
660+ nemo_window_show_sidebar (window );
616661 nemo_window_set_sidebar_id (window , NEMO_WINDOW_SIDEBAR_TREE );
617- nemo_window_set_show_sidebar ( window , TRUE );
662+ g_idle_add (( GSourceFunc ) focus_sidebar_idle , window );
618663}
619664
620665static void
@@ -2793,6 +2838,18 @@ nemo_window_initialize_menus (NemoWindow *window)
27932838 /* add the UI */
27942839 gtk_ui_manager_add_ui_from_resource (ui_manager , "/org/nemo/nemo-shell-ui.xml" , NULL );
27952840
2841+ /* Explicitly connect accelerators for actions that have no menu proxy.
2842+ * Without a proxy widget, gtk_action_connect_accelerator() is never called
2843+ * automatically, so the accel group never receives the binding. */
2844+ {
2845+ GtkAccelGroup * accel_group = gtk_ui_manager_get_accel_group (ui_manager );
2846+ GtkAction * a ;
2847+ a = gtk_action_group_get_action (window -> details -> main_action_group , NEMO_ACTION_SHOW_PLACES );
2848+ if (a ) { gtk_action_set_accel_group (a , accel_group ); gtk_action_connect_accelerator (a ); }
2849+ a = gtk_action_group_get_action (window -> details -> main_action_group , NEMO_ACTION_SHOW_TREEVIEW );
2850+ if (a ) { gtk_action_set_accel_group (a , accel_group ); gtk_action_connect_accelerator (a ); }
2851+ }
2852+
27962853 GtkWidget * menuitem , * submenu ;
27972854 menuitem = gtk_ui_manager_get_widget (nemo_window_get_ui_manager (window ), NEMO_VIEW_MENUBAR_FILE_PATH );
27982855 submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (menuitem ));
0 commit comments