[gnome-control-center] keyboard: add support for system, app, user groups of keybindings
- From: William Jon McCann <mccann src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center] keyboard: add support for system, app, user groups of keybindings
- Date: Wed, 19 Jan 2011 02:00:06 +0000 (UTC)
commit fe305ff6feecd8ca606123536a812897be4e5752
Author: William Jon McCann <jmccann redhat com>
Date: Tue Jan 18 20:59:04 2011 -0500
keyboard: add support for system, app, user groups of keybindings
panels/keyboard/00-multimedia-key.xml.in | 2 +-
panels/keyboard/01-desktop-key.xml.in | 2 +-
panels/keyboard/keyboard-shortcuts.c | 212 ++++++++++++++++++++++++------
3 files changed, 175 insertions(+), 41 deletions(-)
---
diff --git a/panels/keyboard/00-multimedia-key.xml.in b/panels/keyboard/00-multimedia-key.xml.in
index 5650785..8d67e5c 100644
--- a/panels/keyboard/00-multimedia-key.xml.in
+++ b/panels/keyboard/00-multimedia-key.xml.in
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<KeyListEntries _name="Sound and Media">
+<KeyListEntries group="system" _name="Sound and Media">
<KeyListEntry
name="/apps/gnome_settings_daemon/keybindings/volume_mute" />
diff --git a/panels/keyboard/01-desktop-key.xml.in b/panels/keyboard/01-desktop-key.xml.in
index f41567c..8517ca8 100644
--- a/panels/keyboard/01-desktop-key.xml.in
+++ b/panels/keyboard/01-desktop-key.xml.in
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<KeyListEntries _name="Launchers and Actions">
+<KeyListEntries group="system" _name="Launchers and Actions">
<KeyListEntry
name="/apps/gnome_settings_daemon/keybindings/help" />
diff --git a/panels/keyboard/keyboard-shortcuts.c b/panels/keyboard/keyboard-shortcuts.c
index 82358b0..f41d8e4 100644
--- a/panels/keyboard/keyboard-shortcuts.c
+++ b/panels/keyboard/keyboard-shortcuts.c
@@ -31,6 +31,8 @@
typedef struct {
char *name;
+ /* The group of keybindings (system or application) */
+ char *group;
/* The gettext package to use to translate the section title */
char *package;
/* Name of the window manager the keys would apply to */
@@ -77,9 +79,23 @@ typedef struct
enum
{
- DESCRIPTION_COLUMN,
- KEYENTRY_COLUMN,
- N_COLUMNS
+ BINDING_GROUP_SYSTEM,
+ BINDING_GROUP_APP,
+ BINDING_GROUP_USER,
+};
+
+enum
+{
+ DETAIL_DESCRIPTION_COLUMN,
+ DETAIL_KEYENTRY_COLUMN,
+ DETAIL_N_COLUMNS
+};
+
+enum
+{
+ SECTION_DESCRIPTION_COLUMN,
+ SECTION_GROUP_COLUMN,
+ SECTION_N_COLUMNS
};
static guint maybe_block_accels_id = 0;
@@ -200,7 +216,7 @@ keybinding_key_changed_foreach (GtkTreeModel *model,
key_entry = (KeyEntry *)user_data;
gtk_tree_model_get (key_entry->model, iter,
- KEYENTRY_COLUMN, &tmp_key_entry,
+ DETAIL_KEYENTRY_COLUMN, &tmp_key_entry,
-1);
if (key_entry == tmp_key_entry)
@@ -271,16 +287,21 @@ keybinding_command_changed (GConfClient *client,
}
static void
-append_section (GtkBuilder *builder, const gchar *title, const KeyListEntry *keys_list)
+append_section (GtkBuilder *builder,
+ const gchar *title,
+ int group,
+ const KeyListEntry *keys_list)
{
GPtrArray *keys_array;
+ GtkTreeModel *sort_model;
GtkTreeModel *model;
GConfClient *client;
GtkTreeIter iter;
gint i;
client = gconf_client_get_default ();
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (gtk_builder_get_object (builder, "section_treeview")));
+ sort_model = gtk_tree_view_get_model (GTK_TREE_VIEW (gtk_builder_get_object (builder, "section_treeview")));
+ model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (sort_model));
/* Add all KeyEntry's for this section */
keys_array = g_ptr_array_new ();
@@ -392,13 +413,26 @@ append_section (GtkBuilder *builder, const gchar *title, const KeyListEntry *key
/* Add the keys to the hash table */
if (keys_array->len > 0)
{
+ static gboolean have_sep = FALSE;
+
g_hash_table_insert (kb_sections, g_strdup (title), keys_array);
/* Append the section to the left tree view */
gtk_list_store_append (GTK_LIST_STORE (model), &iter);
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
- DESCRIPTION_COLUMN, title,
+ SECTION_DESCRIPTION_COLUMN, title,
+ SECTION_GROUP_COLUMN, group,
-1);
+ if (!have_sep && group != BINDING_GROUP_SYSTEM)
+ {
+ have_sep = TRUE;
+ /* Append the section to the left tree view */
+ gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+ SECTION_DESCRIPTION_COLUMN, NULL,
+ SECTION_GROUP_COLUMN, BINDING_GROUP_SYSTEM,
+ -1);
+ }
}
}
@@ -423,6 +457,7 @@ parse_start_tag (GMarkupParseContext *ctx,
{
const char *wm_name = NULL;
const char *package = NULL;
+ const char *group = NULL;
while (*attr_names && *attr_values)
{
@@ -430,6 +465,9 @@ parse_start_tag (GMarkupParseContext *ctx,
{
if (**attr_values)
name = *attr_values;
+ } else if (g_str_equal (*attr_names, "group")) {
+ if (**attr_values)
+ group = *attr_values;
} else if (g_str_equal (*attr_names, "wm_name")) {
if (**attr_values)
wm_name = *attr_values;
@@ -462,6 +500,13 @@ parse_start_tag (GMarkupParseContext *ctx,
g_free (keylist->package);
keylist->package = g_strdup (package);
}
+ if (group)
+ {
+ if (keylist->group)
+ g_warning ("Duplicate group");
+ g_free (keylist->group);
+ keylist->group = g_strdup (group);
+ }
return;
}
@@ -541,6 +586,7 @@ append_sections_from_file (GtkBuilder *builder, const gchar *path, gchar **wm_ke
KeyList *keylist;
KeyListEntry key, *keys;
const char *title;
+ int group;
guint i;
GMarkupParseContext *ctx;
GMarkupParser parser = { parse_start_tag, NULL, NULL, NULL, NULL };
@@ -602,8 +648,12 @@ append_sections_from_file (GtkBuilder *builder, const gchar *path, gchar **wm_ke
} else {
title = _(keylist->name);
}
+ if (keylist->group && strcmp (keylist->group, "system") == 0)
+ group = BINDING_GROUP_SYSTEM;
+ else
+ group = BINDING_GROUP_APP;
- append_section (builder, title, keys);
+ append_section (builder, title, group, keys);
g_free (keylist->name);
g_free (keylist->package);
@@ -656,7 +706,7 @@ append_sections_from_gconf (GtkBuilder *builder, const gchar *gconf_path)
g_array_append_val (entries, key);
keys = (KeyListEntry *) entries->data;
- append_section (builder, _("Custom Shortcuts"), keys);
+ append_section (builder, _("Custom Shortcuts"), BINDING_GROUP_USER, keys);
for (i = 0; i < entries->len; ++i)
{
g_free (keys[i].name);
@@ -673,9 +723,13 @@ reload_sections (GtkBuilder *builder)
gchar **wm_keybindings;
GDir *dir;
const gchar *name;
- GtkTreeModel *section_model, *shortcut_model;
+ GtkTreeModel *sort_model;
+ GtkTreeModel *section_model;
+ GtkTreeModel *shortcut_model;
+
+ sort_model = gtk_tree_view_get_model (GTK_TREE_VIEW (gtk_builder_get_object (builder, "section_treeview")));
+ section_model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (sort_model));
- section_model = gtk_tree_view_get_model (GTK_TREE_VIEW (gtk_builder_get_object (builder, "section_treeview")));
shortcut_model = gtk_tree_view_get_model (GTK_TREE_VIEW (gtk_builder_get_object (builder, "shortcut_treeview")));
/* FIXME: get current selection and keep it after refreshing */
@@ -720,7 +774,7 @@ accel_set_func (GtkTreeViewColumn *tree_column,
KeyEntry *key_entry;
gtk_tree_model_get (model, iter,
- KEYENTRY_COLUMN, &key_entry,
+ DETAIL_KEYENTRY_COLUMN, &key_entry,
-1);
if (key_entry == NULL)
@@ -757,7 +811,7 @@ description_set_func (GtkTreeViewColumn *tree_column,
KeyEntry *key_entry;
gtk_tree_model_get (model, iter,
- KEYENTRY_COLUMN, &key_entry,
+ DETAIL_KEYENTRY_COLUMN, &key_entry,
-1);
if (key_entry != NULL)
@@ -786,7 +840,7 @@ section_selection_changed (GtkTreeSelection *selection, gpointer data)
gchar *description;
gint i;
- gtk_tree_model_get (model, &iter, DESCRIPTION_COLUMN, &description, -1);
+ gtk_tree_model_get (model, &iter, SECTION_DESCRIPTION_COLUMN, &description, -1);
keys = g_hash_table_lookup (kb_sections, description);
if (keys == NULL)
{
@@ -806,8 +860,8 @@ section_selection_changed (GtkTreeSelection *selection, gpointer data)
gtk_list_store_append (GTK_LIST_STORE (shortcut_model), &new_row);
gtk_list_store_set (GTK_LIST_STORE (shortcut_model), &new_row,
- DESCRIPTION_COLUMN, entry->description,
- KEYENTRY_COLUMN, entry,
+ DETAIL_DESCRIPTION_COLUMN, entry->description,
+ DETAIL_KEYENTRY_COLUMN, entry,
-1);
}
}
@@ -825,7 +879,7 @@ shortcut_selection_changed (GtkTreeSelection *selection, gpointer data)
can_remove = FALSE;
if (gtk_tree_selection_get_selected (selection, &model, &iter))
{
- gtk_tree_model_get (model, &iter, KEYENTRY_COLUMN, &key, -1);
+ gtk_tree_model_get (model, &iter, DETAIL_KEYENTRY_COLUMN, &key, -1);
if (key && key->command != NULL && key->editable)
can_remove = TRUE;
}
@@ -885,7 +939,7 @@ remove_custom_shortcut (GtkTreeModel *model, GtkTreeIter *iter)
KeyEntry *key;
gtk_tree_model_get (model, iter,
- KEYENTRY_COLUMN, &key,
+ DETAIL_KEYENTRY_COLUMN, &key,
-1);
/* not a custom shortcut */
@@ -930,7 +984,7 @@ update_custom_shortcut (GtkTreeModel *model, GtkTreeIter *iter)
KeyEntry *key;
gtk_tree_model_get (model, iter,
- KEYENTRY_COLUMN, &key,
+ DETAIL_KEYENTRY_COLUMN, &key,
-1);
edit_custom_shortcut (key);
@@ -943,7 +997,7 @@ update_custom_shortcut (GtkTreeModel *model, GtkTreeIter *iter)
GConfClient *client;
gtk_tree_store_set (GTK_TREE_STORE (model), iter,
- KEYENTRY_COLUMN, key, -1);
+ DETAIL_KEYENTRY_COLUMN, key, -1);
client = gconf_client_get_default ();
if (key->description != NULL)
gconf_client_set_string (client, key->desc_gconf_key, key->description, NULL);
@@ -998,7 +1052,7 @@ start_editing_cb (GtkTreeView *tree_view,
model = gtk_tree_view_get_model (tree_view);
gtk_tree_model_get_iter (model, &iter, path);
gtk_tree_model_get (model, &iter,
- KEYENTRY_COLUMN, &key,
+ DETAIL_KEYENTRY_COLUMN, &key,
-1);
/* if only the accel can be edited on the selected row
@@ -1040,7 +1094,7 @@ start_editing_kb_cb (GtkTreeView *treeview,
model = gtk_tree_view_get_model (treeview);
gtk_tree_model_get_iter (model, &iter, path);
gtk_tree_model_get (model, &iter,
- KEYENTRY_COLUMN, &key,
+ DETAIL_KEYENTRY_COLUMN, &key,
-1);
if (key == NULL)
@@ -1092,7 +1146,7 @@ description_edited_callback (GtkCellRendererText *renderer,
gtk_tree_path_free (path);
gtk_tree_model_get (model, &iter,
- KEYENTRY_COLUMN, &key_entry,
+ DETAIL_KEYENTRY_COLUMN, &key_entry,
-1);
/* sanity check */
@@ -1180,7 +1234,7 @@ cb_check_for_uniqueness (GtkTreeModel *model,
KeyEntry *element;
gtk_tree_model_get (new_key->model, iter,
- KEYENTRY_COLUMN, &element,
+ DETAIL_KEYENTRY_COLUMN, &element,
-1);
/* no conflict for : blanks, different modifiers, or ourselves */
@@ -1225,7 +1279,7 @@ accel_edited_callback (GtkCellRendererText *cell,
gtk_tree_model_get_iter (model, &iter, path);
gtk_tree_path_free (path);
gtk_tree_model_get (model, &iter,
- KEYENTRY_COLUMN, &key_entry,
+ DETAIL_KEYENTRY_COLUMN, &key_entry,
-1);
/* sanity check */
@@ -1414,7 +1468,7 @@ accel_cleared_callback (GtkCellRendererText *cell,
gtk_tree_model_get_iter (model, &iter, path);
gtk_tree_path_free (path);
gtk_tree_model_get (model, &iter,
- KEYENTRY_COLUMN, &key_entry,
+ DETAIL_KEYENTRY_COLUMN, &key_entry,
-1);
/* sanity check */
@@ -1551,7 +1605,7 @@ add_custom_shortcut (GtkTreeView *tree_view,
g_ptr_array_add (keys_array, key_entry);
gtk_list_store_append (GTK_LIST_STORE (model), &iter);
- gtk_list_store_set (GTK_LIST_STORE (model), &iter, KEYENTRY_COLUMN, key_entry, -1);
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter, DETAIL_KEYENTRY_COLUMN, key_entry, -1);
/* store in gconf */
client = gconf_client_get_default ();
@@ -1639,12 +1693,12 @@ keyentry_sort_func (GtkTreeModel *model,
key_entry_a = NULL;
gtk_tree_model_get (model, a,
- KEYENTRY_COLUMN, &key_entry_a,
+ DETAIL_KEYENTRY_COLUMN, &key_entry_a,
-1);
key_entry_b = NULL;
gtk_tree_model_get (model, b,
- KEYENTRY_COLUMN, &key_entry_b,
+ DETAIL_KEYENTRY_COLUMN, &key_entry_b,
-1);
if (key_entry_a && key_entry_b)
@@ -1686,6 +1740,69 @@ keyentry_sort_func (GtkTreeModel *model,
return retval;
}
+static int
+section_sort_item (GtkTreeModel *model,
+ GtkTreeIter *a,
+ GtkTreeIter *b,
+ gpointer data)
+{
+ char *a_desc;
+ int a_group;
+ char *b_desc;
+ int b_group;
+ int ret;
+
+ ret = 0;
+
+ gtk_tree_model_get (model, a,
+ SECTION_DESCRIPTION_COLUMN, &a_desc,
+ SECTION_GROUP_COLUMN, &a_group,
+ -1);
+ gtk_tree_model_get (model, b,
+ SECTION_DESCRIPTION_COLUMN, &b_desc,
+ SECTION_GROUP_COLUMN, &b_group,
+ -1);
+
+ if (a_group == b_group)
+ {
+ /* separators go after the section */
+ if (a_desc == NULL)
+ ret = 1;
+ else if (b_desc == NULL)
+ ret = -1;
+ else
+ ret = g_utf8_collate (a_desc, b_desc);
+ }
+ else
+ {
+ if (a_group < b_group)
+ ret = -1;
+ else
+ ret = 1;
+ }
+
+ return ret;
+}
+
+static gboolean
+sections_separator_func (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ char *description;
+ gboolean is_separator;
+
+ description = NULL;
+ is_separator = FALSE;
+
+ gtk_tree_model_get (model, iter, SECTION_DESCRIPTION_COLUMN, &description, -1);
+ if (description == NULL)
+ is_separator = TRUE;
+ g_free (description);
+
+ return is_separator;
+}
+
static void
setup_dialog (CcPanel *panel, GtkBuilder *builder)
{
@@ -1698,21 +1815,38 @@ setup_dialog (CcPanel *panel, GtkBuilder *builder)
GSList *allowed_keys;
CcShell *shell;
GtkListStore *model;
+ GtkTreeModelSort *sort_model;
/* Setup the section treeview */
treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "section_treeview"));
+ gtk_tree_view_set_row_separator_func (GTK_TREE_VIEW (treeview),
+ sections_separator_func,
+ panel,
+ NULL);
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes (_("Section"),
renderer,
- "text", DESCRIPTION_COLUMN,
+ "text", SECTION_DESCRIPTION_COLUMN,
NULL);
gtk_tree_view_append_column (treeview, column);
- model = gtk_list_store_new (1, G_TYPE_STRING);
- gtk_tree_view_set_model (treeview, GTK_TREE_MODEL (model));
+ model = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
+ sort_model = GTK_TREE_MODEL_SORT (gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (model)));
+ gtk_tree_view_set_model (treeview, GTK_TREE_MODEL (sort_model));
g_object_unref (model);
+ gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (sort_model),
+ SECTION_DESCRIPTION_COLUMN,
+ section_sort_item,
+ panel,
+ NULL);
+
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
+ SECTION_DESCRIPTION_COLUMN,
+ GTK_SORT_ASCENDING);
+ g_object_unref (sort_model);
+
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
g_signal_connect (selection, "changed",
G_CALLBACK (section_selection_changed), builder);
@@ -1736,13 +1870,13 @@ setup_dialog (CcPanel *panel, GtkBuilder *builder)
column = gtk_tree_view_column_new_with_attributes (_("Action"),
renderer,
- "text", DESCRIPTION_COLUMN,
+ "text", DETAIL_DESCRIPTION_COLUMN,
NULL);
gtk_tree_view_column_set_cell_data_func (column, renderer, description_set_func, NULL, NULL);
gtk_tree_view_column_set_resizable (column, FALSE);
gtk_tree_view_append_column (treeview, column);
- gtk_tree_view_column_set_sort_column_id (column, DESCRIPTION_COLUMN);
+ gtk_tree_view_column_set_sort_column_id (column, DETAIL_DESCRIPTION_COLUMN);
renderer = (GtkCellRenderer *) g_object_new (EGG_TYPE_CELL_RENDERER_KEYS,
"accel_mode", EGG_CELL_RENDERER_KEYS_MODE_X,
@@ -1761,7 +1895,7 @@ setup_dialog (CcPanel *panel, GtkBuilder *builder)
gtk_tree_view_column_set_resizable (column, FALSE);
gtk_tree_view_append_column (treeview, column);
- gtk_tree_view_column_set_sort_column_id (column, KEYENTRY_COLUMN);
+ gtk_tree_view_column_set_sort_column_id (column, DETAIL_KEYENTRY_COLUMN);
gconf_client_add_dir (client, GCONF_BINDING_DIR, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
gconf_client_add_dir (client, "/apps/metacity/general", GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
@@ -1770,11 +1904,11 @@ setup_dialog (CcPanel *panel, GtkBuilder *builder)
(GConfClientNotifyFunc) key_entry_controlling_key_changed,
builder, NULL, NULL);
- model = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_POINTER);
+ model = gtk_list_store_new (DETAIL_N_COLUMNS, G_TYPE_STRING, G_TYPE_POINTER);
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (model),
- KEYENTRY_COLUMN,
- keyentry_sort_func,
- NULL, NULL);
+ DETAIL_KEYENTRY_COLUMN,
+ keyentry_sort_func,
+ NULL, NULL);
gtk_tree_view_set_model (treeview, GTK_TREE_MODEL (model));
g_object_unref (model);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]