[gnome-terminal] keybindings: Port to gsettings
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-terminal] keybindings: Port to gsettings
- Date: Mon, 14 Jan 2013 16:55:19 +0000 (UTC)
commit b8171022016d40618a3ff291258053608c850257
Author: Christian Persch <chpe gnome org>
Date: Mon Jan 14 17:47:32 2013 +0100
keybindings: Port to gsettings
Redo the gconf->gsettings port of the keybindings part. Use gsettings
for the keybindings instead of the simple accel map file.
src/migration.c | 111 +++---
src/org.gnome.Terminal.gschema.xml.in | 143 +++++++-
src/terminal-accels.c | 670 ++++++++++++++++++++++++---------
src/terminal-schemas.h | 1 +
4 files changed, 683 insertions(+), 242 deletions(-)
---
diff --git a/src/migration.c b/src/migration.c
index 6760688..bb02039 100644
--- a/src/migration.c
+++ b/src/migration.c
@@ -1,5 +1,5 @@
/*
- * Copyright  2011 Christian Persch
+ * Copyright  2011, 2012, 2013 Christian Persch
*
* Gnome-terminal is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -508,80 +508,65 @@ migrate_profiles (GSettings *global_settings,
static gboolean
migrate_accels (GError **error)
{
- static const struct { const char *key; const char *path; } data[] = {
- { "new_tab", "FileNewTab" },
- { "new_window", "FileNewWindow" },
- { "new_profile", "FileNewProfile" },
- { "close_tab", "FileCloseTab" },
- { "close_window", "FileCloseWindow"},
- { "copy", "EditCopy" },
- { "paste", "EditPaste" },
- { "toggle_menubar", "ViewMenubar" },
- { "full_screen", "ViewFullscreen" },
- { "zoom_in", "ViewZoomIn" },
- { "zoom_out", "ViewZoomOut" },
- { "zoom_normal", "ViewZoom100" },
- { "set_window_title", "TerminalSetTitle" },
- { "reset", "TerminalReset" },
- { "reset_and_clear", "TerminalResetClear" },
- { "prev_tab", "TabsPrevious" },
- { "next_tab", "TabsNext" },
- { "move_tab_left", "TabsMoveLeft" },
- { "move_tab_right", "TabsMoveRight" },
- { "detach_tab", "TabsDetach" },
- { "switch_to_tab_1", "TabsSwitch1" },
- { "switch_to_tab_2", "TabsSwitch2" },
- { "switch_to_tab_3", "TabsSwitch3" },
- { "switch_to_tab_4", "TabsSwitch4" },
- { "switch_to_tab_5", "TabsSwitch5" },
- { "switch_to_tab_6", "TabsSwitch6" },
- { "switch_to_tab_7", "TabsSwitch7" },
- { "switch_to_tab_8", "TabsSwitch8" },
- { "switch_to_tab_9", "TabsSwitch9" },
- { "switch_to_tab_10", "TabsSwitch10" },
- { "switch_to_tab_11", "TabsSwitch11" },
- { "switch_to_tab_12", "TabsSwitch12" },
- { "help", "HelpContents" }
+ static const const struct { const char *gconf_key; const char *settings_key; } const data[] = {
+ { "new_tab", "new-tab" },
+ { "new_window", "new-window" },
+ { "new_profile", "new-profile" },
+ { "close_tab", "close-tab" },
+ { "close_window", "close-window" },
+ { "copy", "copy" },
+ { "paste", "paste" },
+ { "toggle_menubar", "toggle-menubar" },
+ { "full_screen", "full-screen" },
+ { "zoom_in", "zoom-in" },
+ { "zoom_out", "zoom-out" },
+ { "zoom_normal", "zoom-normal" },
+ { "set_window_title", "set-terminal-title" },
+ { "reset", "reset" },
+ { "reset_and_clear", "reset-and-clear" },
+ { "prev_tab", "prev-tab" },
+ { "next_tab", "next-tab" },
+ { "move_tab_left", "move-tab-left" },
+ { "move_tab_right", "move-tab-right" },
+ { "detach_tab", "detach-tab" },
+ { "switch_to_tab_1", "switch-to-tab-1" },
+ { "switch_to_tab_2", "switch-to-tab-2" },
+ { "switch_to_tab_3", "switch-to-tab-3" },
+ { "switch_to_tab_4", "switch-to-tab-4" },
+ { "switch_to_tab_5", "switch-to-tab-5" },
+ { "switch_to_tab_6", "switch-to-tab-6" },
+ { "switch_to_tab_7", "switch-to-tab-7" },
+ { "switch_to_tab_8", "switch-to-tab-8" },
+ { "switch_to_tab_9", "switch-to-tab-9" },
+ { "switch_to_tab_10", "switch-to-tab-10" },
+ { "switch_to_tab_11", "switch-to-tab-11" },
+ { "switch_to_tab_12", "switch-to-tab-12" },
+ { "help", "help" }
};
GConfClient *client;
+ GSettings *settings;
guint i;
- char *key, *path;
+ char *gconf_path;
GConfValue *value;
- GString *str;
client = gconf_client_get_default ();
- str = g_string_sized_new (1024);
+ settings = g_settings_new (TERMINAL_KEYBINDINGS_SCHEMA);
for (i = 0; i < G_N_ELEMENTS (data); ++i) {
- key = g_strdup_printf ("/apps/gnome-terminal/keybindings/%s", data[i].key);
- path = g_strdup_printf ("<Actions>/Main/%s", data[i].path);
-
- if ((value = gconf_client_get_without_default (client, key, NULL)) != NULL &&
- value->type == GCONF_VALUE_STRING)
- g_string_append_printf (str,
- "(gtk_accel_path \"%s\" \"%s\")\n",
- path, gconf_value_get_string (value));
+ gconf_path = g_strdup_printf ("/apps/gnome-terminal/keybindings/%s", data[i].gconf_key);
- g_free (key);
- g_free (path);
- if (value)
- gconf_value_free (value);
- }
+ value = gconf_client_get_without_default (client, gconf_path, NULL);
+ g_free (gconf_path);
+ if (value == NULL)
+ continue;
- path = g_build_filename (g_get_user_config_dir (),
- "gnome-terminal",
- NULL);
- g_mkdir_with_parents (path, 0700);
- g_free (path);
+ if (value->type == GCONF_VALUE_STRING)
+ g_settings_set_string (settings, data[i].settings_key, gconf_value_get_string (value));
- path = g_build_filename (g_get_user_config_dir (),
- "gnome-terminal",
- "accels",
- NULL);
- g_file_set_contents (path, str->str, str->len, NULL);
- g_free (path);
+ gconf_value_free (value);
+ }
- g_string_free (str, TRUE);
+ g_object_unref (settings);
g_object_unref (client);
return TRUE;
diff --git a/src/org.gnome.Terminal.gschema.xml.in b/src/org.gnome.Terminal.gschema.xml.in
index abbe5d9..b62b14d 100644
--- a/src/org.gnome.Terminal.gschema.xml.in
+++ b/src/org.gnome.Terminal.gschema.xml.in
@@ -312,11 +312,146 @@
</key>
</schema>
- <!-- Profiles list -->
+ <!-- Keybinding settings -->
- <!--
- <schema id="org.gnome.Terminal.Profiles" list-of="org.gnome.Terminal.Profile" />
- -->
+ <schema id="org.gnome.Terminal.Legacy.Keybindings" path="/org/gnome/terminal/legacy/keybindings/">
+ <key name="new-tab" type="s">
+ <default>'<Ctrl><Shift>t'</default>
+ <_summary>Keyboard shortcut to open a new tab</_summary>
+ </key>
+ <key name="new-window" type="s">
+ <default>'<Ctrl><Shift>n'</default>
+ <_summary>Keyboard shortcut to open a new window</_summary>
+ </key>
+ <key name="new-profile" type="s">
+ <default>'disabled'</default>
+ <_summary>Keyboard shortcut to create a new profile</_summary>
+ </key>
+ <key name="save-contents" type="s">
+ <default>'disabled'</default>
+ <_summary>Keyboard shortcut to save the current tab contents to file</_summary>
+ </key>
+ <key name="close-tab" type="s">
+ <default>'<Ctrl><Shift>w'</default>
+ <_summary>Keyboard shortcut to close a tab</_summary>
+ </key>
+ <key name="close-window" type="s">
+ <default>'<Ctrl><Shift>q'</default>
+ <_summary>Keyboard shortcut to close a window</_summary>
+ </key>
+ <key name="copy" type="s">
+ <default>'<Ctrl><Shift>c'</default>
+ <_summary>Keyboard shortcut to copy text</_summary>
+ </key>
+ <key name="paste" type="s">
+ <default>'<Ctrl><Shift>v'</default>
+ <_summary>Keyboard shortcut to paste text</_summary>
+ </key>
+ <key name="full-screen" type="s">
+ <default>'F11'</default>
+ <_summary>Keyboard shortcut to toggle full screen mode</_summary>
+ </key>
+ <key name="toggle-menubar" type="s">
+ <default>'disabled'</default>
+ <_summary>Keyboard shortcut to toggle the visibility of the menubar</_summary>
+ </key>
+ <key name="set-terminal-title" type="s">
+ <default>'disabled'</default>
+ <_summary>Keyboard shortcut to set the terminal title</_summary>
+ </key>
+ <key name="reset" type="s">
+ <default>'disabled'</default>
+ <_summary>Keyboard shortcut to reset the terminal</_summary>
+ </key>
+ <key name="reset-and-clear" type="s">
+ <default>'disabled'</default>
+ <_summary>Keyboard shortcut to reset and clear the terminal</_summary>
+ </key>
+ <key name="prev-tab" type="s">
+ <default>'<Control>Page_Up'</default>
+ <_summary>Keyboard shortcut to switch to the previous tab</_summary>
+ </key>
+ <key name="next-tab" type="s">
+ <default>'<Control>Page_Down'</default>
+ <_summary>Keyboard shortcut to switch to the next tab</_summary>
+ </key>
+ <key name="move-tab-left" type="s">
+ <default>'<Ctrl><Shift>Page_Up'</default>
+ <_summary>Keyboard shortcut to move the current tab to the left</_summary>
+ </key>
+ <key name="move-tab-right" type="s">
+ <default>'<Ctrl><Shift>Page_Down'</default>
+ <_summary>Keyboard shortbut to move the current tab to the right</_summary>
+ </key>
+ <key name="detach-tab" type="s">
+ <default>'disabled'</default>
+ <_summary>Keyboard shortbut to detach current tab</_summary>
+ </key>
+ <key name="switch-to-tab-1" type="s">
+ <default>'<Alt>1'</default>
+ <_summary>Keyboard shortcut to switch to tab 1</_summary>
+ </key>
+ <key name="switch-to-tab-2" type="s">
+ <default>'<Alt>2'</default>
+ <_summary>Keyboard shortcut to switch to tab 2</_summary>
+ </key>
+ <key name="switch-to-tab-3" type="s">
+ <default>'<Alt>3'</default>
+ <_summary>Keyboard shortcut to switch to tab 3</_summary>
+ </key>
+ <key name="switch-to-tab-4" type="s">
+ <default>'<Alt>4'</default>
+ <_summary>Keyboard shortcut to switch to tab 4</_summary>
+ </key>
+ <key name="switch-to-tab-5" type="s">
+ <default>'<Alt>5'</default>
+ <_summary>Keyboard shortcut to switch to tab 5</_summary>
+ </key>
+ <key name="switch-to-tab-6" type="s">
+ <default>'<Alt>6'</default>
+ <_summary>Keyboard shortcut to switch to tab 6</_summary>
+ </key>
+ <key name="switch-to-tab-7" type="s">
+ <default>'<Alt>7'</default>
+ <_summary>Keyboard shortcut to switch to tab 7</_summary>
+ </key>
+ <key name="switch-to-tab-8" type="s">
+ <default>'<Alt>8'</default>
+ <_summary>Keyboard shortcut to switch to tab 8</_summary>
+ </key>
+ <key name="switch-to-tab-9" type="s">
+ <default>'<Alt>9'</default>
+ <_summary>Keyboard shortcut to switch to tab 9</_summary>
+ </key>
+ <key name="switch-to-tab-10" type="s">
+ <default>'<Alt>0'</default>
+ <_summary>Keyboard shortcut to switch to tab 10</_summary>
+ </key>
+ <key name="switch-to-tab-11" type="s">
+ <default>'disabled'</default>
+ <_summary>Keyboard shortcut to switch to tab 11</_summary>
+ </key>
+ <key name="switch-to-tab-12" type="s">
+ <default>'disabled'</default>
+ <_summary>Keyboard shortcut to switch to tab 12</_summary>
+ </key>
+ <key name="help" type="s">
+ <default>'F1'</default>
+ <_summary>Keyboard shortcut to launch help</_summary>
+ </key>
+ <key name="zoom-in" type="s">
+ <default>'<Ctrl>plus'</default>
+ <_summary>Keyboard shortcut to make font larger</_summary>
+ </key>
+ <key name="zoom-out" type="s">
+ <default>'<Ctrl>minus'</default>
+ <_summary>Keyboard shortcut to make font smaller</_summary>
+ </key>
+ <key name="zoom-normal" type="s">
+ <default>'<Ctrl>0'</default>
+ <_summary>Keyboard shortcut to make font normal-size</_summary>
+ </key>
+ </schema>
<!-- Global settings -->
diff --git a/src/terminal-accels.c b/src/terminal-accels.c
index 0d36d2a..29d554e 100644
--- a/src/terminal-accels.c
+++ b/src/terminal-accels.c
@@ -1,6 +1,6 @@
/*
* Copyright  2001, 2002 Havoc Pennington, Red Hat Inc.
- * Copyright  2008, 2011 Christian Persch
+ * Copyright  2008, 2011, 2012, 2013 Christian Persch
*
* Gnome-terminal is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,30 +29,71 @@
#include "terminal-schemas.h"
#include "terminal-util.h"
+/* NOTES
+ *
+ * There are two sources of keybindings changes, from GSettings and from
+ * the accel map (happens with in-place menu editing).
+ *
+ * When a keybinding gconf key changes, we propagate that into the
+ * accel map.
+ * When the accel map changes, we queue a sync to GSettings.
+ *
+ * To avoid infinite loops, we short-circuit in both directions
+ * if the value is unchanged from last known.
+ *
+ * In the keybinding editor, when editing or clearing an accel, we write
+ * the change directly to GSettings and rely on the callback to
+ * actually apply the change to the accel map.
+ */
+
#define ACCEL_PATH_ROOT "<Actions>/Main/"
-#define ACCEL_NEW_TAB "FileNewTab"
-#define ACCEL_NEW_WINDOW "FileNewWindow"
-#define ACCEL_NEW_PROFILE "FileNewProfile"
-#define ACCEL_SAVE_CONTENTS "FileSaveContents"
-#define ACCEL_CLOSE_TAB "FileCloseTab"
-#define ACCEL_CLOSE_WINDOW "FileCloseWindow"
-#define ACCEL_COPY "EditCopy"
-#define ACCEL_PASTE "EditPaste"
-#define ACCEL_TOGGLE_MENUBAR "ViewMenubar"
-#define ACCEL_FULL_SCREEN "ViewFullscreen"
-#define ACCEL_RESET "TerminalReset"
-#define ACCEL_RESET_AND_CLEAR "TerminalResetClear"
-#define ACCEL_PREV_TAB "TabsPrevious"
-#define ACCEL_NEXT_TAB "TabsNext"
-#define ACCEL_SET_TERMINAL_TITLE "TerminalSetTitle"
-#define ACCEL_HELP "HelpContents"
-#define ACCEL_ZOOM_IN "ViewZoomIn"
-#define ACCEL_ZOOM_OUT "ViewZoomOut"
-#define ACCEL_ZOOM_NORMAL "ViewZoom100"
-#define ACCEL_MOVE_TAB_LEFT "TabsMoveLeft"
-#define ACCEL_MOVE_TAB_RIGHT "TabsMoveRight"
-#define ACCEL_DETACH_TAB "TabsDetach"
-#define ACCEL_SWITCH_TAB_PREFIX "TabsSwitch"
+#define ACCEL_PATH_NEW_TAB ACCEL_PATH_ROOT "FileNewTab"
+#define ACCEL_PATH_NEW_WINDOW ACCEL_PATH_ROOT "FileNewWindow"
+#define ACCEL_PATH_NEW_PROFILE ACCEL_PATH_ROOT "FileNewProfile"
+#define ACCEL_PATH_SAVE_CONTENTS ACCEL_PATH_ROOT "FileSaveContents"
+#define ACCEL_PATH_CLOSE_TAB ACCEL_PATH_ROOT "FileCloseTab"
+#define ACCEL_PATH_CLOSE_WINDOW ACCEL_PATH_ROOT "FileCloseWindow"
+#define ACCEL_PATH_COPY ACCEL_PATH_ROOT "EditCopy"
+#define ACCEL_PATH_PASTE ACCEL_PATH_ROOT "EditPaste"
+#define ACCEL_PATH_TOGGLE_MENUBAR ACCEL_PATH_ROOT "ViewMenubar"
+#define ACCEL_PATH_FULL_SCREEN ACCEL_PATH_ROOT "ViewFullscreen"
+#define ACCEL_PATH_RESET ACCEL_PATH_ROOT "TerminalReset"
+#define ACCEL_PATH_RESET_AND_CLEAR ACCEL_PATH_ROOT "TerminalResetClear"
+#define ACCEL_PATH_PREV_TAB ACCEL_PATH_ROOT "TabsPrevious"
+#define ACCEL_PATH_NEXT_TAB ACCEL_PATH_ROOT "TabsNext"
+#define ACCEL_PATH_SET_TERMINAL_TITLE ACCEL_PATH_ROOT "TerminalSetTitle"
+#define ACCEL_PATH_HELP ACCEL_PATH_ROOT "HelpContents"
+#define ACCEL_PATH_ZOOM_IN ACCEL_PATH_ROOT "ViewZoomIn"
+#define ACCEL_PATH_ZOOM_OUT ACCEL_PATH_ROOT "ViewZoomOut"
+#define ACCEL_PATH_ZOOM_NORMAL ACCEL_PATH_ROOT "ViewZoom100"
+#define ACCEL_PATH_MOVE_TAB_LEFT ACCEL_PATH_ROOT "TabsMoveLeft"
+#define ACCEL_PATH_MOVE_TAB_RIGHT ACCEL_PATH_ROOT "TabsMoveRight"
+#define ACCEL_PATH_DETACH_TAB ACCEL_PATH_ROOT "TabsDetach"
+#define ACCEL_PATH_SWITCH_TAB_PREFIX ACCEL_PATH_ROOT "TabsSwitch"
+
+#define KEY_CLOSE_TAB "close-tab"
+#define KEY_CLOSE_WINDOW "close-window"
+#define KEY_COPY "copy"
+#define KEY_DETACH_TAB "detach-tab"
+#define KEY_FULL_SCREEN "full-screen"
+#define KEY_HELP "help"
+#define KEY_MOVE_TAB_LEFT "move-tab-left"
+#define KEY_MOVE_TAB_RIGHT "move-tab-right"
+#define KEY_NEW_PROFILE "new-profile"
+#define KEY_NEW_TAB "new-tab"
+#define KEY_NEW_WINDOW "new-window"
+#define KEY_NEXT_TAB "next-tab"
+#define KEY_PASTE "paste"
+#define KEY_PREV_TAB "prev-tab"
+#define KEY_RESET_AND_CLEAR "reset-and-clear"
+#define KEY_RESET "reset"
+#define KEY_SAVE_CONTENTS "save-contents"
+#define KEY_SET_TERMINAL_TITLE "set-terminal-title"
+#define KEY_TOGGLE_MENUBAR "toggle-menubar"
+#define KEY_ZOOM_IN "zoom-in"
+#define KEY_ZOOM_NORMAL "zoom-normal"
+#define KEY_ZOOM_OUT "zoom-out"
+#define KEY_SWITCH_TAB_PREFIX "switch-to-tab-"
#if 1
/*
@@ -68,10 +109,22 @@
#endif
#endif
+typedef struct {
+ GdkModifierType mods;
+ guint key;
+} Keybinding;
+
typedef struct
{
const char *user_visible_name;
- const char *accel_path_suffix;
+ const char *settings_key;
+ const char *accel_path;
+ /* last values received from settings */
+ Keybinding settings_keybinding;
+ GClosure *closure;
+ /* have gotten a notification from gtk */
+ gboolean needs_settings_sync;
+ gboolean accel_path_unlocked;
} KeyEntry;
typedef struct
@@ -83,61 +136,106 @@ typedef struct
static KeyEntry file_entries[] =
{
- { N_("New Tab"), ACCEL_NEW_TAB },
- { N_("New Window"), ACCEL_NEW_WINDOW },
- { N_("New Profile"), ACCEL_NEW_PROFILE },
+ { N_("New Tab"),
+ KEY_NEW_TAB, ACCEL_PATH_NEW_TAB, { GDK_SHIFT_MASK | GDK_CONTROL_MASK, GDK_KEY_t }, NULL, FALSE, TRUE },
+ { N_("New Window"),
+ KEY_NEW_WINDOW, ACCEL_PATH_NEW_WINDOW, { GDK_SHIFT_MASK | GDK_CONTROL_MASK, GDK_KEY_n }, NULL, FALSE, TRUE },
+ { N_("New Profile"),
+ KEY_NEW_PROFILE, ACCEL_PATH_NEW_PROFILE, { 0, 0 } , NULL, FALSE, TRUE },
#ifdef ENABLE_SAVE
- { N_("Save Contents"), ACCEL_SAVE_CONTENTS },
+ { N_("Save Contents"),
+ KEY_SAVE_CONTENTS, ACCEL_PATH_SAVE_CONTENTS, { 0, 0 }, NULL, FALSE, TRUE },
#endif
- { N_("Close Tab"), ACCEL_CLOSE_TAB },
- { N_("Close Window"), ACCEL_CLOSE_WINDOW }
+ { N_("Close Tab"),
+ KEY_CLOSE_TAB, ACCEL_PATH_CLOSE_TAB, { GDK_SHIFT_MASK | GDK_CONTROL_MASK, GDK_KEY_w }, NULL, FALSE, TRUE },
+ { N_("Close Window"),
+ KEY_CLOSE_WINDOW, ACCEL_PATH_CLOSE_WINDOW, { GDK_SHIFT_MASK | GDK_CONTROL_MASK, GDK_KEY_q }, NULL, FALSE, TRUE },
};
static KeyEntry edit_entries[] =
{
- { N_("Copy"), ACCEL_COPY },
- { N_("Paste"), ACCEL_PASTE }
+ { N_("Copy"),
+ KEY_COPY, ACCEL_PATH_COPY, { GDK_SHIFT_MASK | GDK_CONTROL_MASK, GDK_KEY_c }, NULL, FALSE, TRUE },
+ { N_("Paste"),
+ KEY_PASTE, ACCEL_PATH_PASTE, { GDK_SHIFT_MASK | GDK_CONTROL_MASK, GDK_KEY_v }, NULL, FALSE, TRUE },
};
static KeyEntry view_entries[] =
{
- { N_("Hide and Show menubar"), ACCEL_TOGGLE_MENUBAR },
- { N_("Full Screen"), ACCEL_FULL_SCREEN },
- { N_("Zoom In"), ACCEL_ZOOM_IN },
- { N_("Zoom Out"), ACCEL_ZOOM_OUT },
- { N_("Normal Size"), ACCEL_ZOOM_NORMAL },
+ { N_("Hide and Show menubar"),
+ KEY_TOGGLE_MENUBAR, ACCEL_PATH_TOGGLE_MENUBAR, { 0, 0 }, NULL, FALSE, TRUE },
+ { N_("Full Screen"),
+ KEY_FULL_SCREEN, ACCEL_PATH_FULL_SCREEN, { 0, GDK_KEY_F11 }, NULL, FALSE, TRUE },
+ { N_("Zoom In"),
+ KEY_ZOOM_IN, ACCEL_PATH_ZOOM_IN, { GDK_CONTROL_MASK, GDK_KEY_plus }, NULL, FALSE, TRUE },
+ { N_("Zoom Out"),
+ KEY_ZOOM_OUT, ACCEL_PATH_ZOOM_OUT, { GDK_CONTROL_MASK, GDK_KEY_minus }, NULL, FALSE, TRUE },
+ { N_("Normal Size"),
+ KEY_ZOOM_NORMAL, ACCEL_PATH_ZOOM_NORMAL, { GDK_CONTROL_MASK, GDK_KEY_0 }, NULL, FALSE, TRUE }
};
static KeyEntry terminal_entries[] =
{
- { N_("Set Title"), ACCEL_SET_TERMINAL_TITLE },
- { N_("Reset"), ACCEL_RESET },
- { N_("Reset and Clear"), ACCEL_RESET_AND_CLEAR }
+ { N_("Set Title"),
+ KEY_SET_TERMINAL_TITLE, ACCEL_PATH_SET_TERMINAL_TITLE, { 0, 0 }, NULL, FALSE, TRUE },
+ { N_("Reset"),
+ KEY_RESET, ACCEL_PATH_RESET, { 0, 0 }, NULL, FALSE, TRUE },
+ { N_("Reset and Clear"),
+ KEY_RESET_AND_CLEAR, ACCEL_PATH_RESET_AND_CLEAR, { 0, 0 }, NULL, FALSE, TRUE },
};
static KeyEntry tabs_entries[] =
{
- { N_("Switch to Previous Tab"), ACCEL_PREV_TAB },
- { N_("Switch to Next Tab"), ACCEL_NEXT_TAB },
- { N_("Move Tab to the Left"), ACCEL_MOVE_TAB_LEFT },
- { N_("Move Tab to the Right"), ACCEL_MOVE_TAB_RIGHT },
- { N_("Detach Tab"), ACCEL_DETACH_TAB },
- { N_("Switch to Tab 1"), ACCEL_SWITCH_TAB_PREFIX "1" },
- { N_("Switch to Tab 2"), ACCEL_SWITCH_TAB_PREFIX "2" },
- { N_("Switch to Tab 3"), ACCEL_SWITCH_TAB_PREFIX "3" },
- { N_("Switch to Tab 4"), ACCEL_SWITCH_TAB_PREFIX "4" },
- { N_("Switch to Tab 5"), ACCEL_SWITCH_TAB_PREFIX "5" },
- { N_("Switch to Tab 6"), ACCEL_SWITCH_TAB_PREFIX "6" },
- { N_("Switch to Tab 7"), ACCEL_SWITCH_TAB_PREFIX "7" },
- { N_("Switch to Tab 8"), ACCEL_SWITCH_TAB_PREFIX "8" },
- { N_("Switch to Tab 9"), ACCEL_SWITCH_TAB_PREFIX "9" },
- { N_("Switch to Tab 10"), ACCEL_SWITCH_TAB_PREFIX "10" },
- { N_("Switch to Tab 11"), ACCEL_SWITCH_TAB_PREFIX "11" },
- { N_("Switch to Tab 12"), ACCEL_SWITCH_TAB_PREFIX "12" }
+ { N_("Switch to Previous Tab"),
+ KEY_PREV_TAB, ACCEL_PATH_PREV_TAB, { GDK_CONTROL_MASK, GDK_KEY_Page_Up }, NULL, FALSE, TRUE },
+ { N_("Switch to Next Tab"),
+ KEY_NEXT_TAB, ACCEL_PATH_NEXT_TAB, { GDK_CONTROL_MASK, GDK_KEY_Page_Down }, NULL, FALSE, TRUE },
+ { N_("Move Tab to the Left"),
+ KEY_MOVE_TAB_LEFT, ACCEL_PATH_MOVE_TAB_LEFT, { GDK_SHIFT_MASK | GDK_CONTROL_MASK, GDK_KEY_Page_Up }, NULL, FALSE, TRUE },
+ { N_("Move Tab to the Right"),
+ KEY_MOVE_TAB_RIGHT, ACCEL_PATH_MOVE_TAB_RIGHT, { GDK_SHIFT_MASK | GDK_CONTROL_MASK, GDK_KEY_Page_Down }, NULL, FALSE, TRUE },
+ { N_("Detach Tab"),
+ KEY_DETACH_TAB, ACCEL_PATH_DETACH_TAB, { 0, 0 }, NULL, FALSE, TRUE },
+ { N_("Switch to Tab 1"),
+ KEY_SWITCH_TAB_PREFIX "1",
+ ACCEL_PATH_SWITCH_TAB_PREFIX "1", { GDK_MOD1_MASK, GDK_KEY_1 }, NULL, FALSE, TRUE },
+ { N_("Switch to Tab 2"),
+ KEY_SWITCH_TAB_PREFIX "2",
+ ACCEL_PATH_SWITCH_TAB_PREFIX "2", { GDK_MOD1_MASK, GDK_KEY_2 }, NULL, FALSE, TRUE },
+ { N_("Switch to Tab 3"),
+ KEY_SWITCH_TAB_PREFIX "3",
+ ACCEL_PATH_SWITCH_TAB_PREFIX "3", { GDK_MOD1_MASK, GDK_KEY_3 }, NULL, FALSE, TRUE },
+ { N_("Switch to Tab 4"),
+ KEY_SWITCH_TAB_PREFIX "4",
+ ACCEL_PATH_SWITCH_TAB_PREFIX "4", { GDK_MOD1_MASK, GDK_KEY_4 }, NULL, FALSE, TRUE },
+ { N_("Switch to Tab 5"),
+ KEY_SWITCH_TAB_PREFIX "5",
+ ACCEL_PATH_SWITCH_TAB_PREFIX "5", { GDK_MOD1_MASK, GDK_KEY_5 }, NULL, FALSE, TRUE },
+ { N_("Switch to Tab 6"),
+ KEY_SWITCH_TAB_PREFIX "6",
+ ACCEL_PATH_SWITCH_TAB_PREFIX "6", { GDK_MOD1_MASK, GDK_KEY_6 }, NULL, FALSE, TRUE },
+ { N_("Switch to Tab 7"),
+ KEY_SWITCH_TAB_PREFIX "7",
+ ACCEL_PATH_SWITCH_TAB_PREFIX "7", { GDK_MOD1_MASK, GDK_KEY_7 }, NULL, FALSE, TRUE },
+ { N_("Switch to Tab 8"),
+ KEY_SWITCH_TAB_PREFIX "8",
+ ACCEL_PATH_SWITCH_TAB_PREFIX "8", { GDK_MOD1_MASK, GDK_KEY_8 }, NULL, FALSE, TRUE },
+ { N_("Switch to Tab 9"),
+ KEY_SWITCH_TAB_PREFIX "9",
+ ACCEL_PATH_SWITCH_TAB_PREFIX "9", { GDK_MOD1_MASK, GDK_KEY_9 }, NULL, FALSE, TRUE },
+ { N_("Switch to Tab 10"),
+ KEY_SWITCH_TAB_PREFIX "10",
+ ACCEL_PATH_SWITCH_TAB_PREFIX "10", { GDK_MOD1_MASK, GDK_KEY_0}, NULL, FALSE, TRUE },
+ { N_("Switch to Tab 11"),
+ KEY_SWITCH_TAB_PREFIX "11",
+ ACCEL_PATH_SWITCH_TAB_PREFIX "11", { 0, 0 }, NULL, FALSE, TRUE },
+ { N_("Switch to Tab 12"),
+ KEY_SWITCH_TAB_PREFIX "12",
+ ACCEL_PATH_SWITCH_TAB_PREFIX "12", { 0, 0 }, NULL, FALSE, TRUE }
};
static KeyEntry help_entries[] = {
- { N_("Contents"), ACCEL_HELP }
+ { N_("Contents"), KEY_HELP, ACCEL_PATH_HELP, { 0, GDK_KEY_F1 }, NULL, FALSE, TRUE }
};
static KeyEntryList all_entries[] =
@@ -153,22 +251,32 @@ static KeyEntryList all_entries[] =
enum
{
ACTION_COLUMN,
- ACCEL_PATH_COLUMN,
+ KEYVAL_COLUMN,
N_COLUMNS
};
-static void accel_map_changed_callback (GtkAccelMap *accel_map,
- const char *accel_path,
- guint keyval,
- GdkModifierType modifier,
- gpointer data);
+static void keys_change_notify (GSettings *settings,
+ const char *key,
+ gpointer user_data);
+
+static void accel_changed_callback (GtkAccelGroup *accel_group,
+ guint keyval,
+ GdkModifierType modifier,
+ GClosure *accel_closure,
+ gpointer data);
-static guint save_id = 0;
+static gboolean sync_idle_cb (gpointer data);
+
+static guint sync_idle_id = 0;
+static GtkAccelGroup *notification_group = NULL;
+/* never set settings keys in response to receiving a settings notify. */
+static int inside_settings_notify = 0;
static GtkWidget *edit_keys_dialog = NULL;
static GtkTreeStore *edit_keys_store = NULL;
-static gboolean dirty = FALSE;
+static GHashTable *settings_key_to_entry;
+static GSettings *keybinding_settings = NULL;
-static char *
+static char*
binding_name (guint keyval,
GdkModifierType mask)
{
@@ -178,71 +286,87 @@ binding_name (guint keyval,
return g_strdup ("disabled");
}
-static char *
-get_accel_map_filename (void)
-{
- return g_build_filename (g_get_user_config_dir (),
- "gnome-terminal",
- "accels",
- NULL);
-}
-
static gboolean
-save_cb (gpointer data)
+map_keybinding (GVariant *variant,
+ gpointer *result,
+ gpointer user_data)
{
- char *path;
+ Keybinding *keybinding = user_data;
+ const char *value;
- _terminal_debug_print (TERMINAL_DEBUG_ACCELS,
- "saving accel map\n");
+ value = g_variant_get_string (variant, NULL);
- save_id = 0;
+ if (value == NULL || g_str_equal (value, "disabled"))
+ {
+ keybinding->mods = 0;
+ keybinding->key = 0;
+ return TRUE;
+ }
- if (!dirty)
+ gtk_accelerator_parse (value, &keybinding->key, &keybinding->mods);
+ if (keybinding->key == 0 && keybinding->mods == 0)
return FALSE;
- dirty = FALSE;
-
- path = get_accel_map_filename ();
- gtk_accel_map_save (path);
- g_free (path);
-
- return FALSE; /* don't run again */
+ return TRUE;
}
-static void
-schedule_save (void)
+void
+terminal_accels_init (void)
{
- if (save_id != 0)
- return;
+ guint i, j;
- dirty = TRUE;
+ keybinding_settings = g_settings_new (TERMINAL_KEYBINDINGS_SCHEMA);
+ g_signal_connect (keybinding_settings, "changed", G_CALLBACK (keys_change_notify), NULL);
- save_id = g_timeout_add_seconds (5, save_cb, NULL);
-}
+ settings_key_to_entry = g_hash_table_new (g_str_hash, g_str_equal);
-void
-terminal_accels_init (void)
-{
- char *path;
+ notification_group = gtk_accel_group_new ();
+
+ for (i = 0; i < G_N_ELEMENTS (all_entries); ++i)
+ {
+ for (j = 0; j < all_entries[i].n_elements; ++j)
+ {
+ KeyEntry *key_entry;
+
+ key_entry = &(all_entries[i].key_entry[j]);
+
+ g_hash_table_insert (settings_key_to_entry,
+ (gpointer) key_entry->settings_key,
+ key_entry);
+
+ key_entry->closure = g_closure_new_simple (sizeof (GClosure), key_entry);
- g_signal_connect (gtk_accel_map_get (), "changed",
- G_CALLBACK (accel_map_changed_callback), NULL);
+ g_closure_ref (key_entry->closure);
+ g_closure_sink (key_entry->closure);
+
+ gtk_accel_group_connect_by_path (notification_group,
+ I_(key_entry->accel_path),
+ key_entry->closure);
- path = get_accel_map_filename ();
- gtk_accel_map_load (path);
- g_free (path);
+ keys_change_notify (keybinding_settings, key_entry->settings_key, NULL);
+ }
+ }
+
+ g_signal_connect (notification_group, "accel-changed",
+ G_CALLBACK (accel_changed_callback), NULL);
}
void
terminal_accels_shutdown (void)
{
- if (save_id != 0)
+ g_signal_handlers_disconnect_by_func (keybinding_settings, G_CALLBACK (keys_change_notify), NULL);
+
+ if (sync_idle_id != 0)
{
- g_source_remove (save_id);
- save_id = 0;
+ g_source_remove (sync_idle_id);
+ sync_idle_id = 0;
- save_cb (NULL);
+ sync_idle_cb (NULL);
}
+
+ g_clear_pointer (&settings_key_to_entry, (GDestroyNotify) g_hash_table_unref);
+ g_clear_object (¬ification_group);
+ g_clear_object (&keybinding_settings);
}
static gboolean
@@ -251,10 +375,13 @@ update_model_foreach (GtkTreeModel *model,
GtkTreeIter *iter,
gpointer data)
{
- guint accel_path_quark;
+ KeyEntry *key_entry = NULL;
+
+ gtk_tree_model_get (model, iter,
+ KEYVAL_COLUMN, &key_entry,
+ -1);
- gtk_tree_model_get (model, iter, ACCEL_PATH_COLUMN, &accel_path_quark, -1);
- if (accel_path_quark == GPOINTER_TO_UINT (data))
+ if (key_entry == (KeyEntry *) data)
{
gtk_tree_model_row_changed (model, path, iter);
return TRUE;
@@ -263,20 +390,142 @@ update_model_foreach (GtkTreeModel *model,
}
static void
-accel_map_changed_callback (GtkAccelMap *accel_map,
- const char *accel_path,
- guint keyval,
- GdkModifierType modifier,
- gpointer data)
+keys_change_notify (GSettings *settings,
+ const char *settings_key,
+ gpointer user_data)
+{
+ Keybinding keybinding;
+ KeyEntry *key_entry;
+
+ _terminal_debug_print (TERMINAL_DEBUG_ACCELS,
+ "key %s changed\n",
+ settings_key);
+
+ key_entry = g_hash_table_lookup (settings_key_to_entry, settings_key);
+ if (!key_entry)
+ {
+ /* shouldn't really happen, but let's be safe */
+ _terminal_debug_print (TERMINAL_DEBUG_ACCELS,
+ " WARNING: KeyEntry for changed key not found, bailing out\n");
+ return;
+ }
+
+ g_settings_get_mapped (settings, settings_key,
+ (GSettingsGetMapping) map_keybinding, &keybinding);
+
+ key_entry->settings_keybinding = keybinding;
+
+ /* Unlock the path, so we can change its accel */
+ if (!key_entry->accel_path_unlocked)
+ gtk_accel_map_unlock_path (key_entry->accel_path);
+
+ /* sync over to GTK */
+ _terminal_debug_print (TERMINAL_DEBUG_ACCELS,
+ "changing path %s to %s\n",
+ key_entry->accel_path,
+ binding_name (keybinding.key, keybinding.mods)); /* memleak */
+ inside_settings_notify += 1;
+ /* Note that this may return FALSE, e.g. when the entry was already set correctly. */
+ gtk_accel_map_change_entry (key_entry->accel_path,
+ keybinding.key, keybinding.mods,
+ TRUE);
+ inside_settings_notify -= 1;
+
+ /* Lock the path if the settings key isn't writable */
+ key_entry->accel_path_unlocked = g_settings_is_writable (settings, settings_key);
+ if (!key_entry->accel_path_unlocked)
+ gtk_accel_map_lock_path (key_entry->accel_path);
+
+ /* This seems necessary to update the tree model, since sometimes the
+ * notification on the notification_group seems not to be emitted correctly.
+ * Without this change, when trying to set an accel to e.g. Alt-T (while the main
+ * menu in the terminal windows is _Terminal with Alt-T mnemonic) only displays
+ * the accel change after a re-expose of the row.
+ * FIXME: Find out *why* the accel-changed signal is wrong here!
+ */
+ if (edit_keys_store)
+ gtk_tree_model_foreach (GTK_TREE_MODEL (edit_keys_store), update_model_foreach, key_entry);
+}
+
+static void
+accel_changed_callback (GtkAccelGroup *accel_group,
+ guint keyval,
+ GdkModifierType modifier,
+ GClosure *accel_closure,
+ gpointer data)
+{
+ /* FIXME because GTK accel API is so nonsensical, we get
+ * a notify for each closure, on both the added and the removed
+ * accelerator. We just use the accel closure to find our
+ * accel entry, then update the value of that entry.
+ * We use an idle function to avoid setting the entry
+ * in settings when the accelerator gets removed and then
+ * setting it again when it gets added.
+ */
+ KeyEntry *key_entry;
+
+ _terminal_debug_print (TERMINAL_DEBUG_ACCELS,
+ "Changed accel %s closure %p\n",
+ binding_name (keyval, modifier), /* memleak */
+ accel_closure);
+
+ if (inside_settings_notify)
+ {
+ _terminal_debug_print (TERMINAL_DEBUG_ACCELS,
+ "Ignoring change from gtk because we're inside a settings notify\n");
+ return;
+ }
+
+ key_entry = accel_closure->data;
+ g_assert (key_entry);
+
+ key_entry->needs_settings_sync = TRUE;
+
+ if (sync_idle_id == 0)
+ sync_idle_id = g_idle_add (sync_idle_cb, NULL);
+}
+
+static void
+sync_key_entry (gpointer key,
+ KeyEntry *key_entry,
+ GSettings *settings)
+{
+ GtkAccelKey gtk_key;
+
+ if (!key_entry->needs_settings_sync)
+ return;
+
+ key_entry->needs_settings_sync = FALSE;
+
+ if (gtk_accel_map_lookup_entry (key_entry->accel_path, >k_key) &&
+ (gtk_key.accel_key != key_entry->settings_keybinding.key ||
+ gtk_key.accel_mods != key_entry->settings_keybinding.mods))
+ {
+ char *accel_name;
+
+ accel_name = binding_name (gtk_key.accel_key, gtk_key.accel_mods);
+ g_settings_set_string (settings, key_entry->settings_key, accel_name);
+ g_free (accel_name);
+ }
+}
+
+static gboolean
+sync_idle_cb (gpointer data)
{
_terminal_debug_print (TERMINAL_DEBUG_ACCELS,
- "Changed accel path %s to %s\n",
- accel_path,
- binding_name (keyval, modifier) /* memleak */);
+ "settings sync handler\n");
+ sync_idle_id = 0;
+
+ g_hash_table_foreach (settings_key_to_entry, (GHFunc) sync_key_entry, keybinding_settings);
- schedule_save ();
+ return FALSE;
}
+/* We have the same KeyEntry* in both columns;
+ * we only have two columns because we want to be able
+ * to sort by either one of them.
+ */
+
static void
accel_set_func (GtkTreeViewColumn *tree_column,
GtkCellRenderer *cell,
@@ -284,46 +533,35 @@ accel_set_func (GtkTreeViewColumn *tree_column,
GtkTreeIter *iter,
gpointer data)
{
- guint accel_path_quark;
- GtkAccelKey key;
+ KeyEntry *ke;
+
+ gtk_tree_model_get (model, iter,
+ KEYVAL_COLUMN, &ke,
+ -1);
- gtk_tree_model_get (model, iter, ACCEL_PATH_COLUMN, &accel_path_quark, -1);
- if (accel_path_quark == 0) {
+ if (ke == NULL)
/* This is a title row */
g_object_set (cell,
"visible", FALSE,
NULL);
- return;
- }
-
- if (gtk_accel_map_lookup_entry (g_quark_to_string (accel_path_quark), &key))
- g_object_set (cell,
- "visible", TRUE,
- "sensitive", (key.accel_flags & GTK_ACCEL_LOCKED) == 0,
- "editable", (key.accel_flags & GTK_ACCEL_LOCKED) == 0,
- "accel-key", key.accel_key,
- "accel-mods", (guint) key.accel_mods,
- NULL);
else
g_object_set (cell,
"visible", TRUE,
- "sensitive", TRUE,
- "editable", TRUE,
- "accel-key", (guint) 0,
- "accel-mods", (guint) 0,
- NULL);
+ "sensitive", ke->accel_path_unlocked,
+ "editable", ke->accel_path_unlocked,
+ "accel-key", ke->settings_keybinding.key,
+ "accel-mods", ke->settings_keybinding.mods,
+ NULL);
}
static void
-treeview_accel_map_changed_cb (GtkAccelMap *accel_map,
- const char *accel_path,
- guint keyval,
- GdkModifierType modifier,
- GtkTreeModel *model)
+treeview_accel_changed_cb (GtkAccelGroup *accel_group,
+ guint keyval,
+ GdkModifierType modifier,
+ GClosure *accel_closure,
+ GtkTreeModel *model)
{
- gtk_tree_model_foreach (model,
- update_model_foreach,
- GUINT_TO_POINTER (g_quark_from_string (accel_path)));
+ gtk_tree_model_foreach (model, update_model_foreach, accel_closure->data);
}
static void
@@ -337,7 +575,10 @@ accel_edited_callback (GtkCellRendererAccel *cell,
GtkTreeModel *model;
GtkTreePath *path;
GtkTreeIter iter;
- guint accel_path_quark;
+ KeyEntry *ke;
+ GtkAccelGroupEntry *entries;
+ guint n_entries;
+ char *str;
model = gtk_tree_view_get_model (view);
@@ -351,12 +592,69 @@ accel_edited_callback (GtkCellRendererAccel *cell,
}
gtk_tree_path_free (path);
- gtk_tree_model_get (model, &iter, ACCEL_PATH_COLUMN, &accel_path_quark, -1);
+ gtk_tree_model_get (model, &iter, KEYVAL_COLUMN, &ke, -1);
+
/* sanity check */
- if (accel_path_quark == 0)
+ if (ke == NULL)
return;
- gtk_accel_map_change_entry (g_quark_to_string (accel_path_quark), keyval, mask, TRUE);
+ /* Check if we already have an entry using this accel */
+ entries = gtk_accel_group_query (notification_group, keyval, mask, &n_entries);
+ if (n_entries > 0)
+ {
+ if (entries[0].accel_path_quark != g_quark_from_string (ke->accel_path))
+ {
+ GtkWidget *dialog;
+ char *name;
+ KeyEntry *other_key;
+
+ name = gtk_accelerator_get_label (keyval, mask);
+ other_key = entries[0].closure->data;
+ g_assert (other_key);
+
+ dialog =
+ gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (view))),
+ GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_OK,
+ _("The shortcut key â%sâ is already bound to the â%sâ action"),
+ name,
+ other_key->user_visible_name ? _(other_key->user_visible_name) : other_key->settings_key);
+ g_free (name);
+
+ g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
+ gtk_window_present (GTK_WINDOW (dialog));
+ }
+
+ return;
+ }
+
+ str = binding_name (keyval, mask);
+
+ _terminal_debug_print (TERMINAL_DEBUG_ACCELS,
+ "Edited path %s keyval %s, setting settings to %s\n",
+ ke->accel_path,
+ gdk_keyval_name (keyval) ? gdk_keyval_name (keyval) : "null",
+ str);
+#ifdef GNOME_ENABLE_DEBUG
+ _TERMINAL_DEBUG_IF (TERMINAL_DEBUG_ACCELS)
+ {
+ GtkAccelKey old_key;
+
+ if (gtk_accel_map_lookup_entry (ke->accel_path, &old_key)) {
+ _terminal_debug_print (TERMINAL_DEBUG_ACCELS,
+ " Old entry of path %s is keyval %s mask %x\n",
+ ke->accel_path, gdk_keyval_name (old_key.accel_key), old_key.accel_mods);
+ } else {
+ _terminal_debug_print (TERMINAL_DEBUG_ACCELS,
+ " Failed to look up the old entry of path %s\n",
+ ke->accel_path);
+ }
+ }
+#endif
+
+ g_settings_set_string (keybinding_settings, ke->settings_key, str);
+ g_free (str);
}
static void
@@ -367,7 +665,8 @@ accel_cleared_callback (GtkCellRendererAccel *cell,
GtkTreeModel *model;
GtkTreePath *path;
GtkTreeIter iter;
- guint accel_path_quark;
+ KeyEntry *ke;
+ char *str;
model = gtk_tree_view_get_model (view);
@@ -381,21 +680,31 @@ accel_cleared_callback (GtkCellRendererAccel *cell,
}
gtk_tree_path_free (path);
- gtk_tree_model_get (model, &iter, ACCEL_PATH_COLUMN, &accel_path_quark, -1);
+ gtk_tree_model_get (model, &iter, KEYVAL_COLUMN, &ke, -1);
+
/* sanity check */
- if (accel_path_quark == 0)
+ if (ke == NULL)
return;
- gtk_accel_map_change_entry (g_quark_to_string (accel_path_quark), 0, 0, TRUE);
+ ke->settings_keybinding.key = 0;
+ ke->settings_keybinding.mods = 0;
+ ke->needs_settings_sync = TRUE;
+
+ str = binding_name (0, 0);
+
+ _terminal_debug_print (TERMINAL_DEBUG_ACCELS,
+ "Cleared keybinding for settings %s",
+ ke->settings_key);
+
+ g_settings_set_string (keybinding_settings, ke->settings_key, str);
+ g_free (str);
}
static void
edit_keys_dialog_destroy_cb (GtkWidget *widget,
gpointer user_data)
{
- g_signal_handlers_disconnect_by_func (gtk_accel_map_get (),
- G_CALLBACK (treeview_accel_map_changed_cb),
- user_data);
+ g_signal_handlers_disconnect_by_func (notification_group, G_CALLBACK (treeview_accel_changed_cb), user_data);
edit_keys_dialog = NULL;
edit_keys_store = NULL;
}
@@ -404,16 +713,28 @@ static void
edit_keys_dialog_response_cb (GtkWidget *editor,
int response,
gpointer use_data)
-{
+{
if (response == GTK_RESPONSE_HELP)
{
terminal_util_show_help ("gnome-terminal-shortcuts", GTK_WINDOW (editor));
return;
}
-
+
gtk_widget_destroy (editor);
}
+#ifdef GNOME_ENABLE_DEBUG
+static void
+row_changed (GtkTreeModel *tree_model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+ _terminal_debug_print (TERMINAL_DEBUG_ACCELS,
+ "ROW-CHANGED [%s]\n", gtk_tree_path_to_string (path) /* leak */);
+}
+#endif
+
void
terminal_edit_keys_dialog_show (GtkWindow *transient_parent)
{
@@ -421,8 +742,8 @@ terminal_edit_keys_dialog_show (GtkWindow *transient_parent)
GtkTreeViewColumn *column;
GtkCellRenderer *cell_renderer;
GtkTreeStore *tree;
- GSettings *settings;
guint i;
+ GSettings *settings;
if (edit_keys_dialog != NULL)
goto done;
@@ -475,7 +796,12 @@ terminal_edit_keys_dialog_show (GtkWindow *transient_parent)
/* Add the data */
- tree = edit_keys_store = gtk_tree_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_UINT);
+ tree = edit_keys_store = gtk_tree_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_POINTER);
+
+#ifdef GNOME_ENABLE_DEBUG
+ _TERMINAL_DEBUG_IF (TERMINAL_DEBUG_ACCELS)
+ g_signal_connect (tree, "row-changed", G_CALLBACK (row_changed), NULL);
+#endif
for (i = 0; i < G_N_ELEMENTS (all_entries); ++i)
{
@@ -484,34 +810,28 @@ terminal_edit_keys_dialog_show (GtkWindow *transient_parent)
gtk_tree_store_insert_with_values (tree, &parent_iter, NULL, -1,
ACTION_COLUMN, _(all_entries[i].user_visible_name),
- ACCEL_PATH_COLUMN, 0,
+ KEYVAL_COLUMN, NULL,
-1);
for (j = 0; j < all_entries[i].n_elements; ++j)
{
KeyEntry *key_entry = &(all_entries[i].key_entry[j]);
GtkTreeIter iter;
- char *accel_path;
- accel_path = g_strconcat (ACCEL_PATH_ROOT, key_entry->accel_path_suffix, NULL);
gtk_tree_store_insert_with_values (tree, &iter, &parent_iter, -1,
ACTION_COLUMN, _(key_entry->user_visible_name),
- ACCEL_PATH_COLUMN, g_quark_from_string (accel_path),
+ KEYVAL_COLUMN, key_entry,
-1);
- g_free (accel_path);
}
}
- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (tree), ACTION_COLUMN,
- GTK_SORT_ASCENDING);
-
gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), GTK_TREE_MODEL (tree));
g_object_unref (tree);
gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
- g_signal_connect (gtk_accel_map_get (), "changed",
- G_CALLBACK (treeview_accel_map_changed_cb), tree);
+ g_signal_connect (notification_group, "accel-changed",
+ G_CALLBACK (treeview_accel_changed_cb), tree);
edit_keys_dialog = dialog;
g_signal_connect (dialog, "destroy",
diff --git a/src/terminal-schemas.h b/src/terminal-schemas.h
index 0d335c2..cd2acbc 100644
--- a/src/terminal-schemas.h
+++ b/src/terminal-schemas.h
@@ -26,6 +26,7 @@ G_BEGIN_DECLS
#define TERMINAL_SCHEMA_VERSION (1u)
+#define TERMINAL_KEYBINDINGS_SCHEMA "org.gnome.Terminal.Legacy.Keybindings"
#define TERMINAL_PROFILE_SCHEMA "org.gnome.Terminal.Legacy.Profile"
#define TERMINAL_SETTING_SCHEMA "org.gnome.Terminal.Settings"
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]