diff options
-rw-r--r-- | ChangeLog | 23 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-background.c | 82 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-background.h | 7 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-directory-background.c | 150 | ||||
-rw-r--r-- | libnautilus-private/nautilus-background.c | 82 | ||||
-rw-r--r-- | libnautilus-private/nautilus-background.h | 7 | ||||
-rw-r--r-- | libnautilus-private/nautilus-directory-background.c | 150 |
7 files changed, 445 insertions, 56 deletions
@@ -1,3 +1,26 @@ +2000-08-15 Michael Engber <engber@eazel.com> + + Third cut at syncing our desktop background with GNOME's (bug 1047) + Now we update the GNOME desktop (root window) when we make changes. + Still need to handle nautilus getting notified when the capplet makes + changes. + + * libnautilus-extensions/nautilus-background.c: + (nautilus_background_initialize_class), + (nautilus_background_set_color_no_signal), + (nautilus_background_set_color), (load_image_callback), + (nautilus_background_set_image_uri_no_signal), + (nautilus_background_set_image_uri), + (nautilus_background_is_loaded), (nautilus_background_real_reset), + (nautilus_background_receive_dropped_color): + * libnautilus-extensions/nautilus-background.h: + * libnautilus-extensions/nautilus-directory-background.c: + (nautilus_directory_background_write_desktop_settings), + (nautilus_directory_background_write_desktop_default_settings), + (make_root_pixmap), (dispose_root_pixmap), (set_root_pixmap), + (image_loaded_callback), (nautilus_directory_update_root_window), + (background_changed_callback), (background_reset_callback): + 2000-08-15 Darin Adler <darin@eazel.com> * libnautilus-extensions/nautilus-search-uri.c: diff --git a/libnautilus-extensions/nautilus-background.c b/libnautilus-extensions/nautilus-background.c index e4a3a2a92..108f86f56 100644 --- a/libnautilus-extensions/nautilus-background.c +++ b/libnautilus-extensions/nautilus-background.c @@ -64,6 +64,7 @@ NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusBackground, nautilus_background, GTK_ enum { APPEARANCE_CHANGED, SETTINGS_CHANGED, + IMAGE_LOADED, RESET, LAST_SIGNAL }; @@ -108,6 +109,15 @@ nautilus_background_initialize_class (gpointer klass) gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); + signals[IMAGE_LOADED] = + gtk_signal_new ("image_loaded", + GTK_RUN_LAST | GTK_RUN_NO_RECURSE, + object_class->type, + GTK_SIGNAL_OFFSET (NautilusBackgroundClass, + image_loaded), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, + 0); signals[RESET] = gtk_signal_new ("reset", GTK_RUN_LAST | GTK_RUN_NO_RECURSE, @@ -532,25 +542,32 @@ nautilus_background_get_image_uri (NautilusBackground *background) return g_strdup (background->details->image_uri); } -void -nautilus_background_set_color (NautilusBackground *background, +static gboolean +nautilus_background_set_color_no_signal (NautilusBackground *background, const char *color) { - g_return_if_fail (NAUTILUS_IS_BACKGROUND (background)); + g_return_val_if_fail (NAUTILUS_IS_BACKGROUND (background), FALSE); if (nautilus_strcmp (background->details->color, color) == 0) { - return; + return FALSE; } g_free (background->details->color); background->details->color = g_strdup (color); + return TRUE; +} - gtk_signal_emit (GTK_OBJECT (background), - signals[SETTINGS_CHANGED]); - gtk_signal_emit (GTK_OBJECT (background), - signals[APPEARANCE_CHANGED]); +void +nautilus_background_set_color (NautilusBackground *background, + const char *color) +{ + if (nautilus_background_set_color_no_signal (background, color)) { + gtk_signal_emit (GTK_OBJECT (background), signals[SETTINGS_CHANGED]); + gtk_signal_emit (GTK_OBJECT (background), signals[APPEARANCE_CHANGED]); + } } + static void load_image_callback (GnomeVFSResult error, GdkPixbuf *pixbuf, @@ -575,6 +592,8 @@ load_image_callback (GnomeVFSResult error, gtk_signal_emit (GTK_OBJECT (background), signals[APPEARANCE_CHANGED]); + gtk_signal_emit (GTK_OBJECT (background), + signals[IMAGE_LOADED]); } static void @@ -602,14 +621,14 @@ nautilus_background_receive_dropped_background_image (NautilusBackground *backgr } } -void -nautilus_background_set_image_uri (NautilusBackground *background, +static gboolean +nautilus_background_set_image_uri_no_signal (NautilusBackground *background, const char *image_uri) { - g_return_if_fail (NAUTILUS_IS_BACKGROUND (background)); + g_return_val_if_fail (NAUTILUS_IS_BACKGROUND (background), FALSE); if (nautilus_strcmp (background->details->image_uri, image_uri) == 0) { - return; + return FALSE; } nautilus_cancel_gdk_pixbuf_load (background->details->load_image_handle); @@ -624,10 +643,17 @@ nautilus_background_set_image_uri (NautilusBackground *background, background->details->image_uri = g_strdup (image_uri); start_loading_image (background); - gtk_signal_emit (GTK_OBJECT (background), - signals[SETTINGS_CHANGED]); - gtk_signal_emit (GTK_OBJECT (background), - signals[APPEARANCE_CHANGED]); + return TRUE; +} + +void +nautilus_background_set_image_uri (NautilusBackground *background, + const char *image_uri) +{ + if (nautilus_background_set_image_uri_no_signal (background, image_uri)) { + gtk_signal_emit (GTK_OBJECT (background), signals[SETTINGS_CHANGED]); + gtk_signal_emit (GTK_OBJECT (background), signals[APPEARANCE_CHANGED]); + } } static GtkStyleClass * @@ -774,6 +800,16 @@ nautilus_background_is_set (NautilusBackground *background) background->details->image_uri != NULL; } +/* Returns false if the image is still loading, true + * if it's done loading or there is no image. + */ +gboolean +nautilus_background_is_loaded (NautilusBackground *background) +{ + return background->details->image_uri == NULL || + background->details->image != NULL; +} + /** * nautilus_background_reset: * @@ -790,8 +826,10 @@ nautilus_background_reset (NautilusBackground *background) static void nautilus_background_real_reset (NautilusBackground *background) { - nautilus_background_set_color (background, NULL); - nautilus_background_set_image_uri (background, NULL); + nautilus_background_set_color_no_signal (background, NULL); + nautilus_background_set_image_uri_no_signal (background, NULL); + gtk_signal_emit (GTK_OBJECT (background), signals[SETTINGS_CHANGED]); + gtk_signal_emit (GTK_OBJECT (background), signals[APPEARANCE_CHANGED]); } static void @@ -974,9 +1012,11 @@ nautilus_background_receive_dropped_color (NautilusBackground *background, g_free (color_spec); - nautilus_background_set_color (background, new_gradient_spec); - nautilus_background_set_image_uri (background, NULL); - + nautilus_background_set_color_no_signal (background, new_gradient_spec); + nautilus_background_set_image_uri_no_signal (background, NULL); + gtk_signal_emit (GTK_OBJECT (background), signals[SETTINGS_CHANGED]); + gtk_signal_emit (GTK_OBJECT (background), signals[APPEARANCE_CHANGED]); + g_free (new_gradient_spec); } diff --git a/libnautilus-extensions/nautilus-background.h b/libnautilus-extensions/nautilus-background.h index 843ebb164..1e653601d 100644 --- a/libnautilus-extensions/nautilus-background.h +++ b/libnautilus-extensions/nautilus-background.h @@ -80,12 +80,13 @@ void nautilus_background_set_image_placement (Nautil /* Calls to interrogate the current state of a background. */ char * nautilus_background_get_color (NautilusBackground *background); -char * nautilus_background_get_image_uri (NautilusBackground *background); +char * nautilus_background_get_image_uri (NautilusBackground *background); gboolean nautilus_background_get_combine_mode (NautilusBackground *background); nautilus_background_image_placement nautilus_background_get_image_placement (NautilusBackground *background); gboolean nautilus_background_is_dark (NautilusBackground *background); gboolean nautilus_background_is_set (NautilusBackground *background); +gboolean nautilus_background_is_loaded (NautilusBackground *background); /* Explicitly fills a rectangle with a background. */ void nautilus_background_draw (NautilusBackground *background, @@ -141,6 +142,10 @@ struct NautilusBackgroundClass */ void (* appearance_changed) (NautilusBackground *); + /* This signal is emitted whenever an image is loaded. + */ + void (* image_loaded) (NautilusBackground *); + /* This signal is emitted when the background is reset by receiving the reset property from a drag */ diff --git a/libnautilus-extensions/nautilus-directory-background.c b/libnautilus-extensions/nautilus-directory-background.c index d5812cfbc..9f08dbbf7 100644 --- a/libnautilus-extensions/nautilus-directory-background.c +++ b/libnautilus-extensions/nautilus-directory-background.c @@ -36,13 +36,16 @@ #include "nautilus-theme.h" #include "libnautilus-extensions/nautilus-gdk-extensions.h" +#include <gdk/gdkx.h> +#include <X11/Xatom.h> + static void background_changed_callback (NautilusBackground *background, NautilusDirectory *directory); static void directory_changed_callback (NautilusDirectory *directory, NautilusBackground *background); static void background_reset_callback (NautilusBackground *background, NautilusDirectory *directory); - + void static nautilus_directory_background_set_desktop (NautilusBackground *background) { @@ -257,10 +260,6 @@ nautilus_directory_background_write_desktop_settings (char *color, char *image, } gnome_config_sync (); - - /* FIXME - * Try to trick GNOME into re-reading the settings. - */ } static void @@ -272,7 +271,138 @@ nautilus_directory_background_write_desktop_default_settings () nautilus_background_image_placement placement; nautilus_directory_background_get_default_settings (TRUE, &color, &image, &placement, &combine); nautilus_directory_background_write_desktop_settings (color, image, placement, combine); -} +} + +/* Create a persistant pixmap. We create a separate display + * and set the closedown mode on it to RetainPermanent + * (copied from gnome-source/control-panels/capplets/background-properties/render-background.c) + */ +static GdkPixmap * +make_root_pixmap (gint width, gint height) +{ + Pixmap result; + + gdk_flush (); + + XSetCloseDownMode (gdk_display, RetainPermanent); + + result = XCreatePixmap (gdk_display, + DefaultRootWindow (gdk_display), + width, height, + DefaultDepthOfScreen (DefaultScreenOfDisplay (GDK_DISPLAY()))); + + return gdk_pixmap_foreign_new (result); +} + +/* (copied from gnome-source/control-panels/capplets/background-properties/render-background.c) + */ +static void +dispose_root_pixmap (GdkPixmap *pixmap) +{ + /* Unrefing a foreign pixmap causes it to be destroyed - so we include + * this bad hack, that will work for GTK+-1.2 until the problem + * is fixed in the next release + */ + + GdkWindowPrivate *private = (GdkWindowPrivate *)pixmap; + + gdk_xid_table_remove (private->xwindow); + g_dataset_destroy (private); + g_free (private); + +} + +/* Set the root pixmap, and properties pointing to it. We + * do this atomically with XGrabServer to make sure that + * we won't leak the pixmap if somebody else it setting + * it at the same time. (This assumes that they follow the + * same conventions we do + * (copied from gnome-source/control-panels/capplets/background-properties/render-background.c) + */ +static void +set_root_pixmap (GdkPixmap *pixmap) +{ + GdkAtom type; + gulong nitems, bytes_after; + gint format; + guchar *data_esetroot; + Pixmap pixmap_id = GDK_WINDOW_XWINDOW (pixmap); + + XGrabServer (GDK_DISPLAY()); + + XGetWindowProperty (GDK_DISPLAY(), GDK_ROOT_WINDOW(), + gdk_atom_intern("ESETROOT_PMAP_ID", FALSE), + 0L, 1L, False, XA_PIXMAP, + &type, &format, &nitems, &bytes_after, + &data_esetroot); + + if (type == XA_PIXMAP) { + if (format == 32 && nitems == 4) + XKillClient(GDK_DISPLAY(), *((Pixmap*)data_esetroot)); + + XFree (data_esetroot); + } + + XChangeProperty (GDK_DISPLAY(), GDK_ROOT_WINDOW(), + gdk_atom_intern("ESETROOT_PMAP_ID", FALSE), XA_PIXMAP, + 32, PropModeReplace, + (guchar *) &pixmap_id, 1); + XChangeProperty (GDK_DISPLAY(), GDK_ROOT_WINDOW(), + gdk_atom_intern("_XROOTPMAP_ID", FALSE), XA_PIXMAP, + 32, PropModeReplace, + (guchar *) &pixmap_id, 1); + + XSetWindowBackgroundPixmap (GDK_DISPLAY(), GDK_ROOT_WINDOW(), pixmap_id); + XClearWindow (GDK_DISPLAY (), GDK_ROOT_WINDOW ()); + + XUngrabServer (GDK_DISPLAY()); + + XFlush(GDK_DISPLAY()); +} + +static void +image_loaded_callback (NautilusBackground *background, void *calledDirectly) +{ + GdkGC *gc; + GdkPixmap *bg_pixmap; + GdkRectangle screen_rectangle; + + g_assert (NAUTILUS_IS_BACKGROUND (background)); + + if (!(gboolean) calledDirectly) { + gtk_signal_disconnect_by_func (GTK_OBJECT (background), + GTK_SIGNAL_FUNC (image_loaded_callback), + calledDirectly); + } + + screen_rectangle.x = 0; + screen_rectangle.y = 0; + screen_rectangle.width = gdk_screen_width (); + screen_rectangle.height = gdk_screen_height (); + + bg_pixmap = make_root_pixmap (screen_rectangle.width, screen_rectangle.height); + gc = gdk_gc_new (bg_pixmap); + + nautilus_background_draw (background, bg_pixmap, gc, &screen_rectangle, 0, 0); + + set_root_pixmap (bg_pixmap); + + dispose_root_pixmap (bg_pixmap); + gdk_gc_unref (gc); +} + +static void +nautilus_directory_update_root_window (NautilusBackground *background) +{ + if (nautilus_background_is_loaded (background)) { + image_loaded_callback (background, (void *) TRUE); + } else { + gtk_signal_connect (GTK_OBJECT (background), + "image_loaded", + GTK_SIGNAL_FUNC (image_loaded_callback), + (void *) FALSE); + } +} /* return true if the background is not in the default state */ gboolean @@ -353,6 +483,10 @@ background_changed_callback (NautilusBackground *background, g_free (color); g_free (image); + + if (nautilus_directory_background_is_desktop (background)) { + nautilus_directory_update_root_window (background); + } } /* handle the directory changed signal */ @@ -461,6 +595,10 @@ background_reset_callback (NautilusBackground *background, * It will set color and image_uri to NULL. */ gtk_signal_emit_stop_by_name (GTK_OBJECT (background), "reset"); + + if (nautilus_directory_background_is_desktop (background)) { + nautilus_directory_update_root_window (background); + } } /* handle the background destroyed signal */ diff --git a/libnautilus-private/nautilus-background.c b/libnautilus-private/nautilus-background.c index e4a3a2a92..108f86f56 100644 --- a/libnautilus-private/nautilus-background.c +++ b/libnautilus-private/nautilus-background.c @@ -64,6 +64,7 @@ NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusBackground, nautilus_background, GTK_ enum { APPEARANCE_CHANGED, SETTINGS_CHANGED, + IMAGE_LOADED, RESET, LAST_SIGNAL }; @@ -108,6 +109,15 @@ nautilus_background_initialize_class (gpointer klass) gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); + signals[IMAGE_LOADED] = + gtk_signal_new ("image_loaded", + GTK_RUN_LAST | GTK_RUN_NO_RECURSE, + object_class->type, + GTK_SIGNAL_OFFSET (NautilusBackgroundClass, + image_loaded), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, + 0); signals[RESET] = gtk_signal_new ("reset", GTK_RUN_LAST | GTK_RUN_NO_RECURSE, @@ -532,25 +542,32 @@ nautilus_background_get_image_uri (NautilusBackground *background) return g_strdup (background->details->image_uri); } -void -nautilus_background_set_color (NautilusBackground *background, +static gboolean +nautilus_background_set_color_no_signal (NautilusBackground *background, const char *color) { - g_return_if_fail (NAUTILUS_IS_BACKGROUND (background)); + g_return_val_if_fail (NAUTILUS_IS_BACKGROUND (background), FALSE); if (nautilus_strcmp (background->details->color, color) == 0) { - return; + return FALSE; } g_free (background->details->color); background->details->color = g_strdup (color); + return TRUE; +} - gtk_signal_emit (GTK_OBJECT (background), - signals[SETTINGS_CHANGED]); - gtk_signal_emit (GTK_OBJECT (background), - signals[APPEARANCE_CHANGED]); +void +nautilus_background_set_color (NautilusBackground *background, + const char *color) +{ + if (nautilus_background_set_color_no_signal (background, color)) { + gtk_signal_emit (GTK_OBJECT (background), signals[SETTINGS_CHANGED]); + gtk_signal_emit (GTK_OBJECT (background), signals[APPEARANCE_CHANGED]); + } } + static void load_image_callback (GnomeVFSResult error, GdkPixbuf *pixbuf, @@ -575,6 +592,8 @@ load_image_callback (GnomeVFSResult error, gtk_signal_emit (GTK_OBJECT (background), signals[APPEARANCE_CHANGED]); + gtk_signal_emit (GTK_OBJECT (background), + signals[IMAGE_LOADED]); } static void @@ -602,14 +621,14 @@ nautilus_background_receive_dropped_background_image (NautilusBackground *backgr } } -void -nautilus_background_set_image_uri (NautilusBackground *background, +static gboolean +nautilus_background_set_image_uri_no_signal (NautilusBackground *background, const char *image_uri) { - g_return_if_fail (NAUTILUS_IS_BACKGROUND (background)); + g_return_val_if_fail (NAUTILUS_IS_BACKGROUND (background), FALSE); if (nautilus_strcmp (background->details->image_uri, image_uri) == 0) { - return; + return FALSE; } nautilus_cancel_gdk_pixbuf_load (background->details->load_image_handle); @@ -624,10 +643,17 @@ nautilus_background_set_image_uri (NautilusBackground *background, background->details->image_uri = g_strdup (image_uri); start_loading_image (background); - gtk_signal_emit (GTK_OBJECT (background), - signals[SETTINGS_CHANGED]); - gtk_signal_emit (GTK_OBJECT (background), - signals[APPEARANCE_CHANGED]); + return TRUE; +} + +void +nautilus_background_set_image_uri (NautilusBackground *background, + const char *image_uri) +{ + if (nautilus_background_set_image_uri_no_signal (background, image_uri)) { + gtk_signal_emit (GTK_OBJECT (background), signals[SETTINGS_CHANGED]); + gtk_signal_emit (GTK_OBJECT (background), signals[APPEARANCE_CHANGED]); + } } static GtkStyleClass * @@ -774,6 +800,16 @@ nautilus_background_is_set (NautilusBackground *background) background->details->image_uri != NULL; } +/* Returns false if the image is still loading, true + * if it's done loading or there is no image. + */ +gboolean +nautilus_background_is_loaded (NautilusBackground *background) +{ + return background->details->image_uri == NULL || + background->details->image != NULL; +} + /** * nautilus_background_reset: * @@ -790,8 +826,10 @@ nautilus_background_reset (NautilusBackground *background) static void nautilus_background_real_reset (NautilusBackground *background) { - nautilus_background_set_color (background, NULL); - nautilus_background_set_image_uri (background, NULL); + nautilus_background_set_color_no_signal (background, NULL); + nautilus_background_set_image_uri_no_signal (background, NULL); + gtk_signal_emit (GTK_OBJECT (background), signals[SETTINGS_CHANGED]); + gtk_signal_emit (GTK_OBJECT (background), signals[APPEARANCE_CHANGED]); } static void @@ -974,9 +1012,11 @@ nautilus_background_receive_dropped_color (NautilusBackground *background, g_free (color_spec); - nautilus_background_set_color (background, new_gradient_spec); - nautilus_background_set_image_uri (background, NULL); - + nautilus_background_set_color_no_signal (background, new_gradient_spec); + nautilus_background_set_image_uri_no_signal (background, NULL); + gtk_signal_emit (GTK_OBJECT (background), signals[SETTINGS_CHANGED]); + gtk_signal_emit (GTK_OBJECT (background), signals[APPEARANCE_CHANGED]); + g_free (new_gradient_spec); } diff --git a/libnautilus-private/nautilus-background.h b/libnautilus-private/nautilus-background.h index 843ebb164..1e653601d 100644 --- a/libnautilus-private/nautilus-background.h +++ b/libnautilus-private/nautilus-background.h @@ -80,12 +80,13 @@ void nautilus_background_set_image_placement (Nautil /* Calls to interrogate the current state of a background. */ char * nautilus_background_get_color (NautilusBackground *background); -char * nautilus_background_get_image_uri (NautilusBackground *background); +char * nautilus_background_get_image_uri (NautilusBackground *background); gboolean nautilus_background_get_combine_mode (NautilusBackground *background); nautilus_background_image_placement nautilus_background_get_image_placement (NautilusBackground *background); gboolean nautilus_background_is_dark (NautilusBackground *background); gboolean nautilus_background_is_set (NautilusBackground *background); +gboolean nautilus_background_is_loaded (NautilusBackground *background); /* Explicitly fills a rectangle with a background. */ void nautilus_background_draw (NautilusBackground *background, @@ -141,6 +142,10 @@ struct NautilusBackgroundClass */ void (* appearance_changed) (NautilusBackground *); + /* This signal is emitted whenever an image is loaded. + */ + void (* image_loaded) (NautilusBackground *); + /* This signal is emitted when the background is reset by receiving the reset property from a drag */ diff --git a/libnautilus-private/nautilus-directory-background.c b/libnautilus-private/nautilus-directory-background.c index d5812cfbc..9f08dbbf7 100644 --- a/libnautilus-private/nautilus-directory-background.c +++ b/libnautilus-private/nautilus-directory-background.c @@ -36,13 +36,16 @@ #include "nautilus-theme.h" #include "libnautilus-extensions/nautilus-gdk-extensions.h" +#include <gdk/gdkx.h> +#include <X11/Xatom.h> + static void background_changed_callback (NautilusBackground *background, NautilusDirectory *directory); static void directory_changed_callback (NautilusDirectory *directory, NautilusBackground *background); static void background_reset_callback (NautilusBackground *background, NautilusDirectory *directory); - + void static nautilus_directory_background_set_desktop (NautilusBackground *background) { @@ -257,10 +260,6 @@ nautilus_directory_background_write_desktop_settings (char *color, char *image, } gnome_config_sync (); - - /* FIXME - * Try to trick GNOME into re-reading the settings. - */ } static void @@ -272,7 +271,138 @@ nautilus_directory_background_write_desktop_default_settings () nautilus_background_image_placement placement; nautilus_directory_background_get_default_settings (TRUE, &color, &image, &placement, &combine); nautilus_directory_background_write_desktop_settings (color, image, placement, combine); -} +} + +/* Create a persistant pixmap. We create a separate display + * and set the closedown mode on it to RetainPermanent + * (copied from gnome-source/control-panels/capplets/background-properties/render-background.c) + */ +static GdkPixmap * +make_root_pixmap (gint width, gint height) +{ + Pixmap result; + + gdk_flush (); + + XSetCloseDownMode (gdk_display, RetainPermanent); + + result = XCreatePixmap (gdk_display, + DefaultRootWindow (gdk_display), + width, height, + DefaultDepthOfScreen (DefaultScreenOfDisplay (GDK_DISPLAY()))); + + return gdk_pixmap_foreign_new (result); +} + +/* (copied from gnome-source/control-panels/capplets/background-properties/render-background.c) + */ +static void +dispose_root_pixmap (GdkPixmap *pixmap) +{ + /* Unrefing a foreign pixmap causes it to be destroyed - so we include + * this bad hack, that will work for GTK+-1.2 until the problem + * is fixed in the next release + */ + + GdkWindowPrivate *private = (GdkWindowPrivate *)pixmap; + + gdk_xid_table_remove (private->xwindow); + g_dataset_destroy (private); + g_free (private); + +} + +/* Set the root pixmap, and properties pointing to it. We + * do this atomically with XGrabServer to make sure that + * we won't leak the pixmap if somebody else it setting + * it at the same time. (This assumes that they follow the + * same conventions we do + * (copied from gnome-source/control-panels/capplets/background-properties/render-background.c) + */ +static void +set_root_pixmap (GdkPixmap *pixmap) +{ + GdkAtom type; + gulong nitems, bytes_after; + gint format; + guchar *data_esetroot; + Pixmap pixmap_id = GDK_WINDOW_XWINDOW (pixmap); + + XGrabServer (GDK_DISPLAY()); + + XGetWindowProperty (GDK_DISPLAY(), GDK_ROOT_WINDOW(), + gdk_atom_intern("ESETROOT_PMAP_ID", FALSE), + 0L, 1L, False, XA_PIXMAP, + &type, &format, &nitems, &bytes_after, + &data_esetroot); + + if (type == XA_PIXMAP) { + if (format == 32 && nitems == 4) + XKillClient(GDK_DISPLAY(), *((Pixmap*)data_esetroot)); + + XFree (data_esetroot); + } + + XChangeProperty (GDK_DISPLAY(), GDK_ROOT_WINDOW(), + gdk_atom_intern("ESETROOT_PMAP_ID", FALSE), XA_PIXMAP, + 32, PropModeReplace, + (guchar *) &pixmap_id, 1); + XChangeProperty (GDK_DISPLAY(), GDK_ROOT_WINDOW(), + gdk_atom_intern("_XROOTPMAP_ID", FALSE), XA_PIXMAP, + 32, PropModeReplace, + (guchar *) &pixmap_id, 1); + + XSetWindowBackgroundPixmap (GDK_DISPLAY(), GDK_ROOT_WINDOW(), pixmap_id); + XClearWindow (GDK_DISPLAY (), GDK_ROOT_WINDOW ()); + + XUngrabServer (GDK_DISPLAY()); + + XFlush(GDK_DISPLAY()); +} + +static void +image_loaded_callback (NautilusBackground *background, void *calledDirectly) +{ + GdkGC *gc; + GdkPixmap *bg_pixmap; + GdkRectangle screen_rectangle; + + g_assert (NAUTILUS_IS_BACKGROUND (background)); + + if (!(gboolean) calledDirectly) { + gtk_signal_disconnect_by_func (GTK_OBJECT (background), + GTK_SIGNAL_FUNC (image_loaded_callback), + calledDirectly); + } + + screen_rectangle.x = 0; + screen_rectangle.y = 0; + screen_rectangle.width = gdk_screen_width (); + screen_rectangle.height = gdk_screen_height (); + + bg_pixmap = make_root_pixmap (screen_rectangle.width, screen_rectangle.height); + gc = gdk_gc_new (bg_pixmap); + + nautilus_background_draw (background, bg_pixmap, gc, &screen_rectangle, 0, 0); + + set_root_pixmap (bg_pixmap); + + dispose_root_pixmap (bg_pixmap); + gdk_gc_unref (gc); +} + +static void +nautilus_directory_update_root_window (NautilusBackground *background) +{ + if (nautilus_background_is_loaded (background)) { + image_loaded_callback (background, (void *) TRUE); + } else { + gtk_signal_connect (GTK_OBJECT (background), + "image_loaded", + GTK_SIGNAL_FUNC (image_loaded_callback), + (void *) FALSE); + } +} /* return true if the background is not in the default state */ gboolean @@ -353,6 +483,10 @@ background_changed_callback (NautilusBackground *background, g_free (color); g_free (image); + + if (nautilus_directory_background_is_desktop (background)) { + nautilus_directory_update_root_window (background); + } } /* handle the directory changed signal */ @@ -461,6 +595,10 @@ background_reset_callback (NautilusBackground *background, * It will set color and image_uri to NULL. */ gtk_signal_emit_stop_by_name (GTK_OBJECT (background), "reset"); + + if (nautilus_directory_background_is_desktop (background)) { + nautilus_directory_update_root_window (background); + } } /* handle the background destroyed signal */ |