From 07da36c8b2c8db0e0a0c1357000be9af51952606 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Jun 23 2014 12:29:23 +0000 Subject: greeter: add a gnomekbd indicator to panel This lets users switch between keyboard layouts configured for the system. --- diff --git a/configure.ac b/configure.ac index 943c65b..f430508 100644 --- a/configure.ac +++ b/configure.ac @@ -47,6 +47,7 @@ SCROLLKEEPER_REQUIRED_VERSION=0.1.4 GCONF_REQUIRED_VERSION=2.6.1 GNOME_PANEL_REQUIRED_VERSION=2.0.0 LIBXKLAVIER_REQUIRED_VERSION=4.0 +LIBGNOMEKBDUI_REQUIRED_VERSION=0.1 LIBCANBERRA_GTK_REQUIRED_VERSION=0.4 #FONTCONFIG_REQUIRED_VERSION=2.6.0 FONTCONFIG_REQUIRED_VERSION=2.5.0 @@ -138,6 +139,18 @@ AC_SUBST(HAVE_LIBXKLAVIER) AC_SUBST(LIBXKLAVIER_CFLAGS) AC_SUBST(LIBXKLAVIER_LIBS) +PKG_CHECK_MODULES(LIBGNOMEKBDUI, + libgnomekbdui >= $LIBGNOMEKBDUI_REQUIRED_VERSION, + have_libgnomekbdui=yes, + have_libgnomekbdui=no) +if test "x$have_libgnomekbdui" = "xyes" ; then + AC_DEFINE(HAVE_LIBGNOMEKBDUI, [], [Define if we have libgnomekbdui]) +fi +AM_CONDITIONAL(HAVE_LIBGNOMEKBD, test x$have_libgnomekbd = xyes) +AC_SUBST(HAVE_LIBGNOMEKBD) +AC_SUBST(LIBGNOMEKBD_CFLAGS) +AC_SUBST(LIBGNOMEKBD_LIBS) + PKG_CHECK_MODULES(SIMPLE_CHOOSER, dbus-glib-1 >= $DBUS_GLIB_REQUIRED_VERSION gtk+-2.0 >= $GTK_REQUIRED_VERSION diff --git a/gui/simple-greeter/Makefile.am b/gui/simple-greeter/Makefile.am index 86742d2..56c60dd 100644 --- a/gui/simple-greeter/Makefile.am +++ b/gui/simple-greeter/Makefile.am @@ -23,6 +23,8 @@ AM_CPPFLAGS = \ $(DISABLE_DEPRECATED_CFLAGS) \ $(GTK_CFLAGS) \ $(SIMPLE_GREETER_CFLAGS) \ + $(LIBGNOMEKBDUI_CFLAGS) \ + $(LIBXKLAVIER_CFLAGS) \ $(NULL) @INTLTOOL_SCHEMAS_RULE@ @@ -92,6 +94,7 @@ test_greeter_login_window_LDADD = \ $(COMMON_LIBS) \ $(SIMPLE_GREETER_LIBS) \ $(RBAC_LIBS) \ + $(LIBXKLAVIER_LIBS) \ $(NULL) test_greeter_panel_SOURCES = \ @@ -133,6 +136,7 @@ test_greeter_panel_LDADD = \ $(SIMPLE_GREETER_LIBS) \ $(GTK_LIBS) \ $(GCONF_LIBS) \ + $(LIBGNOMEKBDUI_LIBS) \ $(DEVKIT_POWER_LIBS) \ $(NULL) @@ -288,6 +292,7 @@ gdm_simple_greeter_LDADD = \ $(EXTRA_GREETER_LIBS) \ $(SIMPLE_GREETER_LIBS) \ $(RBAC_LIBS) \ + $(LIBGNOMEKBDUI_LIBS) \ $(DEVKIT_POWER_LIBS) \ $(NULL) diff --git a/gui/simple-greeter/gdm-greeter-panel.c b/gui/simple-greeter/gdm-greeter-panel.c index c3d3372..06563dc 100644 --- a/gui/simple-greeter/gdm-greeter-panel.c +++ b/gui/simple-greeter/gdm-greeter-panel.c @@ -44,6 +44,9 @@ #include #endif +#include +#include + #include "gdm-languages.h" #include "gdm-greeter-panel.h" #include "gdm-clock-widget.h" @@ -79,6 +82,7 @@ struct GdmGreeterPanelPrivate GtkWidget *shutdown_button; GtkWidget *shutdown_menu; GtkWidget *language_option_widget; + GtkWidget *keyboard_indicator_widget; GtkWidget *session_option_widget; GdmTimer *animation_timer; @@ -697,12 +701,99 @@ on_shutdown_menu_deactivate (GdmGreeterPanel *panel) } static void +show_or_hide_keyboard_indicator (GdmGreeterPanel *panel) +{ + XklEngine *engine; + guint num_groups; + + engine = gkbd_indicator_get_xkl_engine (); + + num_groups = xkl_engine_get_num_groups (engine); + if (num_groups > 1) { + gtk_widget_show (panel->priv->keyboard_indicator_widget); + } else { + gtk_widget_hide (panel->priv->keyboard_indicator_widget); + } +} + +static void +on_num_groups_changed (XklEngine *engine, + GParamSpec *pspec, + GdmGreeterPanel *panel) +{ + show_or_hide_keyboard_indicator (panel); +} + +static void +on_x_config_changed (XklEngine *engine, + GdmGreeterPanel *panel) +{ + show_or_hide_keyboard_indicator (panel); +} + +static void +on_x_state_changed (XklEngine *engine, + XklEngineStateChange type, + int num, + gboolean predicate, + GdmGreeterPanel *panel) +{ + show_or_hide_keyboard_indicator (panel); +} + +static void +activate_keyboard_layout (GdmGreeterPanel *panel) +{ + XklEngine *engine; + XklConfigRec *config; + + engine = gkbd_indicator_get_xkl_engine (); + config = xkl_config_rec_new (); + + if (xkl_config_rec_get_from_server (config, engine)) { + int i; + + for (i = 1; config->layouts[i] != NULL; i++) { + /* put us at the front of the list, since usernames and + * passwords are usually ascii + */ + if (strcmp (config->layouts[i], "us") == 0) { + char *temp_layout; + char *temp_variant = NULL; + char *temp_options = NULL; + + temp_layout = config->layouts[0]; + config->layouts[0] = config->layouts[i]; + config->layouts[i] = temp_layout; + + if (config->variants != NULL) { + temp_variant = config->variants[0]; + config->variants[0] = config->variants[i]; + config->variants[i] = temp_variant; + } + + if (config->options != NULL) { + temp_options = config->options[0]; + config->options[0] = config->options[i]; + config->options[i] = temp_options; + } + break; + } + } + xkl_config_rec_activate (config, engine); + } + +} + +static void setup_panel (GdmGreeterPanel *panel) { NaTray *tray; GtkWidget *spacer; int padding; + XklEngine *engine; + gdm_profile_start (NULL); GTK_WIDGET_SET_FLAGS (GTK_WIDGET (panel), GTK_CAN_FOCUS); @@ -817,6 +908,27 @@ setup_panel (GdmGreeterPanel *panel) GTK_WIDGET (panel->priv->clock), FALSE, FALSE, 6); gtk_widget_show (panel->priv->clock); + panel->priv->keyboard_indicator_widget = gkbd_indicator_new (); + + gtk_box_pack_end (GTK_BOX (panel->priv->hbox), + GTK_WIDGET (panel->priv->keyboard_indicator_widget), FALSE, FALSE, 6); + + activate_keyboard_layout (panel); + show_or_hide_keyboard_indicator (panel); + + engine = gkbd_indicator_get_xkl_engine (); + g_signal_connect (engine, "notify::num-groups", + G_CALLBACK (on_num_groups_changed), + panel); + + g_signal_connect (engine, "X-config-changed", + G_CALLBACK (on_x_config_changed), + panel); + + g_signal_connect (engine, "X-state-changed", + G_CALLBACK (on_x_state_changed), + panel); + tray = na_tray_new_for_screen (gtk_window_get_screen (GTK_WINDOW (panel)), GTK_ORIENTATION_HORIZONTAL);