[Xfce4-commits] <xfce4-panel:master> Add support for more background options (bug #1731).
Nick Schermer
noreply at xfce.org
Sun May 9 22:30:01 CEST 2010
Updating branch refs/heads/master
to 8c9fcef677f360e82f5a8de7d3bbf7a2e206d55e (commit)
from 5db31ffd871d39cbe4fb51862405aafac5cf1d0d (commit)
commit 8c9fcef677f360e82f5a8de7d3bbf7a2e206d55e
Author: Nick Schermer <nick at xfce.org>
Date: Sun Apr 25 11:34:05 2010 +0200
Add support for more background options (bug #1731).
Add support for colored and image backgrounds. This makes theming the
panel a lot easier and allows us to handle the colors and image
positioning in the external plugins.
The background image does not apply to the autohide window.
common/panel-dbus.h | 3 +
common/panel-xfconf.c | 5 +-
libxfce4panel/xfce-panel-macros-46.h | 115 +++++++++--
libxfce4panel/xfce-panel-plugin-provider.h | 1 +
panel/panel-application.c | 12 +
panel/panel-base-window.c | 302 ++++++++++++++++++++++++---
panel/panel-base-window.h | 15 ++-
panel/panel-plugin-external-46.c | 259 ++++++++++++++++--------
panel/panel-plugin-external-46.h | 8 +-
panel/panel-plugin-external.c | 59 ++++++
panel/panel-plugin-external.h | 6 +
panel/panel-preferences-dialog.c | 144 +++++++++++++-
panel/panel-preferences-dialog.glade | 184 +++++++++++++++---
panel/panel-window.c | 30 +++-
wrapper/main.c | 20 ++-
wrapper/wrapper-plug.c | 179 ++++++++++++++---
wrapper/wrapper-plug.h | 6 +
17 files changed, 1134 insertions(+), 214 deletions(-)
diff --git a/common/panel-dbus.h b/common/panel-dbus.h
index 611456c..32d8c39 100644
--- a/common/panel-dbus.h
+++ b/common/panel-dbus.h
@@ -38,6 +38,9 @@
#define SIGNAL_WRAPPER_SET_SENSITIVE "i"
#define SIGNAL_WRAPPER_BACKGROUND_ALPHA "j"
#define SIGNAL_WRAPPER_QUIT "k"
+#define SIGNAL_WRAPPER_BACKGROUND_COLOR "l"
+#define SIGNAL_WRAPPER_BACKGROUND_IMAGE "m"
+#define SIGNAL_WRAPPER_BACKGROUND_UNSET "n"
/* special types for dbus communication */
#define PANEL_TYPE_DBUS_SET_MESSAGE \
diff --git a/common/panel-xfconf.c b/common/panel-xfconf.c
index ccae3ae..5d45d11 100644
--- a/common/panel-xfconf.c
+++ b/common/panel-xfconf.c
@@ -109,7 +109,10 @@ panel_properties_bind (XfconfChannel *channel,
if (save_properties)
panel_properties_store_value (channel, property, prop->type, object, prop->property);
- xfconf_g_property_bind (channel, property, prop->type, object, prop->property);
+ if (G_LIKELY (prop->type != GDK_TYPE_COLOR))
+ xfconf_g_property_bind (channel, property, prop->type, object, prop->property);
+ else
+ xfconf_g_property_bind_gdkcolor (channel, property, object, prop->property);
g_free (property);
}
diff --git a/libxfce4panel/xfce-panel-macros-46.h b/libxfce4panel/xfce-panel-macros-46.h
index 2a6f3e5..e29acad 100644
--- a/libxfce4panel/xfce-panel-macros-46.h
+++ b/libxfce4panel/xfce-panel-macros-46.h
@@ -50,7 +50,9 @@ enum /*< skip >*/
PANEL_CLIENT_EVENT_SET_SIZE,
PANEL_CLIENT_EVENT_SHOW_ABOUT,
PANEL_CLIENT_EVENT_SHOW_CONFIGURE,
- PANEL_CLIENT_EVENT_QUIT
+ PANEL_CLIENT_EVENT_QUIT,
+ PANEL_CLIENT_EVENT_SET_BG_COLOR,
+ PANEL_CLIENT_EVENT_UNSET_BG
};
/*< private >*/
@@ -274,9 +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 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) \
@@ -357,6 +363,19 @@ enum /*< skip >*/
_xpp_quit_main_loop (); \
break; \
\
+ case PANEL_CLIENT_EVENT_SET_BG_COLOR: \
+ _xpp_bg_color.red = event->data.s[1]; \
+ _xpp_bg_color.green = event->data.s[2]; \
+ _xpp_bg_color.blue = event->data.s[3]; \
+ _xpp_bg_style = 1; \
+ gtk_widget_queue_draw (plug); \
+ break; \
+ \
+ case PANEL_CLIENT_EVENT_UNSET_BG: \
+ _xpp_bg_style = 0; \
+ gtk_widget_queue_draw (plug); \
+ break; \
+ \
default: \
g_warning ("Received unknow client event %d", message); \
break; \
@@ -417,29 +436,78 @@ enum /*< skip >*/
_xpp_expose_event (GtkWidget *plug, \
GdkEventExpose *event) \
{ \
- cairo_t *cr; \
- GdkColor *color; \
+ cairo_t *cr; \
+ const GdkColor *color; \
+ gdouble real_alpha; \
+ GdkPixbuf *pixbuf; \
+ GError *error = NULL; \
+ \
+ if (!GTK_WIDGET_DRAWABLE (plug)) \
+ return FALSE; \
\
- if (_xpp_composited \
- && GTK_WIDGET_DRAWABLE (plug) \
- && _xpp_alpha < 1.00) \
+ 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); \
\
- color = &(gtk_widget_get_style (plug)->bg[GTK_STATE_NORMAL]); \
- cairo_set_source_rgba (cr, \
- color->red / 65535.00, \
- color->green / 65535.00, \
- color->blue / 65535.00, \
- _xpp_alpha); \
- \
- cairo_rectangle (cr, event->area.x, event->area.y, \
- event->area.width, event->area.height); \
+ 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_fill (cr); \
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); \
+ gdk_cairo_rectangle (cr, &event->area); \
+ cairo_fill (cr); \
+ cairo_destroy (cr); \
+ } \
+ } \
\
return FALSE; \
} \
@@ -524,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 f1a32a0..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>
@@ -268,6 +270,9 @@ panel_application_xfconf_window_bindings (PanelApplication *application,
{ "enter-opacity", G_TYPE_UINT },
{ "leave-opacity", G_TYPE_UINT },
{ "background-alpha", G_TYPE_UINT },
+ { "background-style", G_TYPE_UINT },
+ { "background-color", GDK_TYPE_COLOR },
+ { "background-image", G_TYPE_STRING },
{ "output-name", G_TYPE_STRING },
{ "position", G_TYPE_STRING },
{ "disable-struts", G_TYPE_BOOLEAN },
@@ -616,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 77eb5fe..ae51528 100644
--- a/panel/panel-base-window.c
+++ b/panel/panel-base-window.c
@@ -61,8 +61,14 @@ static void panel_base_window_update_provider_info (GtkWidget
gpointer user_data);
static gboolean panel_base_window_active_timeout (gpointer user_data);
static void panel_base_window_active_timeout_destroyed (gpointer user_data);
+static void panel_base_window_set_plugin_data (PanelBaseWindow *window,
+ GtkCallback func);
static void panel_base_window_set_plugin_background_alpha (GtkWidget *widget,
gpointer user_data);
+static void panel_base_window_set_plugin_background_color (GtkWidget *widget,
+ gpointer user_data);
+static void panel_base_window_set_plugin_background_image (GtkWidget *widget,
+ gpointer user_data);
@@ -75,19 +81,24 @@ enum
PROP_BORDERS,
PROP_ACTIVE,
PROP_COMPOSITED,
+ PROP_BACKGROUND_STYLE,
+ PROP_BACKGROUND_COLOR,
+ PROP_BACKGROUND_IMAGE
};
struct _PanelBaseWindowPrivate
{
- /* borders */
- PanelBorders borders;
+ PanelBorders borders;
- /* settings */
- gdouble enter_opacity;
- gdouble leave_opacity;
+ /* background image cache */
+ cairo_pattern_t *bg_image_cache;
+
+ /* transparency settings */
+ gdouble enter_opacity;
+ gdouble leave_opacity;
/* active window timeout id */
- guint active_timeout_id;
+ guint active_timeout_id;
};
@@ -138,6 +149,29 @@ panel_base_window_class_init (PanelBaseWindowClass *klass)
EXO_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
+ PROP_BACKGROUND_STYLE,
+ g_param_spec_uint ("background-style",
+ NULL, NULL,
+ PANEL_BG_STYLE_NONE,
+ PANEL_BG_STYLE_IMAGE,
+ PANEL_BG_STYLE_NONE,
+ EXO_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_BACKGROUND_COLOR,
+ g_param_spec_boxed ("background-color",
+ NULL, NULL,
+ GDK_TYPE_COLOR,
+ EXO_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_BACKGROUND_IMAGE,
+ g_param_spec_string ("background-image",
+ NULL, NULL,
+ NULL,
+ EXO_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
PROP_BORDERS,
g_param_spec_uint ("borders",
NULL, NULL,
@@ -169,12 +203,16 @@ panel_base_window_init (PanelBaseWindow *window)
window->is_composited = FALSE;
window->background_alpha = 1.00;
+ window->background_style = PANEL_BG_STYLE_NONE;
+ window->background_image = NULL;
+ window->background_color = NULL;
+ window->priv->bg_image_cache = NULL;
+
window->priv->enter_opacity = 1.00;
window->priv->leave_opacity = 1.00;
window->priv->borders = PANEL_BORDER_NONE;
window->priv->active_timeout_id = 0;
- /* set colormap */
panel_base_window_composited_changed (GTK_WIDGET (window));
}
@@ -203,6 +241,18 @@ panel_base_window_get_property (GObject *object,
g_value_set_uint (value, rint (window->background_alpha * 100.00));
break;
+ case PROP_BACKGROUND_STYLE:
+ g_value_set_uint (value, window->background_style);
+ break;
+
+ case PROP_BACKGROUND_COLOR:
+ g_value_set_boxed (value, window->background_color);
+ break;
+
+ case PROP_BACKGROUND_IMAGE:
+ g_value_set_string (value, window->background_image);
+ break;
+
case PROP_BORDERS:
g_value_set_uint (value, priv->borders);
break;
@@ -231,7 +281,7 @@ panel_base_window_set_property (GObject *object,
{
PanelBaseWindow *window = PANEL_BASE_WINDOW (object);
PanelBaseWindowPrivate *priv = window->priv;
- GtkWidget *itembar;
+ PanelBgStyle bg_style;
switch (prop_id)
{
@@ -254,10 +304,74 @@ panel_base_window_set_property (GObject *object,
gtk_widget_queue_draw (GTK_WIDGET (object));
/* send the new background alpha to the external plugins */
- itembar = gtk_bin_get_child (GTK_BIN (window));
- if (G_LIKELY (itembar != NULL))
- gtk_container_foreach (GTK_CONTAINER (itembar),
- panel_base_window_set_plugin_background_alpha, window);
+ panel_base_window_set_plugin_data (window,
+ panel_base_window_set_plugin_background_alpha);
+ break;
+
+ case PROP_BACKGROUND_STYLE:
+ bg_style = g_value_get_uint (value);
+ if (window->background_style != bg_style)
+ {
+ window->background_style = bg_style;
+
+ if (priv->bg_image_cache != NULL)
+ {
+ /* destroy old image cache */
+ cairo_pattern_destroy (priv->bg_image_cache);
+ priv->bg_image_cache = NULL;
+ }
+
+ /* send information to external plugins */
+ if (window->background_style == PANEL_BG_STYLE_IMAGE
+ && window->background_image != NULL)
+ {
+ panel_base_window_set_plugin_data (window,
+ panel_base_window_set_plugin_background_image);
+ }
+ else if (window->background_style == PANEL_BG_STYLE_NONE
+ || (window->background_style == PANEL_BG_STYLE_COLOR
+ && window->background_color != NULL))
+ {
+ panel_base_window_set_plugin_data (window,
+ panel_base_window_set_plugin_background_color);
+ }
+
+ /* resize to update border size too */
+ gtk_widget_queue_resize (GTK_WIDGET (window));
+ }
+ break;
+
+ case PROP_BACKGROUND_COLOR:
+ if (window->background_color != NULL)
+ gdk_color_free (window->background_color);
+ window->background_color = g_value_dup_boxed (value);
+
+ if (window->background_style == PANEL_BG_STYLE_COLOR)
+ {
+ panel_base_window_set_plugin_data (window,
+ panel_base_window_set_plugin_background_color);
+ gtk_widget_queue_draw (GTK_WIDGET (window));
+ }
+ break;
+
+ case PROP_BACKGROUND_IMAGE:
+ /* store new filename */
+ g_free (window->background_image);
+ window->background_image = g_value_dup_string (value);
+
+ /* drop old cache */
+ if (priv->bg_image_cache != NULL)
+ {
+ cairo_pattern_destroy (priv->bg_image_cache);
+ priv->bg_image_cache = NULL;
+ }
+
+ if (window->background_style == PANEL_BG_STYLE_IMAGE)
+ {
+ panel_base_window_set_plugin_data (window,
+ panel_base_window_set_plugin_background_image);
+ gtk_widget_queue_draw (GTK_WIDGET (window));
+ }
break;
case PROP_BORDERS:
@@ -299,11 +413,18 @@ panel_base_window_set_property (GObject *object,
static void
panel_base_window_finalize (GObject *object)
{
- PanelBaseWindowPrivate *priv = PANEL_BASE_WINDOW (object)->priv;
+ PanelBaseWindow *window = PANEL_BASE_WINDOW (object);
/* stop running marching ants timeout */
- if (priv->active_timeout_id != 0)
- g_source_remove (priv->active_timeout_id);
+ if (window->priv->active_timeout_id != 0)
+ g_source_remove (window->priv->active_timeout_id);
+
+ /* release bg image data */
+ g_free (window->background_image);
+ if (window->priv->bg_image_cache != NULL)
+ cairo_pattern_destroy (window->priv->bg_image_cache);
+ if (window->background_color != NULL)
+ gdk_color_free (window->background_color);
(*G_OBJECT_CLASS (panel_base_window_parent_class)->finalize) (object);
}
@@ -315,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;
@@ -324,6 +445,9 @@ panel_base_window_expose_event (GtkWidget *widget,
const gdouble dashes[] = { 4.00, 4.00 };
GTimeVal timeval;
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);
@@ -337,27 +461,77 @@ panel_base_window_expose_event (GtkWidget *widget,
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
cairo_set_line_width (cr, 1.00);
- /* clip the drawing area */
+ /* set rectangle to clip the drawing area */
gdk_cairo_rectangle (cr, &event->area);
- /* get background alpha */
- alpha = window->is_composited ? window->background_alpha : 1.00;
-
- /* only do something with the background when compositing is enabled */
- if (G_UNLIKELY (alpha < 1.00))
+ if (window->background_style == PANEL_BG_STYLE_IMAGE)
{
- /* clip the drawing area, but preserve the rectangle */
- cairo_clip_preserve (cr);
+ /* clip the drawing area */
+ cairo_clip (cr);
+
+ 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)
+ {
+ /* load the image in a pixbuf */
+ pixbuf = gdk_pixbuf_new_from_file (window->background_image, &error);
+
+ if (G_LIKELY (pixbuf != NULL))
+ {
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
+ g_object_unref (G_OBJECT (pixbuf));
- /* make the background transparent */
- color = &(widget->style->bg[GTK_STATE_NORMAL]);
- panel_util_set_source_rgba (cr, color, alpha);
- cairo_fill (cr);
+ priv->bg_image_cache = cairo_get_source (cr);
+ cairo_pattern_reference (priv->bg_image_cache);
+ cairo_pattern_set_extend (priv->bg_image_cache, CAIRO_EXTEND_REPEAT);
+ cairo_paint (cr);
+ }
+ else
+ {
+ /* print error message */
+ g_warning ("Background image disabled, \"%s\" could not be loaded: %s",
+ window->background_image, error != NULL ? error->message : "No error");
+ g_error_free (error);
+
+ /* disable background image mode */
+ window->background_style = PANEL_BG_STYLE_NONE;
+ }
+ }
}
else
{
- /* clip the drawing area */
- cairo_clip (cr);
+ /* get background alpha */
+ alpha = window->is_composited ? window->background_alpha : 1.00;
+
+ /* get the background color */
+ if (window->background_style == PANEL_BG_STYLE_COLOR)
+ color = window->background_color;
+ else
+ color = &(widget->style->bg[GTK_STATE_NORMAL]);
+
+ /* only do something with the background when compositing is enabled */
+ if (G_UNLIKELY (alpha < 1.00
+ || window->background_style != PANEL_BG_STYLE_NONE))
+ {
+ /* clip the drawing area, but preserve the rectangle */
+ cairo_clip_preserve (cr);
+
+ /* draw the background */
+ panel_util_set_source_rgba (cr, color, alpha);
+ cairo_fill (cr);
+ }
+ else
+ {
+ /* clip the drawing area */
+ cairo_clip (cr);
+ }
}
/* draw marching ants selection if the timeout is running */
@@ -375,7 +549,7 @@ panel_base_window_expose_event (GtkWidget *widget,
cairo_rectangle (cr, 0.5, 0.5, width - 1, height - 1);
cairo_stroke (cr);
}
- else
+ else if (window->background_style == PANEL_BG_STYLE_NONE)
{
if (PANEL_HAS_FLAG (priv->borders, PANEL_BORDER_BOTTOM | PANEL_BORDER_RIGHT))
{
@@ -483,6 +657,13 @@ panel_base_window_composited_changed (GtkWidget *widget)
gtk_widget_unrealize (widget);
}
+ /* clear cairo image cache */
+ if (window->priv->bg_image_cache != NULL)
+ {
+ cairo_pattern_destroy (window->priv->bg_image_cache);
+ window->priv->bg_image_cache = NULL;
+ }
+
/* get the widget screen */
screen = gtk_window_get_screen (GTK_WINDOW (widget));
panel_return_if_fail (GDK_IS_SCREEN (screen));
@@ -567,6 +748,19 @@ panel_base_window_active_timeout_destroyed (gpointer user_data)
static void
+panel_base_window_set_plugin_data (PanelBaseWindow *window,
+ GtkCallback func)
+{
+ GtkWidget *itembar;
+
+ itembar = gtk_bin_get_child (GTK_BIN (window));
+ if (G_LIKELY (itembar != NULL))
+ gtk_container_foreach (GTK_CONTAINER (itembar), func, window);
+}
+
+
+
+static void
panel_base_window_set_plugin_background_alpha (GtkWidget *widget,
gpointer user_data)
{
@@ -584,6 +778,44 @@ panel_base_window_set_plugin_background_alpha (GtkWidget *widget,
+static void
+panel_base_window_set_plugin_background_color (GtkWidget *widget,
+ gpointer user_data)
+{
+ PanelBaseWindow *window = PANEL_BASE_WINDOW (user_data);
+ GdkColor *color;
+
+ panel_return_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (widget));
+ panel_return_if_fail (PANEL_IS_BASE_WINDOW (user_data));
+
+ /* send null if the style is not a bg color */
+ color = window->background_style == PANEL_BG_STYLE_COLOR ? window->background_color : NULL;
+
+ if (PANEL_IS_PLUGIN_EXTERNAL (widget))
+ panel_plugin_external_set_background_color (PANEL_PLUGIN_EXTERNAL (widget), color);
+ else if (PANEL_IS_PLUGIN_EXTERNAL_46 (widget))
+ panel_plugin_external_46_set_background_color (PANEL_PLUGIN_EXTERNAL_46 (widget), color);
+}
+
+
+
+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);
+}
+
+
+
void
panel_base_window_move_resize (PanelBaseWindow *window,
gint x,
@@ -629,6 +861,8 @@ panel_base_window_get_borders (PanelBaseWindow *window)
if (priv->active_timeout_id != 0)
return PANEL_BORDER_TOP | PANEL_BORDER_BOTTOM
| PANEL_BORDER_LEFT | PANEL_BORDER_RIGHT;
+ else if (window->background_style != PANEL_BG_STYLE_NONE)
+ return PANEL_BORDER_NONE;
return priv->borders;
}
@@ -636,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 78333e4..f74ac13 100644
--- a/panel/panel-base-window.h
+++ b/panel/panel-base-window.h
@@ -27,6 +27,7 @@ typedef struct _PanelBaseWindowClass PanelBaseWindowClass;
typedef struct _PanelBaseWindow PanelBaseWindow;
typedef struct _PanelBaseWindowPrivate PanelBaseWindowPrivate;
typedef enum _PanelBorders PanelBorders;
+typedef enum _PanelBgStyle PanelBgStyle;
#define PANEL_TYPE_BASE_WINDOW (panel_base_window_get_type ())
#define PANEL_BASE_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PANEL_TYPE_BASE_WINDOW, PanelBaseWindow))
@@ -44,6 +45,13 @@ enum _PanelBorders
PANEL_BORDER_BOTTOM = 1 << 3
};
+enum _PanelBgStyle
+{
+ PANEL_BG_STYLE_NONE,
+ PANEL_BG_STYLE_COLOR,
+ PANEL_BG_STYLE_IMAGE
+};
+
struct _PanelBaseWindowClass
{
GtkWindowClass __parent__;
@@ -56,9 +64,12 @@ struct _PanelBaseWindow
/*< private >*/
PanelBaseWindowPrivate *priv;
- /*< private >*/
guint is_composited : 1;
+
gdouble background_alpha;
+ PanelBgStyle background_style;
+ GdkColor *background_color;
+ gchar *background_image;
};
GType panel_base_window_get_type (void) G_GNUC_CONST;
@@ -77,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 415d615..2e7c030 100644
--- a/panel/panel-plugin-external-46.c
+++ b/panel/panel-plugin-external-46.c
@@ -48,53 +48,55 @@
-static void panel_plugin_external_46_provider_init (XfcePanelPluginProviderInterface *iface);
-static void panel_plugin_external_46_finalize (GObject *object);
-static void panel_plugin_external_46_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-static void panel_plugin_external_46_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
-static void panel_plugin_external_46_realize (GtkWidget *widget);
-static void panel_plugin_external_46_unrealize (GtkWidget *widget);
-static gboolean panel_plugin_external_46_client_event (GtkWidget *widget,
- GdkEventClient *event);
-static gboolean panel_plugin_external_46_plug_removed (GtkSocket *socket);
-static void panel_plugin_external_46_plug_added (GtkSocket *socket);
-static void panel_plugin_external_46_send_client_event (PanelPluginExternal46 *external,
- gint message,
- gint value);
-static void panel_plugin_external_46_queue_add (PanelPluginExternal46 *external,
- gint message,
- gint value);
-static const gchar *panel_plugin_external_46_get_name (XfcePanelPluginProvider *provider);
-static gint panel_plugin_external_46_get_unique_id (XfcePanelPluginProvider *provider);
-static void panel_plugin_external_46_set_size (XfcePanelPluginProvider *provider,
- gint size);
-static void panel_plugin_external_46_set_orientation (XfcePanelPluginProvider *provider,
- GtkOrientation orientation);
-static void panel_plugin_external_46_set_screen_position (XfcePanelPluginProvider *provider,
- XfceScreenPosition screen_position);
-static void panel_plugin_external_46_save (XfcePanelPluginProvider *provider);
-static gboolean panel_plugin_external_46_get_show_configure (XfcePanelPluginProvider *provider);
-static void panel_plugin_external_46_show_configure (XfcePanelPluginProvider *provider);
-static gboolean panel_plugin_external_46_get_show_about (XfcePanelPluginProvider *provider);
-static void panel_plugin_external_46_show_about (XfcePanelPluginProvider *provider);
-static void panel_plugin_external_46_removed (XfcePanelPluginProvider *provider);
-static gboolean panel_plugin_external_46_remote_event (XfcePanelPluginProvider *provider,
- const gchar *name,
- const GValue *value,
- guint *handler_id);
-static void panel_plugin_external_46_set_locked (XfcePanelPluginProvider *provider,
- gboolean locked);
-static void panel_plugin_external_46_set_sensitive (PanelPluginExternal46 *external);
-static void panel_plugin_external_46_child_watch (GPid pid,
- gint status,
- gpointer user_data);
-static void panel_plugin_external_46_child_watch_destroyed (gpointer user_data);
+static void panel_plugin_external_46_provider_init (XfcePanelPluginProviderInterface *iface);
+static void panel_plugin_external_46_finalize (GObject *object);
+static void panel_plugin_external_46_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void panel_plugin_external_46_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void panel_plugin_external_46_realize (GtkWidget *widget);
+static void panel_plugin_external_46_unrealize (GtkWidget *widget);
+static gboolean panel_plugin_external_46_client_event (GtkWidget *widget,
+ GdkEventClient *event);
+static gboolean panel_plugin_external_46_plug_removed (GtkSocket *socket);
+static void panel_plugin_external_46_plug_added (GtkSocket *socket);
+static void panel_plugin_external_46_send_client_event (PanelPluginExternal46 *external,
+ GdkEventClient *event);
+static void panel_plugin_external_46_send_client_event_simple (PanelPluginExternal46 *external,
+ gint message,
+ gint value);
+static void panel_plugin_external_46_queue_add (PanelPluginExternal46 *external,
+ gint message,
+ gint value);
+static const gchar *panel_plugin_external_46_get_name (XfcePanelPluginProvider *provider);
+static gint panel_plugin_external_46_get_unique_id (XfcePanelPluginProvider *provider);
+static void panel_plugin_external_46_set_size (XfcePanelPluginProvider *provider,
+ gint size);
+static void panel_plugin_external_46_set_orientation (XfcePanelPluginProvider *provider,
+ GtkOrientation orientation);
+static void panel_plugin_external_46_set_screen_position (XfcePanelPluginProvider *provider,
+ XfceScreenPosition screen_position);
+static void panel_plugin_external_46_save (XfcePanelPluginProvider *provider);
+static gboolean panel_plugin_external_46_get_show_configure (XfcePanelPluginProvider *provider);
+static void panel_plugin_external_46_show_configure (XfcePanelPluginProvider *provider);
+static gboolean panel_plugin_external_46_get_show_about (XfcePanelPluginProvider *provider);
+static void panel_plugin_external_46_show_about (XfcePanelPluginProvider *provider);
+static void panel_plugin_external_46_removed (XfcePanelPluginProvider *provider);
+static gboolean panel_plugin_external_46_remote_event (XfcePanelPluginProvider *provider,
+ const gchar *name,
+ const GValue *value,
+ guint *handler_id);
+static void panel_plugin_external_46_set_locked (XfcePanelPluginProvider *provider,
+ gboolean locked);
+static void panel_plugin_external_46_set_sensitive (PanelPluginExternal46 *external);
+static void panel_plugin_external_46_child_watch (GPid pid,
+ gint status,
+ gpointer user_data);
+static void panel_plugin_external_46_child_watch_destroyed (gpointer user_data);
@@ -126,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;
@@ -139,13 +144,6 @@ enum
PROP_ARGUMENTS
};
-typedef struct
-{
- gint message;
- gint value;
-}
-QueueItem;
-
static GdkAtom panel_atom = GDK_NONE;
@@ -218,6 +216,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",
@@ -262,11 +261,12 @@ panel_plugin_external_46_finalize (GObject *object)
if (external->queue != NULL)
{
for (li = external->queue; li != NULL; li = li->next)
- g_slice_free (QueueItem, li->data);
+ g_slice_free (GdkEventClient, li->data);
g_slist_free (external->queue);
}
g_strfreev (external->arguments);
+ g_free (external->background_image);
if (external->restart_timer != NULL)
g_timer_destroy (external->restart_timer);
@@ -374,6 +374,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++)
@@ -420,7 +425,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);
@@ -433,7 +438,7 @@ panel_plugin_external_46_unrealize (GtkWidget *widget)
}
/* quit the plugin */
- panel_plugin_external_46_send_client_event (external, PANEL_CLIENT_EVENT_QUIT, FALSE);
+ panel_plugin_external_46_send_client_event_simple (external, PANEL_CLIENT_EVENT_QUIT, FALSE);
(*GTK_WIDGET_CLASS (panel_plugin_external_46_parent_class)->unrealize) (widget);
}
@@ -547,13 +552,13 @@ panel_plugin_external_46_plug_added (GtkSocket *socket)
{
PanelPluginExternal46 *external = PANEL_PLUGIN_EXTERNAL_46 (socket);
GSList *li;
- QueueItem *item;
+ GdkEventClient *event;
/* plug has been added */
external->plug_embedded = TRUE;
panel_debug (PANEL_DEBUG_DOMAIN_EXTERNAL46,
- "plugin %d has been embedded, %d values 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 */
@@ -562,11 +567,9 @@ panel_plugin_external_46_plug_added (GtkSocket *socket)
external->queue = g_slist_reverse (external->queue);
for (li = external->queue; li != NULL; li = li->next)
{
- item = li->data;
- panel_plugin_external_46_send_client_event (external,
- item->message,
- item->value);
- g_slice_free (QueueItem, item);
+ event = li->data;
+ panel_plugin_external_46_send_client_event (external, event);
+ g_slice_free (GdkEventClient, event);
}
g_slist_free (external->queue);
@@ -578,30 +581,44 @@ panel_plugin_external_46_plug_added (GtkSocket *socket)
static void
panel_plugin_external_46_send_client_event (PanelPluginExternal46 *external,
- gint message,
- gint value)
+ GdkEventClient *event)
{
- GdkEventClient event;
-
panel_return_if_fail (PANEL_IS_PLUGIN_EXTERNAL_46 (external));
panel_return_if_fail (panel_atom != GDK_NONE);
panel_return_if_fail (GDK_IS_WINDOW (GTK_WIDGET (external)->window));
- event.type = GDK_CLIENT_EVENT;
- event.window = GTK_WIDGET (external)->window;
- event.send_event = TRUE;
- event.message_type = panel_atom;
- event.data_format = 16;
- event.data.s[0] = message;
- event.data.s[1] = value;
- event.data.s[2] = 0;
+ /* complete event information */
+ event->type = GDK_CLIENT_EVENT;
+ event->window = GTK_WIDGET (external)->window;
+ event->send_event = TRUE;
+ event->message_type = panel_atom;
gdk_error_trap_push ();
- gdk_event_send_client_message ((GdkEvent *) &event,
+ gdk_event_send_client_message ((GdkEvent *) event,
GDK_WINDOW_XID (gtk_socket_get_plug_window (GTK_SOCKET (external))));
gdk_flush ();
if (gdk_error_trap_pop () != 0)
- g_warning ("Failed to send client event %d", message);
+ g_warning ("Failed to send client event %d", event->data.s[0]);
+}
+
+
+
+static void
+panel_plugin_external_46_send_client_event_simple (PanelPluginExternal46 *external,
+ gint message,
+ gint value)
+{
+ GdkEventClient event;
+
+ panel_return_if_fail (PANEL_IS_PLUGIN_EXTERNAL_46 (external));
+
+ /* set event data */
+ event.data_format = 16;
+ event.data.s[0] = message;
+ event.data.s[1] = value;
+ event.data.s[2] = 0;
+
+ panel_plugin_external_46_send_client_event (external, &event);
}
@@ -611,23 +628,24 @@ panel_plugin_external_46_queue_add (PanelPluginExternal46 *external,
gint message,
gint value)
{
- QueueItem *item;
+ GdkEventClient *event;
panel_return_if_fail (PANEL_IS_PLUGIN_EXTERNAL_46 (external));
if (external->plug_embedded)
{
/* directly send the message */
- panel_plugin_external_46_send_client_event (external, message, value);
+ panel_plugin_external_46_send_client_event_simple (external, message, value);
}
else
{
/* queue the message until the plug is embedded */
- item = g_slice_new0 (QueueItem);
- item->message = message;
- item->value = value;
+ event = g_slice_new0 (GdkEventClient);
+ event->data_format = 16;
+ event->data.s[0] = message;
+ event->data.s[1] = value;
- external->queue = g_slist_prepend (external->queue, item);
+ external->queue = g_slist_prepend (external->queue, event);
}
}
@@ -839,7 +857,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) */
@@ -892,3 +910,74 @@ panel_plugin_external_46_set_background_alpha (PanelPluginExternal46 *external,
PANEL_CLIENT_EVENT_SET_BACKGROUND_ALPHA,
rint (alpha * 100.0));
}
+
+
+
+void
+panel_plugin_external_46_set_background_color (PanelPluginExternal46 *external,
+ const GdkColor *color)
+{
+ GdkEventClient *event;
+
+ panel_return_if_fail (PANEL_IS_PLUGIN_EXTERNAL_46 (external));
+
+ event = g_slice_new0 (GdkEventClient);
+
+ if (color != NULL)
+ {
+ event->data_format = 16;
+ event->data.s[0] = PANEL_CLIENT_EVENT_SET_BG_COLOR;
+ event->data.s[1] = color->red;
+ event->data.s[2] = color->green;
+ event->data.s[3] = color->blue;
+ event->data.s[4] = 0;
+ }
+ else
+ {
+ event->data_format = 16;
+ event->data.s[0] = PANEL_CLIENT_EVENT_UNSET_BG;
+ }
+
+ if (external->plug_embedded)
+ {
+ /* directly send the event */
+ panel_plugin_external_46_send_client_event (external, event);
+ g_slice_free (GdkEventClient, event);
+ }
+ else
+ {
+ /* queue the event until the plug is embedded */
+ external->queue = g_slist_prepend (external->queue, event);
+ }
+}
+
+
+void
+panel_plugin_external_46_set_background_image (PanelPluginExternal46 *external,
+ 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 f5cb4c2..4b2ae26 100644
--- a/panel/panel-plugin-external-46.h
+++ b/panel/panel-plugin-external-46.h
@@ -42,9 +42,15 @@ GtkWidget *panel_plugin_external_46_new (PanelModule
gint unique_id,
gchar **arguments) G_GNUC_MALLOC;
-void panel_plugin_external_46_set_background_alpha (PanelPluginExternal46 *external,
+void panel_plugin_external_46_set_background_alpha (PanelPluginExternal46 *external,
gdouble alpha);
+void panel_plugin_external_46_set_background_color (PanelPluginExternal46 *external,
+ const GdkColor *color);
+
+void panel_plugin_external_46_set_background_image (PanelPluginExternal46 *external,
+ const gchar *image);
+
G_END_DECLS
#endif /* !__PANEL_PLUGIN_EXTERNAL_46_H__ */
diff --git a/panel/panel-plugin-external.c b/panel/panel-plugin-external.c
index a31dc45..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))
@@ -1040,3 +1041,61 @@ panel_plugin_external_set_background_alpha (PanelPluginExternal *external,
g_value_unset (&value);
}
+
+
+
+void
+panel_plugin_external_set_background_color (PanelPluginExternal *external,
+ const GdkColor *color)
+{
+ GValue value = { 0, };
+ const gchar *prop;
+
+ panel_return_if_fail (PANEL_IS_PLUGIN_EXTERNAL (external));
+
+ if (G_LIKELY (color != NULL))
+ {
+ prop = SIGNAL_WRAPPER_BACKGROUND_COLOR;
+
+ g_value_init (&value, G_TYPE_STRING);
+ g_value_take_string (&value, gdk_color_to_string (color));
+ }
+ else
+ {
+ prop = SIGNAL_WRAPPER_BACKGROUND_UNSET;
+
+ g_value_init (&value, G_TYPE_BOOLEAN);
+ }
+
+ panel_plugin_external_queue_add (external, FALSE, prop, &value);
+
+ g_value_unset (&value);
+}
+
+
+
+void
+panel_plugin_external_set_background_image (PanelPluginExternal *external,
+ const gchar *image)
+{
+ GValue value = { 0, };
+
+ panel_return_if_fail (PANEL_IS_PLUGIN_EXTERNAL (external));
+
+ if (G_UNLIKELY (image != NULL))
+ {
+ g_value_init (&value, G_TYPE_STRING);
+ g_value_set_string (&value, image);
+
+ panel_plugin_external_queue_add (external, FALSE,
+ SIGNAL_WRAPPER_BACKGROUND_IMAGE,
+ &value);
+
+ g_value_unset (&value);
+ }
+ else
+ {
+ /* unset the bg */
+ panel_plugin_external_set_background_color (external, NULL);
+ }
+}
diff --git a/panel/panel-plugin-external.h b/panel/panel-plugin-external.h
index 04c0a1b..7864ad7 100644
--- a/panel/panel-plugin-external.h
+++ b/panel/panel-plugin-external.h
@@ -45,6 +45,12 @@ GtkWidget *panel_plugin_external_new (PanelModule *mod
void panel_plugin_external_set_background_alpha (PanelPluginExternal *external,
gdouble alpha);
+void panel_plugin_external_set_background_color (PanelPluginExternal *external,
+ const GdkColor *color);
+
+void panel_plugin_external_set_background_image (PanelPluginExternal *external,
+ const gchar *image);
+
G_END_DECLS
#endif /* !__PANEL_PLUGIN_EXTERNAL_H__ */
diff --git a/panel/panel-preferences-dialog.c b/panel/panel-preferences-dialog.c
index aca1304..1e80f49 100644
--- a/panel/panel-preferences-dialog.c
+++ b/panel/panel-preferences-dialog.c
@@ -53,6 +53,10 @@ static void panel_preferences_dialog_bindings_update (PanelPreferencesDialog *di
static void panel_preferences_dialog_output_changed (GtkComboBox *combobox, PanelPreferencesDialog *dialog);
+static void panel_preferences_dialog_bg_style_changed (PanelPreferencesDialog *dialog);
+static void panel_preferences_dialog_bg_image_file_set (GtkFileChooserButton *button, PanelPreferencesDialog *dialog);
+static void panel_preferences_dialog_bg_image_notified (PanelPreferencesDialog *dialog);
+
static void panel_preferences_dialog_panel_combobox_changed (GtkComboBox *combobox, PanelPreferencesDialog *dialog);
static void panel_preferences_dialog_panel_combobox_rebuild (PanelPreferencesDialog *dialog);
static void panel_preferences_dialog_panel_add (GtkWidget *widget, PanelPreferencesDialog *dialog);
@@ -108,6 +112,9 @@ struct _PanelPreferencesDialog
/* changed signal for the active panel's itembar */
gulong items_changed_handler_id;
+ /* background image watch */
+ gulong bg_image_notify_handler_id;
+
/* changed signal for the output selector */
gulong output_changed_handler_id;
};
@@ -167,6 +174,22 @@ panel_preferences_dialog_init (PanelPreferencesDialog *dialog)
connect_signal ("panel-remove", "clicked", panel_preferences_dialog_panel_remove);
connect_signal ("panel-combobox", "changed", panel_preferences_dialog_panel_combobox_changed);
+ /* style tab */
+ object = gtk_builder_get_object (GTK_BUILDER (dialog), "background-style");
+ panel_return_if_fail (G_IS_OBJECT (object));
+ g_signal_connect_swapped (G_OBJECT (object), "changed",
+ G_CALLBACK (panel_preferences_dialog_bg_style_changed), dialog);
+
+ object = gtk_builder_get_object (GTK_BUILDER (dialog), "composited");
+ panel_return_if_fail (G_IS_OBJECT (object));
+ g_signal_connect_swapped (G_OBJECT (object), "notify::visible",
+ G_CALLBACK (panel_preferences_dialog_bg_style_changed), dialog);
+
+ object = gtk_builder_get_object (GTK_BUILDER (dialog), "background-image");
+ panel_return_if_fail (GTK_IS_FILE_CHOOSER_BUTTON (object));
+ g_signal_connect (G_OBJECT (object), "file-set",
+ G_CALLBACK (panel_preferences_dialog_bg_image_file_set), dialog);
+
/* items treeview and buttons */
connect_signal ("item-up", "clicked", panel_preferences_dialog_item_move);
connect_signal ("item-down", "clicked", panel_preferences_dialog_item_move);
@@ -232,12 +255,24 @@ panel_preferences_dialog_finalize (GObject *object)
PanelPreferencesDialog *dialog = PANEL_PREFERENCES_DIALOG (object);
GtkWidget *itembar;
- /* disconnect changed signal */
- if (dialog->active != NULL && dialog->items_changed_handler_id != 0)
+ /* free bindings list */
+ g_slist_free (dialog->bindings);
+
+ if (dialog->active != NULL)
{
- itembar = gtk_bin_get_child (GTK_BIN (dialog->active));
- g_signal_handler_disconnect (G_OBJECT (itembar),
- dialog->items_changed_handler_id);
+ if (dialog->items_changed_handler_id != 0)
+ {
+ /* disconnect changed signal */
+ itembar = gtk_bin_get_child (GTK_BIN (dialog->active));
+ g_signal_handler_disconnect (G_OBJECT (itembar),
+ dialog->items_changed_handler_id);
+ }
+
+ if (dialog->bg_image_notify_handler_id != 0)
+ {
+ g_signal_handler_disconnect (G_OBJECT (dialog->active),
+ dialog->bg_image_notify_handler_id);
+ }
}
/* deselect all windows */
@@ -278,7 +313,7 @@ panel_preferences_dialog_bindings_unbind (PanelPreferencesDialog *dialog)
{
GSList *li;
- if (dialog->bindings)
+ if (dialog->bindings != NULL)
{
/* remove all bindings */
for (li = dialog->bindings; li != NULL; li = li->next)
@@ -287,6 +322,18 @@ panel_preferences_dialog_bindings_unbind (PanelPreferencesDialog *dialog)
g_slist_free (dialog->bindings);
dialog->bindings = NULL;
}
+
+ /* disconnect image watch */
+ if (dialog->bg_image_notify_handler_id != 0)
+ {
+ if (dialog->active != NULL)
+ {
+ g_signal_handler_disconnect (G_OBJECT (dialog->active),
+ dialog->bg_image_notify_handler_id);
+ }
+
+ dialog->bg_image_notify_handler_id = 0;
+ }
}
@@ -346,6 +393,13 @@ panel_preferences_dialog_bindings_update (PanelPreferencesDialog *dialog)
panel_preferences_dialog_bindings_add (dialog, "enter-opacity", "value");
panel_preferences_dialog_bindings_add (dialog, "leave-opacity", "value");
panel_preferences_dialog_bindings_add (dialog, "composited", "visible");
+ panel_preferences_dialog_bindings_add (dialog, "background-style", "active");
+ panel_preferences_dialog_bindings_add (dialog, "background-color", "color");
+
+ /* watch image changes from the panel */
+ dialog->bg_image_notify_handler_id = g_signal_connect_swapped (G_OBJECT (dialog->active),
+ "notify::background-image", G_CALLBACK (panel_preferences_dialog_bg_image_notified), dialog);
+ panel_preferences_dialog_bg_image_notified (dialog);
/* get run mode of the driver (multiple screens or randr) */
display = gtk_widget_get_display (GTK_WIDGET (dialog->active));
@@ -508,6 +562,84 @@ panel_preferences_dialog_output_changed (GtkComboBox *combobox,
static void
+panel_preferences_dialog_bg_style_changed (PanelPreferencesDialog *dialog)
+{
+ gint active;
+ GObject *object;
+ gboolean composited;
+
+ panel_return_if_fail (PANEL_IS_PREFERENCES_DIALOG (dialog));
+ panel_return_if_fail (PANEL_WINDOW (dialog->active));
+
+ object = gtk_builder_get_object (GTK_BUILDER (dialog), "background-style");
+ panel_return_if_fail (GTK_IS_COMBO_BOX (object));
+ active = gtk_combo_box_get_active (GTK_COMBO_BOX (object));
+
+ object = gtk_builder_get_object (GTK_BUILDER (dialog), "bg-alpha-box");
+ panel_return_if_fail (GTK_IS_WIDGET (object));
+ g_object_get (G_OBJECT (dialog->active), "composited", &composited, NULL);
+ g_object_set (G_OBJECT (object), "visible", composited && active < 2, NULL);
+
+ object = gtk_builder_get_object (GTK_BUILDER (dialog), "bg-color-box");
+ panel_return_if_fail (GTK_IS_WIDGET (object));
+ g_object_set (G_OBJECT (object), "visible", active == 1, NULL);
+
+ object = gtk_builder_get_object (GTK_BUILDER (dialog), "bg-image-box");
+ panel_return_if_fail (GTK_IS_WIDGET (object));
+ g_object_set (G_OBJECT (object), "visible", active == 2, NULL);
+}
+
+
+
+static void
+panel_preferences_dialog_bg_image_file_set (GtkFileChooserButton *button,
+ PanelPreferencesDialog *dialog)
+{
+ gchar *filename;
+
+ panel_return_if_fail (GTK_IS_FILE_CHOOSER_BUTTON (button));
+ panel_return_if_fail (PANEL_IS_PREFERENCES_DIALOG (dialog));
+ panel_return_if_fail (PANEL_IS_WINDOW (dialog->active));
+
+ g_signal_handler_block (G_OBJECT (dialog->active),
+ dialog->bg_image_notify_handler_id);
+
+ filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (button));
+ g_object_set (G_OBJECT (dialog->active), "background-image", filename, NULL);
+ g_free (filename);
+
+ g_signal_handler_unblock (G_OBJECT (dialog->active),
+ dialog->bg_image_notify_handler_id);
+}
+
+
+
+static void
+panel_preferences_dialog_bg_image_notified (PanelPreferencesDialog *dialog)
+{
+ gchar *filename;
+ GObject *button;
+
+ panel_return_if_fail (PANEL_IS_PREFERENCES_DIALOG (dialog));
+ panel_return_if_fail (PANEL_IS_WINDOW (dialog->active));
+
+ button = gtk_builder_get_object (GTK_BUILDER (dialog), "background-image");
+ panel_return_if_fail (GTK_IS_FILE_CHOOSER_BUTTON (button));
+
+ g_signal_handlers_block_by_func (G_OBJECT (button),
+ G_CALLBACK (panel_preferences_dialog_bg_image_file_set), dialog);
+
+ g_object_get (G_OBJECT (dialog->active), "background-image", &filename, NULL);
+ gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (button), filename != NULL ? filename : "");
+ g_free (filename);
+
+ g_signal_handlers_unblock_by_func (G_OBJECT (button),
+ G_CALLBACK (panel_preferences_dialog_bg_image_file_set), dialog);
+}
+
+
+
+static void
panel_preferences_dialog_panel_sensitive (PanelPreferencesDialog *dialog)
{
diff --git a/panel/panel-preferences-dialog.glade b/panel/panel-preferences-dialog.glade
index eafa71a..9c8485b 100644
--- a/panel/panel-preferences-dialog.glade
+++ b/panel/panel-preferences-dialog.glade
@@ -31,6 +31,23 @@
<column type="gchararray"/>
</columns>
</object>
+ <object class="GtkListStore" id="styles-store">
+ <columns>
+ <!-- column-name title -->
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0" translatable="yes">None (use system style)</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">Solid color</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">Background image</col>
+ </row>
+ </data>
+ </object>
<object class="XfceTitledDialog" id="dialog">
<property name="title" translatable="yes">Xfce Panel</property>
<property name="window_position">center-on-parent</property>
@@ -349,11 +366,12 @@
</child>
<child>
<object class="GtkCheckButton" id="length-adjust">
- <property name="label" translatable="yes">Automatically increase the length</property>
+ <property name="label" translatable="yes">A_utomatically increase the length</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Select this option to automatically increase the length of the panel if the plugins request more space.</property>
+ <property name="use_underline">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
@@ -394,7 +412,7 @@
</packing>
</child>
<child>
- <object class="GtkVBox" id="composited">
+ <object class="GtkVBox" id="vbox7">
<property name="visible">True</property>
<property name="border_width">6</property>
<property name="orientation">vertical</property>
@@ -409,35 +427,151 @@
<property name="visible">True</property>
<property name="left_padding">12</property>
<child>
- <object class="GtkHBox" id="hbox2">
+ <object class="GtkVBox" id="vbox4">
<property name="visible">True</property>
<property name="border_width">6</property>
- <property name="spacing">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
<child>
- <object class="GtkLabel" id="label7">
+ <object class="GtkHBox" id="hbox2">
<property name="visible">True</property>
- <property name="label" translatable="yes" comments="I18N: label for the background alha slider">_Alpha:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">alpha-scale</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Style:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">background-style</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="background-style">
+ <property name="visible">True</property>
+ <property name="model">styles-store</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext4"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
</object>
<packing>
- <property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
- <object class="GtkHScale" id="alpha-scale">
+ <object class="GtkHBox" id="bg-alpha-box">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="tooltip_text" translatable="yes">Alpha value of the panel background, between 0 (transparent) and 100 (opaque).</property>
- <property name="adjustment">background-alpha</property>
- <property name="digits">0</property>
- <property name="value_pos">right</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label15">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Alpha:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">bg-alpha-scale</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHScale" id="bg-alpha-scale">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip_text" translatable="yes">Alpha value of the panel background, between 0 (transparent) and 100 (opaq
+ue).</property>
+ <property name="adjustment">background-alpha</property>
+ <property name="digits">0</property>
+ <property name="value_pos">right</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
+ <child>
+ <object class="GtkHBox" id="bg-color-box">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label16">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">C_olor:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">background-color</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkColorButton" id="background-color">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="title" translatable="yes">Pick a Panel Color</property>
+ <property name="color">#000000000000</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="bg-image-box">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label19">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_File:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">background-image</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFileChooserButton" id="background-image">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Select A Background Image</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
</object>
</child>
</object>
@@ -458,14 +592,13 @@
</packing>
</child>
<child>
- <object class="GtkFrame" id="frame4">
+ <object class="GtkFrame" id="composited">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkAlignment" id="alignment4">
<property name="visible">True</property>
- <property name="bottom_padding">6</property>
<property name="left_padding">12</property>
<child>
<object class="GtkTable" id="table2">
@@ -558,7 +691,7 @@
<child type="tab">
<object class="GtkLabel" id="label12">
<property name="visible">True</property>
- <property name="label" translatable="yes">C_ompositing</property>
+ <property name="label" translatable="yes">Appeara_nce</property>
<property name="use_underline">True</property>
</object>
<packing>
@@ -822,17 +955,18 @@
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
- <object class="GtkSizeGroup" id="composing-sizegroup">
+ <object class="GtkSizeGroup" id="display-sizegroup">
<widgets>
- <widget name="label7"/>
- <widget name="label9"/>
- <widget name="label10"/>
+ <widget name="label13"/>
+ <widget name="label1"/>
</widgets>
</object>
- <object class="GtkSizeGroup" id="display-sizegroup">
+ <object class="GtkSizeGroup" id="bg-sizegroup">
<widgets>
- <widget name="label1"/>
- <widget name="label13"/>
+ <widget name="label7"/>
+ <widget name="label15"/>
+ <widget name="label16"/>
+ <widget name="label19"/>
</widgets>
</object>
</interface>
diff --git a/panel/panel-window.c b/panel/panel-window.c
index 3d3dcb8..c13e340 100644
--- a/panel/panel-window.c
+++ b/panel/panel-window.c
@@ -1972,7 +1972,8 @@ panel_window_set_autohide (PanelWindow *window,
GtkWidget *popup;
guint i;
const gchar *properties[] = { "enter-opacity", "leave-opacity",
- "background-alpha", "borders" };
+ "background-alpha", "borders",
+ "background-style", "background-color" };
panel_return_if_fail (PANEL_IS_WINDOW (window));
@@ -2326,20 +2327,41 @@ void
panel_window_set_povider_info (PanelWindow *window,
GtkWidget *provider)
{
+ PanelBaseWindow *base_window = PANEL_BASE_WINDOW (window);
+
panel_return_if_fail (PANEL_IS_WINDOW (window));
panel_return_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider));
xfce_panel_plugin_provider_set_locked (XFCE_PANEL_PLUGIN_PROVIDER (provider),
panel_window_get_locked (window));
- if (PANEL_BASE_WINDOW (window)->background_alpha < 1.0)
+ if (base_window->background_alpha < 1.0)
{
if (PANEL_IS_PLUGIN_EXTERNAL (provider))
panel_plugin_external_set_background_alpha (PANEL_PLUGIN_EXTERNAL (provider),
- PANEL_BASE_WINDOW (window)->background_alpha);
+ base_window->background_alpha);
else if (PANEL_IS_PLUGIN_EXTERNAL_46 (provider))
panel_plugin_external_46_set_background_alpha (PANEL_PLUGIN_EXTERNAL_46 (provider),
- PANEL_BASE_WINDOW (window)->background_alpha);
+ base_window->background_alpha);
+ }
+
+ if (base_window->background_style == PANEL_BG_STYLE_COLOR)
+ {
+ if (PANEL_IS_PLUGIN_EXTERNAL (provider))
+ panel_plugin_external_set_background_color (PANEL_PLUGIN_EXTERNAL (provider),
+ base_window->background_color);
+ else if (PANEL_IS_PLUGIN_EXTERNAL_46 (provider))
+ panel_plugin_external_46_set_background_color (PANEL_PLUGIN_EXTERNAL_46 (provider),
+ base_window->background_color);
+ }
+ else if (base_window->background_style == PANEL_BG_STYLE_IMAGE)
+ {
+ if (PANEL_IS_PLUGIN_EXTERNAL (provider))
+ panel_plugin_external_set_background_image (PANEL_PLUGIN_EXTERNAL (provider),
+ base_window->background_image);
+ else if (PANEL_IS_PLUGIN_EXTERNAL_46 (provider))
+ panel_plugin_external_46_set_background_image (PANEL_PLUGIN_EXTERNAL_46 (provider),
+ base_window->background_image);
}
panel_window_set_plugin_orientation (provider, window);
diff --git a/wrapper/main.c b/wrapper/main.c
index 69e83d5..36a9ea8 100644
--- a/wrapper/main.c
+++ b/wrapper/main.c
@@ -90,11 +90,6 @@ wrapper_gproxy_set (DBusGProxy *dbus_gproxy,
xfce_panel_plugin_provider_set_screen_position (provider, g_value_get_uint (value));
else if (strcmp (property, SIGNAL_SET_LOCKED) == 0)
xfce_panel_plugin_provider_set_locked (provider, g_value_get_boolean (value));
- else if (strcmp (property, SIGNAL_WRAPPER_BACKGROUND_ALPHA) == 0)
- {
- plug = g_object_get_qdata (G_OBJECT (provider), plug_quark);
- wrapper_plug_set_background_alpha (plug, g_value_get_double (value));
- }
else if (strcmp (property, SIGNAL_SAVE) == 0)
xfce_panel_plugin_provider_save (provider);
else if (strcmp (property, SIGNAL_SHOW_CONFIGURE) == 0)
@@ -108,7 +103,20 @@ wrapper_gproxy_set (DBusGProxy *dbus_gproxy,
else if (strcmp (property, SIGNAL_WRAPPER_QUIT) == 0)
gtk_main_quit ();
else
- panel_assert_not_reached ();
+ {
+ plug = g_object_get_qdata (G_OBJECT (provider), plug_quark);
+
+ if (strcmp (property, SIGNAL_WRAPPER_BACKGROUND_ALPHA) == 0)
+ wrapper_plug_set_background_alpha (plug, g_value_get_double (value));
+ else if (strcmp (property, SIGNAL_WRAPPER_BACKGROUND_COLOR) == 0)
+ wrapper_plug_set_background_color (plug, g_value_get_string (value));
+ else if (strcmp (property, SIGNAL_WRAPPER_BACKGROUND_IMAGE) == 0)
+ wrapper_plug_set_background_image (plug, g_value_get_string (value));
+ else if (strcmp (property, SIGNAL_WRAPPER_BACKGROUND_UNSET) == 0)
+ wrapper_plug_set_background_color (plug, NULL);
+ else
+ panel_assert_not_reached ();
+ }
g_free (property);
g_value_unset (value);
diff --git a/wrapper/wrapper-plug.c b/wrapper/wrapper-plug.c
index fcefe9c..cdeb124 100644
--- a/wrapper/wrapper-plug.c
+++ b/wrapper/wrapper-plug.c
@@ -29,8 +29,10 @@
-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);
@@ -43,11 +45,14 @@ struct _WrapperPlug
{
GtkPlug __parent__;
- /* background alpha */
- gdouble background_alpha;
-
/* 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;
+ cairo_pattern_t *background_image_cache;
};
@@ -64,8 +69,12 @@ G_DEFINE_TYPE (WrapperPlug, wrapper_plug, GTK_TYPE_PLUG)
static void
wrapper_plug_class_init (WrapperPlugClass *klass)
{
+ GObjectClass *gobject_class;
GtkWidgetClass *gtkwidget_class;
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = wrapper_plug_finalize;
+
gtkwidget_class = GTK_WIDGET_CLASS (klass);
gtkwidget_class->expose_event = wrapper_plug_expose_event;
}
@@ -79,6 +88,9 @@ wrapper_plug_init (WrapperPlug *plug)
GdkScreen *screen;
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");
@@ -110,43 +122,113 @@ wrapper_plug_init (WrapperPlug *plug)
+static void
+wrapper_plug_finalize (GObject *object)
+{
+ wrapper_plug_background_reset (WRAPPER_PLUG (object));
+
+ G_OBJECT_CLASS (wrapper_plug_parent_class)->finalize (object);
+}
+
+
+
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)
+ 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);
+ 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
+ {
+ 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);
+ }
+ }
+ }
- /* get the background gdk color */
- color = &(widget->style->bg[state]);
+ return GTK_WIDGET_CLASS (wrapper_plug_parent_class)->expose_event (widget, event);
+}
- /* set the cairo source color */
- cairo_set_source_rgba (cr, PANEL_GDKCOLOR_TO_DOUBLE (color),
- plug->background_alpha);
- /* 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);
+static void
+wrapper_plug_background_reset (WrapperPlug *plug)
+{
+ panel_return_if_fail (WRAPPER_IS_PLUG (plug));
- /* paint rectangle */
- cairo_fill (cr);
+ if (plug->background_color != NULL)
+ gdk_color_free (plug->background_color);
+ plug->background_color = NULL;
- /* destroy cairo context */
- cairo_destroy (cr);
- }
+ if (plug->background_image_cache != NULL)
+ cairo_pattern_destroy (plug->background_image_cache);
+ plug->background_image_cache = NULL;
- return GTK_WIDGET_CLASS (wrapper_plug_parent_class)->expose_event (widget, event);
+ g_free (plug->background_image);
+ plug->background_image = NULL;
}
@@ -181,3 +263,38 @@ wrapper_plug_set_background_alpha (WrapperPlug *plug,
if (plug->is_composited)
gtk_widget_queue_draw (GTK_WIDGET (plug));
}
+
+
+
+
+void
+wrapper_plug_set_background_color (WrapperPlug *plug,
+ const gchar *color_string)
+{
+ GdkColor color = { 0, };
+
+ panel_return_if_fail (WRAPPER_IS_PLUG (plug));
+
+ wrapper_plug_background_reset (plug);
+
+ if (color_string != NULL
+ && gdk_color_parse (color_string, &color))
+ plug->background_color = gdk_color_copy (&color);
+
+ gtk_widget_queue_draw (GTK_WIDGET (plug));
+}
+
+
+
+void
+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));
+}
diff --git a/wrapper/wrapper-plug.h b/wrapper/wrapper-plug.h
index 5a089af..ab0d3f5 100644
--- a/wrapper/wrapper-plug.h
+++ b/wrapper/wrapper-plug.h
@@ -44,6 +44,12 @@ WrapperPlug *wrapper_plug_new (GdkNativeWindow socket_id);
void wrapper_plug_set_background_alpha (WrapperPlug *plug,
gdouble alpha);
+void wrapper_plug_set_background_color (WrapperPlug *plug,
+ const gchar *color_string);
+
+void wrapper_plug_set_background_image (WrapperPlug *plug,
+ const gchar *image);
+
G_END_DECLS
#endif /* !__WRAPPER_PLUG_H__ */
More information about the Xfce4-commits
mailing list