diff options
-rw-r--r-- | configure.ac | 36 | ||||
-rw-r--r-- | src/Makefile.am | 7 | ||||
-rw-r--r-- | src/lightdm-gtk-greeter.c | 250 |
3 files changed, 200 insertions, 93 deletions
diff --git a/configure.ac b/configure.ac index 60c0adc..d7132c4 100644 --- a/configure.ac +++ b/configure.ac @@ -41,7 +41,10 @@ INDICATOR_REQUIRED_VERSION=0.3.92 AS_IF([test "x$have_gtk2" = "xyes"], [INDICATOR_PKG=indicator-0.4], - [INDICATOR_PKG=indicator3-0.4]) + [ + INDICATOR_PKG=indicator3-0.4 + IDO_PKG=libido3-0.1 + ]) AC_ARG_ENABLE([libindicator], AC_HELP_STRING([--enable-libindicator], [Enable libindicator support]) @@ -51,8 +54,11 @@ AC_ARG_ENABLE([libindicator], AS_IF([test "x$enable_libindicator" = "xyes"], [ AS_IF([$PKG_CONFIG --exists "$INDICATOR_PKG >= $INDICATOR_REQUIRED_VERSION" >/dev/null 2>&1], [ PKG_CHECK_MODULES([LIBINDICATOR], [$INDICATOR_PKG >= $INDICATOR_REQUIRED_VERSION], [ + have_libindicator=yes INDICATORDIR=`$PKG_CONFIG --variable=indicatordir $INDICATOR_PKG` AC_SUBST(INDICATORDIR) + UNITY_INDICATORDIR="${prefix}/share/unity/indicators" + AC_SUBST(UNITY_INDICATORDIR) AC_DEFINE([HAVE_LIBINDICATOR], [1], [Define if "$INDICATOR_PKG" is present]) ]) ], [ @@ -64,6 +70,34 @@ AS_IF([test "x$enable_libindicator" = "xyes"], [ AC_MSG_RESULT([disabled]) ]) +AC_ARG_ENABLE([libido], + AC_HELP_STRING([--enable-libido], [Enable libido support]) + AC_HELP_STRING([--disable-libido], [Disable libido support]), + [], [enable_libido=yes]) + +AS_IF([test "x$enable_libido" = "xyes" && test "x$have_libindicator" = "xyes"], [ + AS_IF([$PKG_CONFIG --exists "$IDO_PKG" >/dev/null 2>&1], [ + PKG_CHECK_MODULES([LIBIDO], [$IDO_PKG], [ + AC_DEFINE([HAVE_LIBIDO], [1], [Define if "$IDO_PKG" is present]) + ]) + ], [ + AC_MSG_CHECKING([for optional package $IDO_PKG]) + AC_MSG_RESULT([not found]) + ]) +], [ + AC_MSG_CHECKING([for optional package $IDO_PKG]) + AC_MSG_RESULT([disabled]) +]) + +AC_ARG_ENABLE([indicator-services], + AC_HELP_STRING([--enable-indicator-services], [Try to start indicator services]) + AC_HELP_STRING([--disable-indicator-services], [Do not start indicator services]), + [], [enable_indicator_services=no]) + +AS_IF([test "x$enable_indicator_services" != "xno" && test "x$have_libindicator" = "xyes"], [ + AC_DEFINE([START_INDICATOR_SERVICES], [], [Try to start indicator-services]) +]) + dnl ########################################################################### dnl Internationalization dnl ########################################################################### diff --git a/src/Makefile.am b/src/Makefile.am index 1e501cd..4e32dc5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -15,6 +15,7 @@ AM_CPPFLAGS = \ -DGREETER_DATA_DIR=\""$(datadir)/lightdm-gtk-greeter"\" \ -DCONFIG_FILE=\""$(sysconfdir)/lightdm/lightdm-gtk-greeter.conf"\" \ -DINDICATOR_DIR=\""$(INDICATORDIR)"\" \ + -DUNITY_INDICATOR_DIR=\""$(UNITY_INDICATORDIR)"\" \ $(WARN_CFLAGS) lightdm_gtk_greeter_CFLAGS = \ @@ -23,7 +24,8 @@ lightdm_gtk_greeter_CFLAGS = \ $(GTHREAD_CFLAGS) \ $(LIGHTDMGOBJECT_CFLAGS) \ $(LIBX11_CFLAGS) \ - $(LIBINDICATOR_CFLAGS) + $(LIBINDICATOR_CFLAGS) \ + $(LIBIDO_CFLAGS) lightdm_gtk_greeter_LDADD = \ $(GTK_LIBS) \ @@ -31,7 +33,8 @@ lightdm_gtk_greeter_LDADD = \ $(GTHREAD_LIBS) \ $(LIGHTDMGOBJECT_LIBS) \ $(LIBX11_LIBS) \ - $(LIBINDICATOR_LIBS) + $(LIBINDICATOR_LIBS) \ + $(LIBIDO_LIBS) if MAINTAINER_MODE diff --git a/src/lightdm-gtk-greeter.c b/src/lightdm-gtk-greeter.c index 550b19a..562415b 100644 --- a/src/lightdm-gtk-greeter.c +++ b/src/lightdm-gtk-greeter.c @@ -21,6 +21,7 @@ #include <gtk/gtk.h> #include <glib/gi18n.h> #include <cairo-xlib.h> +#include <sys/wait.h> #include <X11/Xlib.h> #include <X11/Xatom.h> #include <gdk-pixbuf/gdk-pixbuf.h> @@ -34,6 +35,14 @@ #ifdef HAVE_LIBINDICATOR #include <libindicator/indicator-object.h> +#if GTK_CHECK_VERSION (3, 0, 0) +#include <libindicator/indicator-ng.h> +#endif +#endif + +#ifdef HAVE_LIBIDO +/* Some indicators need ido library */ +#include "libido/libido.h" #endif #include <lightdm.h> @@ -52,7 +61,7 @@ static GdkPixbuf *background_pixbuf = NULL; /* Panel Widgets */ static GtkWindow *panel_window; static GtkWidget *clock_label; -static GtkWidget *menubar, *power_menuitem, *session_menuitem, *language_menuitem, *session_badge; +static GtkWidget *menubar, *power_menuitem, *session_menuitem, *language_menuitem, *a11y_menuitem, *session_badge; static GtkWidget *suspend_menuitem, *hibernate_menuitem, *restart_menuitem, *shutdown_menuitem; static GtkMenu *session_menu, *language_menu; static GtkCheckMenuItem *keyboard_menuitem; @@ -263,41 +272,117 @@ menu_show (IndicatorObject *io, IndicatorObjectEntry *entry, guint32 timestamp, } } -static gboolean -load_module (const gchar *name, GtkWidget *menubar) +static void +greeter_set_env (const gchar* key, const gchar* value) +{ + g_setenv (key, value, TRUE); + + GDBusProxy* proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + NULL, NULL); + GVariant* result; + GVariantBuilder* builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY); + g_variant_builder_add (builder, "{ss}", key, value); + result = g_dbus_proxy_call_sync (proxy, "UpdateActivationEnvironment", g_variant_new ("(a{ss})", builder), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + g_variant_unref (result); + g_variant_builder_unref (builder); + g_object_unref (proxy); +} + +static void +#ifdef START_INDICATOR_SERVICES +init_indicators (GKeyFile* config, GPid* indicator_pid, GPid* spi_pid) +#else +init_indicators (GKeyFile* config) +#endif { - IndicatorObject *io; - GList *entries, *lp; - gchar *path; + gchar **names = NULL; + gsize length = 0; + guint i; - g_return_val_if_fail (name, FALSE); +#ifdef START_INDICATOR_SERVICES + GError *error = NULL; + gchar *AT_SPI_CMD[] = {"/usr/lib/at-spi2-core/at-spi-bus-launcher", "--launch-immediately", NULL}; + gchar *INDICATORS_CMD[] = {"init", "--user", "--startup-event", "indicator-services-start", NULL}; +#endif - if (!g_str_has_suffix (name, G_MODULE_SUFFIX)) - return FALSE; + /* Set indicators to run with reduced functionality */ + greeter_set_env ("INDICATOR_GREETER_MODE", "1"); + /* Don't allow virtual file systems? */ + greeter_set_env ("GIO_USE_VFS", "local"); + greeter_set_env ("GVFS_DISABLE_FUSE", "1"); - path = g_build_filename (INDICATOR_DIR, name, NULL); - io = indicator_object_new_from_file (path); - g_free (path); + #ifdef START_INDICATOR_SERVICES + if (!g_spawn_async (NULL, AT_SPI_CMD, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, spi_pid, &error)) + g_warning ("Failed to run \"at-spi-bus-launcher\": %s", error->message); + g_clear_error (&error); - /* used to store/fetch menu entries */ - g_object_set_data_full (G_OBJECT (io), "indicator-custom-menuitems-data", - g_hash_table_new (g_direct_hash, g_direct_equal), - (GDestroyNotify) g_hash_table_destroy); + if (!g_spawn_async (NULL, INDICATORS_CMD, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, indicator_pid, &error)) + g_warning ("Failed to run \"indicator-services\": %s", error->message); + g_clear_error (&error); + #endif - g_signal_connect (G_OBJECT (io), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED, - G_CALLBACK (entry_added), menubar); - g_signal_connect (G_OBJECT (io), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED, - G_CALLBACK (entry_removed), menubar); - g_signal_connect (G_OBJECT (io), INDICATOR_OBJECT_SIGNAL_MENU_SHOW, - G_CALLBACK (menu_show), menubar); + names = g_key_file_get_string_list (config, "greeter", "show-indicators", &length, NULL); - entries = indicator_object_get_entries (io); - for (lp = entries; lp; lp = g_list_next (lp)) - entry_added (io, lp->data, menubar); + for (i = 0; i < length; ++i) + { + gchar* path = NULL; + IndicatorObject* io = NULL; - g_list_free (entries); + if (g_path_is_absolute (names[i])) + { /* library with absolute path */ + io = indicator_object_new_from_file (names[i]); + } + else if (g_str_has_suffix (names[i], G_MODULE_SUFFIX)) + { /* library */ + path = g_build_filename (INDICATOR_DIR, names[i], NULL); + io = indicator_object_new_from_file (path); + } + #if GTK_CHECK_VERSION (3, 0, 0) + else + { /* service file */ + if (strchr (names[i], '.')) + path = g_strdup_printf ("%s/%s", UNITY_INDICATOR_DIR, names[i]); + else + path = g_strdup_printf ("%s/com.canonical.indicator.%s", UNITY_INDICATOR_DIR, names[i]); + io = INDICATOR_OBJECT (indicator_ng_new_for_profile (path, "desktop_greeter", NULL)); + } + #endif - return TRUE; + if (io) + { + GList *entries, *lp; + + /* used to store/fetch menu entries */ + g_object_set_data_full (G_OBJECT (io), "indicator-custom-menuitems-data", + g_hash_table_new (g_direct_hash, g_direct_equal), + (GDestroyNotify) g_hash_table_destroy); + + g_signal_connect (G_OBJECT (io), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED, + G_CALLBACK (entry_added), menubar); + g_signal_connect (G_OBJECT (io), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED, + G_CALLBACK (entry_removed), menubar); + g_signal_connect (G_OBJECT (io), INDICATOR_OBJECT_SIGNAL_MENU_SHOW, + G_CALLBACK (menu_show), menubar); + + entries = indicator_object_get_entries (io); + for (lp = entries; lp; lp = g_list_next (lp)) + entry_added (io, lp->data, menubar); + g_list_free (entries); + } + else + { + g_warning ("Indicator \"%s\": failed to load", names[i]); + } + + g_free (path); + } + g_strfreev (names); } #endif @@ -305,7 +390,7 @@ static gchar * get_session (void) { GList *menu_items, *menu_iter; - + /* if the user manually selected a session, use it */ if (current_session) return current_session; @@ -410,7 +495,7 @@ set_language (const gchar *language) GList *menu_items, *menu_iter; menu_items = gtk_container_get_children(GTK_CONTAINER(language_menu)); - + if (language) { for (menu_iter = menu_items; menu_iter != NULL; menu_iter = g_list_next(menu_iter)) @@ -1934,7 +2019,7 @@ main (int argc, char **argv) GtkBuilder *builder; const GList *items, *item; GtkCellRenderer *renderer; - GtkWidget *menuitem, *image, *infobar_compat, *content_area; + GtkWidget *image, *infobar_compat, *content_area; gchar *value, *state_dir; #if GTK_CHECK_VERSION (3, 0, 0) GdkRGBA background_color; @@ -1943,12 +2028,6 @@ main (int argc, char **argv) GdkColor background_color; #endif GError *error = NULL; -#ifdef HAVE_LIBINDICATOR - gchar **whitelist; - GDir *dir; - gsize length = 0; - guint indicators_loaded = 0, i; -#endif /* Background windows */ gint monitor, scr; @@ -1958,6 +2037,10 @@ main (int argc, char **argv) Display* display; + #ifdef START_INDICATOR_SERVICES + GPid indicator_pid = 0, spi_pid = 0; + #endif + /* Disable global menus */ g_unsetenv ("UBUNTU_MENUPROXY"); @@ -1977,6 +2060,10 @@ main (int argc, char **argv) /* init gtk */ gtk_init (&argc, &argv); + +#ifdef HAVE_LIBIDO + ido_init (); +#endif config = g_key_file_new (); g_key_file_load_from_file (config, CONFIG_FILE, G_KEY_FILE_NONE, &error); @@ -2135,7 +2222,7 @@ main (int argc, char **argv) language_menu = GTK_MENU(gtk_builder_get_object (builder, "language_menu")); clock_label = GTK_WIDGET(gtk_builder_get_object (builder, "clock_label")); menubar = GTK_WIDGET (gtk_builder_get_object (builder, "menubar")); - + keyboard_menuitem = GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "keyboard_menuitem")); /* Login window */ @@ -2144,22 +2231,22 @@ main (int argc, char **argv) user_combo = GTK_COMBO_BOX (gtk_builder_get_object (builder, "user_combobox")); username_entry = GTK_ENTRY (gtk_builder_get_object (builder, "username_entry")); password_entry = GTK_ENTRY (gtk_builder_get_object (builder, "password_entry")); - + /* Add InfoBar via code for GTK+2 compatability */ infobar_compat = GTK_WIDGET(gtk_builder_get_object(builder, "infobar_compat")); info_bar = GTK_INFO_BAR (gtk_info_bar_new()); gtk_info_bar_set_message_type(info_bar, GTK_MESSAGE_ERROR); gtk_widget_set_name(GTK_WIDGET(info_bar), "greeter_infobar"); content_area = gtk_info_bar_get_content_area(info_bar); - + message_label = GTK_LABEL (gtk_builder_get_object (builder, "message_label")); g_object_ref(message_label); gtk_container_remove(GTK_CONTAINER(infobar_compat), GTK_WIDGET(message_label)); gtk_container_add(GTK_CONTAINER(content_area), GTK_WIDGET(message_label)); g_object_unref(message_label); - + gtk_container_add(GTK_CONTAINER(infobar_compat), GTK_WIDGET(info_bar)); - + cancel_button = GTK_BUTTON (gtk_builder_get_object (builder, "cancel_button")); login_button = GTK_BUTTON (gtk_builder_get_object (builder, "login_button")); @@ -2168,7 +2255,7 @@ main (int argc, char **argv) #else g_signal_connect (G_OBJECT (login_window), "size-allocate", G_CALLBACK (login_window_size_allocate), NULL); #endif - + /* To maintain compatability with GTK+2, set special properties here */ #if GTK_CHECK_VERSION (3, 0, 0) gtk_box_set_child_packing(GTK_BOX(content_area), GTK_WIDGET(message_label), TRUE, TRUE, 0, GTK_PACK_START); @@ -2184,45 +2271,18 @@ main (int argc, char **argv) gtk_widget_set_tooltip_text(GTK_WIDGET(username_entry), _("Enter your username")); #endif - /* Glade can't handle custom menuitems, so set them up manually */ -#ifdef HAVE_LIBINDICATOR - /* whitelisted indicator modules to show */ - whitelist = g_key_file_get_string_list (config, "greeter", "show-indicators", &length, NULL); - menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "menubar")); - /* load indicators */ - if (g_file_test (INDICATOR_DIR, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) - { - const gchar *name; - dir = g_dir_open (INDICATOR_DIR, 0, NULL); - - while ((name = g_dir_read_name (dir))) - { - gboolean match = FALSE; - for (i = 0; i < length; ++i) - if ((match = (g_strcmp0 (name, whitelist[i]) == 0))) - break; - - if (G_LIKELY (!match)) - { - g_debug ("Ignoring module (not in whitelist): %s", name); - continue; - } - - if (load_module (name, menuitem)) - ++indicators_loaded; - } - - g_dir_close (dir); - } - - if (length > 0) - g_strfreev (whitelist); + /* Indicators */ + session_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "session_menuitem")); + language_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "language_menuitem")); + a11y_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "a11y_menuitem")); + power_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "power_menuitem")); - if (indicators_loaded > 0) - { - gtk_widget_set_can_focus (menuitem, TRUE); - gtk_widget_show (menuitem); - } +#ifdef HAVE_LIBINDICATOR +#ifdef START_INDICATOR_SERVICES + init_indicators (config, &indicator_pid, &spi_pid); +#else + init_indicators (config); +#endif #endif value = g_key_file_get_value (config, "greeter", "default-user-image", NULL); @@ -2250,7 +2310,6 @@ main (int argc, char **argv) clock_format = "%a, %H:%M"; /* Session menu */ - session_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "session_menuitem")); #if GTK_CHECK_VERSION (3, 0, 0) if (gtk_icon_theme_has_icon(icon_theme, "document-properties-symbolic")) session_badge = gtk_image_new_from_icon_name ("document-properties-symbolic", GTK_ICON_SIZE_MENU); @@ -2282,7 +2341,6 @@ main (int argc, char **argv) /* Language menu */ if (g_key_file_get_boolean (config, "greeter", "show-language-selector", NULL)) { - language_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "language_menuitem")); items = lightdm_get_languages (); GSList *languages = NULL; for (item = items; item; item = item->next) @@ -2323,7 +2381,6 @@ main (int argc, char **argv) } /* a11y menu */ - menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "a11y_menuitem")); #if GTK_CHECK_VERSION (3, 0, 0) if (gtk_icon_theme_has_icon(icon_theme, "preferences-desktop-accessibility-symbolic")) image = gtk_image_new_from_icon_name ("preferences-desktop-accessibility-symbolic", GTK_ICON_SIZE_MENU); @@ -2333,10 +2390,9 @@ main (int argc, char **argv) image = gtk_image_new_from_icon_name ("preferences-desktop-accessibility", GTK_ICON_SIZE_MENU); #endif gtk_widget_show (image); - gtk_container_add (GTK_CONTAINER (menuitem), image); + gtk_container_add (GTK_CONTAINER (a11y_menuitem), image); /* Power menu */ - power_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "power_menuitem")); #if GTK_CHECK_VERSION (3, 0, 0) if (gtk_icon_theme_has_icon(icon_theme, "system-shutdown-symbolic")) image = gtk_image_new_from_icon_name ("system-shutdown-symbolic", GTK_ICON_SIZE_MENU); @@ -2359,7 +2415,7 @@ main (int argc, char **argv) gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (user_combo), renderer, TRUE); gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (user_combo), renderer, "text", 1); gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (user_combo), renderer, "weight", 2); - + #if GDK_VERSION_CUR_STABLE < G_ENCODE_VERSION(3, 10) numScreens = gdk_display_get_n_screens (gdk_display_get_default()); #endif @@ -2430,7 +2486,7 @@ main (int argc, char **argv) g_free (value); } - + gtk_builder_connect_signals(builder, greeter); gtk_widget_show (GTK_WIDGET (login_window)); @@ -2446,7 +2502,7 @@ main (int argc, char **argv) gtk_widget_show (GTK_WIDGET (login_window)); gdk_window_focus (gtk_widget_get_window (GTK_WIDGET (login_window)), GDK_CURRENT_TIME); - + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (keyboard_menuitem), FALSE); if (a11y_keyboard_command) { @@ -2461,14 +2517,14 @@ main (int argc, char **argv) gtk_widget_set_size_request (GTK_WIDGET (onboard_window), 605, 205); gtk_window_move (onboard_window, (monitor_geometry.width - 605)/2, monitor_geometry.height - 205); } - + gtk_widget_show (GTK_WIDGET (keyboard_menuitem)); } else { gtk_widget_hide (GTK_WIDGET (keyboard_menuitem)); } - + gdk_threads_add_timeout( 100, (GSourceFunc) clock_timeout_thread, NULL ); /* focus fix (source: unity-greeter) */ @@ -2486,6 +2542,20 @@ main (int argc, char **argv) gdk_threads_leave(); #endif +#ifdef START_INDICATOR_SERVICES + if (indicator_pid) + { + kill (indicator_pid, SIGTERM); + waitpid (indicator_pid, NULL, 0); + } + + if (spi_pid) + { + kill (spi_pid, SIGTERM); + waitpid (spi_pid, NULL, 0); + } +#endif + if (background_pixbuf) g_object_unref (background_pixbuf); if (default_background_pixbuf) |