Author: kelnos
Date: 2006-07-14 21:49:22 +0000 (Fri, 14 Jul 2006)
New Revision: 22449
Modified:
xfdesktop/trunk/src/xfce-desktop.c
Log:
redo how the backdrop is drawn to fix ugly gradients on 16-bit displays
(bug 1819). this also makes drawing quite a bit simpler and possibly even
a bit faster.
Modified: xfdesktop/trunk/src/xfce-desktop.c
===================================================================
--- xfdesktop/trunk/src/xfce-desktop.c 2006-07-14 18:49:46 UTC (rev 22448)
+++ xfdesktop/trunk/src/xfce-desktop.c 2006-07-14 21:49:22 UTC (rev 22449)
@@ -223,6 +223,8 @@
{
gchar property_name[128];
+ gdk_error_trap_push();
+
g_snprintf(property_name, 128, XFDESKTOP_IMAGE_FILE_FMT, monitor);
if(filename) {
gdk_property_change(gdk_screen_get_root_window(desktop->priv->gscreen),
@@ -234,19 +236,47 @@
gdk_property_delete(gdk_screen_get_root_window(desktop->priv->gscreen),
gdk_atom_intern(property_name, FALSE));
}
+
+ gdk_error_trap_pop();
}
static void
+set_real_root_window_pixmap(GdkScreen *gscreen,
+ GdkPixmap *pmap)
+{
+ Window xid;
+ GdkWindow *groot;
+
+ xid = GDK_DRAWABLE_XID(pmap);
+ groot = gdk_screen_get_root_window(gscreen);
+
+ gdk_error_trap_push();
+
+ /* set root property for transparent Eterms */
+ gdk_property_change(groot,
+ gdk_atom_intern("_XROOTPMAP_ID", FALSE),
+ gdk_atom_intern("PIXMAP", FALSE), 32,
+ GDK_PROP_MODE_REPLACE, (guchar *)&xid, 1);
+ /* set this other property because someone might need it sometime. */
+ gdk_property_change(groot,
+ gdk_atom_intern("ESETROOT_PMAP_ID", FALSE),
+ gdk_atom_intern("PIXMAP", FALSE), 32,
+ GDK_PROP_MODE_REPLACE, (guchar *)&xid, 1);
+ /* and set the root window's BG pixmap, because aterm is somewhat lame. */
+ gdk_window_set_back_pixmap(groot, pmap, FALSE);
+ /* there really should be a standard for this crap... */
+
+ gdk_error_trap_pop();
+}
+
+static void
backdrop_changed_cb(XfceBackdrop *backdrop, gpointer user_data)
{
XfceDesktop *desktop = XFCE_DESKTOP(user_data);
+ GdkPixmap *pmap = desktop->priv->bg_pixmap;
+ GdkScreen *gscreen = desktop->priv->gscreen;
GdkPixbuf *pix;
- GdkPixmap *pmap = NULL;
- GdkColormap *cmap;
- GdkScreen *gscreen;
GdkRectangle rect;
- Pixmap xid;
- GdkWindow *groot;
gint i, monitor = -1;
TRACE("entering");
@@ -258,9 +288,6 @@
TRACE("really entering");
- gscreen = desktop->priv->gscreen;
- cmap =
gdk_drawable_get_colormap(GDK_DRAWABLE(GTK_WIDGET(desktop)->window));
-
for(i = 0; i < XFCE_DESKTOP(desktop)->priv->nbackdrops; i++) {
if(backdrop == XFCE_DESKTOP(desktop)->priv->backdrops[i]) {
monitor = i;
@@ -275,86 +302,24 @@
if(!pix)
return;
- if(desktop->priv->nbackdrops == 1) {
- /* optimised for single monitor: just dump the pixbuf into a pixmap */
- gdk_pixbuf_render_pixmap_and_mask_for_colormap(pix, cmap, &pmap, NULL,
0);
- g_object_unref(G_OBJECT(pix));
- if(!pmap)
- return;
+ if(desktop->priv->nbackdrops == 1) {
+ /* single monitor */
rect.x = rect.y = 0;
rect.width = gdk_screen_get_width(gscreen);
rect.height = gdk_screen_get_height(gscreen);
- } else {
- /* multiple monitors (xinerama): download the current backdrop, paint
- * over the correct area, and upload it back. this is slow, but
- * probably still faster than redoing the whole thing. */
- GdkPixmap *cur_pmap = NULL;
- GdkPixbuf *cur_pbuf = NULL;
- gint swidth, sheight;
-
- swidth = gdk_screen_get_width(gscreen);
- sheight = gdk_screen_get_height(gscreen);
-
- cur_pmap = desktop->priv->bg_pixmap;
- if(cur_pmap) {
- gint pw, ph;
- gdk_drawable_get_size(GDK_DRAWABLE(cur_pmap), &pw, &ph);
- if(pw == swidth && ph == sheight) {
- cur_pbuf = gdk_pixbuf_get_from_drawable(NULL,
- GDK_DRAWABLE(cur_pmap), cmap, 0, 0, 0, 0, swidth,
- sheight);
- } else
- cur_pmap = NULL;
- }
- /* if the style's bg_pixmap was empty, or the above failed... */
- if(!cur_pmap) {
- cur_pbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8,
- swidth, sheight);
- }
-
+ } else
gdk_screen_get_monitor_geometry(gscreen, monitor, &rect);
- gdk_pixbuf_copy_area(pix, 0, 0, gdk_pixbuf_get_width(pix),
- gdk_pixbuf_get_height(pix), cur_pbuf, rect.x, rect.y);
- g_object_unref(G_OBJECT(pix));
- pmap = NULL;
- gdk_pixbuf_render_pixmap_and_mask_for_colormap(cur_pbuf, cmap,
- &pmap, NULL, 0);
- g_object_unref(G_OBJECT(cur_pbuf));
- if(!pmap)
- return;
- }
+
+ gdk_draw_pixbuf(GDK_DRAWABLE(pmap), GTK_WIDGET(desktop)->style->black_gc,
+ pix, 0, 0, rect.x, rect.y,
+ gdk_pixbuf_get_width(pix), gdk_pixbuf_get_height(pix),
+ GDK_RGB_DITHER_MAX, 0, 0);
+ g_object_unref(G_OBJECT(pix));
- xid = GDK_DRAWABLE_XID(pmap);
- groot = gdk_screen_get_root_window(gscreen);
-
- gdk_error_trap_push();
-
- /* set root property for transparent Eterms */
- gdk_property_change(groot,
- gdk_atom_intern("_XROOTPMAP_ID", FALSE),
- gdk_atom_intern("PIXMAP", FALSE), 32,
- GDK_PROP_MODE_REPLACE, (guchar *)&xid, 1);
- /* set this other property because someone might need it sometime. */
- gdk_property_change(groot,
- gdk_atom_intern("ESETROOT_PMAP_ID", FALSE),
- gdk_atom_intern("PIXMAP", FALSE), 32,
- GDK_PROP_MODE_REPLACE, (guchar *)&xid, 1);
- /* and set the root window's BG pixmap, because aterm is somewhat lame. */
- gdk_window_set_back_pixmap(groot, pmap, FALSE);
- /* there really should be a standard for this crap... */
-
- /* clear the old pixmap, if any */
- if(desktop->priv->bg_pixmap)
- g_object_unref(G_OBJECT(desktop->priv->bg_pixmap));
-
- /* set the new pixmap and tell gtk to redraw it */
- desktop->priv->bg_pixmap = pmap;
- gdk_window_set_back_pixmap(GTK_WIDGET(desktop)->window, pmap, FALSE);
+ /* tell gtk to redraw the repainted area */
gtk_widget_queue_draw_area(GTK_WIDGET(desktop), rect.x, rect.y,
rect.width, rect.height);
- gdk_error_trap_pop();
-
set_imgfile_root_property(desktop,
xfce_backdrop_get_image_filename(backdrop),
monitor);
@@ -374,10 +339,13 @@
gtk_widget_set_size_request(GTK_WIDGET(desktop), w, h);
gtk_window_resize(GTK_WINDOW(desktop), w, h);
- if(desktop->priv->bg_pixmap) {
- g_object_unref(G_OBJECT(desktop->priv->bg_pixmap));
- desktop->priv->bg_pixmap = NULL;
- }
+ g_object_unref(G_OBJECT(desktop->priv->bg_pixmap));
+ desktop->priv->bg_pixmap =
gdk_pixmap_new(GDK_DRAWABLE(GTK_WIDGET(desktop)->window),
+ w, h, -1);
+ set_real_root_window_pixmap(desktop->priv->gscreen,
+ desktop->priv->bg_pixmap);
+ gdk_window_set_back_pixmap(GTK_WIDGET(desktop)->window,
+ desktop->priv->bg_pixmap, FALSE);
/* special case for 1 backdrop to handle xinerama stretching properly.
* this is broken if it ever becomes possible to change the number of
@@ -452,8 +420,6 @@
}
}
-
-
static void
screen_set_selection(XfceDesktop *desktop)
{
@@ -554,7 +520,7 @@
{
XfceDesktop *desktop = XFCE_DESKTOP(widget);
GdkAtom atom;
- gint i;
+ gint i, sw, sh;
Window xid;
GdkDisplay *gdpy;
GdkWindow *groot;
@@ -563,6 +529,8 @@
TRACE("entering");
gtk_window_set_screen(GTK_WINDOW(desktop), desktop->priv->gscreen);
+ sw = gdk_screen_get_width(desktop->priv->gscreen);
+ sh = gdk_screen_get_height(desktop->priv->gscreen);
/* chain up */
GTK_WIDGET_CLASS(xfce_desktop_parent_class)->realize(widget);
@@ -571,9 +539,7 @@
if(GTK_WIDGET_DOUBLE_BUFFERED(GTK_WIDGET(desktop)))
gtk_widget_set_double_buffered(GTK_WIDGET(desktop), FALSE);
- gtk_widget_set_size_request(GTK_WIDGET(desktop),
- gdk_screen_get_width(desktop->priv->gscreen),
- gdk_screen_get_height(desktop->priv->gscreen));
+ gtk_widget_set_size_request(GTK_WIDGET(desktop), sw, sh);
gtk_window_move(GTK_WINDOW(desktop), 0, 0);
atom = gdk_atom_intern("_NET_WM_WINDOW_TYPE_DESKTOP", FALSE);
@@ -608,6 +574,13 @@
rect.width, rect.height);
}
+ desktop->priv->bg_pixmap =
gdk_pixmap_new(GDK_DRAWABLE(GTK_WIDGET(desktop)->window),
+ sw, sh, -1);
+ set_real_root_window_pixmap(desktop->priv->gscreen,
+ desktop->priv->bg_pixmap);
+ gdk_window_set_back_pixmap(GTK_WIDGET(desktop)->window,
+ desktop->priv->bg_pixmap, FALSE);
+
for(i = 0; i < desktop->priv->nbackdrops; i++) {
g_signal_connect(G_OBJECT(desktop->priv->backdrops[i]), "changed",
G_CALLBACK(backdrop_changed_cb), desktop);
@@ -648,6 +621,7 @@
gdk_property_delete(groot, gdk_atom_intern("NAUTILUS_DESKTOP_WINDOW_ID",
FALSE));
gdk_property_delete(groot, gdk_atom_intern("_XROOTPMAP_ID", FALSE));
gdk_property_delete(groot, gdk_atom_intern("ESETROOT_PMAP_ID", FALSE));
+ gdk_window_set_back_pixmap(groot, NULL, FALSE);
if(desktop->priv->backdrops) {
for(i = 0; i < desktop->priv->nbackdrops; i++) {
@@ -659,10 +633,8 @@
desktop->priv->backdrops = NULL;
}
- if(desktop->priv->bg_pixmap) {
- g_object_unref(G_OBJECT(desktop->priv->bg_pixmap));
- desktop->priv->bg_pixmap = NULL;
- }
+ g_object_unref(G_OBJECT(desktop->priv->bg_pixmap));
+ desktop->priv->bg_pixmap = NULL;
gtk_window_set_icon(GTK_WINDOW(widget), NULL);
@@ -720,10 +692,8 @@
{
XfceDesktop *desktop = XFCE_DESKTOP(w);
- if(desktop->priv->bg_pixmap) {
- gdk_window_set_back_pixmap(w->window, desktop->priv->bg_pixmap, FALSE);
- gtk_widget_queue_draw(w);
- }
+ gdk_window_set_back_pixmap(w->window, desktop->priv->bg_pixmap, FALSE);
+ gtk_widget_queue_draw(w);
}
_______________________________________________
Xfce4-commits mailing list
[email protected]
http://foo-projects.org/mailman/listinfo/xfce4-commits