From 8c5c2e37d3ec59aa9592cb1f289c2f5809b3743c Mon Sep 17 00:00:00 2001 From: pax Date: Thu, 9 Apr 2026 20:51:59 -0500 Subject: [PATCH] popout/window: reorder stack switch, drop stop, fix close position MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit behavior change: _apply_load_video now switches the stack to the video surface BEFORE calling play_file so mpv's first frame lands on a visible widget instead of a cleared image viewer. Removes the redundant stop() call — loadfile("replace") atomically replaces the current file. Also fixes video position not surviving popout close: StopMedia (part of CloseRequested effects) destroyed mpv's time_pos before get_video_state could read it. Now closeEvent snapshots position_ms before dispatching CloseRequested, and get_video_state returns the snapshot. --- booru_viewer/gui/popout/window.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/booru_viewer/gui/popout/window.py b/booru_viewer/gui/popout/window.py index 98de449..da61077 100644 --- a/booru_viewer/gui/popout/window.py +++ b/booru_viewer/gui/popout/window.py @@ -592,15 +592,15 @@ class FullscreenPreview(QMainWindow): def _apply_load_video(self, e: LoadVideo) -> None: """Apply LoadVideo effect — hand the path or URL to mpv. - Mirrors the legacy `set_media` body's video branch. play_file - already handles the http(s) → referer detection internally - (see media/video_player.py:343-347), so the adapter doesn't - need to thread the referer through. + Stack switch happens FIRST so the video surface is visible + the moment mpv produces its first frame. clear() releases the + previous image (now hidden behind the video surface). No + explicit stop() — loadfile("replace") atomically replaces the + current file without the eof side-effect of command('stop'). """ - self._viewer.clear() - self._video.stop() - self._video.play_file(e.path, e.info) self._stack.setCurrentIndex(1) + self._viewer.clear() + self._video.play_file(e.path, e.info) def _apply_stop_media(self) -> None: """Apply StopMedia effect — clear both surfaces. @@ -719,7 +719,7 @@ class FullscreenPreview(QMainWindow): "mute": self._video.is_muted, "autoplay": self._video.autoplay, "loop_state": self._video.loop_state, - "position_ms": ( + "position_ms": getattr(self, "_close_position_ms", None) or ( self._video.get_position_ms() if self.is_video_active() else 0 @@ -1558,6 +1558,14 @@ class FullscreenPreview(QMainWindow): else: FullscreenPreview._saved_geometry = self.frameGeometry() QApplication.instance().removeEventFilter(self) + # Snapshot video position BEFORE StopMedia destroys it. + # _on_fullscreen_closed reads this via get_video_state() to + # seek the embedded preview to the same position. + self._close_position_ms = ( + self._video.get_position_ms() + if self.is_video_active() + else 0 + ) # NOW dispatch + apply CloseRequested. Effects are # [StopMedia, EmitClosed]. StopMedia clears the media stack; # EmitClosed emits self.closed which triggers main_window's