AnyBot/deploy/linux/dev/gnome/op.py

65 lines
4.8 KiB
Python
Raw Normal View History

# The test's stand-in for the person: screenshots through the portal, clicks and keys through
# Mutter's own remote desktop interface. op.py shot out.png | click x y | key keysym
import sys, time, shutil, urllib.parse
from gi.repository import Gio, GLib
bus = Gio.bus_get_sync(Gio.BusType.SESSION)
def call(dest, path, iface, method, args=None, sig=None):
return bus.call_sync(dest, path, iface, method, args, None, 0, -1, None)
def shot(out):
token = 'op%d' % int(time.time() * 1000)
sender = bus.get_unique_name()[1:].replace('.', '_')
req = '/org/freedesktop/portal/desktop/request/%s/%s' % (sender, token)
loop = GLib.MainLoop(); res = {}
def on(conn, snd, path, iface, sig, params, *a):
res['r'] = params.unpack(); loop.quit()
bus.signal_subscribe(None, 'org.freedesktop.portal.Request', 'Response', req, None, 0, on)
call('org.freedesktop.portal.Desktop', '/org/freedesktop/portal/desktop', 'org.freedesktop.portal.Screenshot', 'Screenshot',
GLib.Variant('(sa{sv})', ('', {'handle_token': GLib.Variant('s', token), 'interactive': GLib.Variant('b', False)})))
GLib.timeout_add_seconds(10, loop.quit); loop.run()
uri = res['r'][1]['uri']
shutil.move(urllib.parse.unquote(uri[7:]), out)
def session():
path = call('org.gnome.Mutter.RemoteDesktop', '/org/gnome/Mutter/RemoteDesktop', 'org.gnome.Mutter.RemoteDesktop', 'CreateSession').unpack()[0]
call('org.gnome.Mutter.RemoteDesktop', path, 'org.gnome.Mutter.RemoteDesktop.Session', 'Start')
return lambda m, a: call('org.gnome.Mutter.RemoteDesktop', path, 'org.gnome.Mutter.RemoteDesktop.Session', m, a)
def eye(out):
# Mutter's own screen cast (the operator's view, no portal), one frame through GStreamer.
import subprocess
sp = call('org.gnome.Mutter.ScreenCast', '/org/gnome/Mutter/ScreenCast', 'org.gnome.Mutter.ScreenCast', 'CreateSession', GLib.Variant('(a{sv})', ({},))).unpack()[0]
st = call('org.gnome.Mutter.ScreenCast', sp, 'org.gnome.Mutter.ScreenCast.Session', 'RecordMonitor', GLib.Variant('(sa{sv})', ('Meta-0', {}))).unpack()[0]
loop = GLib.MainLoop(); res = {}
def on(conn, snd, path, iface, sig, params, *a):
res['node'] = params.unpack()[0]; loop.quit()
bus.signal_subscribe(None, 'org.gnome.Mutter.ScreenCast.Stream', 'PipeWireStreamAdded', st, None, 0, on)
call('org.gnome.Mutter.ScreenCast', sp, 'org.gnome.Mutter.ScreenCast.Session', 'Start')
GLib.timeout_add_seconds(5, loop.quit); loop.run()
subprocess.run(['gst-launch-1.0', '-q', 'pipewiresrc', 'path=%d' % res['node'], 'num-buffers=3', '!', 'videoconvert', '!', 'pngenc', 'snapshot=true', '!', 'filesink', 'location=' + out], timeout=20)
call('org.gnome.Mutter.ScreenCast', sp, 'org.gnome.Mutter.ScreenCast.Session', 'Stop')
cmd = sys.argv[1]
if cmd == 'eye':
eye(sys.argv[2])
if cmd == 'shot':
shot(sys.argv[2])
elif cmd == 'click':
# Absolute moves need a screen cast stream tied to the remote desktop session.
rdp = call('org.gnome.Mutter.RemoteDesktop', '/org/gnome/Mutter/RemoteDesktop', 'org.gnome.Mutter.RemoteDesktop', 'CreateSession').unpack()[0]
sid = call('org.gnome.Mutter.RemoteDesktop', rdp, 'org.freedesktop.DBus.Properties', 'Get', GLib.Variant('(ss)', ('org.gnome.Mutter.RemoteDesktop.Session', 'SessionId'))).unpack()[0]
sp = call('org.gnome.Mutter.ScreenCast', '/org/gnome/Mutter/ScreenCast', 'org.gnome.Mutter.ScreenCast', 'CreateSession', GLib.Variant('(a{sv})', ({'remote-desktop-session-id': GLib.Variant('s', sid)},))).unpack()[0]
st = call('org.gnome.Mutter.ScreenCast', sp, 'org.gnome.Mutter.ScreenCast.Session', 'RecordMonitor', GLib.Variant('(sa{sv})', ('Meta-0', {}))).unpack()[0]
loop = GLib.MainLoop()
bus.signal_subscribe(None, 'org.gnome.Mutter.ScreenCast.Stream', 'PipeWireStreamAdded', st, None, 0, lambda *a: loop.quit())
call('org.gnome.Mutter.RemoteDesktop', rdp, 'org.gnome.Mutter.RemoteDesktop.Session', 'Start')
GLib.timeout_add_seconds(5, loop.quit); loop.run()
import subprocess
gst = subprocess.Popen(['gst-launch-1.0', '-q', 'pipewiresrc', 'path=%d' % 0, '!', 'fakesink'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
s = lambda m, a: call('org.gnome.Mutter.RemoteDesktop', rdp, 'org.gnome.Mutter.RemoteDesktop.Session', m, a)
time.sleep(0.5)
s('NotifyPointerMotionAbsolute', GLib.Variant('(sdd)', (st, float(sys.argv[2]), float(sys.argv[3])))); time.sleep(0.2)
s('NotifyPointerButton', GLib.Variant('(ib)', (0x110, True))); time.sleep(0.05)
s('NotifyPointerButton', GLib.Variant('(ib)', (0x110, False))); time.sleep(0.3)
elif cmd == 'key':
s = session(); time.sleep(0.3)
for k in sys.argv[2:]:
s('NotifyKeyboardKeysym', GLib.Variant('(ub)', (int(k, 16), True))); time.sleep(0.05)
s('NotifyKeyboardKeysym', GLib.Variant('(ub)', (int(k, 16), False))); time.sleep(0.1)