[Xfce4-commits] <xfce4-panel:nick/background> Make the remaining background stuff work.

Nick Schermer noreply at xfce.org
Sun May 9 22:06:01 CEST 2010


Updating branch refs/heads/nick/background
         to 16b3dc1e280206731ac4d6062f712e286bc5936d (commit)
       from 3e035afb3bb2a777bd6d543ceeeea8dc844b01b6 (commit)

commit 16b3dc1e280206731ac4d6062f712e286bc5936d
Author: Nick Schermer <nick at xfce.org>
Date:   Sun May 9 22:05:00 2010 +0200

    Make the remaining background stuff work.

 libxfce4panel/xfce-panel-macros-46.h       |   83 ++++++++++++---
 libxfce4panel/xfce-panel-plugin-provider.h |    1 +
 panel/panel-application.c                  |    9 ++
 panel/panel-base-window.c                  |   21 +++-
 panel/panel-base-window.h                  |    2 +-
 panel/panel-plugin-external-46.c           |   44 +++++++-
 panel/panel-plugin-external-46.h           |    4 +-
 panel/panel-plugin-external.c              |    6 +-
 panel/panel-plugin-external.h              |    4 +-
 plugins/tasklist/tasklist.desktop.in       |    2 +-
 wrapper/wrapper-plug.c                     |  150 +++++++++++++++++++---------
 11 files changed, 243 insertions(+), 83 deletions(-)

diff --git a/libxfce4panel/xfce-panel-macros-46.h b/libxfce4panel/xfce-panel-macros-46.h
index 82644d0..e29acad 100644
--- a/libxfce4panel/xfce-panel-macros-46.h
+++ b/libxfce4panel/xfce-panel-macros-46.h
@@ -276,11 +276,13 @@ enum /*< skip >*/
  *                  for more information.
  **/
 #define XFCE_PANEL_PLUGIN_REGISTER_EXTERNAL_FULL(construct_func, preinit_func, check_func) \
-  static GdkAtom  _xpp_atom = GDK_NONE; \
-  static gdouble  _xpp_alpha = 1.00; \
-  static gboolean _xpp_composited = FALSE; \
-  static guint    _xpp_bg_style = 0; \
-  static GdkColor _xpp_bg_color = { 0, }; \
+  static GdkAtom          _xpp_atom = GDK_NONE; \
+  static gdouble          _xpp_alpha = 1.00; \
+  static gboolean         _xpp_composited = FALSE; \
+  static guint            _xpp_bg_style = 0; \
+  static GdkColor         _xpp_bg_color = { 0, }; \
+  static const gchar     *_xpp_bg_image = NULL; \
+  static cairo_pattern_t *_xpp_bg_image_cache = NULL; \
   \
   static void \
   _xpp_quit_main_loop (void) \
@@ -434,39 +436,77 @@ enum /*< skip >*/
   _xpp_expose_event (GtkWidget      *plug, \
                      GdkEventExpose *event) \
   { \
-    cairo_t  *cr; \
-    GdkColor *color; \
-    gdouble   real_alpha = _xpp_composited ? _xpp_alpha : 1.00; \
+    cairo_t        *cr; \
+    const GdkColor *color; \
+    gdouble         real_alpha; \
+    GdkPixbuf      *pixbuf; \
+    GError         *error = NULL; \
     \
-    if (GTK_WIDGET_DRAWABLE (plug) \
-        && (real_alpha < 1.00 || _xpp_bg_style > 0)) \
+    if (!GTK_WIDGET_DRAWABLE (plug)) \
+      return FALSE; \
+    \
+    if (G_UNLIKELY (_xpp_bg_style == 2)) \
       { \
         cr = gdk_cairo_create (gtk_widget_get_window (plug)); \
         cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); \
+        gdk_cairo_rectangle (cr, &event->area); \
+        cairo_clip (cr); \
         \
-        if (G_UNLIKELY (_xpp_bg_style == 2)) \
+        if (G_LIKELY (_xpp_bg_image_cache != NULL)) \
           { \
+            cairo_set_source (cr, _xpp_bg_image_cache); \
+            cairo_paint (cr); \
           } \
         else \
           { \
+            /* load the image in a pixbuf */ \
+            pixbuf = gdk_pixbuf_new_from_file (_xpp_bg_image, &error); \
+            if (G_LIKELY (pixbuf != NULL)) \
+              { \
+                gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); \
+                g_object_unref (G_OBJECT (pixbuf)); \
+                \
+                _xpp_bg_image_cache = cairo_get_source (cr); \
+                cairo_pattern_reference (_xpp_bg_image_cache); \
+                cairo_pattern_set_extend (_xpp_bg_image_cache, CAIRO_EXTEND_REPEAT); \
+                cairo_paint (cr); \
+              } \
+            else \
+              { \
+                /* print error message */ \
+                g_warning ("Background image disabled, \"%s\" could not be loaded: %s", \
+                           _xpp_bg_image, error != NULL ? error->message : "No error"); \
+                g_error_free (error); \
+                \
+                /* disable background image */ \
+                _xpp_bg_style = 0; \
+              } \
+          } \
+        \
+        cairo_destroy (cr); \
+      } \
+    else \
+      { \
+        real_alpha = _xpp_composited ? _xpp_alpha : 1.00; \
+        \
+        if (_xpp_bg_style == 1 || real_alpha < 1.00) \
+          { \
             if (G_LIKELY (_xpp_bg_style == 0)) \
               color = &(gtk_widget_get_style (plug)->bg[GTK_STATE_NORMAL]); \
             else \
               color = &_xpp_bg_color; \
             \
+            cr = gdk_cairo_create (gtk_widget_get_window (plug)); \
+            cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); \
             cairo_set_source_rgba (cr, \
                                    color->red / 65535.00, \
                                    color->green / 65535.00, \
                                    color->blue / 65535.00, \
                                    real_alpha); \
-            \
-            cairo_rectangle (cr, event->area.x, event->area.y, \
-                             event->area.width, event->area.height); \
-            \
+            gdk_cairo_rectangle (cr, &event->area); \
             cairo_fill (cr); \
+            cairo_destroy (cr); \
           } \
-        \
-        cairo_destroy (cr); \
       } \
     \
     return FALSE; \
@@ -552,12 +592,21 @@ enum /*< skip >*/
         G_CALLBACK (_xpp_provider_signal), plug); \
     gtk_widget_show (xpp); \
     \
+    if (*argv[PLUGIN_ARGV_BACKGROUND_IMAGE] != '\0') \
+      { \
+        _xpp_bg_image = argv[PLUGIN_ARGV_BACKGROUND_IMAGE]; \
+        _xpp_bg_style = 2; \
+      } \
+    \
     g_signal_connect (G_OBJECT (plug), "client-event", \
        G_CALLBACK (_xpp_client_event), xpp); \
     gtk_widget_show (plug); \
     \
     gtk_main (); \
     \
+    if (_xpp_bg_image_cache != NULL) \
+      cairo_pattern_destroy (_xpp_bg_image_cache); \
+    \
     if (GTK_IS_WIDGET (plug)) \
       gtk_widget_destroy (plug); \
     \
diff --git a/libxfce4panel/xfce-panel-plugin-provider.h b/libxfce4panel/xfce-panel-plugin-provider.h
index b43be8d..1949b04 100644
--- a/libxfce4panel/xfce-panel-plugin-provider.h
+++ b/libxfce4panel/xfce-panel-plugin-provider.h
@@ -113,6 +113,7 @@ enum
   PLUGIN_ARGV_NAME,
   PLUGIN_ARGV_DISPLAY_NAME,
   PLUGIN_ARGV_COMMENT,
+  PLUGIN_ARGV_BACKGROUND_IMAGE,
   PLUGIN_ARGV_ARGUMENTS
 };
 
diff --git a/panel/panel-application.c b/panel/panel-application.c
index 13c6d15..ae3eb75 100644
--- a/panel/panel-application.c
+++ b/panel/panel-application.c
@@ -38,6 +38,8 @@
 #include <libxfce4panel/xfce-panel-plugin-provider.h>
 
 #include <panel/panel-dbus-service.h>
+#include <panel/panel-base-window.h>
+#include <panel/panel-plugin-external-46.h>
 #include <panel/panel-window.h>
 #include <panel/panel-application.h>
 #include <panel/panel-itembar.h>
@@ -619,6 +621,13 @@ panel_application_plugin_insert (PanelApplication  *application,
   g_signal_connect (G_OBJECT (provider), "provider-signal",
       G_CALLBACK (panel_application_plugin_provider_signal), application);
 
+  /* work around the problem that we need a background before
+   * realizing for 4.6 panel plugins */
+  if (PANEL_BASE_WINDOW (window)->background_style == PANEL_BG_STYLE_IMAGE
+      && PANEL_IS_PLUGIN_EXTERNAL_46 (provider))
+    panel_plugin_external_46_set_background_image (PANEL_PLUGIN_EXTERNAL_46 (provider),
+        PANEL_BASE_WINDOW (window)->background_image);
+
   /* add the item to the panel */
   itembar = gtk_bin_get_child (GTK_BIN (window));
   panel_itembar_insert (PANEL_ITEMBAR (itembar),
diff --git a/panel/panel-base-window.c b/panel/panel-base-window.c
index 4ff9d9d..ae51528 100644
--- a/panel/panel-base-window.c
+++ b/panel/panel-base-window.c
@@ -436,7 +436,7 @@ panel_base_window_expose_event (GtkWidget      *widget,
                                 GdkEventExpose *event)
 {
   cairo_t                *cr;
-  GdkColor               *color;
+  const GdkColor         *color;
   PanelBaseWindow        *window = PANEL_BASE_WINDOW (widget);
   PanelBaseWindowPrivate *priv = window->priv;
   gdouble                 alpha;
@@ -447,6 +447,7 @@ panel_base_window_expose_event (GtkWidget      *widget,
   gboolean                result;
   GdkPixbuf              *pixbuf;
   GError                 *error = NULL;
+  cairo_matrix_t          matrix = { 1, 0, 0, 1, 0, 0 }; /* identity matrix */
 
   result = (*GTK_WIDGET_CLASS (panel_base_window_parent_class)->expose_event) (widget, event);
 
@@ -470,7 +471,11 @@ panel_base_window_expose_event (GtkWidget      *widget,
 
       if (G_LIKELY (priv->bg_image_cache != NULL))
         {
+          if (G_UNLIKELY (priv->active_timeout_id != 0))
+            cairo_matrix_init_translate (&matrix, -1, -1);
+
           cairo_set_source (cr, priv->bg_image_cache);
+          cairo_pattern_set_matrix (priv->bg_image_cache, &matrix);
           cairo_paint (cr);
         }
       else if (window->background_image != NULL)
@@ -798,7 +803,15 @@ static void
 panel_base_window_set_plugin_background_image (GtkWidget *widget,
                                                gpointer   user_data)
 {
+  panel_return_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (widget));
+  panel_return_if_fail (PANEL_IS_BASE_WINDOW (user_data));
 
+  if (PANEL_IS_PLUGIN_EXTERNAL (widget))
+    panel_plugin_external_set_background_image (PANEL_PLUGIN_EXTERNAL (widget),
+        PANEL_BASE_WINDOW (user_data)->background_image);
+  else if (PANEL_IS_PLUGIN_EXTERNAL_46 (widget))
+    panel_plugin_external_46_set_background_image (PANEL_PLUGIN_EXTERNAL_46 (widget),
+        PANEL_BASE_WINDOW (user_data)->background_image);
 }
 
 
@@ -857,9 +870,9 @@ panel_base_window_get_borders (PanelBaseWindow *window)
 
 
 void
-panel_util_set_source_rgba (cairo_t  *cr,
-                            GdkColor *color,
-                            gdouble   alpha)
+panel_util_set_source_rgba (cairo_t        *cr,
+                            const GdkColor *color,
+                            gdouble         alpha)
 {
   panel_return_if_fail (alpha >= 0.00 && alpha <= 1.00);
 
diff --git a/panel/panel-base-window.h b/panel/panel-base-window.h
index 0502359..f74ac13 100644
--- a/panel/panel-base-window.h
+++ b/panel/panel-base-window.h
@@ -88,7 +88,7 @@ void         panel_base_window_set_active  (PanelBaseWindow *window,
                                             gboolean         active);
 
 void         panel_util_set_source_rgba    (cairo_t         *cr,
-                                            GdkColor        *color,
+                                            const GdkColor  *color,
                                             gdouble          alpha);
 
 G_END_DECLS
diff --git a/panel/panel-plugin-external-46.c b/panel/panel-plugin-external-46.c
index 116e346..40123c6 100644
--- a/panel/panel-plugin-external-46.c
+++ b/panel/panel-plugin-external-46.c
@@ -128,6 +128,9 @@ struct _PanelPluginExternal46
   guint             show_configure : 1;
   guint             show_about : 1;
 
+  /* background image location */
+  gchar            *background_image;
+
   /* child watch data */
   GPid              pid;
   guint             watch_id;
@@ -220,6 +223,7 @@ panel_plugin_external_46_init (PanelPluginExternal46 *external)
   external->restart_timer = NULL;
   external->show_configure = FALSE;
   external->show_about = FALSE;
+  external->background_image = NULL;
 
   /* signal to pass gtk_widget_set_sensitive() changes to the remote window */
   g_signal_connect (G_OBJECT (external), "notify::sensitive",
@@ -269,6 +273,7 @@ panel_plugin_external_46_finalize (GObject *object)
     }
 
   g_strfreev (external->arguments);
+  g_free (external->background_image);
 
   if (external->restart_timer != NULL)
     g_timer_destroy (external->restart_timer);
@@ -376,6 +381,11 @@ panel_plugin_external_46_realize (GtkWidget *widget)
   argv[PLUGIN_ARGV_DISPLAY_NAME] = (gchar *) panel_module_get_display_name (external->module);
   argv[PLUGIN_ARGV_COMMENT] = (gchar *) panel_module_get_comment (external->module);
 
+  if (external->background_image != NULL)
+    argv[PLUGIN_ARGV_BACKGROUND_IMAGE] = (gchar *) external->background_image;
+  else
+    argv[PLUGIN_ARGV_BACKGROUND_IMAGE] = (gchar *) "";
+
   /* append the arguments */
   if (G_UNLIKELY (external->arguments != NULL))
     for (i = 0; external->arguments[i] != NULL; i++)
@@ -422,7 +432,7 @@ panel_plugin_external_46_unrealize (GtkWidget *widget)
   external->plug_embedded = FALSE;
 
   panel_debug (PANEL_DEBUG_DOMAIN_EXTERNAL46,
-               "Plugin %s-%d unrealized, quiting GtkPlug",
+               "plugin %s-%d unrealized, quiting GtkPlug",
                panel_module_get_name (external->module),
                external->unique_id);
 
@@ -555,7 +565,7 @@ panel_plugin_external_46_plug_added (GtkSocket *socket)
   external->plug_embedded = TRUE;
 
   panel_debug (PANEL_DEBUG_DOMAIN_EXTERNAL46,
-               "plugin  %d has been embedded, %d events in queue",
+               "plugin %d has been embedded, %d events in queue",
                external->unique_id, g_slist_length (external->queue));
 
   /* send all the messages in the queue */
@@ -854,7 +864,7 @@ panel_plugin_external_46_child_watch (GPid     pid,
         case PLUGIN_EXIT_CHECK_FAILED:
         case PLUGIN_EXIT_NO_PROVIDER:
           panel_debug (PANEL_DEBUG_DOMAIN_EXTERNAL46,
-                       "Plugin exited with status %d. Removing from "
+                       "plugin exited with status %d. Removing from "
                        "configuration.", WEXITSTATUS (status));
 
           /* cleanup the plugin configuration (in panel-application) */
@@ -912,7 +922,7 @@ panel_plugin_external_46_set_background_alpha (PanelPluginExternal46 *external,
 
 void
 panel_plugin_external_46_set_background_color (PanelPluginExternal46 *external,
-                                               GdkColor              *color)
+                                               const GdkColor        *color)
 {
   GdkEventClient *event;
 
@@ -949,10 +959,32 @@ panel_plugin_external_46_set_background_color (PanelPluginExternal46 *external,
 }
 
 
-
 void
 panel_plugin_external_46_set_background_image (PanelPluginExternal46 *external,
-                                               gchar                 *image)
+                                               const gchar           *image)
 {
+  GtkWidget *window;
+
   panel_return_if_fail (PANEL_IS_PLUGIN_EXTERNAL_46 (external));
+
+  /* store new file location */
+  g_free (external->background_image);
+  external->background_image = g_strdup (image);
+
+  /* restart the plugin if a process is already running */
+  if (external->plug_embedded)
+    {
+      panel_debug (PANEL_DEBUG_DOMAIN_EXTERNAL46,
+                   "going to restart plugin %d for background image change",
+                   external->unique_id);
+
+      gtk_widget_unrealize (GTK_WIDGET (external));
+      gtk_widget_hide (GTK_WIDGET (external));
+
+      window = gtk_widget_get_toplevel (GTK_WIDGET (external));
+      panel_return_if_fail (PANEL_IS_WINDOW (window));
+      panel_window_set_povider_info (PANEL_WINDOW (window), GTK_WIDGET (external));
+
+      gtk_widget_show (GTK_WIDGET (external));
+    }
 }
diff --git a/panel/panel-plugin-external-46.h b/panel/panel-plugin-external-46.h
index b4730a7..4b2ae26 100644
--- a/panel/panel-plugin-external-46.h
+++ b/panel/panel-plugin-external-46.h
@@ -46,10 +46,10 @@ void       panel_plugin_external_46_set_background_alpha (PanelPluginExternal46
                                                           gdouble                 alpha);
 
 void       panel_plugin_external_46_set_background_color (PanelPluginExternal46  *external,
-                                                          GdkColor               *color);
+                                                          const GdkColor         *color);
 
 void       panel_plugin_external_46_set_background_image (PanelPluginExternal46  *external,
-                                                          gchar                  *image);
+                                                          const gchar            *image);
 
 G_END_DECLS
 
diff --git a/panel/panel-plugin-external.c b/panel/panel-plugin-external.c
index d9ce8b8..55ed76a 100644
--- a/panel/panel-plugin-external.c
+++ b/panel/panel-plugin-external.c
@@ -457,6 +457,7 @@ panel_plugin_external_realize (GtkWidget *widget)
   argv[PLUGIN_ARGV_NAME] = (gchar *) panel_module_get_name (external->module);
   argv[PLUGIN_ARGV_DISPLAY_NAME] = (gchar *) panel_module_get_display_name (external->module);
   argv[PLUGIN_ARGV_COMMENT] = (gchar *) panel_module_get_comment (external->module);
+  argv[PLUGIN_ARGV_BACKGROUND_IMAGE] = (gchar *) ""; /* unused, for 4.6 plugins only */
 
   /* append the arguments */
   if (G_UNLIKELY (external->arguments != NULL))
@@ -1045,7 +1046,7 @@ panel_plugin_external_set_background_alpha (PanelPluginExternal *external,
 
 void
 panel_plugin_external_set_background_color (PanelPluginExternal *external,
-                                            GdkColor            *color)
+                                            const GdkColor      *color)
 {
   GValue       value = { 0, };
   const gchar *prop;
@@ -1064,7 +1065,6 @@ panel_plugin_external_set_background_color (PanelPluginExternal *external,
       prop = SIGNAL_WRAPPER_BACKGROUND_UNSET;
 
       g_value_init (&value, G_TYPE_BOOLEAN);
-      g_value_take_string (&value, FALSE);
     }
 
   panel_plugin_external_queue_add (external, FALSE, prop, &value);
@@ -1076,7 +1076,7 @@ panel_plugin_external_set_background_color (PanelPluginExternal *external,
 
 void
 panel_plugin_external_set_background_image (PanelPluginExternal *external,
-                                            gchar               *image)
+                                            const gchar         *image)
 {
   GValue value = { 0, };
 
diff --git a/panel/panel-plugin-external.h b/panel/panel-plugin-external.h
index 175e11b..7864ad7 100644
--- a/panel/panel-plugin-external.h
+++ b/panel/panel-plugin-external.h
@@ -46,10 +46,10 @@ void       panel_plugin_external_set_background_alpha (PanelPluginExternal  *ext
                                                        gdouble               alpha);
 
 void       panel_plugin_external_set_background_color (PanelPluginExternal  *external,
-                                                       GdkColor             *color);
+                                                       const GdkColor       *color);
 
 void       panel_plugin_external_set_background_image (PanelPluginExternal  *external,
-                                                       gchar                *image);
+                                                       const gchar          *image);
 
 G_END_DECLS
 
diff --git a/plugins/tasklist/tasklist.desktop.in b/plugins/tasklist/tasklist.desktop.in
index fd20d49..07c184a 100644
--- a/plugins/tasklist/tasklist.desktop.in
+++ b/plugins/tasklist/tasklist.desktop.in
@@ -5,4 +5,4 @@ _Name=Window Buttons
 _Comment=Switch between open windows using buttons
 Icon=preferences-system-windows
 X-XFCE-Module=tasklist
-X-XFCE-Internal=TRUE
+X-XFCE-Internal=FALSE
diff --git a/wrapper/wrapper-plug.c b/wrapper/wrapper-plug.c
index 8b2b1fc..cdeb124 100644
--- a/wrapper/wrapper-plug.c
+++ b/wrapper/wrapper-plug.c
@@ -29,9 +29,10 @@
 
 
 
-static void     wrapper_plug_finalize     (GObject        *object);
-static gboolean wrapper_plug_expose_event (GtkWidget      *widget,
-                                           GdkEventExpose *event);
+static void     wrapper_plug_finalize         (GObject        *object);
+static gboolean wrapper_plug_expose_event     (GtkWidget      *widget,
+                                               GdkEventExpose *event);
+static void     wrapper_plug_background_reset (WrapperPlug    *plug);
 
 
 
@@ -45,12 +46,13 @@ struct _WrapperPlug
   GtkPlug __parent__;
 
   /* whether the wrapper has a rgba colormap */
-  guint     is_composited : 1;
+  guint            is_composited : 1;
 
   /* background information */
-  gdouble   background_alpha;
-  GdkColor *background_color;
-  gchar    *background_image;
+  gdouble          background_alpha;
+  GdkColor        *background_color;
+  gchar           *background_image;
+  cairo_pattern_t *background_image_cache;
 };
 
 
@@ -88,6 +90,7 @@ wrapper_plug_init (WrapperPlug *plug)
   plug->background_alpha = 1.00;
   plug->background_color = NULL;
   plug->background_image = NULL;
+  plug->background_image_cache = NULL;
 
   gtk_widget_set_name (GTK_WIDGET (plug), "XfcePanelWindowWrapper");
 
@@ -122,11 +125,7 @@ wrapper_plug_init (WrapperPlug *plug)
 static void
 wrapper_plug_finalize (GObject *object)
 {
-  WrapperPlug *plug = WRAPPER_PLUG (object);
-
-  g_free (plug->background_image);
-  if (plug->background_color)
-    gdk_color_free (plug->background_color);
+  wrapper_plug_background_reset (WRAPPER_PLUG (object));
 
   G_OBJECT_CLASS (wrapper_plug_parent_class)->finalize (object);
 }
@@ -137,43 +136,99 @@ static gboolean
 wrapper_plug_expose_event (GtkWidget      *widget,
                            GdkEventExpose *event)
 {
-  WrapperPlug   *plug = WRAPPER_PLUG (widget);
-  cairo_t       *cr;
-  GdkColor      *color;
-  GtkStateType   state = GTK_STATE_NORMAL;
-  gdouble        alpha = plug->is_composited ? plug->background_alpha : 1.00;
-
-  if (GTK_WIDGET_DRAWABLE (widget)
-      && (alpha < 1.00 || plug->background_color != NULL))
+  WrapperPlug    *plug = WRAPPER_PLUG (widget);
+  cairo_t        *cr;
+  const GdkColor *color;
+  gdouble         alpha;
+  GdkPixbuf      *pixbuf;
+  GError         *error = NULL;
+
+  if (GTK_WIDGET_DRAWABLE (widget))
     {
-      /* create the cairo context */
-      cr = gdk_cairo_create (widget->window);
-
-      /* get the background gdk color */
-      if (plug->background_color != NULL)
-        color = plug->background_color;
+      if (G_UNLIKELY (plug->background_image != NULL))
+        {
+          cr = gdk_cairo_create (widget->window);
+          cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+          gdk_cairo_rectangle (cr, &event->area);
+          cairo_clip (cr);
+
+          if (G_LIKELY (plug->background_image_cache != NULL))
+            {
+              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 (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);
+
+                  /* disable background image */
+                  wrapper_plug_background_reset (plug);
+                }
+            }
+
+          cairo_destroy (cr);
+        }
       else
-        color = &(widget->style->bg[state]);
+        {
+          alpha = plug->is_composited ? plug->background_alpha : 1.00;
+
+          if (alpha < 1.00 || plug->background_color != NULL)
+            {
+              /* get the background gdk color */
+              if (plug->background_color != NULL)
+                color = plug->background_color;
+              else
+                color = &(widget->style->bg[GTK_STATE_NORMAL]);
+
+              /* draw the background color */
+              cr = gdk_cairo_create (widget->window);
+              cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+              cairo_set_source_rgba (cr, PANEL_GDKCOLOR_TO_DOUBLE (color), alpha);
+              gdk_cairo_rectangle (cr, &event->area);
+              cairo_fill (cr);
+              cairo_destroy (cr);
+            }
+        }
+    }
 
-      /* set the cairo source color */
-      cairo_set_source_rgba (cr, PANEL_GDKCOLOR_TO_DOUBLE (color),
-                             plug->background_alpha);
+  return GTK_WIDGET_CLASS (wrapper_plug_parent_class)->expose_event (widget, event);
+}
 
-      /* create retangle */
-      cairo_rectangle (cr, event->area.x, event->area.y,
-                       event->area.width, event->area.height);
 
-      /* draw on source */
-      cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
 
-      /* paint rectangle */
-      cairo_fill (cr);
+static void
+wrapper_plug_background_reset (WrapperPlug *plug)
+{
+  panel_return_if_fail (WRAPPER_IS_PLUG (plug));
 
-      /* destroy cairo context */
-      cairo_destroy (cr);
-    }
+  if (plug->background_color != NULL)
+    gdk_color_free (plug->background_color);
+  plug->background_color = NULL;
 
-  return GTK_WIDGET_CLASS (wrapper_plug_parent_class)->expose_event (widget, event);
+  if (plug->background_image_cache != NULL)
+    cairo_pattern_destroy (plug->background_image_cache);
+  plug->background_image_cache = NULL;
+
+  g_free (plug->background_image);
+  plug->background_image = NULL;
 }
 
 
@@ -220,12 +275,7 @@ wrapper_plug_set_background_color (WrapperPlug *plug,
 
   panel_return_if_fail (WRAPPER_IS_PLUG (plug));
 
-  if (plug->background_color != NULL)
-    gdk_color_free (plug->background_color);
-  plug->background_color = NULL;
-
-  g_free (plug->background_image);
-  plug->background_image = NULL;
+  wrapper_plug_background_reset (plug);
 
   if (color_string != NULL
       && gdk_color_parse (color_string, &color))
@@ -241,4 +291,10 @@ wrapper_plug_set_background_image (WrapperPlug *plug,
                                    const gchar *image)
 {
   panel_return_if_fail (WRAPPER_IS_PLUG (plug));
+
+  wrapper_plug_background_reset (plug);
+
+  plug->background_image = g_strdup (image);
+
+  gtk_widget_queue_draw (GTK_WIDGET (plug));
 }



More information about the Xfce4-commits mailing list