From 129b78bdf05074e89b0331b4c78a5fd6c255b225 Mon Sep 17 00:00:00 2001 From: Eric Koegel Date: Mon, 23 Dec 2013 11:53:02 +0300 Subject: [PATCH] Fix transparency issues with GTK3 plugins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch uses some GTK3 CSS magic written by Simon Steinbeiß to make the GtkPlug button in the panel transparent. Small changes were made to the wrapper_plug_draw code as well, i.e. no need to check GTK_WIDGET_IS_DRAWABLE since gtk does this before calling the draw signal. It also transforms the draw coordinates from widget-relative back to window-relative. --- libxfce4panel/xfce-panel-plugin.c | 5 +- wrapper/wrapper-plug.c | 115 ++++++++++++++++++++++---------------- 2 files changed, 68 insertions(+), 52 deletions(-) diff --git a/libxfce4panel/xfce-panel-plugin.c b/libxfce4panel/xfce-panel-plugin.c index df417fe..9fb43d1 100644 --- a/libxfce4panel/xfce-panel-plugin.c +++ b/libxfce4panel/xfce-panel-plugin.c @@ -715,10 +715,7 @@ xfce_panel_plugin_init (XfcePanelPlugin *plugin) #endif /* hide the event box window to make the plugin transparent */ - // FIXME - // Temporarily disabled to workaround plugin transparency issues. - // It breaks background transparency and color support. - //gtk_event_box_set_visible_window (GTK_EVENT_BOX (plugin), FALSE); + gtk_event_box_set_visible_window (GTK_EVENT_BOX (plugin), FALSE); } diff --git a/wrapper/wrapper-plug.c b/wrapper/wrapper-plug.c index 6dc4432..6832a35 100644 --- a/wrapper/wrapper-plug.c +++ b/wrapper/wrapper-plug.c @@ -94,6 +94,8 @@ wrapper_plug_init (WrapperPlug *plug) GdkVisual *visual = NULL; GdkScreen *screen; GtkStyleContext *context; + GtkCssProvider *provider = gtk_css_provider_new(); + gchar *css_string; #else GdkColormap *colormap = NULL; GdkScreen *screen; @@ -135,6 +137,17 @@ wrapper_plug_init (WrapperPlug *plug) context = gtk_widget_get_style_context (GTK_WIDGET (plug)); gtk_style_context_add_class (context, "panel"); gtk_style_context_add_class (context, "xfce4-panel"); + + /* We need to set the plugin button to transparent and let everything else + * be in the theme or panel's color */ + css_string = g_strdup_printf (".xfce4-panel .button { background-color: transparent; }"); + gtk_css_provider_load_from_data (provider, css_string, -1, NULL); + gtk_style_context_add_provider (context, + GTK_STYLE_PROVIDER (provider), + GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + + g_free (css_string); + g_object_unref (provider); #endif } @@ -163,72 +176,78 @@ wrapper_plug_draw (GtkWidget *widget, GdkPixbuf *pixbuf; GError *error = NULL; - if (gtk_widget_is_drawable (widget)) + cairo_save (cr); + + /* The "draw" signal is in widget coordinates, transform back to window */ + gtk_cairo_transform_to_window (cr, + GTK_WIDGET (plug), + gtk_widget_get_window (gtk_widget_get_toplevel (GTK_WIDGET (plug)))); + + if (G_UNLIKELY (plug->background_image != NULL)) { - if (G_UNLIKELY (plug->background_image != NULL)) + cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); + + if (G_LIKELY (plug->background_image_cache != NULL)) { - cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); + cairo_set_source (cr, plug->background_image_cache); + cairo_paint (cr); + } + else + { + /* load the image in a pixbuf */ + pixbuf = gdk_pixbuf_new_from_file (plug->background_image, &error); - if (G_LIKELY (plug->background_image_cache != NULL)) + if (G_LIKELY (pixbuf != NULL)) { - cairo_set_source (cr, plug->background_image_cache); + gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); + g_object_unref (G_OBJECT (pixbuf)); + + plug->background_image_cache = cairo_get_source (cr); + cairo_pattern_reference (plug->background_image_cache); + cairo_pattern_set_extend (plug->background_image_cache, CAIRO_EXTEND_REPEAT); cairo_paint (cr); } else { - /* load the image in a pixbuf */ - pixbuf = gdk_pixbuf_new_from_file (plug->background_image, &error); - - if (G_LIKELY (pixbuf != NULL)) - { - gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); - g_object_unref (G_OBJECT (pixbuf)); - - plug->background_image_cache = cairo_get_source (cr); - cairo_pattern_reference (plug->background_image_cache); - cairo_pattern_set_extend (plug->background_image_cache, CAIRO_EXTEND_REPEAT); - cairo_paint (cr); - } - else - { - /* print error message */ - g_warning ("Background image disabled, \"%s\" could not be loaded: %s", - plug->background_image, error != NULL ? error->message : "No error"); - g_error_free (error); + /* print error message */ + g_warning ("Background image disabled, \"%s\" could not be loaded: %s", + plug->background_image, error != NULL ? error->message : "No error"); + g_error_free (error); - /* disable background image */ - wrapper_plug_background_reset (plug); - } + /* disable background image */ + wrapper_plug_background_reset (plug); } } - else + } + else + { + alpha = gtk_widget_is_composited (GTK_WIDGET (plug)) ? plug->background_alpha : 1.00; + + if (alpha < 1.00 || plug->background_color != NULL) { - alpha = gtk_widget_is_composited (GTK_WIDGET (plug)) ? plug->background_alpha : 1.00; + cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); - if (alpha < 1.00 || plug->background_color != NULL) + /* get the background gdk color */ + if (plug->background_color != NULL) { - cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); - - /* get the background gdk color */ - if (plug->background_color != NULL) - { - color = plug->background_color; - cairo_set_source_rgba (cr, PANEL_GDKCOLOR_TO_DOUBLE (color), alpha); - } - else - { - style = gtk_widget_get_style_context (widget); - gtk_style_context_get_background_color (style, GTK_STATE_FLAG_NORMAL, &rgba); - rgba.alpha = alpha; - gdk_cairo_set_source_rgba (cr, &rgba); - } - - /* draw the background color */ - cairo_fill (cr); + color = plug->background_color; + cairo_set_source_rgba (cr, PANEL_GDKCOLOR_TO_DOUBLE (color), alpha); } + else + { + style = gtk_widget_get_style_context (widget); + gtk_style_context_get_background_color (style, GTK_STATE_FLAG_NORMAL, &rgba); + rgba.alpha = alpha; + gdk_cairo_set_source_rgba (cr, &rgba); + } + + /* draw the background color */ + cairo_paint (cr); } } + cairo_restore(cr); + return GTK_WIDGET_CLASS (wrapper_plug_parent_class)->draw (widget, cr); } -- 1.8.3.2