Observe QEMU swipe presses (#546)

This commit is contained in:
Noah
2026-09-11 10:31:09 -06:00
parent 7e0089826b
commit 55660b7c01
2 changed files with 103 additions and 14 deletions
+51 -14
View File
@@ -239,6 +239,16 @@ def do_observed_tap(ctx, ax, ay):
return observed
def _move_swipe(s, f, ax1, ay1, ax2, ay2, ms, steps):
for i in range(1, steps + 1):
t = i / steps
send_events(s, f, [
abs_ev("x", int(ax1 + (ax2 - ax1) * t)),
abs_ev("y", int(ay1 + (ay2 - ay1) * t)),
])
time.sleep(ms / 1000.0 / steps)
def do_swipe(s, f, x1, y1, x2, y2, size, ms=400, steps=None):
"""Drag with interpolated motion.
@@ -254,15 +264,41 @@ def do_swipe(s, f, x1, y1, x2, y2, size, ms=400, steps=None):
if steps is None:
steps = max(6, int(ms / 25))
send_events(s, f, [abs_ev("x", ax1), abs_ev("y", ay1), btn_ev(True)])
time.sleep(0.05)
for i in range(1, steps + 1):
t = i / steps
send_events(s, f, [
abs_ev("x", int(ax1 + (ax2 - ax1) * t)),
abs_ev("y", int(ay1 + (ay2 - ay1) * t)),
])
time.sleep(ms / 1000.0 / steps)
send_events(s, f, [btn_ev(False)])
try:
time.sleep(0.05)
_move_swipe(s, f, ax1, ay1, ax2, ay2, ms, steps)
finally:
send_events(s, f, [btn_ev(False)])
def do_observed_swipe(ctx, x1, y1, x2, y2, ms=400, steps=None):
"""Start a drag only after the guest has consumed its press."""
ax1, ay1 = to_axis(x1, ctx.size), to_axis(y1, ctx.size)
ax2, ay2 = to_axis(x2, ctx.size), to_axis(y2, ctx.size)
if steps is None:
steps = max(6, int(ms / 25))
before = parse_stats(ctx.ctl.send("stats")).get("presses")
send_events(ctx.s, ctx.f, [abs_ev("x", ax1), abs_ev("y", ay1), btn_ev(True)])
observed = before is None
try:
if observed:
time.sleep(0.05)
else:
deadline = time.monotonic() + TAP_OBSERVE_TIMEOUT_S
while time.monotonic() < deadline:
now = parse_stats(ctx.ctl.send("stats")).get("presses")
if now is not None and now != before:
observed = True
break
time.sleep(0.02)
if not observed:
return False
_move_swipe(ctx.s, ctx.f, ax1, ay1, ax2, ay2, ms, steps)
return True
finally:
send_events(ctx.s, ctx.f, [btn_ev(False)])
class Ctl:
@@ -724,14 +760,15 @@ def verb_tap(ctx, lineno, cmd, args, line):
def verb_swipe(ctx, lineno, cmd, args, line):
ms = int(args[4]) if len(args) > 4 else 400
do_swipe(ctx.s, ctx.f, int(args[0]), int(args[1]), int(args[2]), int(args[3]), ctx.size, ms)
return "ok", ""
observed = do_observed_swipe(
ctx, int(args[0]), int(args[1]), int(args[2]), int(args[3]), ms)
return ("ok", "") if observed else ("fail", "press was not consumed within 2 seconds")
def verb_fling(ctx, lineno, cmd, args, line):
do_swipe(ctx.s, ctx.f, int(args[0]), int(args[1]), int(args[2]), int(args[3]),
ctx.size, ms=120)
return "ok", ""
observed = do_observed_swipe(
ctx, int(args[0]), int(args[1]), int(args[2]), int(args[3]), ms=120)
return ("ok", "") if observed else ("fail", "press was not consumed within 2 seconds")
def verb_sleep(ctx, lineno, cmd, args, line):