feat: playlist UI improvements, smooth transitions, and freezing fixes#253
Open
rhafaelcm wants to merge 17 commits intojeffshee:masterfrom
Open
feat: playlist UI improvements, smooth transitions, and freezing fixes#253rhafaelcm wants to merge 17 commits intojeffshee:masterfrom
rhafaelcm wants to merge 17 commits intojeffshee:masterfrom
Conversation
Allows users to create a video playlist that rotates across all monitors. Each video plays to completion N times (configurable repeat count) before advancing to the next video in a circular loop. Uses VLC's MediaPlayerEndReached event for precise end-of-video detection. Made-with: Cursor
- Fix _checkDefaultSource crashing with None path for non-video modes - Add "Add to Playlist" option to right-click context menu in Local Video tab - Remove separate Add button from Playlist tab, update description - Add PKG_CONFIG_PATH and runtime env vars for lib64 in Flatpak manifest Made-with: Cursor
Add LIBVA_DRIVERS_PATH with Intel, Mesa, and Mesa default driver paths so libva can auto-detect the correct VA-API driver for any GPU. Made-with: Cursor
… button - Add fade-out/fade-in opacity transition between playlist videos - Show thumbnails and video duration in the Playlist tab (TreeView) - Display video duration below each thumbnail in Local Video tab - Add "Add All to Playlist" button in Local Video tab - Add get_video_duration() and get_thumbnail_pixbuf() utility functions - Fix thumbnail loading bug when generate_thumbnail returns True but path is None Made-with: Cursor
- Static wallpaper only set once (first video) instead of every transition, and now runs in a background thread to avoid blocking the GTK main loop - Add _is_transitioning flag to prevent race conditions from overlapping fade animations when MediaPlayerEndReached fires multiple times - Move get_video_duration calls to background threads in playlist store to avoid blocking UI with synchronous ffprobe calls - Use GLib.idle_add for thread-safe ListStore updates in IconView Made-with: Cursor
Wrap generate_thumbnail and get_thumbnail in try/except to catch GLib.GError when the external thumbnailer (totem-video-thumbnailer) fails for unsupported or corrupted videos, preventing thread crashes. Made-with: Cursor
- Add "Clear playlist" button with edit-clear-all-symbolic icon - Show "Unsaved changes" label when playlist is edited (add, remove, move, clear) that disappears after clicking "Apply Playlist" Made-with: Cursor
…d resource leaks - Fix critical race condition in Fade class using cycle_id to prevent orphaned Timer thread accumulation across playlist transitions - Release old VLC Media objects in set_media() to prevent memory leak - Protect _is_transitioning with try/finally to prevent permanent deadlock - Cache ffprobe video dimensions in _setup_playlist to avoid blocking GTK main thread on every transition - Fix Image.open() file descriptor leak in set_static_wallpaper - Add diagnostic logs: health check every 60s, transition tracking, media end counting, thread count monitoring Made-with: Cursor
- Add logging.basicConfig() in player process so diagnostic logs appear - Replace synchronous ffprobe pre-cache of all 43 videos (which blocked GTK main loop for 20-90s) with lazy background probing per video - Fix config save race: save config inside _setup_player() after setting mode and Default, so the player process reads correct values from disk Made-with: Cursor
…repeats The stop()/play() cycle for repeating videos was reinitializing the hardware decoder on every repeat, leaking VA-API contexts and memory (549MB -> 817MB in 7 media ends). VLC eventually entered a dead state. Delegate repeat handling to VLC via :input-repeat media option, which loops internally without destroying the decoder pipeline. Made-with: Cursor
Stop all VLC players explicitly before set_media() during transitions to ensure VA-API decoder resources are fully released before creating new ones. Previously, set_media() on a still-playing player caused overlapping decoder contexts and memory growth. Add a watchdog timer (30s) that detects stuck playback by monitoring player position, forcing advance to next video if VLC enters a dead state. Also switch health check memory metric from ru_maxrss (peak) to VmRSS (current RSS) for accurate diagnostics. Made-with: Cursor
VLC's player.stop() waits synchronously for decoder threads to finish, but those threads need the GTK main thread for X11 video output rendering, creating a deadlock. set_media() handles the swap internally without this issue. The watchdog timer recovers from stuck VLC decoder states. Made-with: Cursor
Transition between playlist videos is now instant instead of fading opacity out/in, simplifying the transition logic. Made-with: Cursor
Replace in-place set_media() with full VLCWidget recreation on each playlist video change. The old widget is cleaned up in a background thread, avoiding the GTK main thread deadlock caused by VLC's internal decoder stop. Made-with: Cursor
Made-with: Cursor
Synchronize VLC widget cleanup to release GPU decoder buffers before allocating a new instance. Previously, cleanup ran in a daemon thread that could fail to complete, causing GPU memory to grow unbounded. - Make replace_vlc_widget() cleanup synchronous (stop, release media, release player/instance, gc.collect) before creating the new widget - Detach MediaPlayerEndReached event from old player before replacement - Guard GLib timers with _timers_active flag to prevent accumulation - Release vlc.Media in VLCWidget.cleanup() before releasing the player - Call gc.collect() after VLC cleanup to force GPU resource deallocation Made-with: Cursor
… scaling on 2K monitors video_set_crop_geometry() was called before start_playback(), so VLC could silently ignore the crop on newly created widget instances. Now schedule_centercrop() uses the MediaPlayerVout event plus a timed retry fallback to ensure the geometry is applied once the video output actually exists. Also fixes _on_size_changed() calling non-existent methods on Gdk.Monitor instead of the player window. Made-with: Cursor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
stop()(triggered byset_media()on an active player) blocks waiting for decoder threads, which in turn need the GTK main thread for X11 video output — causing a deadlock. To solve this:set_media()with fullVLCWidgetrecreation on each playlist video change — the old widget is cleaned up synchronously, completely avoiding the GTK main thread deadlockvideo_set_crop_geometry()was being called before VLC created its video output, causing intermittent failure to fill the screen (especially on 2K monitors). Now uses theMediaPlayerVoutevent with a timed retry fallback to apply crop geometry only after the video output is ready. Also fixed_on_size_changed()calling non-existent methods onGdk.Monitor.Commits
6903541feature: add playlist mode with repeat count for all monitors4c82608fix: resolve TypeError in config load and improve playlist UXc7aa0e1feat: enable VA-API hardware acceleration in Flatpak692ca64feat: smooth playlist transitions, thumbnails/duration in UI, add-all button5b46ad3fix: resolve freezing during playlist transitions60740b2fix: handle thumbnail generation errors gracefully6b8f46bfeat: add clear playlist button and unsaved changes warning186e572fix: resolve playlist freezing caused by Fade timer race condition and resource leaks7398abafix: resolve playlist freeze caused by blocking ffprobe and config race7962ffbfix: use VLC input-repeat to prevent VA-API decoder leak on playlist repeats9d33b14fix: stop players before loading new media and add stuck-video watchdog8462addfix: remove explicit stop() that caused GTK main thread deadlock134880arefactor: remove fade transition effect from playlist video switching2eff7a0fix: recreate VLCWidget per playlist transition to prevent deadlock43b56f8feat: open GUI on the tab matching the active playback mode350e46efix: prevent GPU memory leak during playlist transitions10ef8fffix: apply centercrop after VLC vout is ready to prevent intermittent scaling on 2K monitorsTest plan
https://github.com/rhafaelcm/hidamari/releases/tag/fork-v0.1.0-playlist