diff options
| author | Javier <dev.git@javispedro.com> | 2015-02-21 16:34:35 +0100 | 
|---|---|---|
| committer | Javier <dev.git@javispedro.com> | 2015-02-21 16:34:35 +0100 | 
| commit | 40bee9911209e2e9e9c30bdb1a87443f7e36a3f1 (patch) | |
| tree | 96387394251be15120b10db8d11cc049818627bf | |
| parent | f56b5b34e2a14327021168ff3ad6ce49cdd27bed (diff) | |
| download | mdock-40bee9911209e2e9e9c30bdb1a87443f7e36a3f1.tar.gz mdock-40bee9911209e2e9e9c30bdb1a87443f7e36a3f1.zip  | |
add red dot if any window on item needs attention
| -rw-r--r-- | libmdock/mdock-item.c | 56 | ||||
| -rw-r--r-- | libmdock/mdock-item.h | 1 | 
2 files changed, 56 insertions, 1 deletions
diff --git a/libmdock/mdock-item.c b/libmdock/mdock-item.c index 68cfb80..6ee7b6a 100644 --- a/libmdock/mdock-item.c +++ b/libmdock/mdock-item.c @@ -31,6 +31,7 @@ struct _MDockItemPrivate  	guint icon_size;  	GdkPixbuf *icon;  	GList *windows; +	gboolean needs_attention;  };  G_DEFINE_TYPE (MDockItem, mdock_item, GTK_TYPE_WIDGET) @@ -41,6 +42,7 @@ enum {  	PROP_DESKTOP_APP_INFO,  	PROP_N_WINDOWS,  	PROP_DISPLAY_NAME, +	PROP_NEEDS_ATTENTION,  	N_PROPERTIES  }; @@ -107,6 +109,30 @@ static void mdock_item_update_icon_geometry(MDockItem *self)  	}  } +static void mdock_item_update_needs_attention(MDockItem *self) +{ +	gboolean needs_it = FALSE; + +	for (GList *l = self->priv->windows; l; l = g_list_next(l)) { +		WnckWindow *window = WNCK_WINDOW(l->data); +		needs_it |= wnck_window_or_transient_needs_attention(window); +	} + +	if (needs_it != self->priv->needs_attention) { +		self->priv->needs_attention = needs_it; +		gtk_widget_queue_draw(GTK_WIDGET(self)); +		g_object_notify_by_pspec(G_OBJECT(self), +		                         obj_properties[PROP_NEEDS_ATTENTION]); +	} +} + +static void handle_window_state_changed(WnckWindow *window, WnckWindowState changed_mask, WnckWindowState new_state, MDockItem *self) +{ +	if (changed_mask & (WNCK_WINDOW_STATE_DEMANDS_ATTENTION | WNCK_WINDOW_STATE_URGENT)) { +		mdock_item_update_needs_attention(self); +	} +} +  static void mdock_item_realize(GtkWidget *widget)  {  	MDockItem *self = MDOCK_ITEM(widget); @@ -163,7 +189,11 @@ static gboolean mdock_item_expose(GtkWidget *widget, GdkEventExpose *event)  	if (self->priv->windows) {  		double circle_radius = self->priv->icon_size / 8.0;  		cairo_save(cr); -		cairo_set_source_rgba(cr, 0.4, 0.4, 0.6, 0.8); +		if (self->priv->needs_attention) { +			cairo_set_source_rgba(cr, 0.9, 0.3, 0.3, 1.0); +		} else { +			cairo_set_source_rgba(cr, 0.4, 0.4, 0.6, 0.8); +		}  		cairo_translate(cr, self->priv->icon_size / 2.0, self->priv->icon_size - circle_radius / 2.0 - 1.0);  		cairo_arc(cr, 0, 0, circle_radius, 0, 2 * M_PI);  		cairo_fill(cr); @@ -214,6 +244,9 @@ static void mdock_item_get_property(GObject        *object,  	case PROP_DISPLAY_NAME:  		g_value_set_string(value, mdock_item_get_display_name(self));  		break; +	case PROP_NEEDS_ATTENTION: +		g_value_set_boolean(value, self->priv->needs_attention); +		break;  	default:  		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);  		break; @@ -240,6 +273,7 @@ static void mdock_item_init(MDockItem *self)  	self->priv = MDOCK_ITEM_GET_PRIVATE (self);  	self->priv->pinned = FALSE;  	self->priv->icon_size = REQUISITION_ICON_SIZE; +	self->priv->needs_attention = FALSE;  	gtk_widget_add_events(GTK_WIDGET(self),  	                      GDK_BUTTON_PRESS_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK); @@ -285,6 +319,12 @@ mdock_item_class_init(MDockItemClass *klass)  	                                                        "",  	                                                        G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); +	obj_properties[PROP_NEEDS_ATTENTION] = g_param_spec_boolean("needs-attention", +	                                                            "Needs attention", +	                                                            "Whether any of the windows in this item requires attention", +	                                                            FALSE, +	                                                            G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); +  	g_object_class_install_properties(obj_class, N_PROPERTIES, obj_properties);  	g_type_class_add_private (obj_class, sizeof (MDockItemPrivate)); @@ -386,6 +426,11 @@ GdkPixbuf *mdock_item_get_icon_pixbuf(MDockItem *self)  	return self->priv->icon;  } +gboolean mdock_item_needs_attention(MDockItem *self) +{ +	return self->priv->needs_attention; +} +  void mdock_item_add_window(MDockItem *self, WnckWindow *window)  {  	if (!self->priv->windows) { @@ -398,6 +443,11 @@ void mdock_item_add_window(MDockItem *self, WnckWindow *window)  		mdock_item_update_icon(self);  	}  	mdock_item_update_icon_geometry_for_window(self, window); +	if (wnck_window_or_transient_needs_attention(window)) { +		mdock_item_update_needs_attention(self); +	} +	g_signal_connect_object(window, "state-changed", +	                        G_CALLBACK(handle_window_state_changed), self, 0);  	g_object_notify_by_pspec(G_OBJECT(self), obj_properties[PROP_N_WINDOWS]);  } @@ -409,6 +459,10 @@ void mdock_item_remove_window(MDockItem *self, WnckWindow *window)  		// we want to redraw in order to remove the "active" indicator.  		gtk_widget_queue_draw(GTK_WIDGET(self));  	} +	if (wnck_window_or_transient_needs_attention(window)) { +		mdock_item_update_needs_attention(self); +	} +	g_signal_handlers_disconnect_by_data(window, self);  	g_object_notify_by_pspec(G_OBJECT(self), obj_properties[PROP_N_WINDOWS]);  } diff --git a/libmdock/mdock-item.h b/libmdock/mdock-item.h index 739c966..bb7a2ab 100644 --- a/libmdock/mdock-item.h +++ b/libmdock/mdock-item.h @@ -64,6 +64,7 @@ void mdock_item_launch(MDockItem *self);  const gchar *mdock_item_get_display_name(MDockItem *self);  GdkPixbuf *mdock_item_get_icon_pixbuf(MDockItem *self); +gboolean mdock_item_needs_attention(MDockItem *self);  void mdock_item_add_window(MDockItem *self, WnckWindow *window);  void mdock_item_remove_window(MDockItem *self, WnckWindow *window);  | 
