[gnome-shell] screenshot: Composite multiple captures into one image
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] screenshot: Composite multiple captures into one image
- Date: Tue, 6 Sep 2016 07:40:21 +0000 (UTC)
commit 22f0d3076ead0c20ff5fc0e5f861d7164142e168
Author: Jonas Ådahl <jadahl gmail com>
Date: Fri Aug 19 10:47:57 2016 +0800
screenshot: Composite multiple captures into one image
When clutter gives us multiple captures (multiple cairo_surface_t's),
composite them into one large image and use that as final screenshot
result. This makes screenshooting work when mutter uses multiple views.
https://bugzilla.gnome.org/show_bug.cgi?id=770128
src/shell-screenshot.c | 16 +++++++++-------
src/shell-util.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
src/shell-util.h | 7 +++++++
3 files changed, 62 insertions(+), 7 deletions(-)
---
diff --git a/src/shell-screenshot.c b/src/shell-screenshot.c
index d7c8088..089828e 100644
--- a/src/shell-screenshot.c
+++ b/src/shell-screenshot.c
@@ -10,6 +10,7 @@
#include "shell-global.h"
#include "shell-screenshot.h"
+#include "shell-util.h"
#define A11Y_APPS_SCHEMA "org.gnome.desktop.a11y.applications"
#define MAGNIFIER_ACTIVE_KEY "screen-magnifier-enabled"
@@ -233,14 +234,15 @@ do_grab_screenshot (ShellScreenshot *screenshot,
if (n_captures == 0)
return;
+ else if (n_captures == 1)
+ priv->image = cairo_surface_reference (captures[0].image);
+ else
+ priv->image = shell_util_composite_capture_images (captures,
+ n_captures,
+ x, y,
+ width, height);
- /*
- * TODO: Deal with each capture region separately, instead of dropping
- * anything except the first one.
- */
- priv->image = captures[0].image;
-
- for (i = 1; i < n_captures; i++)
+ for (i = 0; i < n_captures; i++)
cairo_surface_destroy (captures[i].image);
g_free (captures);
diff --git a/src/shell-util.c b/src/shell-util.c
index b998f2b..f72645c 100644
--- a/src/shell-util.c
+++ b/src/shell-util.c
@@ -446,3 +446,49 @@ shell_util_get_content_for_window_actor (MetaWindowActor *window_actor,
return content;
}
+
+cairo_surface_t *
+shell_util_composite_capture_images (ClutterCapture *captures,
+ int n_captures,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ int i;
+ cairo_format_t format;
+ cairo_surface_t *image;
+ cairo_t *cr;
+
+ format = cairo_image_surface_get_format (captures[0].image);
+ image = cairo_image_surface_create (format, width, height);
+
+ cr = cairo_create (image);
+
+ for (i = 0; i < n_captures; i++)
+ {
+ ClutterCapture *capture = &captures[i];
+ double capture_scale = 1.0;
+
+ /*
+ * Ignore capture regions with scale other than 1 for now; mutter can't
+ * produce them yet, so there is no way to test them.
+ */
+ cairo_surface_get_device_scale (capture->image, &capture_scale, NULL);
+ if ((int) capture_scale != 1)
+ continue;
+
+ cairo_save (cr);
+
+ cairo_translate (cr,
+ capture->rect.x - x,
+ capture->rect.y - y);
+ cairo_set_source_surface (cr, capture->image, 0, 0);
+ cairo_paint (cr);
+
+ cairo_restore (cr);
+ }
+ cairo_destroy (cr);
+
+ return image;
+}
diff --git a/src/shell-util.h b/src/shell-util.h
index 1d25d6f..532e19b 100644
--- a/src/shell-util.h
+++ b/src/shell-util.h
@@ -51,6 +51,13 @@ gboolean shell_util_need_background_refresh (void);
ClutterContent * shell_util_get_content_for_window_actor (MetaWindowActor *window_actor,
MetaRectangle *window_rect);
+cairo_surface_t * shell_util_composite_capture_images (ClutterCapture *captures,
+ int n_captures,
+ int x,
+ int y,
+ int width,
+ int height);
+
G_END_DECLS
#endif /* __SHELL_UTIL_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]