--- a/menus.c 2012-03-01 22:19:32.633118556 -0600 +++ b/menus.c 2012-03-01 22:06:58.822666947 -0600 @@ -244,6 +244,19 @@ hook_dissociate_full (item->hook, (HookFunction) hook_cb, check); } +static void hotkey_changed (GtkAccelMap *object, gchar *accel_path, guint accel_key, + GdkModifierType accel_mods, gpointer user_data) +{ + if (g_str_has_prefix (accel_path, "/")) + { + gchar *entry = g_strconcat ("key_", accel_path+strlen("/"), NULL); + gchar *name=gtk_accelerator_name (accel_key, accel_mods); + aud_set_string ("gtkui", entry, name); + g_free (name); + g_free (entry); + } +} + static void populate_menu (GtkWidget * shell, const struct MenuItem * items, gint n_items, GtkAccelGroup * accel) { @@ -292,6 +305,7 @@ else { sub = gtk_menu_new (); + gtk_menu_set_accel_group (GTK_MENU (sub), accel); populate_menu (sub, item->items, item->n_items, accel); } @@ -303,9 +317,36 @@ if (! widget) continue; - if (item->key) - gtk_widget_add_accelerator (widget, "activate", accel, item->key, - item->mod, GTK_ACCEL_VISIBLE); + guint fkey = 0; + GdkModifierType fmod = 0; + if (item->identifier) + { + gchar *temp = g_strconcat ("key_", item->identifier, NULL); + gchar *nkey = aud_get_string ("gtkui", temp); + gtk_accelerator_parse (nkey, &fkey, &fmod); + g_free (nkey); + g_free (temp); + } + + if(!fkey) + { + fkey = item->key; + fmod = item->mod; + } + + if (fkey) + { + if (item->identifier) + { + gchar *accel_path=g_strconcat ("/", item->identifier, NULL); + gtk_menu_item_set_accel_path (GTK_MENU_ITEM (widget), accel_path); + gtk_accel_map_add_entry (accel_path, fkey, fmod); + g_free (accel_path); + } + else + gtk_widget_add_accelerator (widget, "activate", accel, fkey, + fmod, GTK_ACCEL_VISIBLE); + } gtk_widget_show (widget); gtk_menu_shell_append ((GtkMenuShell *) shell, widget); @@ -316,12 +357,14 @@ { GtkWidget * bar = gtk_menu_bar_new (); populate_menu (bar, main_items, G_N_ELEMENTS (main_items), accel); + g_signal_connect (gtk_accel_map_get (), "changed", G_CALLBACK (hotkey_changed), NULL); return bar; } GtkWidget * make_menu_main (GtkAccelGroup * accel) { GtkWidget * shell = gtk_menu_new (); + gtk_menu_set_accel_group (GTK_MENU (shell), accel); populate_menu (shell, main_items, G_N_ELEMENTS (main_items), accel); return shell; } @@ -329,6 +372,7 @@ GtkWidget * make_menu_rclick (GtkAccelGroup * accel) { GtkWidget * shell = gtk_menu_new (); + gtk_menu_set_accel_group (GTK_MENU (shell), accel); populate_menu (shell, rclick_items, G_N_ELEMENTS (rclick_items), accel); return shell; } @@ -336,6 +380,7 @@ GtkWidget * make_menu_tab (GtkAccelGroup * accel) { GtkWidget * shell = gtk_menu_new (); + gtk_menu_set_accel_group (GTK_MENU (shell), accel); populate_menu (shell, tab_items, G_N_ELEMENTS (tab_items), accel); return shell; } --- a/ui_gtk.c 2012-03-01 22:13:44.702653861 -0600 +++ b/ui_gtk.c 2012-03-01 22:13:29.522779015 -0600 @@ -483,6 +483,14 @@ static gboolean window_keypress_cb (GtkWidget * widget, GdkEventKey * event, void * unused) { + /* spacebar is handled specially by treeviews (libaudgui/list.c) so it needs some love here */ + if ((event->keyval == ' ' && ! (event->state & GDK_CONTROL_MASK)) && G_OBJECT_TYPE (G_OBJECT (gtk_window_get_focus (GTK_WINDOW (widget)))) == GTK_TYPE_TREE_VIEW) + return FALSE; + + /* prevent hotkeys from interfering with text input */ + if (gtk_window_propagate_key_event(GTK_WINDOW (widget), event)) + return TRUE; + switch (event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK)) { case GDK_CONTROL_MASK: