diff options
Diffstat (limited to 'panels/keyboard/cc-keyboard-panel.c')
-rw-r--r-- | panels/keyboard/cc-keyboard-panel.c | 266 |
1 files changed, 266 insertions, 0 deletions
diff --git a/panels/keyboard/cc-keyboard-panel.c b/panels/keyboard/cc-keyboard-panel.c new file mode 100644 index 0000000..2e91fe7 --- /dev/null +++ b/panels/keyboard/cc-keyboard-panel.c @@ -0,0 +1,266 @@ +/* cc-keyboard-panel.c + * + * Copyright (C) 2010 Intel, Inc + * Copyright (C) 2016 Endless, Inc + * Copyright (C) 2020 System76, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Thomas Wood <thomas.wood@intel.com> + * Georges Basile Stavracas Neto <gbsneto@gnome.org> + * Ian Douglas Scott <idscott@system76.com> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include <glib/gi18n.h> + +#include "cc-keyboard-panel.h" +#include "cc-keyboard-resources.h" +#include "cc-keyboard-shortcut-dialog.h" +#include "cc-input-list-box.h" +#include "cc-xkb-modifier-dialog.h" + +#include "keyboard-shortcuts.h" + +struct _CcKeyboardPanel +{ + CcPanel parent_instance; + + GtkCheckButton *per_window_source; + GtkCheckButton *same_source; + GSettings *keybindings_settings; + + GSettings *input_source_settings; + AdwPreferencesGroup *input_switch_group; + AdwActionRow *alt_chars_row; + AdwActionRow *compose_row; + GtkWidget *value_alternate_chars; + GtkWidget *value_compose; + + AdwActionRow *common_shortcuts_row; +}; + +CC_PANEL_REGISTER (CcKeyboardPanel, cc_keyboard_panel) + +enum { + PROP_0, + PROP_PARAMETERS +}; + +static const CcXkbModifier LV3_MODIFIER = { + "lv3:", + N_("Alternate Characters Key"), + N_("The alternate characters key can be used to enter additional characters. These are sometimes printed as a third-option on your keyboard."), + (CcXkbOption[]){ + { NC_("keyboard key", "Left Alt"), "lv3:lalt_switch" }, + { NC_("keyboard key", "Right Alt"), "lv3:ralt_switch" }, + { NC_("keyboard key", "Left Super"), "lv3:lwin_switch" }, + { NC_("keyboard key", "Right Super"), "lv3:rwin_switch" }, + { NC_("keyboard key", "Menu key"), "lv3:menu_switch" }, + { NC_("keyboard key", "Right Ctrl"), "lv3:switch" }, + { NULL, NULL } + }, + "lv3:ralt_switch", +}; + +static const CcXkbModifier COMPOSE_MODIFIER = { + "compose:", + N_("Compose Key"), + N_("The compose key allows a wide variety of characters to be entered. To use it, press compose then a sequence of characters. " + " For example, compose key followed by <b>C</b> and <b>o</b> will enter <b>©</b>, " + "<b>a</b> followed by <b>'</b> will enter <b>á</b>."), + (CcXkbOption[]){ + { NC_("keyboard key", "Left Alt"), "compose:lalt" }, + { NC_("keyboard key", "Right Alt"), "compose:ralt" }, + { NC_("keyboard key", "Left Super"), "compose:lwin" }, + { NC_("keyboard key", "Right Super"), "compose:rwin" }, + { NC_("keyboard key", "Menu key"), "compose:menu" }, + { NC_("keyboard key", "Right Ctrl"), "compose:rctrl" }, + { NC_("keyboard key", "Caps Lock"), "compose:caps" }, + { NC_("keyboard key", "Scroll Lock"), "compose:sclk" }, + { NC_("keyboard key", "Print Screen"), "compose:prsc" }, + { NULL, NULL } + }, + NULL, +}; + +static void +special_chars_activated (AdwActionRow *row, + CcKeyboardPanel *self) +{ + const CcXkbModifier *modifier; + GtkWindow *window, *dialog; + + window = GTK_WINDOW (cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (self)))); + + if (row == self->alt_chars_row) + modifier = &LV3_MODIFIER; + else if (row == self->compose_row) + modifier = &COMPOSE_MODIFIER; + else + return; + + dialog = GTK_WINDOW (cc_xkb_modifier_dialog_new (self->input_source_settings, modifier)); + + gtk_window_set_transient_for (dialog, window); + gtk_widget_show (GTK_WIDGET (dialog)); +} + +static void +keyboard_shortcuts_activated (AdwActionRow *row, + CcKeyboardPanel *self) +{ + GtkWindow *window; + GtkWidget *shortcut_dialog; + + if (row == self->common_shortcuts_row) + { + window = GTK_WINDOW (cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (self)))); + + shortcut_dialog = cc_keyboard_shortcut_dialog_new (); + gtk_window_set_transient_for (GTK_WINDOW (shortcut_dialog), window); + gtk_widget_show (GTK_WIDGET (shortcut_dialog)); + } +} + +static void +cc_keyboard_panel_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) + { + case PROP_PARAMETERS: + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static const char * +cc_keyboard_panel_get_help_uri (CcPanel *panel) +{ + return "help:gnome-help/keyboard"; +} + +static void +cc_keyboard_panel_finalize (GObject *object) +{ + CcKeyboardPanel *self = CC_KEYBOARD_PANEL (object); + + g_clear_object (&self->input_source_settings); + g_clear_object (&self->keybindings_settings); + + G_OBJECT_CLASS (cc_keyboard_panel_parent_class)->finalize (object); +} + +static void +cc_keyboard_panel_class_init (CcKeyboardPanelClass *klass) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + CcPanelClass *panel_class = CC_PANEL_CLASS (klass); + + panel_class->get_help_uri = cc_keyboard_panel_get_help_uri; + + object_class->set_property = cc_keyboard_panel_set_property; + object_class->finalize = cc_keyboard_panel_finalize; + + g_object_class_override_property (object_class, PROP_PARAMETERS, "parameters"); + + g_type_ensure (CC_TYPE_INPUT_LIST_BOX); + + gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/keyboard/cc-keyboard-panel.ui"); + + gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, input_switch_group); + gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, per_window_source); + gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, same_source); + gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, alt_chars_row); + gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, compose_row); + gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, value_alternate_chars); + gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, value_compose); + gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, common_shortcuts_row); + + gtk_widget_class_bind_template_callback (widget_class, special_chars_activated); + gtk_widget_class_bind_template_callback (widget_class, keyboard_shortcuts_activated); +} + +static gboolean +translate_switch_input_source (GValue *value, + GVariant *variant, + gpointer user_data) +{ + g_autofree const gchar **strv = NULL; + g_autofree gchar *accel_text = NULL; + g_autofree gchar *label = NULL; + CcKeyCombo combo = { 0 }; + + strv = g_variant_get_strv (variant, NULL); + + gtk_accelerator_parse (strv[0] ? strv[0] : "", &combo.keyval, &combo.mask); + accel_text = convert_keysym_state_to_string (&combo); + + label = g_strdup_printf (_("Input sources can be switched using the %s " + "keyboard shortcut.\nThis can be changed in " + "the keyboard shortcut settings."), + accel_text); + + g_value_set_string (value, label); + + return TRUE; +} + +static void +cc_keyboard_panel_init (CcKeyboardPanel *self) +{ + g_resources_register (cc_keyboard_get_resource ()); + + gtk_widget_init_template (GTK_WIDGET (self)); + + self->input_source_settings = g_settings_new ("org.gnome.desktop.input-sources"); + + /* "Input Source Switching" section */ + g_settings_bind (self->input_source_settings, "per-window", + self->same_source, "active", + G_SETTINGS_BIND_DEFAULT | G_SETTINGS_BIND_INVERT_BOOLEAN); + self->keybindings_settings = g_settings_new ("org.gnome.desktop.wm.keybindings"); + g_settings_bind_with_mapping (self->keybindings_settings, "switch-input-source", + self->input_switch_group, "description", + G_SETTINGS_BIND_GET, + translate_switch_input_source, + NULL, NULL, NULL); + + /* "Type Special Characters" section */ + g_settings_bind_with_mapping (self->input_source_settings, + "xkb-options", + self->value_alternate_chars, + "label", + G_SETTINGS_BIND_GET, + xcb_modifier_transform_binding_to_label, + NULL, + (gpointer)&LV3_MODIFIER, + NULL); + g_settings_bind_with_mapping (self->input_source_settings, + "xkb-options", + self->value_compose, + "label", + G_SETTINGS_BIND_GET, + xcb_modifier_transform_binding_to_label, + NULL, + (gpointer)&COMPOSE_MODIFIER, + NULL); +} |