Skip to content

v0.9.0 — the Plex Watchlist, a Library that opens on the grid, and Collections you can find

Latest

Choose a tag to compare

@github-actions github-actions released this 23 Oct 12:50
· 148 commits to main since this release
02f59f3

This release adds the Plex Watchlist, makes the Library open on your library itself instead of on a page of recommendations, and puts Collections one press away from the Library header. Underneath that, subtitles are drawn by one renderer for every text format, more video and audio files direct-play, PlxNative remembers your audio and subtitle choices from episode to episode, and it speaks Italian, French, German, European Portuguese and Hungarian. It is the first release since 0.8.0, which was cut on 2026-10-07.

What's new

  • The Plex Watchlist. A bookmark tab sits before Search in the top bar and opens your plex.tv Watchlist as a grid, with one Sort & Filter pill for Type, Sort and Show. Movies and shows have a bookmark button on their page and on the Home hero, and the hold menu on a movie or show offers Add to Watchlist or Remove from Watchlist (on an episode or a season, for its show). A title you have not got on any of your servers opens a catalog page with its status and an Add to Watchlist or On Watchlist button and no Play; on the grid it wears a mark and the caption Not on your servers, and titles that are listed but not out yet read as coming soon. The list belongs to your plex.tv profile, not to a server, so adding or removing a title changes your real Watchlist, the same one the Plex apps on your phone show.
  • A Library that opens on the library. The Library page is now always the full A to Z grid of posters: the sub-tabs and the All heading are gone, and the recommended shelves no longer sit above the grid. One header row carries the library names (with two or more libraries, the ones that do not fit fold into a +N menu, and a library switches on OK, never just by passing over it), then Collections, Recommended and Sort & Filter. When a filter is on, a read-out such as 15 of 16 films sits beside it. Recommended opens the server's shelves for that library on a page of their own, and BACK returns to the grid. Your sort, Unwatched switch, genre and listing type are still remembered for every library, per profile.
  • Under posters. Settings → Libraries → Under posters chooses what is written under a poster: a Title switch and one line of Year and length, Genre, Video, Age rating and score, or Nothing. It applies to every poster in the app, Home, Library, Collections, Search, a person's films, the Watchlist and the shelves on a title's page, with a live preview in the setting.
  • Collections are easier to find. Beside the Library header's Sort & Filter, Collections shows how many the library has and opens them as a grid; it appears once the server has said how many there are and is left out for a library without any. A single collection is still found in Search, from a collection shelf's heading on Home and on a library's Recommended page, and from the collection row on a movie's own page. A collection page names the page you came from above its title.
  • Open a Plex title from another app. Another app on the television, such as a launcher's Continue Watching row, can ask PlxNative to open a title's page or to start playing it, by passing the server and the item in the launch parameters. This means any app on your television that can launch apps can do that, and a link that arrives during playback ends the film first; the details are in Launch links. Sign-in, the profile picker and onboarding are never interrupted: the link waits behind them, and once someone signs in, a link that names its server opens on that account while one that names no server is dropped. A running app picks the link up only where LG's own SDL library has the hook PlxNative uses, which per the firmware inventories is platform release 7.4 and later (measured on a 2022 LG C2 on platform release 9.2.2); everywhere else it works when the app is closed first.
  • One tile per show in Continue Watching. If your own server and a friend's server both hold a show, Continue Watching now shows it once, as Plex Web does. A Continue Watching tile for an episode now reads like S3 · E4 · 18m left, and with Continue Watching set to Open details, OK on it opens the show (see Changed). Every show's page now opens on the season of the episode you are up to, with that episode in view, instead of on the first season.
  • PlxNative remembers your tracks per show. An audio or subtitle choice you make in an episode is remembered for that show and applied to its next episodes, including a remembered external subtitle and a new Forced only row in the Subtitles menu. The choice is also written back to Plex, so your other Plex apps open the episode with the same tracks.
  • Text subtitles through one renderer. SubRip, WebVTT and the other text formats are now drawn by the same renderer as ASS and SSA, with a bundled bold face for 22 more scripts, including Arabic, Hebrew, Thai and Devanagari. Subtitles in legacy encodings such as GBK, Big5, Shift_JIS and EUC-KR are detected per track instead of coming out as garbled characters. There is a Huge caption size above Extra large, and long captions wrap by width, capped at three quarters of the screen.
  • Scrubbing with a preview. While you scrub, a still from the server's preview thumbnails floats above the knob, when the server has them. Left and Right, fast-forward and rewind only move the target; OK, Play or Play/Pause commits the jump and BACK cancels it. A held key starts at 60 times speed and doubles every second up to 480 times. Thanks to dimitrije83 for the preview thumbnails.
  • More files direct-play. AV1 and VP9 direct-play on sets whose own decoder table lists them, and a VP9 file tagged HDR10 now switches the television to HDR. Dolby Vision Profile 7 files, the dual-layer kind on UHD Blu-ray remuxes, are converted to Profile 8.1 in the app and played as Dolby Vision; AV1 Dolby Vision declares itself; and a Dolby Vision file keeps its Dolby Vision when the server only copies the video, which is what Boost dialog and Normalize loudness do. Thanks to RichiL10 for the Profile 7 conversion and to Tiago Pereira for the other two. A DTS track from a real Plex server direct-plays on a set whose table lists DTS, because the server's name for it, dca, is now understood. On webOS 5 and newer a seek no longer reloads the video.
  • Settings are per profile. The playback settings, the subtitle size, position and look, Boost dialog and Normalize loudness, Under posters and the Home hero's trailer autoplay belong to each profile, and Settings names the profile it shows. A profile that has not chosen yet starts from the television-wide value. Automatic sign-in and Interface resolution stay television-wide.
  • Five new interface languages. Italian, French, German, European Portuguese and Hungarian, alongside English, Spanish and Belarusian. Thanks to Massisalo, Yagz, U3knOwn, Tiago Pereira and Danzig.
  • Emoji in titles and library names are drawn instead of an empty box. Thanks to Tiago Pereira.
  • Sets on webOS 3.x, which are outside the supported range, got attention. The prebuilt 0.8.0 closed on them at the first press of a remote's arrow key and again when a video began (issue #862, issue #249): it called two functions their system does not have, and this release finds both at run time instead. A 2016 set on platform release 3.4.3 now signs in, browses and plays, a 2017 set on 3.9.0 reports the same on a nightly build, and Settings → System → Interface resolution (webOS 1 to 3 only) offers a lower resolution for smoother menus. Details are under Compatibility. Thanks to selfhealer-png, chriskoperdraad-tech, Melvin Holt and Psychotonikum.
  • Also new. The player's HUD truncates a long title and reveals it while paused (infectiousstupidity), the no-server screen offers Use another account, the Quality row says what is actually playing, the video overlay and subtitles dim during HDR playback, the Magic Remote pointer hides after D-pad presses on webOS 3.x, and on a server you own, a page showing a title re-reads it when another Plex app plays or stops that title, and Continue Watching refreshes when it stops.

Fixed

  • A film whose audio is stored ahead of its video never started. An MKV with its audio about 48 seconds early (issue #600) and one whose audio starts about 11 seconds late now start and keep playing; thanks to Danzig for the late-audio case.
  • A film no longer stays on its last frame after the credits when its audio runs past the last picture. Thanks to Tiago Pereira.
  • With Boost dialog or Normalize loudness on, a 4K film could be shown at about 15 frames per second. The server only copies the video then, and the film's own frame rate was not passed to the television.
  • Dolby Vision was lost with Boost dialog or Normalize loudness (issue #885); it is kept now.
  • Boost dialog and Normalize loudness stayed unavailable for the rest of a film after a subtitle the app cannot draw itself, such as a .sup file, was chosen; the server now burns that subtitle in while it converts the sound.
  • Changing the audio track while paused blanked the picture behind a Buffering spinner until Play was pressed. The paused frame now shows, and preparing it no longer makes a short sound.
  • An automatically chosen forced subtitle switched subtitles off. A track titled Forced or SDH was treated as a normal one when the account's language rule picked (issue #828).
  • Also available showed a wrong runtime on show and season pages (issue #814); a show or season copy now shows none, and About's Runtime row is for movies and episodes only.
  • Play after coming back from a film started from the old position, and an episode you had finished was not marked watched (issue #575, issue #680). The page is re-read once your stop has reached the server.
  • Chinese, Japanese and Korean text could not be drawn on webOS 3.x and 4.x sets (issue #628). Their system rejected the bundled font as it was; it is now cut down to a form they open, with no characters dropped.
  • Some embedded ASS and SSA subtitles never appeared, because their headers end in a byte the renderer refused. Thanks to Shakil Choudhury.
  • Subtitle size and position were forgotten between restarts (issue #582), subtitles longer than three lines were cut off (issue #585), and a retry before the playback plan landed turned subtitles Off.
  • A 4K H.264 file failed on some sets with a resource allocation error (issue #665): the frame rate class of a file with a millisecond timebase was declared too high.
  • Direct play of a DTS-HD MA file hung when the track list had not loaded (issue #584); the server now converts the audio.
  • Direct play over plain HTTP no longer stalls when the server cuts the transfer or stops sending, and large MP4s with the index at the end start on webOS 3. Thanks to Tiago Pereira, selfhealer-png and Melvin Holt.
  • HDR10+ files stalled the decoder when the HDR10+ data shared a unit with other data. Thanks to Tiago Pereira.
  • Your answers to Connect without encryption?, subtitle timings and Library views survived signing out (issue #385); sign-out now clears them, along with the remembered tracks and per-profile settings.
  • BACK over the playback controls left the film instead of hiding them, a screensaver that took the decoder back left playback stuck, and a click with no control under the pointer did nothing after D-pad navigation. Thanks to dimitrije83 and Frank Muller.
  • Poster and focus glitches: posters blanking when a menu closed over a Collection, a card snapping when a held key left it, Home briefly showing the shelf you had left when you moved down from the hero, the Home hero blinking black and changing title after you came back from a film, the show's logo drawn across the season pills while an episode had focus (issue #679), and a ghosted copy of an episode still when its menu opened.
  • Home and the Library lists reach their real end (no fixed reach), Home's Recently Added loads in pages (thanks to Shakil Choudhury), and Library posters load ahead of a fast scroll. Key presses on Home and on Recommended, and a held key across a grid of posters, drop fewer frames.
  • Image cache on webOS 3.4 was off because the app could not find a writable directory; it now uses the one writable directory the television offers, sized to its free space.
  • Force Direct Play names the audio codec it refuses instead of saying this audio format.

Changed

  • Scrubbing asks for OK. Releasing a held key no longer jumps; see What's new.
  • The Library's sub-tabs, All heading and TYPE menu are gone, and the Library no longer scrolls the recommended shelves before the grid. Recommended and Collections are header buttons, and a TV library's Shows, Seasons and Episodes are under Sort & Filter → Show.
  • OK on a Continue Watching episode opens the show, not the episode page, when Settings → Playback → Continue Watching is Open details (the default). Choose Play there to start the video as before.
  • Signing out clears more. The remembered tracks, per-profile settings, subtitle timings, Library views and the last Library are removed with your sign-in, so one account's choices no longer carry to the next account on the same television.
  • The press-and-hold hint is shown once per television, not once each time the app starts.
  • Crash and playback-error reports carry more fixed-value fields (what failed, and the television's operating system and hardware, as codes and library names), for people who share reports. They are listed in the reporting question's preview and in the privacy policy; nobody is asked the reporting question again.
  • Two settings send a little more, and nothing is sent unless you turned them on. With Product analytics on, leaving a screen now also reports broad classes of how smoothly the app ran on it: late frames, frozen frames, the app not responding, and a remote key pressed repeatedly with nothing happening; they are classes, never counts, durations, key names or anything you watched or searched for. With Crash reports on, a freeze of five seconds or more while the app is open on screen is reported like a crash (code addresses and a duration range), and one small record per stretch of use is sent even when nothing went wrong, so crashes can be counted per release: when it started, how long it lasted, how it ended, the Crash report ID, and the app version, with no content, account or server. Nobody is asked the questions again, because the choices are the same ones you already made; the privacy policy now describes all of it. Turning Crash reports off or signing out deletes the local session record and any waiting to be sent.

Compatibility

  • Plays video, verified by watching it — 2019 LG sets. One television: an LG 49SM9000PLA, which reports platform release 4.10.2 (LG markets this generation as webOS 4.5). Several changes in this version were checked on it while they were written; the audit says which, and that the release-level suites had not been run on it when this note was written.
  • Plays video, reported by someone else — 2025, 2021, 2019 and 2018 sets. On 2026-10-21 an owner reported sign-in, browsing, search and movie playback on an LG OLED77B5PUA (2025, platform release 10.3.0) running the 0.8.0 release build: discussion 906. On 2026-10-20 an owner reported sign-in, browsing, direct play of an MKV, resume and fast-forward on an LG 75UK6570AUA (2018, platform release 4.4.3) running 0.8.0: discussion 882. Earlier reports stand for a 2019 set on LG's k5lp chip on v0.6.3 (issue #74) and an LG 65UP7560AUD (2021, platform release 6.5.2) on v0.2.1 (issue #22). None of these has been repeated on 0.9.0.
  • Sets on webOS 3.x are outside the supported range, but some now work on nightly builds. The prebuilt 0.8.0 started on them and then died on the first D-pad press or the first video frame (issue #862); that is fixed in this release. On 2026-10-20, an owner reported sign-in by QR code, browsing, search and video playback on an LG 65UJ6200-UA (2017, platform release 3.9.0) on the 0.9.0 nightly of that day: discussion 878. On 2026-10-21, an owner reported sign-in, browsing, direct play, a transcoded stream, subtitles and seeking on an LG OLED55C7V (2017, platform release 3.9.4) on a nightly, after crashes on 0.8.0: discussion 900. A 2016 set on platform release 3.4.3 was tested by the author of the fix, selfhealer-png, on a build of the change itself: pull request 578. On a 2017 LG C7 on platform release 3.9.3, a build from source carrying the playback-start fix plays direct play: pull request 700. These are nightly, branch or source builds, not this release, and other 3.x sets are untested.
  • Starts, and nothing further is known — every other firmware from webOS 4.0 up is expected to start. This binary's libraries and symbols are checked against the firmware images webosbrew has; the result for this build is in the technical audit, including what it says for webOS 3.x. That grades startup and says nothing about whether video plays.

Separately, opt-in usage reports from 0.6.6 show video starting, directly and by transcode, on sets from platform release 4.4.2 up to 11.2.0. That is a count of starts, not a person watching a named set, so it moves none of the lines above.

If your set is not in the first group, tell us what happened. It working is as useful a report as it failing.

Known issues

  • Some 2019 sets on LG's k5lp or k3lp chip, installed through Developer Mode, cannot play video. LG's sandbox can withhold a device the video path needs. The app says so instead of crashing, and on a rooted television the failure screen offers Repair, which has not been run on an affected set (issue #74, closed with this still the case).
  • Sets on webOS 3.x are outside what is supported. Seeking restarts the stream instead of jumping in place there, and menus can drop frames at 1920x1080. The crashes described under What's new were confirmed gone only on nightly and branch builds, not on this release's package.
  • A crash on televisions built on LG's k6hp chip, seen only in opt-in crash reports and not reproduced, because no such set is available (issue #174).
  • Seeking without a reload on webOS 5 and newer has not been watched on one. It goes through LG's public Seek call and was checked only by forcing that path on the 2019 set.
  • Dolby Vision Profile 7 conversion has not been watched on a television, and AV1 and VP9 direct play depend on what the set's own decoder table says.
  • DTS audio has not been heard on a television. The app sends DTS only when the set's codec table lists it, and DTS-HD MA 7.1 plays its core only.
  • Rare sequences can still leave a page empty, and Home can still miss a refresh while you flip the hero or move between shelves, which reads as a small hitch. Neither was re-examined for this release.
  • Not every new feature has been seen on a television, in particular server pages refreshing on their own, the Watchlist on a real account, and the per-profile settings across a restart. The new Italian, French, German, European Portuguese and Hungarian wording has not been reviewed by us, and some Belarusian and Spanish wording from 0.8.0 still wants a native speaker.
  • Auto quality has only been exercised in a laboratory, and servers behind Plex's relay, and servers that require an encrypted connection, are reached but have not been watched end to end.

Help test this release

If you have a set on webOS 5 or newer, seek in a direct-play film, in the middle and near the end, and tell us whether the picture carries on without a black flash. If you have Dolby Vision Profile 7 files and a Dolby Vision set, tell us whether the panel switches to Dolby Vision. If you have a set on webOS 3.x, tell us which platform release it reports in Settings → About This TV and whether the app starts, browses and plays. If you use the Watchlist, tell us whether a title you add on the television appears in the Plex app on your phone. Open an issue. It working is as useful a report as it failing.

Installing

Download com.beb.plxnative_0.9.0_arm.ipk and install it with the Homebrew Channel or dev-manager-desktop. You do not need a rooted TV.

Nothing in this distribution chain is signed, so this sha256 is what tells you the file you have is the file published here:

d6bc601667a25d0c7dbb13ea95efb0f065f481ab46f9391960687220c7557c30  com.beb.plxnative_0.9.0_arm.ipk

Installing and checking a download covers the other assets, how to check the hash on each platform, and the Developer Mode expiry that uninstalls your apps. PlxNative is licensed GPL-3.0-or-later and bundles FFmpeg under LGPL-2.1-or-later and the libass subtitle renderer with its own libraries under their licences; the complete corresponding source is attached to this release. Exactly what was built, verified and shipped is in the technical audit for v0.9.0.

What's Changed

  • Issue labels: dry runs show the whole pick by @GLinnik21 in #483
  • ci: retire the CI metrics workflow and its build-time chart by @GLinnik21 in #487
  • Site: rerender the close-ups and link card at full resolution for 0.8.0 by @GLinnik21 in #488
  • Make the host suites runnable from a Claude Code cloud session by @GLinnik21 in #477
  • Simulator CI: a host FFmpeg/libass cache hit now means no rebuild by @GLinnik21 in #489
  • Tests: stop idling on mock deadlines, settle two flaky tests, leave nothing in $TMPDIR by @GLinnik21 in #490
  • check: run the Python/shell/C gates concurrently from one manifest (lone make check 203 s -> 101 s) by @GLinnik21 in #492
  • Item menu: the opener lift stands down once a dismissed menu's page focus has moved off the opener by @GLinnik21 in #493
  • Demo library: the mock serves cited metadata; Sintel and Tears of Steel complete by @GLinnik21 in #494
  • Cards: a behaviour conformance suite over today's card screens (tests only) by @GLinnik21 in #495
  • CI: bring the build-time page back (jobs derived from the data, red runs and re-runs, hand-measured local milestones) by @GLinnik21 in #496
  • Cards conformance: Home and Detail's Related shelf join the suite (tests only) by @GLinnik21 in #497
  • Demo library: the completeness gate, a shrink-only pending list, asset kinds and sizes by @GLinnik21 in #499
  • Cards: one press source for every card strip, and a Collection content revision the page syncs on by @GLinnik21 in #498
  • Cards: Shelf and Grid, one shared component for every strip and grid of cards by @GLinnik21 in #500
  • Image-cache stress fixture: write the access-log row before the response goes out by @GLinnik21 in #501
  • Collection adopts cards::Grid: its pop, scroll, stops, placement and paging come from the shared component by @GLinnik21 in #502
  • Person adopts cards::Shelf, its store gains a content revision, and a person with no guid stops waiting on a profile by @GLinnik21 in #503
  • cards::Grid: columns, style and left edge come from the spec, and the page can own the scroll by @GLinnik21 in #505
  • Search adopts cards::Shelf: each result row's pop, scroll, stops and placement come from the shared component by @GLinnik21 in #506
  • Up Next: the player screen comes to rest, and the site's Up Next close-up is rerendered by @GLinnik21 in #491
  • Library: the All grid is a cards::Grid (external scroll), with an exact, clamped landing shift by @GLinnik21 in #507
  • Demo library: text content for the 28 titles the completeness gate listed by @GLinnik21 in #509
  • Dump mode (S5a-1): convert four landing sites (Person, Collection, Search, SubtitleSearch) and the gfx constants by @GLinnik21 in #508
  • Dump mode (S5a-3): Home's hubs and the discovery take wait for their own request, plain takes under dump are counted by @GLinnik21 in #510
  • cards::Stack: Collection and Person become a page of card sections with no hand-written focus code by @GLinnik21 in #511
  • Dump mode (S5a-2): a superseded request cannot release the new claim; Metadata, Browse and ViewState land on their own request by @GLinnik21 in #512
  • Troubleshooting: how to collect the app's logs, and a bug-report form that asks for them by @GLinnik21 in #513
  • Detail: the Related, Collection, Extras and Cast shelves are cards::Shelf by @GLinnik21 in #515
  • CI page: a working instrument for build time (PR runs, daily local bench, what got slower) by @GLinnik21 in #516
  • Demo library (S2b): the hero-geometry check, pinned to the layout's Rust constants by @GLinnik21 in #517
  • tools/site_video.py: encode, quality gates, sentinel scan and adopt for the site demo video (S6) by @GLinnik21 in #520
  • Library: the hub shelves are cards::Shelf, and a landing can no longer overscroll a shelf by @GLinnik21 in #523
  • CI: non-code pushes (issue forms, prose, images, agent config) no longer start the full pipeline by @GLinnik21 in #514
  • UI: count every placeholder at its draw, plus a pixel sentinel build (S4) by @GLinnik21 in #518
  • Issue form: say each thing once by @GLinnik21 in #522
  • Route users: report links to the form chooser, jail help to the docs, a sign-in troubleshooting section by @GLinnik21 in #524
  • Home: the hub shelves are cards::Shelf by @GLinnik21 in #525
  • Issue labeler: never a second kind, and retire the question label by @GLinnik21 in #526
  • Privacy policy: the logs are emptied at launch, they do not rotate by @GLinnik21 in #527
  • Daily build bench: make check can pass on the runner, noise is per row, the run is 9 minutes by @GLinnik21 in #529
  • Cards: element-keyed pop pool behind the plxnative-poppool dev trigger by @GLinnik21 in #530
  • Demo library: backdrops for the missing titles, hero boxes, posters from stills, per-title flags by @GLinnik21 in #532
  • Cards: no screen names the L0 primitives, and the item-menu opener asks the page by @GLinnik21 in #533
  • S5b-1: the frame-dump driver core, make site-video-sim, site_video.py render by @GLinnik21 in #528
  • Detail: a vanished card-shelf card falls to the same slot in its shelf, not to the hero by @GLinnik21 in #534
  • Daily build bench: read the branch times the runner really prints by @GLinnik21 in #535
  • Demo library: clear logos for the pending titles, hero boxes for Sintel and Tears of Steel by @GLinnik21 in #537
  • Cards: pop springs follow their element in every build; the per-position path and the plxnative-poppool switch are gone by @GLinnik21 in #538
  • Search: the page is a cards::Stack by @GLinnik21 in #539
  • fps --mock: run the card-screen scenes against the synthetic library by @GLinnik21 in #541
  • Hold hint: the other card screens teach it too, once per screen kind per run by @GLinnik21 in #542
  • Frame dump: virtual frames are reproducible whatever the iteration count (S5b-2) by @GLinnik21 in #540
  • Cards: simplify what the shared-sections series left behind by @GLinnik21 in #544
  • Site video: the Linux CI render workflow (site-video.yml) by @GLinnik21 in #536
  • Demo library S3.4: drop Sherlock Holmes, final catalog order by @GLinnik21 in #543
  • Docs: card screens are Stack pages and Shelf/Grid own the strips by @GLinnik21 in #546
  • Demo video: the storyboard film, filmed by the simulator and gated (S5c) by @GLinnik21 in #545
  • Site video: simplify what the series left behind by @GLinnik21 in #547
  • Hero title: the settled-miss peek runs only when placeholder accounting can see it by @GLinnik21 in #548
  • site: lead the FAQ with PlxNative, not "Plex" by @GLinnik21 in #550
  • Hold hint: a once-per-run showing is spent once it has been readable, not when it starts by @GLinnik21 in #552
  • Build-time page: daily charts that fit their days, a true caption, a top block ordered by what a developer waits for by @GLinnik21 in #553
  • Site video v2: the Library caption animates, hero paging, a Detail that is not Sintel by @GLinnik21 in #551
  • Hold hint: time under a covered page is not rest, and the capsule's layout is resolved once per language by @GLinnik21 in #554
  • Frame dump hygiene: an admission rule and a gate for the switch, a poster test race, a full tree hash by @GLinnik21 in #556
  • Site: add AVPasión and Paspu to the press section by @GLinnik21 in #555
  • Dev tooling: close 12 CodeQL py/* alerts (path containment, TLS 1.2 floor, no secret echo) by @GLinnik21 in #557
  • Diagnose mid-body transport failures: log the curl rc, bucket it into the handled playback error by @GLinnik21 in #560
  • Site: adopt the Linux-rendered demo video by @GLinnik21 in #558
  • Item menu: the lifted card is the opener lift's alone, so a taken hold's spring is not page damage by @GLinnik21 in #561
  • fps: real hold and tap scenes, and the bench counts a present deferred by the capture fence by @GLinnik21 in #562
  • Site video: refresh the film after a stable release by @GLinnik21 in #559
  • Film: a pushed page is filmed live under the dip, never as a held image by @GLinnik21 in #565
  • Posters: the texture warm-up draws offscreen, so an upload no longer takes the back-buffer wait inside prepare by @GLinnik21 in #563
  • Cards: a press abandoned by a direction key springs back on the card that was pressed by @GLinnik21 in #566
  • Site stills: the simulator-made images refresh after a stable release, with the film by @GLinnik21 in #564
  • Tests: fix two wall-clock host-test flakes (claim-hold sink clock, discovery incident stamp) by @GLinnik21 in #571
  • Library: a push to the other kind's library aims the store before the page image is taken by @GLinnik21 in #570
  • Site film and stills tooling: share the tree-hash, needs-render and film-paragraph helpers by @GLinnik21 in #572
  • Simulator CI: replay in a 960x540 window (--window), the runner has no GPU by @GLinnik21 in #576
  • check-parallel tests: interrupt only after the quick step has been printed by @GLinnik21 in #577
  • webOS 3.4: resolve the two missing imports at runtime, and seek by reload on 3.x by @selfhealer-png in #578
  • webOS 3.x follow-up: gate in-place seek on the Feed ABI, guard the COW reply destructor by @GLinnik21 in #581
  • Site: add Telesatellite and turn the press section into a compact dated list by @GLinnik21 in #580
  • Library: posters load ahead of the scroll, so a fast scroll shows far fewer loading tiles by @GLinnik21 in #583
  • Load Home Recently Added lists in bounded pages by @sh-k-l in #567
  • Reopen a direct-play transfer that the server cuts mid-body by @selfhealer-png in #579
  • Subtitles: stop cutting a cue off after three lines by @GLinnik21 in #588
  • Sign-out forgets the plaintext-connection answers by @GLinnik21 in #589
  • ci/check-elf.sh: grade the storage helper's DT_NEEDED by @GLinnik21 in #590
  • Playback: don't direct-play an undecodable audio codec when tracks aren't loaded (DTS-HD MA) by @GLinnik21 in #587
  • Subtitle size and position now persist when set back to the default by @GLinnik21 in #586
  • AGENTS.md: branches may carry any number of commits; the squash happens at merge by @GLinnik21 in #592
  • Detail: a return from the player re-reads the page, so Play resumes where the stop left off (#575) by @GLinnik21 in #597
  • Docs: hostsim test command, build gotchas, and what the PMS does with a stop position by @GLinnik21 in #598
  • AV1: direct-play on sets whose codec table lists an AV1 decoder by @GLinnik21 in #602
  • VP9: direct-play on sets whose codec table lists a VP9 decoder by @GLinnik21 in #604
  • Every list pages to its real end: no caps on reach, bounded windows, stable focus by @GLinnik21 in #605
  • README: add Trendshift badge by @GLinnik21 in #610
  • VP9: tell the display a PQ stream is HDR10 (sourceInfo envelope rewrite) by @GLinnik21 in #606
  • dev: DIAG trigger list is 39 long (main stopped compiling after #605 + #606) by @GLinnik21 in #613
  • ci: the ELF gate's parallel-scratch test reads its snapshot once, at the synchronised call by @GLinnik21 in #611
  • Paging store: incremental ledger update, one row release, one fan-out turn by @GLinnik21 in #608
  • Screens: one key-table prune, one hold band, one row neighbourhood by @GLinnik21 in #609
  • Episode list sits on the shared page cache; one eviction guard by @GLinnik21 in #607
  • A key a page lists twice is one card: backward reads and hub previews keep the first occurrence by @GLinnik21 in #612
  • Codecs: refuse what the pipeline cannot feed, hold the three codec lists to one definition by @GLinnik21 in #614
  • VP9: claim 10-bit where it was measured (webOS 4 family), keep the 8-bit cap elsewhere by @GLinnik21 in #616
  • Player: a film whose audio starts late plays from the start (lands #603) by @GLinnik21 in #618
  • Home: the top bar's glass keeps its blur source through a held key by @GLinnik21 in #619
  • Frame probe: time the back-buffer wait and the prepare stage on every route by @GLinnik21 in #620
  • A retry before the plan lands no longer forces subtitles Off by @GLinnik21 in #621
  • PlayingItem carries the Plex item type by @GLinnik21 in #622
  • Site: landing page from the Claude Design v10 mockup by @GLinnik21 in #615
  • Characterisation tests pin how player settings persist, publish and restore by @GLinnik21 in #623
  • Site: bring the landing page up to the final Landing Page v10 by @GLinnik21 in #625
  • The nine player settings are one declared Preferences struct, tied to a Setting row each by @GLinnik21 in #626
  • Rows show skeleton cells past an edge the list goes on beyond by @GLinnik21 in #629
  • The nine live player settings are one LiveCell each, one restore_all, one write door by @GLinnik21 in #630
  • The seven live Settings picks are one Choice command through one door by @GLinnik21 in #633
  • Per-profile memory has one door: ProfileList, remember and recall, with subtitle offsets as the first tenant by @GLinnik21 in #634
  • Crash and playback-error reports say what failed and why, with symbols for the bundled libraries by @GLinnik21 in #632
  • Site: hero buttons on phones, "Built differently." and the stack scene by @GLinnik21 in #627
  • Site: frosted stack plates without the Safari halo by @GLinnik21 in #637
  • Site: feature stages, storytelling and captures by @GLinnik21 in #638
  • Site: centre the decoder and network diagrams by @GLinnik21 in #644
  • Rust panic reports carry the same os, webos and hardware contexts as the fault fallback by @GLinnik21 in #646
  • Show pages open at the resume point; Continue Watching opens the show by @GLinnik21 in #647
  • Detail: a short Related row asks for its tail without focus by @GLinnik21 in #648
  • Player: holding a seek key climbs in doubling steps, 10x to 320x by @GLinnik21 in #649
  • mock_pms: a show with an on-deck episode and a Continue Watching episode by @GLinnik21 in #650
  • docs: translations are accepted after native-speaker review by @GLinnik21 in #652
  • Player: a held seek key starts at 60x, survives key bounces, and shares one hold implementation by @GLinnik21 in #654
  • theme: retire two near-duplicate palette stops; add design-tokens.py drift check by @GLinnik21 in #651
  • Locales: French UI language by @Yagz in #636
  • plex: track_memory row, household budget and the document guard (data layer, nothing wired to it) by @GLinnik21 in #671
  • plex: the remaining preference keys become Preferences rows; NOT_YET_ROWS is gone by @GLinnik21 in #672
  • plex, platform: sign-out clears the per-profile data that used to survive it by @GLinnik21 in #673
  • media: track memory read path (matchers, rungs, write-back provenance, fresh_play) by @GLinnik21 in #674
  • Site film: a tighter storyboard with the title page scrolled to About and the Movies poster grid, plus cast portraits by @GLinnik21 in #645
  • The nine player settings are per profile (fallback to the legacy install-wide key), restored at the seat by @GLinnik21 in #675
  • Settings names the profile whose playback settings it shows by @GLinnik21 in #678
  • Q-TOP (b): burn a remembered subtitle only on a route that already re-encodes video by @GLinnik21 in #677
  • Hero trailer autoplay is a per-profile setting (P1c) by @GLinnik21 in #676
  • ui: hover moves no focus while the TV keyboard is up by @frank-m in #656
  • Subtitles: wrap captions by pixel width, capped at 75% of the screen by @Yagz in #663
  • Site: pin the stack scene on phones so a swipe no longer races through it by @GLinnik21 in #684
  • Track memory: a subtitle or audio pick on an episode is remembered for its show by @GLinnik21 in #685
  • Image cache: reach webOS 3.4's one writable directory, sized to its free space by @selfhealer-png in #667
  • Link conditioner test waits for its wire-log row instead of reading the log once by @GLinnik21 in #686
  • Tests: a track-memory resolve captures a private event log, not the machine-wide one by @GLinnik21 in #688
  • Accept NUL-terminated embedded ASS headers and packets from FFmpeg by @sh-k-l in #641
  • webOS 3.x: hide the Magic Remote pointer on D-pad presses and after 5 s idle (#642) by @chriskoperdraad-tech in #655
  • Track memory: a remembered external subtitle selects the next episode's same-language sidecar (C5) by @GLinnik21 in #691
  • net, media: the player sends the User-Agent boot installs (#670) by @dasunNimantha in #687
  • Track memory: an applied remembered choice is written back to Plex on the first decoded frame (WB) by @GLinnik21 in #690
  • Direct Play of >4 GiB moov-at-end MP4s on webOS 3 (416 at EOF, 32-bit body length, DV declaration) by @MelvinHolt in #692
  • Track memory: Forced only, the third remembered subtitle state (FO) by @GLinnik21 in #696
  • Track memory: one simplify pass over the series (no behaviour change) by @GLinnik21 in #698
  • net, media: one place applies the User-Agent, and a check keeps it that way by @GLinnik21 in #693
  • session: log the DB8 document size and canonical write latency (track-memory U5) by @GLinnik21 in #699
  • dev: plxnative-trackmemory=fill[:N] to read the DB8 write cost at the track-memory budget (U5) by @GLinnik21 in #701
  • README: webOS 3.9.3 plays direct play from a source build (dual-ABI Feed dlsym) by @Psychotonikum in #700
  • route: the forced subtitle burn is spent only when an audio enhancement is asked for by @GLinnik21 in #703
  • session: a login over another account's stored session does not inherit its library views (N7) by @GLinnik21 in #705
  • test: an episode played to its end is watched on the Detail page it returns to (#680) by @GLinnik21 in #702
  • docs: state exactly what a remembered Off and the after-pick subtitle write do by @GLinnik21 in #706
  • route: the track memory's code gets its own modules; one sub_traits, one pick-changed rule, one sidecar commit (#698 follow-ups) by @GLinnik21 in #707
  • locales(be): the unseated Settings line uses Выберыце, matching the rest of the locale by @GLinnik21 in #711
  • locales(be): the choose verb is абраць everywhere by @GLinnik21 in #712
  • login: the no-server read-out offers Use another account by @GLinnik21 in #714
  • player: seek in place on webOS 5+ through LG's public Seek, no reload per seek (#568) by @GLinnik21 in #713
  • app: re-read Home's hubs after a playback once the stop has landed, not 800 ms later by @GLinnik21 in #710
  • Fonts: subset appfont-cjk.ttf to cmap-reachable glyphs so webOS 3/4 FreeType opens it (#628) by @GLinnik21 in #709
  • Text subtitles: decode legacy-encoded tracks (GBK/Big5/Shift_JIS/EUC-KR/…) per track with chardetng (#628) by @GLinnik21 in #708
  • player: BACK over the transport hides it instead of leaving the film by @dimitrije83 in #704
  • libass series 1/N: assperf instrumentation and make_ass_stress.py by @GLinnik21 in #715
  • media: text_ass converter and text_style mapping, pure and not wired (libass text subs, PR 5) by @GLinnik21 in #718
  • libass 2/n: render only on change (validity window, Normal/Ahead) and renderer reuse by @GLinnik21 in #721
  • appkit: player_hud reads the caption mapping from media text_style (libass PR 5a) by @GLinnik21 in #720
  • libass: libunibreak, face-growth patch, facade ABI 3 (PR 4 of the text-subtitle series) by @GLinnik21 in #717
  • libass 3/n: bundled Noto Sans Bold subtitle faces for 22 scripts (D6) by @GLinnik21 in #725
  • media: Source.origin, Text track headers, restyle and published alignment classes (libass text subs, PR 6a) by @GLinnik21 in #724
  • screens: ass_subtitles renders Text-origin frames full-screen and lifts bottom regions with the HUD (libass text subs, PR 6) by @GLinnik21 in #726
  • libass 5b: native goldens for the synthesized text style; MarginV trimmed to today's ink baseline by @GLinnik21 in #729
  • libass 7a: embedded text subtitle tracks render through libass by @GLinnik21 in #730
  • libass 7c: bucketed subtitle texture upload with glTexSubImage2D (gfx) by @GLinnik21 in #732
  • libass 7b: sidecar SRT/VTT render through libass; delete the plain-text sidecar path by @GLinnik21 in #734
  • route: gate post-playback refreshes on timeline_stop_landed (layer-1 view state 2/N) by @GLinnik21 in #716
  • player: the pump owns a seek made while paused, on every seek route by @GLinnik21 in #722
  • libass 8: the player screen stops drawing the old caption path by @GLinnik21 in #739
  • Tests: harden three flakes (DUMP arm leak, link-conditioner wire log, withdrawn related read) by @GLinnik21 in #743
  • View state: publish_view and ViewAt, show/season cascade (series PR 3) by @GLinnik21 in #719
  • libass 9: appkit deletes the old caption path by @GLinnik21 in #742
  • View state: a ViewLedger re-patches a read that a press overtook by @GLinnik21 in #723
  • libass 10: media deletes the embedded text-cue store by @GLinnik21 in #744
  • libass 11: docs describe the libass-only text subtitle path by @GLinnik21 in #745
  • View state 4/N: the read-back worker, the Facts patch, covered membership re-query by @GLinnik21 in #727
  • Tests: make the sidecar restyle test wait on its worker, not the clock by @GLinnik21 in #746
  • View state 5: stop record, immediate resume patch, held reconcile under the player, EOS fan-out by @GLinnik21 in #728
  • View state 6: Facts and Offset reach Search, Person, Collection and Detail's Related and collection tiles by @GLinnik21 in #731
  • View state: parent rows in the read-back (season and show facts) by @GLinnik21 in #733
  • View state 8: Detail folds into the view-state system (DetailReconcile) by @GLinnik21 in #736
  • net: a streaming HTTPS read for long-lived responses (layer-2 view state 1/6) by @GLinnik21 in #747
  • libass: simplify the text-subtitle series by @GLinnik21 in #749
  • Cards: animated landings with ghosts from the previous snapshot (10a) by @GLinnik21 in #737
  • Home: focus follows the show (10b) and the return hold (10c) by @GLinnik21 in #738
  • Home: quiet per-source refetch and visibility-gated staging (L2-3) by @GLinnik21 in #748
  • Server updates L2-5: re-read covered pages and on resume by @GLinnik21 in #751
  • gfx: remove the unused bucketed subtitle upload by @GLinnik21 in #752
  • Server updates L2-2: PMS SSE notification client, shipped off, owned servers only by @GLinnik21 in #753
  • Player: a screensaver that takes back the video decoder parks playback until the next key press by @frank-m in #756
  • Server updates L2-4: map PMS notifications to read-backs (ships off) by @GLinnik21 in #755
  • Starfish Load declares what is fed: a ms-timebase rate's own class, and a fixed quality's ceiling on start.mkv (#665) by @GLinnik21 in #697
  • Player: a reload while paused shows its first frame, and a paused idle player shows no Buffering spinner by @GLinnik21 in #750
  • base: worker threads carry their names in shipping builds by @GLinnik21 in #757
  • Player: a real stop's Starfish Unload runs off the frame that handled BACK by @GLinnik21 in #758
  • Player: a paused seek or reload re-pauses only once the video plane shows the frame by @GLinnik21 in #759
  • Server updates: turn PMS notifications on (owned servers) by @GLinnik21 in #761
  • Subtitles: add a Huge caption size above Extra large by @Yagz in #664
  • Player: the paused-frame preroll plays muted (StarfishMediaAPIs::setVolume) by @GLinnik21 in #762
  • Server updates: one simplify pass over the series (no behaviour change) by @GLinnik21 in #764
  • Server updates: simplify pass 2 — notify, stream read, off-frame release (no behaviour change) by @GLinnik21 in #766
  • AGENTS.md: gotchas from the server-updates series by @GLinnik21 in #763
  • Dependencies: Dependabot for cargo, Actions, pip and npm; generated crate notices by @GLinnik21 in #770
  • Dependencies: one manifest for every non-Rust dependency, no copied upstream code by @GLinnik21 in #777
  • Add Italian localization (it) by @Massisalo in #771
  • Player: dim the overlay and subtitles during HDR playback (#741) by @GLinnik21 in #782
  • input: OK under a transparent pointer arrives as a click; turn it back into OK by @dimitrije83 in #781
  • Dependencies: weekly bump PRs for ci/dependencies.json; C libraries in the dependency graph by @GLinnik21 in #785
  • Dependencies: harfbuzz -> 14.6.0 by @github-actions[bot] in #789
  • Dependencies: drop the copied SDL2/GLES2/KHR headers by @GLinnik21 in #790
  • Dependencies: updater tests use a frozen fixture manifest by @GLinnik21 in #792
  • Tools: Bump the node-tools group across 1 directory with 2 updates by @dependabot[bot] in #774
  • Dependencies: ffmpeg -> 9.0.2 by @github-actions[bot] in #786
  • Home: a hero that leaves the pool hands the billboard to its successor, never a bare frame by @GLinnik21 in #793
  • tv-session: background/foreground driver; notification-feed TV checks (c, e) by @GLinnik21 in #797
  • Dependencies: apply the Sentry Native patch strictly, never with fuzz by @GLinnik21 in #798
  • CI: Bump the actions group across 4 directories with 6 updates by @dependabot[bot] in #778
  • Onboarding: first-run pages use the default ambient ground, not the hero's colours by @GLinnik21 in #799
  • Tools: Bump the python-tools group across 1 directory with 2 updates by @dependabot[bot] in #772
  • Dependencies: freetype -> 2.15.0 by @github-actions[bot] in #788
  • Player HUD: Quality row says what is playing; Audio note names the real reason by @GLinnik21 in #796
  • Deps: Bump the rust-minor-patch group across 1 directory with 4 updates by @dependabot[bot] in #773
  • Player: the menu dim is neutral, not keyed from the item's UltraBlur by @GLinnik21 in #800
  • Dependencies: sentry-native -> 0.17.3 by @github-actions[bot] in #787
  • player: a still from the server's preview thumbnails floats above the knob while scrubbing by @dimitrije83 in #767
  • Enhancement: keep Boost available after picking an undrawable subtitle mid-play by @GLinnik21 in #808
  • tools: netloss-proxy, a fault-injecting TCP proxy for real-looking network loss by @GLinnik21 in #810
  • CI: report main's required checks on every pull request by @GLinnik21 in #813
  • Player: a key scrub waits for OK — click to confirm where to jump by @GLinnik21 in #809
  • Draw emoji in library and title names by @tiper in #804
  • Italian localization: land #783 (wire it, replace #771's uncompiled catalogs) by @GLinnik21 in #795
  • i18n: language registry — a locales/ directory is a language or a build error by @GLinnik21 in #801
  • i18n: keep technical strings English-only (diagnostics panel, verdict line, dev warnings) by @GLinnik21 in #806
  • Add European Portuguese (pt-PT) language by @tiper in #802
  • Build: stable Rust 1.99.1 for the ARM and host builds, no nightly or build-std by @GLinnik21 in #816
  • CI: deps-update owned() misreads a foreign branch under pipefail; netloss proxy test race by @GLinnik21 in #819
  • Dependencies: Dependabot bumps the pinned Rust toolchain by @GLinnik21 in #818
  • Build: link glibc libm ahead of the Rust staticlib so math calls use VFP by @GLinnik21 in #821
  • Claude settings: allow the release check on the pinned toolchain by @GLinnik21 in #823
  • Add German (de) as a UI language by @CE-Repo in #820
  • Watchlist: a plex.tv Watchlist tab, page, catalog page, Detail and menu controls by @GLinnik21 in #831
  • input: a click with no control under it is OK after D-pad navigation by @dimitrije83 in #803
  • Route: a remux declares the source frame rate in the Load by @GLinnik21 in #832
  • tools: make test-crate works on the stable toolchain by @GLinnik21 in #833
  • webOS 1-3: opt-in Interface resolution; native 1080p stays the default by @selfhealer-png in #666
  • CI: re-baseline the ARM binary size budget at 13,799,944 bytes by @GLinnik21 in #836
  • Locales: Hungarian (Magyar) UI language by @danzig666 in #835
  • HEVC: strip HDR10+ wherever it sits in an SEI NAL by @tiper in #822
  • Direct play: recover a plain-http body that ends early, goes silent or cannot be crossed by @tiper in #817
  • Dolby Vision: direct-play Profile 7, converted to 8.1 in-app by @RichiL10 in #825
  • Dolby Vision: declare Profile 10 on AV1, not only on HEVC by @tiper in #838
  • Player: a press that asks to play wakes a decoder-release park Playing by @frank-m in #834
  • Dolby Vision: keep the declaration when the server copies the video by @tiper in #839
  • agent guides: never write an ad-hoc mechanism when a shared one exists by @GLinnik21 in #844
  • Disk budget: inventory, eviction planner and a read-only report (deletes nothing) by @GLinnik21 in #846
  • build-gc --evict: carry out the disk planner's plan, and drive it from --auto by @GLinnik21 in #848
  • make test-hostsim and make check-nodef: managed in-checkout target dirs by @GLinnik21 in #845
  • glass: the ambient wash is applied at composite, so an easing wash no longer re-sources live glass by @GLinnik21 in #847
  • site: say plainly that the LG Content Store listing isn't available by @GLinnik21 in #852
  • Dependencies: sentry-native -> 0.17.4 by @github-actions[bot] in #850
  • Disk budget 3/6: the preflight makes room at every build entry by @GLinnik21 in #849
  • Library: Collections redesign (header row, Collections and Recommended pages, Under posters, scroll chrome) by @GLinnik21 in #843
  • Cards and captions: late art dissolves once per frame across glass walks; gliding captions fade at both edges by @GLinnik21 in #854
  • Frame dump: slow pages film their loading frames; fps:library-switch stops flipping on its own cycle's phase by @GLinnik21 in #855
  • Collection: closing a menu over the page no longer blanks every poster by @GLinnik21 in #856
  • Discover: one base for the person page and the Watchlist; a mock boot never reaches the real provider by @GLinnik21 in #857
  • Home: a key press no longer costs a late frame - key tables update in place, the catalog sync touches only changed rows, the hold band has hysteresis by @GLinnik21 in #858
  • Library: a key on a deep Recommended page no longer costs a late frame, and library-shelves-deep can pass by @GLinnik21 in #860
  • Cards: a released card lands at rest, and a resting card's interior skips the card math - held paging 52 -> 59 fps on the TV by @GLinnik21 in #861
  • drawmask: card parts (interior, ring, focus) for the TV, and --save-logs keeps the profiler counters by @GLinnik21 in #863
  • tests: app-tier route tests for #857-#861 (released cards at exact rest, deep shelves, Home and Recommended Detail return) by @GLinnik21 in #864
  • Cards: every released grid card lands on its own spring, so a held key no longer snaps the card it left by @GLinnik21 in #866
  • Captions: Under posters applies to every poster tile, a caption line shows only once its room is there, and Home rests like the Library by @GLinnik21 in #859
  • statics: no static mut owns heap - render caches are thread_local!, and a tree-wide gate refuses the class (the plx_ui test abort) by @GLinnik21 in #867
  • home: Down from the hero dives to the first shelf only, and a shelf keeps its offset at the hero by @GLinnik21 in #871
  • docs: LG Seller Lounge does not accept native apps by @GLinnik21 in #870
  • Recommended: arrive through the shared mechanisms, and BACK onto it no longer holds the dip's image by @GLinnik21 in #872
  • Library header: one gap between the controls, and Collections only with a known count by @GLinnik21 in #875
  • Hold hint: shown once per install, and the Detail season pill teaches it on a faster dwell by @GLinnik21 in #876
  • Detail: choosing an episode keeps the show logo; the season strip rests under it by @GLinnik21 in #877
  • Compatibility reports: a Discussions category, a form, and a list by @GLinnik21 in #881
  • Compatibility list: link the 2018 UK6570 report at its discussion by @GLinnik21 in #883
  • UI: a shared horizontal stack (hstack); the page header, crumb and Library name packer ride it by @GLinnik21 in #886
  • Hero: no name under a focused icon-only control by @GLinnik21 in #887
  • ui: hstack glyphs by ink, the filter read-out on one equal gap, control rows on HStack by @GLinnik21 in #888
  • appkit: hero row, HUD and info card on HStack; HUD gap is CONTROL_GAP (Q5), info card spaced like Detail (Q3) by @GLinnik21 in #889
  • ui: strips and top-bar tabs on HStack (HStack::widths), one placement pass per frame by @GLinnik21 in #890
  • screens: one heading+count idiom (Q4), facts dot pad (Q2), glyphs by ink in the tracks footer and Button (Q6) by @GLinnik21 in #891
  • Playback: a file whose audio is stored far ahead of its video starts and keeps playing (#600) by @GLinnik21 in #874
  • Continue Watching: one tile per show across servers, as the official client (#892) by @GLinnik21 in #894
  • Subtitles: the account rule reads forced/SDH the way the track menu does (#828) by @GLinnik21 in #895
  • ui: text runs and the remaining screen rows on HStack/Flow; still_line glyph by ink (Q6) by @GLinnik21 in #896
  • ui: one vertical stack — vstack facade, Item::before, AlertHead; y ladders moved, no pixel moves by @GLinnik21 in #901
  • Detail: Accessibility rows and episode meta keep one gap; Watchlist read-out uses the overlay's bands by @GLinnik21 in #903
  • watchdog: a main-thread hang names its loop phase (labels from the heartbeat marks and loop spans) by @GLinnik21 in #904
  • ui: the last hand-summed spacing sites stand on hstack/vstack by @GLinnik21 in #907
  • collections probe: the warm walk no longer holds its queue lock across the GET by @GLinnik21 in #908
  • docs: tv-lock prefix rule, the while-let lock trap, and span attribution of a stall by @GLinnik21 in #910
  • Force Direct Play: the audio refusal names the codec by @GLinnik21 in #898
  • Compatibility list: #900 and #906 by @GLinnik21 in #911
  • DTS: PMS's dca spelling direct-plays; Force Direct Play offers DTS only with a DTS table row by @GLinnik21 in #899
  • Continue Watching: the caption names the episode (S3 · E4 · 18m left) and is always shown by @GLinnik21 in #912
  • replay: re-record 1-boot-home-chip-grid for #912's Continue Watching caption by @GLinnik21 in #913
  • Player HUD: truncate long titles and reveal them while paused by @infectiousstupidity in #914
  • Open a Plex title from another app's launch params by @thewillwilson in #853
  • CodeQL: font slots are AtomicPtr tables; the late-audio test's pop guards with if by @GLinnik21 in #919
  • Detail: a held episode still is drawn once at the press dip; focus casts fade outside the face by @GLinnik21 in #920
  • Also available: a show or season copy shows no runtime (#814) by @GLinnik21 in #897
  • player: a film ends on the pipeline's end-of-stream by @tiper in #865
  • tests: a clip whose audio outlasts its video plays to the end by @GLinnik21 in #924
  • sim: the host sink reports the pipeline's end-of-stream by @GLinnik21 in #925
  • CI: track flaky tests per commit on plxnative.com/ci by @GLinnik21 in #926
  • Release notes and audit for v0.9.0 by @GLinnik21 in #922
  • Crash reports: Sentry release-health sessions (crash-free sessions per release) by @GLinnik21 in #930
  • Crash reports: detect and report main-thread freezes by @GLinnik21 in #932
  • Telemetry: per-screen frame health and repeated-key signal (route.left) by @GLinnik21 in #928
  • Release notes v0.9.0: the new opt-in report contents (#928, #930, #932) by @GLinnik21 in #936
  • Auto: an automatic Original recovery no longer needs a Plex client to fly by @GLinnik21 in #942
  • Test tooling: ABR calibrate skips quick stubs; FPS mock runs keep the panel on by @GLinnik21 in #943
  • Auto: a refused Original recovery is not asked again on the HLS route that refused it by @GLinnik21 in #944
  • tests: server-tier graders read the seek window and the client-drawn subtitle by @GLinnik21 in #947
  • tests: test_user.token_file supplies a managed-user token without an owner token by @GLinnik21 in #946
  • tests: a case whose app died fails, and keeps the device's stderr by @GLinnik21 in #948
  • release: 0.9.0 by @GLinnik21 in #952

New Contributors

Full Changelog: v0.8.0...v0.9.0