summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Šimerda <psimerda@redhat.com>2014-12-17 14:38:42 +0100
committerDan Williams <dcbw@redhat.com>2015-02-17 09:31:22 -0600
commiteb5336831cbd8444c2b70d11e5769092defc139a (patch)
tree11ff1582064f5805d2482863d5933e0bf1f8ab1f
parentd558ea0c58c1adfd3d11d6c2a5bc960183347b13 (diff)
downloadnetwork-manager-applet-dcbw/indicator.tar.gz
applet: add support for --with-appindicatordcbw/indicator
Add new configure option --with-appindicator 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. (many cleanups and consolidations by dcbw)
-rw-r--r--configure.ac6
-rw-r--r--src/Makefile.am2
-rw-r--r--src/ap-menu-item.c57
-rw-r--r--src/applet.c179
-rw-r--r--src/applet.h12
-rw-r--r--src/mb-menu-item.c59
6 files changed, 261 insertions, 54 deletions
diff --git a/configure.ac b/configure.ac
index 5452784b..639810b4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -145,6 +145,12 @@ case "${with_bluetooth}" in
;;
esac
+AC_ARG_WITH([appindicator], AS_HELP_STRING([--with-appindicator|--without-appindicator], [Build with libappindicator support instead of xembed systray support.]))
+if test "$with_appindicator" == "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 for WWAN support
diff --git a/src/Makefile.am b/src/Makefile.am
index 903102cf..c0407a60 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,6 +8,7 @@ nm_applet_CPPFLAGS = \
$(LIBSECRET_CFLAGS) \
$(NOTIFY_CFLAGS) \
$(MM_GLIB_CFLAGS) \
+ $(APPINDICATOR_CFLAGS) \
-DNM_VERSION_MIN_REQUIRED=NM_VERSION_0_9_10 \
-DNM_VERSION_MAX_ALLOWED=NM_VERSION_0_9_10 \
-DICONDIR=\""$(datadir)/icons"\" \
@@ -82,6 +83,7 @@ nm_applet_LDADD = \
$(LIBSECRET_LIBS) \
$(NOTIFY_LIBS) \
$(MM_GLIB_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/ap-menu-item.c b/src/ap-menu-item.c
index 2a30977e..a622eb2b 100644
--- a/src/ap-menu-item.c
+++ b/src/ap-menu-item.c
@@ -39,10 +39,12 @@ G_DEFINE_TYPE (NMNetworkMenuItem, nm_network_menu_item, GTK_TYPE_IMAGE_MENU_ITEM
#define NM_NETWORK_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_NETWORK_MENU_ITEM, NMNetworkMenuItemPrivate))
typedef struct {
+#ifndef ENABLE_INDICATOR
GtkWidget * ssid;
GtkWidget * strength;
GtkWidget * detail;
GtkWidget * hbox;
+#endif
char * ssid_string;
guint32 int_strength;
@@ -99,18 +101,20 @@ update_icon (NMNetworkMenuItem *item, NMApplet *applet)
{
NMNetworkMenuItemPrivate *priv = NM_NETWORK_MENU_ITEM_GET_PRIVATE (item);
GdkPixbuf *icon = NULL, *pixbuf, *top, *scaled;
+ const char *icon_name = NULL;
if (priv->int_strength > 80)
- icon = nma_icon_check_and_load ("nm-signal-100", applet);
+ icon_name = "nm-signal-100";
else if (priv->int_strength > 55)
- icon = nma_icon_check_and_load ("nm-signal-75", applet);
+ icon_name = "nm-signal-75";
else if (priv->int_strength > 30)
- icon = nma_icon_check_and_load ("nm-signal-50", applet);
+ icon_name = "nm-signal-50";
else if (priv->int_strength > 5)
- icon = nma_icon_check_and_load ("nm-signal-25", applet);
+ icon_name = "nm-signal-25";
else
- icon = nma_icon_check_and_load ("nm-signal-00", applet);
+ icon_name = "nm-signal-00";
+ icon = nma_icon_check_and_load (icon_name, applet);
pixbuf = gdk_pixbuf_copy (icon);
/* If the AP is "secure", composite the lock icon on top of the signal bars */
@@ -129,9 +133,16 @@ update_icon (NMNetworkMenuItem *item, NMApplet *applet)
pixbuf = scaled;
}
+#ifdef ENABLE_INDICATOR
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), gtk_image_new_from_pixbuf (pixbuf));
+ /* For some reason we must always re-set always-show after setting the image */
+ gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (item), TRUE);
+#else
gtk_image_set_from_pixbuf (GTK_IMAGE (priv->strength), pixbuf);
+#endif
g_object_unref (pixbuf);
+#ifndef ENABLE_INDICATOR
if (priv->is_adhoc && !gtk_image_get_pixbuf (GTK_IMAGE (priv->detail))) {
scaled = NULL;
pixbuf = nma_icon_check_and_load ("nm-adhoc", applet);
@@ -140,6 +151,7 @@ update_icon (NMNetworkMenuItem *item, NMApplet *applet)
gtk_image_set_from_pixbuf (GTK_IMAGE (priv->detail), scaled ? scaled : pixbuf);
g_clear_object (&scaled);
}
+#endif
}
void
@@ -190,31 +202,30 @@ nm_network_menu_item_find_dupe (NMNetworkMenuItem *item, NMAccessPoint *ap)
}
static void
-set_label (NMNetworkMenuItem *item, const char *label, gboolean use_markup)
+update_label (NMNetworkMenuItem *item, gboolean use_bold)
{
NMNetworkMenuItemPrivate *priv = NM_NETWORK_MENU_ITEM_GET_PRIVATE (item);
- gtk_label_set_use_markup (GTK_LABEL (priv->ssid), use_markup);
- if (use_markup)
- gtk_label_set_markup (GTK_LABEL (priv->ssid), label);
- else
- gtk_label_set_text (GTK_LABEL (priv->ssid), label);
+#ifdef ENABLE_INDICATOR
+ gtk_menu_item_set_label (GTK_MENU_ITEM (item), priv->ssid_string);
+#else
+ gtk_label_set_use_markup (GTK_LABEL (priv->ssid), use_bold);
+ if (use_bold) {
+ char *markup = g_markup_printf_escaped ("<b>%s</b>", priv->ssid_string);
+
+ gtk_label_set_markup (GTK_LABEL (priv->ssid), markup);
+ g_free (markup);
+ } else
+ gtk_label_set_text (GTK_LABEL (priv->ssid), priv->ssid_string);
+#endif
}
void
nm_network_menu_item_set_active (NMNetworkMenuItem *item, gboolean active)
{
- NMNetworkMenuItemPrivate *priv;
- char *markup = NULL;
-
g_return_if_fail (NM_IS_NETWORK_MENU_ITEM (item));
- priv = NM_NETWORK_MENU_ITEM_GET_PRIVATE (item);
-
- if (active)
- markup = g_markup_printf_escaped ("<b>%s</b>", priv->ssid_string);
- set_label (item, markup ? markup : priv->ssid_string, !!markup);
- g_free (markup);
+ update_label (item, active);
}
void
@@ -307,7 +318,7 @@ nm_network_menu_item_new (NMAccessPoint *ap,
gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE);
}
- set_label (item, priv->ssid_string, FALSE);
+ update_label (item, FALSE);
update_icon (item, applet);
update_atk_desc (item);
@@ -317,6 +328,7 @@ nm_network_menu_item_new (NMAccessPoint *ap,
static void
nm_network_menu_item_init (NMNetworkMenuItem *item)
{
+#ifndef ENABLE_INDICATOR
NMNetworkMenuItemPrivate *priv = NM_NETWORK_MENU_ITEM_GET_PRIVATE (item);
priv->hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
@@ -336,6 +348,9 @@ nm_network_menu_item_init (NMNetworkMenuItem *item)
gtk_widget_show (priv->ssid);
gtk_widget_show (priv->detail);
gtk_widget_show (priv->hbox);
+#else
+ gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (item), TRUE);
+#endif
}
static void
diff --git a/src/applet.c b/src/applet.c
index f15d463b..c72ab488 100644
--- a/src/applet.c
+++ b/src/applet.c
@@ -676,6 +676,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;
@@ -695,6 +698,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 *
@@ -703,11 +707,14 @@ applet_new_menu_item_helper (NMConnection *connection,
gboolean add_active)
{
NMSettingConnection *s_con = nm_connection_get_setting_connection (connection);
- GtkWidget *item = gtk_image_menu_item_new_with_label ("");
- char *markup;
- GtkWidget *label;
+ GtkWidget *item;
+ item = gtk_image_menu_item_new_with_label ("");
+#ifndef ENABLE_INDICATOR
if (add_active && (active == connection)) {
+ char *markup;
+ GtkWidget *label;
+
/* Pure evil */
label = gtk_bin_get_child (GTK_BIN (item));
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
@@ -715,12 +722,14 @@ applet_new_menu_item_helper (NMConnection *connection,
gtk_label_set_markup (GTK_LABEL (label), markup);
g_free (markup);
} else
+#endif
gtk_menu_item_set_label (GTK_MENU_ITEM (item), nm_setting_connection_get_id (s_con));
gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (item), TRUE);
return item;
}
+#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 )
@@ -784,6 +793,7 @@ menu_title_item_draw (GtkWidget *widget, cairo_t *cr, gpointer user_data)
menu_item_draw_generic (widget, cr);
return TRUE;
}
+#endif /* ENABLE_INDICATOR */
GtkWidget *
applet_menu_item_create_device_item_helper (NMDevice *device,
@@ -794,7 +804,9 @@ applet_menu_item_create_device_item_helper (NMDevice *device,
item = gtk_menu_item_new_with_label (text);
gtk_widget_set_sensitive (item, FALSE);
+#ifndef ENABLE_INDICATOR
g_signal_connect (item, "draw", G_CALLBACK (menu_title_item_draw), NULL);
+#endif
return item;
}
@@ -852,8 +864,13 @@ 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)
+ return;
+#else
if (!gtk_status_icon_is_embedded (applet->status_icon))
return;
+#endif
/* if we're not acting as a secret agent, don't notify either */
if (!applet->agent)
@@ -1193,6 +1210,10 @@ activate_vpn_cb (NMClient *client,
g_free (info);
}
+#ifdef ENABLE_INDICATOR
+static void nma_menu_disconnect_vpn_item_activate (GtkMenuItem *item, gpointer user_data);
+#endif
+
static void
nma_menu_vpn_item_clicked (GtkMenuItem *item, gpointer user_data)
{
@@ -1216,6 +1237,9 @@ nma_menu_vpn_item_clicked (GtkMenuItem *item, gpointer user_data)
}
if (applet_get_active_for_connection (applet, connection)) {
+#ifdef ENABLE_INDICATOR
+ nma_menu_disconnect_vpn_item_activate (item, applet);
+#endif
/* Connection already active; do nothing */
return;
}
@@ -1765,6 +1789,7 @@ nma_menu_add_vpn_submenu (GtkWidget *menu, NMApplet *applet)
item = GTK_MENU_ITEM (gtk_menu_item_new_with_mnemonic (_("_VPN Connections")));
gtk_menu_item_set_submenu (item, GTK_WIDGET (vpn_menu));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), GTK_WIDGET (item));
+ gtk_widget_show (GTK_WIDGET (item));
list = get_vpn_connections (applet);
for (iter = list; iter; iter = g_slist_next (iter)) {
@@ -1782,8 +1807,8 @@ nma_menu_add_vpn_submenu (GtkWidget *menu, NMApplet *applet)
name = get_connection_id (connection);
- item = GTK_MENU_ITEM (gtk_image_menu_item_new_with_label (name));
- gtk_image_menu_item_set_always_show_image(GTK_IMAGE_MENU_ITEM(item), TRUE);
+ item = GTK_MENU_ITEM (gtk_check_menu_item_new_with_label (name));
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(item), FALSE);
/* If no VPN connections are active, draw all menu items enabled. If
* >= 1 VPN connections are active, only the active VPN menu item is
@@ -1802,9 +1827,7 @@ nma_menu_add_vpn_submenu (GtkWidget *menu, NMApplet *applet)
gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE);
if (active) {
- 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);
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(item), TRUE);
}
g_object_set_data_full (G_OBJECT (item), "connection",
@@ -1813,6 +1836,7 @@ nma_menu_add_vpn_submenu (GtkWidget *menu, NMApplet *applet)
g_signal_connect (item, "activate", G_CALLBACK (nma_menu_vpn_item_clicked), applet);
gtk_menu_shell_append (GTK_MENU_SHELL (vpn_menu), GTK_WIDGET (item));
+ gtk_widget_show (GTK_WIDGET (item));
}
/* Draw a seperator, but only if we have VPN connections above it */
@@ -1822,12 +1846,14 @@ nma_menu_add_vpn_submenu (GtkWidget *menu, NMApplet *applet)
item = GTK_MENU_ITEM (gtk_menu_item_new_with_mnemonic (_("_Configure VPN...")));
g_signal_connect (item, "activate", G_CALLBACK (nma_menu_configure_vpn_item_activate), applet);
gtk_menu_shell_append (GTK_MENU_SHELL (vpn_menu), GTK_WIDGET (item));
+ gtk_widget_show (GTK_WIDGET (item));
item = GTK_MENU_ITEM (gtk_menu_item_new_with_mnemonic (_("_Disconnect VPN")));
g_signal_connect (item, "activate", G_CALLBACK (nma_menu_disconnect_vpn_item_activate), applet);
gtk_menu_shell_append (GTK_MENU_SHELL (vpn_menu), GTK_WIDGET (item));
if (num_vpn_active == 0)
gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE);
+ gtk_widget_show (GTK_WIDGET (item));
g_slist_free (list);
}
@@ -1878,6 +1904,7 @@ nma_set_networking_enabled_cb (GtkWidget *widget, NMApplet *applet)
}
+#ifndef ENABLE_INDICATOR
static void
nma_set_notifications_enabled_cb (GtkWidget *widget, NMApplet *applet)
{
@@ -1900,6 +1927,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)
@@ -1936,7 +1964,9 @@ static void nma_menu_show_cb (GtkWidget *menu, NMApplet *applet)
g_return_if_fail (menu != NULL);
g_return_if_fail (applet != NULL);
+#ifndef ENABLE_INDICATOR
gtk_status_icon_set_tooltip_text (applet->status_icon, NULL);
+#endif
if (!nm_client_get_manager_running (applet->nm_client)) {
nma_menu_add_text_item (menu, _("NetworkManager is not running..."));
@@ -1958,11 +1988,14 @@ static void nma_menu_show_cb (GtkWidget *menu, NMApplet *applet)
nma_menu_add_create_network_item (menu, applet);
}
+#ifndef ENABLE_INDICATOR
gtk_widget_show_all (menu);
+#endif
// nmi_dbus_signal_user_interface_activated (applet->connection);
}
+#ifndef ENABLE_INDICATOR
static gboolean
destroy_old_menu (gpointer user_data)
{
@@ -1984,6 +2017,7 @@ nma_menu_deactivate_cb (GtkWidget *widget, NMApplet *applet)
/* Re-set the tooltip */
gtk_status_icon_set_tooltip_text (applet->status_icon, applet->tip);
}
+#endif
static gboolean
is_permission_yes (NMApplet *applet, NMClientPermission perm)
@@ -2009,7 +2043,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);
@@ -2069,6 +2105,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);
@@ -2080,6 +2117,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) {
@@ -2155,7 +2193,9 @@ applet_connection_info_cb (NMApplet *applet)
static GtkWidget *nma_context_menu_create (NMApplet *applet)
{
GtkMenuShell *menu;
+#ifndef ENABLE_INDICATOR
GtkWidget *menu_item;
+#endif
GtkWidget *image;
guint id;
@@ -2201,6 +2241,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,
@@ -2211,6 +2252,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"));
@@ -2235,6 +2277,7 @@ static GtkWidget *nma_context_menu_create (NMApplet *applet)
/* Separator */
nma_menu_add_separator_item (GTK_WIDGET (menu));
+#ifndef ENABLE_INDICATOR
#if 0 /* FIXME: Implement the help callback, nma_help_cb()! */
/* Help item */
menu_item = gtk_image_menu_item_new_with_mnemonic (_("_Help"));
@@ -2251,6 +2294,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);
+#endif
gtk_widget_show_all (GTK_WIDGET (menu));
@@ -2353,9 +2397,31 @@ applet_add_default_connection_item (NMDevice *device,
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
}
+#ifdef ENABLE_INDICATOR
+static gboolean
+applet_update_indicator_menu (gpointer user_data)
+{
+ NMApplet *applet = NM_APPLET (user_data);
+ GtkWidget *menu = nma_context_menu_create (applet);
+
+ nma_menu_show_cb (menu, applet);
+ nma_menu_add_separator_item (menu);
+ nma_context_menu_update (applet);
+
+ app_indicator_set_menu (applet->app_indicator, GTK_MENU (menu));
+
+ applet->update_menu_id = 0;
+ return FALSE;
+}
+#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
}
/*****************************************************************************/
@@ -2365,6 +2431,16 @@ 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
+ /* FIXME: We rely on the fact that VPN icon gets drawn later and therefore
+ * wins but we cannot currently set a combined pixmap made of both the link
+ * icon and the VPN icon.
+ */
+ 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);
+#else
/* Load the pixbuf by icon name */
if (icon_name && !pixbuf)
pixbuf = nma_icon_check_and_load (icon_name, applet);
@@ -2402,6 +2478,7 @@ foo_set_icon (NMApplet *applet, guint32 layer, GdkPixbuf *pixbuf, char *icon_nam
gtk_status_icon_set_from_pixbuf (applet->status_icon, pixbuf);
g_object_unref (pixbuf);
+#endif
}
NMRemoteConnection *
@@ -2556,6 +2633,17 @@ foo_client_state_changed_cb (NMClient *client, GParamSpec *pspec, gpointer user_
applet_schedule_update_menu (applet);
}
+#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);
+ applet_schedule_update_menu (applet);
+}
+#endif
+
static void
foo_manager_running_cb (NMClient *client,
GParamSpec *pspec,
@@ -2652,6 +2740,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);
@@ -2924,7 +3017,11 @@ applet_update_icon (gpointer user_data)
if (!nm_running)
state = NM_STATE_UNKNOWN;
+#ifdef ENABLE_INDICATOR
+ app_indicator_set_status (applet->app_indicator, nm_running ? APP_INDICATOR_STATUS_ACTIVE : APP_INDICATOR_STATUS_PASSIVE);
+#else
gtk_status_icon_set_visible (applet->status_icon, applet->visible);
+#endif
switch (state) {
case NM_STATE_UNKNOWN:
@@ -2985,7 +3082,13 @@ applet_update_icon (gpointer user_data)
/* update tooltip */
g_free (applet->tip);
applet->tip = g_strdup (vpn_tip ? vpn_tip : dev_tip);
+#ifdef ENABLE_INDICATOR
+ /* FIXME: The applet->tip attribute seems to only be picked up by
+ * the next call to foo_set_icon() which is not particularly nice.
+ */
+#else
gtk_status_icon_set_tooltip_text (applet->status_icon, applet->tip);
+#endif
g_free (vpn_tip);
g_free (dev_tip);
@@ -3331,7 +3434,6 @@ error:
static void nma_icons_init (NMApplet *applet)
{
- GdkScreen *screen;
gboolean path_appended;
if (applet->icon_theme) {
@@ -3341,9 +3443,15 @@ static void nma_icons_init (NMApplet *applet)
g_object_unref (G_OBJECT (applet->icon_theme));
}
- screen = gtk_status_icon_get_screen (applet->status_icon);
- g_assert (screen);
- applet->icon_theme = gtk_icon_theme_get_for_screen (screen);
+#ifdef ENABLE_INDICATOR
+ applet->icon_theme = gtk_icon_theme_get_default ();
+#else
+ {
+ GdkScreen *screen = gtk_status_icon_get_screen (applet->status_icon);
+
+ applet->icon_theme = gtk_icon_theme_get_for_screen (screen);
+ }
+#endif
/* If not done yet, append our search path */
path_appended = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (applet->icon_theme),
@@ -3358,6 +3466,7 @@ static void nma_icons_init (NMApplet *applet)
g_signal_connect (applet->icon_theme, "changed", G_CALLBACK (nma_icons_reload), applet);
}
+#ifndef ENABLE_INDICATOR
static void
status_icon_screen_changed_cb (GtkStatusIcon *icon,
GParamSpec *pspec,
@@ -3429,11 +3538,30 @@ status_icon_popup_menu_cb (GtkStatusIcon *icon,
gtk_status_icon_position_menu, icon,
button, activate_time);
}
+#endif /* ENABLE_INDICATOR */
static gboolean
setup_widgets (NMApplet *applet)
{
+#ifdef ENABLE_INDICATOR
+ GtkWidget *menu;
+
+ 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);
+
+ menu = nma_context_menu_create (applet);
+ nma_context_menu_update (applet);
+
+ app_indicator_set_menu (applet->app_indicator, GTK_MENU (menu));
+
+ return TRUE;
+#else
applet->status_icon = gtk_status_icon_new ();
if (shell_debug)
@@ -3453,8 +3581,18 @@ setup_widgets (NMApplet *applet)
return FALSE;
return TRUE;
+#endif
}
+#ifdef ENABLE_INDICATOR
+static void
+new_connection_cb (NMRemoteSettings *settings, NMRemoteConnection *connection, gpointer user_data)
+{
+ NMApplet *applet = NM_APPLET (user_data);
+
+ applet_schedule_update_menu (applet);
+}
+#else
static void
applet_embedded_cb (GObject *object, GParamSpec *pspec, gpointer user_data)
{
@@ -3463,6 +3601,7 @@ applet_embedded_cb (GObject *object, GParamSpec *pspec, gpointer user_data)
g_debug ("applet now %s the notification area",
embedded ? "embedded in" : "removed from");
}
+#endif
static void
register_agent (NMApplet *applet)
@@ -3475,6 +3614,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
@@ -3519,7 +3664,9 @@ applet_gsettings_show_changed (GSettings *settings,
applet->visible = g_settings_get_boolean (settings, key);
+#ifndef ENABLE_INDICATOR
gtk_status_icon_set_visible (applet->status_icon, applet->visible);
+#endif
}
static gboolean
@@ -3620,12 +3767,14 @@ initable_init (GInitable *initable, GCancellable *cancellable, GError **error)
mm1_client_setup (applet);
#endif
+#ifndef ENABLE_INDICATOR
/* Track embedding to help debug issues where user has removed the
* notification area applet from the panel, and thus nm-applet too.
*/
g_signal_connect (applet->status_icon, "notify::embedded",
G_CALLBACK (applet_embedded_cb), NULL);
applet_embedded_cb (G_OBJECT (applet->status_icon), NULL, NULL);
+#endif
register_agent (applet);
@@ -3652,12 +3801,18 @@ static void finalize (GObject *object)
if (applet->update_icon_id)
g_source_remove (applet->update_icon_id);
+#ifdef ENABLE_INDICATOR
+ g_clear_object (&applet->app_indicator);
+ if (applet->update_menu_id)
+ g_source_remove (applet->update_menu_id);
+#else
g_clear_object (&applet->status_icon);
g_clear_object (&applet->menu);
g_clear_pointer (&applet->icon_cache, g_hash_table_destroy);
g_clear_object (&applet->fallback_icon);
g_free (applet->tip);
nma_icons_free (applet);
+#endif
while (g_slist_length (applet->secrets_reqs))
applet_secrets_request_free ((SecretsRequest *) applet->secrets_reqs->data);
diff --git a/src/applet.h b/src/applet.h
index cf729afa..549cc5db 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>
@@ -129,19 +133,23 @@ typedef struct
GtkIconTheme * icon_theme;
GHashTable * icon_cache;
GdkPixbuf * fallback_icon;
+ int icon_size;
/* Active status icon pixbufs */
GdkPixbuf * icon_layers[ICON_LAYER_MAX + 1];
- /* Direct UI elements */
+#ifdef ENABLE_INDICATOR
+ AppIndicator * app_indicator;
+ guint update_menu_id;
+#else
GtkStatusIcon * status_icon;
- int icon_size;
GtkWidget * menu;
GtkWidget * context_menu;
GtkWidget * notifications_enabled_item;
guint notifications_enabled_toggled_id;
+#endif
GtkWidget * networking_enabled_item;
guint networking_enabled_toggled_id;
diff --git a/src/mb-menu-item.c b/src/mb-menu-item.c
index 4f204f17..216f7b6f 100644
--- a/src/mb-menu-item.c
+++ b/src/mb-menu-item.c
@@ -36,12 +36,15 @@ G_DEFINE_TYPE (NMMbMenuItem, nm_mb_menu_item, GTK_TYPE_IMAGE_MENU_ITEM);
#define NM_MB_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MB_MENU_ITEM, NMMbMenuItemPrivate))
typedef struct {
- GtkWidget *desc;
- char *desc_string;
+#ifndef ENABLE_INDICATOR
GtkWidget *strength;
- guint32 int_strength;
GtkWidget *detail;
GtkWidget *hbox;
+ GtkWidget *desc;
+#endif
+
+ char *desc_string;
+ guint32 int_strength;
} NMMbMenuItemPrivate;
static const char *
@@ -78,6 +81,25 @@ get_tech_name (guint32 tech)
return NULL;
}
+static void
+update_label (NMMbMenuItem *item, gboolean use_bold)
+{
+ NMMbMenuItemPrivate *priv = NM_MB_MENU_ITEM_GET_PRIVATE (item);
+
+#ifdef ENABLE_INDICATOR
+ gtk_menu_item_set_label (GTK_MENU_ITEM (item), priv->desc_string);
+#else
+ gtk_label_set_use_markup (GTK_LABEL (priv->desc), use_bold);
+ if (use_bold) {
+ char *markup = g_markup_printf_escaped ("<b>%s</b>", priv->desc_string);
+
+ gtk_label_set_markup (GTK_LABEL (priv->desc), markup);
+ g_free (markup);
+ } else
+ gtk_label_set_text (GTK_LABEL (priv->desc), priv->desc_string);
+#endif
+}
+
GtkWidget *
nm_mb_menu_item_new (const char *connection_name,
guint32 strength,
@@ -93,8 +115,7 @@ nm_mb_menu_item_new (const char *connection_name,
const char *tech_name = NULL;
item = g_object_new (NM_TYPE_MB_MENU_ITEM, NULL);
- if (!item)
- return NULL;
+ g_assert (item);
priv = NM_MB_MENU_ITEM_GET_PRIVATE (item);
priv->int_strength = strength;
@@ -168,24 +189,20 @@ nm_mb_menu_item_new (const char *connection_name,
break;
}
- if (enabled && connection_name && active) {
- char *markup;
-
- gtk_label_set_use_markup (GTK_LABEL (priv->desc), TRUE);
- markup = g_markup_printf_escaped ("<b>%s</b>", priv->desc_string);
- gtk_label_set_markup (GTK_LABEL (priv->desc), markup);
- g_free (markup);
- } else {
- /* Disconnected and disabled states */
- gtk_label_set_use_markup (GTK_LABEL (priv->desc), FALSE);
- gtk_label_set_text (GTK_LABEL (priv->desc), priv->desc_string);
- }
+ update_label (item, (enabled && connection_name && active));
/* And the strength icon, if we have strength information at all */
if (enabled && strength) {
- GdkPixbuf *pixbuf = nma_icon_check_and_load (mobile_helper_get_quality_icon_name (strength), applet);
-
+ const char *icon_name = mobile_helper_get_quality_icon_name (strength);
+ GdkPixbuf *pixbuf = nma_icon_check_and_load (icon_name, applet);
+
+#ifdef ENABLE_INDICATOR
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), gtk_image_new_from_pixbuf (pixbuf));
+ /* For some reason we must always re-set always-show after setting the image */
+ gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (item), TRUE);
+#else
gtk_image_set_from_pixbuf (GTK_IMAGE (priv->strength), pixbuf);
+#endif
}
return GTK_WIDGET (item);
@@ -196,6 +213,7 @@ nm_mb_menu_item_new (const char *connection_name,
static void
nm_mb_menu_item_init (NMMbMenuItem *self)
{
+#ifndef ENABLE_INDICATOR
NMMbMenuItemPrivate *priv = NM_MB_MENU_ITEM_GET_PRIVATE (self);
priv->hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
@@ -211,6 +229,9 @@ nm_mb_menu_item_init (NMMbMenuItem *self)
gtk_widget_show (priv->desc);
gtk_widget_show (priv->strength);
gtk_widget_show (priv->hbox);
+#else
+ gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (self), TRUE);
+#endif
}
static void