"""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)))