733
717
+ XklEngine *engine = gkbd_configuration_get_xkl_engine (gkbd_configuration);
735
719
XklEngine *engine = gkbd_status_get_xkl_engine ();
722
+ XklState *st = xkl_engine_get_current_state(engine);
725
- st.group = group_number;
740
726
+#ifdef HAVE_APPINDICATOR
741
+ if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (item)))
727
+ if ((item != NULL) && (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (item))))
745
st.group = group_number;
730
+ st->group = group_number;
746
731
xkl_engine_allow_one_switch_to_secondary_group (engine);
747
732
cur = xkl_engine_get_current_window (engine);
748
@@ -382,15 +424,61 @@
733
if (cur != (Window) NULL) {
734
xkl_debug (150, "Enforcing the state %d for window %lx\n",
737
xkl_engine_save_state (engine,
738
xkl_engine_get_current_window
741
/* XSetInputFocus( GDK_DISPLAY(), cur, RevertToNone, CurrentTime );*/
744
"??? Enforcing the state %d for unknown window\n",
749
747
/* strange situation - bad things can happen */
751
xkl_engine_lock_group (engine, st.group);
749
- xkl_engine_lock_group (engine, st.group);
750
+ xkl_engine_lock_group (engine, st->group);
752
751
+#ifdef HAVE_APPINDICATOR
753
+ // Most of this comes directly from libgnomekbd it's not great, but it should work
754
+ // -- Karl Lattimer <karl@qdh.org.uk>
755
+ XklConfigRec * xklrec = xkl_config_rec_new();
756
+ xkl_config_rec_get_from_server (xklrec, engine);
757
+ gkbd_keyboard_config_load_from_x_current (¤t_kbd_config, xklrec);
759
+ XklConfigRegistry *registry = xkl_config_registry_get_instance(engine);
760
+ xkl_config_registry_load (registry, current_config.load_extra_items);
762
+ gchar * layout_name;
764
+ gchar ** shortnames;
765
+ gchar ** longnames;
766
+ static GHashTable *ln2cnt_map;
768
+ gkbd_desktop_config_load_group_descriptions(¤t_config, registry,
769
+ (const gchar **) xklrec->layouts,
770
+ (const gchar **) xklrec->variants,
774
+ layout_name = gkbd_indicator_extract_layout_name(st.group, engine, ¤t_kbd_config, shortnames, longnames);
775
+ lbl_title = gkbd_indicator_create_label_title (st.group, &ln2cnt_map, layout_name);
776
+ if (st.group + 1 == xkl_engine_get_num_groups(engine)) {
777
+ g_hash_table_destroy(ln2cnt_map);
780
+ // Guide of 3 wide-ish and one thin
781
+ app_indicator_set_label(app_indicator, lbl_title, "XXX1");
783
+ // Deallocate memory so we don't leak wildly
784
+ /*g_object_unref (G_OBJECT (xklrec));
785
+ g_object_unref (G_OBJECT (registry));
786
+ g_strfreev(longnames);
787
+ g_strfreev(shortnames);
788
+ g_free(layout_name);
789
+ g_free(lbl_title);*/
752
+ XklConfigRec * xklrec = xkl_config_rec_new();
753
+ xkl_config_rec_get_from_server (xklrec, engine);
754
+ XklConfigRegistry *registry = xkl_config_registry_get_instance(engine);
756
+ gkbd_keyboard_config_load_from_x_current (¤t_kbd_config, xklrec);
757
+ xkl_config_registry_load (registry, current_config.load_extra_items);
760
+ gchar ** shortnames;
761
+ gchar ** longnames;
762
+ gchar * layout_name;
763
+ gchar * lname = NULL;
764
+ GHashTable *ln2cnt_map = g_hash_table_new (g_str_hash, g_str_equal);
766
+ gkbd_desktop_config_load_group_descriptions(¤t_config, registry,
767
+ (const gchar **) xklrec->layouts,
768
+ (const gchar **) xklrec->variants,
772
+ for (g = 0; g < g_strv_length (shortnames);g++) {
773
+ gpointer pcounter = NULL;
774
+ gchar *prev_layout_name = NULL;
777
+ if (g < g_strv_length (shortnames)) {
778
+ if (xkl_engine_get_features (engine) &
779
+ XKLF_MULTIPLE_LAYOUTS_SUPPORTED) {
780
+ gchar *longname = (gchar *) g_slist_nth_data (current_kbd_config.layouts_variants, g);
781
+ gchar *variant_name;
782
+ if (!gkbd_keyboard_config_split_items (longname, &lname, &variant_name))
786
+ /* make it freeable */
787
+ lname = g_strdup (lname);
789
+ if (shortnames != NULL) {
790
+ gchar *shortname = shortnames[g];
791
+ if (shortname != NULL && *shortname != '\0') {
792
+ /* drop the long name */
794
+ lname = g_strdup (shortname);
798
+ lname = g_strdup (longnames[g]);
802
+ lname = g_strdup ("");
804
+ /* Process layouts with repeating description */
805
+ if (g_hash_table_lookup_extended (ln2cnt_map, lname, (gpointer *) & prev_layout_name, &pcounter)) {
806
+ /* "next" same description */
807
+ counter = GPOINTER_TO_INT (pcounter);
809
+ g_hash_table_insert (ln2cnt_map, lname, GINT_TO_POINTER (counter+1));
811
+ if (st->group == g) {
813
+ gchar appendix[10] = "";
816
+ /* Unicode subscript 2, 3, 4 */
817
+ cidx = 0x2081 + counter;
818
+ utf8length = g_unichar_to_utf8 (cidx, appendix);
819
+ appendix[utf8length] = '\0';
820
+ layout_name = g_strconcat (lname, appendix, NULL);
822
+ layout_name = g_strdup(lname);
828
+ // Guide of 3 wide-ish and one thin
829
+ app_indicator_set_label(app_indicator, layout_name, "XXX1");
830
+ g_hash_table_destroy(ln2cnt_map);
832
+ // Deallocate memory so we don't leak wildly
833
+ g_free(layout_name);
834
+ g_object_unref (G_OBJECT (xklrec));
835
+ g_object_unref (G_OBJECT (registry));
836
+ g_strfreev(longnames);
837
+ g_strfreev(shortnames);
841
+#ifdef HAVE_APPINDICATOR
794
843
-status_icon_popup_menu_cb (GtkStatusIcon * icon, guint button, guint time)
844
+state_callback (XklEngine * engine,
845
+ XklEngineStateChange changeType,
846
+ gint group, gboolean restore)
848
+ if (changeType == GROUP_CHANGED)
849
+ popup_menu_set_group(NULL, GINT_TO_POINTER(group));
795
853
+static GtkMenu *
796
854
+create_status_menu (void)
798
856
GtkMenu *popup_menu = GTK_MENU (gtk_menu_new ());
857
+#ifndef HAVE_APPINDICATOR
799
858
GtkMenu *groups_menu = GTK_MENU (gtk_menu_new ());
801
861
+#ifdef HAVE_APPINDICATOR
802
862
+ const char * const *current_name = gkbd_configuration_get_group_names (gkbd_configuration);
807
867
gchar **current_name = gkbd_status_get_group_names ();
870
+#ifndef HAVE_APPINDICATOR
810
871
GtkWidget *item = gtk_menu_item_new_with_mnemonic (_("_Groups"));
811
872
gtk_widget_show (item);
873
gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item);
875
gtk_widget_show (item);
813
876
g_signal_connect (item, "activate", popup_menu_show_layout, NULL);
814
877
gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item);
816
- for (i = 0; *current_name; i++, current_name++) {
817
882
+ for (i = 0; current_name && *current_name; i++, current_name++) {
818
883
+#ifdef HAVE_APPINDICATOR
819
884
+ item = gtk_radio_menu_item_new_with_label (groups_items_group, *current_name);
820
885
+ groups_items_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (item));
887
- for (i = 0; *current_name; i++, current_name++) {
822
888
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
890
+ gtk_widget_show (item);
891
+ gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item);
892
+ g_signal_connect (item, "activate",
893
+ G_CALLBACK (popup_menu_set_group),
894
+ GINT_TO_POINTER (i));
825
896
gchar *image_file = gkbd_status_get_image_filename (i);
827
898
if (image_file == NULL) {
829
(GTK_IMAGE_MENU_ITEM (item), TRUE);
833
gtk_widget_show (item);
834
gtk_menu_shell_append (GTK_MENU_SHELL (groups_menu), item);
899
@@ -438,17 +587,62 @@
835
900
g_signal_connect (item, "activate",
836
@@ -440,15 +536,78 @@
901
G_CALLBACK (popup_menu_set_group),
837
902
GINT_TO_POINTER (i));
906
+#ifdef HAVE_APPINDICATOR
907
+ item = gtk_separator_menu_item_new();
908
+ gtk_widget_show(item);
909
+ gtk_menu_shell_append(GTK_MENU_SHELL (popup_menu), item);
912
+ gtk_menu_item_new_with_mnemonic (_("Keyboard _Preferences"));
913
+ gtk_widget_show (item);
914
+ g_signal_connect (item, "activate", popup_menu_launch_capplet,
916
+ gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item);
918
+ item = gtk_menu_item_new_with_mnemonic (_("Show Current _Layout"));
919
+ gtk_widget_show (item);
920
+ g_signal_connect (item, "activate", popup_menu_show_layout, NULL);
921
+ gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item);
840
924
+ return popup_menu;
863
947
+ app_indicator = app_indicator_new ("gst-keyboard-xkb",
865
949
+ APP_INDICATOR_CATEGORY_HARDWARE);
866
+ // Most of this comes directly from libgnomekbd it's not great, but it should work
867
+ // -- Karl Lattimer <karl@qdh.org.uk>
868
+ XklEngine *engine = gkbd_configuration_get_xkl_engine (gkbd_configuration);
950
+ XklEngine *engine = gkbd_configuration_get_xkl_engine (gkbd_configuration);
869
951
+ XklState *st = xkl_engine_get_current_state(engine);
870
+ XklConfigRec * xklrec = xkl_config_rec_new();
871
+ xkl_config_rec_get_from_server (xklrec, engine);
872
+ gkbd_keyboard_config_load_from_x_current (¤t_kbd_config, xklrec);
874
+ XklConfigRegistry *registry = xkl_config_registry_get_instance(engine);
875
+ xkl_config_registry_load (registry, current_config.load_extra_items);
877
+ gchar * layout_name;
879
+ gchar ** shortnames;
880
+ gchar ** longnames;
881
+ static GHashTable *ln2cnt_map;
883
+ gkbd_desktop_config_load_group_descriptions(¤t_config, registry,
884
+ (const gchar **) xklrec->layouts,
885
+ (const gchar **) xklrec->variants,
889
+ layout_name = gkbd_indicator_extract_layout_name(st->group, engine, ¤t_kbd_config, shortnames, longnames);
890
+ lbl_title = gkbd_indicator_create_label_title (st->group, &ln2cnt_map, layout_name);
891
+ if (st->group + 1 == xkl_engine_get_num_groups(engine)) {
892
+ g_hash_table_destroy(ln2cnt_map);
895
+ // Guide of 3 wide-ish and one thin
896
+ app_indicator_set_label(app_indicator, lbl_title, "XXX1");
898
+ // Deallocate memory so we don't leak wildly
899
+ /*g_object_unref (G_OBJECT (xklrec));
900
+ g_object_unref (G_OBJECT (registry));
901
+ g_strfreev(longnames);
902
+ g_strfreev(shortnames);
903
+ g_free(layout_name);
904
+ g_free(lbl_title);*/
952
+ popup_menu_set_group(NULL, GINT_TO_POINTER(st->group));
906
953
+ app_indicator_set_status (app_indicator,
907
954
+ APP_INDICATOR_STATUS_ACTIVE);
908
955
+ app_indicator_set_menu (app_indicator,