SUMMARY Patches to add a new mode for backgrounds provisionally entitled "Zoom". These are from an existing bug 105231. I've been using them for the last year. http://bugs.gnome.org/show_bug.cgi?id=105231 DESCRIPTION This mode enlarges the image so as to cover desktop while maintaining the aspect ratio by chopping either the top and bottom or left and right edges. I.e. you're zooming or cropping the image to fill the screen. I've primarily done this for my widescreen laptop where stretched mode ("Fill Screen") makes 4:3 images look bad, but it would be useful for any images that don't match the aspect ratio of your monitor. PROBLEM The patches have been available since last year but not applied due to a naming issue. Rodney Dawes didn't like "Zoom" as being too generic (see comment #14 in bug). Second best name so far IMHO is "Cropped". Suggestions please as getting this into Gnome 2.14 would be nice. PATCHES There are four attached patches for eel, control-center, nautilus and gnome-user-docs plus a new stock image. The patches are against CVS HEAD as of today (22/11/2005). 1) bgzoom-eel.patch Required before other patches can be considered. Raised in bug 320830. http://bugzilla.gnome.org/show_bug.cgi?id=320830 Adds an EEL_BACKGROUND_ZOOM background placement enum and the two functions eel_gdk_scale_to_min_factor() and eel_gdk_pixbuf_scale_to_min(). The functions are basically the opposite of the existing eel_gdk_scale_to_fit_factor() and eel_gdk_pixbuf_scale_to_fit() functions. Instead of scaling to fit within a box these are used scale to fit outwith a box. 2) bgzoom-controlcenter.patch The control center patch. 3) bgzoom-nautilus.patch Apparently Nautilus pulls the latest libbackground from CVS when it is checked out (according to an email from Rodney Dawes) so only the two small hunks for nautilus/libnautilus-private/nautilus-directory-background.c need applied? 4) bgzoom-gnome2userdocs.patch Add help for Zoomed mode. Also corrects the (very wrong) Tiled mode and (slightly imprecise) Fill Screen descriptions. 5) stock_wallpaper-zoom.png Basically I wanted to show that the image would extend beyond the boundary of the window. Tricky in a 16x16 icon... Needs to be added next to the gnome-icon-theme/16x16/stock/image/ directory and its name added to gnome-icon-theme/16x16/stock/image/Makefile.am so it is installed. -- Alan. "One must never be purposelessnessnesslessness."
diff -ur gnome-control-center.orig/capplets/background/gnome-wp-capplet.c gnome-control-center/capplets/background/gnome-wp-capplet.c --- gnome-control-center.orig/capplets/background/gnome-wp-capplet.c 2005-11-21 04:42:44.000000000 +0000 +++ gnome-control-center/capplets/background/gnome-wp-capplet.c 2005-11-22 00:21:34.000000000 +0000 @@ -259,6 +259,9 @@ } else if (!strcmp (value, "scaled")) { gtk_option_menu_set_history (GTK_OPTION_MENU (capplet->wp_opts), GNOME_WP_SCALE_TYPE_SCALED); + } else if (!strcmp (value, "zoom")) { + gtk_option_menu_set_history (GTK_OPTION_MENU (capplet->wp_opts), + GNOME_WP_SCALE_TYPE_ZOOM); } else if (strcmp (value, "none") != 0) { gtk_option_menu_set_history (GTK_OPTION_MENU (capplet->wp_opts), GNOME_WP_SCALE_TYPE_TILED); @@ -423,6 +426,9 @@ case GNOME_WP_SCALE_TYPE_SCALED: item->options = g_strdup ("scaled"); break; + case GNOME_WP_SCALE_TYPE_ZOOM: + item->options = g_strdup ("zoom"); + break; case GNOME_WP_SCALE_TYPE_TILED: item->options = g_strdup ("wallpaper"); break; @@ -1133,6 +1139,27 @@ gtk_widget_show (mitem); mitem = gtk_menu_item_new (); + set_accessible_name (mitem, _("Zoom")); + icofile = gnome_icon_theme_lookup_icon (capplet->theme, + "stock_wallpaper-zoom", + 16, NULL, NULL); + mbox = gtk_hbox_new (FALSE, 6); + gtk_container_add (GTK_CONTAINER (mitem), mbox); + gtk_widget_show (mbox); + + if (icofile != NULL) { + capplet->sitem = gtk_image_new_from_file (icofile); + gtk_box_pack_start (GTK_BOX (mbox), capplet->sitem, FALSE, FALSE, 0); + gtk_widget_show (capplet->sitem); + } + label = gtk_label_new (_("Zoom")); + gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); + gtk_box_pack_start (GTK_BOX (mbox), label, TRUE, TRUE, 0); + gtk_widget_show (label); + gtk_menu_append (GTK_MENU (menu), mitem); + gtk_widget_show (mitem); + + mitem = gtk_menu_item_new (); set_accessible_name (mitem, _("Tiled")); icon_info = gtk_icon_theme_lookup_icon (capplet->theme, "stock_wallpaper-tile", diff -ur gnome-control-center.orig/capplets/background/gnome-wp-capplet.h gnome-control-center/capplets/background/gnome-wp-capplet.h --- gnome-control-center.orig/capplets/background/gnome-wp-capplet.h 2005-07-10 21:45:00.000000000 +0100 +++ gnome-control-center/capplets/background/gnome-wp-capplet.h 2005-11-22 00:19:50.000000000 +0000 @@ -100,6 +100,7 @@ GNOME_WP_SCALE_TYPE_CENTERED, GNOME_WP_SCALE_TYPE_STRETCHED, GNOME_WP_SCALE_TYPE_SCALED, + GNOME_WP_SCALE_TYPE_ZOOM, GNOME_WP_SCALE_TYPE_TILED } GnomeWPScaleType; diff -ur gnome-control-center.orig/capplets/background/gnome-wp-item.c gnome-control-center/capplets/background/gnome-wp-item.c --- gnome-control-center.orig/capplets/background/gnome-wp-item.c 2005-10-01 22:29:39.000000000 +0100 +++ gnome-control-center/capplets/background/gnome-wp-item.c 2005-11-22 00:19:50.000000000 +0000 @@ -274,6 +274,15 @@ tw = bw; } scaled = gnome_wp_pixbuf_center (pixbuf, bgpixbuf, tw, th); + } else if (!strcmp (item->options, "zoom")) { + if ((gdouble) ph * (gdouble) bw < (gdouble) pw * (gdouble) bh) { + tw = 0.5 + (gdouble) pw * (gdouble) bh / (gdouble) ph; + th = bh; + } else { + th = 0.5 + (gdouble) ph * (gdouble) bw / (gdouble) pw; + tw = bw; + } + scaled = gnome_wp_pixbuf_center (pixbuf, bgpixbuf, tw, th); } } diff -ur gnome-control-center.orig/libbackground/applier.c gnome-control-center/libbackground/applier.c --- gnome-control-center.orig/libbackground/applier.c 2005-06-10 19:49:06.000000000 +0100 +++ gnome-control-center/libbackground/applier.c 2005-11-22 00:19:50.000000000 +0000 @@ -1091,6 +1091,27 @@ break; + case WPTYPE_ZOOM: + asp = (gdouble) pwidth / (gdouble) virtual_geom->width; + + if (asp > (gdouble) pheight / virtual_geom->height) { + src_geom->width = pwidth * virtual_geom->height / pheight; + src_geom->height = pheight; + src_geom->x = (pwidth - src_geom->width) / 2; + src_geom->y = 0; + } else { + src_geom->width = pwidth; + src_geom->height = pheight * virtual_geom->width / pwidth; + src_geom->x = 0; + src_geom->y = (pheight - src_geom->height) / 2; + } + + dest_geom->x = dest_geom->y = 0; + dest_geom->width = field_geom->width; + dest_geom->height = field_geom->height; + + break; + case WPTYPE_STRETCHED: dest_geom->width = field_geom->width; dest_geom->height = field_geom->height; diff -ur gnome-control-center.orig/libbackground/preferences.c gnome-control-center/libbackground/preferences.c --- gnome-control-center.orig/libbackground/preferences.c 2005-11-07 17:56:46.000000000 +0000 +++ gnome-control-center/libbackground/preferences.c 2005-11-22 00:19:50.000000000 +0000 @@ -50,6 +50,7 @@ { WPTYPE_CENTERED, "WPTYPE_CENTERED", "centered"}, { WPTYPE_SCALED, "WPTYPE_SCALED", "scaled"}, { WPTYPE_STRETCHED, "WPTYPE_STRETCHED", "stretched"}, + { WPTYPE_ZOOM, "WPTYPE_ZOOM", "zoom"}, { WPTYPE_NONE, "WPTYPE_NONE", "none"}, { 0, NULL, NULL } }; @@ -383,6 +384,8 @@ type = WPTYPE_SCALED; } else if (!strncmp (string, "stretched", sizeof ("stretched"))) { type = WPTYPE_STRETCHED; + } else if (!strncmp (string, "zoom", sizeof ("zoom"))) { + type = WPTYPE_ZOOM; } g_free (string); } @@ -432,6 +435,8 @@ return "scaled"; case WPTYPE_STRETCHED: return "stretched"; + case WPTYPE_ZOOM: + return "zoom"; case WPTYPE_NONE: return "none"; case WPTYPE_UNSET: diff -ur gnome-control-center.orig/libbackground/preferences.h gnome-control-center/libbackground/preferences.h --- gnome-control-center.orig/libbackground/preferences.h 2002-03-20 03:30:11.000000000 +0000 +++ gnome-control-center/libbackground/preferences.h 2005-11-22 00:19:50.000000000 +0000 @@ -52,7 +52,7 @@ typedef enum _wallpaper_type_t { WPTYPE_TILED = 0, WPTYPE_CENTERED, WPTYPE_SCALED, - WPTYPE_STRETCHED, WPTYPE_NONE, + WPTYPE_STRETCHED, WPTYPE_ZOOM, WPTYPE_NONE, WPTYPE_UNSET } wallpaper_type_t;
diff -ur eel.orig/eel/eel-background.c eel/eel/eel-background.c --- eel.orig/eel/eel-background.c 2005-10-27 16:03:37.000000000 +0100 +++ eel/eel/eel-background.c 2005-11-22 00:17:03.000000000 +0000 @@ -551,6 +551,7 @@ switch (background->details->image_placement) { case EEL_BACKGROUND_TILED: case EEL_BACKGROUND_SCALED: + case EEL_BACKGROUND_ZOOM: return TRUE; default: g_assert_not_reached (); @@ -676,6 +677,24 @@ } } break; + case EEL_BACKGROUND_ZOOM: + eel_gdk_scale_to_min_factor (background->details->image_width_unscaled, + background->details->image_height_unscaled, + dest_width, dest_height, + &fit_width, &fit_height); + + if (image_width != fit_width || image_height != fit_height) { + if (cur_scaled) { + reload_image = TRUE; + } else { + scaled_pixbuf = eel_gdk_pixbuf_scale_to_min (background->details->image, dest_width, dest_height); + g_object_unref (background->details->image); + background->details->image = scaled_pixbuf; + image_width = gdk_pixbuf_get_width (scaled_pixbuf); + image_height = gdk_pixbuf_get_height (scaled_pixbuf); + } + } + break; } if (reload_image) { @@ -757,6 +776,7 @@ case EEL_BACKGROUND_CENTERED: case EEL_BACKGROUND_SCALED: case EEL_BACKGROUND_SCALED_ASPECT: + case EEL_BACKGROUND_ZOOM: *pixmap_width = entire_width; *pixmap_height = entire_height; } @@ -1354,6 +1374,7 @@ case EEL_BACKGROUND_CENTERED: case EEL_BACKGROUND_SCALED: case EEL_BACKGROUND_SCALED_ASPECT: + case EEL_BACKGROUND_ZOOM: /* Since the image has already been scaled, all these cases * can be treated identically. */ diff -ur eel.orig/eel/eel-background.h eel/eel/eel-background.h --- eel.orig/eel/eel-background.h 2005-03-16 08:29:16.000000000 +0000 +++ eel/eel/eel-background.h 2005-11-22 00:17:03.000000000 +0000 @@ -63,7 +63,8 @@ EEL_BACKGROUND_TILED = 0, /* zero makes this the default placement */ EEL_BACKGROUND_CENTERED, EEL_BACKGROUND_SCALED, - EEL_BACKGROUND_SCALED_ASPECT + EEL_BACKGROUND_SCALED_ASPECT, + EEL_BACKGROUND_ZOOM } EelBackgroundImagePlacement; GtkType eel_background_get_type (void); diff -ur eel.orig/eel/eel-gdk-pixbuf-extensions.c eel/eel/eel-gdk-pixbuf-extensions.c --- eel.orig/eel/eel-gdk-pixbuf-extensions.c 2005-10-27 16:03:37.000000000 +0100 +++ eel/eel/eel-gdk-pixbuf-extensions.c 2005-11-22 00:17:03.000000000 +0000 @@ -404,6 +404,37 @@ } } +double +eel_gdk_scale_to_min_factor (int width, int height, + int min_width, int min_height, + int *scaled_width, int *scaled_height) +{ + double scale_factor; + + scale_factor = MAX (min_width / (double) width, min_height / (double) height); + + *scaled_width = floor (width * scale_factor + .5); + *scaled_height = floor (height * scale_factor + .5); + + return scale_factor; +} + +/* Returns a scaled copy of pixbuf, preserving aspect ratio. The copy will + * be scaled as small as possible without going under the specified width and height. + */ +GdkPixbuf * +eel_gdk_pixbuf_scale_to_min (GdkPixbuf *pixbuf, int min_width, int min_height) +{ + int scaled_width; + int scaled_height; + + eel_gdk_scale_to_min_factor (gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf), + min_width, min_height, + &scaled_width, &scaled_height); + + return gdk_pixbuf_scale_simple (pixbuf, scaled_width, scaled_height, GDK_INTERP_BILINEAR); +} + /** * eel_gdk_pixbuf_is_valid: * @pixbuf: A GdkPixbuf diff -ur eel.orig/eel/eel-gdk-pixbuf-extensions.h eel/eel/eel-gdk-pixbuf-extensions.h --- eel.orig/eel/eel-gdk-pixbuf-extensions.h 2002-07-10 09:20:11.000000000 +0100 +++ eel/eel/eel-gdk-pixbuf-extensions.h 2005-11-22 00:17:03.000000000 +0000 @@ -71,6 +71,15 @@ int max_height, int *scaled_width, int *scaled_height); +GdkPixbuf * eel_gdk_pixbuf_scale_to_min (GdkPixbuf *pixbuf, + int min_width, + int min_height); +double eel_gdk_scale_to_min_factor (int width, + int height, + int min_width, + int min_height, + int *scaled_width, + int *scaled_height); /* return average color values for each component (argb) */ guint32 eel_gdk_pixbuf_average_value (GdkPixbuf *pixbuf);
diff -ur nautilus.orig/libbackground/applier.c nautilus/libbackground/applier.c --- nautilus.orig/libbackground/applier.c 2005-06-10 19:49:06.000000000 +0100 +++ nautilus/libbackground/applier.c 2005-11-22 00:25:13.000000000 +0000 @@ -1091,6 +1091,28 @@ break; + case WPTYPE_ZOOM: + asp = (gdouble) pwidth / (gdouble) virtual_geom->width; + + if (asp > (gdouble) pheight / virtual_geom->height) { + src_geom->width = pwidth * virtual_geom->height / pheight; + src_geom->height = pheight; + src_geom->x = (pwidth - src_geom->width) / 2; + src_geom->y = 0; + } else { + src_geom->width = pwidth; + src_geom->height = pheight * virtual_geom->width / pwidth; + src_geom->x = 0; + src_geom->y = (pheight - src_geom->height) / 2; + } + + + dest_geom->x = dest_geom->y = 0; + dest_geom->width = field_geom->width; + dest_geom->height = field_geom->height; + + break; + case WPTYPE_STRETCHED: dest_geom->width = field_geom->width; dest_geom->height = field_geom->height; diff -ur nautilus.orig/libbackground/preferences.c nautilus/libbackground/preferences.c --- nautilus.orig/libbackground/preferences.c 2005-11-07 17:56:46.000000000 +0000 +++ nautilus/libbackground/preferences.c 2005-11-22 00:25:13.000000000 +0000 @@ -50,6 +50,7 @@ { WPTYPE_CENTERED, "WPTYPE_CENTERED", "centered"}, { WPTYPE_SCALED, "WPTYPE_SCALED", "scaled"}, { WPTYPE_STRETCHED, "WPTYPE_STRETCHED", "stretched"}, + { WPTYPE_ZOOM, "WPTYPE_ZOOM", "zoom"}, { WPTYPE_NONE, "WPTYPE_NONE", "none"}, { 0, NULL, NULL } }; @@ -383,6 +384,8 @@ type = WPTYPE_SCALED; } else if (!strncmp (string, "stretched", sizeof ("stretched"))) { type = WPTYPE_STRETCHED; + } else if (!strncmp (string, "zoom", sizeof ("zoom"))) { + type = WPTYPE_ZOOM; } g_free (string); } @@ -432,6 +435,8 @@ return "scaled"; case WPTYPE_STRETCHED: return "stretched"; + case WPTYPE_ZOOM: + return "zoom"; case WPTYPE_NONE: return "none"; case WPTYPE_UNSET: diff -ur nautilus.orig/libbackground/preferences.h nautilus/libbackground/preferences.h --- nautilus.orig/libbackground/preferences.h 2002-03-20 03:30:11.000000000 +0000 +++ nautilus/libbackground/preferences.h 2005-11-22 00:25:13.000000000 +0000 @@ -52,7 +52,7 @@ typedef enum _wallpaper_type_t { WPTYPE_TILED = 0, WPTYPE_CENTERED, WPTYPE_SCALED, - WPTYPE_STRETCHED, WPTYPE_NONE, + WPTYPE_STRETCHED, WPTYPE_ZOOM, WPTYPE_NONE, WPTYPE_UNSET } wallpaper_type_t; diff -ur nautilus.orig/libnautilus-private/nautilus-directory-background.c nautilus/libnautilus-private/nautilus-directory-background.c --- nautilus.orig/libnautilus-private/nautilus-directory-background.c 2005-08-12 19:11:29.000000000 +0100 +++ nautilus/libnautilus-private/nautilus-directory-background.c 2005-11-22 00:25:13.000000000 +0000 @@ -154,6 +154,9 @@ case WPTYPE_SCALED: *placement = EEL_BACKGROUND_SCALED_ASPECT; break; + case WPTYPE_ZOOM: + *placement = EEL_BACKGROUND_ZOOM; + break; } end_color = eel_gdk_rgb_to_color_spec (eel_gdk_color_to_rgb (prefs->color2)); @@ -230,6 +233,9 @@ case EEL_BACKGROUND_SCALED_ASPECT: wallpaper_align = WPTYPE_SCALED; break; + case EEL_BACKGROUND_ZOOM: + wallpaper_align = WPTYPE_ZOOM; + break; default: g_assert_not_reached (); wallpaper_align = WPTYPE_TILED;
Attachment:
stock_wallpaper-zoom.png
Description: PNG image
diff -ur gnome-user-docs.orig/gnome2-user-guide/C/goscustdesk.xml gnome-user-docs/gnome2-user-guide/C/goscustdesk.xml --- gnome-user-docs.orig/gnome2-user-guide/C/goscustdesk.xml.orig 2005-11-22 00:30:26.000000000 +0000 +++ gnome-user-docs/gnome2-user-guide/C/goscustdesk.xml 2005-11-22 00:34:44.000000000 +0000 @@ -169,7 +169,7 @@ </listitem> <listitem> <para><guilabel>Fill Screen</guilabel>: Enlarges the image to cover -the desktop and maintains the relative dimensions of the image.</para> +the desktop, but without maintaining the relative dimensions of the image.</para> </listitem> <listitem> <para><guilabel>Scaled</guilabel>: Enlarges the image until the @@ -177,8 +177,12 @@ image.</para> </listitem> <listitem> - <para><guilabel>Tiled</guilabel>: Enlarges the image until the image -meets the screen edges, and maintains the relative dimensions of the image.</para> + <para><guilabel>Zoomed</guilabel>: Enlarges the image until the +image covers the desktop, while maintaining the relative dimensions of the image.</para> + </listitem> + <listitem> + <para><guilabel>Tiled</guilabel>: Repeats the image from top left +corner to cover the desktop.</para> </listitem> </itemizedlist> </entry>
Attachment:
signature.asc
Description: This is a digitally signed message part