[gnome-shell] screenshot-ui: Use ImageContent for notification icon



commit 27bcf0da484cc1274eda0c2ed133b883e8cfe76e
Author: Ivan Molodetskikh <yalterz gmail com>
Date:   Fri Nov 26 20:06:36 2021 +0300

    screenshot-ui: Use ImageContent for notification icon
    
    StImageContent specifically, when used as a notification icon, preserves
    the screenshot aspect ratio and avoids ugly scaling.
    
    Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1954>

 js/ui/screenshot.js    | 31 +++++++++++++++++++++----------
 src/shell-screenshot.c | 11 ++++++-----
 src/shell-screenshot.h |  4 ++--
 3 files changed, 29 insertions(+), 17 deletions(-)
---
diff --git a/js/ui/screenshot.js b/js/ui/screenshot.js
index c6b4c1387f..11f97831c2 100644
--- a/js/ui/screenshot.js
+++ b/js/ui/screenshot.js
@@ -1,7 +1,7 @@
 // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 /* exported ScreenshotService, ScreenshotUI, showScreenshotUI */
 
-const { Clutter, Gio, GObject, GLib, Gtk, Meta, Shell, St } = imports.gi;
+const { Clutter, Cogl, Gio, GObject, GLib, Gtk, Meta, Shell, St } = imports.gi;
 
 const GrabHelper = imports.ui.grabHelper;
 const Layout = imports.ui.layout;
@@ -1531,7 +1531,7 @@ class ScreenshotUI extends St.Widget {
         this.close();
     }
 
-    _storeScreenshot(bytes) {
+    _storeScreenshot(bytes, pixbuf) {
         // Store to the clipboard first in case storing to file fails.
         const clipboard = St.Clipboard.get_default();
         clipboard.set_content(St.ClipboardType.CLIPBOARD, 'image/png', bytes);
@@ -1589,6 +1589,20 @@ class ScreenshotUI extends St.Widget {
         // Add it to recent files.
         Gtk.RecentManager.get_default().add_item(file.get_uri());
 
+        // Create a St.ImageContent icon for the notification. We want
+        // St.ImageContent specifically because it preserves the aspect ratio when
+        // shown in a notification.
+        const pixels = pixbuf.read_pixel_bytes();
+        const content =
+            St.ImageContent.new_with_preferred_size(pixbuf.width, pixbuf.height);
+        content.set_bytes(
+            pixels,
+            Cogl.PixelFormat.RGBA_8888,
+            pixbuf.width,
+            pixbuf.height,
+            pixbuf.rowstride
+        );
+
         // Show a notification.
         const source = new MessageTray.Source(
             // Translators: notification source name.
@@ -1601,10 +1615,7 @@ class ScreenshotUI extends St.Widget {
             _('Screenshot captured'),
             // Translators: notification body when a screenshot was captured.
             _('You can paste the image from the clipboard.'),
-            {
-                datetime: time,
-                gicon: Gio.BytesIcon.new(bytes),
-            }
+            { datetime: time, gicon: content }
         );
         // Translators: button on the screenshot notification.
         notification.addAction(_('Show in Files'), () => {
@@ -1660,9 +1671,9 @@ class ScreenshotUI extends St.Widget {
                 this._cursor.y * this._scale,
                 this._cursorScale,
                 stream
-            ).then(() => {
+            ).then(pixbuf => {
                 stream.close(null);
-                this._storeScreenshot(stream.steal_as_bytes());
+                this._storeScreenshot(stream.steal_as_bytes(), pixbuf);
             }).catch(err => {
                 logError(err, 'Error capturing screenshot');
             });
@@ -1693,9 +1704,9 @@ class ScreenshotUI extends St.Widget {
                 window.cursorPoint.y * window.bufferScale,
                 this._cursorScale,
                 stream
-            ).then(() => {
+            ).then(pixbuf => {
                 stream.close(null);
-                this._storeScreenshot(stream.steal_as_bytes());
+                this._storeScreenshot(stream.steal_as_bytes(), pixbuf);
             }).catch(err => {
                 logError(err, 'Error capturing screenshot');
             });
diff --git a/src/shell-screenshot.c b/src/shell-screenshot.c
index f87b61e490..fcf2da2365 100644
--- a/src/shell-screenshot.c
+++ b/src/shell-screenshot.c
@@ -1049,7 +1049,7 @@ shell_screenshot_pick_color_finish (ShellScreenshot  *screenshot,
 #undef INDEX_B
 
 static void
-composite_to_stream_on_png_saved (GObject      *source,
+composite_to_stream_on_png_saved (GObject      *pixbuf,
                                   GAsyncResult *result,
                                   gpointer      user_data)
 {
@@ -1059,7 +1059,7 @@ composite_to_stream_on_png_saved (GObject      *source,
   if (!gdk_pixbuf_save_to_stream_finish (result, &error))
     g_task_return_error (task, error);
   else
-    g_task_return_boolean (task, TRUE);
+    g_task_return_pointer (task, g_object_ref (pixbuf), g_object_unref);
 
   g_object_unref (task);
 }
@@ -1193,10 +1193,11 @@ shell_screenshot_composite_to_stream (CoglTexture         *texture,
  * Finish the asynchronous operation started by
  * shell_screenshot_composite_to_stream () and obtain its result.
  *
- * Returns: whether the operation was successful
+ * Returns: (transfer full) (nullable): a GdkPixbuf with the final image if the
+ * operation was successful, or NULL on error.
  *
  */
-gboolean
+GdkPixbuf *
 shell_screenshot_composite_to_stream_finish (GAsyncResult  *result,
                                              GError       **error)
 {
@@ -1205,7 +1206,7 @@ shell_screenshot_composite_to_stream_finish (GAsyncResult  *result,
                                                   shell_screenshot_composite_to_stream),
                         FALSE);
 
-  return g_task_propagate_boolean (G_TASK (result), error);
+  return g_task_propagate_pointer (G_TASK (result), error);
 }
 
 ShellScreenshot *
diff --git a/src/shell-screenshot.h b/src/shell-screenshot.h
index b379b8a0aa..441410d6c5 100644
--- a/src/shell-screenshot.h
+++ b/src/shell-screenshot.h
@@ -84,7 +84,7 @@ void shell_screenshot_composite_to_stream (CoglTexture         *texture,
                                            GOutputStream       *stream,
                                            GAsyncReadyCallback  callback,
                                            gpointer             user_data);
-gboolean shell_screenshot_composite_to_stream_finish (GAsyncResult  *result,
-                                                      GError       **error);
+GdkPixbuf *shell_screenshot_composite_to_stream_finish (GAsyncResult  *result,
+                                                        GError       **error);
 
 #endif /* ___SHELL_SCREENSHOT_H__ */


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