diff options
author | Cosimo Cecchi <cosimoc@gnome.org> | 2013-08-02 14:37:13 +0200 |
---|---|---|
committer | Cosimo Cecchi <cosimoc@gnome.org> | 2013-08-03 15:13:16 +0200 |
commit | 0d4555d76f86ba2d49f48836b7eea11f1adfb2fd (patch) | |
tree | d02fd7c18b591e1f623247b5aac9524b502ed2c3 /libnautilus-private | |
parent | 9fd0032d2b4e44425941d1d8eb41b0d2c30a6527 (diff) | |
download | nautilus-0d4555d76f86ba2d49f48836b7eea11f1adfb2fd.tar.gz |
Support HiDpi icons
Port the rendering of icons to cairo surfaces, so that we can apply the
GDK scale factor when rendering icons.
Diffstat (limited to 'libnautilus-private')
-rw-r--r-- | libnautilus-private/nautilus-canvas-item.c | 153 | ||||
-rw-r--r-- | libnautilus-private/nautilus-file-conflict-dialog.c | 4 | ||||
-rw-r--r-- | libnautilus-private/nautilus-file.c | 30 | ||||
-rw-r--r-- | libnautilus-private/nautilus-file.h | 2 | ||||
-rw-r--r-- | libnautilus-private/nautilus-icon-info.c | 64 | ||||
-rw-r--r-- | libnautilus-private/nautilus-icon-info.h | 12 | ||||
-rw-r--r-- | libnautilus-private/nautilus-program-choosing.c | 4 | ||||
-rw-r--r-- | libnautilus-private/nautilus-ui-utilities.c | 14 | ||||
-rw-r--r-- | libnautilus-private/nautilus-ui-utilities.h | 6 |
9 files changed, 172 insertions, 117 deletions
diff --git a/libnautilus-private/nautilus-canvas-item.c b/libnautilus-private/nautilus-canvas-item.c index 9747349a1..b976fe554 100644 --- a/libnautilus-private/nautilus-canvas-item.c +++ b/libnautilus-private/nautilus-canvas-item.c @@ -74,7 +74,7 @@ struct NautilusCanvasItemDetails { /* The image, text, font. */ double x, y; GdkPixbuf *pixbuf; - GdkPixbuf *rendered_pixbuf; + cairo_surface_t *rendered_surface; char *editable_text; /* Text that can be modified by a renaming function */ char *additional_text; /* Text that cannot be modifed, such as file size, etc. */ GdkPoint *attach_points; @@ -222,9 +222,9 @@ nautilus_canvas_item_finalize (GObject *object) g_free (details->editable_text); g_free (details->additional_text); g_free (details->attach_points); - - if (details->rendered_pixbuf != NULL) { - g_object_unref (details->rendered_pixbuf); + + if (details->rendered_surface != NULL) { + cairo_surface_destroy (details->rendered_surface); } if (details->editable_text_layout != NULL) { @@ -428,12 +428,34 @@ nautilus_canvas_item_get_property (GObject *object, } } +static void +get_scaled_icon_size (NautilusCanvasItem *item, + gint *width, + gint *height) +{ + EelCanvas *canvas; + GdkPixbuf *pixbuf = NULL; + gint scale; + + if (item != NULL) { + canvas = EEL_CANVAS_ITEM (item)->canvas; + scale = gtk_widget_get_scale_factor (GTK_WIDGET (canvas)); + pixbuf = item->details->pixbuf; + } + + if (width) + *width = (pixbuf == NULL) ? 0 : (gdk_pixbuf_get_width (pixbuf) / scale); + if (height) + *height = (pixbuf == NULL) ? 0 : (gdk_pixbuf_get_height (pixbuf) / scale); +} + cairo_surface_t * nautilus_canvas_item_get_drag_surface (NautilusCanvasItem *item) { cairo_surface_t *surface; EelCanvas *canvas; int width, height; + int pix_width, pix_height; int item_offset_x, item_offset_y; EelIRect icon_rect; double item_x, item_y; @@ -469,12 +491,14 @@ nautilus_canvas_item_get_drag_surface (NautilusCanvasItem *item) cr = cairo_create (surface); gtk_render_icon (context, cr, item->details->pixbuf, - item_offset_x, item_offset_y); + item_offset_x, item_offset_y); + + get_scaled_icon_size (item, &pix_width, &pix_height); icon_rect.x0 = item_offset_x; icon_rect.y0 = item_offset_y; - icon_rect.x1 = item_offset_x + gdk_pixbuf_get_width (item->details->pixbuf); - icon_rect.y1 = item_offset_y + gdk_pixbuf_get_height (item->details->pixbuf); + icon_rect.x1 = item_offset_x + pix_width; + icon_rect.y1 = item_offset_y + pix_height; draw_embedded_text (item, cr, item_offset_x, item_offset_y); @@ -506,9 +530,9 @@ nautilus_canvas_item_set_image (NautilusCanvasItem *item, if (details->pixbuf != NULL) { g_object_unref (details->pixbuf); } - if (details->rendered_pixbuf != NULL) { - g_object_unref (details->rendered_pixbuf); - details->rendered_pixbuf = NULL; + if (details->rendered_surface != NULL) { + cairo_surface_destroy (details->rendered_surface); + details->rendered_surface = NULL; } details->pixbuf = image; @@ -1236,13 +1260,14 @@ draw_pixbuf (GdkPixbuf *pixbuf, } /* shared code to highlight or dim the passed-in pixbuf */ -static GdkPixbuf * -real_map_pixbuf (NautilusCanvasItem *canvas_item) +static cairo_surface_t * +real_map_surface (NautilusCanvasItem *canvas_item) { EelCanvas *canvas; GdkPixbuf *temp_pixbuf, *old_pixbuf; GtkStyleContext *style; GdkRGBA color; + cairo_surface_t *surface; temp_pixbuf = canvas_item->details->pixbuf; canvas = EEL_CANVAS_ITEM(canvas_item)->canvas; @@ -1272,23 +1297,28 @@ real_map_pixbuf (NautilusCanvasItem *canvas_item) g_object_unref (old_pixbuf); } - - return temp_pixbuf; + + surface = gdk_cairo_surface_create_from_pixbuf (temp_pixbuf, + gtk_widget_get_scale_factor (GTK_WIDGET (canvas)), + gtk_widget_get_window (GTK_WIDGET (canvas))); + g_object_unref (temp_pixbuf); + + return surface; } -static GdkPixbuf * -map_pixbuf (NautilusCanvasItem *canvas_item) +static cairo_surface_t * +map_surface (NautilusCanvasItem *canvas_item) { - if (!(canvas_item->details->rendered_pixbuf != NULL + if (!(canvas_item->details->rendered_surface != NULL && canvas_item->details->rendered_is_prelit == canvas_item->details->is_prelit && canvas_item->details->rendered_is_highlighted_for_selection == canvas_item->details->is_highlighted_for_selection && canvas_item->details->rendered_is_highlighted_for_drop == canvas_item->details->is_highlighted_for_drop && canvas_item->details->rendered_is_highlighted_for_clipboard == canvas_item->details->is_highlighted_for_clipboard && (canvas_item->details->is_highlighted_for_selection && canvas_item->details->rendered_is_focused == gtk_widget_has_focus (GTK_WIDGET (EEL_CANVAS_ITEM (canvas_item)->canvas))))) { - if (canvas_item->details->rendered_pixbuf != NULL) { - g_object_unref (canvas_item->details->rendered_pixbuf); + if (canvas_item->details->rendered_surface != NULL) { + cairo_surface_destroy (canvas_item->details->rendered_surface); } - canvas_item->details->rendered_pixbuf = real_map_pixbuf (canvas_item); + canvas_item->details->rendered_surface = real_map_surface (canvas_item); canvas_item->details->rendered_is_prelit = canvas_item->details->is_prelit; canvas_item->details->rendered_is_highlighted_for_selection = canvas_item->details->is_highlighted_for_selection; canvas_item->details->rendered_is_highlighted_for_drop = canvas_item->details->is_highlighted_for_drop; @@ -1296,9 +1326,9 @@ map_pixbuf (NautilusCanvasItem *canvas_item) canvas_item->details->rendered_is_focused = gtk_widget_has_focus (GTK_WIDGET (EEL_CANVAS_ITEM (canvas_item)->canvas)); } - g_object_ref (canvas_item->details->rendered_pixbuf); + cairo_surface_reference (canvas_item->details->rendered_surface); - return canvas_item->details->rendered_pixbuf; + return canvas_item->details->rendered_surface; } static void @@ -1368,7 +1398,7 @@ nautilus_canvas_item_draw (EelCanvasItem *item, NautilusCanvasItem *canvas_item; NautilusCanvasItemDetails *details; EelIRect icon_rect; - GdkPixbuf *temp_pixbuf; + cairo_surface_t *temp_surface; GtkStyleContext *context; container = NAUTILUS_CANVAS_CONTAINER (item->canvas); @@ -1385,12 +1415,12 @@ nautilus_canvas_item_draw (EelCanvasItem *item, gtk_style_context_add_class (context, "nautilus-canvas-item"); icon_rect = canvas_item->details->icon_rect; - temp_pixbuf = map_pixbuf (canvas_item); + temp_surface = map_surface (canvas_item); - gtk_render_icon (context, cr, - temp_pixbuf, - icon_rect.x0, icon_rect.y0); - g_object_unref (temp_pixbuf); + gtk_render_icon_surface (context, cr, + temp_surface, + icon_rect.x0, icon_rect.y0); + cairo_surface_destroy (temp_surface); draw_embedded_text (canvas_item, cr, icon_rect.x0, icon_rect.y0); @@ -1710,6 +1740,7 @@ nautilus_canvas_item_ensure_bounds_up_to_date (NautilusCanvasItem *canvas_item) EelIRect total_rect, total_rect_for_layout, total_rect_for_entire_text; EelCanvasItem *item; double pixels_per_unit; + gint width, height; details = canvas_item->details; item = EEL_CANVAS_ITEM (canvas_item); @@ -1724,17 +1755,13 @@ nautilus_canvas_item_ensure_bounds_up_to_date (NautilusCanvasItem *canvas_item) icon_rect.y0 = 0; icon_rect_raw.x0 = 0; icon_rect_raw.y0 = 0; - if (details->pixbuf == NULL) { - icon_rect.x1 = icon_rect.x0; - icon_rect.y1 = icon_rect.y0; - icon_rect_raw.x1 = icon_rect_raw.x0; - icon_rect_raw.y1 = icon_rect_raw.y0; - } else { - icon_rect_raw.x1 = icon_rect_raw.x0 + gdk_pixbuf_get_width (details->pixbuf); - icon_rect_raw.y1 = icon_rect_raw.y0 + gdk_pixbuf_get_height (details->pixbuf); - icon_rect.x1 = icon_rect_raw.x1 / pixels_per_unit; - icon_rect.y1 = icon_rect_raw.y1 / pixels_per_unit; - } + + get_scaled_icon_size (canvas_item, &width, &height); + + icon_rect_raw.x1 = icon_rect_raw.x0 + width; + icon_rect_raw.y1 = icon_rect_raw.y0 + height; + icon_rect.x1 = icon_rect_raw.x1 / pixels_per_unit; + icon_rect.y1 = icon_rect_raw.y1 / pixels_per_unit; /* Compute text rectangle. */ text_rect = compute_text_rectangle (canvas_item, icon_rect, FALSE, BOUNDS_USAGE_FOR_DISPLAY); @@ -1759,18 +1786,17 @@ nautilus_canvas_item_get_icon_rectangle (const NautilusCanvasItem *item) { EelDRect rectangle; double pixels_per_unit; - GdkPixbuf *pixbuf; + gint width, height; g_return_val_if_fail (NAUTILUS_IS_CANVAS_ITEM (item), eel_drect_empty); rectangle.x0 = item->details->x; rectangle.y0 = item->details->y; - pixbuf = item->details->pixbuf; - pixels_per_unit = EEL_CANVAS_ITEM (item)->canvas->pixels_per_unit; - rectangle.x1 = rectangle.x0 + (pixbuf == NULL ? 0 : gdk_pixbuf_get_width (pixbuf)) / pixels_per_unit; - rectangle.y1 = rectangle.y0 + (pixbuf == NULL ? 0 : gdk_pixbuf_get_height (pixbuf)) / pixels_per_unit; + get_scaled_icon_size (NAUTILUS_CANVAS_ITEM (item), &width, &height); + rectangle.x1 = rectangle.x0 + width / pixels_per_unit; + rectangle.y1 = rectangle.y0 + height / pixels_per_unit; eel_canvas_item_i2w (EEL_CANVAS_ITEM (item), &rectangle.x0, @@ -1791,18 +1817,17 @@ nautilus_canvas_item_get_text_rectangle (NautilusCanvasItem *item, EelIRect text_rectangle; EelDRect ret; double pixels_per_unit; - GdkPixbuf *pixbuf; + gint width, height; g_return_val_if_fail (NAUTILUS_IS_CANVAS_ITEM (item), eel_drect_empty); icon_rectangle.x0 = item->details->x; icon_rectangle.y0 = item->details->y; - pixbuf = item->details->pixbuf; - pixels_per_unit = EEL_CANVAS_ITEM (item)->canvas->pixels_per_unit; - icon_rectangle.x1 = icon_rectangle.x0 + (pixbuf == NULL ? 0 : gdk_pixbuf_get_width (pixbuf)) / pixels_per_unit; - icon_rectangle.y1 = icon_rectangle.y0 + (pixbuf == NULL ? 0 : gdk_pixbuf_get_height (pixbuf)) / pixels_per_unit; + get_scaled_icon_size (item, &width, &height); + icon_rectangle.x1 = icon_rectangle.x0 + width / pixels_per_unit; + icon_rectangle.y1 = icon_rectangle.y0 + height / pixels_per_unit; measure_label_text (item); @@ -1824,27 +1849,27 @@ nautilus_canvas_item_get_text_rectangle (NautilusCanvasItem *item, return ret; } - /* Get the rectangle of the icon only, in canvas coordinates. */ static void get_icon_rectangle (NautilusCanvasItem *item, - EelIRect *rect) + EelIRect *rect) { - GdkPixbuf *pixbuf; + gint width, height; g_assert (NAUTILUS_IS_CANVAS_ITEM (item)); g_assert (rect != NULL); + eel_canvas_w2c (EEL_CANVAS_ITEM (item)->canvas, item->details->x, item->details->y, &rect->x0, &rect->y0); - pixbuf = item->details->pixbuf; + get_scaled_icon_size (item, &width, &height); - rect->x1 = rect->x0 + (pixbuf == NULL ? 0 : gdk_pixbuf_get_width (pixbuf)); - rect->y1 = rect->y0 + (pixbuf == NULL ? 0 : gdk_pixbuf_get_height (pixbuf)); + rect->x1 = rect->x0 + width; + rect->y1 = rect->y0 + height; } void @@ -2385,13 +2410,7 @@ nautilus_canvas_item_accessible_get_image_size NautilusCanvasItem *item; item = NAUTILUS_CANVAS_ITEM (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (image))); - - if (!item || !item->details->pixbuf) { - *width = *height = 0; - } else { - *width = gdk_pixbuf_get_width (item->details->pixbuf); - *height = gdk_pixbuf_get_height (item->details->pixbuf); - } + get_scaled_icon_size (item, width, height); } static void @@ -2471,7 +2490,7 @@ nautilus_canvas_item_accessible_get_offset_at_point (AtkText *text, char *canvas_text; gboolean have_editable; gboolean have_additional; - gint text_offset; + gint text_offset, height; atk_component_get_extents (ATK_COMPONENT (text), &real_x, &real_y, &real_width, &real_height, coords); @@ -2482,7 +2501,8 @@ nautilus_canvas_item_accessible_get_offset_at_point (AtkText *text, item = NAUTILUS_CANVAS_ITEM (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text))); if (item->details->pixbuf) { - y -= gdk_pixbuf_get_height (item->details->pixbuf); + get_scaled_icon_size (item, NULL, &height); + y -= height; } have_editable = item->details->editable_text != NULL && item->details->editable_text[0] != '\0'; @@ -2578,13 +2598,14 @@ nautilus_canvas_item_accessible_get_character_extents (AtkText *text, PangoRectangle rect; PangoRectangle rect0; gboolean have_editable; - gint text_offset; + gint text_offset, pix_height; atk_component_get_position (ATK_COMPONENT (text), &pos_x, &pos_y, coords); item = NAUTILUS_CANVAS_ITEM (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text))); if (item->details->pixbuf) { - pos_y += gdk_pixbuf_get_height (item->details->pixbuf); + get_scaled_icon_size (item, NULL, &pix_height); + pos_y += pix_height; } have_editable = item->details->editable_text != NULL && diff --git a/libnautilus-private/nautilus-file-conflict-dialog.c b/libnautilus-private/nautilus-file-conflict-dialog.c index 7290fe414..c20e081e5 100644 --- a/libnautilus-private/nautilus-file-conflict-dialog.c +++ b/libnautilus-private/nautilus-file-conflict-dialog.c @@ -78,6 +78,7 @@ file_icons_changed (NautilusFile *file, pixbuf = nautilus_file_get_icon_pixbuf (fcd->details->destination, NAUTILUS_ICON_SIZE_LARGE, TRUE, + gtk_widget_get_scale_factor (fcd->details->dest_image), NAUTILUS_FILE_ICON_FLAGS_USE_THUMBNAILS); gtk_image_set_from_pixbuf (GTK_IMAGE (fcd->details->dest_image), pixbuf); @@ -86,6 +87,7 @@ file_icons_changed (NautilusFile *file, pixbuf = nautilus_file_get_icon_pixbuf (fcd->details->source, NAUTILUS_ICON_SIZE_LARGE, TRUE, + gtk_widget_get_scale_factor (fcd->details->src_image), NAUTILUS_FILE_ICON_FLAGS_USE_THUMBNAILS); gtk_image_set_from_pixbuf (GTK_IMAGE (fcd->details->src_image), pixbuf); @@ -221,6 +223,7 @@ file_list_ready_cb (GList *files, pixbuf = nautilus_file_get_icon_pixbuf (dest, NAUTILUS_ICON_SIZE_LARGE, TRUE, + gtk_widget_get_scale_factor (fcd->details->titles_vbox), NAUTILUS_FILE_ICON_FLAGS_USE_THUMBNAILS); details->dest_image = gtk_image_new_from_pixbuf (pixbuf); gtk_box_pack_start (GTK_BOX (details->first_hbox), @@ -231,6 +234,7 @@ file_list_ready_cb (GList *files, pixbuf = nautilus_file_get_icon_pixbuf (src, NAUTILUS_ICON_SIZE_LARGE, TRUE, + gtk_widget_get_scale_factor (fcd->details->titles_vbox), NAUTILUS_FILE_ICON_FLAGS_USE_THUMBNAILS); details->src_image = gtk_image_new_from_pixbuf (pixbuf); gtk_box_pack_start (GTK_BOX (details->second_hbox), diff --git a/libnautilus-private/nautilus-file.c b/libnautilus-private/nautilus-file.c index 5ae7cc419..75fadfbdf 100644 --- a/libnautilus-private/nautilus-file.c +++ b/libnautilus-private/nautilus-file.c @@ -4230,6 +4230,7 @@ nautilus_file_get_thumbnail_path (NautilusFile *file) NautilusIconInfo * nautilus_file_get_icon (NautilusFile *file, int size, + int scale, NautilusFileIconFlags flags) { NautilusIconInfo *icon; @@ -4247,7 +4248,7 @@ nautilus_file_get_icon (NautilusFile *file, } if (gicon != NULL) { - icon = nautilus_icon_info_lookup (gicon, size); + icon = nautilus_icon_info_lookup (gicon, size, scale); g_object_unref (gicon); return icon; @@ -4268,7 +4269,7 @@ nautilus_file_get_icon (NautilusFile *file, nautilus_file_should_show_thumbnail (file)) { if (file->details->thumbnail) { int w, h, s; - double scale; + double thumb_scale; raw_pixbuf = g_object_ref (file->details->thumbnail); @@ -4278,19 +4279,19 @@ nautilus_file_get_icon (NautilusFile *file, s = MAX (w, h); /* Don't scale up small thumbnails in the standard view */ if (s <= cached_thumbnail_size) { - scale = (double)size / NAUTILUS_ICON_SIZE_STANDARD; + thumb_scale = (double)size / NAUTILUS_ICON_SIZE_STANDARD; } else { - scale = (double)modified_size / s; + thumb_scale = (double)modified_size / s; } /* Make sure that icons don't get smaller than NAUTILUS_ICON_SIZE_SMALLEST */ - if (s*scale <= NAUTILUS_ICON_SIZE_SMALLEST) { - scale = (double) NAUTILUS_ICON_SIZE_SMALLEST / s; + if (s*thumb_scale <= NAUTILUS_ICON_SIZE_SMALLEST) { + thumb_scale = (double) NAUTILUS_ICON_SIZE_SMALLEST / s; } scaled_pixbuf = gdk_pixbuf_scale_simple (raw_pixbuf, - MAX (w * scale, 1), - MAX (h * scale, 1), + MAX (w * thumb_scale, 1), + MAX (h * thumb_scale, 1), GDK_INTERP_BILINEAR); /* We don't want frames around small icons */ @@ -4313,9 +4314,9 @@ nautilus_file_get_icon (NautilusFile *file, } DEBUG ("Returning thumbnailed image, at size %d %d", - (int) (w * scale), (int) (h * scale)); + (int) (w * thumb_scale), (int) (h * thumb_scale)); - icon = nautilus_icon_info_new_for_pixbuf (scaled_pixbuf); + icon = nautilus_icon_info_new_for_pixbuf (scaled_pixbuf, scale); g_object_unref (scaled_pixbuf); return icon; } else if (file->details->thumbnail_path == NULL && @@ -4335,15 +4336,15 @@ nautilus_file_get_icon (NautilusFile *file, gicon = nautilus_file_get_gicon (file, flags); if (gicon) { - icon = nautilus_icon_info_lookup (gicon, size); + icon = nautilus_icon_info_lookup (gicon, size, scale); if (nautilus_icon_info_is_fallback (icon)) { g_object_unref (icon); - icon = nautilus_icon_info_lookup (get_default_file_icon (flags), size); + icon = nautilus_icon_info_lookup (get_default_file_icon (flags), size, scale); } g_object_unref (gicon); return icon; } else { - return nautilus_icon_info_lookup (get_default_file_icon (flags), size); + return nautilus_icon_info_lookup (get_default_file_icon (flags), size, scale); } } @@ -4351,12 +4352,13 @@ GdkPixbuf * nautilus_file_get_icon_pixbuf (NautilusFile *file, int size, gboolean force_size, + int scale, NautilusFileIconFlags flags) { NautilusIconInfo *info; GdkPixbuf *pixbuf; - info = nautilus_file_get_icon (file, size, flags); + info = nautilus_file_get_icon (file, size, scale, flags); if (force_size) { pixbuf = nautilus_icon_info_get_pixbuf_at_size (info, size); } else { diff --git a/libnautilus-private/nautilus-file.h b/libnautilus-private/nautilus-file.h index 488d85685..fb1c62cbf 100644 --- a/libnautilus-private/nautilus-file.h +++ b/libnautilus-private/nautilus-file.h @@ -435,10 +435,12 @@ GIcon * nautilus_file_get_gicon (Nautilu NautilusFileIconFlags flags); NautilusIconInfo * nautilus_file_get_icon (NautilusFile *file, int size, + int scale, NautilusFileIconFlags flags); GdkPixbuf * nautilus_file_get_icon_pixbuf (NautilusFile *file, int size, gboolean force_size, + int scale, NautilusFileIconFlags flags); gboolean nautilus_file_has_open_window (NautilusFile *file); diff --git a/libnautilus-private/nautilus-icon-info.c b/libnautilus-private/nautilus-icon-info.c index 57ea3a200..81894d2dd 100644 --- a/libnautilus-private/nautilus-icon-info.c +++ b/libnautilus-private/nautilus-icon-info.c @@ -40,6 +40,8 @@ struct _NautilusIconInfo GdkPoint *attach_points; char *display_name; char *icon_name; + + gint orig_scale; }; struct _NautilusIconInfoClass @@ -118,7 +120,8 @@ nautilus_icon_info_class_init (NautilusIconInfoClass *icon_info_class) } NautilusIconInfo * -nautilus_icon_info_new_for_pixbuf (GdkPixbuf *pixbuf) +nautilus_icon_info_new_for_pixbuf (GdkPixbuf *pixbuf, + gint scale) { NautilusIconInfo *icon; @@ -126,13 +129,16 @@ nautilus_icon_info_new_for_pixbuf (GdkPixbuf *pixbuf) if (pixbuf) { icon->pixbuf = g_object_ref (pixbuf); - } + } + + icon->orig_scale = scale; return icon; } static NautilusIconInfo * -nautilus_icon_info_new_for_icon_info (GtkIconInfo *icon_info) +nautilus_icon_info_new_for_icon_info (GtkIconInfo *icon_info, + gint scale) { NautilusIconInfo *icon; GdkPoint *points; @@ -163,6 +169,8 @@ nautilus_icon_info_new_for_icon_info (GtkIconInfo *icon_info) } icon->icon_name = basename; } + + icon->orig_scale = scale; return icon; } @@ -326,7 +334,8 @@ themed_icon_key_free (ThemedIconKey *key) NautilusIconInfo * nautilus_icon_info_lookup (GIcon *icon, - int size) + int size, + int scale) { NautilusIconInfo *icon_info; GdkPixbuf *pixbuf; @@ -354,17 +363,18 @@ nautilus_icon_info_lookup (GIcon *icon, pixbuf = NULL; stream = g_loadable_icon_load (G_LOADABLE_ICON (icon), - size, + size * scale, NULL, NULL, NULL); if (stream) { pixbuf = gdk_pixbuf_new_from_stream_at_scale (stream, - size, size, TRUE, + size * scale, size * scale, + TRUE, NULL, NULL); g_input_stream_close (stream, NULL, NULL); g_object_unref (stream); } - icon_info = nautilus_icon_info_new_for_pixbuf (pixbuf); + icon_info = nautilus_icon_info_new_for_pixbuf (pixbuf, scale); key = loadable_icon_key_new (icon, size); g_hash_table_insert (loadable_icon_cache, key, icon_info); @@ -389,16 +399,17 @@ nautilus_icon_info_lookup (GIcon *icon, names = g_themed_icon_get_names (G_THEMED_ICON (icon)); icon_theme = gtk_icon_theme_get_default (); - gtkicon_info = gtk_icon_theme_choose_icon (icon_theme, (const char **)names, size, 0); + gtkicon_info = gtk_icon_theme_choose_icon_for_scale (icon_theme, (const char **)names, + size, scale, 0); if (gtkicon_info == NULL) { - return nautilus_icon_info_new_for_pixbuf (NULL); + return nautilus_icon_info_new_for_pixbuf (NULL, scale); } filename = gtk_icon_info_get_filename (gtkicon_info); if (filename == NULL) { g_object_unref (gtkicon_info); - return nautilus_icon_info_new_for_pixbuf (NULL); + return nautilus_icon_info_new_for_pixbuf (NULL, scale); } lookup_key.filename = (char *)filename; @@ -410,7 +421,7 @@ nautilus_icon_info_lookup (GIcon *icon, return g_object_ref (icon_info); } - icon_info = nautilus_icon_info_new_for_icon_info (gtkicon_info); + icon_info = nautilus_icon_info_new_for_icon_info (gtkicon_info, scale); key = themed_icon_key_new (filename, size); g_hash_table_insert (themed_icon_cache, key, icon_info); @@ -422,10 +433,11 @@ nautilus_icon_info_lookup (GIcon *icon, GdkPixbuf *pixbuf; GtkIconInfo *gtk_icon_info; - gtk_icon_info = gtk_icon_theme_lookup_by_gicon (gtk_icon_theme_get_default (), - icon, - size, - GTK_ICON_LOOKUP_GENERIC_FALLBACK); + gtk_icon_info = gtk_icon_theme_lookup_by_gicon_for_scale (gtk_icon_theme_get_default (), + icon, + size, + scale, + GTK_ICON_LOOKUP_GENERIC_FALLBACK); if (gtk_icon_info != NULL) { pixbuf = gtk_icon_info_load_icon (gtk_icon_info, NULL); g_object_unref (gtk_icon_info); @@ -433,7 +445,7 @@ nautilus_icon_info_lookup (GIcon *icon, pixbuf = NULL; } - icon_info = nautilus_icon_info_new_for_pixbuf (pixbuf); + icon_info = nautilus_icon_info_new_for_pixbuf (pixbuf, scale); if (pixbuf != NULL) { g_object_unref (pixbuf); @@ -445,20 +457,22 @@ nautilus_icon_info_lookup (GIcon *icon, NautilusIconInfo * nautilus_icon_info_lookup_from_name (const char *name, - int size) + int size, + int scale) { GIcon *icon; NautilusIconInfo *info; icon = g_themed_icon_new (name); - info = nautilus_icon_info_lookup (icon, size); + info = nautilus_icon_info_lookup (icon, size, scale); g_object_unref (icon); return info; } NautilusIconInfo * nautilus_icon_info_lookup_from_path (const char *path, - int size) + int size, + int scale) { GFile *icon_file; GIcon *icon; @@ -466,7 +480,7 @@ nautilus_icon_info_lookup_from_path (const char *path, icon_file = g_file_new_for_path (path); icon = g_file_icon_new (icon_file); - info = nautilus_icon_info_lookup (icon, size); + info = nautilus_icon_info_lookup (icon, size, scale); g_object_unref (icon); g_object_unref (icon_file); return info; @@ -527,9 +541,9 @@ nautilus_icon_info_get_pixbuf_nodefault_at_size (NautilusIconInfo *icon, if (pixbuf == NULL) return NULL; - - w = gdk_pixbuf_get_width (pixbuf); - h = gdk_pixbuf_get_height (pixbuf); + + w = gdk_pixbuf_get_width (pixbuf) / icon->orig_scale; + h = gdk_pixbuf_get_height (pixbuf) / icon->orig_scale; s = MAX (w, h); if (s == forced_size) { return pixbuf; @@ -554,8 +568,8 @@ nautilus_icon_info_get_pixbuf_at_size (NautilusIconInfo *icon, pixbuf = nautilus_icon_info_get_pixbuf (icon); - w = gdk_pixbuf_get_width (pixbuf); - h = gdk_pixbuf_get_height (pixbuf); + w = gdk_pixbuf_get_width (pixbuf) / icon->orig_scale; + h = gdk_pixbuf_get_height (pixbuf) / icon->orig_scale; s = MAX (w, h); if (s == forced_size) { return pixbuf; diff --git a/libnautilus-private/nautilus-icon-info.h b/libnautilus-private/nautilus-icon-info.h index 6a0f95a72..1f87b2dc5 100644 --- a/libnautilus-private/nautilus-icon-info.h +++ b/libnautilus-private/nautilus-icon-info.h @@ -53,13 +53,17 @@ typedef struct _NautilusIconInfoClass NautilusIconInfoClass; GType nautilus_icon_info_get_type (void) G_GNUC_CONST; -NautilusIconInfo * nautilus_icon_info_new_for_pixbuf (GdkPixbuf *pixbuf); +NautilusIconInfo * nautilus_icon_info_new_for_pixbuf (GdkPixbuf *pixbuf, + int scale); NautilusIconInfo * nautilus_icon_info_lookup (GIcon *icon, - int size); + int size, + int scale); NautilusIconInfo * nautilus_icon_info_lookup_from_name (const char *name, - int size); + int size, + int scale); NautilusIconInfo * nautilus_icon_info_lookup_from_path (const char *path, - int size); + int size, + int scale); gboolean nautilus_icon_info_is_fallback (NautilusIconInfo *icon); GdkPixbuf * nautilus_icon_info_get_pixbuf (NautilusIconInfo *icon); GdkPixbuf * nautilus_icon_info_get_pixbuf_nodefault (NautilusIconInfo *icon); diff --git a/libnautilus-private/nautilus-program-choosing.c b/libnautilus-private/nautilus-program-choosing.c index 25b99b276..6c74760b5 100644 --- a/libnautilus-private/nautilus-program-choosing.c +++ b/libnautilus-private/nautilus-program-choosing.c @@ -136,7 +136,9 @@ nautilus_launch_application_by_uri (GAppInfo *application, } file = nautilus_file_get_by_uri (uris->data); - icon = nautilus_file_get_icon (file, 48, 0); + icon = nautilus_file_get_icon (file, + 48, gtk_widget_get_scale_factor (GTK_WIDGET (parent_window)), + 0); nautilus_file_unref (file); if (icon) { gdk_app_launch_context_set_icon_name (launch_context, diff --git a/libnautilus-private/nautilus-ui-utilities.c b/libnautilus-private/nautilus-ui-utilities.c index 0a1e37487..7a1ec364b 100644 --- a/libnautilus-private/nautilus-ui-utilities.c +++ b/libnautilus-private/nautilus-ui-utilities.c @@ -69,7 +69,8 @@ extension_action_callback (GtkAction *action, } GtkAction * -nautilus_action_from_menu_item (NautilusMenuItem *item) +nautilus_action_from_menu_item (NautilusMenuItem *item, + GtkWidget *parent_widget) { char *name, *label, *tip, *icon_name; gboolean sensitive, priority; @@ -89,7 +90,7 @@ nautilus_action_from_menu_item (NautilusMenuItem *item) NULL); if (icon_name != NULL) { - pixbuf = nautilus_ui_get_menu_icon (icon_name); + pixbuf = nautilus_ui_get_menu_icon (icon_name, parent_widget); if (pixbuf != NULL) { gtk_action_set_gicon (action, G_ICON (pixbuf)); g_object_unref (pixbuf); @@ -113,18 +114,21 @@ nautilus_action_from_menu_item (NautilusMenuItem *item) } GdkPixbuf * -nautilus_ui_get_menu_icon (const char *icon_name) +nautilus_ui_get_menu_icon (const char *icon_name, + GtkWidget *parent_widget) { NautilusIconInfo *info; GdkPixbuf *pixbuf; int size; + int scale; size = nautilus_get_icon_size_for_stock_size (GTK_ICON_SIZE_MENU); + scale = gtk_widget_get_scale_factor (parent_widget); if (g_path_is_absolute (icon_name)) { - info = nautilus_icon_info_lookup_from_path (icon_name, size); + info = nautilus_icon_info_lookup_from_path (icon_name, size, scale); } else { - info = nautilus_icon_info_lookup_from_name (icon_name, size); + info = nautilus_icon_info_lookup_from_name (icon_name, size, scale); } pixbuf = nautilus_icon_info_get_pixbuf_nodefault_at_size (info, size); g_object_unref (info); diff --git a/libnautilus-private/nautilus-ui-utilities.h b/libnautilus-private/nautilus-ui-utilities.h index 12e2e5e5a..333285e34 100644 --- a/libnautilus-private/nautilus-ui-utilities.h +++ b/libnautilus-private/nautilus-ui-utilities.h @@ -34,9 +34,11 @@ void nautilus_ui_prepare_merge_ui (GtkUIManager *ui_manage const char *name, guint *merge_id, GtkActionGroup **action_group); -GtkAction * nautilus_action_from_menu_item (NautilusMenuItem *item); +GtkAction * nautilus_action_from_menu_item (NautilusMenuItem *item, + GtkWidget *parent_widget); -GdkPixbuf * nautilus_ui_get_menu_icon (const char *icon_name); +GdkPixbuf * nautilus_ui_get_menu_icon (const char *icon_name, + GtkWidget *parent_widget); char * nautilus_escape_action_name (const char *action_name, const char *prefix); |