diff options
| author | Javier <dev.git@javispedro.com> | 2015-07-26 03:11:35 +0200 | 
|---|---|---|
| committer | Javier <dev.git@javispedro.com> | 2015-07-26 03:11:35 +0200 | 
| commit | 2da9d48c9bcd1800f8a499b5e46c6ce04678acd5 (patch) | |
| tree | 9c9fc6716b1ee4a098d49dcea3bbb0b778484491 | |
| parent | baef440d424640a6fc99edd8a12a6abcea80c5fc (diff) | |
| download | topmenu-gtk-2da9d48c9bcd1800f8a499b5e46c6ce04678acd5.tar.gz topmenu-gtk-2da9d48c9bcd1800f8a499b5e46c6ce04678acd5.zip | |
add gtk+3 support for transparent backgroundstransparency
| -rw-r--r-- | README.md | 1 | ||||
| -rw-r--r-- | libtopmenu-client/topmenu-client.c | 1 | ||||
| -rw-r--r-- | libtopmenu-common/topmenu-background.c | 72 | ||||
| -rw-r--r-- | libtopmenu-common/topmenu-background.h | 1 | 
4 files changed, 62 insertions, 13 deletions
| @@ -35,7 +35,6 @@ please send questions or problem reports to dev.bugs at javispedro com. Alternat  * Multi-monitor support. Currently only one applet instance is supported.  Ideally, IF there are multiple panel applets, they should synchronize to only embed menubars from the same display.  * Allow Qt programs to render the menubars using Qt itself instead of using Gtk+. -* Transparent panels without XComposite (relative X11 background pixmaps, maybe?)  * Add some toggables for some commonely requested options: hide/show the application menu, "menu button" instead of menu bar.  # Design diff --git a/libtopmenu-client/topmenu-client.c b/libtopmenu-client/topmenu-client.c index ae9eac3..266ba54 100644 --- a/libtopmenu-client/topmenu-client.c +++ b/libtopmenu-client/topmenu-client.c @@ -95,7 +95,6 @@ static GdkFilterReturn handle_plug_window_event(GdkXEvent *xevent, GdkEvent *eve  	if (((XEvent*)xevent)->type == ClientMessage) {  		XClientMessageEvent *msg = (XClientMessageEvent*) xevent;  		if (msg->message_type == atom_change_background) { -			g_debug("received change background message");  			TopMenuBackground *bg = g_object_get_qdata(G_OBJECT(window), background_quark());  			g_return_val_if_fail(bg, GDK_FILTER_REMOVE); diff --git a/libtopmenu-common/topmenu-background.c b/libtopmenu-common/topmenu-background.c index 99d36e9..04ea20d 100644 --- a/libtopmenu-common/topmenu-background.c +++ b/libtopmenu-common/topmenu-background.c @@ -40,6 +40,11 @@ G_DEFINE_TYPE(TopMenuBackground, topmenu_background, G_TYPE_OBJECT)  static guint signals[N_SIGNALS]; +#if GTK_MAJOR_VERSION == 3 +#define TOPMENU_BACKGROUND_CSS_STYLE_CLASS    "topmenu-background" +static GtkCssProvider *topmenu_provider; +#endif +  static inline GdkDisplay * topmenu_background_get_display(TopMenuBackground *self)  {  	return gdk_display_get_default(); @@ -94,12 +99,6 @@ TopMenuBackground *topmenu_background_new(void)  void topmenu_background_set_from_color(TopMenuBackground *self, double red, double green, double blue, double alpha)  { -	if (self->priv->has_color -	        && self->priv->red == red && self->priv->green == green -	        && self->priv->blue == blue && self->priv->alpha == alpha) { -		return; // Nothing to do -	} -  	topmenu_background_reset(self);  	self->priv->has_color = TRUE; @@ -150,6 +149,7 @@ void topmenu_background_set_from_drawable(TopMenuBackground *self, Drawable draw  				width, height);  	if (!new_surface) {  		g_debug("could not create new surface"); +		XFreePixmap(xdpy, self->priv->pixmap);  		goto err_out;  	} @@ -283,13 +283,10 @@ void topmenu_background_set_from_client_message(TopMenuBackground *self, XClient  		       green = ((rgba >> 16) & 0xFF) / 255.0,  		       blue = ((rgba >> 8) & 0xFF) / 255.0,  		       alpha = ((rgba >> 0) & 0xFF) / 255.0; -		g_debug("received color %.2f,%.2f,%.2f,%.2f", red, green, blue, alpha);  		topmenu_background_set_from_color(self, red, green, blue, alpha);  	} else if (event->data.l[2] != None) { -		g_debug("received pixmap 0x%lx", event->data.l[2]);  		topmenu_background_set_from_drawable(self, event->data.l[2]);  	} else { -		g_debug("received nothing");  		topmenu_background_clear(self);  	}  } @@ -310,7 +307,41 @@ static GdkPixmap * get_pixmap(GdkDisplay *display, Pixmap pixmap)  void topmenu_background_apply(TopMenuBackground *self, GtkWidget *widget)  {  #if GTK_MAJOR_VERSION == 3 -	g_debug("background set not yet supported on Gtk+ 3"); +	if (!topmenu_provider) { +		topmenu_provider = gtk_css_provider_new(); +		gtk_css_provider_load_from_data(topmenu_provider, +			"." TOPMENU_BACKGROUND_CSS_STYLE_CLASS " {\n" +				" background-color: rgba (0, 0, 0, 0);\n" +				" background-image: none;\n" +			"}", -1, NULL); +	} + +	GtkStyleContext *context = gtk_widget_get_style_context(widget); + +	GdkWindow *widget_window = gtk_widget_get_window(widget); +	double red, green, blue, alpha; +	Pixmap pixmap; +	if (topmenu_background_get_color(self, &red, &green, &blue, &alpha)) { +		gtk_style_context_add_class(context, TOPMENU_BACKGROUND_CSS_STYLE_CLASS); +		if (widget_window) { +			GdkRGBA color = {red, green, blue, alpha}; +			gdk_window_set_background_rgba(widget_window, &color); +			g_debug("do color"); + +		} +	} else if (topmenu_background_get_pixmap(self, &pixmap)) { +		gtk_style_context_add_class(context, TOPMENU_BACKGROUND_CSS_STYLE_CLASS); +		if (widget_window) { +			cairo_pattern_t * pattern = topmenu_background_get_cairo_pattern(self); +			gdk_window_set_background_pattern(widget_window, pattern); +			cairo_pattern_destroy(pattern); +		} +	} else { +		gtk_style_context_remove_class(context, TOPMENU_BACKGROUND_CSS_STYLE_CLASS); +	} + +	gtk_style_context_add_provider(context, GTK_STYLE_PROVIDER(topmenu_provider), +	                               GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);  #elif GTK_MAJOR_VERSION == 2  	// Clear current background  	GtkRcStyle *rc_style; @@ -347,15 +378,34 @@ void topmenu_background_apply(TopMenuBackground *self, GtkWidget *widget)  			g_object_unref(style);  		}  	} - +#endif  	gtk_widget_queue_draw(widget); +} + +void topmenu_background_unapply(TopMenuBackground *self, GtkWidget *widget) +{ +#if GTK_MAJOR_VERSION == 3 +	GtkStyleContext *context = gtk_widget_get_style_context(widget); +	gtk_style_context_remove_class(context, TOPMENU_BACKGROUND_CSS_STYLE_CLASS); +	gtk_style_context_remove_provider(context, GTK_STYLE_PROVIDER(topmenu_provider)); +#elif GTK_MAJOR_VERSION == 2 +	// Clear current background +	GtkRcStyle *rc_style; +	gtk_widget_set_style(widget, NULL); +	rc_style = gtk_rc_style_new(); +	gtk_widget_modify_style(widget, rc_style); +	g_object_unref(rc_style);  #endif +	gtk_widget_queue_draw(widget);  }  void topmenu_background_connect(TopMenuBackground *self, GtkWidget *widget)  {  	g_signal_connect(self, "changed",  	                 G_CALLBACK(topmenu_background_apply), widget); +	if (gtk_widget_get_realized(widget)) { +		topmenu_background_apply(self, widget); +	}  }  void topmenu_background_disconnect(TopMenuBackground *self, GtkWidget *widget) diff --git a/libtopmenu-common/topmenu-background.h b/libtopmenu-common/topmenu-background.h index aca72f8..76c9f6d 100644 --- a/libtopmenu-common/topmenu-background.h +++ b/libtopmenu-common/topmenu-background.h @@ -65,6 +65,7 @@ void topmenu_background_fill_client_message(TopMenuBackground *self, XClientMess  void topmenu_background_set_from_client_message(TopMenuBackground *self, XClientMessageEvent *event);  void topmenu_background_apply(TopMenuBackground *self, GtkWidget *widget); +void topmenu_background_unapply(TopMenuBackground *self, GtkWidget *widget);  void topmenu_background_connect(TopMenuBackground *self, GtkWidget *widget);  void topmenu_background_disconnect(TopMenuBackground *self, GtkWidget *widget); | 
