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 Xfce4-commits@xfce.org http://foo-projects.org/mailman/listinfo/xfce4-commits