[gnome-control-center/wip/alt-chars-key: 515/515] keyboard: Add "Alternate Characters Key" configuration
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center/wip/alt-chars-key: 515/515] keyboard: Add "Alternate Characters Key" configuration
- Date: Thu, 24 Jan 2019 09:34:12 +0000 (UTC)
commit fd1cf53f08d551ce95b4bbbf230b98fdbd10fa5b
Author: Bastien Nocera <hadess hadess net>
Date: Thu Mar 29 13:33:15 2018 +0200
keyboard: Add "Alternate Characters Key" configuration
This adds an entry to select the "Level 3" selection key, which is
usually Right Alt (or Alt-Gr on a majority of keyboards).
Mockups at:
https://raw.githubusercontent.com/gnome-design-team/gnome-mockups/master/system-settings/keyboard/keyboard-wires.png
However, we replaced the "Left Ctrl" key option with a "Menu key"
option, as "Left Ctrl" isn't a possible XKB option for the level3 key.
panels/keyboard/alt-chars-key.ui | 177 +++++++++++++++++++++++++++++++++
panels/keyboard/cc-keyboard-panel.c | 139 +++++++++++++++++++++++++-
panels/keyboard/cc-keyboard-panel.ui | 96 ++++++++++++++++++
panels/keyboard/keyboard.gresource.xml | 1 +
4 files changed, 412 insertions(+), 1 deletion(-)
---
diff --git a/panels/keyboard/alt-chars-key.ui b/panels/keyboard/alt-chars-key.ui
new file mode 100644
index 000000000..c6f7eeb30
--- /dev/null
+++ b/panels/keyboard/alt-chars-key.ui
@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.0 -->
+<interface>
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="alt_chars_key_dialog">
+ <property name="can_focus">False</property>
+ <property name="resizable">False</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_left">12</property>
+ <property name="margin_right">12</property>
+ <property name="margin_top">12</property>
+ <property name="margin_bottom">12</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_top">12</property>
+ <property name="margin_bottom">12</property>
+ <property name="label" translatable="yes">The alternate characters key can be used to enter
additional characters. These are sometimes printed as a third-option on your keyboard.</property>
+ <property name="wrap">True</property>
+ <property name="width_chars">50</property>
+ <property name="max_width_chars">50</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+ <property name="column_homogeneous">True</property>
+ <child>
+ <object class="GtkRadioButton" id="radiobutton_leftalt">
+ <property name="label" translatable="yes">Left Alt</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobutton_rightalt">
+ <property name="label" translatable="yes">Right Alt</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobutton_leftalt</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobutton_leftsuper">
+ <property name="label" translatable="yes">Left Super</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobutton_leftalt</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobutton_rightsuper">
+ <property name="label" translatable="yes">Right Super</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobutton_leftalt</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobutton_menukey">
+ <property name="label" translatable="yes">Menu key</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobutton_leftalt</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobutton_rightctrl">
+ <property name="label" translatable="yes">Right Ctrl</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobutton_leftalt</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="headerbar">
+ <object class="GtkHeaderBar">
+ <property name="can_focus">False</property>
+ <property name="show_close_button">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/panels/keyboard/cc-keyboard-panel.c b/panels/keyboard/cc-keyboard-panel.c
index 8162e5ab9..03e3fd7ea 100644
--- a/panels/keyboard/cc-keyboard-panel.c
+++ b/panels/keyboard/cc-keyboard-panel.c
@@ -57,6 +57,10 @@ struct _CcKeyboardPanel
GtkListBoxRow *add_shortcut_row;
GtkSizeGroup *accelerator_sizegroup;
+ /* Alternate characters key */
+ GSettings *input_source_settings;
+ GtkWidget *value_alternate_chars;
+
/* Custom shortcut dialog */
GtkWidget *shortcut_editor;
@@ -77,6 +81,21 @@ static const gchar* custom_css =
" padding: 0;"
"}";
+
+#define DEFAULT_LV3_OPTION 5
+static struct {
+ const char *xkb_option;
+ const char *label;
+ const char *widget_name;
+} lv3_xkb_options[] = {
+ { "lv3:switch", NC_("keyboard key", "Right Ctrl"), "radiobutton_rightctrl" },
+ { "lv3:menu_switch", NC_("keyboard key", "Menu Key"), "radiobutton_menukey" },
+ { "lv3:lwin_switch", NC_("keyboard key", "Left Super"), "radiobutton_leftsuper" },
+ { "lv3:rwin_switch", NC_("keyboard key", "Right Super"), "radiobutton_rightsuper" },
+ { "lv3:lalt_switch", NC_("keyboard key", "Left Alt"), "radiobutton_leftalt" },
+ { "lv3:ralt_switch", NC_("keyboard key", "Right Alt"), "radiobutton_rightalt" },
+};
+
/* RowData functions */
static RowData *
row_data_new (CcKeyboardItem *item,
@@ -264,7 +283,7 @@ add_item (CcKeyboardPanel *self,
"binding",
label,
"label",
- G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE,
+ G_SETTINGS_BIND_GET | G_BINDING_SYNC_CREATE,
transform_binding_to_accel,
NULL, NULL, NULL);
@@ -598,6 +617,113 @@ shortcut_row_activated (GtkWidget *button,
gtk_widget_show (self->shortcut_editor);
}
+static void
+active_lv3_changed (GtkToggleButton *button,
+ CcKeyboardPanel *self)
+{
+ char **options;
+ GPtrArray *array;
+ guint i;
+ gboolean found;
+
+ if (!gtk_toggle_button_get_active (button))
+ return;
+
+ /* Either replace the existing "lv3:" option in the string
+ * array, or add the option at the end */
+ array = g_ptr_array_new_with_free_func (g_free);
+ options = g_settings_get_strv (self->input_source_settings, "xkb-options");
+ found = FALSE;
+ for (i = 0; options != NULL && options[i] != NULL; i++) {
+ if (g_str_has_prefix (options[i], "lv3:")) {
+ found = TRUE;
+ g_ptr_array_add (array, g_strdup ((char *) g_object_get_data (G_OBJECT (button), "option")));
+ } else {
+ g_ptr_array_add (array, g_strdup (options[i]));
+ }
+ }
+ g_strfreev (options);
+
+ if (!found)
+ g_ptr_array_add (array, g_strdup ((char *) g_object_get_data (G_OBJECT (button), "option")));
+
+ g_ptr_array_add (array, NULL);
+
+ g_settings_set_strv (self->input_source_settings, "xkb-options",
+ (const char **) array->pdata);
+ g_ptr_array_free (array, TRUE);
+}
+
+static void
+alternate_chars_activated (GtkWidget *button,
+ GtkListBoxRow *row,
+ CcKeyboardPanel *self)
+{
+ GtkBuilder *builder;
+ GtkWidget *dialog;
+ guint i;
+ const char *current_lv3_widget;
+
+ current_lv3_widget = g_object_get_data (G_OBJECT (self->value_alternate_chars), "lv3_widget_name");
+ builder = gtk_builder_new_from_resource ("/org/gnome/control-center/keyboard/alt-chars-key.ui");
+ for (i = 0; i < G_N_ELEMENTS(lv3_xkb_options); i++) {
+ GObject *label;
+
+ label = gtk_builder_get_object (builder, lv3_xkb_options[i].widget_name);
+ g_object_set_data (label, "option", (gpointer) lv3_xkb_options[i].xkb_option);
+ if (g_str_equal (current_lv3_widget, lv3_xkb_options[i].widget_name))
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (label), TRUE);
+
+ g_signal_connect (label, "toggled", G_CALLBACK (active_lv3_changed), self);
+ }
+ dialog = GTK_WIDGET (gtk_builder_get_object (builder, "alt_chars_key_dialog"));
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Alternate Characters Key"));
+ gtk_window_set_transient_for (GTK_WINDOW (dialog),
+ GTK_WINDOW (cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (self)))));
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ g_object_unref (builder);
+}
+
+static gboolean
+transform_binding_to_alt_chars (GValue *value,
+ GVariant *variant,
+ gpointer user_data)
+{
+ GObject *value_alternate_chars = user_data;
+ const char **items;
+ guint i;
+
+ items = g_variant_get_strv (variant, NULL);
+ if (!items)
+ goto bail;
+
+ for (i = 0; items[i] != NULL; i++) {
+ guint j;
+ if (!g_str_has_prefix (items[i], "lv3:"))
+ continue;
+
+ for (j = 0; j < G_N_ELEMENTS (lv3_xkb_options); j++) {
+ if (g_str_equal (items[i], lv3_xkb_options[j].xkb_option)) {
+ g_value_set_string (value,
+ g_dpgettext2 (NULL, "keyboard key", lv3_xkb_options[j].label));
+ g_object_set_data (value_alternate_chars,
+ "lv3_widget_name",
+ (gpointer) lv3_xkb_options[j].widget_name);
+ return TRUE;
+ }
+ }
+ }
+
+bail:
+ g_value_set_string (value,
+ g_dpgettext2 (NULL, "keyboard key", lv3_xkb_options[DEFAULT_LV3_OPTION].label));
+ g_object_set_data (value_alternate_chars,
+ "lv3_widget_name",
+ (gpointer) lv3_xkb_options[DEFAULT_LV3_OPTION].widget_name);
+ return TRUE;
+}
+
static void
cc_keyboard_panel_set_property (GObject *object,
guint property_id,
@@ -628,6 +754,7 @@ cc_keyboard_panel_finalize (GObject *object)
g_clear_pointer (&self->pictures_regex, g_regex_unref);
g_clear_object (&self->accelerator_sizegroup);
+ g_clear_object (&self->input_source_settings);
cc_keyboard_option_clear_all ();
@@ -684,9 +811,11 @@ cc_keyboard_panel_class_init (CcKeyboardPanelClass *klass)
gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, search_bar);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, search_button);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, search_entry);
+ gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, value_alternate_chars);
gtk_widget_class_bind_template_callback (widget_class, reset_all_clicked_cb);
gtk_widget_class_bind_template_callback (widget_class, shortcut_row_activated);
+ gtk_widget_class_bind_template_callback (widget_class, alternate_chars_activated);
}
static void
@@ -708,6 +837,14 @@ cc_keyboard_panel_init (CcKeyboardPanel *self)
g_object_unref (provider);
+ /* Alternate characters key */
+ self->input_source_settings = g_settings_new ("org.gnome.desktop.input-sources");
+ g_settings_bind_with_mapping (self->input_source_settings, "xkb-options",
+ self->value_alternate_chars, "label",
+ G_SETTINGS_BIND_GET,
+ transform_binding_to_alt_chars,
+ NULL, self->value_alternate_chars, NULL);
+
/* Shortcut manager */
self->manager = cc_keyboard_manager_new ();
diff --git a/panels/keyboard/cc-keyboard-panel.ui b/panels/keyboard/cc-keyboard-panel.ui
index 4a526577b..d94cf8647 100644
--- a/panels/keyboard/cc-keyboard-panel.ui
+++ b/panels/keyboard/cc-keyboard-panel.ui
@@ -53,6 +53,102 @@
<property name="margin_right">18</property>
<property name="spacing">12</property>
<property name="halign">center</property>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkListBox" id="alternate_chars_listbox">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="selection-mode">none</property>
+ <property name="width-request">250</property>
+ <signal name="row-activated" handler="alternate_chars_activated"
object="CcKeyboardPanel" swapped="no" />
+ <child>
+ <object class="GtkListBoxRow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="expand">True</property>
+ <property name="border_width">6</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="heading_alternate_chars">
+ <property name="hexpand">True</property>
+ <property name="expand">True</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_start">12</property>
+ <property name="margin_end">12</property>
+ <property name="margin_top">6</property>
+ <property name="margin_bottom">0</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Alternate Characters
Key</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">value_alternate_chars</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="subtitle_alternate_chars">
+ <property name="hexpand">True</property>
+ <property name="expand">True</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_start">12</property>
+ <property name="margin_end">12</property>
+ <property name="margin_top">0</property>
+ <property name="margin_bottom">6</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Hold down and type to
enter different characters</property>
+ <property name="use_underline">False</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel" id="value_alternate_chars">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="margin_start">12</property>
+ <property name="margin_end">12</property>
+ <property name="margin_top">12</property>
+ <property name="margin_bottom">12</property>
+ <property name="label" translatable="no">Right Alt</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
diff --git a/panels/keyboard/keyboard.gresource.xml b/panels/keyboard/keyboard.gresource.xml
index 862f9f754..8cc4e2b85 100644
--- a/panels/keyboard/keyboard.gresource.xml
+++ b/panels/keyboard/keyboard.gresource.xml
@@ -4,5 +4,6 @@
<file preprocess="xml-stripblanks">cc-keyboard-panel.ui</file>
<file preprocess="xml-stripblanks">enter-keyboard-shortcut.svg</file>
<file preprocess="xml-stripblanks">shortcut-editor.ui</file>
+ <file preprocess="xml-stripblanks">alt-chars-key.ui</file>
</gresource>
</gresources>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]