From 90036546b6218a92fbb5adda845ea538753de556 Mon Sep 17 00:00:00 2001 From: Jan Arne Petersen Date: Tue, 16 Feb 2010 00:09:36 +0100 Subject: [PATCH] Add basic app-indicator support. --- configure.ac | 28 +++++++ plugins/a11y-keyboard/Makefile.am | 2 + plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c | 60 ++++++++++++++++ plugins/keyboard/Makefile.am | 2 + plugins/keyboard/gsd-keyboard-xkb.c | 79 ++++++++++++++++++++- plugins/xrandr/Makefile.am | 2 + plugins/xrandr/gsd-xrandr-manager.c | 49 +++++++++++++ 7 files changed, 219 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 8eb4809..88d0343 100644 --- a/configure.ac +++ b/configure.ac @@ -51,6 +51,7 @@ GCONF_REQUIRED_VERSION=2.6.1 GIO_REQUIRED_VERSION=2.17.3 GNOME_DESKTOP_REQUIRED_VERSION=2.26.3 LIBNOTIFY_REQUIRED_VERSION=0.4.3 +APPINDICATOR_REQUIRED_VERSION=0.0.13 EXTRA_COMPILE_WARNINGS(yes) @@ -105,6 +106,32 @@ fi AC_SUBST(LIBNOTIFY_CFLAGS) AC_SUBST(LIBNOTIFY_LIBS) +dnl --------------------------------- +dnl - Application indicator +dnl --------------------------------- + +AC_ARG_ENABLE([appindicator], + AS_HELP_STRING([--enable-appindicator[=@<:@no/auto/yes@:>@]],[Build support for application indicators]), + [enable_appindicator=$enableval], + [enable_appindicator="auto"]) + + +if test x$enable_appindicator = xauto ; then + PKG_CHECK_EXISTS(appindicator-0.1 >= $APPINDICATOR_REQUIRED_VERSION, + [enable_appindicator="yes"], + [enable_appindicator="no"]) +fi + +if test x$enable_appindicator = xyes ; then + PKG_CHECK_MODULES(APPINDICATOR, + [appindicator-0.1 >= $APPINDICATOR_REQUIRED_VERSION], + [AC_DEFINE(HAVE_APPINDICATOR, 1, [Have AppIndicator])]) +fi + +AM_CONDITIONAL(HAVE_APPINDICATOR, test x$enable_appindicator = xyes) +AC_SUBST(APPINDICATOR_CFLAGS) +AC_SUBST(APPINDICATOR_LIBS) + dnl --------------------------------------------------------------------------- dnl - Check for D-Bus dnl --------------------------------------------------------------------------- @@ -399,6 +426,7 @@ echo " dbus-1 system.d dir: ${DBUS_SYS_DIR} Libnotify support: ${have_libnotify} + App indicatpr support: ${enable_appindicator} PulseAudio support: ${have_pulse} Profiling support: ${enable_profiling} " diff --git a/plugins/a11y-keyboard/Makefile.am b/plugins/a11y-keyboard/Makefile.am index 99bfa90..5770c1f 100644 --- a/plugins/a11y-keyboard/Makefile.am +++ b/plugins/a11y-keyboard/Makefile.am @@ -53,6 +53,7 @@ liba11y_keyboard_la_CPPFLAGS = \ liba11y_keyboard_la_CFLAGS = \ $(SETTINGS_PLUGIN_CFLAGS) \ $(LIBNOTIFY_CFLAGS) \ + $(APPINDICATOR_CFLAGS) \ $(AM_CFLAGS) liba11y_keyboard_la_LDFLAGS = \ @@ -63,6 +64,7 @@ liba11y_keyboard_la_LIBADD = \ $(SETTINGS_PLUGIN_LIBS) \ $(XF86MISC_LIBS) \ $(LIBNOTIFY_LIBS) \ + $(APPINDICATOR_LIBS) \ $(NULL) plugin_in_files = \ diff --git a/plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c b/plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c index ba19b42..e5da396 100644 --- a/plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c +++ b/plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c @@ -45,6 +45,10 @@ #include #endif /* HAVE_LIBNOTIFY */ +#ifdef HAVE_APPINDICATOR +#include +#endif + #include "gnome-settings-profile.h" #include "gsd-a11y-keyboard-manager.h" #include "gsd-a11y-preferences-dialog.h" @@ -62,7 +66,11 @@ struct GsdA11yKeyboardManagerPrivate GtkWidget *stickykeys_alert; GtkWidget *slowkeys_alert; GtkWidget *preferences_dialog; +#ifdef HAVE_APPINDICATOR + AppIndicator *app_indicator; +#else GtkStatusIcon *status_icon; +#endif XkbDescRec *original_xkb_desc; guint gconf_notify; @@ -435,11 +443,24 @@ maybe_show_status_icon (GsdA11yKeyboardManager *manager) show = gconf_client_get_bool (client, CONFIG_ROOT "/enable", NULL); g_object_unref (client); +#ifdef HAVE_APPINDICATOR + if (!show && manager->priv->app_indicator == NULL) + return; + + gsd_a11y_keyboard_manager_ensure_status_icon (manager); + if (show) + app_indicator_set_status (manager->priv->app_indicator, + APP_INDICATOR_STATUS_ACTIVE); + else + app_indicator_set_status (manager->priv->app_indicator, + APP_INDICATOR_STATUS_PASSIVE); +#else if (!show && manager->priv->status_icon == NULL) return; gsd_a11y_keyboard_manager_ensure_status_icon (manager); gtk_status_icon_set_visible (manager->priv->status_icon, show); +#endif } #ifdef HAVE_LIBNOTIFY @@ -521,9 +542,11 @@ ax_slowkeys_warning_post_bubble (GsdA11yKeyboardManager *manager, message = _("You just held down the Shift key for 8 seconds. This is the shortcut " "for the Slow Keys feature, which affects the way your keyboard works."); +#ifndef HAVE_APPINDICATOR if (manager->priv->status_icon == NULL || ! gtk_status_icon_is_embedded (manager->priv->status_icon)) { return FALSE; } +#endif if (manager->priv->slowkeys_alert != NULL) { gtk_widget_destroy (manager->priv->slowkeys_alert); @@ -538,7 +561,9 @@ ax_slowkeys_warning_post_bubble (GsdA11yKeyboardManager *manager, message, "preferences-desktop-accessibility", NULL); +#ifndef HAVE_APPINDICATOR notify_notification_attach_to_status_icon (manager->priv->notification, manager->priv->status_icon); +#endif notify_notification_set_timeout (manager->priv->notification, NOTIFICATION_TIMEOUT * 1000); notify_notification_add_action (manager->priv->notification, @@ -660,9 +685,11 @@ ax_stickykeys_warning_post_bubble (GsdA11yKeyboardManager *manager, _("You just pressed two keys at once, or pressed the Shift key 5 times in a row. " "This turns off the Sticky Keys feature, which affects the way your keyboard works."); +#ifndef HAVE_APPINDICATOR if (manager->priv->status_icon == NULL || ! gtk_status_icon_is_embedded (manager->priv->status_icon)) { return FALSE; } +#endif if (manager->priv->slowkeys_alert != NULL) { gtk_widget_destroy (manager->priv->slowkeys_alert); @@ -677,7 +704,9 @@ ax_stickykeys_warning_post_bubble (GsdA11yKeyboardManager *manager, message, "preferences-desktop-accessibility", NULL); +#ifndef HAVE_APPINDICATOR notify_notification_attach_to_status_icon (manager->priv->notification, manager->priv->status_icon); +#endif notify_notification_set_timeout (manager->priv->notification, NOTIFICATION_TIMEOUT * 1000); notify_notification_add_action (manager->priv->notification, @@ -1072,8 +1101,14 @@ gsd_a11y_keyboard_manager_stop (GsdA11yKeyboardManager *manager) g_debug ("Stopping a11y_keyboard manager"); +#ifdef HAVE_APPINDICATOR + if (p->app_indicator) + app_indicator_set_status (p->app_indicator, + APP_INDICATOR_STATUS_PASSIVE); +#else if (p->status_icon) gtk_status_icon_set_visible (p->status_icon, FALSE); +#endif if (p->gconf_notify != 0) { GConfClient *client = gconf_client_get_default (); @@ -1190,8 +1225,13 @@ on_preferences_dialog_response (GtkDialog *dialog, } static void +#ifdef HAVE_APPINDICATOR +on_status_icon_activate (GtkMenuItem *item, + GsdA11yKeyboardManager *manager) +#else on_status_icon_activate (GtkStatusIcon *status_icon, GsdA11yKeyboardManager *manager) +#endif { if (manager->priv->preferences_dialog == NULL) { manager->priv->preferences_dialog = gsd_a11y_preferences_dialog_new (); @@ -1215,6 +1255,25 @@ gsd_a11y_keyboard_manager_ensure_status_icon (GsdA11yKeyboardManager *manager) { gnome_settings_profile_start (NULL); +#ifdef HAVE_APPINDICATOR + if (!manager->priv->app_indicator) { + GtkWidget *menu = gtk_menu_new (); + GtkWidget *item = gtk_menu_item_new_with_label (_("Universal Access Preferences")); + + g_signal_connect (item, + "activate", + G_CALLBACK (on_status_icon_activate), + manager); + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + + manager->priv->app_indicator = app_indicator_new ("gsd-a11y-keyboard", + "preferences-desktop-accessibility", + APP_INDICATOR_CATEGORY_OTHER); + app_indicator_set_menu (manager->priv->app_indicator, + GTK_MENU (menu)); + } +#else if (!manager->priv->status_icon) { manager->priv->status_icon = gtk_status_icon_new_from_icon_name ("preferences-desktop-accessibility"); @@ -1223,6 +1282,7 @@ gsd_a11y_keyboard_manager_ensure_status_icon (GsdA11yKeyboardManager *manager) G_CALLBACK (on_status_icon_activate), manager); } +#endif gnome_settings_profile_end (NULL); } diff --git a/plugins/keyboard/Makefile.am b/plugins/keyboard/Makefile.am index 1b7bc3e..a42ce45 100644 --- a/plugins/keyboard/Makefile.am +++ b/plugins/keyboard/Makefile.am @@ -29,6 +29,7 @@ libkeyboard_la_CPPFLAGS = \ libkeyboard_la_CFLAGS = \ $(SETTINGS_PLUGIN_CFLAGS) \ $(LIBGNOMEKBDUI_CFLAGS) \ + $(APPINDICATOR_CFLAGS) \ $(AM_CFLAGS) libkeyboard_la_LDFLAGS = \ @@ -39,6 +40,7 @@ libkeyboard_la_LIBADD = \ $(SETTINGS_PLUGIN_LIBS) \ $(XF86MISC_LIBS) \ $(LIBGNOMEKBDUI_LIBS) \ + $(APPINDICATOR_LIBS) \ $(NULL) plugin_in_files = \ diff --git a/plugins/keyboard/gsd-keyboard-xkb.c b/plugins/keyboard/gsd-keyboard-xkb.c index ff31149..8280287 100644 --- a/plugins/keyboard/gsd-keyboard-xkb.c +++ b/plugins/keyboard/gsd-keyboard-xkb.c @@ -31,12 +31,19 @@ #include #include +#ifndef HAVE_APPINDICATOR #include +#endif #include #include #include #include +#ifdef HAVE_APPINDICATOR +#include +#include +#endif + #include "gsd-xmodmap.h" #include "gsd-keyboard-xkb.h" #include "delayed-dialog.h" @@ -66,7 +73,12 @@ static const char KNOWN_FILES_KEY[] = static const char *gdm_keyboard_layout = NULL; +#ifdef HAVE_APPINDICATOR +static AppIndicator *app_indicator = NULL; +static GkbdConfiguration *gkbd_configuration = NULL; +#else static GtkStatusIcon *icon = NULL; +#endif static GHashTable *preview_dialogs = NULL; @@ -233,7 +245,11 @@ popup_menu_show_layout () XklEngine *engine = xkl_engine_get_instance (GDK_DISPLAY ()); XklState *xkl_state = xkl_engine_get_current_state (engine); +#ifdef HAVE_APPINDICATOR + gchar **group_names = gkbd_configuration_get_group_names (gkbd_configuration); +#else gchar **group_names = gkbd_status_get_group_names (); +#endif gpointer p = g_hash_table_lookup (preview_dialogs, GINT_TO_POINTER (xkl_state->group)); @@ -355,7 +371,11 @@ static void popup_menu_set_group (GtkMenuItem * item, gpointer param) { gint group_number = GPOINTER_TO_INT (param); +#ifdef HAVE_APPINDICATOR + XklEngine *engine = gkbd_configuration_get_xkl_engine (gkbd_configuration); +#else XklEngine *engine = gkbd_status_get_xkl_engine (); +#endif XklState st; Window cur; @@ -378,13 +398,17 @@ popup_menu_set_group (GtkMenuItem * item, gpointer param) xkl_engine_lock_group (engine, st.group); } -static void -status_icon_popup_menu_cb (GtkStatusIcon * icon, guint button, guint time) +static GtkMenu * +create_status_menu (void) { GtkMenu *popup_menu = GTK_MENU (gtk_menu_new ()); GtkMenu *groups_menu = GTK_MENU (gtk_menu_new ()); int i = 0; +#ifdef HAVE_APPINDICATOR + gchar **current_name = gkbd_configuration_get_group_names (gkbd_configuration); +#else gchar **current_name = gkbd_status_get_group_names (); +#endif GtkWidget *item = gtk_menu_item_new_with_mnemonic (_("_Groups")); gtk_widget_show (item); @@ -404,19 +428,28 @@ status_icon_popup_menu_cb (GtkStatusIcon * icon, guint button, guint time) g_signal_connect (item, "activate", popup_menu_show_layout, NULL); gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item); - for (i = 0; *current_name; i++, current_name++) { + for (i = 0; current_name && *current_name; i++, current_name++) { +#ifdef HAVE_APPINDICATOR + gchar *image_file = gkbd_configuration_get_image_filename (gkbd_configuration, i); +#else gchar *image_file = gkbd_status_get_image_filename (i); +#endif if (image_file == NULL) { item = gtk_menu_item_new_with_label (*current_name); } else { +#ifdef HAVE_APPINDICATOR + GtkWidget *img = gtk_image_new_from_icon_name (image_file, + GTK_ICON_SIZE_MENU); +#else GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file_at_size (image_file, 24, 24, NULL); GtkWidget *img = gtk_image_new_from_pixbuf (pixbuf); +#endif item = gtk_image_menu_item_new_with_label (*current_name); @@ -425,7 +458,9 @@ status_icon_popup_menu_cb (GtkStatusIcon * icon, guint button, guint time) (item), img); gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (item), TRUE); +#ifndef HAVE_APPINDICATOR g_free (image_file); +#endif } gtk_widget_show (item); gtk_menu_shell_append (GTK_MENU_SHELL (groups_menu), item); @@ -434,15 +469,41 @@ status_icon_popup_menu_cb (GtkStatusIcon * icon, guint button, guint time) GINT_TO_POINTER (i)); } + return popup_menu; +} + +#ifndef HAVE_APPINDICATOR +static void +status_icon_popup_menu_cb (GtkStatusIcon * icon, guint button, guint time) +{ + GtkMenu *popup_menu = create_status_menu (); + gtk_menu_popup (popup_menu, NULL, NULL, gtk_status_icon_position_menu, (gpointer) icon, button, time); } +#endif static void show_hide_icon () { if (g_slist_length (current_kbd_config.layouts_variants) > 1) { +#ifdef HAVE_APPINDICATOR + if (gkbd_configuration == NULL) { + gkbd_configuration = gkbd_configuration_get (); + } + if (app_indicator == NULL) { + GtkMenu *popup_menu = create_status_menu (); + + app_indicator = app_indicator_new ("gst-keyboard-xkb", + "keyboard", + APP_INDICATOR_CATEGORY_HARDWARE); + app_indicator_set_status (app_indicator, + APP_INDICATOR_STATUS_ACTIVE); + app_indicator_set_menu (app_indicator, + popup_menu); + } +#else if (icon == NULL) { xkl_debug (150, "Creating new icon\n"); icon = gkbd_status_new (); @@ -452,12 +513,24 @@ show_hide_icon () NULL); } +#endif } else { +#ifdef HAVE_APPINDICATOR + if (gkbd_configuration != NULL) { + g_object_unref (gkbd_configuration); + gkbd_configuration = NULL; + } + if (app_indicator != NULL) { + g_object_unref (app_indicator); + app_indicator = NULL; + } +#else if (icon != NULL) { xkl_debug (150, "Destroying icon\n"); g_object_unref (icon); icon = NULL; } +#endif } } diff --git a/plugins/xrandr/Makefile.am b/plugins/xrandr/Makefile.am index d84eca1..124bf26 100644 --- a/plugins/xrandr/Makefile.am +++ b/plugins/xrandr/Makefile.am @@ -54,6 +54,7 @@ libxrandr_la_CPPFLAGS = \ libxrandr_la_CFLAGS = \ $(SETTINGS_PLUGIN_CFLAGS) \ $(LIBNOTIFY_CFLAGS) \ + $(APPINDICATOR_CFLAGS) \ $(AM_CFLAGS) libxrandr_la_LDFLAGS = \ @@ -62,6 +63,7 @@ libxrandr_la_LDFLAGS = \ libxrandr_la_LIBADD = \ $(SETTINGS_PLUGIN_LIBS) \ $(LIBNOTIFY_LIBS) \ + $(APPINDICATOR_LIBS) \ $(RANDR_LIBS) plugin_in_files = \ diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c index 08a75d5..0eaedc9 100644 --- a/plugins/xrandr/gsd-xrandr-manager.c +++ b/plugins/xrandr/gsd-xrandr-manager.c @@ -53,6 +53,10 @@ #include #endif +#ifdef HAVE_APPINDICATOR +#include +#endif + #include "gnome-settings-profile.h" #include "gsd-xrandr-manager.h" @@ -97,7 +101,11 @@ struct GsdXrandrManagerPrivate GnomeRRScreen *rw_screen; gboolean running; +#ifdef HAVE_APPINDICATOR + AppIndicator *app_indicator; +#else GtkStatusIcon *status_icon; +#endif GtkWidget *popup_menu; GnomeRRConfig *configuration; GnomeRRLabeler *labeler; @@ -919,17 +927,21 @@ static void error_message (GsdXrandrManager *mgr, const char *primary_text, GError *error_to_display, const char *secondary_text) { #ifdef HAVE_LIBNOTIFY +#ifndef HAVE_APPINDICATOR GsdXrandrManagerPrivate *priv = mgr->priv; +#endif NotifyNotification *notification; g_assert (error_to_display == NULL || secondary_text == NULL); +#ifndef HAVE_APPINDICATOR if (priv->status_icon) notification = notify_notification_new_with_status_icon (primary_text, error_to_display ? error_to_display->message : secondary_text, GSD_XRANDR_ICON_NAME, priv->status_icon); else +#endif notification = notify_notification_new (primary_text, error_to_display ? error_to_display->message : secondary_text, GSD_XRANDR_ICON_NAME, @@ -1161,6 +1173,11 @@ refresh_tray_icon_menu_if_active (GsdXrandrManager *manager, guint32 timestamp) gtk_menu_shell_cancel (GTK_MENU_SHELL (priv->popup_menu)); /* status_icon_popup_menu_selection_done_cb() will free everything */ status_icon_popup_menu (manager, 0, timestamp); } +#if 0 + else { + status_icon_popup_menu (manager, 0, GDK_CURRENT_TIME); + } +#endif } static void @@ -1867,11 +1884,16 @@ status_icon_popup_menu (GsdXrandrManager *manager, guint button, guint32 timesta struct GsdXrandrManagerPrivate *priv = manager->priv; GtkWidget *item; +#ifdef HAVE_APPINDICATOR + if (!priv->configuration) + priv->configuration = gnome_rr_config_new_current (priv->rw_screen); +#else g_assert (priv->configuration == NULL); priv->configuration = gnome_rr_config_new_current (priv->rw_screen); g_assert (priv->labeler == NULL); priv->labeler = gnome_rr_labeler_new (priv->configuration); +#endif g_assert (priv->popup_menu == NULL); priv->popup_menu = gtk_menu_new (); @@ -1888,14 +1910,20 @@ status_icon_popup_menu (GsdXrandrManager *manager, guint button, guint32 timesta gtk_widget_show (item); gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), item); +#ifdef HAVE_APPINDICATOR + app_indicator_set_menu (priv->app_indicator, + GTK_MENU (priv->popup_menu)); +#else g_signal_connect (priv->popup_menu, "selection-done", G_CALLBACK (status_icon_popup_menu_selection_done_cb), manager); gtk_menu_popup (GTK_MENU (priv->popup_menu), NULL, NULL, gtk_status_icon_position_menu, priv->status_icon, button, timestamp); +#endif } +#ifndef HAVE_APPINDICATOR static void status_icon_activate_cb (GtkStatusIcon *status_icon, gpointer data) { @@ -1912,12 +1940,23 @@ status_icon_popup_menu_cb (GtkStatusIcon *status_icon, guint button, guint32 tim status_icon_popup_menu (manager, button, timestamp); } +#endif static void status_icon_start (GsdXrandrManager *manager) { struct GsdXrandrManagerPrivate *priv = manager->priv; +#ifdef HAVE_APPINDICATOR + if (!priv->app_indicator) { + priv->app_indicator = app_indicator_new ("gsd-xrandr", + GSD_XRANDR_ICON_NAME, + APP_INDICATOR_CATEGORY_HARDWARE); + app_indicator_set_status (priv->app_indicator, + APP_INDICATOR_STATUS_ACTIVE); + status_icon_popup_menu (manager, 0, 0); + } +#else /* Ideally, we should detect if we are on a tablet and only display * the icon in that case. */ @@ -1930,6 +1969,7 @@ status_icon_start (GsdXrandrManager *manager) g_signal_connect (priv->status_icon, "popup-menu", G_CALLBACK (status_icon_popup_menu_cb), manager); } +#endif } static void @@ -1937,6 +1977,14 @@ status_icon_stop (GsdXrandrManager *manager) { struct GsdXrandrManagerPrivate *priv = manager->priv; +#ifdef HAVE_APPINDICATOR + if (priv->app_indicator) { + app_indicator_set_status (priv->app_indicator, + APP_INDICATOR_STATUS_PASSIVE); + g_object_unref (priv->app_indicator); + priv->app_indicator = NULL; + } +#else if (priv->status_icon) { g_signal_handlers_disconnect_by_func ( priv->status_icon, G_CALLBACK (status_icon_activate_cb), manager); @@ -1949,6 +1997,7 @@ status_icon_stop (GsdXrandrManager *manager) g_object_unref (priv->status_icon); priv->status_icon = NULL; } +#endif } static void -- 1.6.6.1