[network-manager-applet/pavlix/appindicator-bgo740574: 2/7] indicator: add support for --enable-indicator



commit fbce2eb19d0ad45f3ed8d191ac9458bf7a952449
Author: Pavel Šimerda <psimerda redhat com>
Date:   Sun Nov 23 13:30:46 2014 +0100

    indicator: add support for --enable-indicator
    
    Add new configure option --enable-indicator which implies a optional
    dependency on libappindicator. This is the way systray is done in the
    current versions of Unity, KDE and Enlightenment and others. Some of the
    systray implementations already dropped support for Xembed, others are
    going to, mostly to gain independence on X11 as part of being ported to
    Wayland.
    
    Keep the previous functionality intact.

 configure.ac                  |    8 +
 src/Makefile.am               |    2 +
 src/applet.c                  |  308 ++++++++++++++++++++++++++++++++++++++---
 src/applet.h                  |   10 ++
 src/gconf-helpers/Makefile.am |    2 +
 src/mobile-helpers.c          |  115 +++++++++++++++
 src/mobile-helpers.h          |    5 +
 7 files changed, 431 insertions(+), 19 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index f6ce1d5..3a4ca79 100644
--- a/configure.ac
+++ b/configure.ac
@@ -145,6 +145,14 @@ case "${with_bluetooth}" in
                ;;
 esac
 
+AC_ARG_ENABLE([indicator],
+[  --enable-indicator  Enables using libappindicator to draw the applet
+                          on the screen, instead of the standard status icons.])
+if test "$enable_indicator" == "yes"; then
+       PKG_CHECK_MODULES(APPINDICATOR, appindicator3-0.1)
+       AC_DEFINE([ENABLE_INDICATOR], 1, [Enable using libappindicator])
+fi
+
 AM_CONDITIONAL(HAVE_GBT, test x"$have_gbt" = "xyes")
 
 dnl ModemManager1 with libmm-glib
diff --git a/src/Makefile.am b/src/Makefile.am
index 0e85dd5..a587267 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -7,6 +7,7 @@ nm_applet_CPPFLAGS = \
        $(NMA_CFLAGS) \
        $(LIBSECRET_CFLAGS) \
        $(NOTIFY_CFLAGS) \
+       $(APPINDICATOR_CFLAGS) \
        -DNM_VERSION_MAX_ALLOWED=NM_VERSION_0_9_10 \
        -DICONDIR=\""$(datadir)/icons"\"                                                \
        -DUIDIR=\""$(uidir)"\"                                                  \
@@ -77,6 +78,7 @@ nm_applet_LDADD = \
        $(NMA_LIBS) \
        $(LIBSECRET_LIBS) \
        $(NOTIFY_LIBS) \
+       $(APPINDICATOR_LIBS) \
        ${top_builddir}/src/marshallers/libmarshallers.la \
        ${top_builddir}/src/utils/libutils.la \
        ${top_builddir}/src/wireless-security/libwireless-security.la \
diff --git a/src/applet.c b/src/applet.c
index 9b7eb5e..12d3e46 100644
--- a/src/applet.c
+++ b/src/applet.c
@@ -562,6 +562,8 @@ applet_item_activate_info_destroy (AppletItemActivateInfo *info)
        g_free (info);
 }
 
+void applet_schedule_update_menu (NMApplet *applet);
+
 static void
 add_and_activate_cb (NMClient *client,
                      NMActiveConnection *active,
@@ -569,6 +571,8 @@ add_and_activate_cb (NMClient *client,
                      GError *error,
                      gpointer user_data)
 {
+       NMApplet *applet = NM_APPLET (user_data);
+
        if (error) {
                const char *text = _("Failed to add/activate connection");
                char *err_text = g_strdup_printf ("(%d) %s", error->code,
@@ -579,7 +583,8 @@ add_and_activate_cb (NMClient *client,
                g_free (err_text);
        }
 
-       applet_schedule_update_icon (NM_APPLET (user_data));
+       applet_schedule_update_icon (applet);
+       applet_schedule_update_menu (applet);
 }
 
 static void
@@ -613,6 +618,8 @@ applet_menu_item_activate_helper_new_connection (NMConnection *connection,
 static void
 disconnect_cb (NMDevice *device, GError *error, gpointer user_data)
 {
+       NMApplet *applet = NM_APPLET (user_data);
+
        if (error) {
                const char *text = _("Device disconnect failed");
                char *err_text = g_strdup_printf ("(%d) %s", error->code,
@@ -622,6 +629,9 @@ disconnect_cb (NMDevice *device, GError *error, gpointer user_data)
                utils_show_error_dialog (_("Disconnect failure"), text, err_text, FALSE, NULL);
                g_free (err_text);
        }
+
+       applet_schedule_update_icon (applet);
+       applet_schedule_update_menu (applet);
 }
 
 void
@@ -630,7 +640,7 @@ applet_menu_item_disconnect_helper (NMDevice *device,
 {
        g_return_if_fail (NM_IS_DEVICE (device));
 
-       nm_device_disconnect (device, disconnect_cb, NULL);
+       nm_device_disconnect (device, disconnect_cb, applet);
 }
 
 static void
@@ -700,6 +710,9 @@ applet_menu_item_add_complex_separator_helper (GtkWidget *menu,
                                                NMApplet *applet,
                                                const gchar* label)
 {
+#ifdef ENABLE_INDICATOR
+       gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new ());
+#else
        GtkWidget *menu_item = gtk_image_menu_item_new ();
        GtkWidget *box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
        GtkWidget *xlabel = NULL;
@@ -719,6 +732,7 @@ applet_menu_item_add_complex_separator_helper (GtkWidget *menu,
                      "sensitive", FALSE,
                      NULL);
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
+#endif
 }
 
 GtkWidget *
@@ -726,13 +740,15 @@ applet_new_menu_item_helper (NMConnection *connection,
                              NMConnection *active,
                              gboolean add_active)
 {
-       GtkWidget *item;
-       NMSettingConnection *s_con;
+       NMSettingConnection *s_con = nm_connection_get_setting_connection (connection);
+#ifdef ENABLE_INDICATOR
+
+       return gtk_menu_item_new_with_label (nm_setting_connection_get_id (s_con));
+#else
+       GtkWidget *item = gtk_image_menu_item_new_with_label ("");
        char *markup;
        GtkWidget *label;
 
-       s_con = nm_connection_get_setting_connection (connection);
-       item = gtk_image_menu_item_new_with_label ("");
        if (add_active && (active == connection)) {
                /* Pure evil */
                label = gtk_bin_get_child (GTK_BIN (item));
@@ -745,8 +761,10 @@ applet_new_menu_item_helper (NMConnection *connection,
 
        gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (item), TRUE);
        return item;
+#endif
 }
 
+#ifndef ENABLE_INDICATOR
 #define TITLE_TEXT_R ((double) 0x5e / 255.0 )
 #define TITLE_TEXT_G ((double) 0x5e / 255.0 )
 #define TITLE_TEXT_B ((double) 0x5e / 255.0 )
@@ -810,6 +828,7 @@ menu_title_item_draw (GtkWidget *widget, cairo_t *cr, gpointer user_data)
        menu_item_draw_generic (widget, cr);
        return TRUE;
 }
+#endif
 
 GtkWidget *
 applet_menu_item_create_device_item_helper (NMDevice *device,
@@ -819,8 +838,10 @@ applet_menu_item_create_device_item_helper (NMDevice *device,
        GtkWidget *item;
 
        item = gtk_menu_item_new_with_label (text);
+#ifndef ENABLE_INDICATOR
        gtk_widget_set_sensitive (item, FALSE);
        g_signal_connect (item, "draw", G_CALLBACK (menu_title_item_draw), NULL);
+#endif
        return item;
 }
 
@@ -878,6 +899,9 @@ applet_do_notify (NMApplet *applet,
        g_return_if_fail (summary != NULL);
        g_return_if_fail (message != NULL);
 
+#ifdef ENABLE_INDICATOR
+       if (app_indicator_get_status (applet->app_indicator) == APP_INDICATOR_STATUS_PASSIVE)
+#endif
        if (!gtk_status_icon_is_embedded (applet->status_icon))
                return;
 
@@ -1157,6 +1181,7 @@ vpn_connection_state_changed (NMVPNConnection *vpn,
                clear_animation_timeout (applet);
 
        applet_schedule_update_icon (applet);
+       applet_schedule_update_menu (applet);
 }
 
 static const char *
@@ -1212,10 +1237,13 @@ activate_vpn_cb (NMClient *client,
        }
 
        applet_schedule_update_icon (info->applet);
+       applet_schedule_update_menu (info->applet);
        g_free (info->vpn_name);
        g_free (info);
 }
 
+static void nma_menu_disconnect_vpn_item_activate (GtkMenuItem *item, gpointer user_data);
+
 static void
 nma_menu_vpn_item_clicked (GtkMenuItem *item, gpointer user_data)
 {
@@ -1238,9 +1266,14 @@ nma_menu_vpn_item_clicked (GtkMenuItem *item, gpointer user_data)
                return;
        }
 
-       if (applet_get_active_for_connection (applet, connection))
+       if (applet_get_active_for_connection (applet, connection)) {
+#ifdef ENABLE_INDICATOR
+               nma_menu_disconnect_vpn_item_activate (item, applet);
+#else
                /* Connection already active; do nothing */
                return;
+#endif
+       }
 
        s_con = nm_connection_get_setting_connection (connection);
        info = g_malloc0 (sizeof (VPNActivateInfo));
@@ -1799,13 +1832,16 @@ nma_menu_add_vpn_submenu (GtkWidget *menu, NMApplet *applet)
                NMConnection *connection = NM_CONNECTION (iter->data);
                NMActiveConnection *active;
                const char *name;
-               GtkWidget *image;
                NMState state;
 
                name = get_connection_id (connection);
 
                item = GTK_MENU_ITEM (gtk_image_menu_item_new_with_label (name));
+#ifdef ENABLE_INDICATOR
+               gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(item), FALSE);
+#else
                gtk_image_menu_item_set_always_show_image(GTK_IMAGE_MENU_ITEM(item), TRUE);
+#endif
 
                /* If no VPN connections are active, draw all menu items enabled. If
                 * >= 1 VPN connections are active, only the active VPN menu item is
@@ -1824,8 +1860,13 @@ nma_menu_add_vpn_submenu (GtkWidget *menu, NMApplet *applet)
                        gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE);
 
                if (active) {
-                       image = gtk_image_new_from_stock (GTK_STOCK_CONNECT, GTK_ICON_SIZE_MENU);
+#ifdef ENABLE_INDICATOR
+                       gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(item), TRUE);
+#else
+                       GtkWidget *image = gtk_image_new_from_stock (GTK_STOCK_CONNECT, GTK_ICON_SIZE_MENU);
+
                        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
+#endif
                }
 
                g_object_set_data_full (G_OBJECT (item), "connection", 
@@ -1899,6 +1940,7 @@ nma_set_networking_enabled_cb (GtkWidget *widget, NMApplet *applet)
 }
 
 
+#ifndef ENABLE_INDICATOR
 static void
 nma_set_notifications_enabled_cb (GtkWidget *widget, NMApplet *applet)
 {
@@ -1921,6 +1963,7 @@ nma_set_notifications_enabled_cb (GtkWidget *widget, NMApplet *applet)
                                PREF_SUPPRESS_WIFI_NETWORKS_AVAILABLE,
                                !state);
 }
+#endif /* ENABLE_INDICATOR */
 
 static gboolean
 has_usable_wifi (NMApplet *applet)
@@ -2030,7 +2073,9 @@ nma_context_menu_update (NMApplet *applet)
        gboolean wifi_hw_enabled;
        gboolean wwan_hw_enabled;
        gboolean wimax_hw_enabled;
+#ifndef ENABLE_INDICATOR
        gboolean notifications_enabled = TRUE;
+#endif
        gboolean sensitive = FALSE;
 
        state = nm_client_get_state (applet->nm_client);
@@ -2090,6 +2135,7 @@ nma_context_menu_update (NMApplet *applet)
        gtk_widget_set_sensitive (GTK_WIDGET (applet->wimax_enabled_item),
                                  wimax_hw_enabled && is_permission_yes (applet, 
NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX));
 
+#ifndef ENABLE_INDICATOR
        /* Enabled notifications */
        g_signal_handler_block (G_OBJECT (applet->notifications_enabled_item),
                                applet->notifications_enabled_toggled_id);
@@ -2101,6 +2147,7 @@ nma_context_menu_update (NMApplet *applet)
        gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (applet->notifications_enabled_item), 
notifications_enabled);
        g_signal_handler_unblock (G_OBJECT (applet->notifications_enabled_item),
                                  applet->notifications_enabled_toggled_id);
+#endif
 
        /* Don't show wifi-specific stuff if wifi is off */
        if (state != NM_STATE_ASLEEP) {
@@ -2183,6 +2230,7 @@ static GtkWidget *nma_context_menu_create (NMApplet *applet)
        g_return_val_if_fail (applet != NULL, NULL);
 
        menu = GTK_MENU_SHELL (gtk_menu_new ());
+       g_object_ref_sink (menu);
 
        /* 'Enable Networking' item */
        applet->networking_enabled_item = gtk_check_menu_item_new_with_mnemonic (_("Enable _Networking"));
@@ -2222,6 +2270,7 @@ static GtkWidget *nma_context_menu_create (NMApplet *applet)
 
        nma_menu_add_separator_item (GTK_WIDGET (menu));
 
+#ifndef ENABLE_INDICATOR
        /* Toggle notifications item */
        applet->notifications_enabled_item = gtk_check_menu_item_new_with_mnemonic (_("Enable 
N_otifications"));
        id = g_signal_connect (applet->notifications_enabled_item,
@@ -2232,6 +2281,7 @@ static GtkWidget *nma_context_menu_create (NMApplet *applet)
        gtk_menu_shell_append (menu, applet->notifications_enabled_item);
 
        nma_menu_add_separator_item (GTK_WIDGET (menu));
+#endif
 
        /* 'Connection Information' item */
        applet->info_menu_item = gtk_image_menu_item_new_with_mnemonic (_("Connection _Information"));
@@ -2272,6 +2322,7 @@ static GtkWidget *nma_context_menu_create (NMApplet *applet)
        image = gtk_image_new_from_stock (GTK_STOCK_ABOUT, GTK_ICON_SIZE_MENU);
        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), image);
        gtk_menu_shell_append (menu, menu_item);
+       gtk_widget_set_sensitive (menu_item, FALSE);
 
        gtk_widget_show_all (GTK_WIDGET (menu));
 
@@ -2374,6 +2425,53 @@ applet_add_default_connection_item (NMDevice *device,
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
 }
 
+#ifdef ENABLE_INDICATOR
+static void
+indicator_update_menu (NMApplet *applet)
+{
+       if (!applet->in_fallback) {
+               if (applet->menu)
+                       g_object_unref (applet->menu);
+               applet->menu = nma_context_menu_create (applet);
+
+               nma_menu_show_cb (applet->menu, applet);
+               nma_menu_add_separator_item (applet->menu);
+
+               app_indicator_set_menu (applet->app_indicator, GTK_MENU (applet->menu));
+
+               nma_context_menu_update (applet);
+       }
+
+       applet->update_menu_id = 0;
+}
+
+static gboolean
+applet_update_indicator_menu (gpointer user_data)
+{
+       NMApplet *applet = NM_APPLET (user_data);
+
+       indicator_update_menu (applet);
+
+       return FALSE;
+}
+
+static void
+new_connection_cb (NMRemoteSettings *settings, NMRemoteConnection *connection, gpointer user_data)
+{
+       NMApplet *applet = NM_APPLET (user_data);
+
+       applet_schedule_update_menu (applet);
+}
+#endif /* ENABLE_INDICATOR */
+
+void
+applet_schedule_update_menu (NMApplet *applet)
+{
+#ifdef ENABLE_INDICATOR
+       if (!applet->update_menu_id)
+               applet->update_menu_id = g_idle_add (applet_update_indicator_menu, applet);
+#endif
+}
 
 /*****************************************************************************/
 
@@ -2384,6 +2482,17 @@ foo_set_icon (NMApplet *applet, guint32 layer, GdkPixbuf *pixbuf, char *icon_nam
 
        g_return_if_fail (layer == ICON_LAYER_LINK || layer == ICON_LAYER_VPN);
 
+#ifdef ENABLE_INDICATOR
+       if (icon_name == NULL && layer == ICON_LAYER_LINK) {
+               icon_name = g_strdup ("nm-no-connection");
+       }
+
+       if (icon_name != NULL &&
+           g_strcmp0 (app_indicator_get_icon (applet->app_indicator), icon_name) != 0) {
+               app_indicator_set_icon_full (applet->app_indicator, icon_name, applet->tip);
+       }
+#endif
+
        /* Ignore setting of the same icon as is already displayed */
        if (applet->icon_layers[layer] == pixbuf)
                return;
@@ -2523,6 +2632,9 @@ foo_device_state_changed_cb (NMDevice *device,
        }
 
        applet_schedule_update_icon (applet);
+#ifdef ENABLE_INDICATOR
+       applet_schedule_update_menu (applet);
+#endif
 }
 
 static void
@@ -2566,7 +2678,23 @@ foo_client_state_changed_cb (NMClient *client, GParamSpec *pspec, gpointer user_
        }
 
        applet_schedule_update_icon (applet);
+#ifdef ENABLE_INDICATOR
+       applet_schedule_update_menu (applet);
+#endif
+}
+
+#ifdef ENABLE_INDICATOR
+static void
+foo_device_removed_cb (NMClient *client, NMDevice *device, gpointer user_data)
+{
+       NMApplet *applet = NM_APPLET (user_data);
+
+       applet_schedule_update_icon (applet);
+#ifdef ENABLE_INDICATOR
+       applet_schedule_update_menu (applet);
+#endif
 }
+#endif
 
 static void
 foo_manager_running_cb (NMClient *client,
@@ -2583,6 +2711,9 @@ foo_manager_running_cb (NMClient *client,
        }
 
        applet_schedule_update_icon (applet);
+#ifdef ENABLE_INDICATOR
+       applet_schedule_update_menu (applet);
+#endif
 }
 
 #define VPN_STATE_ID_TAG "vpn-state-id"
@@ -2612,6 +2743,9 @@ foo_active_connections_changed_cb (NMClient *client,
        }
 
        applet_schedule_update_icon (applet);
+#ifdef ENABLE_INDICATOR
+       applet_schedule_update_menu (applet);
+#endif
 }
 
 static void
@@ -2644,6 +2778,9 @@ foo_set_initial_state (gpointer data)
        return FALSE;
 }
 
+static gboolean setup_widgets (NMApplet *applet);
+static void nma_icons_init (NMApplet *applet);
+
 static void
 foo_client_setup (NMApplet *applet)
 {
@@ -2662,6 +2799,11 @@ foo_client_setup (NMApplet *applet)
        g_signal_connect (applet->nm_client, "device-added",
                          G_CALLBACK (foo_device_added_cb),
                          applet);
+#ifdef ENABLE_INDICATOR
+       g_signal_connect (applet->nm_client, "device-removed",
+                         G_CALLBACK (foo_device_removed_cb),
+                         applet);
+#endif
        g_signal_connect (applet->nm_client, "notify::manager-running",
                          G_CALLBACK (foo_manager_running_cb),
                          applet);
@@ -2934,7 +3076,19 @@ applet_update_icon (gpointer user_data)
        if (!nm_running)
                state = NM_STATE_UNKNOWN;
 
+#ifdef ENABLE_INDICATOR
+       if (applet->in_fallback)
+               gtk_status_icon_set_visible (applet->status_icon, applet->visible);
+       else
+               gtk_status_icon_set_visible (applet->status_icon, FALSE);
+
+       if (nm_running)
+               app_indicator_set_status (applet->app_indicator, APP_INDICATOR_STATUS_ACTIVE);
+       else
+               app_indicator_set_status (applet->app_indicator, APP_INDICATOR_STATUS_PASSIVE);
+#else
        gtk_status_icon_set_visible (applet->status_icon, applet->visible);
+#endif
 
        switch (state) {
        case NM_STATE_UNKNOWN:
@@ -2964,21 +3118,23 @@ applet_update_icon (gpointer user_data)
        icon_name = NULL;
        active_vpn = applet_get_first_active_vpn_connection (applet, &vpn_state);
        if (active_vpn) {
-               char *name;
-
                switch (vpn_state) {
                case NM_VPN_CONNECTION_STATE_ACTIVATED:
+#ifndef ENABLE_INDICATOR
                        icon_name = g_strdup_printf ("nm-vpn-active-lock");
                        pixbuf = nma_icon_check_and_load (icon_name, applet);
+#else
+                       icon_name = g_strdup_printf ("%s-secure", app_indicator_get_icon 
(applet->app_indicator));
+#endif
                        break;
                case NM_VPN_CONNECTION_STATE_PREPARE:
                case NM_VPN_CONNECTION_STATE_NEED_AUTH:
                case NM_VPN_CONNECTION_STATE_CONNECT:
                case NM_VPN_CONNECTION_STATE_IP_CONFIG_GET:
-                       name = g_strdup_printf ("nm-vpn-connecting%02d", applet->animation_step + 1);
-                       pixbuf = nma_icon_check_and_load (name, applet);
-                       g_free (name);
-
+                       icon_name = g_strdup_printf ("nm-vpn-connecting%02d", applet->animation_step + 1);
+#ifndef ENABLE_INDICATOR
+                       pixbuf = nma_icon_check_and_load (icon_name, applet);
+#endif
                        applet->animation_step++;
                        if (applet->animation_step >= NUM_VPN_CONNECTING_FRAMES)
                                applet->animation_step = 0;
@@ -3447,18 +3603,88 @@ status_icon_popup_menu_cb (GtkStatusIcon *icon,
         */
        applet_clear_notify (applet);
 
+       if (applet->context_menu)
+               g_object_unref (applet->context_menu);
+       applet->context_menu = nma_context_menu_create (applet);
+
        nma_context_menu_update (applet);
        gtk_menu_popup (GTK_MENU (applet->context_menu), NULL, NULL,
                        gtk_status_icon_position_menu, icon,
                        button, activate_time);
 }
 
+#ifdef ENABLE_INDICATOR
+static GtkStatusIcon *
+indicator_fallback (AppIndicator *indicator)
+{
+       NMApplet *applet;
+
+       applet = NM_APPLET(g_object_get_data (G_OBJECT (indicator), "applet"));
+       g_return_val_if_fail (NM_IS_APPLET (applet), NULL);
+       g_return_val_if_fail (applet->status_icon, NULL);
+
+       g_message ("using fallback from indicator to GtkStatusIcon");
+       gtk_status_icon_set_visible (applet->status_icon, applet->visible);
+
+       applet->in_fallback = TRUE;
+
+       return applet->status_icon;
+}
+
+static void
+indicator_unfallback (AppIndicator *indicator, GtkStatusIcon *status_icon)
+{
+       NMApplet *applet;
+
+       applet = NM_APPLET(g_object_get_data (G_OBJECT (indicator), "applet"));
+       g_return_if_fail (NM_IS_APPLET (applet));
+       g_return_if_fail (applet->status_icon);
+
+       g_message ("moving back from GtkStatusIcon to indicator");
+       gtk_status_icon_set_visible (applet->status_icon, FALSE);
+
+       applet->in_fallback = FALSE;
+}
+
 static gboolean
-setup_widgets (NMApplet *applet)
+setup_indicator_menu (NMApplet *applet)
+{
+       g_return_val_if_fail (NM_IS_APPLET (applet), FALSE);
+
+       applet->in_fallback = FALSE;
+
+       applet->app_indicator = app_indicator_new
+                               ("nm-applet", "nm-no-connection",
+                                APP_INDICATOR_CATEGORY_SYSTEM_SERVICES);
+
+       app_indicator_set_title(applet->app_indicator, _("Network"));
+
+       g_object_set_data (G_OBJECT (applet->app_indicator), "applet", (gpointer) applet);
+
+       APP_INDICATOR_GET_CLASS(applet->app_indicator)->fallback = indicator_fallback;
+       APP_INDICATOR_GET_CLASS(applet->app_indicator)->unfallback = indicator_unfallback;
+
+       applet->menu = nma_context_menu_create (applet);
+
+       nma_context_menu_update(applet);
+
+       app_indicator_set_menu(applet->app_indicator, GTK_MENU(applet->menu));
+
+       return TRUE;
+}
+#endif /* ENABLE_INDICATOR */
+
+static gboolean
+setup_statusicon_menu (NMApplet *applet)
 {
        g_return_val_if_fail (NM_IS_APPLET (applet), FALSE);
 
        applet->status_icon = gtk_status_icon_new ();
+
+#ifdef ENABLE_INDICATOR
+       gtk_status_icon_set_visible (applet->status_icon, FALSE);
+#endif
+
        if (!applet->status_icon)
                return FALSE;
        if (shell_debug)
@@ -3474,10 +3700,32 @@ setup_widgets (NMApplet *applet)
                          G_CALLBACK (status_icon_popup_menu_cb), applet);
 
        applet->context_menu = nma_context_menu_create (applet);
-       if (!applet->context_menu)
-               return FALSE;
 
-       return TRUE;
+       return TRUE;
+}
+
+static gboolean
+setup_widgets (NMApplet *applet)
+{
+       gboolean success = FALSE;
+#ifdef ENABLE_INDICATOR
+       gboolean indicator_success = FALSE;
+#endif
+
+       g_return_val_if_fail (NM_IS_APPLET (applet), FALSE);
+
+       success = setup_statusicon_menu (applet);
+
+#ifdef ENABLE_INDICATOR
+       indicator_success = setup_indicator_menu (applet);
+#endif
+
+#ifndef ENABLE_INDICATOR
+       return success;
+#else
+       return success || indicator_success;
+#endif
+       return success;
 }
 
 static void
@@ -3500,6 +3748,12 @@ register_agent (NMApplet *applet)
                          G_CALLBACK (applet_agent_get_secrets_cb), applet);
        g_signal_connect (applet->agent, APPLET_AGENT_CANCEL_SECRETS,
                          G_CALLBACK (applet_agent_cancel_secrets_cb), applet);
+#ifdef ENABLE_INDICATOR
+       /* Watch for new connections */
+       g_signal_connect (applet->settings, "new-connection",
+                         G_CALLBACK (new_connection_cb),
+                         applet);
+#endif
 }
 
 static gboolean
@@ -3567,6 +3821,9 @@ initable_init (GInitable *initable, GCancellable *cancellable, GError **error)
        g_signal_connect (applet->gsettings, "changed::show-applet",
                          G_CALLBACK (applet_gsettings_show_changed), applet);
 
+#ifdef ENABLE_INDICATOR
+       foo_client_setup (applet);
+#endif
 
        /* Load pixmaps and create applet widgets */
        if (!setup_widgets (applet)) {
@@ -3686,6 +3943,11 @@ static void finalize (GObject *object)
        if (applet->update_icon_id)
                g_source_remove (applet->update_icon_id);
 
+#ifdef ENABLE_INDICATOR
+       if (applet->update_menu_id)
+               g_source_remove (applet->update_menu_id);
+#endif
+
        if (applet->menu)
                g_object_unref (applet->menu);
        g_clear_pointer (&applet->icon_cache, g_hash_table_destroy);
@@ -3710,6 +3972,14 @@ static void finalize (GObject *object)
        if (applet->status_icon)
                g_object_unref (applet->status_icon);
 
+#ifdef ENABLE_INDICATOR
+       if (applet->app_indicator)
+       {
+               APP_INDICATOR_GET_CLASS(applet->app_indicator)->unfallback = NULL;
+               g_object_unref (applet->app_indicator);
+       }
+#endif
+
        if (applet->nm_client)
                g_object_unref (applet->nm_client);
 
diff --git a/src/applet.h b/src/applet.h
index 66ca945..bc8c29c 100644
--- a/src/applet.h
+++ b/src/applet.h
@@ -36,6 +36,10 @@
 
 #include <libnotify/notify.h>
 
+#ifdef ENABLE_INDICATOR
+#include <libappindicator/app-indicator.h>
+#endif
+
 #include <nm-connection.h>
 #include <nm-client.h>
 #include <nm-access-point.h>
@@ -135,6 +139,11 @@ typedef struct
        guint                   animation_id;
 
        /* Direct UI elements */
+#ifdef ENABLE_INDICATOR
+       AppIndicator *  app_indicator;
+       guint           update_menu_id;
+       gboolean        in_fallback;
+#endif
        GtkStatusIcon * status_icon;
        int             icon_size;
 
@@ -244,6 +253,7 @@ GType nma_get_type (void);
 NMApplet *nm_applet_new (void);
 
 void applet_schedule_update_icon (NMApplet *applet);
+void applet_schedule_update_menu (NMApplet *applet);
 
 NMRemoteSettings *applet_get_settings (NMApplet *applet);
 
diff --git a/src/gconf-helpers/Makefile.am b/src/gconf-helpers/Makefile.am
index 3740f18..f9d5f52 100644
--- a/src/gconf-helpers/Makefile.am
+++ b/src/gconf-helpers/Makefile.am
@@ -16,6 +16,7 @@ libgconf_helpers_la_CPPFLAGS = \
        -I$(top_srcdir)/src/utils \
        $(GTK_CFLAGS) \
        $(NMA_CFLAGS) \
+       $(APPINDICATOR_CFLAGS) \
        $(MIGRATION_CFLAGS) \
        $(DISABLE_DEPRECATED)
 
@@ -34,6 +35,7 @@ libgconf_helpers_test_la_CPPFLAGS = \
        -I$(top_srcdir)/src/utils \
        $(GTK_CFLAGS) \
        $(NMA_CFLAGS) \
+       $(APPINDICATOR_CFLAGS) \
        $(MIGRATION_CFLAGS) \
        $(DISABLE_DEPRECATED)
 
diff --git a/src/mobile-helpers.c b/src/mobile-helpers.c
index 9cfb5fe..78f382a 100644
--- a/src/mobile-helpers.c
+++ b/src/mobile-helpers.c
@@ -107,6 +107,116 @@ mobile_helper_get_quality_icon_name (guint32 quality)
                return "nm-signal-00";
 }
 
+static const char *
+get_tech_name (guint32 tech)
+{
+       switch (tech) {
+       case MB_TECH_1XRTT:
+               return _("CDMA");
+       case MB_TECH_EVDO:
+               return _("EVDO");
+       case MB_TECH_GSM:
+               return _("GSM");
+       case MB_TECH_GPRS:
+               return _("GPRS");
+       case MB_TECH_EDGE:
+               return _("EDGE");
+       case MB_TECH_UMTS:
+               return _("UMTS");
+       case MB_TECH_HSDPA:
+               return _("HSDPA");
+       case MB_TECH_HSUPA:
+               return _("HSUPA");
+       case MB_TECH_HSPA:
+               return _("HSPA");
+       case MB_TECH_HSPA_PLUS:
+               return _("HSPA+");
+       case MB_TECH_LTE:
+               return _("LTE");
+       default:
+               break;
+       }
+       return NULL;
+}
+
+char *
+mobile_helper_get_connection_label (const char *connection_name,
+                                    const char *provider,
+                                    guint32 technology,
+                                    guint32 state)
+{
+       const char *tech_name;
+       char *desc_string;
+
+       /* Construct the description string */
+       tech_name = get_tech_name (technology);
+       switch (state) {
+       default:
+       case MB_STATE_UNKNOWN:
+               desc_string = g_strdup (_("not enabled"));
+               break;
+       case MB_STATE_IDLE:
+               if (connection_name)
+                       desc_string = g_strdup (connection_name);
+               else
+                       desc_string = g_strdup (_("not registered"));
+               break;
+       case MB_STATE_HOME:
+               if (connection_name) {
+                       if (provider && tech_name)
+                               desc_string = g_strdup_printf ("%s (%s %s)", connection_name, provider, 
tech_name);
+                       else if (provider || tech_name)
+                               desc_string = g_strdup_printf ("%s (%s)", connection_name, provider ? 
provider : tech_name);
+                       else
+                               desc_string = g_strdup_printf ("%s", connection_name);
+               } else {
+                       if (provider) {
+                               if (tech_name)
+                                       desc_string = g_strdup_printf ("%s %s", provider, tech_name);
+                               else
+                                       desc_string = g_strdup_printf ("%s", provider);
+                       } else {
+                               if (tech_name)
+                                       desc_string = g_strdup_printf (_("Home network (%s)"), tech_name);
+                               else
+                                       desc_string = g_strdup_printf (_("Home network"));
+                       }
+               }
+               break;
+       case MB_STATE_SEARCHING:
+               if (connection_name)
+                       desc_string = g_strdup (connection_name);
+               else
+                       desc_string = g_strdup (_("searching"));
+               break;
+       case MB_STATE_DENIED:
+               desc_string = g_strdup (_("registration denied"));
+               break;
+       case MB_STATE_ROAMING:
+               if (connection_name) {
+                       if (tech_name)
+                               desc_string = g_strdup_printf (_("%s (%s roaming)"), connection_name, 
tech_name);
+                       else
+                               desc_string = g_strdup_printf (_("%s (roaming)"), connection_name);
+               } else {
+                       if (provider) {
+                               if (tech_name)
+                                       desc_string = g_strdup_printf (_("%s (%s roaming)"), provider, 
tech_name);
+                               else
+                                       desc_string = g_strdup_printf (_("%s (roaming)"), provider);
+                       } else {
+                               if (tech_name)
+                                       desc_string = g_strdup_printf (_("Roaming network (%s)"), tech_name);
+                               else
+                                       desc_string = g_strdup_printf (_("Roaming network"));
+                       }
+               }
+               break;
+       }
+
+       return desc_string;
+}
+
 const char *
 mobile_helper_get_tech_icon_name (guint32 tech)
 {
@@ -592,11 +702,16 @@ mobile_helper_get_icon (NMDevice *device,
                *tip = g_strdup_printf (_("Requesting a network address for '%s'..."), id);
                break;
        case NM_DEVICE_STATE_ACTIVATED:
+#ifdef ENABLE_INDICATOR
+               *out_icon_name = mobile_helper_get_quality_icon_name (quality_valid ? quality : 0);
+#else
                *out_pixbuf = mobile_helper_get_status_pixbuf (quality,
                                                               quality_valid,
                                                               mb_state,
                                                               mb_tech,
                                                               applet);
+#endif
+
                if ((mb_state != MB_STATE_UNKNOWN) && quality_valid) {
                        gboolean roaming = (mb_state == MB_STATE_ROAMING);
 
diff --git a/src/mobile-helpers.h b/src/mobile-helpers.h
index cbb0143..8e40819 100644
--- a/src/mobile-helpers.h
+++ b/src/mobile-helpers.h
@@ -65,6 +65,11 @@ GdkPixbuf *mobile_helper_get_status_pixbuf (guint32 quality,
 const char *mobile_helper_get_quality_icon_name (guint32 quality);
 const char *mobile_helper_get_tech_icon_name (guint32 tech);
 
+char *mobile_helper_get_connection_label (const char *connection_name,
+                                          const char *provider,
+                                          guint32 technology,
+                                          guint32 state);
+
 /********************************************************************/
 
 gboolean   mobile_helper_wizard (NMDeviceModemCapabilities capabilities,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]