diff --git a/panels/keyboard/cc-keyboard-panel.c b/panels/keyboard/cc-keyboard-panel.c index 8c0e03056139ba6aeea86fcf10a1e3efd0d139d7..f1dfc425eeaaf33609834156d2a158126265cebc 100644 --- a/panels/keyboard/cc-keyboard-panel.c +++ b/panels/keyboard/cc-keyboard-panel.c @@ -68,6 +68,7 @@ static const CcXkbModifier LV3_MODIFIER = { 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", "None"), "lv3:ralt_alt" }, { NC_("keyboard key", "Left Alt"), "lv3:lalt_switch" }, { NC_("keyboard key", "Right Alt"), "lv3:ralt_switch" }, { NC_("keyboard key", "Left Super"), "lv3:lwin_switch" }, @@ -77,6 +78,7 @@ static const CcXkbModifier LV3_MODIFIER = { { NULL, NULL } }, "lv3:ralt_switch", + "lv3:ralt_alt", }; static const CcXkbModifier COMPOSE_MODIFIER = { @@ -98,6 +100,7 @@ static const CcXkbModifier COMPOSE_MODIFIER = { { NULL, NULL } }, NULL, + NULL, }; static const gchar *custom_css = diff --git a/panels/keyboard/cc-xkb-modifier-dialog.c b/panels/keyboard/cc-xkb-modifier-dialog.c index b1fae3d6d200a09e2537063dbfd34caa1039d549..16b89a435dbfdd900fb3ea35091b803fd6b74ff8 100644 --- a/panels/keyboard/cc-xkb-modifier-dialog.c +++ b/panels/keyboard/cc-xkb-modifier-dialog.c @@ -30,7 +30,7 @@ struct _CcXkbModifierDialog GtkDialog parent_instance; GtkLabel *description_label; - GtkSwitch *enabled_switch; + GtkSwitch *default_switch; GtkListBox *listbox; GtkListBox *switch_listbox; HdyActionRow *switch_row; @@ -38,6 +38,7 @@ struct _CcXkbModifierDialog GSettings *input_source_settings; const CcXkbModifier *modifier; GSList *radio_group; + gboolean updating_active_radio; }; G_DEFINE_TYPE (CcXkbModifierDialog, cc_xkb_modifier_dialog, GTK_TYPE_DIALOG) @@ -53,9 +54,9 @@ get_xkb_option_from_name (const CcXkbModifier *modifier, const gchar* name) const CcXkbOption *options = modifier->options; int i; - for (i = 0; options[i].label && options[i].xkb_option; i++) + for (i = 0; options[i].label; i++) { - if (g_str_equal (name, options[i].xkb_option)) + if (g_strcmp0 (name, options[i].xkb_option) == 0) return &options[i]; } @@ -83,9 +84,12 @@ static void update_active_radio (CcXkbModifierDialog *self) { g_auto(GStrv) options = NULL; - GtkRadioButton *rightalt_radio; - const CcXkbOption *default_option; + GtkRadioButton *none_radio; guint i; + gboolean have_nodefault_option = FALSE; + + // Block `on_active_radio_changed_cb` from running + self->updating_active_radio = TRUE; options = g_settings_get_strv (self->input_source_settings, "xkb-options"); @@ -96,27 +100,32 @@ update_active_radio (CcXkbModifierDialog *self) if (!g_str_has_prefix (options[i], self->modifier->prefix)) continue; + if (g_strcmp0 (options[i], self->modifier->nodefault_option) == 0) + have_nodefault_option = TRUE; + radio = get_radio_button_from_xkb_option_name (self, options[i]); if (!radio) continue; gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE); - gtk_switch_set_active (self->enabled_switch, TRUE); + gtk_switch_set_active (self->default_switch, FALSE); + self->updating_active_radio = FALSE; return; } - if (self->modifier->default_option != NULL) + if (have_nodefault_option) { - default_option = get_xkb_option_from_name(self->modifier, self->modifier->default_option); - rightalt_radio = get_radio_button_from_xkb_option_name (self, default_option->xkb_option); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rightalt_radio), TRUE); - gtk_switch_set_active (self->enabled_switch, TRUE); + none_radio = get_radio_button_from_xkb_option_name (self, self->modifier->nodefault_option); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (none_radio), TRUE); + gtk_switch_set_active (self->default_switch, FALSE); } else { - gtk_switch_set_active (self->enabled_switch, FALSE); + gtk_switch_set_active (self->default_switch, TRUE); } + + self->updating_active_radio = FALSE; } static void @@ -127,6 +136,12 @@ set_xkb_option (CcXkbModifierDialog *self, g_auto(GStrv) options = NULL; gboolean found; guint i; + gboolean add_nodefault; + + add_nodefault = xkb_option != self->modifier->default_option + && xkb_option != self->modifier->nodefault_option + && xkb_option != NULL + && self->modifier->nodefault_option != NULL; /* Either replace the existing ":" option in the string * array, or add the option at the end @@ -139,6 +154,8 @@ set_xkb_option (CcXkbModifierDialog *self, { if (g_str_has_prefix (options[i], self->modifier->prefix)) { + if (!found && add_nodefault) + g_ptr_array_add (array, self->modifier->nodefault_option); if (!found && xkb_option != NULL) g_ptr_array_add (array, xkb_option); found = TRUE; @@ -149,6 +166,8 @@ set_xkb_option (CcXkbModifierDialog *self, } } + if (!found && add_nodefault) + g_ptr_array_add (array, self->modifier->nodefault_option); if (!found && xkb_option != NULL) g_ptr_array_add (array, xkb_option); @@ -168,7 +187,10 @@ on_active_radio_changed_cb (CcXkbModifierDialog *self, if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radio))) return; - if (!gtk_switch_get_state (self->enabled_switch)) + if (gtk_switch_get_state (self->default_switch)) + return; + + if (self->updating_active_radio) return; xkb_option = (gchar *)g_object_get_data (G_OBJECT (radio), "xkb-option"); @@ -183,17 +205,17 @@ on_xkb_options_changed_cb (CcXkbModifierDialog *self) } static gboolean -enable_switch_changed_cb (GtkSwitch *widget, - gboolean state, - gpointer user_data) +default_switch_changed_cb (GtkSwitch *widget, + gboolean state, + gpointer user_data) { CcXkbModifierDialog *self = user_data; gchar *xkb_option; GSList *l; - gtk_widget_set_sensitive (GTK_WIDGET (self->listbox), state); + gtk_widget_set_sensitive (GTK_WIDGET (self->listbox), !state); - if (state) + if (!state) { for (l = self->radio_group; l != NULL; l = l->next) { @@ -234,12 +256,12 @@ cc_xkb_modifier_dialog_class_init (CcXkbModifierDialogClass *klass) gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/keyboard/cc-xkb-modifier-dialog.ui"); gtk_widget_class_bind_template_child (widget_class, CcXkbModifierDialog, description_label); - gtk_widget_class_bind_template_child (widget_class, CcXkbModifierDialog, enabled_switch); + gtk_widget_class_bind_template_child (widget_class, CcXkbModifierDialog, default_switch); gtk_widget_class_bind_template_child (widget_class, CcXkbModifierDialog, listbox); gtk_widget_class_bind_template_child (widget_class, CcXkbModifierDialog, switch_listbox); gtk_widget_class_bind_template_child (widget_class, CcXkbModifierDialog, switch_row); - gtk_widget_class_bind_template_callback (widget_class, enable_switch_changed_cb); + gtk_widget_class_bind_template_callback (widget_class, default_switch_changed_cb); } static void @@ -249,7 +271,7 @@ add_radio_buttons (CcXkbModifierDialog *self) CcXkbOption *options = self->modifier->options; int i; - for (i = 0; options[i].label && options[i].xkb_option; i++) + for (i = 0; options[i].label != NULL; i++) { row = g_object_new (GTK_TYPE_LIST_BOX_ROW, "visible", TRUE, @@ -319,12 +341,10 @@ cc_xkb_modifier_dialog_new (GSettings *input_settings, self->modifier = modifier; gtk_window_set_title (GTK_WINDOW (self), gettext (modifier->title)); - hdy_preferences_row_set_title (HDY_PREFERENCES_ROW (self->switch_row), gettext (modifier->title)); gtk_label_set_markup (self->description_label, gettext (modifier->description)); - gtk_widget_set_visible (GTK_WIDGET (self->switch_listbox), modifier->default_option == NULL); add_radio_buttons (self); update_active_radio (self); - gtk_widget_set_sensitive (GTK_WIDGET (self->listbox), gtk_switch_get_state (self->enabled_switch)); + gtk_widget_set_sensitive (GTK_WIDGET (self->listbox), !gtk_switch_get_state (self->default_switch)); return self; } @@ -338,6 +358,7 @@ xcb_modifier_transform_binding_to_label (GValue *value, const CcXkbOption *entry = NULL; const char **items; guint i; + gboolean have_nodefault_option = FALSE; items = g_variant_get_strv (variant, NULL); @@ -346,19 +367,18 @@ xcb_modifier_transform_binding_to_label (GValue *value, entry = get_xkb_option_from_name (modifier, items[i]); if (entry != NULL) break; - } - if (entry == NULL && modifier->default_option == NULL) - { - g_value_set_string (value, _("Disabled")); - return TRUE; + if (g_strcmp0 (items[i], modifier->nodefault_option) == 0) + have_nodefault_option = TRUE; } + + if (entry != NULL) + g_value_set_string (value, + g_dpgettext2 (NULL, "keyboard key", entry->label)); + if (entry == NULL && have_nodefault_option) + g_value_set_string (value, _("None")); else if (entry == NULL) - { - entry = get_xkb_option_from_name(modifier, modifier->default_option); - } + g_value_set_string (value, _("Layout default")); - g_value_set_string (value, - g_dpgettext2 (NULL, "keyboard key", entry->label)); return TRUE; } diff --git a/panels/keyboard/cc-xkb-modifier-dialog.h b/panels/keyboard/cc-xkb-modifier-dialog.h index 91efbcdde7f737c5d28dccc25aa0e159b3d40782..fd05b329bb6f8aee9245acd6c1601b641c15492e 100644 --- a/panels/keyboard/cc-xkb-modifier-dialog.h +++ b/panels/keyboard/cc-xkb-modifier-dialog.h @@ -37,6 +37,7 @@ typedef struct gchar *description; CcXkbOption *options; gchar *default_option; + gchar *nodefault_option; } CcXkbModifier; #define CC_TYPE_XKB_MODIFIER_DIALOG (cc_xkb_modifier_dialog_get_type()) diff --git a/panels/keyboard/cc-xkb-modifier-dialog.ui b/panels/keyboard/cc-xkb-modifier-dialog.ui index 7863ebef31ee36ad9029db66b2ab1d74f2dcd251..e8e030de96c592718bf45a5c8a5fc67214fbcfa8 100644 --- a/panels/keyboard/cc-xkb-modifier-dialog.ui +++ b/panels/keyboard/cc-xkb-modifier-dialog.ui @@ -43,11 +43,12 @@ True False False + Use layout default - + True center - +