From 934e3541dcda08c7e7f6e96cee1625c2cab35287 Mon Sep 17 00:00:00 2001 From: Eric Koegel Date: Sun, 22 Feb 2015 13:32:34 +0300 Subject: [PATCH] Bring back the tray icon (Bug #11054) This patch uses the PowerManagerButton to implement the tray icon. It doesn't do the show when (dis)charging stuff since it will display different battery types now, however that can be added back if desired. --- data/interfaces/xfpm-settings.ui | 15 ++ .../power-manager-plugin/power-manager-button.c | 125 +++++++++++++-- .../power-manager-plugin/power-manager-button.h | 11 ++ settings/xfpm-settings.c | 22 +++ src/Makefile.am | 7 +- src/xfpm-manager.c | 175 ++++++++++++++++++++- src/xfpm-power.c | 1 - 7 files changed, 337 insertions(+), 19 deletions(-) diff --git a/data/interfaces/xfpm-settings.ui b/data/interfaces/xfpm-settings.ui index e5b6dfb..5b2cf6d 100644 --- a/data/interfaces/xfpm-settings.ui +++ b/data/interfaces/xfpm-settings.ui @@ -621,6 +621,21 @@ 1 + + + Show system tray icon + True + True + False + True + + + + True + True + 1 + + diff --git a/panel-plugins/power-manager-plugin/power-manager-button.c b/panel-plugins/power-manager-plugin/power-manager-button.c index 7cfac03..6d5844d 100644 --- a/panel-plugins/power-manager-plugin/power-manager-button.c +++ b/panel-plugins/power-manager-plugin/power-manager-button.c @@ -71,6 +71,8 @@ struct PowerManagerButtonPrivate gchar *panel_icon_name; /* Keep track of the last icon size for use during updates */ gint panel_icon_width; + /* Keep track of the tooltip */ + gchar *tooltip; /* Upower 0.99 has a display device that can be used for the * panel image and tooltip description */ @@ -111,6 +113,13 @@ typedef enum PROP_BRIGHTNESS_MIN_LEVEL, } POWER_MANAGER_BUTTON_PROPERTIES; +enum { + SIG_ICON_NAME_CHANGED = 0, + SIG_TOOLTIP_CHANGED, + SIG_N_SIGNALS, +}; + +static guint __signals[SIG_N_SIGNALS] = { 0, }; G_DEFINE_TYPE (PowerManagerButton, power_manager_button, GTK_TYPE_TOGGLE_BUTTON) @@ -119,7 +128,6 @@ static GList* find_device_in_list (PowerManagerButton *button, const gchar *obje static gboolean power_manager_button_device_icon_expose (GtkWidget *img, GdkEventExpose *event, gpointer userdata); static gboolean power_manager_button_set_icon (PowerManagerButton *button); static gboolean power_manager_button_press_event (GtkWidget *widget, GdkEventButton *event); -static void power_manager_button_show_menu (PowerManagerButton *button); static gboolean power_manager_button_menu_add_device (PowerManagerButton *button, BatteryDevice *battery_device, gboolean append); static void increase_brightness (PowerManagerButton *button); static void decrease_brightness (PowerManagerButton *button); @@ -190,18 +198,30 @@ power_manager_button_set_tooltip (PowerManagerButton *button) return; } + if (button->priv->tooltip != NULL) + { + g_free (button->priv->tooltip); + button->priv->tooltip = NULL; + } + if ( display_device ) { /* if we have something, display it */ if( display_device->details ) { + button->priv->tooltip = g_strdup(display_device->details); gtk_widget_set_tooltip_markup (GTK_WIDGET (button), display_device->details); + /* Tooltip changed! */ + g_signal_emit (button, __signals[SIG_TOOLTIP_CHANGED], 0); return; } } /* Odds are this is a desktop without any batteries attached */ - gtk_widget_set_tooltip_text (GTK_WIDGET (button), _("Display battery levels for attached devices")); + button->priv->tooltip = g_strdup(_("Display battery levels for attached devices")); + gtk_widget_set_tooltip_text (GTK_WIDGET (button), button->priv->tooltip); + /* Tooltip changed! */ + g_signal_emit (button, __signals[SIG_TOOLTIP_CHANGED], 0); } static GList* @@ -343,7 +363,8 @@ power_manager_button_update_device_icon_and_details (PowerManagerButton *button, TRACE("entering for %s", object_path); - g_return_if_fail ( POWER_MANAGER_IS_BUTTON (button) ); + if ( !POWER_MANAGER_IS_BUTTON (button) ) + return; item = find_device_in_list (button, object_path); @@ -492,19 +513,10 @@ battery_device_remove_pix (BatteryDevice *battery_device) } static void -power_manager_button_remove_device (PowerManagerButton *button, const gchar *object_path) +remove_battery_device (PowerManagerButton *button, BatteryDevice *battery_device) { - GList *item; - BatteryDevice *battery_device; - - TRACE("entering for %s", object_path); - - item = find_device_in_list (button, object_path); - - if (item == NULL) - return; - - battery_device = item->data; + g_return_if_fail ( POWER_MANAGER_IS_BUTTON(button) ); + g_return_if_fail ( battery_device != NULL ); /* If it is being shown in the menu, remove it */ if(battery_device->menu_item && button->priv->menu) @@ -523,6 +535,25 @@ power_manager_button_remove_device (PowerManagerButton *button, const gchar *obj g_object_unref (battery_device->device); battery_device->device = NULL; } +} + +static void +power_manager_button_remove_device (PowerManagerButton *button, const gchar *object_path) +{ + GList *item; + BatteryDevice *battery_device; + + TRACE("entering for %s", object_path); + + item = find_device_in_list (button, object_path); + + if (item == NULL) + return; + + battery_device = item->data; + + /* Remove its resources */ + remove_battery_device (button, battery_device); /* remove it item and free the battery device */ button->priv->devices = g_list_delete_link (button->priv->devices, item); @@ -578,6 +609,29 @@ power_manager_button_add_all_devices (PowerManagerButton *button) } static void +power_manager_button_remove_all_devices (PowerManagerButton *button) +{ + GList *item = NULL; + + TRACE("entering"); + + g_return_if_fail ( POWER_MANAGER_IS_BUTTON(button) ); + + for (item = g_list_first (button->priv->devices); item != NULL; item = g_list_next (item)) + { + BatteryDevice *battery_device = item->data; + if (battery_device == NULL) + { + DBG("!battery_device"); + continue; + } + + /* Remove its resources */ + remove_battery_device (button, battery_device); + } +} + +static void brightness_up (PowerManagerButton *button) { gint32 level; @@ -715,6 +769,24 @@ power_manager_button_class_init (PowerManagerButtonClass *klass) g_type_class_add_private (klass, sizeof (PowerManagerButtonPrivate)); + __signals[SIG_TOOLTIP_CHANGED] = g_signal_new("tooltip-changed", + POWER_MANAGER_TYPE_BUTTON, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(PowerManagerButtonClass, + tooltip_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + __signals[SIG_ICON_NAME_CHANGED] = g_signal_new("icon-name-changed", + POWER_MANAGER_TYPE_BUTTON, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(PowerManagerButtonClass, + icon_name_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + #define XFPM_PARAM_FLAGS (G_PARAM_READWRITE \ | G_PARAM_CONSTRUCT \ | G_PARAM_STATIC_NAME \ @@ -772,6 +844,8 @@ power_manager_button_finalize (GObject *object) { PowerManagerButton *button; + DBG("entering"); + button = POWER_MANAGER_BUTTON (object); g_free(button->priv->panel_icon_name); @@ -784,6 +858,8 @@ power_manager_button_finalize (GObject *object) g_signal_handlers_disconnect_by_data (button->priv->upower, button); + power_manager_button_remove_all_devices (button); + #ifdef XFCE_PLUGIN g_object_unref (button->priv->plugin); #endif @@ -798,6 +874,9 @@ power_manager_button_new (XfcePanelPlugin *plugin) #ifdef LXDE_PLUGIN power_manager_button_new (void) #endif +#ifdef XFPM_SYSTRAY +power_manager_button_new (void) +#endif { PowerManagerButton *button = NULL; button = g_object_new (POWER_MANAGER_TYPE_BUTTON, NULL, NULL); @@ -829,6 +908,8 @@ power_manager_button_set_icon (PowerManagerButton *button) if ( pixbuf ) { gtk_image_set_from_pixbuf (GTK_IMAGE (button->priv->panel_icon_image), pixbuf); + /* Notify others the icon name changed */ + g_signal_emit (button, __signals[SIG_ICON_NAME_CHANGED], 0); g_object_unref (pixbuf); return TRUE; } @@ -836,6 +917,18 @@ power_manager_button_set_icon (PowerManagerButton *button) return FALSE; } +const gchar * +power_manager_button_get_icon_name (PowerManagerButton *button) +{ + return button->priv->panel_icon_name; +} + +const gchar * +power_manager_button_get_tooltip (PowerManagerButton *button) +{ + return button->priv->tooltip; +} + void power_manager_button_set_width (PowerManagerButton *button, gint width) { @@ -1157,7 +1250,7 @@ range_show_cb (GtkWidget *widget, PowerManagerButton *button) gtk_grab_remove(widget); } -static void +void power_manager_button_show_menu (PowerManagerButton *button) { GtkWidget *menu, *mi, *img = NULL; diff --git a/panel-plugins/power-manager-plugin/power-manager-button.h b/panel-plugins/power-manager-plugin/power-manager-button.h index 0ae1368..f879e10 100644 --- a/panel-plugins/power-manager-plugin/power-manager-button.h +++ b/panel-plugins/power-manager-plugin/power-manager-button.h @@ -49,6 +49,9 @@ typedef struct { GtkToggleButtonClass parent_class; + /*< Signals >*/ + void (*tooltip_changed) (PowerManagerButton *button); + void (*icon_name_changed)(PowerManagerButton *button); } PowerManagerButtonClass; GType power_manager_button_get_type (void) G_GNUC_CONST; @@ -59,11 +62,19 @@ GtkWidget *power_manager_button_new (XfcePanelPlugin *plugin #ifdef LXDE_PLUGIN GtkWidget *power_manager_button_new (void); #endif +#ifdef XFPM_SYSTRAY +GtkWidget *power_manager_button_new (void); +#endif void power_manager_button_show (PowerManagerButton *button); void power_manager_button_set_width (PowerManagerButton *button, gint width); +void power_manager_button_show_menu (PowerManagerButton *button); + +const gchar *power_manager_button_get_icon_name (PowerManagerButton *button); +const gchar *power_manager_button_get_tooltip (PowerManagerButton *button); + G_END_DECLS #endif /* __POWER_MANAGER_BUTTON_H */ diff --git a/settings/xfpm-settings.c b/settings/xfpm-settings.c index 4f0eb1b..aab02e0 100644 --- a/settings/xfpm-settings.c +++ b/settings/xfpm-settings.c @@ -126,6 +126,8 @@ void button_hibernate_changed_cb (GtkWidget *w, void notify_toggled_cb (GtkWidget *w, XfconfChannel *channel); +void systray_toggled_cb (GtkWidget *w, + XfconfChannel *channel); void on_sleep_mode_changed_cb (GtkWidget *w, XfconfChannel *channel); @@ -362,6 +364,18 @@ notify_toggled_cb (GtkWidget *w, XfconfChannel *channel) } void +systray_toggled_cb (GtkWidget *w, XfconfChannel *channel) +{ + gboolean val = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w)); + + if (!xfconf_channel_set_int (channel, PROPERTIES_PREFIX SHOW_TRAY_ICON_CFG, (int)val) ) + { + g_critical ("Cannot set value for property %s\n", SHOW_TRAY_ICON_CFG); + } +} + + +void on_ac_sleep_mode_changed_cb (GtkWidget *w, XfconfChannel *channel) { GtkTreeModel *model; @@ -1265,11 +1279,13 @@ xfpm_settings_general (XfconfChannel *channel, gboolean auth_suspend, GtkWidget *sleep_w; GtkWidget *sleep_label; GtkWidget *notify; + GtkWidget *systray; guint value; guint list_value; gboolean valid; gboolean val; + gint systray_val; GtkWidget *dpms; GtkListStore *list_store; @@ -1450,6 +1466,12 @@ xfpm_settings_general (XfconfChannel *channel, gboolean auth_suspend, val = xfconf_channel_get_bool (channel, PROPERTIES_PREFIX GENERAL_NOTIFICATION_CFG, TRUE); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(notify), val); + + /* Enable/Disable systray icon */ + systray = GTK_WIDGET (gtk_builder_get_object (xml, "show-systray")); + systray_val = xfconf_channel_get_int (channel, PROPERTIES_PREFIX SHOW_TRAY_ICON_CFG, FALSE); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(systray), systray_val); } static void diff --git a/src/Makefile.am b/src/Makefile.am index 6ac0b06..25c9429 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -36,7 +36,11 @@ xfce4_power_manager_SOURCES = \ xfpm-errors.c \ xfpm-errors.h \ xfpm-suspend.c \ - xfpm-suspend.h + xfpm-suspend.h \ + ../panel-plugins/power-manager-plugin/power-manager-button.c \ + ../panel-plugins/power-manager-plugin/power-manager-button.h \ + ../panel-plugins/power-manager-plugin/scalemenuitem.c \ + ../panel-plugins/power-manager-plugin/scalemenuitem.h xfce4_power_manager_CFLAGS = \ -I$(top_srcdir) \ @@ -48,6 +52,7 @@ xfce4_power_manager_CFLAGS = \ -DSBINDIR=\"$(sbindir)\" \ -DUPOWER_ENABLE_DEPRECATED \ -DXFPM_SUSPEND_HELPER_CMD=\"$(prefix)/bin/xfce4-pm-helper\" \ + -DXFPM_SYSTRAY \ $(GOBJECT_CFLAGS) \ $(GTHREAD_CFLAGS) \ $(DBUS_GLIB_CFLAGS) \ diff --git a/src/xfpm-manager.c b/src/xfpm-manager.c index 9549b66..d0d62eb 100644 --- a/src/xfpm-manager.c +++ b/src/xfpm-manager.c @@ -62,15 +62,26 @@ #include "xfpm-enum-types.h" #include "xfpm-dbus-monitor.h" #include "xfpm-systemd.h" - +#include "../panel-plugins/power-manager-plugin/power-manager-button.h" static void xfpm_manager_finalize (GObject *object); +static void xfpm_manager_set_property(GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void xfpm_manager_get_property(GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); static void xfpm_manager_dbus_class_init (XfpmManagerClass *klass); static void xfpm_manager_dbus_init (XfpmManager *manager); static gboolean xfpm_manager_quit (XfpmManager *manager); +static void xfpm_manager_show_tray_icon (XfpmManager *manager); +static void xfpm_manager_hide_tray_icon (XfpmManager *manager); + #define XFPM_MANAGER_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE((o), XFPM_TYPE_MANAGER, XfpmManagerPrivate)) @@ -93,6 +104,9 @@ struct XfpmManagerPrivate XfpmDBusMonitor *monitor; XfpmInhibit *inhibit; EggIdletime *idle; + GtkStatusIcon *adapter_icon; + GtkWidget *power_button; + gint show_tray_icon; XfpmDpms *dpms; @@ -104,6 +118,12 @@ struct XfpmManagerPrivate gint inhibit_fd; }; +enum +{ + PROP_0 = 0, + PROP_SHOW_TRAY_ICON +}; + G_DEFINE_TYPE (XfpmManager, xfpm_manager, G_TYPE_OBJECT) static void @@ -112,8 +132,24 @@ xfpm_manager_class_init (XfpmManagerClass *klass) GObjectClass *object_class = G_OBJECT_CLASS(klass); object_class->finalize = xfpm_manager_finalize; + object_class->set_property = xfpm_manager_set_property; + object_class->get_property = xfpm_manager_get_property; g_type_class_add_private (klass, sizeof (XfpmManagerPrivate)); + +#define XFPM_PARAM_FLAGS (G_PARAM_READWRITE \ + | G_PARAM_CONSTRUCT \ + | G_PARAM_STATIC_NAME \ + | G_PARAM_STATIC_NICK \ + | G_PARAM_STATIC_BLURB) + + g_object_class_install_property(object_class, PROP_SHOW_TRAY_ICON, + g_param_spec_int(SHOW_TRAY_ICON_CFG, + SHOW_TRAY_ICON_CFG, + SHOW_TRAY_ICON_CFG, + 0, 5, 0, + XFPM_PARAM_FLAGS)); +#undef XFPM_PARAM_FLAGS } static void @@ -163,6 +199,57 @@ xfpm_manager_finalize (GObject *object) } static void +xfpm_manager_set_property(GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + XfpmManager *manager = XFPM_MANAGER(object); + gint new_value; + + switch(property_id) { + case PROP_SHOW_TRAY_ICON: + new_value = g_value_get_int (value); + if (new_value != manager->priv->show_tray_icon) + { + manager->priv->show_tray_icon = new_value; + if (new_value > 0) + { + xfpm_manager_show_tray_icon (manager); + } + else + { + xfpm_manager_hide_tray_icon (manager); + } + } + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void +xfpm_manager_get_property(GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + XfpmManager *manager = XFPM_MANAGER(object); + + switch(property_id) { + case PROP_SHOW_TRAY_ICON: + g_value_set_int (value, manager->priv->show_tray_icon); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void xfpm_manager_release_names (XfpmManager *manager) { xfpm_dbus_release_name (dbus_g_connection_get_connection(manager->priv->session_bus), @@ -617,6 +704,87 @@ xfpm_manager_systemd_events_changed (XfpmManager *manager) manager->priv->inhibit_fd = xfpm_manager_inhibit_sleep_systemd (manager); } +static void +xfpm_manager_tray_update_tooltip (PowerManagerButton *button, XfpmManager *manager) +{ + g_return_if_fail (XFPM_IS_MANAGER (manager)); + g_return_if_fail (POWER_MANAGER_IS_BUTTON (manager->priv->power_button)); + g_return_if_fail (GTK_IS_STATUS_ICON (manager->priv->adapter_icon)); + + XFPM_DEBUG ("updating tooltip"); + + if (power_manager_button_get_tooltip (POWER_MANAGER_BUTTON(manager->priv->power_button)) == NULL) + return; + + gtk_status_icon_set_tooltip_markup (manager->priv->adapter_icon, power_manager_button_get_tooltip (POWER_MANAGER_BUTTON(manager->priv->power_button))); +} + +static void +xfpm_manager_tray_update_icon (PowerManagerButton *button, XfpmManager *manager) +{ + g_return_if_fail (XFPM_IS_MANAGER (manager)); + g_return_if_fail (POWER_MANAGER_IS_BUTTON (manager->priv->power_button)); + + XFPM_DEBUG ("updating icon"); + + gtk_status_icon_set_from_icon_name (manager->priv->adapter_icon, power_manager_button_get_icon_name (POWER_MANAGER_BUTTON(manager->priv->power_button))); +} + +static void +xfpm_manager_show_tray_menu (GtkStatusIcon *icon, guint button, guint activate_time, XfpmManager *manager) +{ + power_manager_button_show_menu (POWER_MANAGER_BUTTON(manager->priv->power_button)); +} + +static void +xfpm_manager_show_tray_icon (XfpmManager *manager) +{ + if (manager->priv->adapter_icon != NULL) { + XFPM_DEBUG ("tray icon already being shown"); + return; + } + + manager->priv->adapter_icon = gtk_status_icon_new (); + manager->priv->power_button = power_manager_button_new (); + + XFPM_DEBUG ("Showing tray icon"); + + /* send a show event to startup the button */ + power_manager_button_show (POWER_MANAGER_BUTTON(manager->priv->power_button)); + + /* initial update the tray icon + tooltip */ + xfpm_manager_tray_update_icon (POWER_MANAGER_BUTTON(manager->priv->power_button), manager); + xfpm_manager_tray_update_tooltip (POWER_MANAGER_BUTTON(manager->priv->power_button), manager); + + /* Listen to the tooltip and icon changes */ + g_signal_connect (G_OBJECT(manager->priv->power_button), "tooltip-changed", G_CALLBACK(xfpm_manager_tray_update_tooltip), manager); + g_signal_connect (G_OBJECT(manager->priv->power_button), "icon-name-changed", G_CALLBACK(xfpm_manager_tray_update_icon), manager); + + gtk_status_icon_set_visible (manager->priv->adapter_icon, TRUE); + + g_signal_connect (manager->priv->adapter_icon, "popup-menu", G_CALLBACK (xfpm_manager_show_tray_menu), manager); +} + +static void +xfpm_manager_hide_tray_icon (XfpmManager *manager) +{ + if (manager->priv->adapter_icon == NULL) + return; + + gtk_status_icon_set_visible (manager->priv->adapter_icon, FALSE); + + /* disconnect from all the signals */ + g_signal_handlers_disconnect_by_func (G_OBJECT(manager->priv->power_button), G_CALLBACK(xfpm_manager_tray_update_tooltip), manager); + g_signal_handlers_disconnect_by_func (G_OBJECT(manager->priv->power_button), G_CALLBACK(xfpm_manager_tray_update_icon), manager); + g_signal_handlers_disconnect_by_func (G_OBJECT(manager->priv->adapter_icon), G_CALLBACK(xfpm_manager_show_tray_menu), manager); + + g_object_unref (manager->priv->power_button); + g_object_unref (manager->priv->adapter_icon); + + manager->priv->power_button = NULL; + manager->priv->adapter_icon = NULL; +} + XfpmManager * xfpm_manager_new (DBusGConnection *bus, const gchar *client_id) { @@ -757,6 +925,11 @@ void xfpm_manager_start (XfpmManager *manager) g_signal_connect_swapped (manager->priv->power, "shutdown", G_CALLBACK (xfpm_manager_shutdown), manager); + xfconf_g_property_bind(xfpm_xfconf_get_channel (manager->priv->conf), + PROPERTIES_PREFIX SHOW_TRAY_ICON_CFG, + G_TYPE_INT, + G_OBJECT(manager), + SHOW_TRAY_ICON_CFG); out: ; } diff --git a/src/xfpm-power.c b/src/xfpm-power.c index b071da7..967aab4 100644 --- a/src/xfpm-power.c +++ b/src/xfpm-power.c @@ -63,7 +63,6 @@ #include "xfpm-suspend.h" #include "xfpm-brightness.h" - static void xfpm_power_finalize (GObject *object); static void xfpm_power_get_property (GObject *object, -- 2.3.0