From 987d98751235abeec64f2f26ccc173e20df9a26b Mon Sep 17 00:00:00 2001 From: pax Date: Tue, 7 Apr 2026 23:03:09 -0500 Subject: [PATCH] Popout polish: thumbnail download bar when preview hidden, no overlay reshow on nav MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two fixes that surfaced from daily use after the v0.2.2 popout polish round 1. 1. Show download progress on the active thumbnail when the embedded preview is hidden (gui/app.py) After the previous fix to suppress the dl_progress widget when the popout is open, the user lost all visible feedback about the active download in the main app. The grid had no indicator, the dl_progress widget was hidden, and the only signal was the status bar text "Loading #X..." at the bottom edge. `_on_post_activated` now decides per call whether to use the dl_progress widget at the bottom of the right splitter or fall back to drawing the download progress on the active thumbnail in the main grid via the existing prefetch-progress paint path. The decision is captured at function entry as `preview_hidden = not (self._preview.isVisible() and self._preview.width() > 0)` and closed over by the `_progress` callback and the `_load` coroutine, so the indicator that starts on a download stays on the same target even if the user opens or closes the popout mid-download. The thumbnail bar uses the same paint path as prefetch indicators (`set_prefetch_progress(0.0..1.0)` for fill, `set_prefetch_progress(-1)` for clear), so the visual is identical and no new widget code was added. `_load`'s finally block emits the clear when `preview_hidden` was true at start. Generalizes to any reason the preview is hidden, not just the popout-open case: a user who has dragged the main splitter to collapse the preview also gets the thumbnail indicator now, even with the popout closed. 2. Stop auto-showing the popout overlay on every navigation (gui/preview.py) `FullscreenPreview.set_media` ended with an unconditional `self._show_overlay()` call, which meant the floating toolbar and video controls bar popped back into view on every left/ right/hjkl navigation between posts. Visually noisy and not what the user wants once they've started navigating — the overlay is supposed to be a hover-triggered surface, not a per-post popup. Removed the call. The overlay is still shown by: - `__init__` default state (`_ui_visible = True`), so the user sees it for ~2 seconds on first popout open and the auto-hide timer hides it after that - `eventFilter` mouse-move-into-top/bottom-edge zone (the intended hover trigger, unchanged) - Volume scroll on video stack (unchanged) - Ctrl+H toggle (unchanged) After this, the only way the overlay appears mid-session is hover or Ctrl+H. Navigation through posts no longer flashes it back into view. --- booru_viewer/gui/app.py | 32 ++++++++++++++++++++++++-------- booru_viewer/gui/preview.py | 8 +++++++- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/booru_viewer/gui/app.py b/booru_viewer/gui/app.py index f160b38..d034d84 100644 --- a/booru_viewer/gui/app.py +++ b/booru_viewer/gui/app.py @@ -1275,19 +1275,31 @@ class BooruApp(QMainWindow): ) self._preview.update_save_state(self._is_post_saved(post.id)) self._status.showMessage(f"Loading #{post.id}...") - # Skip the dl_progress widget when the popout is open. The user - # is looking at the popout, not the embedded preview area, and - # the right splitter is set to [0, 0, 1000] so the show/hide - # pulse on the dl_progress section forces a layout pass that - # briefly compresses the main grid (visible flash on every - # click, even on the same post since download_image still runs - # against the cache and the show/hide cycle still fires). - if not (self._fullscreen_window and self._fullscreen_window.isVisible()): + # Decide where the user can actually see download progress. + # If the embedded preview is visible (normal layout), use the + # dl_progress widget at the bottom of the right splitter. If + # the preview is hidden — popout open, splitter collapsed, + # whatever — fall back to drawing the progress bar directly + # on the active thumbnail in the main grid via the existing + # prefetch-progress paint path. This avoids the dl_progress + # show/hide flash on the right splitter (the previous fix) + # and gives the user some visible feedback even when the + # preview area can't show the bar. + preview_hidden = not ( + self._preview.isVisible() and self._preview.width() > 0 + ) + if preview_hidden: + self._signals.prefetch_progress.emit(index, 0.0) + else: self._dl_progress.show() self._dl_progress.setRange(0, 0) def _progress(downloaded, total): self._signals.download_progress.emit(downloaded, total) + if preview_hidden and total > 0: + self._signals.prefetch_progress.emit( + index, downloaded / total + ) async def _load(): self._prefetch_pause.clear() # pause prefetch @@ -1301,6 +1313,10 @@ class BooruApp(QMainWindow): self._signals.image_error.emit(str(e)) finally: self._prefetch_pause.set() # resume prefetch + if preview_hidden: + # Clear the thumbnail progress bar that was + # standing in for the dl_progress widget. + self._signals.prefetch_progress.emit(index, -1) self._run_async(_load) diff --git a/booru_viewer/gui/preview.py b/booru_viewer/gui/preview.py index e0a9f44..00bc2c8 100644 --- a/booru_viewer/gui/preview.py +++ b/booru_viewer/gui/preview.py @@ -386,7 +386,13 @@ class FullscreenPreview(QMainWindow): pix = self._viewer._pixmap if pix and not pix.isNull(): self._fit_to_content(pix.width(), pix.height()) - self._show_overlay() + # Note: do NOT auto-show the overlay on every set_media. The + # overlay should appear in response to user hover (handled in + # eventFilter on mouse-move into the top/bottom edge zones), + # not pop back up after every navigation. First popout open + # already starts with _ui_visible = True and the auto-hide + # timer running, so the user sees the controls for ~2s on + # first open and then they stay hidden until hover. def _on_video_size(self, w: int, h: int) -> None: if not self.isFullScreen() and w > 0 and h > 0: