[gnome-shell] shell-screenshot: Apply monitor scale to cursor surface



commit 115eda96501102ba26d4a46c7184c7f079c25602
Author: Marco Trevisan (Treviño) <mail 3v1n0 net>
Date:   Wed Feb 13 02:30:28 2019 +0100

    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

 src/shell-screenshot.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)
---
diff --git a/src/shell-screenshot.c b/src/shell-screenshot.c
index 00c8cd227..61fdc1d1e 100644
--- a/src/shell-screenshot.c
+++ b/src/shell-screenshot.c
@@ -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);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]