Add support for per-monitor backgrounds

https://bugzilla.gnome.org/show_bug.cgi?id=147808
This commit is contained in:
William Jon McCann 2009-12-04 19:54:47 -05:00
parent e90d5dda76
commit 9d4a90d798
4 changed files with 184 additions and 66 deletions

View file

@ -82,7 +82,6 @@ get_selected_item (AppearanceData *data,
if (selected != NULL) if (selected != NULL)
{ {
GtkTreeIter sel_iter; GtkTreeIter sel_iter;
gchar *wpfile;
gtk_tree_model_get_iter (data->wp_model, &sel_iter, gtk_tree_model_get_iter (data->wp_model, &sel_iter,
selected->data); selected->data);
@ -93,10 +92,7 @@ get_selected_item (AppearanceData *data,
if (iter) if (iter)
*iter = sel_iter; *iter = sel_iter;
gtk_tree_model_get (data->wp_model, &sel_iter, 2, &wpfile, -1); gtk_tree_model_get (data->wp_model, &sel_iter, 1, &item, -1);
item = g_hash_table_lookup (data->wp_hash, wpfile);
g_free (wpfile);
} }
return item; return item;
@ -129,7 +125,10 @@ static void on_item_changed (GnomeBG *bg, AppearanceData *data) {
g_signal_handlers_block_by_func (bg, G_CALLBACK (on_item_changed), data); g_signal_handlers_block_by_func (bg, G_CALLBACK (on_item_changed), data);
pixbuf = gnome_wp_item_get_thumbnail (item, data->thumb_factory); pixbuf = gnome_wp_item_get_thumbnail (item,
data->thumb_factory,
data->thumb_width,
data->thumb_height);
if (pixbuf) { if (pixbuf) {
gtk_list_store_set (GTK_LIST_STORE (data->wp_model), &iter, 0, pixbuf, -1); gtk_list_store_set (GTK_LIST_STORE (data->wp_model), &iter, 0, pixbuf, -1);
g_object_unref (pixbuf); g_object_unref (pixbuf);
@ -153,13 +152,14 @@ wp_props_load_wallpaper (gchar *key,
gtk_list_store_append (GTK_LIST_STORE (data->wp_model), &iter); gtk_list_store_append (GTK_LIST_STORE (data->wp_model), &iter);
pixbuf = gnome_wp_item_get_thumbnail (item, data->thumb_factory); pixbuf = gnome_wp_item_get_thumbnail (item, data->thumb_factory,
data->thumb_width,
data->thumb_height);
gnome_wp_item_update_description (item); gnome_wp_item_update_description (item);
gtk_list_store_set (GTK_LIST_STORE (data->wp_model), &iter, gtk_list_store_set (GTK_LIST_STORE (data->wp_model), &iter,
0, pixbuf, 0, pixbuf,
1, item->description, 1, item,
2, item->filename,
-1); -1);
if (pixbuf != NULL) if (pixbuf != NULL)
@ -313,7 +313,9 @@ wp_scale_type_changed (GtkComboBox *combobox,
item->options = gtk_combo_box_get_active (GTK_COMBO_BOX (data->wp_style_menu)); item->options = gtk_combo_box_get_active (GTK_COMBO_BOX (data->wp_style_menu));
pixbuf = gnome_wp_item_get_thumbnail (item, data->thumb_factory); pixbuf = gnome_wp_item_get_thumbnail (item, data->thumb_factory,
data->thumb_width,
data->thumb_height);
gtk_list_store_set (GTK_LIST_STORE (data->wp_model), &iter, 0, pixbuf, -1); gtk_list_store_set (GTK_LIST_STORE (data->wp_model), &iter, 0, pixbuf, -1);
if (pixbuf != NULL) if (pixbuf != NULL)
g_object_unref (pixbuf); g_object_unref (pixbuf);
@ -338,7 +340,9 @@ wp_shade_type_changed (GtkWidget *combobox,
item->shade_type = gtk_combo_box_get_active (GTK_COMBO_BOX (data->wp_color_menu)); item->shade_type = gtk_combo_box_get_active (GTK_COMBO_BOX (data->wp_color_menu));
pixbuf = gnome_wp_item_get_thumbnail (item, data->thumb_factory); pixbuf = gnome_wp_item_get_thumbnail (item, data->thumb_factory,
data->thumb_width,
data->thumb_height);
gtk_list_store_set (GTK_LIST_STORE (data->wp_model), &iter, 0, pixbuf, -1); gtk_list_store_set (GTK_LIST_STORE (data->wp_model), &iter, 0, pixbuf, -1);
if (pixbuf != NULL) if (pixbuf != NULL)
g_object_unref (pixbuf); g_object_unref (pixbuf);
@ -768,7 +772,6 @@ wp_view_tooltip_cb (GtkWidget *widget,
AppearanceData *data) AppearanceData *data)
{ {
GtkTreeIter iter; GtkTreeIter iter;
gchar *wpfile;
GnomeWPItem *item; GnomeWPItem *item;
if (gtk_icon_view_get_tooltip_context (data->wp_view, if (gtk_icon_view_get_tooltip_context (data->wp_view,
@ -778,10 +781,7 @@ wp_view_tooltip_cb (GtkWidget *widget,
NULL, NULL,
&iter)) &iter))
{ {
gtk_tree_model_get (data->wp_model, &iter, 2, &wpfile, -1); gtk_tree_model_get (data->wp_model, &iter, 1, &item, -1);
item = g_hash_table_lookup (data->wp_hash, wpfile);
g_free (wpfile);
gtk_tooltip_set_markup (tooltip, item->description); gtk_tooltip_set_markup (tooltip, item->description);
return TRUE; return TRUE;
@ -795,31 +795,25 @@ wp_list_sort (GtkTreeModel *model,
GtkTreeIter *a, GtkTreeIter *b, GtkTreeIter *a, GtkTreeIter *b,
AppearanceData *data) AppearanceData *data)
{ {
gchar *foo, *bar; GnomeWPItem *itema, *itemb;
gchar *desca, *descb;
gint retval; gint retval;
gtk_tree_model_get (model, a, 1, &desca, 2, &foo, -1); gtk_tree_model_get (model, a, 1, &itema, -1);
gtk_tree_model_get (model, b, 1, &descb, 2, &bar, -1); gtk_tree_model_get (model, b, 1, &itemb, -1);
if (!strcmp (foo, "(none)")) if (!strcmp (itema->filename, "(none)"))
{ {
retval = -1; retval = -1;
} }
else if (!strcmp (bar, "(none)")) else if (!strcmp (itemb->filename, "(none)"))
{ {
retval = 1; retval = 1;
} }
else else
{ {
retval = g_utf8_collate (desca, descb); retval = g_utf8_collate (itema->description, itemb->description);
} }
g_free (desca);
g_free (descb);
g_free (foo);
g_free (bar);
return retval; return retval;
} }
@ -874,6 +868,68 @@ wp_update_preview (GtkFileChooser *chooser,
gtk_file_chooser_set_preview_widget_active (chooser, TRUE); gtk_file_chooser_set_preview_widget_active (chooser, TRUE);
} }
static gboolean
reload_item (GtkTreeModel *model,
GtkTreePath *path,
GtkTreeIter *iter,
AppearanceData *data)
{
GnomeWPItem *item;
GdkPixbuf *pixbuf;
gtk_tree_model_get (model, iter, 1, &item, -1);
pixbuf = gnome_wp_item_get_thumbnail (item,
data->thumb_factory,
data->thumb_width,
data->thumb_height);
if (pixbuf) {
gtk_list_store_set (GTK_LIST_STORE (data->wp_model), iter, 0, pixbuf, -1);
g_object_unref (pixbuf);
}
return FALSE;
}
static gdouble
get_monitor_aspect_ratio_for_widget (GtkWidget *widget)
{
gdouble aspect;
gint monitor;
GdkRectangle rect;
monitor = gdk_screen_get_monitor_at_window (gtk_widget_get_screen (widget), gtk_widget_get_window (widget));
gdk_screen_get_monitor_geometry (gtk_widget_get_screen (widget), monitor, &rect);
aspect = rect.height / (gdouble)rect.width;
return aspect;
}
#define LIST_IMAGE_SIZE 108
static void
compute_thumbnail_sizes (AppearanceData *data)
{
gdouble aspect;
aspect = get_monitor_aspect_ratio_for_widget (GTK_WIDGET (data->wp_view));
if (aspect > 1) {
/* portrait */
data->thumb_width = LIST_IMAGE_SIZE / aspect;
data->thumb_height = LIST_IMAGE_SIZE;
} else {
data->thumb_width = LIST_IMAGE_SIZE;
data->thumb_height = LIST_IMAGE_SIZE * aspect;
}
}
static void
reload_wallpapers (AppearanceData *data)
{
compute_thumbnail_sizes (data);
gtk_tree_model_foreach (data->wp_model, (GtkTreeModelForeachFunc)reload_item, data);
}
static gboolean static gboolean
wp_load_stuffs (void *user_data) wp_load_stuffs (void *user_data)
{ {
@ -883,6 +939,8 @@ wp_load_stuffs (void *user_data)
data = (AppearanceData *) user_data; data = (AppearanceData *) user_data;
compute_thumbnail_sizes (data);
gnome_wp_xml_load_list (data); gnome_wp_xml_load_list (data);
g_hash_table_foreach (data->wp_hash, (GHFunc) wp_props_load_wallpaper, g_hash_table_foreach (data->wp_hash, (GHFunc) wp_props_load_wallpaper,
data); data);
@ -976,8 +1034,11 @@ static void
wp_select_after_realize (GtkWidget *widget, wp_select_after_realize (GtkWidget *widget,
AppearanceData *data) AppearanceData *data)
{ {
GnomeWPItem *item = get_selected_item (data, NULL); GnomeWPItem *item;
g_idle_add (wp_load_stuffs, data);
item = get_selected_item (data, NULL);
if (item == NULL) if (item == NULL)
item = g_hash_table_lookup (data->wp_hash, "(none)"); item = g_hash_table_lookup (data->wp_hash, "(none)");
@ -1043,7 +1104,11 @@ next_frame (AppearanceData *data,
item = get_selected_item (data, &iter); item = get_selected_item (data, &iter);
if (frame >= 0) if (frame >= 0)
pixbuf = gnome_wp_item_get_frame_thumbnail (item, data->thumb_factory, frame); pixbuf = gnome_wp_item_get_frame_thumbnail (item,
data->thumb_factory,
data->thumb_width,
data->thumb_height,
frame);
if (pixbuf) { if (pixbuf) {
gtk_list_store_set (GTK_LIST_STORE (data->wp_model), &iter, 0, pixbuf, -1); gtk_list_store_set (GTK_LIST_STORE (data->wp_model), &iter, 0, pixbuf, -1);
g_object_unref (pixbuf); g_object_unref (pixbuf);
@ -1056,7 +1121,11 @@ next_frame (AppearanceData *data,
pb = buttons[0]; pb = buttons[0];
} }
else { else {
pixbuf = gnome_wp_item_get_frame_thumbnail (item, data->thumb_factory, frame + 1); pixbuf = gnome_wp_item_get_frame_thumbnail (item,
data->thumb_factory,
data->thumb_width,
data->thumb_height,
frame + 1);
if (pixbuf) if (pixbuf)
g_object_unref (pixbuf); g_object_unref (pixbuf);
else else
@ -1140,6 +1209,13 @@ buttons_cell_data_func (GtkCellLayout *layout,
gtk_tree_path_free (path); gtk_tree_path_free (path);
} }
static void
screen_monitors_changed (GdkScreen *screen,
AppearanceData *data)
{
reload_wallpapers (data);
}
void void
desktop_init (AppearanceData *data, desktop_init (AppearanceData *data,
const gchar **uris) const gchar **uris)
@ -1194,9 +1270,8 @@ desktop_init (AppearanceData *data,
(GConfClientNotifyFunc) wp_color2_changed, (GConfClientNotifyFunc) wp_color2_changed,
data, NULL, NULL); data, NULL, NULL);
data->wp_model = GTK_TREE_MODEL (gtk_list_store_new (3, GDK_TYPE_PIXBUF, data->wp_model = GTK_TREE_MODEL (gtk_list_store_new (2, GDK_TYPE_PIXBUF,
G_TYPE_STRING, G_TYPE_POINTER));
G_TYPE_STRING));
data->wp_view = GTK_ICON_VIEW (appearance_capplet_get_widget (data, "wp_view")); data->wp_view = GTK_ICON_VIEW (appearance_capplet_get_widget (data, "wp_view"));
gtk_icon_view_set_model (data->wp_view, GTK_TREE_MODEL (data->wp_model)); gtk_icon_view_set_model (data->wp_view, GTK_TREE_MODEL (data->wp_model));
@ -1232,12 +1307,12 @@ desktop_init (AppearanceData *data,
data->frame = -1; data->frame = -1;
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (data->wp_model), 2, gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (data->wp_model), 1,
(GtkTreeIterCompareFunc) wp_list_sort, (GtkTreeIterCompareFunc) wp_list_sort,
data, NULL); data, NULL);
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (data->wp_model), gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (data->wp_model),
2, GTK_SORT_ASCENDING); 1, GTK_SORT_ASCENDING);
gtk_drag_dest_set (GTK_WIDGET (data->wp_view), GTK_DEST_DEFAULT_ALL, drop_types, gtk_drag_dest_set (GTK_WIDGET (data->wp_view), GTK_DEST_DEFAULT_ALL, drop_types,
G_N_ELEMENTS (drop_types), GDK_ACTION_COPY | GDK_ACTION_MOVE); G_N_ELEMENTS (drop_types), GDK_ACTION_COPY | GDK_ACTION_MOVE);
@ -1280,14 +1355,20 @@ desktop_init (AppearanceData *data,
g_signal_connect (data->wp_rem_button, "clicked", g_signal_connect (data->wp_rem_button, "clicked",
(GCallback) wp_remove_wallpaper, data); (GCallback) wp_remove_wallpaper, data);
data->screen_monitors_handler = g_signal_connect (gtk_widget_get_screen (GTK_WIDGET (data->wp_view)),
g_idle_add (wp_load_stuffs, data); "monitors-changed",
G_CALLBACK (screen_monitors_changed),
data);
data->screen_size_handler = g_signal_connect (gtk_widget_get_screen (GTK_WIDGET (data->wp_view)),
"size-changed",
G_CALLBACK (screen_monitors_changed),
data);
g_signal_connect (data->wp_view, "selection-changed", g_signal_connect (data->wp_view, "selection-changed",
(GCallback) wp_props_wp_selected, data); (GCallback) wp_props_wp_selected, data);
g_signal_connect (data->wp_view, "query-tooltip", g_signal_connect (data->wp_view, "query-tooltip",
(GCallback) wp_view_tooltip_cb, data); (GCallback) wp_view_tooltip_cb, data);
gtk_widget_set_has_tooltip (data->wp_view, TRUE); gtk_widget_set_has_tooltip (GTK_WIDGET (data->wp_view), TRUE);
wp_set_sensitivities (data); wp_set_sensitivities (data);
@ -1300,6 +1381,18 @@ void
desktop_shutdown (AppearanceData *data) desktop_shutdown (AppearanceData *data)
{ {
gnome_wp_xml_save_list (data); gnome_wp_xml_save_list (data);
if (data->screen_monitors_handler > 0) {
g_signal_handler_disconnect (gtk_widget_get_screen (GTK_WIDGET (data->wp_view)),
data->screen_monitors_handler);
data->screen_monitors_handler = 0;
}
if (data->screen_size_handler > 0) {
g_signal_handler_disconnect (gtk_widget_get_screen (GTK_WIDGET (data->wp_view)),
data->screen_size_handler);
data->screen_size_handler = 0;
}
g_slist_foreach (data->wp_uris, (GFunc) g_free, NULL); g_slist_foreach (data->wp_uris, (GFunc) g_free, NULL);
g_slist_free (data->wp_uris); g_slist_free (data->wp_uris);
if (data->wp_filesel) if (data->wp_filesel)

View file

@ -36,6 +36,8 @@ typedef struct
GConfClient *client; GConfClient *client;
GtkBuilder *ui; GtkBuilder *ui;
GnomeDesktopThumbnailFactory *thumb_factory; GnomeDesktopThumbnailFactory *thumb_factory;
gulong screen_size_handler;
gulong screen_monitors_handler;
/* desktop */ /* desktop */
GHashTable *wp_hash; GHashTable *wp_hash;
@ -51,6 +53,8 @@ typedef struct
GtkWidget *wp_image; GtkWidget *wp_image;
GSList *wp_uris; GSList *wp_uris;
gint frame; gint frame;
gint thumb_width;
gint thumb_height;
/* font */ /* font */
GtkWidget *font_details; GtkWidget *font_details;

View file

@ -205,22 +205,19 @@ add_slideshow_frame (GdkPixbuf *pixbuf)
return tmp; return tmp;
} }
#define LIST_IMAGE_WIDTH 108
GdkPixbuf * gnome_wp_item_get_frame_thumbnail (GnomeWPItem * item, GdkPixbuf * gnome_wp_item_get_frame_thumbnail (GnomeWPItem * item,
GnomeDesktopThumbnailFactory * thumbs, GnomeDesktopThumbnailFactory * thumbs,
int width,
int height,
gint frame) { gint frame) {
GdkPixbuf *pixbuf = NULL; GdkPixbuf *pixbuf = NULL;
double aspect =
(double)gdk_screen_get_height (gdk_screen_get_default()) /
gdk_screen_get_width (gdk_screen_get_default());
set_bg_properties (item); set_bg_properties (item);
if (frame != -1) if (frame != -1)
pixbuf = gnome_bg_create_frame_thumbnail (item->bg, thumbs, gdk_screen_get_default (), LIST_IMAGE_WIDTH, LIST_IMAGE_WIDTH * aspect, frame); pixbuf = gnome_bg_create_frame_thumbnail (item->bg, thumbs, gdk_screen_get_default (), width, height, frame);
else else
pixbuf = gnome_bg_create_thumbnail (item->bg, thumbs, gdk_screen_get_default(), LIST_IMAGE_WIDTH, LIST_IMAGE_WIDTH * aspect); pixbuf = gnome_bg_create_thumbnail (item->bg, thumbs, gdk_screen_get_default(), width, height);
if (pixbuf && gnome_bg_changes_with_time (item->bg)) if (pixbuf && gnome_bg_changes_with_time (item->bg))
{ {
@ -231,15 +228,17 @@ GdkPixbuf * gnome_wp_item_get_frame_thumbnail (GnomeWPItem * item,
pixbuf = tmp; pixbuf = tmp;
} }
gnome_bg_get_image_size (item->bg, thumbs, &item->width, &item->height); gnome_bg_get_image_size (item->bg, thumbs, width, height, &item->width, &item->height);
return pixbuf; return pixbuf;
} }
GdkPixbuf * gnome_wp_item_get_thumbnail (GnomeWPItem * item, GdkPixbuf * gnome_wp_item_get_thumbnail (GnomeWPItem * item,
GnomeDesktopThumbnailFactory * thumbs) { GnomeDesktopThumbnailFactory * thumbs,
return gnome_wp_item_get_frame_thumbnail (item, thumbs, -1); gint width,
gint height) {
return gnome_wp_item_get_frame_thumbnail (item, thumbs, width, height, -1);
} }
void gnome_wp_item_update_description (GnomeWPItem * item) { void gnome_wp_item_update_description (GnomeWPItem * item) {
@ -252,37 +251,55 @@ void gnome_wp_item_update_description (GnomeWPItem * item) {
gchar *size; gchar *size;
gchar *dirname = g_path_get_dirname (item->filename); gchar *dirname = g_path_get_dirname (item->filename);
description = NULL;
size = NULL;
if (strcmp (item->fileinfo->mime_type, "application/xml") == 0) if (strcmp (item->fileinfo->mime_type, "application/xml") == 0)
{ {
if (gnome_bg_changes_with_time (item->bg)) if (gnome_bg_changes_with_time (item->bg))
description = _("Slide Show"); description = _("Slide Show");
else else if (item->width > 0 && item->height > 0)
description = _("Image"); description = _("Image");
} }
else else
description = g_content_type_get_description (item->fileinfo->mime_type); description = g_content_type_get_description (item->fileinfo->mime_type);
if (gnome_bg_changes_with_size (item->bg)) if (gnome_bg_has_multiple_sizes (item->bg))
size = g_strdup (_("multiple sizes")); size = g_strdup (_("multiple sizes"));
else else if (item->width > 0 && item->height > 0) {
/* translators: x pixel(s) by y pixel(s) */ /* translators: x pixel(s) by y pixel(s) */
size = g_strdup_printf ("%d %s by %d %s", size = g_strdup_printf ("%d %s by %d %s",
item->width, item->width,
ngettext ("pixel", "pixels", item->width), ngettext ("pixel", "pixels", item->width),
item->height, item->height,
ngettext ("pixel", "pixels", item->height)); ngettext ("pixel", "pixels", item->height));
}
if (description && size) {
/* translators: <b>wallpaper name</b>
* mime type, size
* Folder: /path/to/file
*/
item->description = g_markup_printf_escaped (_("<b>%s</b>\n"
"%s, %s\n"
"Folder: %s"),
item->name,
description,
size,
dirname);
} else {
/* translators: <b>wallpaper name</b>
* Image missing
* Folder: /path/to/file
*/
item->description = g_markup_printf_escaped (_("<b>%s</b>\n"
"%s\n"
"Folder: %s"),
item->name,
_("Image missing"),
dirname);
}
/* translators: <b>wallpaper name</b>
* mime type, size
* Folder: /path/to/file
*/
item->description = g_markup_printf_escaped (_("<b>%s</b>\n"
"%s, %s\n"
"Folder: %s"),
item->name,
description,
size,
dirname);
g_free (size); g_free (size);
g_free (dirname); g_free (dirname);
} }

View file

@ -71,10 +71,14 @@ GnomeWPItem * gnome_wp_item_new (const gchar *filename,
void gnome_wp_item_free (GnomeWPItem *item); void gnome_wp_item_free (GnomeWPItem *item);
GdkPixbuf * gnome_wp_item_get_thumbnail (GnomeWPItem *item, GdkPixbuf * gnome_wp_item_get_thumbnail (GnomeWPItem *item,
GnomeDesktopThumbnailFactory *thumbs);
GdkPixbuf * gnome_wp_item_get_frame_thumbnail (GnomeWPItem *item,
GnomeDesktopThumbnailFactory *thumbs, GnomeDesktopThumbnailFactory *thumbs,
gint frame); gint width,
gint height);
GdkPixbuf * gnome_wp_item_get_frame_thumbnail (GnomeWPItem *item,
GnomeDesktopThumbnailFactory *thumbs,
gint width,
gint height,
gint frame);
void gnome_wp_item_update (GnomeWPItem *item); void gnome_wp_item_update (GnomeWPItem *item);
void gnome_wp_item_update_description (GnomeWPItem *item); void gnome_wp_item_update_description (GnomeWPItem *item);
void gnome_wp_item_ensure_gnome_bg (GnomeWPItem *item); void gnome_wp_item_ensure_gnome_bg (GnomeWPItem *item);