diff options
author | Cosimo Cecchi <cosimoc@gnome.org> | 2019-07-24 17:45:35 +0200 |
---|---|---|
committer | Cosimo Cecchi <cosimoc@gnome.org> | 2019-07-24 20:31:46 +0200 |
commit | e0c4cd438a1e8225499a44dbca4013e3dc92e7d9 (patch) | |
tree | 97a3b1b9435bfc815de36ecb7a1c5a09798e0d68 | |
parent | 3f25eb50c562d3dc267c987329e0c8ec9cca6d94 (diff) | |
download | gnome-screenshot-e0c4cd438a1e8225499a44dbca4013e3dc92e7d9.tar.gz |
utils: fix X11 fallback code path for HiDPi
The X11 fallback code path did not correctly account for the
scale factor, and would lead to screenshots of a quarter size only.
-rw-r--r-- | src/screenshot-utils.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/src/screenshot-utils.c b/src/screenshot-utils.c index 434b6ee..04c0c8e 100644 --- a/src/screenshot-utils.c +++ b/src/screenshot-utils.c @@ -444,6 +444,7 @@ screenshot_fallback_get_pixbuf (GdkRectangle *rectangle) &rectangle_order); if (rectangles && rectangle_count > 0) { + int scale_factor = gdk_window_get_scale_factor (wm_window); gboolean has_alpha = gdk_pixbuf_get_has_alpha (screenshot); GdkPixbuf *tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, gdk_pixbuf_get_width (screenshot), @@ -461,11 +462,15 @@ screenshot_fallback_get_pixbuf (GdkRectangle *rectangle) * areas for the invisible borders themselves. * In that case, trim every rectangle we get by the offset between the * WM window size and the frame extents. + * + * Note that the XShape values are in actual pixels, whereas the GDK + * ones are in display pixels (i.e. scaled), so we need to apply the + * scale factor to the former to use display pixels for all our math. */ - rec_x = rectangles[i].x; - rec_y = rectangles[i].y; - rec_width = rectangles[i].width - (frame_offset.left + frame_offset.right); - rec_height = rectangles[i].height - (frame_offset.top + frame_offset.bottom); + rec_x = rectangles[i].x / scale_factor; + rec_y = rectangles[i].y / scale_factor; + rec_width = rectangles[i].width / scale_factor - (frame_offset.left + frame_offset.right); + rec_height = rectangles[i].height / scale_factor - (frame_offset.top + frame_offset.bottom); if (real_coords.x < 0) { @@ -487,19 +492,20 @@ screenshot_fallback_get_pixbuf (GdkRectangle *rectangle) if (screenshot_coords.y + rec_y + rec_height > gdk_screen_height ()) rec_height = gdk_screen_height () - screenshot_coords.y - rec_y; - for (y = rec_y; y < rec_y + rec_height; y++) + /* Undo the scale factor in order to copy the pixbuf data pixel-wise */ + for (y = rec_y * scale_factor; y < (rec_y + rec_height) * scale_factor; y++) { guchar *src_pixels, *dest_pixels; gint x; src_pixels = gdk_pixbuf_get_pixels (screenshot) + y * gdk_pixbuf_get_rowstride(screenshot) - + rec_x * (has_alpha ? 4 : 3); + + rec_x * scale_factor * (has_alpha ? 4 : 3); dest_pixels = gdk_pixbuf_get_pixels (tmp) + y * gdk_pixbuf_get_rowstride (tmp) - + rec_x * 4; + + rec_x * scale_factor * 4; - for (x = 0; x < rec_width; x++) + for (x = 0; x < rec_width * scale_factor; x++) { *dest_pixels++ = *src_pixels++; *dest_pixels++ = *src_pixels++; |