Arrow-key skip preserves play/pause state instead of always pausing

_seek_relative() was unconditionally calling player.pause() before
seeking. mpv's seek command doesn't itself change pause state, so
simply not forcing it is enough: paused stays paused, playing keeps
playing through the skip. (Frame-step still always pauses, correctly
-- that's for precisely inspecting a single frame, a different
use case from a coarse 5s nudge.)

Verified by calling _seek_relative() directly rather than simulating
the QShortcut keypress: a debug script isolated that PlayerWidget.seek()
itself works fine while playing, and QTest.keyClick against this
shortcut turned out to be unreliable in this headless setup even with
Qt's active-window state forced -- consistent with the flakiness
already noted in smoke_test_arrow_seek.py. The real key binding itself
was already confirmed with live xdotool keypresses in an earlier
session; this only needed to test the new state-preservation logic.
This commit is contained in:
ThePendulum
2026-07-26 02:44:37 +02:00
parent 105dd5be88
commit 6f76b3f15a
2 changed files with 80 additions and 2 deletions
+75
View File
@@ -0,0 +1,75 @@
"""Verifies arrow-key skips preserve whichever play/pause state the user
was already in, instead of always forcing a pause.
Calls the real MainWindow._seek_relative() method directly rather than
simulating the QShortcut keypress: QTest.keyClick against this shortcut was
observed to be unreliable in this headless setup even with Qt's
active-window state forced (see smoke_test_arrow_seek.py's note) --
sometimes the simulated key silently doesn't reach the shortcut at all, and
a debug script isolated that PlayerWidget.seek() itself works correctly
while playing, so the flakiness is in the synthetic-keypress dispatch, not
the app. The QShortcut -> _seek_relative wiring itself (a single line) was
already independently confirmed with real xdotool keypresses against a
live window in an earlier session.
"""
import sys
import time
from pathlib import Path
from PyQt6.QtWidgets import QApplication
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
import main as app_main
ROOT = Path(__file__).resolve().parent.parent
CLIP = str(ROOT / "test_media" / "sync_test_INSYNC.mp4")
def main():
qapp = QApplication(sys.argv)
win = app_main.MainWindow()
win.show()
qapp.processEvents()
win._load(CLIP)
qapp.processEvents()
time.sleep(0.2)
qapp.processEvents()
# -- Case 1: paused before the skip -> stays paused after
assert win.player.mpv.pause is True
before_pos = win.player.get_position()
win._seek_relative(5.0)
qapp.processEvents()
time.sleep(0.2)
qapp.processEvents()
after_pos = win.player.get_position()
print(f"paused case: before={before_pos:.3f}s after={after_pos:.3f}s")
assert win.player.mpv.pause is True, "should still be paused after skip"
assert win.play_button.text() == "Play"
assert after_pos > before_pos + 4.0, "should have actually skipped forward"
print("PASS: stays paused across arrow-key skip when it started paused")
# -- Case 2: playing before the skip -> stays playing after
win.player.seek(0.0)
win.player.play()
win.play_button.setText("Pause")
qapp.processEvents()
time.sleep(0.2)
before_pos = win.player.get_position()
win._seek_relative(5.0)
qapp.processEvents()
time.sleep(0.2)
qapp.processEvents()
assert win.player.mpv.pause is False, "should still be playing after skip"
assert win.play_button.text() == "Pause"
after_pos = win.player.get_position()
print(f"playing case: before={before_pos:.3f}s after={after_pos:.3f}s (should have jumped ~5s and kept playing)")
assert after_pos > before_pos + 4.0, "should have actually skipped forward"
win.player.shutdown()
print("\nPRESERVE PLAY STATE SMOKE TEST PASSED")
if __name__ == "__main__":
main()