| Server IP : 85.112.90.236 / Your IP : 192.168.1.26 Web Server : Apache System : Linux 85-112-90-236.cprapid.com 6.12.0-211.7.3.el10_2.x86_64 #1 SMP PREEMPT_DYNAMIC Tue May 19 12:46:58 EDT 2026 x86_64 User : ftechme ( 1002) PHP Version : 8.2.32 Disable Function : exec,passthru,shell_exec,system MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /bin/ |
Upload File : |
#!/usr/bin/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()