This commit is contained in:
2026-09-11 14:20:57 -04:00
parent 275a44975f
commit 78cb03e6cb
22 changed files with 248 additions and 25 deletions
+36
View File
@@ -0,0 +1,36 @@
#!/usr/bin/env python3
import json
import sys
from gi.repository import Atspi
mode, limit = sys.argv[1], int(sys.argv[2])
Atspi.init()
desktop = Atspi.get_desktop(0)
nodes = []
def walk(node, depth=0):
if len(nodes) >= limit or node is None or depth > 30:
return
try:
role = node.get_role_name() or ''
name = node.get_name() or ''
component = node.get_component()
rect = component.get_extents(Atspi.CoordType.SCREEN) if component else None
if role and (name or rect):
nodes.append({'role': role, 'name': name, 'rect': [rect.x, rect.y, rect.width, rect.height] if rect else None, 'state': [str(s) for s in node.get_state_set().get_states()]})
for i in range(node.get_child_count()):
walk(node.get_child_at_index(i), depth + 1)
except Exception:
return
if mode == 'focused':
for i in range(desktop.get_child_count()):
app = desktop.get_child_at_index(i)
try:
for j in range(app.get_child_count()):
window = app.get_child_at_index(j)
if window.get_state_set().contains(Atspi.StateType.ACTIVE):
walk(window)
except Exception:
continue
else:
walk(desktop)
print(json.dumps(nodes, ensure_ascii=False))
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/env python3
import sys
from PIL import Image
source, target, cap, quality = sys.argv[1], sys.argv[2], int(sys.argv[3]), int(sys.argv[4])
with Image.open(source) as image:
image = image.convert('RGB')
if len(sys.argv) == 9:
x, y, width, height = [int(v) for v in sys.argv[5:9]]
image = image.crop((x, y, x + width, y + height))
scale = min(1.0, cap / max(image.width, image.height))
if scale < 1.0:
image = image.resize((round(image.width * scale), round(image.height * scale)), Image.Resampling.LANCZOS)
image.save(target, 'WEBP', quality=quality, method=4)
+27
View File
@@ -0,0 +1,27 @@
#!/usr/bin/env python3
"""Capture one frame through the GNOME Screenshot portal and print its path."""
import sys
from gi.repository import Gio, GLib
target = sys.argv[1]
bus = Gio.bus_get_sync(Gio.BusType.SESSION, None)
proxy = Gio.DBusProxy.new_sync(bus, Gio.DBusProxyFlags.NONE, None, 'org.freedesktop.portal.Desktop', '/org/freedesktop/portal/desktop', 'org.freedesktop.portal.Screenshot', None)
request = proxy.call_sync('Screenshot', GLib.Variant('(a{sv})', ({'interactive': GLib.Variant('b', False)},)), Gio.DBusCallFlags.NONE, -1, None).unpack()[0]
loop = GLib.MainLoop()
result = {'uri': None, 'code': 1}
def response(_conn, _sender, _path, _interface, _member, params):
code, values = params.unpack()
if code == 0:
result['uri'] = values.get('uri')
result['code'] = 0
loop.quit()
subscription = bus.signal_subscribe(None, 'org.freedesktop.portal.Request', 'Response', request, None, Gio.DBusSignalFlags.NONE, response)
loop.run()
bus.signal_unsubscribe(subscription)
if not result['uri']:
raise SystemExit('Screenshot portal returned no image URI')
ok, contents, _etag = Gio.File.new_for_uri(result['uri']).load_contents(None)
if not ok:
raise SystemExit('could not read screenshot portal URI')
Gio.File.new_for_path(target).replace_contents(contents, None, False, Gio.FileCreateFlags.REPLACE_DESTINATION, None)
print(target)