From 27bcf0da484cc1274eda0c2ed133b883e8cfe76e Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Fri, 26 Nov 2021 20:06:36 +0300 Subject: [PATCH] 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: --- 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 c6b4c1387..11f97831c 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 f87b61e49..fcf2da236 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 b379b8a0a..441410d6c 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__ */