Get symbolic colors for statusicons from systray
Uses the X property _NET_SYSTEM_TRAY_COLORS.
This commit is contained in:
		| @ -170,6 +170,10 @@ static void     gtk_status_icon_screen_changed   (GtkStatusIcon  *status_icon, | ||||
| 						  GdkScreen      *old_screen); | ||||
| 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_fg_changed       (GtkStatusIcon *status_icon); | ||||
| static void     gtk_status_icon_color_changed    (GtkTrayIcon   *tray, | ||||
|                                                   GParamSpec    *pspec, | ||||
|                                                   GtkStatusIcon *status_icon); | ||||
| static gboolean gtk_status_icon_scroll           (GtkStatusIcon  *status_icon, | ||||
| 						  GdkEventScroll *event); | ||||
| static gboolean gtk_status_icon_query_tooltip    (GtkStatusIcon *status_icon, | ||||
| @ -827,7 +831,7 @@ gtk_status_icon_init (GtkStatusIcon *status_icon) | ||||
|   priv = G_TYPE_INSTANCE_GET_PRIVATE (status_icon, GTK_TYPE_STATUS_ICON, | ||||
| 				      GtkStatusIconPrivate); | ||||
|   status_icon->priv = priv; | ||||
|    | ||||
|  | ||||
|   priv->storage_type = GTK_IMAGE_EMPTY; | ||||
|   priv->visible      = TRUE; | ||||
|  | ||||
| @ -850,6 +854,14 @@ gtk_status_icon_init (GtkStatusIcon *status_icon) | ||||
| 			    G_CALLBACK (gtk_status_icon_embedded_changed), status_icon); | ||||
|   g_signal_connect_swapped (priv->tray_icon, "notify::orientation", | ||||
| 			    G_CALLBACK (gtk_status_icon_orientation_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", | ||||
|                     G_CALLBACK (gtk_status_icon_color_changed), status_icon); | ||||
|   g_signal_connect (priv->tray_icon, "notify::warning-color", | ||||
|                     G_CALLBACK (gtk_status_icon_color_changed), status_icon); | ||||
|   g_signal_connect (priv->tray_icon, "notify::success-color", | ||||
|                     G_CALLBACK (gtk_status_icon_color_changed), status_icon); | ||||
|   g_signal_connect_swapped (priv->tray_icon, "button-press-event", | ||||
| 			    G_CALLBACK (gtk_status_icon_button_press), status_icon); | ||||
|   g_signal_connect_swapped (priv->tray_icon, "button-release-event", | ||||
| @ -974,6 +986,10 @@ gtk_status_icon_finalize (GObject *object) | ||||
| 			                gtk_status_icon_embedded_changed, status_icon); | ||||
|   g_signal_handlers_disconnect_by_func (priv->tray_icon, | ||||
| 			                gtk_status_icon_orientation_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); | ||||
|   g_signal_handlers_disconnect_by_func (priv->tray_icon, | ||||
| 			                gtk_status_icon_button_press, status_icon); | ||||
|   g_signal_handlers_disconnect_by_func (priv->tray_icon, | ||||
| @ -1690,6 +1706,48 @@ gtk_status_icon_orientation_changed (GtkStatusIcon *status_icon) | ||||
|   g_object_notify (G_OBJECT (status_icon), "orientation"); | ||||
| } | ||||
|  | ||||
| static void | ||||
| gtk_status_icon_fg_changed (GtkStatusIcon *status_icon) | ||||
| { | ||||
|   GtkStatusIconPrivate *priv = status_icon->priv; | ||||
|   GdkColor color; | ||||
|  | ||||
|   g_object_get (priv->tray_icon, "fg-color", &color, NULL); | ||||
|   gtk_widget_modify_fg (priv->image, GTK_STATE_NORMAL, &color); | ||||
| } | ||||
|  | ||||
| static void | ||||
| gtk_status_icon_color_changed (GtkTrayIcon   *tray, | ||||
|                                GParamSpec    *pspec, | ||||
|                                GtkStatusIcon *status_icon) | ||||
| { | ||||
|   GtkStatusIconPrivate *priv = status_icon->priv; | ||||
|   const gchar *name; | ||||
|   GdkColor color; | ||||
|  | ||||
|   switch (pspec->name[0]) | ||||
|     { | ||||
|     case 'e': | ||||
|       name = "error"; | ||||
|       break; | ||||
|     case 'w': | ||||
|       name = "warning"; | ||||
|       break; | ||||
|     case 's': | ||||
|       name = "success"; | ||||
|       break; | ||||
|     default: | ||||
|       name = NULL; | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|   if (name) | ||||
|     { | ||||
|       g_object_get (priv->tray_icon, pspec->name, &color, NULL); | ||||
|       gtk_widget_modify_symbolic_color (priv->image, name, &color); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| gtk_status_icon_key_press (GtkStatusIcon  *status_icon, | ||||
| 			   GdkEventKey    *event) | ||||
|  | ||||
| @ -43,7 +43,11 @@ | ||||
|  | ||||
| enum { | ||||
|   PROP_0, | ||||
|   PROP_ORIENTATION | ||||
|   PROP_ORIENTATION, | ||||
|   PROP_FG_COLOR, | ||||
|   PROP_ERROR_COLOR, | ||||
|   PROP_WARNING_COLOR, | ||||
|   PROP_SUCCESS_COLOR | ||||
| }; | ||||
|  | ||||
| struct _GtkTrayIconPrivate | ||||
| @ -55,11 +59,16 @@ struct _GtkTrayIconPrivate | ||||
|   Atom system_tray_opcode_atom; | ||||
|   Atom orientation_atom; | ||||
|   Atom visual_atom; | ||||
|   Atom colors_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; | ||||
| }; | ||||
|  | ||||
| static void gtk_tray_icon_constructed   (GObject     *object); | ||||
| @ -75,7 +84,7 @@ static void     gtk_tray_icon_style_set (GtkWidget   *widget, | ||||
| 					 GtkStyle    *previous_style); | ||||
| static gboolean gtk_tray_icon_delete    (GtkWidget   *widget, | ||||
| 					 GdkEventAny *event); | ||||
| static gboolean gtk_tray_icon_expose    (GtkWidget      *widget,  | ||||
| static gboolean gtk_tray_icon_expose    (GtkWidget      *widget, | ||||
| 					 GdkEventExpose *event); | ||||
|  | ||||
| static void gtk_tray_icon_clear_manager_window     (GtkTrayIcon *icon); | ||||
| @ -113,6 +122,38 @@ gtk_tray_icon_class_init (GtkTrayIconClass *class) | ||||
| 						      GTK_ORIENTATION_HORIZONTAL, | ||||
| 						      GTK_PARAM_READABLE)); | ||||
|  | ||||
|   g_object_class_install_property (gobject_class, | ||||
|                                    PROP_FG_COLOR, | ||||
|                                    g_param_spec_boxed ("fg-color", | ||||
|                                                        P_("Foreground color"), | ||||
|                                                        P_("Foreground color for symbolic icons"), | ||||
|                                                        GDK_TYPE_COLOR, | ||||
|                                                        GTK_PARAM_READABLE)); | ||||
|  | ||||
|   g_object_class_install_property (gobject_class, | ||||
|                                    PROP_ERROR_COLOR, | ||||
|                                    g_param_spec_boxed ("error-color", | ||||
|                                                        P_("Error color"), | ||||
|                                                        P_("Error color for symbolic icons"), | ||||
|                                                        GDK_TYPE_COLOR, | ||||
|                                                        GTK_PARAM_READABLE)); | ||||
|  | ||||
|   g_object_class_install_property (gobject_class, | ||||
|                                    PROP_WARNING_COLOR, | ||||
|                                    g_param_spec_boxed ("warning-color", | ||||
|                                                        P_("Warning color"), | ||||
|                                                        P_("Warning color for symbolic icons"), | ||||
|                                                        GDK_TYPE_COLOR, | ||||
|                                                        GTK_PARAM_READABLE)); | ||||
|  | ||||
|   g_object_class_install_property (gobject_class, | ||||
|                                    PROP_SUCCESS_COLOR, | ||||
|                                    g_param_spec_boxed ("success-color", | ||||
|                                                        P_("Success color"), | ||||
|                                                        P_("Success color for symbolic icons"), | ||||
|                                                        GDK_TYPE_COLOR, | ||||
|                                                        GTK_PARAM_READABLE)); | ||||
|  | ||||
|   g_type_class_add_private (class, sizeof (GtkTrayIconPrivate)); | ||||
| } | ||||
|  | ||||
| @ -121,9 +162,21 @@ gtk_tray_icon_init (GtkTrayIcon *icon) | ||||
| { | ||||
|   icon->priv = G_TYPE_INSTANCE_GET_PRIVATE (icon, GTK_TYPE_TRAY_ICON, | ||||
| 					    GtkTrayIconPrivate); | ||||
|    | ||||
|  | ||||
|   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; | ||||
|  | ||||
|   gtk_widget_set_app_paintable (GTK_WIDGET (icon), TRUE); | ||||
|   gtk_widget_add_events (GTK_WIDGET (icon), GDK_PROPERTY_CHANGE_MASK); | ||||
| @ -161,6 +214,10 @@ gtk_tray_icon_constructed (GObject *object) | ||||
| 					 "_NET_SYSTEM_TRAY_VISUAL", | ||||
| 					 False); | ||||
|  | ||||
|   icon->priv->colors_atom = XInternAtom (xdisplay, | ||||
|                                          "_NET_SYSTEM_TRAY_COLORS", | ||||
|                                          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); | ||||
| @ -212,6 +269,18 @@ gtk_tray_icon_get_property (GObject    *object, | ||||
|     case PROP_ORIENTATION: | ||||
|       g_value_set_enum (value, icon->priv->orientation); | ||||
|       break; | ||||
|     case PROP_FG_COLOR: | ||||
|       g_value_set_boxed (value, &icon->priv->fg_color); | ||||
|       break; | ||||
|     case PROP_ERROR_COLOR: | ||||
|       g_value_set_boxed (value, &icon->priv->error_color); | ||||
|       break; | ||||
|     case PROP_WARNING_COLOR: | ||||
|       g_value_set_boxed (value, &icon->priv->warning_color); | ||||
|       break; | ||||
|     case PROP_SUCCESS_COLOR: | ||||
|       g_value_set_boxed (value, &icon->priv->success_color); | ||||
|       break; | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||||
|       break; | ||||
| @ -372,9 +441,103 @@ gtk_tray_icon_get_visual_property (GtkTrayIcon *icon) | ||||
|     XFree (prop.prop); | ||||
| } | ||||
|  | ||||
| static void | ||||
| gtk_tray_icon_get_colors_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->colors_atom, | ||||
| 			       0, G_MAXLONG, FALSE, | ||||
| 			       XA_CARDINAL, | ||||
| 			       &type, &format, &nitems, | ||||
| 			       &bytes_after, &(prop.prop_ch)); | ||||
|   error = gdk_error_trap_pop (); | ||||
|  | ||||
|   if (error || result != Success) | ||||
|     return; | ||||
|  | ||||
|   if (type == XA_CARDINAL && nitems == 12 && format == 32) | ||||
|     { | ||||
|       GdkColor color; | ||||
|  | ||||
|       g_object_freeze_notify (G_OBJECT (icon)); | ||||
|  | ||||
|       color.red = prop.prop[0]; | ||||
|       color.green = prop.prop[1]; | ||||
|       color.blue = prop.prop[2]; | ||||
|  | ||||
|       if (!gdk_color_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]; | ||||
|  | ||||
|       if (!gdk_color_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]; | ||||
|       color.green = prop.prop[7]; | ||||
|       color.blue = prop.prop[8]; | ||||
|  | ||||
|       if (!gdk_color_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]; | ||||
|  | ||||
|       if (!gdk_color_equal (&icon->priv->success_color, &color)) | ||||
|         { | ||||
|           icon->priv->success_color = color; | ||||
|  | ||||
|           g_object_notify (G_OBJECT (icon), "success-color"); | ||||
|         } | ||||
|  | ||||
|       g_object_thaw_notify (G_OBJECT (icon)); | ||||
|     } | ||||
|  | ||||
|   if (type != None) | ||||
|     XFree (prop.prop); | ||||
| } | ||||
|  | ||||
| static GdkFilterReturn | ||||
| gtk_tray_icon_manager_filter (GdkXEvent *xevent,  | ||||
| 			      GdkEvent  *event,  | ||||
| gtk_tray_icon_manager_filter (GdkXEvent *xevent, | ||||
| 			      GdkEvent  *event, | ||||
| 			      gpointer   user_data) | ||||
| { | ||||
|   GtkTrayIcon *icon = user_data; | ||||
| @ -399,6 +562,14 @@ gtk_tray_icon_manager_filter (GdkXEvent *xevent, | ||||
|  | ||||
| 	  gtk_tray_icon_get_orientation_property (icon); | ||||
| 	} | ||||
|       else if (xev->xany.type == PropertyNotify && | ||||
|                xev->xproperty.atom == icon->priv->colors_atom) | ||||
|         { | ||||
|           GTK_NOTE (PLUGSOCKET, | ||||
|                     g_print ("GtkStatusIcon %p: got PropertyNotify on manager window for colors atom\n", icon)); | ||||
|  | ||||
|           gtk_tray_icon_get_colors_property (icon); | ||||
|         } | ||||
|       else if (xev->xany.type == DestroyNotify) | ||||
| 	{ | ||||
|           GTK_NOTE (PLUGSOCKET, | ||||
| @ -501,9 +672,11 @@ gtk_tray_icon_update_manager_window (GtkTrayIcon *icon) | ||||
| 					      icon->priv->manager_window); | ||||
|        | ||||
|       gdk_window_add_filter (gdkwin, gtk_tray_icon_manager_filter, icon); | ||||
|       g_print ("manager window %d\n", icon->priv->manager_window); | ||||
|  | ||||
|       gtk_tray_icon_get_orientation_property (icon); | ||||
|       gtk_tray_icon_get_visual_property (icon); | ||||
|       gtk_tray_icon_get_colors_property (icon); | ||||
|  | ||||
|       if (gtk_widget_get_realized (GTK_WIDGET (icon))) | ||||
| 	{ | ||||
|  | ||||
| @ -69,7 +69,7 @@ void           _gtk_tray_icon_cancel_message  (GtkTrayIcon *icon, | ||||
| 					       guint        id); | ||||
|  | ||||
| GtkOrientation _gtk_tray_icon_get_orientation (GtkTrayIcon *icon); | ||||
| 					     | ||||
|  | ||||
| G_END_DECLS | ||||
|  | ||||
| #endif /* __GTK_TRAY_ICON_H__ */ | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Matthias Clasen
					Matthias Clasen