From dd9a3179e446e13f713448c837bd633efd72562e Mon Sep 17 00:00:00 2001 From: Eric Koegel Date: Mon, 16 Feb 2015 17:58:42 +0300 Subject: [PATCH] Bring back the tray icon (Bug #11054) This patch uses the PowerManagerButton to implement the tray icon. The option currently isn't shown in the settings dialog, but everything else is in place. The xfconf property is: /xfce4-power-manager/show-tray-icon a value of 1 enables it, 0 disables it. 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. --- .../power-manager-plugin/power-manager-button.c | 66 +++++++- .../power-manager-plugin/power-manager-button.h | 11 ++ src/Makefile.am | 7 +- src/xfpm-manager.c | 175 ++++++++++++++++++++- src/xfpm-power.c | 1 - 5 files changed, 253 insertions(+), 7 deletions(-) diff --git a/panel-plugins/power-manager-plugin/power-manager-button.c b/panel-plugins/power-manager-plugin/power-manager-button.c index e02a780..50f1ef8 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); @@ -714,6 +735,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 \ @@ -771,6 +810,8 @@ power_manager_button_finalize (GObject *object) { PowerManagerButton *button; + DBG("entering"); + button = POWER_MANAGER_BUTTON (object); g_free(button->priv->panel_icon_name); @@ -797,6 +838,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); @@ -828,6 +872,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; } @@ -835,6 +881,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) { @@ -1156,7 +1214,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/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..3cf47d7 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 07085ff..f3fff52 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