shell-screenshot: Apply monitor scale to cursor surface

When we grab a screenshot of a framebuffer scaled shell, we shoudl apply the
device scale to the image surface, while the monitor scaling should be applied
to the cursor surface, so that it's painted at proper coordinates and in proper
size in the generated image.

This is not needed for XWayland clients as they are not scaled anyways, while
for wayland clients that are painted in multiple monitors, this might cause
a lower quality cursor in the lower dpi monitor, because the cursor sprite is
generated for the monitor scale, and not for the surface scale.

https://bugzilla.gnome.org/show_bug.cgi?id=765011
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/5
This commit is contained in:
Marco Trevisan (Treviño) 2019-02-13 02:30:28 +01:00 committed by Jonas Ådahl
parent d027e35cef
commit 115eda9650

View File

@ -323,6 +323,22 @@ draw_cursor_image (cairo_surface_t *surface,
width, height,
stride);
cairo_surface_get_device_scale (surface, &xscale, &yscale);
if (xscale != 1.0 || yscale != 1.0)
{
int monitor;
float monitor_scale;
MetaRectangle cursor_rect = {
.x = x, .y = y, .width = width, .height = height
};
monitor = meta_display_get_monitor_index_for_rect (display, &cursor_rect);
monitor_scale = meta_display_get_monitor_scale (display, monitor);
cairo_surface_set_device_scale (cursor_surface, monitor_scale, monitor_scale);
}
cr = cairo_create (surface);
cairo_set_source_surface (cr,
cursor_surface,
@ -462,7 +478,18 @@ grab_window_screenshot (ClutterActor *stage,
priv->datetime = g_date_time_new_now_local ();
if (priv->include_cursor)
draw_cursor_image (priv->image, priv->screenshot_area);
{
if (meta_window_get_client_type (window) == META_WINDOW_CLIENT_TYPE_WAYLAND)
{
float resource_scale;
if (!clutter_actor_get_resource_scale (window_actor, &resource_scale))
resource_scale = 1.0f;
cairo_surface_set_device_scale (priv->image, resource_scale, resource_scale);
}
draw_cursor_image (priv->image, priv->screenshot_area);
}
g_signal_handlers_disconnect_by_func (stage, grab_window_screenshot, result);
task = g_task_new (screenshot, NULL, on_screenshot_written, result);