vdi-cloud/docs/evidence/ubuntu-drag-20261105/motion-inject.py

48 lines
1.9 KiB
Python

"""Separate injection timing from decoded-video sampling; run in test window only."""
import ctypes as C
import json
import os
import subprocess
import time
x = C.CDLL('libX11.so.6')
t = C.CDLL('libXtst.so.6')
x.XOpenDisplay.restype = C.c_void_p
x.XSync.argtypes = [C.c_void_p, C.c_int]
t.XTestFakeMotionEvent.argtypes = [C.c_void_p,C.c_int,C.c_int,C.c_int,C.c_ulong]
t.XTestFakeButtonEvent.argtypes = [C.c_void_p,C.c_uint,C.c_int,C.c_ulong]
d=x.XOpenDisplay(None)
assert d
x.XGetInputFocus.argtypes=[C.c_void_p,C.POINTER(C.c_ulong),C.POINTER(C.c_int)]
x.XFetchName.argtypes=[C.c_void_p,C.c_ulong,C.POINTER(C.c_char_p)]
wid=C.c_ulong();revert=C.c_int();name=C.c_char_p()
x.XGetInputFocus(d,C.byref(wid),C.byref(revert))
x.XQueryTree.argtypes=[C.c_void_p,C.c_ulong,C.POINTER(C.c_ulong),C.POINTER(C.c_ulong),C.POINTER(C.c_void_p),C.POINTER(C.c_uint)]
title=''
for _ in range(8):
x.XFetchName(d,wid.value,C.byref(name))
title=name.value.decode() if name.value else ''
if title: break
root=C.c_ulong();parent=C.c_ulong();children=C.c_void_p();count=C.c_uint()
if not x.XQueryTree(d,wid.value,C.byref(root),C.byref(parent),C.byref(children),C.byref(count)): break
if not parent.value or parent.value==wid.value:break
wid.value=parent.value
assert title in ('Ubuntu drag rendering probe','VDI-Ubuntu - Moonlight'), title
t.XTestFakeMotionEvent(d,-1,800,700,0);x.XSync(d,0)
time.sleep(.5)
sent=[]
try:
t.XTestFakeButtonEvent(d,1,1,0);x.XSync(d,0)
time.sleep(.8)
start=time.monotonic()
for seq in range(1,301):
time.sleep(max(0,start+(seq-1)/60-time.monotonic()))
begin=time.monotonic()
t.XTestFakeMotionEvent(d,-1,800+4*seq,700+seq,0)
x.XSync(d,0)
sent.append(dict(seq=seq,t=time.monotonic(),sync_ms=(time.monotonic()-begin)*1000))
time.sleep(1)
finally:
t.XTestFakeButtonEvent(d,1,0,0);x.XSync(d,0)
print(json.dumps(dict(title=title,events=sent)))