summaryrefslogtreecommitdiffstats
path: root/panels/keyboard/cc-alt-chars-key-dialog.c
diff options
context:
space:
mode:
Diffstat (limited to 'panels/keyboard/cc-alt-chars-key-dialog.c')
-rw-r--r--panels/keyboard/cc-alt-chars-key-dialog.c209
1 files changed, 209 insertions, 0 deletions
diff --git a/panels/keyboard/cc-alt-chars-key-dialog.c b/panels/keyboard/cc-alt-chars-key-dialog.c
new file mode 100644
index 0000000..c32c6ba
--- /dev/null
+++ b/panels/keyboard/cc-alt-chars-key-dialog.c
@@ -0,0 +1,209 @@
+/* cc-alt-chars-key-dialog.c
+ *
+ * Copyright 2019 Bastien Nocera <hadess@hadess.net>
+ *
+ * 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/>.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "cc-alt-chars-key-dialog.h"
+
+struct _CcAltCharsKeyDialog
+{
+ GtkDialog parent_instance;
+
+ GSettings *input_source_settings;
+
+ GtkRadioButton *leftalt_radio;
+ GtkRadioButton *leftsuper_radio;
+ GtkRadioButton *menukey_radio;
+ GtkRadioButton *rightalt_radio;
+ GtkRadioButton *rightctrl_radio;
+ GtkRadioButton *rightsuper_radio;
+};
+
+G_DEFINE_TYPE (CcAltCharsKeyDialog, cc_alt_chars_key_dialog, GTK_TYPE_DIALOG)
+
+static GtkRadioButton *
+get_radio_button_from_xkb_option_name (CcAltCharsKeyDialog *self,
+ const gchar *name)
+{
+ if (g_str_equal (name, "lv3:switch"))
+ return self->rightctrl_radio;
+ else if (g_str_equal (name, "lv3:menu_switch"))
+ return self->menukey_radio;
+ else if (g_str_equal (name, "lv3:lwin_switch"))
+ return self->leftsuper_radio;
+ else if (g_str_equal (name, "lv3:rwin_switch"))
+ return self->rightsuper_radio;
+ else if (g_str_equal (name, "lv3:lalt_switch"))
+ return self->leftalt_radio;
+ else if (g_str_equal (name, "lv3:ralt_switch"))
+ return self->rightalt_radio;
+
+ return NULL;
+}
+
+static const gchar *
+get_xkb_option_name_from_radio_button (CcAltCharsKeyDialog *self,
+ GtkRadioButton *radio)
+{
+ if (radio == self->rightctrl_radio)
+ return "lv3:switch";
+ else if (radio == self->menukey_radio)
+ return "lv3:menu_switch";
+ else if (radio == self->leftsuper_radio)
+ return "lv3:lwin_switch";
+ else if (radio == self->rightsuper_radio)
+ return "lv3:rwin_switch";
+ else if (radio == self->leftalt_radio)
+ return "lv3:lalt_switch";
+ else if (radio == self->rightalt_radio)
+ return "lv3:ralt_switch";
+
+ return NULL;
+}
+
+static void
+update_active_radio (CcAltCharsKeyDialog *self)
+{
+ g_auto(GStrv) options = NULL;
+ guint i;
+
+ options = g_settings_get_strv (self->input_source_settings, "xkb-options");
+
+ for (i = 0; options != NULL && options[i] != NULL; i++)
+ {
+ GtkRadioButton *radio;
+
+ if (!g_str_has_prefix (options[i], "lv3:"))
+ continue;
+
+ radio = get_radio_button_from_xkb_option_name (self, options[i]);
+
+ if (!radio)
+ continue;
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE);
+ return;
+ }
+
+ /* Fallback to Right Alt as default */
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->rightalt_radio), TRUE);
+}
+
+static void
+on_active_lv3_changed_cb (GtkRadioButton *radio,
+ CcAltCharsKeyDialog *self)
+{
+ g_autoptr(GPtrArray) array = NULL;
+ g_auto(GStrv) options = NULL;
+ gboolean found;
+ guint i;
+
+ if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radio)))
+ return;
+
+ /* Either replace the existing "lv3:" option in the string
+ * array, or add the option at the end
+ */
+ array = g_ptr_array_new ();
+ 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:"))
+ {
+ g_ptr_array_add (array, (gchar *)get_xkb_option_name_from_radio_button (self, radio));
+ found = TRUE;
+ }
+ else
+ {
+ g_ptr_array_add (array, options[i]);
+ }
+ }
+
+ if (!found)
+ g_ptr_array_add (array, (gchar *)get_xkb_option_name_from_radio_button (self, radio));
+
+ g_ptr_array_add (array, NULL);
+
+ g_settings_set_strv (self->input_source_settings,
+ "xkb-options",
+ (const gchar * const *) array->pdata);
+}
+
+static void
+on_xkb_options_changed_cb (CcAltCharsKeyDialog *self)
+{
+ update_active_radio (self);
+}
+
+static void
+cc_alt_chars_key_dialog_finalize (GObject *object)
+{
+ CcAltCharsKeyDialog *self = (CcAltCharsKeyDialog *)object;
+
+ g_clear_object (&self->input_source_settings);
+
+ G_OBJECT_CLASS (cc_alt_chars_key_dialog_parent_class)->finalize (object);
+}
+
+static void
+cc_alt_chars_key_dialog_class_init (CcAltCharsKeyDialogClass *klass)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = cc_alt_chars_key_dialog_finalize;
+
+ gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/keyboard/cc-alt-chars-key-dialog.ui");
+
+ gtk_widget_class_bind_template_child (widget_class, CcAltCharsKeyDialog, leftalt_radio);
+ gtk_widget_class_bind_template_child (widget_class, CcAltCharsKeyDialog, leftsuper_radio);
+ gtk_widget_class_bind_template_child (widget_class, CcAltCharsKeyDialog, menukey_radio);
+ gtk_widget_class_bind_template_child (widget_class, CcAltCharsKeyDialog, rightalt_radio);
+ gtk_widget_class_bind_template_child (widget_class, CcAltCharsKeyDialog, rightctrl_radio);
+ gtk_widget_class_bind_template_child (widget_class, CcAltCharsKeyDialog, rightsuper_radio);
+
+ gtk_widget_class_bind_template_callback (widget_class, on_active_lv3_changed_cb);
+}
+
+static void
+cc_alt_chars_key_dialog_init (CcAltCharsKeyDialog *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+
+ self->input_source_settings = g_settings_new ("org.gnome.desktop.input-sources");
+ g_signal_connect_object (self->input_source_settings,
+ "changed::xkb-options",
+ G_CALLBACK (on_xkb_options_changed_cb),
+ self, G_CONNECT_SWAPPED);
+ update_active_radio (self);
+}
+
+CcAltCharsKeyDialog *
+cc_alt_chars_key_dialog_new (GSettings *input_settings)
+{
+ CcAltCharsKeyDialog *self;
+
+ self = g_object_new (CC_TYPE_ALT_CHARS_KEY_DIALOG,
+ "use-header-bar", 1,
+ NULL);
+ self->input_source_settings = g_object_ref (input_settings);
+
+ return self;
+}