|
Packit |
9982d0 |
/*
|
|
Packit |
9982d0 |
* Copyright © 2001, 2002 Havoc Pennington, Red Hat Inc.
|
|
Packit |
9982d0 |
* Copyright © 2008, 2011, 2012, 2013 Christian Persch
|
|
Packit |
9982d0 |
*
|
|
Packit |
9982d0 |
* This program is free software: you can redistribute it and/or modify
|
|
Packit |
9982d0 |
* it under the terms of the GNU General Public License as published by
|
|
Packit |
9982d0 |
* the Free Software Foundation, either version 3 of the License, or
|
|
Packit |
9982d0 |
* (at your option) any later version.
|
|
Packit |
9982d0 |
*
|
|
Packit |
9982d0 |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
9982d0 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
9982d0 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
9982d0 |
* GNU General Public License for more details.
|
|
Packit |
9982d0 |
*
|
|
Packit |
9982d0 |
* You should have received a copy of the GNU General Public License
|
|
Packit |
9982d0 |
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
9982d0 |
*/
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
#include "config.h"
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
#include <string.h>
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
#include <glib.h>
|
|
Packit |
9982d0 |
#include <glib/gi18n.h>
|
|
Packit |
9982d0 |
#include <gtk/gtk.h>
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
#include "terminal-accels.h"
|
|
Packit |
9982d0 |
#include "terminal-app.h"
|
|
Packit |
9982d0 |
#include "terminal-debug.h"
|
|
Packit |
9982d0 |
#include "terminal-schemas.h"
|
|
Packit |
9982d0 |
#include "terminal-intl.h"
|
|
Packit |
9982d0 |
#include "terminal-util.h"
|
|
Packit |
9982d0 |
#include "terminal-libgsystem.h"
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
/* NOTES
|
|
Packit |
9982d0 |
*
|
|
Packit |
9982d0 |
* There are two sources of keybindings changes, from GSettings and from
|
|
Packit |
9982d0 |
* the accel map (happens with in-place menu editing).
|
|
Packit |
9982d0 |
*
|
|
Packit |
9982d0 |
* When a keybinding gconf key changes, we propagate that into the
|
|
Packit |
9982d0 |
* accel map.
|
|
Packit |
9982d0 |
* When the accel map changes, we queue a sync to GSettings.
|
|
Packit |
9982d0 |
*
|
|
Packit |
9982d0 |
* To avoid infinite loops, we short-circuit in both directions
|
|
Packit |
9982d0 |
* if the value is unchanged from last known.
|
|
Packit |
9982d0 |
*
|
|
Packit |
9982d0 |
* In the keybinding editor, when editing or clearing an accel, we write
|
|
Packit |
9982d0 |
* the change directly to GSettings and rely on the callback to
|
|
Packit |
9982d0 |
* actually apply the change to the accel map.
|
|
Packit |
9982d0 |
*/
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
#define KEY_CLOSE_TAB "close-tab"
|
|
Packit |
9982d0 |
#define KEY_CLOSE_WINDOW "close-window"
|
|
Packit |
9982d0 |
#define KEY_COPY "copy"
|
|
Packit |
9982d0 |
#define KEY_COPY_HTML "copy-html"
|
|
Packit |
9982d0 |
#define KEY_DETACH_TAB "detach-tab"
|
|
Packit |
9982d0 |
#define KEY_EXPORT "export"
|
|
Packit |
9982d0 |
#define KEY_FIND "find"
|
|
Packit |
9982d0 |
#define KEY_FIND_CLEAR "find-clear"
|
|
Packit |
9982d0 |
#define KEY_FIND_PREV "find-previous"
|
|
Packit |
9982d0 |
#define KEY_FIND_NEXT "find-next"
|
|
Packit |
9982d0 |
#define KEY_FULL_SCREEN "full-screen"
|
|
Packit |
9982d0 |
#define KEY_HELP "help"
|
|
Packit |
9982d0 |
#define KEY_MOVE_TAB_LEFT "move-tab-left"
|
|
Packit |
9982d0 |
#define KEY_MOVE_TAB_RIGHT "move-tab-right"
|
|
Packit |
9982d0 |
#define KEY_NEW_TAB "new-tab"
|
|
Packit |
9982d0 |
#define KEY_NEW_WINDOW "new-window"
|
|
Packit |
9982d0 |
#define KEY_NEXT_TAB "next-tab"
|
|
Packit |
9982d0 |
#define KEY_PASTE "paste"
|
|
Packit |
9982d0 |
#define KEY_PREFERENCES "preferences"
|
|
Packit |
9982d0 |
#define KEY_PREV_TAB "prev-tab"
|
|
Packit |
9982d0 |
#define KEY_PRINT "print"
|
|
Packit |
9982d0 |
#define KEY_READ_ONLY "read-only"
|
|
Packit |
9982d0 |
#define KEY_RESET_AND_CLEAR "reset-and-clear"
|
|
Packit |
9982d0 |
#define KEY_RESET "reset"
|
|
Packit |
9982d0 |
#define KEY_SAVE_CONTENTS "save-contents"
|
|
Packit |
9982d0 |
#define KEY_SELECT_ALL "select-all"
|
|
Packit |
9982d0 |
#define KEY_TOGGLE_MENUBAR "toggle-menubar"
|
|
Packit |
9982d0 |
#define KEY_ZOOM_IN "zoom-in"
|
|
Packit |
9982d0 |
#define KEY_ZOOM_NORMAL "zoom-normal"
|
|
Packit |
9982d0 |
#define KEY_ZOOM_OUT "zoom-out"
|
|
Packit |
9982d0 |
#define KEY_SWITCH_TAB_PREFIX "switch-to-tab-"
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
#if 1
|
|
Packit |
9982d0 |
/*
|
|
Packit |
9982d0 |
* We don't want to enable content saving until vte supports it async.
|
|
Packit |
9982d0 |
* So we disable this code for stable versions.
|
|
Packit |
9982d0 |
*/
|
|
Packit |
9982d0 |
#include "terminal-version.h"
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
#if (TERMINAL_MINOR_VERSION & 1) != 0
|
|
Packit |
9982d0 |
#define ENABLE_SAVE
|
|
Packit |
9982d0 |
#else
|
|
Packit |
9982d0 |
#undef ENABLE_SAVE
|
|
Packit |
9982d0 |
#endif
|
|
Packit |
9982d0 |
#endif
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
typedef struct
|
|
Packit |
9982d0 |
{
|
|
Packit |
9982d0 |
const char *user_visible_name;
|
|
Packit |
9982d0 |
const char *settings_key;
|
|
Packit |
9982d0 |
const char *action_name;
|
|
Packit |
9982d0 |
const GVariantType *action_parameter_type;
|
|
Packit |
9982d0 |
const char *action_parameter;
|
|
Packit |
9982d0 |
GVariant *parameter;
|
|
Packit |
9982d0 |
const char *shadow_action_name;
|
|
Packit |
9982d0 |
} KeyEntry;
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
typedef struct
|
|
Packit |
9982d0 |
{
|
|
Packit |
9982d0 |
KeyEntry *key_entry;
|
|
Packit |
9982d0 |
guint n_elements;
|
|
Packit |
9982d0 |
const char *user_visible_name;
|
|
Packit |
9982d0 |
} KeyEntryList;
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
#define ENTRY_FULL(name, key, action, type, parameter, shadow_name) \
|
|
Packit |
9982d0 |
{ name, key, "win." action, (const GVariantType *) type, parameter, NULL, shadow_name }
|
|
Packit |
9982d0 |
#define ENTRY(name, key, action, type, parameter) \
|
|
Packit |
9982d0 |
ENTRY_FULL (name, key, action, type, parameter, "win.shadow")
|
|
Packit |
9982d0 |
#define ENTRY_MDI(name, key, action, type, parameter) \
|
|
Packit |
9982d0 |
ENTRY_FULL (name, key, action, type, parameter, "win.shadow-mdi")
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
static KeyEntry file_entries[] = {
|
|
Packit |
9982d0 |
ENTRY (N_("New Tab"), KEY_NEW_TAB, "new-terminal", "(ss)", "('tab','current')" ),
|
|
Packit |
9982d0 |
ENTRY (N_("New Window"), KEY_NEW_WINDOW, "new-terminal", "(ss)", "('window','current')"),
|
|
Packit |
9982d0 |
#ifdef ENABLE_SAVE
|
|
Packit |
9982d0 |
ENTRY (N_("Save Contents"), KEY_SAVE_CONTENTS, "save-contents", NULL, NULL ),
|
|
Packit |
9982d0 |
#endif
|
|
Packit |
9982d0 |
#ifdef ENABLE_EXPORT
|
|
Packit |
9982d0 |
ENTRY (N_("Export"), KEY_EXPORT, "export", NULL, NULL ),
|
|
Packit |
9982d0 |
#endif
|
|
Packit |
9982d0 |
#ifdef ENABLE_PRINT
|
|
Packit |
9982d0 |
ENTRY (N_("Print"), KEY_PRINT, "print", NULL, NULL ),
|
|
Packit |
9982d0 |
#endif
|
|
Packit |
9982d0 |
ENTRY (N_("Close Tab"), KEY_CLOSE_TAB, "close", "s", "'tab'" ),
|
|
Packit |
9982d0 |
ENTRY (N_("Close Window"), KEY_CLOSE_WINDOW, "close", "s", "'window'" ),
|
|
Packit |
9982d0 |
};
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
static KeyEntry edit_entries[] = {
|
|
Packit |
9982d0 |
ENTRY (N_("Copy"), KEY_COPY, "copy", "s", "'text'" ),
|
|
Packit |
9982d0 |
ENTRY (N_("Copy as HTML"), KEY_COPY_HTML, "copy", "s", "'html'" ),
|
|
Packit |
9982d0 |
ENTRY (N_("Paste"), KEY_PASTE, "paste-text", NULL, NULL ),
|
|
Packit |
9982d0 |
ENTRY (N_("Select All"), KEY_SELECT_ALL, "select-all", NULL, NULL ),
|
|
Packit |
9982d0 |
ENTRY (N_("Preferences"), KEY_PREFERENCES, "edit-preferences", NULL, NULL ),
|
|
Packit |
9982d0 |
};
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
static KeyEntry search_entries[] = {
|
|
Packit |
9982d0 |
ENTRY (N_("Find"), KEY_FIND, "find", NULL, NULL),
|
|
Packit |
9982d0 |
ENTRY (N_("Find Next"), KEY_FIND_NEXT, "find-forward", NULL, NULL),
|
|
Packit |
9982d0 |
ENTRY (N_("Find Previous"), KEY_FIND_PREV, "find-backward", NULL, NULL),
|
|
Packit |
9982d0 |
ENTRY (N_("Clear Highlight"), KEY_FIND_CLEAR, "find-clear", NULL, NULL)
|
|
Packit |
9982d0 |
};
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
static KeyEntry view_entries[] = {
|
|
Packit |
9982d0 |
ENTRY (N_("Hide and Show Menubar"), KEY_TOGGLE_MENUBAR, "menubar-visible", NULL, NULL),
|
|
Packit |
9982d0 |
ENTRY (N_("Full Screen"), KEY_FULL_SCREEN, "fullscreen", NULL, NULL),
|
|
Packit |
9982d0 |
ENTRY (N_("Zoom In"), KEY_ZOOM_IN, "zoom-in", NULL, NULL),
|
|
Packit |
9982d0 |
ENTRY (N_("Zoom Out"), KEY_ZOOM_OUT, "zoom-out", NULL, NULL),
|
|
Packit |
9982d0 |
ENTRY (N_("Normal Size"), KEY_ZOOM_NORMAL, "zoom-normal", NULL, NULL)
|
|
Packit |
9982d0 |
};
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
static KeyEntry terminal_entries[] = {
|
|
Packit |
9982d0 |
ENTRY (N_("Read-Only"), KEY_READ_ONLY, "read-only", NULL, NULL ),
|
|
Packit |
9982d0 |
ENTRY (N_("Reset"), KEY_RESET, "reset", "b", "false"),
|
|
Packit |
9982d0 |
ENTRY (N_("Reset and Clear"), KEY_RESET_AND_CLEAR, "reset", "b", "true" ),
|
|
Packit |
9982d0 |
};
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
static KeyEntry tabs_entries[] = {
|
|
Packit |
9982d0 |
ENTRY_MDI (N_("Switch to Previous Tab"), KEY_PREV_TAB, "tab-switch-left", NULL, NULL),
|
|
Packit |
9982d0 |
ENTRY_MDI (N_("Switch to Next Tab"), KEY_NEXT_TAB, "tab-switch-right", NULL, NULL),
|
|
Packit |
9982d0 |
ENTRY_MDI (N_("Move Tab to the Left"), KEY_MOVE_TAB_LEFT, "tab-move-left", NULL, NULL),
|
|
Packit |
9982d0 |
ENTRY_MDI (N_("Move Tab to the Right"), KEY_MOVE_TAB_RIGHT, "tab-move-right", NULL, NULL),
|
|
Packit |
9982d0 |
ENTRY_MDI (N_("Detach Tab"), KEY_DETACH_TAB, "tab-detach", NULL, NULL),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "1", "active-tab", "i", "0"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "2", "active-tab", "i", "1"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "3", "active-tab", "i", "2"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "4", "active-tab", "i", "3"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "5", "active-tab", "i", "4"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "6", "active-tab", "i", "5"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "7", "active-tab", "i", "6"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "8", "active-tab", "i", "7"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "9", "active-tab", "i", "8"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "10", "active-tab", "i", "9"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "11", "active-tab", "i", "10"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "12", "active-tab", "i", "11"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "13", "active-tab", "i", "12"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "14", "active-tab", "i", "13"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "15", "active-tab", "i", "14"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "16", "active-tab", "i", "15"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "17", "active-tab", "i", "16"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "18", "active-tab", "i", "17"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "19", "active-tab", "i", "18"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "20", "active-tab", "i", "19"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "21", "active-tab", "i", "20"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "22", "active-tab", "i", "21"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "23", "active-tab", "i", "22"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "24", "active-tab", "i", "23"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "25", "active-tab", "i", "24"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "26", "active-tab", "i", "25"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "27", "active-tab", "i", "26"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "28", "active-tab", "i", "27"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "29", "active-tab", "i", "28"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "30", "active-tab", "i", "29"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "31", "active-tab", "i", "30"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "32", "active-tab", "i", "31"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "33", "active-tab", "i", "32"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "34", "active-tab", "i", "33"),
|
|
Packit |
9982d0 |
ENTRY_MDI (NULL, KEY_SWITCH_TAB_PREFIX "35", "active-tab", "i", "34"),
|
|
Packit |
9982d0 |
ENTRY_MDI (N_("Switch to Last Tab"), KEY_SWITCH_TAB_PREFIX "last", "active-tab", "i", "-1"),
|
|
Packit |
9982d0 |
};
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
static KeyEntry help_entries[] = {
|
|
Packit |
9982d0 |
ENTRY (N_("Contents"), KEY_HELP, "help", NULL, NULL)
|
|
Packit |
9982d0 |
};
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
#undef ENTRY_FULL
|
|
Packit |
9982d0 |
#undef ENTRY
|
|
Packit |
9982d0 |
#undef ENTRY_MDI
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
static KeyEntryList all_entries[] =
|
|
Packit |
9982d0 |
{
|
|
Packit |
9982d0 |
{ file_entries, G_N_ELEMENTS (file_entries), N_("File") },
|
|
Packit |
9982d0 |
{ edit_entries, G_N_ELEMENTS (edit_entries), N_("Edit") },
|
|
Packit |
9982d0 |
{ view_entries, G_N_ELEMENTS (view_entries), N_("View") },
|
|
Packit |
9982d0 |
{ search_entries, G_N_ELEMENTS (search_entries), N_("Search") },
|
|
Packit |
9982d0 |
{ terminal_entries, G_N_ELEMENTS (terminal_entries), N_("Terminal") },
|
|
Packit |
9982d0 |
{ tabs_entries, G_N_ELEMENTS (tabs_entries), N_("Tabs") },
|
|
Packit |
9982d0 |
{ help_entries, G_N_ELEMENTS (help_entries), N_("Help") }
|
|
Packit |
9982d0 |
};
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
enum
|
|
Packit |
9982d0 |
{
|
|
Packit |
9982d0 |
ACTION_COLUMN,
|
|
Packit |
9982d0 |
KEYVAL_COLUMN,
|
|
Packit |
9982d0 |
N_COLUMNS
|
|
Packit |
9982d0 |
};
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
static GHashTable *settings_key_to_entry;
|
|
Packit |
9982d0 |
static GSettings *keybinding_settings = NULL;
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
GS_DEFINE_CLEANUP_FUNCTION(GtkTreePath*, _terminal_local_free_tree_path, gtk_tree_path_free)
|
|
Packit |
9982d0 |
#define terminal_free_tree_path __attribute__((__cleanup__(_terminal_local_free_tree_path)))
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
static char*
|
|
Packit |
9982d0 |
binding_name (guint keyval,
|
|
Packit |
9982d0 |
GdkModifierType mask)
|
|
Packit |
9982d0 |
{
|
|
Packit |
9982d0 |
if (keyval != 0)
|
|
Packit |
9982d0 |
return gtk_accelerator_name (keyval, mask);
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
return g_strdup ("disabled");
|
|
Packit |
9982d0 |
}
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
static void
|
|
Packit |
9982d0 |
key_changed_cb (GSettings *settings,
|
|
Packit |
9982d0 |
const char *settings_key,
|
|
Packit |
9982d0 |
gpointer user_data)
|
|
Packit |
9982d0 |
{
|
|
Packit |
9982d0 |
GtkApplication *application = user_data;
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
_terminal_debug_print (TERMINAL_DEBUG_ACCELS,
|
|
Packit |
9982d0 |
"key %s changed\n",
|
|
Packit |
9982d0 |
settings_key);
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
KeyEntry *key_entry = g_hash_table_lookup (settings_key_to_entry, settings_key);
|
|
Packit |
9982d0 |
if (!key_entry)
|
|
Packit |
9982d0 |
{
|
|
Packit |
9982d0 |
/* shouldn't really happen, but let's be safe */
|
|
Packit |
9982d0 |
_terminal_debug_print (TERMINAL_DEBUG_ACCELS,
|
|
Packit |
9982d0 |
" WARNING: KeyEntry for changed key not found, bailing out\n");
|
|
Packit |
9982d0 |
return;
|
|
Packit |
9982d0 |
}
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
gs_free char *value = g_settings_get_string (settings, settings_key);
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
gs_free char *detailed = g_action_print_detailed_name (key_entry->action_name,
|
|
Packit |
9982d0 |
key_entry->parameter);
|
|
Packit |
9982d0 |
gs_unref_variant GVariant *shadow_parameter = g_variant_new_string (detailed);
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
/* We want to always consume the action's accelerators, even if the corresponding
|
|
Packit |
9982d0 |
* action is insensitive, so the corresponding shortcut key escape code isn't sent
|
|
Packit |
9982d0 |
* to the terminal. See bug #453193, bug #138609, and bug #559728.
|
|
Packit |
9982d0 |
* Since GtkApplication's accelerators don't use GtkAccelGroup, we have no way
|
|
Packit |
9982d0 |
* to intercept/chain on its activation. The only way to do this that I found
|
|
Packit |
9982d0 |
* was to install an extra action with the same accelerator that shadows
|
|
Packit |
9982d0 |
* the real action and gets activated when the shadowed action is disabled.
|
|
Packit |
9982d0 |
*/
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
if (g_str_equal (value, "disabled")) {
|
|
Packit |
9982d0 |
gtk_application_remove_accelerator (application,
|
|
Packit |
9982d0 |
key_entry->action_name,
|
|
Packit |
9982d0 |
key_entry->parameter);
|
|
Packit |
9982d0 |
gtk_application_remove_accelerator (application,
|
|
Packit |
9982d0 |
key_entry->shadow_action_name,
|
|
Packit |
9982d0 |
shadow_parameter);
|
|
Packit |
9982d0 |
} else {
|
|
Packit |
9982d0 |
gtk_application_add_accelerator (application,
|
|
Packit |
9982d0 |
value,
|
|
Packit |
9982d0 |
key_entry->action_name,
|
|
Packit |
9982d0 |
key_entry->parameter);
|
|
Packit |
9982d0 |
gtk_application_add_accelerator (application,
|
|
Packit |
9982d0 |
value,
|
|
Packit |
9982d0 |
key_entry->shadow_action_name,
|
|
Packit |
9982d0 |
shadow_parameter);
|
|
Packit |
9982d0 |
}
|
|
Packit |
9982d0 |
}
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
void
|
|
Packit |
9982d0 |
terminal_accels_init (GApplication *application,
|
|
Packit |
9982d0 |
GSettings *settings)
|
|
Packit |
9982d0 |
{
|
|
Packit |
9982d0 |
guint i, j;
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
keybinding_settings = g_object_ref (settings);
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
settings_key_to_entry = g_hash_table_new (g_str_hash, g_str_equal);
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
/* Initialise names of tab_switch_entries */
|
|
Packit |
9982d0 |
j = 1;
|
|
Packit |
9982d0 |
for (i = 0; i < G_N_ELEMENTS (tabs_entries); i++)
|
|
Packit |
9982d0 |
{
|
|
Packit |
9982d0 |
gs_free char *name = NULL;
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
if (tabs_entries[i].user_visible_name != NULL)
|
|
Packit |
9982d0 |
continue;
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
name = g_strdup_printf (_("Switch to Tab %u"), j++);
|
|
Packit |
9982d0 |
tabs_entries[i].user_visible_name = g_intern_string (name);
|
|
Packit |
9982d0 |
}
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
for (i = 0; i < G_N_ELEMENTS (all_entries); ++i)
|
|
Packit |
9982d0 |
{
|
|
Packit |
9982d0 |
for (j = 0; j < all_entries[i].n_elements; ++j)
|
|
Packit |
9982d0 |
{
|
|
Packit |
9982d0 |
KeyEntry *key_entry;
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
key_entry = &(all_entries[i].key_entry[j]);
|
|
Packit |
9982d0 |
if (key_entry->action_parameter) {
|
|
Packit |
9982d0 |
GError *err = NULL;
|
|
Packit |
9982d0 |
key_entry->parameter = g_variant_parse (key_entry->action_parameter_type,
|
|
Packit |
9982d0 |
key_entry->action_parameter,
|
|
Packit |
9982d0 |
NULL, NULL, &err;;
|
|
Packit |
9982d0 |
g_assert_no_error (err);
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
g_assert (key_entry->parameter != NULL);
|
|
Packit |
9982d0 |
}
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
g_hash_table_insert (settings_key_to_entry,
|
|
Packit |
9982d0 |
(gpointer) key_entry->settings_key,
|
|
Packit |
9982d0 |
key_entry);
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
key_changed_cb (keybinding_settings, key_entry->settings_key, application);
|
|
Packit |
9982d0 |
}
|
|
Packit |
9982d0 |
}
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
g_signal_connect (keybinding_settings, "changed", G_CALLBACK (key_changed_cb), application);
|
|
Packit |
9982d0 |
}
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
void
|
|
Packit |
9982d0 |
terminal_accels_shutdown (void)
|
|
Packit |
9982d0 |
{
|
|
Packit |
9982d0 |
guint i, j;
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
for (i = 0; i < G_N_ELEMENTS (all_entries); ++i) {
|
|
Packit |
9982d0 |
for (j = 0; j < all_entries[i].n_elements; ++j) {
|
|
Packit |
9982d0 |
KeyEntry *key_entry;
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
key_entry = &(all_entries[i].key_entry[j]);
|
|
Packit |
9982d0 |
if (key_entry->parameter)
|
|
Packit |
9982d0 |
g_variant_unref (key_entry->parameter);
|
|
Packit |
9982d0 |
}
|
|
Packit |
9982d0 |
}
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
g_signal_handlers_disconnect_by_func (keybinding_settings,
|
|
Packit |
9982d0 |
G_CALLBACK (key_changed_cb),
|
|
Packit |
9982d0 |
g_application_get_default ());
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
g_clear_pointer (&settings_key_to_entry, (GDestroyNotify) g_hash_table_unref);
|
|
Packit |
9982d0 |
g_clear_object (&keybinding_settings);
|
|
Packit |
9982d0 |
}
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
static gboolean
|
|
Packit |
9982d0 |
foreach_row_cb (GtkTreeModel *model,
|
|
Packit |
9982d0 |
GtkTreePath *path,
|
|
Packit |
9982d0 |
GtkTreeIter *iter,
|
|
Packit |
9982d0 |
gpointer data)
|
|
Packit |
9982d0 |
{
|
|
Packit |
9982d0 |
const char *key = data;
|
|
Packit |
9982d0 |
KeyEntry *key_entry;
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
gtk_tree_model_get (model, iter,
|
|
Packit |
9982d0 |
KEYVAL_COLUMN, &key_entry,
|
|
Packit |
9982d0 |
-1);
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
if (key_entry == NULL ||
|
|
Packit |
9982d0 |
!g_str_equal (key_entry->settings_key, key))
|
|
Packit |
9982d0 |
return FALSE;
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
gtk_tree_model_row_changed (model, path, iter);
|
|
Packit |
9982d0 |
return TRUE;
|
|
Packit |
9982d0 |
}
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
static void
|
|
Packit |
9982d0 |
treeview_key_changed_cb (GSettings *settings,
|
|
Packit |
9982d0 |
const char *key,
|
|
Packit |
9982d0 |
GtkTreeView *tree_view)
|
|
Packit |
9982d0 |
{
|
|
Packit |
9982d0 |
gtk_tree_model_foreach (gtk_tree_view_get_model (tree_view), foreach_row_cb, (gpointer) key);
|
|
Packit |
9982d0 |
}
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
static void
|
|
Packit |
9982d0 |
accel_set_func (GtkTreeViewColumn *tree_column,
|
|
Packit |
9982d0 |
GtkCellRenderer *cell,
|
|
Packit |
9982d0 |
GtkTreeModel *model,
|
|
Packit |
9982d0 |
GtkTreeIter *iter,
|
|
Packit |
9982d0 |
gpointer data)
|
|
Packit |
9982d0 |
{
|
|
Packit |
9982d0 |
KeyEntry *ke;
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
gtk_tree_model_get (model, iter,
|
|
Packit |
9982d0 |
KEYVAL_COLUMN, &ke,
|
|
Packit |
9982d0 |
-1);
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
if (ke == NULL) {
|
|
Packit |
9982d0 |
/* This is a title row */
|
|
Packit |
9982d0 |
g_object_set (cell,
|
|
Packit |
9982d0 |
"visible", FALSE,
|
|
Packit |
9982d0 |
NULL);
|
|
Packit |
9982d0 |
} else {
|
|
Packit |
9982d0 |
gs_free char *value;
|
|
Packit |
9982d0 |
guint key;
|
|
Packit |
9982d0 |
GdkModifierType mods;
|
|
Packit |
9982d0 |
gboolean writable;
|
|
Packit |
9982d0 |
GtkWidget *button = data;
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
value = g_settings_get_string (keybinding_settings, ke->settings_key);
|
|
Packit |
9982d0 |
gtk_accelerator_parse (value, &key, &mods;;
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
writable = g_settings_is_writable (keybinding_settings, ke->settings_key) &&
|
|
Packit |
9982d0 |
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
g_object_set (cell,
|
|
Packit |
9982d0 |
"visible", TRUE,
|
|
Packit |
9982d0 |
"sensitive", writable,
|
|
Packit |
9982d0 |
"editable", writable,
|
|
Packit |
9982d0 |
"accel-key", key,
|
|
Packit |
9982d0 |
"accel-mods", mods,
|
|
Packit |
9982d0 |
NULL);
|
|
Packit |
9982d0 |
}
|
|
Packit |
9982d0 |
}
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
static void
|
|
Packit |
9982d0 |
accel_update (GtkTreeView *view,
|
|
Packit |
9982d0 |
GtkCellRendererAccel *cell,
|
|
Packit |
9982d0 |
gchar *path_string,
|
|
Packit |
9982d0 |
guint keyval,
|
|
Packit |
9982d0 |
GdkModifierType mask)
|
|
Packit |
9982d0 |
{
|
|
Packit |
9982d0 |
GtkTreeModel *model;
|
|
Packit |
9982d0 |
terminal_free_tree_path GtkTreePath *path = NULL;
|
|
Packit |
9982d0 |
GtkTreeIter iter;
|
|
Packit |
9982d0 |
KeyEntry *ke;
|
|
Packit |
9982d0 |
gs_free char *str = NULL;
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
model = gtk_tree_view_get_model (view);
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
path = gtk_tree_path_new_from_string (path_string);
|
|
Packit |
9982d0 |
if (!path)
|
|
Packit |
9982d0 |
return;
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
if (!gtk_tree_model_get_iter (model, &iter, path))
|
|
Packit |
9982d0 |
return;
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
gtk_tree_model_get (model, &iter, KEYVAL_COLUMN, &ke, -1);
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
/* sanity check */
|
|
Packit |
9982d0 |
if (ke == NULL)
|
|
Packit |
9982d0 |
return;
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
str = binding_name (keyval, mask);
|
|
Packit |
9982d0 |
g_settings_set_string (keybinding_settings, ke->settings_key, str);
|
|
Packit |
9982d0 |
}
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
static void
|
|
Packit |
9982d0 |
accel_edited_callback (GtkCellRendererAccel *cell,
|
|
Packit |
9982d0 |
gchar *path_string,
|
|
Packit |
9982d0 |
guint keyval,
|
|
Packit |
9982d0 |
GdkModifierType mask,
|
|
Packit |
9982d0 |
guint hardware_keycode,
|
|
Packit |
9982d0 |
GtkTreeView *view)
|
|
Packit |
9982d0 |
{
|
|
Packit |
9982d0 |
accel_update (view, cell, path_string, keyval, mask);
|
|
Packit |
9982d0 |
}
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
static void
|
|
Packit |
9982d0 |
accel_cleared_callback (GtkCellRendererAccel *cell,
|
|
Packit |
9982d0 |
gchar *path_string,
|
|
Packit |
9982d0 |
GtkTreeView *view)
|
|
Packit |
9982d0 |
{
|
|
Packit |
9982d0 |
accel_update (view, cell, path_string, 0, 0);
|
|
Packit |
9982d0 |
}
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
static void
|
|
Packit |
9982d0 |
treeview_destroy_cb (GtkWidget *tree_view,
|
|
Packit |
9982d0 |
gpointer user_data)
|
|
Packit |
9982d0 |
{
|
|
Packit |
9982d0 |
g_signal_handlers_disconnect_by_func (keybinding_settings,
|
|
Packit |
9982d0 |
G_CALLBACK (treeview_key_changed_cb),
|
|
Packit |
9982d0 |
tree_view);
|
|
Packit |
9982d0 |
}
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
#ifdef ENABLE_DEBUG
|
|
Packit |
9982d0 |
static void
|
|
Packit |
9982d0 |
row_changed (GtkTreeModel *tree_model,
|
|
Packit |
9982d0 |
GtkTreePath *path,
|
|
Packit |
9982d0 |
GtkTreeIter *iter,
|
|
Packit |
9982d0 |
gpointer user_data)
|
|
Packit |
9982d0 |
{
|
|
Packit |
9982d0 |
_terminal_debug_print (TERMINAL_DEBUG_ACCELS,
|
|
Packit |
9982d0 |
"ROW-CHANGED [%s]\n", gtk_tree_path_to_string (path) /* leak */);
|
|
Packit |
9982d0 |
}
|
|
Packit |
9982d0 |
#endif
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
void
|
|
Packit |
9982d0 |
terminal_accels_fill_treeview (GtkWidget *tree_view,
|
|
Packit |
9982d0 |
GtkWidget *disable_shortcuts_button)
|
|
Packit |
9982d0 |
{
|
|
Packit |
9982d0 |
GtkTreeViewColumn *column;
|
|
Packit |
9982d0 |
GtkCellRenderer *cell_renderer;
|
|
Packit |
9982d0 |
gs_unref_object GtkTreeStore *tree = NULL;
|
|
Packit |
9982d0 |
guint i;
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
/* Column 1 */
|
|
Packit |
9982d0 |
cell_renderer = gtk_cell_renderer_text_new ();
|
|
Packit |
9982d0 |
column = gtk_tree_view_column_new_with_attributes (_("_Action"),
|
|
Packit |
9982d0 |
cell_renderer,
|
|
Packit |
9982d0 |
"text", ACTION_COLUMN,
|
|
Packit |
9982d0 |
NULL);
|
|
Packit |
9982d0 |
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
/* Column 2 */
|
|
Packit |
9982d0 |
cell_renderer = gtk_cell_renderer_accel_new ();
|
|
Packit |
9982d0 |
g_object_set (cell_renderer,
|
|
Packit |
9982d0 |
"editable", TRUE,
|
|
Packit |
9982d0 |
"accel-mode", GTK_CELL_RENDERER_ACCEL_MODE_GTK,
|
|
Packit |
9982d0 |
NULL);
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
g_signal_connect (cell_renderer, "accel-edited",
|
|
Packit |
9982d0 |
G_CALLBACK (accel_edited_callback), tree_view);
|
|
Packit |
9982d0 |
g_signal_connect (cell_renderer, "accel-cleared",
|
|
Packit |
9982d0 |
G_CALLBACK (accel_cleared_callback), tree_view);
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
column = gtk_tree_view_column_new ();
|
|
Packit |
9982d0 |
gtk_tree_view_column_set_title (column, _("Shortcut _Key"));
|
|
Packit |
9982d0 |
gtk_tree_view_column_pack_start (column, cell_renderer, TRUE);
|
|
Packit |
9982d0 |
gtk_tree_view_column_set_cell_data_func (column, cell_renderer, accel_set_func,
|
|
Packit |
9982d0 |
disable_shortcuts_button, NULL);
|
|
Packit |
9982d0 |
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
/* Add the data */
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
tree = gtk_tree_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_POINTER);
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
#ifdef ENABLE_DEBUG
|
|
Packit |
9982d0 |
_TERMINAL_DEBUG_IF (TERMINAL_DEBUG_ACCELS)
|
|
Packit |
9982d0 |
g_signal_connect (tree, "row-changed", G_CALLBACK (row_changed), NULL);
|
|
Packit |
9982d0 |
#endif
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
for (i = 0; i < G_N_ELEMENTS (all_entries); ++i)
|
|
Packit |
9982d0 |
{
|
|
Packit |
9982d0 |
GtkTreeIter parent_iter;
|
|
Packit |
9982d0 |
guint j;
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
gtk_tree_store_insert_with_values (tree, &parent_iter, NULL, -1,
|
|
Packit |
9982d0 |
ACTION_COLUMN, _(all_entries[i].user_visible_name),
|
|
Packit |
9982d0 |
KEYVAL_COLUMN, NULL,
|
|
Packit |
9982d0 |
-1);
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
for (j = 0; j < all_entries[i].n_elements; ++j)
|
|
Packit |
9982d0 |
{
|
|
Packit |
9982d0 |
KeyEntry *key_entry = &(all_entries[i].key_entry[j]);
|
|
Packit |
9982d0 |
GtkTreeIter iter;
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
gtk_tree_store_insert_with_values (tree, &iter, &parent_iter, -1,
|
|
Packit |
9982d0 |
ACTION_COLUMN, _(key_entry->user_visible_name),
|
|
Packit |
9982d0 |
KEYVAL_COLUMN, key_entry,
|
|
Packit |
9982d0 |
-1);
|
|
Packit |
9982d0 |
}
|
|
Packit |
9982d0 |
}
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), GTK_TREE_MODEL (tree));
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
|
|
Packit |
9982d0 |
|
|
Packit |
9982d0 |
g_signal_connect (keybinding_settings, "changed",
|
|
Packit |
9982d0 |
G_CALLBACK (treeview_key_changed_cb), tree_view);
|
|
Packit |
9982d0 |
g_signal_connect (tree_view, "destroy",
|
|
Packit |
9982d0 |
G_CALLBACK (treeview_destroy_cb), tree);
|
|
Packit |
9982d0 |
}
|