summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mate-panel/panel-run-dialog.c156
1 files changed, 136 insertions, 20 deletions
diff --git a/mate-panel/panel-run-dialog.c b/mate-panel/panel-run-dialog.c
index e426cd56..73f1c2db 100644
--- a/mate-panel/panel-run-dialog.c
+++ b/mate-panel/panel-run-dialog.c
@@ -39,6 +39,7 @@
#include <unistd.h>
#include <glib/gi18n.h>
+#include <glib.h>
#include <gio/gio.h>
#include <gdk/gdkkeysyms.h>
#include <matemenu-tree.h>
@@ -106,6 +107,8 @@ typedef struct {
enum {
COLUMN_GICON,
COLUMN_NAME,
+ COLUMN_ACCELERATOR_MASK,
+ COLUMN_ACCELERATOR_KEY_VALUE,
COLUMN_COMMENT,
COLUMN_PATH,
COLUMN_EXEC,
@@ -113,6 +116,28 @@ enum {
NUM_COLUMNS
};
+typedef struct {
+ gint list_item_idx;
+ GdkModifierType modifier;
+ guint key_id;
+} AcceleratorKeyMapping;
+
+const AcceleratorKeyMapping accelerator_key_mapping[] =
+{
+ {0, GDK_MOD1_MASK, GDK_KEY_1 },
+ {1, GDK_MOD1_MASK, GDK_KEY_2 },
+ {2, GDK_MOD1_MASK, GDK_KEY_3 },
+ {3, GDK_MOD1_MASK, GDK_KEY_4 },
+ {4, GDK_MOD1_MASK, GDK_KEY_5 },
+ {5, GDK_MOD1_MASK, GDK_KEY_6 },
+ {6, GDK_MOD1_MASK, GDK_KEY_7 },
+ {7, GDK_MOD1_MASK, GDK_KEY_8 },
+ {8, GDK_MOD1_MASK, GDK_KEY_9 },
+ {9, GDK_MOD1_MASK, GDK_KEY_0 },
+};
+
+static GHashTable *accelerator_keys_to_tree_iter_map = NULL;
+
static PanelRunDialog *static_dialog = NULL;
static void panel_run_dialog_disconnect_pixmap (PanelRunDialog *dialog);
@@ -238,6 +263,10 @@ panel_run_dialog_destroy (PanelRunDialog *dialog)
g_hash_table_destroy (dialog->dir_hash);
dialog->dir_hash = NULL;
+ if (accelerator_keys_to_tree_iter_map)
+ g_hash_table_destroy (accelerator_keys_to_tree_iter_map);
+ accelerator_keys_to_tree_iter_map = NULL;
+
for (l = dialog->possible_executables; l; l = l->next)
g_free (l->data);
g_list_free (dialog->possible_executables);
@@ -664,19 +693,6 @@ fuzzy_command_match (const char *cmd1,
}
static gboolean
-panel_run_dialog_make_all_list_visible (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer data)
-{
- gtk_list_store_set (GTK_LIST_STORE (model), iter,
- COLUMN_VISIBLE, TRUE,
- -1);
-
- return FALSE;
-}
-
-static gboolean
panel_run_dialog_find_command_idle (PanelRunDialog *dialog)
{
GtkTreeIter iter;
@@ -686,6 +702,7 @@ panel_run_dialog_find_command_idle (PanelRunDialog *dialog)
GIcon *found_icon;
char *found_name;
gboolean fuzzy;
+ gint visible_program_idx = 0;
model = GTK_TREE_MODEL (dialog->program_list_store);
path = gtk_tree_path_new_first ();
@@ -704,12 +721,14 @@ panel_run_dialog_find_command_idle (PanelRunDialog *dialog)
found_icon = NULL;
found_name = NULL;
fuzzy = FALSE;
+ g_hash_table_remove_all (accelerator_keys_to_tree_iter_map);
do {
char *exec = NULL;
GIcon *icon = NULL;
char *name = NULL;
char *comment = NULL;
+ gboolean visible = FALSE;
gtk_tree_model_get (model, &iter,
COLUMN_EXEC, &exec,
@@ -744,6 +763,23 @@ panel_run_dialog_find_command_idle (PanelRunDialog *dialog)
-1);
}
+ gtk_tree_model_get (model, &iter, COLUMN_VISIBLE, &visible, -1);
+ if (visible && visible_program_idx < G_N_ELEMENTS (accelerator_key_mapping)) {
+ gtk_list_store_set (dialog->program_list_store,
+ &iter,
+ COLUMN_ACCELERATOR_MASK, (gint)accelerator_key_mapping[visible_program_idx].modifier,
+ COLUMN_ACCELERATOR_KEY_VALUE, accelerator_key_mapping[visible_program_idx].key_id,
+ -1);
+ g_hash_table_insert (accelerator_keys_to_tree_iter_map, GUINT_TO_POINTER(accelerator_key_mapping[visible_program_idx].key_id), GINT_TO_POINTER(visible_program_idx));
+ visible_program_idx++;
+ } else {
+ gtk_list_store_set (dialog->program_list_store,
+ &iter,
+ COLUMN_ACCELERATOR_MASK, 0,
+ COLUMN_ACCELERATOR_KEY_VALUE, 0,
+ -1);
+ }
+
g_free (exec);
if (icon != NULL)
g_object_unref (icon);
@@ -895,6 +931,8 @@ panel_run_dialog_add_items_idle (PanelRunDialog *dialog)
dialog->program_list_store = gtk_list_store_new (NUM_COLUMNS,
G_TYPE_ICON,
G_TYPE_STRING,
+ G_TYPE_INT, // For accelerator modifier mask
+ G_TYPE_UINT, // For accelerator key value
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_STRING,
@@ -922,6 +960,9 @@ panel_run_dialog_add_items_idle (PanelRunDialog *dialog)
}
}
+ gint i = 0;
+ g_hash_table_remove_all (accelerator_keys_to_tree_iter_map);
+
for (l = all_applications; l; l = l->next) {
MateMenuTreeEntry *entry = l->data;
GtkTreeIter iter;
@@ -940,6 +981,19 @@ panel_run_dialog_add_items_idle (PanelRunDialog *dialog)
COLUMN_PATH, matemenu_tree_entry_get_desktop_file_path (entry),
COLUMN_VISIBLE, TRUE,
-1);
+ if (i < G_N_ELEMENTS (accelerator_key_mapping)) {
+ gtk_list_store_set (dialog->program_list_store, &iter,
+ COLUMN_ACCELERATOR_MASK, (gint)accelerator_key_mapping[i].modifier,
+ COLUMN_ACCELERATOR_KEY_VALUE, accelerator_key_mapping[i].key_id,
+ -1);
+ g_hash_table_insert (accelerator_keys_to_tree_iter_map, GUINT_TO_POINTER(accelerator_key_mapping[i].key_id), GINT_TO_POINTER(i));
+ i++;
+ } else {
+ gtk_list_store_set (dialog->program_list_store, &iter,
+ COLUMN_ACCELERATOR_MASK, (gint)GDK_MOD1_MASK,
+ COLUMN_ACCELERATOR_KEY_VALUE, 0,
+ -1);
+ }
}
g_slist_free_full (all_applications, matemenu_tree_item_unref);
@@ -963,11 +1017,23 @@ panel_run_dialog_add_items_idle (PanelRunDialog *dialog)
NULL);
renderer = gtk_cell_renderer_text_new ();
- gtk_tree_view_column_pack_start (column, renderer, TRUE);
+ gtk_tree_view_column_pack_start (column, renderer, FALSE);
gtk_tree_view_column_set_attributes (column, renderer,
"text", COLUMN_NAME,
NULL);
+ gtk_tree_view_column_set_sizing (column,
+ GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+
+ gtk_tree_view_append_column (GTK_TREE_VIEW (dialog->program_list), column);
+
+ renderer = gtk_cell_renderer_accel_new ();
+ g_object_set (renderer, "accel-mode", GTK_CELL_RENDERER_ACCEL_MODE_GTK,
+ "editable", FALSE, NULL);
+
+ column = gtk_tree_view_column_new_with_attributes ("Shortcut", renderer,
+ "accel-mods", COLUMN_ACCELERATOR_MASK, "accel-key",
+ COLUMN_ACCELERATOR_KEY_VALUE, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (dialog->program_list), column);
dialog->add_items_idle_id = 0;
@@ -1630,12 +1696,31 @@ combobox_changed (GtkComboBox *combobox,
}
if (panel_profile_get_enable_program_list ()) {
- GtkTreeIter iter;
- GtkTreePath *path;
-
- gtk_tree_model_foreach (GTK_TREE_MODEL (dialog->program_list_store),
- panel_run_dialog_make_all_list_visible,
- NULL);
+ GtkTreeIter iter;
+ GtkTreePath *path;
+ GtkTreeModel *model;
+ gint i = 0;
+ gboolean valid = FALSE;
+
+ g_hash_table_remove_all (accelerator_keys_to_tree_iter_map);
+ model = GTK_TREE_MODEL (dialog->program_list_store);
+ for (valid = gtk_tree_model_get_iter_first (model, &iter); valid; valid = gtk_tree_model_iter_next (model, &iter)) {
+ if (i < G_N_ELEMENTS (accelerator_key_mapping)) {
+ gtk_list_store_set (GTK_LIST_STORE (GTK_TREE_MODEL (dialog->program_list_store)), &iter,
+ COLUMN_VISIBLE, TRUE,
+ COLUMN_ACCELERATOR_MASK, (gint)accelerator_key_mapping[i].modifier,
+ COLUMN_ACCELERATOR_KEY_VALUE, accelerator_key_mapping[i].key_id,
+ -1);
+ g_hash_table_insert (accelerator_keys_to_tree_iter_map, GUINT_TO_POINTER (accelerator_key_mapping[i].key_id), GINT_TO_POINTER(i));
+ i++;
+ } else {
+ gtk_list_store_set (GTK_LIST_STORE (GTK_TREE_MODEL (dialog->program_list_store)), &iter,
+ COLUMN_VISIBLE, TRUE,
+ COLUMN_ACCELERATOR_MASK, (gint)GDK_MOD1_MASK,
+ COLUMN_ACCELERATOR_KEY_VALUE, 0,
+ -1);
+ }
+ }
path = gtk_tree_path_new_first ();
if (gtk_tree_model_get_iter (gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->program_list)),
@@ -1945,6 +2030,22 @@ key_press_event (GtkWidget *run_dialog,
return FALSE;
}
+static void
+panel_run_dialog_accelerator_key_pressed (GtkAccelGroup *accel_group,
+ GObject *acceleratable,
+ guint keyval,
+ GdkModifierType modifier,
+ PanelRunDialog *dialog)
+{
+ GtkTreePath *path;
+ gpointer index_of_entry;
+ gboolean found = g_hash_table_lookup_extended (accelerator_keys_to_tree_iter_map, GUINT_TO_POINTER(keyval), NULL, &index_of_entry);
+ if (!found) return;
+ path = gtk_tree_path_new_from_indices(GPOINTER_TO_INT(index_of_entry), -1);
+ gtk_tree_view_set_cursor (GTK_TREE_VIEW (dialog->program_list), path, NULL, FALSE);
+ gtk_widget_grab_focus (dialog->program_list);
+}
+
static PanelRunDialog *
panel_run_dialog_new (GdkScreen *screen,
GtkBuilder *gui,
@@ -1962,6 +2063,20 @@ panel_run_dialog_new (GdkScreen *screen,
g_signal_connect_swapped (dialog->run_dialog, "destroy",
G_CALLBACK (panel_run_dialog_destroy), dialog);
+ GtkAccelGroup* accel_group = gtk_accel_group_new ();
+ gtk_window_add_accel_group (GTK_WINDOW(dialog->run_dialog), accel_group);
+ g_object_unref (accel_group);
+ for (gint i = 0; i < G_N_ELEMENTS (accelerator_key_mapping); i++)
+ {
+ GClosure *closure_key = g_cclosure_new (
+ G_CALLBACK (panel_run_dialog_accelerator_key_pressed), dialog, NULL);
+ gtk_accel_group_connect (accel_group,
+ accelerator_key_mapping[i].key_id,
+ accelerator_key_mapping[i].modifier,
+ 0,
+ closure_key);
+ }
+
dialog->run_button = PANEL_GTK_BUILDER_GET (gui, "run_button");
dialog->terminal_checkbox = PANEL_GTK_BUILDER_GET (gui, "terminal_checkbox");
@@ -2023,6 +2138,7 @@ panel_run_dialog_present (GdkScreen *screen,
guint32 activate_time)
{
GtkBuilder *gui;
+ accelerator_keys_to_tree_iter_map = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
if (panel_lockdown_get_disable_command_line ())
return;