GCC Code Coverage Report


Directory: ./
File: panels/keyboard/cc-keyboard-panel.c
Date: 2024-05-03 09:46:52
Exec Total Coverage
Lines: 0 78 0.0%
Functions: 0 13 0.0%
Branches: 0 15 0.0%

Line Branch Exec Source
1 /* cc-keyboard-panel.c
2 *
3 * Copyright (C) 2010 Intel, Inc
4 * Copyright (C) 2016 Endless, Inc
5 * Copyright (C) 2020 System76, Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 *
20 * Author: Thomas Wood <thomas.wood@intel.com>
21 * Georges Basile Stavracas Neto <gbsneto@gnome.org>
22 * Ian Douglas Scott <idscott@system76.com>
23 *
24 * SPDX-License-Identifier: GPL-2.0-or-later
25 */
26
27 #include <glib/gi18n.h>
28
29 #include "cc-keyboard-panel.h"
30 #include "cc-keyboard-resources.h"
31 #include "cc-keyboard-shortcut-dialog.h"
32 #include "cc-input-list-box.h"
33 #include "cc-xkb-modifier-dialog.h"
34 #include "cc-list-row.h"
35
36 #include "keyboard-shortcuts.h"
37
38 struct _CcKeyboardPanel
39 {
40 CcPanel parent_instance;
41
42 GtkCheckButton *per_window_source;
43 GtkCheckButton *same_source;
44 GSettings *keybindings_settings;
45
46 GSettings *input_source_settings;
47 AdwPreferencesGroup *input_switch_group;
48 CcListRow *alt_chars_row;
49 CcListRow *compose_row;
50
51 AdwActionRow *common_shortcuts_row;
52 };
53
54 CC_PANEL_REGISTER (CcKeyboardPanel, cc_keyboard_panel)
55
56 enum {
57 PROP_0,
58 PROP_PARAMETERS
59 };
60
61 static const CcXkbModifier LV3_MODIFIER = {
62 "lv3:",
63 N_("Alternate Characters Key"),
64 N_("The alternate characters key can be used to enter additional characters. These are sometimes printed as a third-option on your keyboard."),
65 (CcXkbOption[]){
66 { NC_("keyboard key", "Left Alt"), "lv3:lalt_switch" },
67 { NC_("keyboard key", "Right Alt"), "lv3:ralt_switch" },
68 { NC_("keyboard key", "Left Super"), "lv3:lwin_switch" },
69 { NC_("keyboard key", "Right Super"), "lv3:rwin_switch" },
70 { NC_("keyboard key", "Menu key"), "lv3:menu_switch" },
71 { NC_("keyboard key", "Right Ctrl"), "lv3:switch" },
72 { NULL, NULL }
73 },
74 "lv3:ralt_switch",
75 };
76
77 static const CcXkbModifier COMPOSE_MODIFIER = {
78 "compose:",
79 N_("Compose Key"),
80 N_("The compose key allows a wide variety of characters to be entered. To use it, press compose then a sequence of characters. "
81 " For example, compose key followed by <b>C</b> and <b>o</b> will enter <b>©</b>, "
82 "<b>a</b> followed by <b>'</b> will enter <b>á</b>."),
83 (CcXkbOption[]){
84 { NC_("keyboard key", "Right Alt"), "compose:ralt" },
85 { NC_("keyboard key", "Left Super"), "compose:lwin" },
86 { NC_("keyboard key", "Right Super"), "compose:rwin" },
87 { NC_("keyboard key", "Menu key"), "compose:menu" },
88 { NC_("keyboard key", "Left Ctrl"), "compose:lctrl" },
89 { NC_("keyboard key", "Right Ctrl"), "compose:rctrl" },
90 { NC_("keyboard key", "Caps Lock"), "compose:caps" },
91 { NC_("keyboard key", "Scroll Lock"), "compose:sclk" },
92 { NC_("keyboard key", "Print Screen"), "compose:prsc" },
93 { NC_("keyboard key", "Insert"), "compose:ins" },
94 { NULL, NULL }
95 },
96 NULL,
97 };
98
99 static void
100 show_modifier_dialog (CcKeyboardPanel *self, const CcXkbModifier *modifier)
101 {
102 AdwDialog *dialog;
103
104 dialog = ADW_DIALOG (cc_xkb_modifier_dialog_new (self->input_source_settings, modifier));
105
106 adw_dialog_present (dialog, GTK_WIDGET (self));
107 }
108
109 static void
110 alt_chars_row_activated (CcKeyboardPanel *self)
111 {
112 show_modifier_dialog (self, &LV3_MODIFIER);
113 }
114
115 static void
116 compose_row_activated (CcKeyboardPanel *self)
117 {
118 show_modifier_dialog (self, &COMPOSE_MODIFIER);
119 }
120
121 static void
122 keyboard_shortcuts_activated (CcKeyboardPanel *self)
123 {
124 GtkWindow *window;
125 GtkWidget *shortcut_dialog;
126
127 window = GTK_WINDOW (cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (self))));
128
129 shortcut_dialog = cc_keyboard_shortcut_dialog_new ();
130 gtk_window_set_transient_for (GTK_WINDOW (shortcut_dialog), window);
131 gtk_window_present (GTK_WINDOW (shortcut_dialog));
132 }
133
134 static void
135 cc_keyboard_panel_set_property (GObject *object,
136 guint property_id,
137 const GValue *value,
138 GParamSpec *pspec)
139 {
140 switch (property_id)
141 {
142 case PROP_PARAMETERS:
143 break;
144
145 default:
146 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
147 }
148 }
149
150 static const char *
151 cc_keyboard_panel_get_help_uri (CcPanel *panel)
152 {
153 return "help:gnome-help/keyboard";
154 }
155
156 static void
157 cc_keyboard_panel_finalize (GObject *object)
158 {
159 CcKeyboardPanel *self = CC_KEYBOARD_PANEL (object);
160
161 g_clear_object (&self->input_source_settings);
162 g_clear_object (&self->keybindings_settings);
163
164 G_OBJECT_CLASS (cc_keyboard_panel_parent_class)->finalize (object);
165 }
166
167 static void
168 cc_keyboard_panel_class_init (CcKeyboardPanelClass *klass)
169 {
170 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
171 GObjectClass *object_class = G_OBJECT_CLASS (klass);
172 CcPanelClass *panel_class = CC_PANEL_CLASS (klass);
173
174 panel_class->get_help_uri = cc_keyboard_panel_get_help_uri;
175
176 object_class->set_property = cc_keyboard_panel_set_property;
177 object_class->finalize = cc_keyboard_panel_finalize;
178
179 g_object_class_override_property (object_class, PROP_PARAMETERS, "parameters");
180
181 g_type_ensure (CC_TYPE_INPUT_LIST_BOX);
182 g_type_ensure (CC_TYPE_LIST_ROW);
183
184 gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/keyboard/cc-keyboard-panel.ui");
185
186 gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, input_switch_group);
187 gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, per_window_source);
188 gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, same_source);
189 gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, alt_chars_row);
190 gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, compose_row);
191 gtk_widget_class_bind_template_child (widget_class, CcKeyboardPanel, common_shortcuts_row);
192
193 gtk_widget_class_bind_template_callback (widget_class, alt_chars_row_activated);
194 gtk_widget_class_bind_template_callback (widget_class, compose_row_activated);
195 gtk_widget_class_bind_template_callback (widget_class, keyboard_shortcuts_activated);
196 }
197
198 static gboolean
199 translate_switch_input_source (GValue *value,
200 GVariant *variant,
201 gpointer user_data)
202 {
203 g_autofree const gchar **strv = NULL;
204 g_autofree gchar *accel_text = NULL;
205 g_autofree gchar *label = NULL;
206 CcKeyCombo combo = { 0 };
207
208 strv = g_variant_get_strv (variant, NULL);
209
210 gtk_accelerator_parse (strv[0] ? strv[0] : "", &combo.keyval, &combo.mask);
211 accel_text = convert_keysym_state_to_string (&combo);
212
213 label = g_strdup_printf (_("Input sources can be switched using the %s "
214 "keyboard shortcut.\nThis can be changed in "
215 "the keyboard shortcut settings."),
216 accel_text);
217
218 g_value_set_string (value, label);
219
220 return TRUE;
221 }
222
223 static void
224 cc_keyboard_panel_init (CcKeyboardPanel *self)
225 {
226 g_resources_register (cc_keyboard_get_resource ());
227
228 gtk_widget_init_template (GTK_WIDGET (self));
229
230 self->input_source_settings = g_settings_new ("org.gnome.desktop.input-sources");
231
232 /* "Input Source Switching" section */
233 g_settings_bind (self->input_source_settings, "per-window",
234 self->same_source, "active",
235 G_SETTINGS_BIND_DEFAULT | G_SETTINGS_BIND_INVERT_BOOLEAN);
236 self->keybindings_settings = g_settings_new ("org.gnome.desktop.wm.keybindings");
237 g_settings_bind_with_mapping (self->keybindings_settings, "switch-input-source",
238 self->input_switch_group, "description",
239 G_SETTINGS_BIND_GET,
240 translate_switch_input_source,
241 NULL, NULL, NULL);
242
243 /* "Type Special Characters" section */
244 g_settings_bind_with_mapping (self->input_source_settings,
245 "xkb-options",
246 self->alt_chars_row,
247 "secondary-label",
248 G_SETTINGS_BIND_GET,
249 xcb_modifier_transform_binding_to_label,
250 NULL,
251 (gpointer)&LV3_MODIFIER,
252 NULL);
253 g_settings_bind_with_mapping (self->input_source_settings,
254 "xkb-options",
255 self->compose_row,
256 "secondary-label",
257 G_SETTINGS_BIND_GET,
258 xcb_modifier_transform_binding_to_label,
259 NULL,
260 (gpointer)&COMPOSE_MODIFIER,
261 NULL);
262 }
263