2
* Copyright (C) 2011 Red Hat, Inc.
4
* Written by: Matthias Clasen <mclasen@redhat.com>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2, or (at your option)
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27
#include <glib/gi18n.h>
28
#include <gio/gdesktopappinfo.h>
30
#define GNOME_DESKTOP_USE_UNSTABLE_API
31
#include <libgnome-desktop/gnome-xkb-info.h>
37
#include "gdm-languages.h"
38
#include "gnome-region-panel-input.h"
39
#include "keyboard-shortcuts.h"
40
#include "gtkentryaccel.h"
42
#define WID(s) GTK_WIDGET(gtk_builder_get_object (builder, s))
44
#define GNOME_DESKTOP_INPUT_SOURCES_DIR "org.gnome.desktop.input-sources"
45
#define KEY_CURRENT_INPUT_SOURCE "current"
46
#define KEY_INPUT_SOURCES "sources"
47
#define INPUT_SOURCE_TYPE_XKB "xkb"
48
#define INPUT_SOURCE_TYPE_IBUS "ibus"
50
#define MEDIA_KEYS_SCHEMA_ID "org.gnome.desktop.wm.keybindings"
51
#define KEY_PREV_INPUT_SOURCE "switch-input-source-backward"
52
#define KEY_NEXT_INPUT_SOURCE "switch-input-source"
54
#define INDICATOR_KEYBOARD_SCHEMA_ID "com.canonical.indicator.keyboard"
55
#define KEY_VISIBLE "visible"
57
#define LIBGNOMEKBD_DESKTOP_SCHEMA_ID "org.gnome.libgnomekbd.desktop"
58
#define KEY_GROUP_PER_WINDOW "group-per-window"
59
#define KEY_DEFAULT_GROUP "default-group"
61
#define IBUS_PANEL_SECTION "panel"
62
#define IBUS_ORIENTATION_KEY "lookup_table_orientation"
63
#define IBUS_USE_CUSTOM_FONT_KEY "use_custom_font"
64
#define IBUS_CUSTOM_FONT_KEY "custom_font"
74
static GSettings *input_sources_settings = NULL;
75
static GSettings *libgnomekbd_settings = NULL;
76
static GSettings *media_key_settings = NULL;
77
static GSettings *indicator_settings = NULL;
78
static GnomeXkbInfo *xkb_info = NULL;
79
static GtkBuilder *builder = NULL; /* weak pointer */
80
static GtkWidget *input_chooser = NULL; /* weak pointer */
81
static CcRegionKeyboardItem *prev_source_item = NULL;
82
static CcRegionKeyboardItem *next_source_item = NULL;
85
static IBusBus *ibus = NULL;
86
static GHashTable *ibus_engines = NULL;
87
static GCancellable *ibus_cancellable = NULL;
88
static guint shell_name_watch_id = 0;
90
#endif /* HAVE_IBUS */
92
static void populate_model (GtkListStore *store,
93
GtkListStore *active_sources_store);
94
static GtkWidget *input_chooser_new (GtkWindow *main_window,
95
GtkListStore *active_sources);
96
static gboolean input_chooser_get_selected (GtkWidget *chooser,
99
static GtkTreeModel *tree_view_get_actual_model (GtkTreeView *tv);
104
return g_strcmp0 (g_getenv ("XDG_CURRENT_DESKTOP"), "Unity") == 0;
108
has_indicator_keyboard (void)
112
const gchar * const *schemas = g_settings_list_schemas ();
114
while (*schemas != NULL)
116
if (g_strcmp0 (*schemas, INDICATOR_KEYBOARD_SCHEMA_ID) == 0)
127
strv_contains (const gchar * const *strv,
130
const gchar * const *p = strv;
131
for (p = strv; *p; p++)
132
if (g_strcmp0 (*p, str) == 0)
142
if (shell_name_watch_id > 0)
144
g_bus_unwatch_name (shell_name_watch_id);
145
shell_name_watch_id = 0;
147
g_cancellable_cancel (ibus_cancellable);
148
g_clear_object (&ibus_cancellable);
149
g_clear_pointer (&ibus_engines, g_hash_table_destroy);
150
g_clear_object (&ibus);
154
engine_get_display_name (IBusEngineDesc *engine_desc)
157
const gchar *language_code;
158
const gchar *language;
161
name = ibus_engine_desc_get_longname (engine_desc);
162
language_code = ibus_engine_desc_get_language (engine_desc);
163
language = ibus_get_language_name (language_code);
165
display_name = g_strdup_printf ("%s (%s)", language, name);
170
static GDesktopAppInfo *
171
setup_app_info_for_id (const gchar *id)
173
GDesktopAppInfo *app_info;
174
gchar *desktop_file_name;
177
strv = g_strsplit (id, ":", 2);
178
desktop_file_name = g_strdup_printf ("ibus-setup-%s.desktop", strv[0]);
181
app_info = g_desktop_app_info_new (desktop_file_name);
182
g_free (desktop_file_name);
188
input_chooser_repopulate (GtkListStore *active_sources_store)
196
builder = g_object_get_data (G_OBJECT (input_chooser), "builder");
197
model = GTK_LIST_STORE (gtk_builder_get_object (builder, "input_source_model"));
199
gtk_list_store_clear (model);
200
populate_model (model, active_sources_store);
204
update_ibus_active_sources (GtkBuilder *builder)
212
tv = GTK_TREE_VIEW (WID ("active_input_sources"));
213
model = tree_view_get_actual_model (tv);
215
ret = gtk_tree_model_get_iter_first (model, &iter);
218
gtk_tree_model_get (model, &iter,
223
if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS))
225
IBusEngineDesc *engine_desc = NULL;
226
GDesktopAppInfo *app_info = NULL;
227
gchar *display_name = NULL;
229
engine_desc = g_hash_table_lookup (ibus_engines, id);
232
display_name = engine_get_display_name (engine_desc);
233
app_info = setup_app_info_for_id (id);
235
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
236
NAME_COLUMN, display_name,
237
SETUP_COLUMN, app_info,
239
g_free (display_name);
241
g_object_unref (app_info);
248
ret = gtk_tree_model_iter_next (model, &iter);
251
input_chooser_repopulate (GTK_LIST_STORE (model));
255
fetch_ibus_engines_result (GObject *object,
256
GAsyncResult *result,
259
gboolean show_all_sources;
264
list = ibus_bus_list_engines_async_finish (ibus, result, &error);
266
g_clear_object (&ibus_cancellable);
270
g_warning ("Couldn't finish IBus request: %s", error->message);
271
g_error_free (error);
275
show_all_sources = g_settings_get_boolean (input_sources_settings, "show-all-sources");
277
/* Maps engine ids to engine description objects */
278
ibus_engines = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
280
for (l = list; l; l = l->next)
282
IBusEngineDesc *engine = l->data;
283
const gchar *engine_id = ibus_engine_desc_get_name (engine);
285
if (g_str_has_prefix (engine_id, "xkb:"))
286
g_object_unref (engine);
288
g_hash_table_replace (ibus_engines, (gpointer)engine_id, engine);
292
update_ibus_active_sources (builder);
296
fetch_ibus_engines (GtkBuilder *builder)
298
ibus_cancellable = g_cancellable_new ();
300
ibus_bus_list_engines_async (ibus,
303
(GAsyncReadyCallback)fetch_ibus_engines_result,
308
maybe_start_ibus (void)
310
/* IBus doesn't export API in the session bus. The only thing
311
* we have there is a well known name which we can use as a
312
* sure-fire way to activate it. */
313
g_bus_unwatch_name (g_bus_watch_name (G_BUS_TYPE_SESSION,
315
G_BUS_NAME_WATCHER_FLAGS_AUTO_START,
323
update_source_radios (GtkBuilder *builder)
325
GtkWidget *same_source_radio = WID ("same-source-radio");
326
GtkWidget *different_source_radio = WID ("different-source-radio");
327
GtkWidget *default_source_radio = WID ("default-source-radio");
328
GtkWidget *current_source_radio = WID ("current-source-radio");
329
gboolean group_per_window = g_settings_get_boolean (libgnomekbd_settings, KEY_GROUP_PER_WINDOW);
330
gboolean default_group = g_settings_get_int (libgnomekbd_settings, KEY_DEFAULT_GROUP) >= 0;
332
gtk_widget_set_sensitive (default_source_radio, group_per_window);
333
gtk_widget_set_sensitive (current_source_radio, group_per_window);
335
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (different_source_radio)) != group_per_window)
337
if (group_per_window)
338
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (different_source_radio), TRUE);
340
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (same_source_radio), TRUE);
343
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (default_source_radio)) != default_group)
346
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (default_source_radio), TRUE);
348
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (current_source_radio), TRUE);
353
update_orientation_combo (GtkBuilder *builder)
358
IBusConfig *config = ibus_bus_get_config (ibus);
359
GVariant *variant = ibus_config_get_value (config, IBUS_PANEL_SECTION, IBUS_ORIENTATION_KEY);
361
g_return_if_fail (variant != NULL);
363
if (g_variant_is_of_type (variant, G_VARIANT_TYPE_INT32))
365
GtkComboBox *orientation_combo = GTK_COMBO_BOX (WID ("orientation-combo"));
366
gint orientation = g_variant_get_int32 (variant);
368
if (gtk_combo_box_get_active (orientation_combo) != orientation)
369
gtk_combo_box_set_active (orientation_combo, orientation);
372
g_warning ("Orientation setting has type '%s', expected type 'i'",
373
g_variant_get_type_string (variant));
375
g_variant_unref (variant);
381
update_custom_font_buttons (GtkBuilder *builder)
386
IBusConfig *config = ibus_bus_get_config (ibus);
387
GVariant *variant = ibus_config_get_value (config, IBUS_PANEL_SECTION, IBUS_USE_CUSTOM_FONT_KEY);
388
GtkToggleButton *custom_font_check = GTK_TOGGLE_BUTTON (WID ("custom-font-check"));
389
GtkFontButton *custom_font_button = GTK_FONT_BUTTON (WID ("custom-font-button"));
393
if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN))
395
gboolean use_custom_font = g_variant_get_boolean (variant);
397
if (gtk_toggle_button_get_active (custom_font_check) != use_custom_font)
398
gtk_toggle_button_set_active (custom_font_check, use_custom_font);
401
g_warning ("Use custom font setting has type '%s', expected type 'b'",
402
g_variant_get_type_string (variant));
404
g_variant_unref (variant);
407
g_warning ("No use custom font setting '" IBUS_USE_CUSTOM_FONT_KEY "'");
409
variant = ibus_config_get_value (config, IBUS_PANEL_SECTION, IBUS_CUSTOM_FONT_KEY);
413
if (g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING))
415
const gchar *custom_font = g_variant_get_string (variant, NULL);
417
if (g_strcmp0 (gtk_font_button_get_font_name (custom_font_button), custom_font))
418
gtk_font_button_set_font_name (custom_font_button, custom_font);
421
g_warning ("Custom font setting has type '%s', expected type 's'",
422
g_variant_get_type_string (variant));
424
g_variant_unref (variant);
427
g_warning ("No custom font setting '" IBUS_CUSTOM_FONT_KEY "'");
429
gtk_widget_set_sensitive (GTK_WIDGET (custom_font_button),
430
gtk_toggle_button_get_active (custom_font_check));
436
source_radio_toggled (GtkToggleButton *widget,
439
GtkWidget *same_source_radio = WID ("same-source-radio");
440
GtkWidget *different_source_radio = WID ("different-source-radio");
441
GtkWidget *default_source_radio = WID ("default-source-radio");
442
GtkWidget *current_source_radio = WID ("current-source-radio");
443
gboolean different_source_active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (different_source_radio));
444
gboolean default_source_active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (default_source_radio));
445
gboolean group_per_window = g_settings_get_boolean (libgnomekbd_settings, KEY_GROUP_PER_WINDOW);
446
gboolean default_group = g_settings_get_int (libgnomekbd_settings, KEY_DEFAULT_GROUP) >= 0;
448
if (different_source_active != group_per_window)
449
g_settings_set_boolean (libgnomekbd_settings, KEY_GROUP_PER_WINDOW, different_source_active);
451
if (default_source_active != default_group)
452
g_settings_set_int (libgnomekbd_settings, KEY_DEFAULT_GROUP, default_source_active ? 0 : -1);
454
gtk_widget_set_sensitive (default_source_radio, different_source_active);
455
gtk_widget_set_sensitive (current_source_radio, different_source_active);
459
orientation_combo_changed (GtkComboBox *widget,
465
GtkBuilder *builder = user_data;
466
GtkComboBox *orientation_combo = GTK_COMBO_BOX (WID ("orientation-combo"));
467
IBusConfig *config = ibus_bus_get_config (ibus);
468
gint orientation = -1;
469
GVariant *variant = ibus_config_get_value (config, IBUS_PANEL_SECTION, IBUS_ORIENTATION_KEY);
473
if (g_variant_is_of_type (variant, G_VARIANT_TYPE_INT32))
474
orientation = g_variant_get_int32 (variant);
476
g_variant_unref (variant);
479
if (gtk_combo_box_get_active (orientation_combo) != orientation)
481
orientation = gtk_combo_box_get_active (orientation_combo);
482
variant = g_variant_new_int32 (orientation);
484
ibus_config_set_value (config, IBUS_PANEL_SECTION, IBUS_ORIENTATION_KEY, variant);
491
custom_font_changed (GtkWidget *widget,
497
GtkBuilder *builder = user_data;
498
GtkToggleButton *custom_font_check = GTK_TOGGLE_BUTTON (WID ("custom-font-check"));
499
GtkFontButton *custom_font_button = GTK_FONT_BUTTON (WID ("custom-font-button"));
500
IBusConfig *config = ibus_bus_get_config (ibus);
501
gboolean update_setting = TRUE;
502
gboolean use_custom_font;
503
const gchar *custom_font;
504
GVariant *variant = ibus_config_get_value (config, IBUS_PANEL_SECTION, IBUS_USE_CUSTOM_FONT_KEY);
508
if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN))
510
use_custom_font = g_variant_get_boolean (variant);
511
update_setting = gtk_toggle_button_get_active (custom_font_check) != use_custom_font;
514
g_variant_unref (variant);
519
use_custom_font = gtk_toggle_button_get_active (custom_font_check);
520
variant = g_variant_new_boolean (use_custom_font);
522
ibus_config_set_value (config, IBUS_PANEL_SECTION, IBUS_USE_CUSTOM_FONT_KEY, variant);
525
update_setting = TRUE;
526
variant = ibus_config_get_value (config, IBUS_PANEL_SECTION, IBUS_CUSTOM_FONT_KEY);
530
if (g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING))
532
custom_font = g_variant_get_string (variant, NULL);
533
update_setting = g_strcmp0 (gtk_font_button_get_font_name (custom_font_button), custom_font);
536
g_variant_unref (variant);
541
custom_font = gtk_font_button_get_font_name (custom_font_button);
542
variant = g_variant_new_string (custom_font);
544
ibus_config_set_value (config, IBUS_PANEL_SECTION, IBUS_CUSTOM_FONT_KEY, variant);
547
gtk_widget_set_sensitive (GTK_WIDGET (custom_font_button),
548
gtk_toggle_button_get_active (custom_font_check));
554
ibus_config_value_changed (IBusConfig *config,
560
if (g_strcmp0 (section, IBUS_PANEL_SECTION) == 0)
562
if (g_strcmp0 (name, IBUS_ORIENTATION_KEY) == 0)
563
update_orientation_combo (builder);
564
else if (g_strcmp0 (name, IBUS_USE_CUSTOM_FONT_KEY) == 0 ||
565
g_strcmp0 (name, IBUS_CUSTOM_FONT_KEY) == 0)
566
update_custom_font_buttons (builder);
571
ibus_connected (IBusBus *bus,
574
GtkBuilder *builder = user_data;
575
IBusConfig *config = ibus_bus_get_config (bus);
577
g_signal_connect (config, "value-changed",
578
G_CALLBACK (ibus_config_value_changed), NULL);
580
fetch_ibus_engines (builder);
582
if (has_indicator_keyboard ())
584
update_source_radios (builder);
585
update_orientation_combo (builder);
586
update_custom_font_buttons (builder);
589
/* We've got everything we needed, don't want to be called again. */
590
g_signal_handlers_disconnect_by_func (ibus, ibus_connected, builder);
594
on_shell_appeared (GDBusConnection *connection,
596
const gchar *name_owner,
599
GtkBuilder *builder = data;
603
ibus = ibus_bus_new_async ();
604
if (ibus_bus_is_connected (ibus))
605
ibus_connected (ibus, builder);
607
g_signal_connect (ibus, "connected", G_CALLBACK (ibus_connected), builder);
611
#endif /* HAVE_IBUS */
614
add_source_to_table (GtkTreeModel *model,
619
GHashTable *hash = data;
623
gtk_tree_model_get (model, iter,
628
g_hash_table_add (hash, g_strconcat (type, id, NULL));
637
populate_model (GtkListStore *store,
638
GtkListStore *active_sources_store)
640
GHashTable *active_sources_table;
643
GList *sources, *tmp;
644
gchar *source_id = NULL;
646
active_sources_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
648
gtk_tree_model_foreach (GTK_TREE_MODEL (active_sources_store),
650
active_sources_table);
652
sources = gnome_xkb_info_get_all_layouts (xkb_info);
654
for (tmp = sources; tmp; tmp = tmp->next)
657
source_id = g_strconcat (INPUT_SOURCE_TYPE_XKB, tmp->data, NULL);
659
if (g_hash_table_contains (active_sources_table, source_id))
662
gnome_xkb_info_get_layout_info (xkb_info, (const gchar *)tmp->data,
663
&name, NULL, NULL, NULL);
665
gtk_list_store_append (store, &iter);
666
gtk_list_store_set (store, &iter,
668
TYPE_COLUMN, INPUT_SOURCE_TYPE_XKB,
669
ID_COLUMN, tmp->data,
674
g_list_free (sources);
681
sources = g_hash_table_get_keys (ibus_engines);
684
for (tmp = sources; tmp; tmp = tmp->next)
687
source_id = g_strconcat (INPUT_SOURCE_TYPE_IBUS, tmp->data, NULL);
689
if (g_hash_table_contains (active_sources_table, source_id))
692
display_name = engine_get_display_name (g_hash_table_lookup (ibus_engines, tmp->data));
694
gtk_list_store_append (store, &iter);
695
gtk_list_store_set (store, &iter,
696
NAME_COLUMN, display_name,
697
TYPE_COLUMN, INPUT_SOURCE_TYPE_IBUS,
698
ID_COLUMN, tmp->data,
700
g_free (display_name);
704
g_list_free (sources);
708
g_hash_table_destroy (active_sources_table);
712
populate_with_active_sources (GtkListStore *store)
720
GDesktopAppInfo *app_info;
721
GtkTreeIter tree_iter;
723
sources = g_settings_get_value (input_sources_settings, KEY_INPUT_SOURCES);
725
g_variant_iter_init (&iter, sources);
726
while (g_variant_iter_next (&iter, "(&s&s)", &type, &id))
731
if (g_str_equal (type, INPUT_SOURCE_TYPE_XKB))
733
gnome_xkb_info_get_layout_info (xkb_info, id, &name, NULL, NULL, NULL);
736
g_warning ("Couldn't find XKB input source '%s'", id);
739
display_name = g_strdup (name);
741
else if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS))
744
IBusEngineDesc *engine_desc = NULL;
747
engine_desc = g_hash_table_lookup (ibus_engines, id);
751
display_name = engine_get_display_name (engine_desc);
752
app_info = setup_app_info_for_id (id);
755
g_warning ("IBus input source type specified but IBus support was not compiled");
761
g_warning ("Unknown input source type '%s'", type);
765
gtk_list_store_append (store, &tree_iter);
766
gtk_list_store_set (store, &tree_iter,
767
NAME_COLUMN, display_name,
770
SETUP_COLUMN, app_info,
772
g_free (display_name);
774
g_object_unref (app_info);
777
g_variant_unref (sources);
781
update_configuration (GtkTreeModel *model)
786
GVariantBuilder builder;
787
GVariant *old_sources;
788
const gchar *old_current_type;
789
const gchar *old_current_id;
790
guint old_current_index;
794
old_sources = g_settings_get_value (input_sources_settings, KEY_INPUT_SOURCES);
795
old_current_index = g_settings_get_uint (input_sources_settings, KEY_CURRENT_INPUT_SOURCE);
796
old_n_sources = g_variant_n_children (old_sources);
798
if (old_n_sources > 0 && old_current_index < old_n_sources)
800
g_variant_get_child (old_sources,
808
old_current_type = "";
812
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ss)"));
814
gtk_tree_model_get_iter_first (model, &iter);
817
gtk_tree_model_get (model, &iter,
821
if (index != old_current_index &&
822
g_str_equal (type, old_current_type) &&
823
g_str_equal (id, old_current_id))
825
g_settings_set_uint (input_sources_settings, KEY_CURRENT_INPUT_SOURCE, index);
827
g_variant_builder_add (&builder, "(ss)", type, id);
832
while (gtk_tree_model_iter_next (model, &iter));
834
g_settings_set_value (input_sources_settings, KEY_INPUT_SOURCES, g_variant_builder_end (&builder));
835
g_settings_apply (input_sources_settings);
837
g_variant_unref (old_sources);
841
get_selected_iter (GtkBuilder *builder,
842
GtkTreeModel **model,
845
GtkTreeSelection *selection;
847
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (WID ("active_input_sources")));
849
return gtk_tree_selection_get_selected (selection, model, iter);
853
idx_from_model_iter (GtkTreeModel *model,
859
path = gtk_tree_model_get_path (model, iter);
863
idx = gtk_tree_path_get_indices (path)[0];
864
gtk_tree_path_free (path);
870
update_button_sensitivity (GtkBuilder *builder)
872
GtkWidget *remove_button;
873
GtkWidget *up_button;
874
GtkWidget *down_button;
875
GtkWidget *show_button;
876
GtkWidget *settings_button;
882
gboolean settings_sensitive;
883
GDesktopAppInfo *app_info;
885
remove_button = WID("input_source_remove");
886
show_button = WID("input_source_show");
887
up_button = WID("input_source_move_up");
888
down_button = WID("input_source_move_down");
889
settings_button = WID("input_source_settings");
891
tv = GTK_TREE_VIEW (WID ("active_input_sources"));
892
n_active = gtk_tree_model_iter_n_children (gtk_tree_view_get_model (tv), NULL);
894
if (get_selected_iter (builder, &model, &iter))
896
index = idx_from_model_iter (model, &iter);
897
gtk_tree_model_get (model, &iter, SETUP_COLUMN, &app_info, -1);
905
settings_sensitive = (index >= 0 && app_info != NULL);
908
g_object_unref (app_info);
910
gtk_widget_set_sensitive (remove_button, index >= 0 && n_active > 1);
911
gtk_widget_set_sensitive (show_button, index >= 0);
912
gtk_widget_set_sensitive (up_button, index > 0);
913
gtk_widget_set_sensitive (down_button, index >= 0 && index < n_active - 1);
914
gtk_widget_set_visible (settings_button, settings_sensitive);
918
set_selected_path (GtkBuilder *builder,
921
GtkTreeSelection *selection;
923
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (WID ("active_input_sources")));
925
gtk_tree_selection_select_path (selection, path);
928
static GtkTreeModel *
929
tree_view_get_actual_model (GtkTreeView *tv)
931
GtkTreeModel *filtered_store;
933
filtered_store = gtk_tree_view_get_model (tv);
935
return gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (filtered_store));
939
chooser_response (GtkWidget *chooser, gint response_id, gpointer data)
941
GtkBuilder *builder = data;
943
if (response_id == GTK_RESPONSE_OK)
948
if (input_chooser_get_selected (chooser, &model, &iter))
951
GtkListStore *child_model;
952
GtkTreeIter child_iter, filter_iter;
956
GDesktopAppInfo *app_info = NULL;
958
gtk_tree_model_get (model, &iter,
965
if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS))
966
app_info = setup_app_info_for_id (id);
969
tv = GTK_TREE_VIEW (WID ("active_input_sources"));
970
child_model = GTK_LIST_STORE (tree_view_get_actual_model (tv));
972
gtk_list_store_append (child_model, &child_iter);
974
gtk_list_store_set (child_model, &child_iter,
978
SETUP_COLUMN, app_info,
984
g_object_unref (app_info);
986
gtk_tree_model_filter_convert_child_iter_to_iter (GTK_TREE_MODEL_FILTER (gtk_tree_view_get_model (tv)),
989
gtk_tree_selection_select_iter (gtk_tree_view_get_selection (tv), &filter_iter);
991
update_button_sensitivity (builder);
992
update_configuration (GTK_TREE_MODEL (child_model));
996
g_debug ("nothing selected, nothing added");
1000
gtk_widget_destroy (GTK_WIDGET (chooser));
1004
add_input (GtkButton *button, gpointer data)
1006
GtkBuilder *builder = data;
1008
GtkWidget *toplevel;
1009
GtkWidget *treeview;
1010
GtkListStore *active_sources;
1012
g_debug ("add an input source");
1014
toplevel = gtk_widget_get_toplevel (WID ("active_input_sources"));
1015
treeview = WID ("active_input_sources");
1016
active_sources = GTK_LIST_STORE (tree_view_get_actual_model (GTK_TREE_VIEW (treeview)));
1018
chooser = input_chooser_new (GTK_WINDOW (toplevel), active_sources);
1019
g_signal_connect (chooser, "response",
1020
G_CALLBACK (chooser_response), builder);
1024
remove_selected_input (GtkButton *button, gpointer data)
1026
GtkBuilder *builder = data;
1027
GtkTreeModel *model;
1028
GtkTreeModel *child_model;
1030
GtkTreeIter child_iter;
1033
g_debug ("remove selected input source");
1035
if (get_selected_iter (builder, &model, &iter) == FALSE)
1038
path = gtk_tree_model_get_path (model, &iter);
1040
child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
1041
gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model),
1044
gtk_list_store_remove (GTK_LIST_STORE (child_model), &child_iter);
1046
if (!gtk_tree_model_get_iter (model, &iter, path))
1047
gtk_tree_path_prev (path);
1049
set_selected_path (builder, path);
1051
gtk_tree_path_free (path);
1053
update_button_sensitivity (builder);
1054
update_configuration (child_model);
1058
move_selected_input_up (GtkButton *button, gpointer data)
1060
GtkBuilder *builder = data;
1061
GtkTreeModel *model;
1062
GtkTreeModel *child_model;
1063
GtkTreeIter iter, prev;
1064
GtkTreeIter child_iter, child_prev;
1067
g_debug ("move selected input source up");
1069
if (!get_selected_iter (builder, &model, &iter))
1073
if (!gtk_tree_model_iter_previous (model, &prev))
1076
path = gtk_tree_model_get_path (model, &prev);
1078
child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
1079
gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model),
1082
gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model),
1085
gtk_list_store_swap (GTK_LIST_STORE (child_model), &child_iter, &child_prev);
1087
set_selected_path (builder, path);
1088
gtk_tree_path_free (path);
1090
update_button_sensitivity (builder);
1091
update_configuration (child_model);
1095
move_selected_input_down (GtkButton *button, gpointer data)
1097
GtkBuilder *builder = data;
1098
GtkTreeModel *model;
1099
GtkTreeModel *child_model;
1100
GtkTreeIter iter, next;
1101
GtkTreeIter child_iter, child_next;
1104
g_debug ("move selected input source down");
1106
if (!get_selected_iter (builder, &model, &iter))
1110
if (!gtk_tree_model_iter_next (model, &next))
1113
path = gtk_tree_model_get_path (model, &next);
1115
child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
1116
gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model),
1119
gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model),
1122
gtk_list_store_swap (GTK_LIST_STORE (child_model), &child_iter, &child_next);
1124
set_selected_path (builder, path);
1125
gtk_tree_path_free (path);
1127
update_button_sensitivity (builder);
1128
update_configuration (child_model);
1132
show_selected_layout (GtkButton *button, gpointer data)
1134
GtkBuilder *builder = data;
1135
GtkTreeModel *model;
1139
gchar *kbd_viewer_args;
1140
const gchar *xkb_layout;
1141
const gchar *xkb_variant;
1143
g_debug ("show selected layout");
1145
if (!get_selected_iter (builder, &model, &iter))
1148
gtk_tree_model_get (model, &iter,
1153
if (g_str_equal (type, INPUT_SOURCE_TYPE_XKB))
1155
gnome_xkb_info_get_layout_info (xkb_info, id, NULL, NULL, &xkb_layout, &xkb_variant);
1157
if (!xkb_layout || !xkb_layout[0])
1159
g_warning ("Couldn't find XKB input source '%s'", id);
1163
else if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS))
1166
IBusEngineDesc *engine_desc = NULL;
1169
engine_desc = g_hash_table_lookup (ibus_engines, id);
1173
xkb_layout = ibus_engine_desc_get_layout (engine_desc);
1178
g_warning ("Couldn't find IBus input source '%s'", id);
1182
g_warning ("IBus input source type specified but IBus support was not compiled");
1188
g_warning ("Unknown input source type '%s'", type);
1193
kbd_viewer_args = g_strdup_printf ("gkbd-keyboard-display -l \"%s\t%s\"",
1194
xkb_layout, xkb_variant);
1196
kbd_viewer_args = g_strdup_printf ("gkbd-keyboard-display -l %s",
1199
g_spawn_command_line_async (kbd_viewer_args, NULL);
1201
g_free (kbd_viewer_args);
1208
show_selected_settings (GtkButton *button, gpointer data)
1210
GtkBuilder *builder = data;
1211
GtkTreeModel *model;
1213
GdkAppLaunchContext *ctx;
1214
GDesktopAppInfo *app_info;
1216
GError *error = NULL;
1218
g_debug ("show selected layout");
1220
if (!get_selected_iter (builder, &model, &iter))
1223
gtk_tree_model_get (model, &iter, SETUP_COLUMN, &app_info, -1);
1228
ctx = gdk_display_get_app_launch_context (gdk_display_get_default ());
1229
gdk_app_launch_context_set_timestamp (ctx, gtk_get_current_event_time ());
1231
gtk_tree_model_get (model, &iter, ID_COLUMN, &id, -1);
1232
g_app_launch_context_setenv (G_APP_LAUNCH_CONTEXT (ctx),
1237
if (!g_app_info_launch (G_APP_INFO (app_info), NULL, G_APP_LAUNCH_CONTEXT (ctx), &error))
1239
g_warning ("Failed to launch input source setup: %s", error->message);
1240
g_error_free (error);
1243
g_object_unref (ctx);
1244
g_object_unref (app_info);
1248
go_to_shortcuts (GtkLinkButton *button,
1249
CcRegionPanel *panel)
1252
const gchar *argv[] = { "shortcuts", "Typing", NULL };
1253
GError *error = NULL;
1255
g_clear_object (&input_sources_settings);
1257
shell = cc_panel_get_shell (CC_PANEL (panel));
1258
if (!cc_shell_set_active_panel_from_id (shell, "keyboard", argv, &error))
1260
g_warning ("Failed to activate Keyboard panel: %s", error->message);
1261
g_error_free (error);
1268
input_sources_changed (GSettings *settings,
1270
GtkBuilder *builder)
1272
GtkWidget *treeview;
1273
GtkTreeModel *store;
1276
GtkTreeModel *model;
1278
treeview = WID("active_input_sources");
1279
store = tree_view_get_actual_model (GTK_TREE_VIEW (treeview));
1281
if (get_selected_iter (builder, &model, &iter))
1282
path = gtk_tree_model_get_path (model, &iter);
1286
gtk_list_store_clear (GTK_LIST_STORE (store));
1287
populate_with_active_sources (GTK_LIST_STORE (store));
1291
set_selected_path (builder, path);
1292
gtk_tree_path_free (path);
1297
update_shortcut_label (GtkWidget *widget,
1301
guint accel_key, *keycode;
1302
GdkModifierType mods;
1304
if (value == NULL || *value == '\0')
1306
gtk_label_set_text (GTK_LABEL (widget), "\342\200\224");
1309
gtk_accelerator_parse_with_keycode (value, &accel_key, &keycode, &mods);
1310
if (accel_key == 0 && keycode == NULL && mods == 0)
1312
gtk_label_set_text (GTK_LABEL (widget), "\342\200\224");
1313
g_warning ("Failed to parse keyboard shortcut: '%s'", value);
1317
text = gtk_accelerator_get_label_with_keycode (gtk_widget_get_display (widget), accel_key, *keycode, mods);
1319
gtk_label_set_text (GTK_LABEL (widget), text);
1324
update_shortcuts (GtkBuilder *builder)
1326
char **previous, **next;
1327
GSettings *settings;
1329
settings = g_settings_new ("org.gnome.desktop.wm.keybindings");
1331
previous = g_settings_get_strv (settings, "switch-input-source-backward");
1332
next = g_settings_get_strv (settings, "switch-input-source");
1334
update_shortcut_label (WID ("prev-source-shortcut-label"), previous[0]);
1335
update_shortcut_label (WID ("next-source-shortcut-label"), next[0]);
1337
g_strfreev (previous);
1342
libgnomekbd_settings_changed (GSettings *settings,
1346
if (g_strcmp0 (key, KEY_GROUP_PER_WINDOW) == 0 || g_strcmp0 (key, KEY_DEFAULT_GROUP) == 0)
1347
update_source_radios (user_data);
1351
active_sources_visible_func (GtkTreeModel *model,
1355
gchar *display_name;
1357
gtk_tree_model_get (model, iter, NAME_COLUMN, &display_name, -1);
1362
g_free (display_name);
1367
static GtkEntryAccelPostAction
1368
shortcut_key_pressed (GtkEntryAccel *entry,
1371
GdkModifierType *mask,
1374
GtkBuilder *builder = user_data;
1375
CcRegionKeyboardItem *item = NULL;
1378
if (entry == GTK_ENTRY_ACCEL (WID ("prev-source-entry")))
1379
item = prev_source_item;
1380
else if (entry == GTK_ENTRY_ACCEL (WID ("next-source-entry")))
1381
item = next_source_item;
1383
if (*mask == 0 && *key == GDK_KEY_Escape)
1384
return GTK_ENTRY_ACCEL_CANCEL;
1386
if (*mask == 0 && *key == GDK_KEY_BackSpace)
1392
return GTK_ENTRY_ACCEL_UPDATE;
1395
if ((*mask & ~GDK_LOCK_MASK) == 0 &&
1396
(*key == GDK_KEY_Tab ||
1397
*key == GDK_KEY_KP_Tab ||
1398
*key == GDK_KEY_ISO_Left_Tab ||
1399
*key == GDK_KEY_3270_BackTab))
1400
return GTK_ENTRY_ACCEL_IGNORE;
1402
edited = keyboard_shortcuts_accel_edited (item,
1406
gtk_widget_get_toplevel (GTK_WIDGET (entry)));
1408
return edited ? GTK_ENTRY_ACCEL_UPDATE : GTK_ENTRY_ACCEL_IGNORE;
1412
builder_finalized (gpointer data,
1413
GObject *where_the_object_was)
1415
keyboard_shortcuts_dispose ();
1417
g_clear_object (&input_sources_settings);
1418
g_clear_object (&libgnomekbd_settings);
1419
g_clear_object (&indicator_settings);
1420
g_clear_object (&media_key_settings);
1421
g_clear_object (&next_source_item);
1422
g_clear_object (&prev_source_item);
1430
get_key_setting (GValue *value,
1436
switch_key = g_variant_get_strv (variant, NULL);
1437
g_value_set_string (value, switch_key[0]);
1444
set_key_setting (const GValue *value,
1445
const GVariantType *expected_type,
1449
gchar **switch_strv;
1450
GVariant *ret = NULL;
1452
switch_strv = g_settings_get_strv(media_key_settings, user_data);
1453
switch_key = g_value_get_string (value);
1454
switch_strv[0] = g_strdup (switch_key);
1456
ret = g_variant_new_strv ((const gchar * const *) switch_strv, -1);
1463
setup_input_tabs (GtkBuilder *builder_,
1464
CcRegionPanel *panel)
1466
GtkWidget *treeview;
1467
GtkTreeViewColumn *column;
1468
GtkCellRenderer *cell;
1469
GtkListStore *store;
1470
GtkTreeModel *filtered_store;
1471
GtkTreeSelection *selection;
1475
g_object_weak_ref (G_OBJECT (builder), builder_finalized, NULL);
1477
keyboard_shortcuts_init ();
1479
prev_source_item = g_object_ref (keyboard_shortcuts_get_item (MEDIA_KEYS_SCHEMA_ID,
1480
KEY_PREV_INPUT_SOURCE));
1481
next_source_item = g_object_ref (keyboard_shortcuts_get_item (MEDIA_KEYS_SCHEMA_ID,
1482
KEY_NEXT_INPUT_SOURCE));
1484
/* set up the list of active inputs */
1485
treeview = WID("active_input_sources");
1486
column = gtk_tree_view_column_new ();
1487
cell = gtk_cell_renderer_text_new ();
1488
gtk_tree_view_column_pack_start (column, cell, TRUE);
1489
gtk_tree_view_column_add_attribute (column, cell, "text", NAME_COLUMN);
1490
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
1492
store = gtk_list_store_new (N_COLUMNS,
1496
G_TYPE_DESKTOP_APP_INFO);
1498
gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (store));
1500
input_sources_settings = g_settings_new (GNOME_DESKTOP_INPUT_SOURCES_DIR);
1502
g_settings_delay (input_sources_settings);
1505
xkb_info = gnome_xkb_info_new ();
1509
shell_name_watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
1511
G_BUS_NAME_WATCHER_FLAGS_NONE,
1518
populate_with_active_sources (store);
1520
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
1521
g_signal_connect_swapped (selection, "changed",
1522
G_CALLBACK (update_button_sensitivity), builder);
1524
/* Some input source types might have their info loaded
1525
* asynchronously. In that case we don't want to show them
1526
* immediately so we use a filter model on top of the real model
1527
* which mirrors the GSettings key. */
1528
filtered_store = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
1529
gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filtered_store),
1530
active_sources_visible_func,
1533
gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), filtered_store);
1535
/* set up the buttons */
1536
g_signal_connect (WID("input_source_add"), "clicked",
1537
G_CALLBACK (add_input), builder);
1538
g_signal_connect (WID("input_source_remove"), "clicked",
1539
G_CALLBACK (remove_selected_input), builder);
1540
g_signal_connect (WID("input_source_move_up"), "clicked",
1541
G_CALLBACK (move_selected_input_up), builder);
1542
g_signal_connect (WID("input_source_move_down"), "clicked",
1543
G_CALLBACK (move_selected_input_down), builder);
1544
g_signal_connect (WID("input_source_show"), "clicked",
1545
G_CALLBACK (show_selected_layout), builder);
1546
g_signal_connect (WID("input_source_settings"), "clicked",
1547
G_CALLBACK (show_selected_settings), builder);
1548
g_signal_connect (WID("jump-to-shortcuts"), "activate-link",
1549
G_CALLBACK (go_to_shortcuts), panel);
1550
g_signal_connect (G_OBJECT (input_sources_settings),
1551
"changed::" KEY_INPUT_SOURCES,
1552
G_CALLBACK (input_sources_changed),
1555
if (has_indicator_keyboard ())
1557
libgnomekbd_settings = g_settings_new (LIBGNOMEKBD_DESKTOP_SCHEMA_ID);
1558
indicator_settings = g_settings_new (INDICATOR_KEYBOARD_SCHEMA_ID);
1559
media_key_settings = g_settings_new (MEDIA_KEYS_SCHEMA_ID);
1561
update_source_radios (builder);
1562
update_orientation_combo (builder);
1563
update_custom_font_buttons (builder);
1565
g_settings_bind (indicator_settings,
1567
WID ("show-indicator-check"),
1569
G_SETTINGS_BIND_DEFAULT);
1570
g_settings_bind_with_mapping (media_key_settings,
1571
KEY_PREV_INPUT_SOURCE,
1572
WID ("prev-source-entry"),
1574
G_SETTINGS_BIND_DEFAULT,
1577
KEY_PREV_INPUT_SOURCE, NULL);
1578
g_settings_bind_with_mapping (media_key_settings,
1579
KEY_NEXT_INPUT_SOURCE,
1580
WID ("next-source-entry"),
1582
G_SETTINGS_BIND_DEFAULT,
1585
KEY_NEXT_INPUT_SOURCE, NULL);
1587
g_signal_connect (WID ("prev-source-entry"), "key-pressed",
1588
G_CALLBACK (shortcut_key_pressed), builder);
1589
g_signal_connect (WID ("next-source-entry"), "key-pressed",
1590
G_CALLBACK (shortcut_key_pressed), builder);
1591
g_signal_connect (WID ("same-source-radio"), "toggled",
1592
G_CALLBACK (source_radio_toggled), builder);
1593
g_signal_connect (WID ("different-source-radio"), "toggled",
1594
G_CALLBACK (source_radio_toggled), builder);
1595
g_signal_connect (WID ("default-source-radio"), "toggled",
1596
G_CALLBACK (source_radio_toggled), builder);
1597
g_signal_connect (WID ("current-source-radio"), "toggled",
1598
G_CALLBACK (source_radio_toggled), builder);
1599
g_signal_connect (WID ("orientation-combo"), "changed",
1600
G_CALLBACK (orientation_combo_changed), builder);
1601
g_signal_connect (WID ("custom-font-check"), "toggled",
1602
G_CALLBACK (custom_font_changed), builder);
1603
g_signal_connect (WID ("custom-font-button"), "font-set",
1604
G_CALLBACK (custom_font_changed), builder);
1605
g_signal_connect (libgnomekbd_settings,
1607
G_CALLBACK (libgnomekbd_settings_changed),
1612
g_settings_bind (input_sources_settings, "per-window",
1613
WID("per-window-radio-true"), "active",
1614
G_SETTINGS_BIND_DEFAULT);
1615
g_settings_bind (input_sources_settings, "per-window",
1616
WID("per-window-radio-false"), "active",
1617
G_SETTINGS_BIND_DEFAULT | G_SETTINGS_BIND_INVERT_BOOLEAN);
1618
/* because we are in delay-apply mode */
1619
g_signal_connect_swapped (WID("per-window-radio-true"), "clicked",
1620
G_CALLBACK (g_settings_apply), input_sources_settings);
1621
g_signal_connect_swapped (WID("per-window-radio-false"), "clicked",
1622
G_CALLBACK (g_settings_apply), input_sources_settings);
1624
update_shortcuts (builder);
1629
filter_clear (GtkEntry *entry,
1630
GtkEntryIconPosition icon_pos,
1634
gtk_entry_set_text (entry, "");
1637
static gchar **search_pattern_list;
1640
filter_changed (GtkBuilder *builder)
1642
GtkTreeModelFilter *filtered_model;
1643
GtkTreeView *tree_view;
1644
GtkTreeSelection *selection;
1645
GtkTreeIter selected_iter;
1646
GtkWidget *filter_entry;
1647
const gchar *pattern;
1650
filter_entry = WID ("input_source_filter");
1651
pattern = gtk_entry_get_text (GTK_ENTRY (filter_entry));
1652
upattern = g_utf8_strup (pattern, -1);
1653
if (!g_strcmp0 (pattern, ""))
1654
g_object_set (G_OBJECT (filter_entry),
1655
"secondary-icon-name", "edit-find-symbolic",
1656
"secondary-icon-activatable", FALSE,
1657
"secondary-icon-sensitive", FALSE,
1660
g_object_set (G_OBJECT (filter_entry),
1661
"secondary-icon-name", "edit-clear-symbolic",
1662
"secondary-icon-activatable", TRUE,
1663
"secondary-icon-sensitive", TRUE,
1666
if (search_pattern_list != NULL)
1667
g_strfreev (search_pattern_list);
1669
search_pattern_list = g_strsplit (upattern, " ", -1);
1672
filtered_model = GTK_TREE_MODEL_FILTER (gtk_builder_get_object (builder, "filtered_input_source_model"));
1673
gtk_tree_model_filter_refilter (filtered_model);
1675
tree_view = GTK_TREE_VIEW (WID ("filtered_input_source_list"));
1676
selection = gtk_tree_view_get_selection (tree_view);
1677
if (gtk_tree_selection_get_selected (selection, NULL, &selected_iter))
1679
GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (filtered_model),
1681
gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.5, 0.5);
1682
gtk_tree_path_free (path);
1687
if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (filtered_model), &iter))
1688
gtk_tree_selection_select_iter (selection, &iter);
1693
selection_changed (GtkTreeSelection *selection,
1694
GtkBuilder *builder)
1696
gtk_widget_set_sensitive (WID ("ok-button"),
1697
gtk_tree_selection_get_selected (selection, NULL, NULL));
1701
row_activated (GtkTreeView *tree_view,
1703
GtkTreeViewColumn *column,
1704
GtkBuilder *builder)
1706
GtkWidget *add_button;
1709
add_button = WID ("ok-button");
1710
dialog = WID ("input_source_chooser");
1711
if (gtk_widget_is_sensitive (add_button))
1712
gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
1716
entry_activated (GtkBuilder *builder,
1719
row_activated (NULL, NULL, NULL, builder);
1723
filter_func (GtkTreeModel *model,
1731
if (search_pattern_list == NULL || search_pattern_list[0] == NULL)
1734
gtk_tree_model_get (model, iter,
1738
pattern = search_pattern_list;
1740
gboolean is_pattern_found = FALSE;
1741
gchar *udesc = g_utf8_strup (name, -1);
1742
if (udesc != NULL && g_strstr_len (udesc, -1, *pattern))
1744
is_pattern_found = TRUE;
1748
if (!is_pattern_found)
1754
} while (*++pattern != NULL);
1762
input_chooser_new (GtkWindow *main_window,
1763
GtkListStore *active_sources)
1765
GtkBuilder *builder;
1767
GtkWidget *filtered_list;
1768
GtkWidget *filter_entry;
1769
GtkTreeViewColumn *visible_column;
1770
GtkTreeSelection *selection;
1771
GtkListStore *model;
1772
GtkTreeModelFilter *filtered_model;
1775
builder = gtk_builder_new ();
1776
gtk_builder_add_from_file (builder,
1777
GNOMECC_UI_DIR "/gnome-region-panel-input-chooser.ui",
1779
chooser = WID ("input_source_chooser");
1780
input_chooser = chooser;
1781
g_object_add_weak_pointer (G_OBJECT (chooser), (gpointer *) &input_chooser);
1782
g_object_set_data_full (G_OBJECT (chooser), "builder", builder, g_object_unref);
1784
filtered_list = WID ("filtered_input_source_list");
1785
filter_entry = WID ("input_source_filter");
1787
g_object_set_data (G_OBJECT (chooser),
1788
"filtered_input_source_list", filtered_list);
1790
gtk_tree_view_column_new_with_attributes ("Input Sources",
1791
gtk_cell_renderer_text_new (),
1792
"text", NAME_COLUMN,
1795
gtk_window_set_transient_for (GTK_WINDOW (chooser), main_window);
1797
gtk_tree_view_append_column (GTK_TREE_VIEW (filtered_list),
1799
/* We handle searching ourselves, thank you. */
1800
gtk_tree_view_set_enable_search (GTK_TREE_VIEW (filtered_list), FALSE);
1801
gtk_tree_view_set_search_column (GTK_TREE_VIEW (filtered_list), -1);
1803
g_signal_connect_swapped (G_OBJECT (filter_entry), "activate",
1804
G_CALLBACK (entry_activated), builder);
1805
g_signal_connect_swapped (G_OBJECT (filter_entry), "notify::text",
1806
G_CALLBACK (filter_changed), builder);
1808
g_signal_connect (G_OBJECT (filter_entry), "icon-release",
1809
G_CALLBACK (filter_clear), NULL);
1811
filtered_model = GTK_TREE_MODEL_FILTER (gtk_builder_get_object (builder, "filtered_input_source_model"));
1812
model = GTK_LIST_STORE (gtk_builder_get_object (builder, "input_source_model"));
1814
populate_model (model, active_sources);
1816
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
1817
NAME_COLUMN, GTK_SORT_ASCENDING);
1819
gtk_tree_model_filter_set_visible_func (filtered_model,
1823
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (filtered_list));
1825
g_signal_connect (G_OBJECT (selection), "changed",
1826
G_CALLBACK (selection_changed), builder);
1828
if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (filtered_model), &iter))
1829
gtk_tree_selection_select_iter (selection, &iter);
1831
g_signal_connect (G_OBJECT (filtered_list), "row-activated",
1832
G_CALLBACK (row_activated), builder);
1834
gtk_widget_grab_focus (filter_entry);
1836
gtk_widget_show (chooser);
1842
input_chooser_get_selected (GtkWidget *dialog,
1843
GtkTreeModel **model,
1847
GtkTreeSelection *selection;
1849
tv = g_object_get_data (G_OBJECT (dialog), "filtered_input_source_list");
1850
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tv));
1852
return gtk_tree_selection_get_selected (selection, model, iter);