AlmaLinux changes: Use AlmaLinux icon as activities button
Use unbranded illustrations Fix Firefox desktop filename in favorites
This commit is contained in:
commit
15ccd9462d
@ -47,10 +47,11 @@ Patch: 0001-data-Update-generated-stylesheets.patch
|
|||||||
%if 0%{!?almalinux}
|
%if 0%{!?almalinux}
|
||||||
Patch: 0001-theme-Welcome-Illustration.patch
|
Patch: 0001-theme-Welcome-Illustration.patch
|
||||||
%endif
|
%endif
|
||||||
|
Patch: screenshot-tool.patch
|
||||||
|
|
||||||
# AlmaLinux Patch
|
# AlmaLinux Patch
|
||||||
Patch: 0001-panel-Bring-the-upstream-workspace-dots-back.patch
|
Patch: 0001-panel-Bring-the-upstream-workspace-dots-back.patch
|
||||||
|
|
||||||
%define eds_version 3.45.1
|
%define eds_version 3.45.1
|
||||||
%define gnome_desktop_version 44.0-7
|
%define gnome_desktop_version 44.0-7
|
||||||
%define glib2_version 2.79.2
|
%define glib2_version 2.79.2
|
||||||
@ -91,6 +92,7 @@ BuildRequires: pkgconfig(libpipewire-0.3) >= %{pipewire_version}
|
|||||||
BuildRequires: pkgconfig(gtk4) >= %{gtk4_version}
|
BuildRequires: pkgconfig(gtk4) >= %{gtk4_version}
|
||||||
BuildRequires: gettext >= 0.19.6
|
BuildRequires: gettext >= 0.19.6
|
||||||
BuildRequires: python3
|
BuildRequires: python3
|
||||||
|
BuildRequires: python3-argcomplete
|
||||||
|
|
||||||
# for rst2man
|
# for rst2man
|
||||||
BuildRequires: python3-docutils
|
BuildRequires: python3-docutils
|
||||||
@ -235,6 +237,7 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/org.gnome.Shell.Porta
|
|||||||
%doc NEWS README.md
|
%doc NEWS README.md
|
||||||
%{_bindir}/gnome-shell
|
%{_bindir}/gnome-shell
|
||||||
%{_bindir}/gnome-extensions
|
%{_bindir}/gnome-extensions
|
||||||
|
%{_bindir}/gnome-screenshot-tool
|
||||||
%{_bindir}/gnome-shell-extension-tool
|
%{_bindir}/gnome-shell-extension-tool
|
||||||
%{_bindir}/gnome-shell-test-tool
|
%{_bindir}/gnome-shell-test-tool
|
||||||
%{_datadir}/glib-2.0/schemas/*.xml
|
%{_datadir}/glib-2.0/schemas/*.xml
|
||||||
@ -242,6 +245,7 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/org.gnome.Shell.Porta
|
|||||||
%{_datadir}/applications/org.gnome.Shell.Extensions.desktop
|
%{_datadir}/applications/org.gnome.Shell.Extensions.desktop
|
||||||
%{_datadir}/applications/org.gnome.Shell.desktop
|
%{_datadir}/applications/org.gnome.Shell.desktop
|
||||||
%{_datadir}/bash-completion/completions/gnome-extensions
|
%{_datadir}/bash-completion/completions/gnome-extensions
|
||||||
|
%{_datadir}/bash-completion/completions/gnome-screenshot-tool
|
||||||
%{_datadir}/gnome-control-center/keybindings/50-gnome-shell-launchers.xml
|
%{_datadir}/gnome-control-center/keybindings/50-gnome-shell-launchers.xml
|
||||||
%{_datadir}/gnome-control-center/keybindings/50-gnome-shell-screenshots.xml
|
%{_datadir}/gnome-control-center/keybindings/50-gnome-shell-screenshots.xml
|
||||||
%{_datadir}/gnome-control-center/keybindings/50-gnome-shell-system.xml
|
%{_datadir}/gnome-control-center/keybindings/50-gnome-shell-system.xml
|
||||||
@ -270,6 +274,7 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/org.gnome.Shell.Porta
|
|||||||
%{_libexecdir}/gnome-shell-perf-helper
|
%{_libexecdir}/gnome-shell-perf-helper
|
||||||
%{_libexecdir}/gnome-shell-hotplug-sniffer
|
%{_libexecdir}/gnome-shell-hotplug-sniffer
|
||||||
%{_mandir}/man1/gnome-extensions.1*
|
%{_mandir}/man1/gnome-extensions.1*
|
||||||
|
%{_mandir}/man1/gnome-screenshot-tool.1*
|
||||||
%{_mandir}/man1/gnome-shell.1*
|
%{_mandir}/man1/gnome-shell.1*
|
||||||
|
|
||||||
%if %{portal_helper}
|
%if %{portal_helper}
|
||||||
|
483
screenshot-tool.patch
Normal file
483
screenshot-tool.patch
Normal file
@ -0,0 +1,483 @@
|
|||||||
|
From c51ee10056e148e7eec74f3b67f3e5168373b563 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||||
|
Date: Sat, 19 Jul 2025 14:12:46 +0200
|
||||||
|
Subject: [PATCH 1/2] screenshot: Fix taking interactive screenshots via D-Bus
|
||||||
|
|
||||||
|
The D-Bus method relies on the `screenshot-taken` and `closed` signals
|
||||||
|
to differentiate successful operations from canceled/failed ones.
|
||||||
|
|
||||||
|
However as the `screenshot-taken` signal is emitted asynchronously,
|
||||||
|
it may end up being emitted after the `closed` signal even in case
|
||||||
|
of success. Await the result to ensure correct ordering.
|
||||||
|
|
||||||
|
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/8499
|
||||||
|
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3803>
|
||||||
|
---
|
||||||
|
js/ui/screenshot.js | 12 ++++++++----
|
||||||
|
1 file changed, 8 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/js/ui/screenshot.js b/js/ui/screenshot.js
|
||||||
|
index 762848c287..962459214f 100644
|
||||||
|
--- a/js/ui/screenshot.js
|
||||||
|
+++ b/js/ui/screenshot.js
|
||||||
|
@@ -1350,7 +1350,7 @@ export const ScreenshotUI = GObject.registerClass({
|
||||||
|
visible: false,
|
||||||
|
}));
|
||||||
|
this._captureButton.connect('clicked',
|
||||||
|
- this._onCaptureButtonClicked.bind(this));
|
||||||
|
+ () => this._onCaptureButtonClicked().catch(logError));
|
||||||
|
this._bottomRowContainer.add_child(this._captureButton);
|
||||||
|
|
||||||
|
this._showPointerButtonContainer = new St.BoxLayout({
|
||||||
|
@@ -1872,9 +1872,13 @@ export const ScreenshotUI = GObject.registerClass({
|
||||||
|
return [x, y, w, h];
|
||||||
|
}
|
||||||
|
|
||||||
|
- _onCaptureButtonClicked() {
|
||||||
|
+ async _onCaptureButtonClicked() {
|
||||||
|
if (this._shotButton.checked) {
|
||||||
|
- this._saveScreenshot().catch(logError);
|
||||||
|
+ try {
|
||||||
|
+ await this._saveScreenshot();
|
||||||
|
+ } catch (e) {
|
||||||
|
+ logError(e);
|
||||||
|
+ }
|
||||||
|
this.close();
|
||||||
|
} else {
|
||||||
|
// Screencast closes the UI on its own.
|
||||||
|
@@ -2139,7 +2143,7 @@ export const ScreenshotUI = GObject.registerClass({
|
||||||
|
symbol === Clutter.KEY_KP_Enter || symbol === Clutter.KEY_ISO_Enter ||
|
||||||
|
((event.get_state() & Clutter.ModifierType.CONTROL_MASK) &&
|
||||||
|
(symbol === Clutter.KEY_c || symbol === Clutter.KEY_C))) {
|
||||||
|
- this._onCaptureButtonClicked();
|
||||||
|
+ this._onCaptureButtonClicked().catch(logError);
|
||||||
|
return Clutter.EVENT_STOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.50.1
|
||||||
|
|
||||||
|
|
||||||
|
From f61170d09c728144ecf9c44b4b0a0392237fadd6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||||
|
Date: Fri, 18 Jul 2025 21:34:36 +0200
|
||||||
|
Subject: [PATCH 2/2] Add screenshot CLI tool
|
||||||
|
|
||||||
|
The tool provides the same API as gnome-screenshot, but leverages
|
||||||
|
GNOME's built-in screenshot UI instead of implementing its own
|
||||||
|
interactive dialog.
|
||||||
|
---
|
||||||
|
man/gnome-screenshot-tool.rst | 49 +++++++
|
||||||
|
man/meson.build | 23 ++-
|
||||||
|
meson.build | 2 +
|
||||||
|
src/gnome-screenshot-tool | 266 ++++++++++++++++++++++++++++++++++
|
||||||
|
src/meson.build | 26 ++++
|
||||||
|
5 files changed, 358 insertions(+), 8 deletions(-)
|
||||||
|
create mode 100644 man/gnome-screenshot-tool.rst
|
||||||
|
create mode 100755 src/gnome-screenshot-tool
|
||||||
|
|
||||||
|
diff --git a/man/gnome-screenshot-tool.rst b/man/gnome-screenshot-tool.rst
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..a471738394
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/man/gnome-screenshot-tool.rst
|
||||||
|
@@ -0,0 +1,49 @@
|
||||||
|
+=====================
|
||||||
|
+gnome-screenshot-tool
|
||||||
|
+=====================
|
||||||
|
+
|
||||||
|
+-----------------------------------------
|
||||||
|
+Screenshot CLI tool for the GNOME desktop
|
||||||
|
+-----------------------------------------
|
||||||
|
+
|
||||||
|
+:Manual section: 1
|
||||||
|
+:Manual group: User Commands
|
||||||
|
+
|
||||||
|
+SYNOPSIS
|
||||||
|
+--------
|
||||||
|
+**gnome-screenshot-tool** [*OPTION*...]
|
||||||
|
+
|
||||||
|
+DESCRIPTION
|
||||||
|
+-----------
|
||||||
|
+**gnome-screenshot-tool** is a GNOME utility for taking screenshots of
|
||||||
|
+the entire screen, a window or a user-defined area of the screen.
|
||||||
|
+
|
||||||
|
+OPTIONS
|
||||||
|
+-------
|
||||||
|
+``-w``, ``--window``
|
||||||
|
+
|
||||||
|
+ Grab the currently active window instead of the entire screen
|
||||||
|
+
|
||||||
|
+``-a``, ``--area``
|
||||||
|
+
|
||||||
|
+ Grab an area of the screen instead of the entire screen
|
||||||
|
+
|
||||||
|
+``-i``, ``--interactive``
|
||||||
|
+
|
||||||
|
+ Bring up GNOME's native screenshot dialog
|
||||||
|
+
|
||||||
|
+``-p``, ``--include-pointer``
|
||||||
|
+
|
||||||
|
+ Include the pointer with the screenshot
|
||||||
|
+
|
||||||
|
+``-d``, ``--delay``\ =\ *SECONDS*
|
||||||
|
+
|
||||||
|
+ Take the screenshot after the specified delay [in seconds]
|
||||||
|
+
|
||||||
|
+``-f``, ``--file``\ =\ *FILENAME*
|
||||||
|
+
|
||||||
|
+ Save the screenshot directly to this file
|
||||||
|
+
|
||||||
|
+``-h``, ``--help``
|
||||||
|
+
|
||||||
|
+ Show a summary of the available options
|
||||||
|
diff --git a/man/meson.build b/man/meson.build
|
||||||
|
index c61bf51513..cfb9c8e07f 100644
|
||||||
|
--- a/man/meson.build
|
||||||
|
+++ b/man/meson.build
|
||||||
|
@@ -1,8 +1,15 @@
|
||||||
|
-custom_target('man page',
|
||||||
|
- input: 'gnome-shell.rst',
|
||||||
|
- output: 'gnome-shell.1',
|
||||||
|
- command: [rst2man, '--syntax-highlight=none', '@INPUT@'],
|
||||||
|
- capture: true,
|
||||||
|
- install_dir: mandir + '/man1',
|
||||||
|
- install: true
|
||||||
|
-)
|
||||||
|
+man_pages = [
|
||||||
|
+ 'gnome-shell.rst',
|
||||||
|
+ 'gnome-screenshot-tool.rst',
|
||||||
|
+]
|
||||||
|
+
|
||||||
|
+foreach page : man_pages
|
||||||
|
+ custom_target(f'@page@ man page',
|
||||||
|
+ input: page,
|
||||||
|
+ output: '@BASENAME@.1',
|
||||||
|
+ command: [rst2man, '--syntax-highlight=none', '@INPUT@'],
|
||||||
|
+ capture: true,
|
||||||
|
+ install_dir: mandir + '/man1',
|
||||||
|
+ install: true
|
||||||
|
+ )
|
||||||
|
+endforeach
|
||||||
|
diff --git a/meson.build b/meson.build
|
||||||
|
index 6f10a366bf..14b793db6a 100644
|
||||||
|
--- a/meson.build
|
||||||
|
+++ b/meson.build
|
||||||
|
@@ -134,6 +134,8 @@ if get_option('man')
|
||||||
|
subdir('man')
|
||||||
|
endif
|
||||||
|
|
||||||
|
+bash_completion = dependency('bash-completion', required: false)
|
||||||
|
+
|
||||||
|
mutter_typelibdir = mutter_dep.get_variable('typelibdir')
|
||||||
|
python = find_program('python3')
|
||||||
|
gjs = find_program('gjs')
|
||||||
|
diff --git a/src/gnome-screenshot-tool b/src/gnome-screenshot-tool
|
||||||
|
new file mode 100755
|
||||||
|
index 0000000000..e29650abfe
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/gnome-screenshot-tool
|
||||||
|
@@ -0,0 +1,266 @@
|
||||||
|
+#!/usr/bin/env python3
|
||||||
|
+
|
||||||
|
+import argparse
|
||||||
|
+import os
|
||||||
|
+import gi
|
||||||
|
+
|
||||||
|
+gi.require_version('Gdk', '4.0')
|
||||||
|
+gi.require_version('Gtk', '4.0')
|
||||||
|
+gi.require_version('GdkPixbuf', '2.0')
|
||||||
|
+from gi.repository import GLib, Gio, GdkPixbuf, Gdk, Gtk # type: ignore
|
||||||
|
+
|
||||||
|
+try:
|
||||||
|
+ import argcomplete
|
||||||
|
+except ModuleNotFoundError:
|
||||||
|
+ pass
|
||||||
|
+
|
||||||
|
+NAME = "org.gnome.Shell.Screenshot"
|
||||||
|
+OBJECT_PATH = "/org/gnome/Shell/Screenshot"
|
||||||
|
+INTERFACE = "org.gnome.Shell.Screenshot"
|
||||||
|
+
|
||||||
|
+class Screenshot:
|
||||||
|
+ def __init__(self):
|
||||||
|
+ self._proxy = Gio.DBusProxy.new_for_bus_sync(
|
||||||
|
+ bus_type = Gio.BusType.SESSION,
|
||||||
|
+ flags = Gio.DBusProxyFlags.NONE,
|
||||||
|
+ info = None,
|
||||||
|
+ name = NAME,
|
||||||
|
+ object_path = OBJECT_PATH,
|
||||||
|
+ interface_name = INTERFACE,
|
||||||
|
+ cancellable = None,
|
||||||
|
+ )
|
||||||
|
+
|
||||||
|
+ def screenshot(self, include_cursor) -> GdkPixbuf.Pixbuf:
|
||||||
|
+ variant = self._proxy.call_sync(
|
||||||
|
+ method_name = "Screenshot",
|
||||||
|
+ parameters = GLib.Variant(
|
||||||
|
+ "(bbs)",
|
||||||
|
+ (
|
||||||
|
+ include_cursor,
|
||||||
|
+ True,
|
||||||
|
+ self._get_tmp_filename(),
|
||||||
|
+ ),
|
||||||
|
+ ),
|
||||||
|
+ flags = Gio.DBusCallFlags.NO_AUTO_START,
|
||||||
|
+ timeout_msec = -1,
|
||||||
|
+ cancellable = None,
|
||||||
|
+ )
|
||||||
|
+ return self._get_screenshot_from_result(variant)
|
||||||
|
+
|
||||||
|
+ def screenshot_window(self, include_cursor) -> GdkPixbuf.Pixbuf:
|
||||||
|
+ variant = self._proxy.call_sync(
|
||||||
|
+ method_name = "ScreenshotWindow",
|
||||||
|
+ parameters = GLib.Variant(
|
||||||
|
+ "(bbbs)",
|
||||||
|
+ (
|
||||||
|
+ True,
|
||||||
|
+ include_cursor,
|
||||||
|
+ True,
|
||||||
|
+ self._get_tmp_filename(),
|
||||||
|
+ ),
|
||||||
|
+ ),
|
||||||
|
+ flags = Gio.DBusCallFlags.NO_AUTO_START,
|
||||||
|
+ timeout_msec = -1,
|
||||||
|
+ cancellable = None,
|
||||||
|
+ )
|
||||||
|
+ return self._get_screenshot_from_result(variant)
|
||||||
|
+
|
||||||
|
+ def screenshot_area(self, x, y, width, height) -> GdkPixbuf.Pixbuf:
|
||||||
|
+ variant = self._proxy.call_sync(
|
||||||
|
+ method_name = "ScreenshotArea",
|
||||||
|
+ parameters = GLib.Variant(
|
||||||
|
+ "(iiiibs)",
|
||||||
|
+ (
|
||||||
|
+ x,
|
||||||
|
+ y,
|
||||||
|
+ width,
|
||||||
|
+ height,
|
||||||
|
+ True,
|
||||||
|
+ self._get_tmp_filename(),
|
||||||
|
+ ),
|
||||||
|
+ ),
|
||||||
|
+ flags = Gio.DBusCallFlags.NO_AUTO_START,
|
||||||
|
+ timeout_msec = -1,
|
||||||
|
+ cancellable = None,
|
||||||
|
+ )
|
||||||
|
+ return self._get_screenshot_from_result(variant)
|
||||||
|
+
|
||||||
|
+ def interactive_screenshot(self) -> GdkPixbuf.Pixbuf:
|
||||||
|
+ variant = self._proxy.call_sync(
|
||||||
|
+ method_name = "InteractiveScreenshot",
|
||||||
|
+ parameters = None,
|
||||||
|
+ flags = Gio.DBusCallFlags.NO_AUTO_START,
|
||||||
|
+ timeout_msec = GLib.MAXINT,
|
||||||
|
+ cancellable = None,
|
||||||
|
+ )
|
||||||
|
+ [success, uri] = variant
|
||||||
|
+ file = Gio.File.new_for_uri(uri)
|
||||||
|
+ return self._get_screenshot_from_result((success, file.get_path()))
|
||||||
|
+
|
||||||
|
+ def select_area(self) -> tuple[int, int, int, int]:
|
||||||
|
+ variant = self._proxy.call_sync(
|
||||||
|
+ method_name = "SelectArea",
|
||||||
|
+ parameters = None,
|
||||||
|
+ flags = Gio.DBusCallFlags.NO_AUTO_START,
|
||||||
|
+ timeout_msec = -1,
|
||||||
|
+ cancellable = None,
|
||||||
|
+ )
|
||||||
|
+ [x, y, width, height] = variant
|
||||||
|
+ return (x, y, width, height)
|
||||||
|
+
|
||||||
|
+ def _get_screenshot_from_result(self, variant):
|
||||||
|
+ [success, filename] = variant
|
||||||
|
+ assert success
|
||||||
|
+ screenshot = GdkPixbuf.Pixbuf.new_from_file(filename)
|
||||||
|
+ GLib.unlink(filename)
|
||||||
|
+ return screenshot
|
||||||
|
+
|
||||||
|
+ def _get_tmp_filename(self):
|
||||||
|
+ path = GLib.build_filenamev([
|
||||||
|
+ GLib.get_user_cache_dir(),
|
||||||
|
+ "gnome-screenshot-tool",
|
||||||
|
+ ])
|
||||||
|
+ GLib.mkdir_with_parents(path, 0o700)
|
||||||
|
+ return GLib.build_filenamev([path, f'scr-{GLib.random_int()}'])
|
||||||
|
+
|
||||||
|
+class ScreenshotApp(Gtk.Application):
|
||||||
|
+ def __init__(self, config):
|
||||||
|
+ super().__init__(application_id="org.gnome.Screenshot")
|
||||||
|
+
|
||||||
|
+ self._config = config
|
||||||
|
+
|
||||||
|
+ def do_startup(self):
|
||||||
|
+ Gtk.Application.do_startup(self)
|
||||||
|
+ self._proxy = Screenshot()
|
||||||
|
+
|
||||||
|
+ def do_activate(self):
|
||||||
|
+ self.hold()
|
||||||
|
+ if self._config.area:
|
||||||
|
+ self._selected_area = self._proxy.select_area()
|
||||||
|
+ self._start_screenshot_timeout()
|
||||||
|
+
|
||||||
|
+ def _start_screenshot_timeout(self):
|
||||||
|
+ GLib.timeout_add_seconds(self._config.delay, self._take_screenshot)
|
||||||
|
+
|
||||||
|
+ def _take_screenshot(self):
|
||||||
|
+ include_pointer = self._config.include_pointer
|
||||||
|
+
|
||||||
|
+ try:
|
||||||
|
+ if self._config.interactive:
|
||||||
|
+ screenshot = self._proxy.interactive_screenshot()
|
||||||
|
+ elif self._config.area:
|
||||||
|
+ [x, y, width, height] = self._selected_area
|
||||||
|
+ screenshot = self._proxy.screenshot_area(x, y, width, height)
|
||||||
|
+ elif self._config.window:
|
||||||
|
+ screenshot = self._proxy.screenshot_window(include_pointer)
|
||||||
|
+ else:
|
||||||
|
+ screenshot = self._proxy.screenshot(include_pointer)
|
||||||
|
+
|
||||||
|
+ # if self._config.clipboard:
|
||||||
|
+ # self._save_screenshot_to_clipboard(screenshot)
|
||||||
|
+
|
||||||
|
+ if self._config.file:
|
||||||
|
+ target_file = Gio.File.new_for_commandline_arg(self._config.file)
|
||||||
|
+ override = True
|
||||||
|
+ else:
|
||||||
|
+ target_file = self._get_default_target_file()
|
||||||
|
+ override = False
|
||||||
|
+
|
||||||
|
+ self._save_screenshot_to_file(screenshot, target_file, override)
|
||||||
|
+ except Exception as e:
|
||||||
|
+ print(f'Failed to take screenshot: {e}')
|
||||||
|
+ finally:
|
||||||
|
+ self.release()
|
||||||
|
+
|
||||||
|
+ return GLib.SOURCE_REMOVE
|
||||||
|
+
|
||||||
|
+ def _save_screenshot_to_clipboard(self, screenshot):
|
||||||
|
+ dpy = Gdk.Display.get_default()
|
||||||
|
+ clipboard = dpy.get_clipboard()
|
||||||
|
+ clipboard.set(screenshot)
|
||||||
|
+
|
||||||
|
+ def _save_screenshot_to_file(self, screenshot, file, override):
|
||||||
|
+ if override:
|
||||||
|
+ ostream = file.replace(None, False, Gio.FileCreateFlags.NONE, None)
|
||||||
|
+ else:
|
||||||
|
+ ostream = file.create(Gio.FileCreateFlags.NONE, None)
|
||||||
|
+
|
||||||
|
+ [_, ext] = os.path.splitext(file.get_basename())
|
||||||
|
+ if not ext:
|
||||||
|
+ ext = 'png'
|
||||||
|
+ else:
|
||||||
|
+ ext = ext[1:]
|
||||||
|
+
|
||||||
|
+ def find_writable_format(formats, ext):
|
||||||
|
+ for f in formats:
|
||||||
|
+ for e in f.get_extensions():
|
||||||
|
+ if e == ext and f.is_writable():
|
||||||
|
+ return f.get_name()
|
||||||
|
+ return None
|
||||||
|
+
|
||||||
|
+ formats = GdkPixbuf.Pixbuf.get_formats()
|
||||||
|
+ format = find_writable_format(formats, ext)
|
||||||
|
+
|
||||||
|
+ if format == 'png':
|
||||||
|
+ keys = ["tEXt::Software"]
|
||||||
|
+ values = ["gnome-screenshot-tool"]
|
||||||
|
+ else:
|
||||||
|
+ keys = None
|
||||||
|
+ values = None
|
||||||
|
+
|
||||||
|
+ screenshot.save_to_streamv(ostream, format, keys, values, None)
|
||||||
|
+
|
||||||
|
+ def _get_default_target_file(self):
|
||||||
|
+ path = GLib.build_filenamev([
|
||||||
|
+ GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_PICTURES) or GLib.get_home_dir(),
|
||||||
|
+ "Screenshots",
|
||||||
|
+ ])
|
||||||
|
+ dir = Gio.File.new_for_path(path)
|
||||||
|
+ try:
|
||||||
|
+ dir.make_directory_with_parents(None)
|
||||||
|
+ except GLib.Error as e:
|
||||||
|
+ if not e.matches(Gio.io_error_quark(), Gio.IOErrorEnum.EXISTS):
|
||||||
|
+ raise e
|
||||||
|
+
|
||||||
|
+ timestamp = GLib.DateTime.new_now_local().format('%Y-%m-%d %H-%M-%S')
|
||||||
|
+ name = "Screenshot From %s" % (timestamp)
|
||||||
|
+
|
||||||
|
+ def suffixes() -> str:
|
||||||
|
+ yield ''
|
||||||
|
+
|
||||||
|
+ i = 1
|
||||||
|
+ while True:
|
||||||
|
+ yield f'-{i}'
|
||||||
|
+ i = i + 1
|
||||||
|
+
|
||||||
|
+ for suffix in suffixes():
|
||||||
|
+ file = dir.get_child(f'{name}{suffix}.png')
|
||||||
|
+ if not file.query_exists(None):
|
||||||
|
+ return file
|
||||||
|
+
|
||||||
|
+def main():
|
||||||
|
+ parser = argparse.ArgumentParser()
|
||||||
|
+
|
||||||
|
+ group = parser.add_mutually_exclusive_group()
|
||||||
|
+ group.add_argument("-w", "--window", action="store_true", help="Grab a window instead of the entire screen")
|
||||||
|
+ group.add_argument("-a", "--area", action="store_true", help="Grab an area of the screen instead of the entire screen")
|
||||||
|
+ group.add_argument("-i", "--interactive", action="store_true", help="Interactively set options")
|
||||||
|
+
|
||||||
|
+ # parser.add_argument("-c", "--clipboard", action="store_true", help="Send the grab directly to the clipboard")
|
||||||
|
+ parser.add_argument("-p", "--include-pointer", action="store_true", help="Include the pointer with the screenshot")
|
||||||
|
+ parser.add_argument("-d", "--delay", type=int, default=0, help="Take a screenshot after the specified delay (in seconds)")
|
||||||
|
+ parser.add_argument("-f", "--file", type=str, help="Save screenshot directly to this file")
|
||||||
|
+
|
||||||
|
+ if argcomplete:
|
||||||
|
+ argcomplete.autocomplete(parser)
|
||||||
|
+ args = parser.parse_args()
|
||||||
|
+
|
||||||
|
+ if args.interactive:
|
||||||
|
+ if args.include_pointer:
|
||||||
|
+ print("Option --include-pointer is ignored in interactive mode.")
|
||||||
|
+
|
||||||
|
+ app = ScreenshotApp(args)
|
||||||
|
+ app.run(None)
|
||||||
|
+
|
||||||
|
+if __name__ == "__main__":
|
||||||
|
+ main()
|
||||||
|
diff --git a/src/meson.build b/src/meson.build
|
||||||
|
index 23d23b4f38..4ccdd3b055 100644
|
||||||
|
--- a/src/meson.build
|
||||||
|
+++ b/src/meson.build
|
||||||
|
@@ -310,3 +310,29 @@ run_test = executable('run-js-test', 'run-js-test.c',
|
||||||
|
include_directories: [conf_inc],
|
||||||
|
build_rpath: mutter_typelibdir,
|
||||||
|
)
|
||||||
|
+
|
||||||
|
+install_data(
|
||||||
|
+ 'gnome-screenshot-tool',
|
||||||
|
+ install_dir: bindir
|
||||||
|
+)
|
||||||
|
+
|
||||||
|
+if bash_completion.found()
|
||||||
|
+ bash_completion_dir = bash_completion.get_variable(
|
||||||
|
+ pkgconfig: 'completionsdir',
|
||||||
|
+ pkgconfig_define: ['datadir', datadir],
|
||||||
|
+ )
|
||||||
|
+
|
||||||
|
+ register_python_argcomplete = find_program('register-python-argcomplete')
|
||||||
|
+
|
||||||
|
+ custom_target(
|
||||||
|
+ 'screenshot-tool-bash-completion',
|
||||||
|
+ output: 'gnome-screenshot-tool',
|
||||||
|
+ command: [
|
||||||
|
+ register_python_argcomplete,
|
||||||
|
+ 'gnome-screenshot-tool',
|
||||||
|
+ ],
|
||||||
|
+ capture: true,
|
||||||
|
+ install_dir: bash_completion_dir,
|
||||||
|
+ install: true,
|
||||||
|
+ )
|
||||||
|
+endif
|
||||||
|
--
|
||||||
|
2.50.1
|
||||||
|
|
Loading…
Reference in New Issue
Block a user