X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtktrayicon-x11.c;h=8295161d7758e11fce46bb9e8e4a9710c07302f5;hb=1074aa0c49f647ed4b2a969618051c59da5aad01;hp=a8f6a1191372b069ecdf1117ba4732d44fbc18f4;hpb=920e8b434367f9aa8aab306721cc024e66892e2e;p=~andy%2Fgtk diff --git a/gtk/gtktrayicon-x11.c b/gtk/gtktrayicon-x11.c index a8f6a1191..8295161d7 100644 --- a/gtk/gtktrayicon-x11.c +++ b/gtk/gtktrayicon-x11.c @@ -12,9 +12,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ /* @@ -52,7 +50,8 @@ enum { PROP_ERROR_COLOR, PROP_WARNING_COLOR, PROP_SUCCESS_COLOR, - PROP_PADDING + PROP_PADDING, + PROP_ICON_SIZE }; struct _GtkTrayIconPrivate @@ -66,16 +65,18 @@ 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; GtkOrientation orientation; - GdkColor fg_color; - GdkColor error_color; - GdkColor warning_color; - GdkColor success_color; + GdkRGBA fg_color; + GdkRGBA error_color; + GdkRGBA warning_color; + GdkRGBA success_color; gint padding; + gint icon_size; }; static void gtk_tray_icon_constructed (GObject *object); @@ -133,7 +134,7 @@ gtk_tray_icon_class_init (GtkTrayIconClass *class) g_param_spec_boxed ("fg-color", P_("Foreground color"), P_("Foreground color for symbolic icons"), - GDK_TYPE_COLOR, + GDK_TYPE_RGBA, GTK_PARAM_READABLE)); g_object_class_install_property (gobject_class, @@ -141,7 +142,7 @@ gtk_tray_icon_class_init (GtkTrayIconClass *class) g_param_spec_boxed ("error-color", P_("Error color"), P_("Error color for symbolic icons"), - GDK_TYPE_COLOR, + GDK_TYPE_RGBA, GTK_PARAM_READABLE)); g_object_class_install_property (gobject_class, @@ -149,7 +150,7 @@ gtk_tray_icon_class_init (GtkTrayIconClass *class) g_param_spec_boxed ("warning-color", P_("Warning color"), P_("Warning color for symbolic icons"), - GDK_TYPE_COLOR, + GDK_TYPE_RGBA, GTK_PARAM_READABLE)); g_object_class_install_property (gobject_class, @@ -157,7 +158,7 @@ gtk_tray_icon_class_init (GtkTrayIconClass *class) g_param_spec_boxed ("success-color", P_("Success color"), P_("Success color for symbolic icons"), - GDK_TYPE_COLOR, + GDK_TYPE_RGBA, GTK_PARAM_READABLE)); g_object_class_install_property (gobject_class, @@ -170,6 +171,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)); } @@ -181,19 +192,24 @@ gtk_tray_icon_init (GtkTrayIcon *icon) icon->priv->stamp = 1; icon->priv->orientation = GTK_ORIENTATION_HORIZONTAL; - icon->priv->fg_color.red = 0x0000; - icon->priv->fg_color.green = 0x0000; - icon->priv->fg_color.blue = 0x0000; - icon->priv->error_color.red = 0xcc00; - icon->priv->error_color.green = 0x0000; - icon->priv->error_color.blue = 0x0000; - icon->priv->warning_color.red = 0xf500; - icon->priv->warning_color.green = 0x7900; - icon->priv->warning_color.blue = 0x3e00; - icon->priv->success_color.red = 0x4e00; - icon->priv->success_color.green = 0x9a00; - icon->priv->success_color.blue = 0x0600; + icon->priv->fg_color.red = 0.0; + icon->priv->fg_color.green = 0.0; + icon->priv->fg_color.blue = 0.0; + icon->priv->fg_color.alpha = 1.0; + icon->priv->error_color.red = 0.7968; + icon->priv->error_color.green = 0.0; + icon->priv->error_color.blue = 0.0; + icon->priv->error_color.alpha = 1.0; + icon->priv->warning_color.red = 0.9570; + icon->priv->warning_color.green = 0.4726; + icon->priv->warning_color.blue = 0.2421; + icon->priv->warning_color.alpha = 1.0; + icon->priv->success_color.red = 0.3047; + icon->priv->success_color.green = 0.6016; + icon->priv->success_color.blue = 0.0234; + icon->priv->success_color.alpha = 1.0; 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 +255,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); @@ -275,6 +295,8 @@ gtk_tray_icon_dispose (GObject *object) gtk_tray_icon_clear_manager_window (icon); gdk_window_remove_filter (root_window, gtk_tray_icon_manager_filter, icon); + + G_OBJECT_CLASS (gtk_tray_icon_parent_class)->dispose (object); } static void @@ -305,6 +327,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; @@ -360,23 +385,16 @@ gtk_tray_icon_draw (GtkWidget *widget, retval = GTK_WIDGET_CLASS (gtk_tray_icon_parent_class)->draw (widget, cr); focus_child = gtk_container_get_focus_child (GTK_CONTAINER (widget)); - if (focus_child && gtk_widget_has_focus (focus_child)) + if (focus_child && gtk_widget_has_visible_focus (focus_child)) { GtkStyleContext *context; - GtkStateFlags state; border_width = gtk_container_get_border_width (GTK_CONTAINER (widget)); context = gtk_widget_get_style_context (widget); - state = gtk_widget_get_state_flags (widget); - - gtk_style_context_save (context); - gtk_style_context_set_state (context, state); gtk_render_focus (context, cr, border_width, border_width, gtk_widget_get_allocated_width (widget) - 2 * border_width, gtk_widget_get_allocated_height (widget) - 2 * border_width); - - gtk_style_context_restore (context); } return retval; @@ -451,10 +469,6 @@ gtk_tray_icon_get_visual_property (GtkTrayIcon *icon) gulong nitems; gulong bytes_after; int error, result; - GdkVisual *visual; - gint red_prec; - gint green_prec; - gint blue_prec; g_assert (icon->priv->manager_window != None); @@ -469,25 +483,31 @@ gtk_tray_icon_get_visual_property (GtkTrayIcon *icon) &bytes_after, &(prop.prop_ch)); error = gdk_error_trap_pop (); - visual = NULL; - if (!error && result == Success && type == XA_VISUALID && nitems == 1 && format == 32) { - VisualID visual_id = prop.prop[0]; + VisualID visual_id; + GdkVisual *visual; + gint red_prec, green_prec, blue_prec; + + visual_id = prop.prop[0]; visual = gdk_x11_screen_lookup_visual (screen, visual_id); + gdk_visual_get_red_pixel_details (visual, NULL, NULL, &red_prec); + gdk_visual_get_green_pixel_details (visual, NULL, NULL, &green_prec); + gdk_visual_get_blue_pixel_details (visual, NULL, NULL, &blue_prec); + icon->priv->manager_visual = visual; + icon->priv->manager_visual_rgba = + (red_prec + blue_prec + green_prec < gdk_visual_get_depth (visual)); + } + else + { + icon->priv->manager_visual = NULL; + icon->priv->manager_visual_rgba = FALSE; } - gdk_visual_get_red_pixel_details (visual, NULL, NULL, &red_prec); - gdk_visual_get_green_pixel_details (visual, NULL, NULL, &green_prec); - gdk_visual_get_blue_pixel_details (visual, NULL, NULL, &blue_prec); - - icon->priv->manager_visual = visual; - icon->priv->manager_visual_rgba = visual != NULL && - (red_prec + blue_prec + green_prec < gdk_visual_get_depth (visual)); - - /* For the background-relative hack we use when we aren't using a real RGBA - * visual, we can't be double-buffered */ + /* For the background-relative hack we use when we aren't + * using a real RGBA visual, we can't be double-buffered + */ gtk_widget_set_double_buffered (GTK_WIDGET (icon), icon->priv->manager_visual_rgba); if (type != None) @@ -529,52 +549,48 @@ gtk_tray_icon_get_colors_property (GtkTrayIcon *icon) if (type == XA_CARDINAL && nitems == 12 && format == 32) { - GdkColor color; + GdkRGBA color; g_object_freeze_notify (G_OBJECT (icon)); - color.red = prop.prop[0]; - color.green = prop.prop[1]; - color.blue = prop.prop[2]; + color.red = prop.prop[0] / 65535.0; + color.green = prop.prop[1] / 65535.0; + color.blue = prop.prop[2] / 65535.0; - if (!gdk_color_equal (&icon->priv->fg_color, &color)) + if (!gdk_rgba_equal (&icon->priv->fg_color, &color)) { icon->priv->fg_color = color; g_object_notify (G_OBJECT (icon), "fg-color"); } - color.red = prop.prop[3]; - color.green = prop.prop[4]; - color.blue = prop.prop[5]; + color.red = prop.prop[3] / 65535.0; + color.green = prop.prop[4] / 65535.0; + color.blue = prop.prop[5] / 65535.0; - if (!gdk_color_equal (&icon->priv->error_color, &color)) + if (!gdk_rgba_equal (&icon->priv->error_color, &color)) { icon->priv->error_color = color; g_object_notify (G_OBJECT (icon), "error-color"); } - g_object_thaw_notify (G_OBJECT (icon)); + color.red = prop.prop[6] / 65535.0; + color.green = prop.prop[7] / 65535.0; + color.blue = prop.prop[8] / 65535.0; - color.red = prop.prop[6]; - color.green = prop.prop[7]; - color.blue = prop.prop[8]; - - if (!gdk_color_equal (&icon->priv->warning_color, &color)) + if (!gdk_rgba_equal (&icon->priv->warning_color, &color)) { icon->priv->warning_color = color; g_object_notify (G_OBJECT (icon), "warning-color"); } - g_object_thaw_notify (G_OBJECT (icon)); - - color.red = prop.prop[9]; - color.green = prop.prop[10]; - color.blue = prop.prop[11]; + color.red = prop.prop[9] / 65535.0; + color.green = prop.prop[10] / 65535.0; + color.blue = prop.prop[11] / 65535.0; - if (!gdk_color_equal (&icon->priv->success_color, &color)) + if (!gdk_rgba_equal (&icon->priv->success_color, &color)) { icon->priv->success_color = color; @@ -637,6 +653,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, @@ -677,6 +742,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, @@ -685,8 +755,10 @@ gtk_tray_icon_manager_filter (GdkXEvent *xevent, gtk_tray_icon_manager_window_destroyed (icon); } else - GTK_NOTE (PLUGSOCKET, - g_print ("GtkStatusIcon %p: got other message on manager window\n", icon)); + { + GTK_NOTE (PLUGSOCKET, + g_print ("GtkStatusIcon %p: got other message on manager window\n", icon)); + } } return GDK_FILTER_CONTINUE; @@ -786,6 +858,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))) { @@ -808,8 +881,10 @@ gtk_tray_icon_update_manager_window (GtkTrayIcon *icon) } } else - GTK_NOTE (PLUGSOCKET, - g_print ("GtkStatusIcon %p: no tray manager found\n", icon)); + { + GTK_NOTE (PLUGSOCKET, + g_print ("GtkStatusIcon %p: no tray manager found\n", icon)); + } } static void @@ -881,8 +956,8 @@ gtk_tray_icon_realize (GtkWidget *widget) if (icon->priv->manager_visual_rgba) { /* Set a transparent background */ - GdkColor transparent = { 0, 0, 0, 0 }; /* Only pixel=0 matters */ - gdk_window_set_background (window, &transparent); + GdkRGBA transparent = { 0.0, 0.0, 0.0, 0.0 }; + gdk_window_set_background_rgba (window, &transparent); } else { @@ -1017,3 +1092,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; +}