diff options
author | Ryan Lortie <desrt@desrt.ca> | 2011-03-29 23:44:21 +0530 |
---|---|---|
committer | Ryan Lortie <desrt@desrt.ca> | 2011-03-30 00:26:27 +0530 |
commit | ae6032b2eae27c9e25b21584a6337c6e4a6114b0 (patch) | |
tree | 1f9fa42957501fde1b1609900461c3120d463160 | |
parent | ae22476931519c8f3846a3995da77b53ef90e38c (diff) | |
download | gtk+-ae6032b2eae27c9e25b21584a6337c6e4a6114b0.tar.gz |
GtkStatusIcon: support fixed-sized icons
Use the _NET_SYSTEM_TRAY_ICON_SIZE property set by the tray mananger as
a hint that we should use a specific icon size. This allows the tray to
instruct us that it expects 16x16 icons, for example.
Bug #645232
-rw-r--r-- | gtk/gtkstatusicon.c | 20 | ||||
-rw-r--r-- | gtk/gtktrayicon-x11.c | 86 | ||||
-rw-r--r-- | gtk/gtktrayicon.h | 1 |
3 files changed, 106 insertions, 1 deletions
diff --git a/gtk/gtkstatusicon.c b/gtk/gtkstatusicon.c index 79abc48bea..cd7e9f44b5 100644 --- a/gtk/gtkstatusicon.c +++ b/gtk/gtkstatusicon.c @@ -158,6 +158,7 @@ static void gtk_status_icon_screen_changed (GtkStatusIcon *status_icon, static void gtk_status_icon_embedded_changed (GtkStatusIcon *status_icon); static void gtk_status_icon_orientation_changed (GtkStatusIcon *status_icon); static void gtk_status_icon_padding_changed (GtkStatusIcon *status_icon); +static void gtk_status_icon_icon_size_changed(GtkStatusIcon *status_icon); static void gtk_status_icon_fg_changed (GtkStatusIcon *status_icon); static void gtk_status_icon_color_changed (GtkTrayIcon *tray, GParamSpec *pspec, @@ -840,6 +841,8 @@ gtk_status_icon_init (GtkStatusIcon *status_icon) G_CALLBACK (gtk_status_icon_orientation_changed), status_icon); g_signal_connect_swapped (priv->tray_icon, "notify::padding", G_CALLBACK (gtk_status_icon_padding_changed), status_icon); + g_signal_connect_swapped (priv->tray_icon, "notify::icon-size", + G_CALLBACK (gtk_status_icon_icon_size_changed), status_icon); g_signal_connect_swapped (priv->tray_icon, "notify::fg-color", G_CALLBACK (gtk_status_icon_fg_changed), status_icon); g_signal_connect (priv->tray_icon, "notify::error-color", @@ -986,6 +989,8 @@ gtk_status_icon_finalize (GObject *object) g_signal_handlers_disconnect_by_func (priv->tray_icon, gtk_status_icon_padding_changed, status_icon); g_signal_handlers_disconnect_by_func (priv->tray_icon, + gtk_status_icon_icon_size_changed, status_icon); + g_signal_handlers_disconnect_by_func (priv->tray_icon, gtk_status_icon_fg_changed, status_icon); g_signal_handlers_disconnect_by_func (priv->tray_icon, gtk_status_icon_color_changed, status_icon); @@ -1650,9 +1655,24 @@ gtk_status_icon_padding_changed (GtkStatusIcon *status_icon) } static void +gtk_status_icon_icon_size_changed (GtkStatusIcon *status_icon) +{ + GtkStatusIconPrivate *priv = status_icon->priv; + gint icon_size; + + icon_size = _gtk_tray_icon_get_icon_size (GTK_TRAY_ICON (priv->tray_icon)); + + if (icon_size != 0) + gtk_image_set_pixel_size (GTK_IMAGE (priv->image), icon_size); + else + gtk_image_set_pixel_size (GTK_IMAGE (priv->image), -1); +} + +static void gtk_status_icon_embedded_changed (GtkStatusIcon *status_icon) { gtk_status_icon_padding_changed (status_icon); + gtk_status_icon_icon_size_changed (status_icon); g_object_notify (G_OBJECT (status_icon), "embedded"); } diff --git a/gtk/gtktrayicon-x11.c b/gtk/gtktrayicon-x11.c index b491397f02..6535a65098 100644 --- a/gtk/gtktrayicon-x11.c +++ b/gtk/gtktrayicon-x11.c @@ -52,7 +52,8 @@ enum { PROP_ERROR_COLOR, PROP_WARNING_COLOR, PROP_SUCCESS_COLOR, - PROP_PADDING + PROP_PADDING, + PROP_ICON_SIZE }; struct _GtkTrayIconPrivate @@ -66,6 +67,7 @@ struct _GtkTrayIconPrivate Atom visual_atom; Atom colors_atom; Atom padding_atom; + Atom icon_size_atom; Window manager_window; GdkVisual *manager_visual; gboolean manager_visual_rgba; @@ -76,6 +78,7 @@ struct _GtkTrayIconPrivate GdkColor warning_color; GdkColor success_color; gint padding; + gint icon_size; }; static void gtk_tray_icon_constructed (GObject *object); @@ -170,6 +173,16 @@ gtk_tray_icon_class_init (GtkTrayIconClass *class) 0, GTK_PARAM_READABLE)); + g_object_class_install_property (gobject_class, + PROP_ICON_SIZE, + g_param_spec_int ("icon-size", + P_("Icon Size"), + P_("The pixel size that icons should be forced to, or zero"), + 0, + G_MAXINT, + 0, + GTK_PARAM_READABLE)); + g_type_class_add_private (class, sizeof (GtkTrayIconPrivate)); } @@ -194,6 +207,7 @@ gtk_tray_icon_init (GtkTrayIcon *icon) icon->priv->success_color.green = 0x9a00; icon->priv->success_color.blue = 0x0600; icon->priv->padding = 0; + icon->priv->icon_size = 0; gtk_widget_set_app_paintable (GTK_WIDGET (icon), TRUE); gtk_widget_add_events (GTK_WIDGET (icon), GDK_PROPERTY_CHANGE_MASK); @@ -239,6 +253,10 @@ gtk_tray_icon_constructed (GObject *object) "_NET_SYSTEM_TRAY_PADDING", False); + icon->priv->icon_size_atom = XInternAtom (xdisplay, + "_NET_SYSTEM_TRAY_ICON_SIZE", + False); + /* Add a root window filter so that we get changes on MANAGER */ gdk_window_add_filter (root_window, gtk_tray_icon_manager_filter, icon); @@ -307,6 +325,9 @@ gtk_tray_icon_get_property (GObject *object, case PROP_PADDING: g_value_set_int (value, icon->priv->padding); break; + case PROP_ICON_SIZE: + g_value_set_int (value, icon->priv->icon_size); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -635,6 +656,55 @@ gtk_tray_icon_get_padding_property (GtkTrayIcon *icon) XFree (prop.prop); } +static void +gtk_tray_icon_get_icon_size_property (GtkTrayIcon *icon) +{ + GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (icon)); + GdkDisplay *display = gdk_screen_get_display (screen); + Display *xdisplay = GDK_DISPLAY_XDISPLAY (display); + + Atom type; + int format; + union { + gulong *prop; + guchar *prop_ch; + } prop = { NULL }; + gulong nitems; + gulong bytes_after; + int error, result; + + g_assert (icon->priv->manager_window != None); + + gdk_error_trap_push (); + type = None; + result = XGetWindowProperty (xdisplay, + icon->priv->manager_window, + icon->priv->icon_size_atom, + 0, G_MAXLONG, FALSE, + XA_CARDINAL, + &type, &format, &nitems, + &bytes_after, &(prop.prop_ch)); + error = gdk_error_trap_pop (); + + if (!error && result == Success && + type == XA_CARDINAL && nitems == 1 && format == 32) + { + gint icon_size; + + icon_size = prop.prop[0]; + + if (icon->priv->icon_size != icon_size) + { + icon->priv->icon_size = icon_size; + + g_object_notify (G_OBJECT (icon), "icon-size"); + } + } + + if (type != None) + XFree (prop.prop); +} + static GdkFilterReturn gtk_tray_icon_manager_filter (GdkXEvent *xevent, GdkEvent *event, @@ -675,6 +745,11 @@ gtk_tray_icon_manager_filter (GdkXEvent *xevent, { gtk_tray_icon_get_padding_property (icon); } + else if (xev->xany.type == PropertyNotify && + xev->xproperty.atom == icon->priv->icon_size_atom) + { + gtk_tray_icon_get_icon_size_property (icon); + } else if (xev->xany.type == DestroyNotify) { GTK_NOTE (PLUGSOCKET, @@ -784,6 +859,7 @@ gtk_tray_icon_update_manager_window (GtkTrayIcon *icon) gtk_tray_icon_get_visual_property (icon); gtk_tray_icon_get_colors_property (icon); gtk_tray_icon_get_padding_property (icon); + gtk_tray_icon_get_icon_size_property (icon); if (gtk_widget_get_realized (GTK_WIDGET (icon))) { @@ -1015,3 +1091,11 @@ _gtk_tray_icon_get_padding (GtkTrayIcon *icon) return icon->priv->padding; } + +gint +_gtk_tray_icon_get_icon_size (GtkTrayIcon *icon) +{ + g_return_val_if_fail (GTK_IS_TRAY_ICON (icon), 0); + + return icon->priv->icon_size; +} diff --git a/gtk/gtktrayicon.h b/gtk/gtktrayicon.h index a990babf4d..4f21cb523e 100644 --- a/gtk/gtktrayicon.h +++ b/gtk/gtktrayicon.h @@ -69,6 +69,7 @@ void _gtk_tray_icon_cancel_message (GtkTrayIcon *icon, GtkOrientation _gtk_tray_icon_get_orientation (GtkTrayIcon *icon); gint _gtk_tray_icon_get_padding (GtkTrayIcon *icon); +gint _gtk_tray_icon_get_icon_size (GtkTrayIcon *icon); G_END_DECLS |