feat: taskbar media controls, startup performance, and UI polish#56
Merged
Conversation
Many sources (YouTube music videos especially) title tracks "Artist - Song" while reporting the artist separately, so the strip showed the artist twice. Drop the leading "Artist - " when the head matches the session artist, with normalised matching so channel noise (VEVO, - Topic, spacing) still lines up. Non-matching titles untouched.
Startup: - Defer notification register, Quick Controls hotkey window, and update check to a post-first-paint low-priority dispatch; move StartupSettingsApplier (WaveLink connect) onto the background init thread. - Gate the first navigation only on audio singletons + rules; seeding and the routing applier's first apply run ungated after. - Add an instant loading skeleton in MainWindow; make HomePage's loading state full-bleed/transparent (no inset card). Perf: - FileLogger holds one StreamWriter (AutoFlush) instead of open/close per line. - AudioEndpointService caches endpoints whose AudioEndpointVolume activation fails, so it stops re-throwing a COMException per dead endpoint each refresh. - Reuse the 20Hz TickAppMeters dictionary + per-card hash set instead of reallocating them. Storage: - Persisted data moves to %APPDATA%\Hoobi\Earmark, logs to %LOCALAPPDATA%\Earmark, both segregated per build channel (Dev/Prerelease subfolder; Release at base) via AppInfo.ChannelFolder. Installer: - Per-channel ARP name, install folder, registry key, and UpgradeCode so Dev/Prerelease/Release coexist as separate Add/Remove Programs entries; component GUIDs switched to auto; Manufacturer set to 'Hoobi' to match the MSIX PublisherDisplayName. Workflow exports EARMARK_CHANNEL for WiX. UI: - Mica Base (was BaseAlt) on MainWindow and QuickControlsWindow so the backdrop bleeds the wallpaper and matches Windows Settings. Also carries in-progress Now Playing divider edits from concurrent work in the shared tree (DeviceCardView, DeviceCard, AppSettings, PeakMeterOptions).
YouTube Music's auto-generated channels report the artist as "<Artist> - Topic". Drop that suffix from the displayed artist line. VEVO is left alone (no separator, so stripping yields "KanyeWest").
…whitespace, native smooth scroll, click-away/Escape dismiss
Replace the hand-built title-bar grid with the WinUI TitleBar control (matching WinUI Gallery): Tall height with caption buttons filling it, a built-in animated pane toggle, icon-less title/subtitle, and the update pill in the RightHeader slot (drops the manual caption-inset math). Add a back/forward history stack to NavigationService since pages are swapped as DI singletons (Frame.CanGoBack is never set). The back button stays visible and disables when there's nowhere to go; mouse XButton1/2 drive back/forward. Disabled back button no longer paints a square fill. Align each page's H1 title with the top of the first nav-rail item by zeroing the page content top inset.
Adds prev / play-pause / next buttons to the taskbar thumbnail toolbar (shown on hover) plus a playback badge on the taskbar icon, both driving the primary SMTC session via INowPlayingService.GetPrimary. The badge is the OS BadgeNotificationManager glyph on packaged builds and a SetOverlayIcon corner overlay on unpackaged builds (where the former throws). Only shown while the main window has a taskbar button.
A device card stretched up to match a taller sibling in its row shrank to its own content when its rules block expanded, instead of holding that height and growing past it. Both wrap layouts now remember the row baseline each card is arranged at (not its own collapsed desired height) and use it as the floor for a card that opts out of the baseline, so it grows for the expanded rules but never drops below its pre-expansion height.
NavigationService swaps DI-singleton pages via Content=, so NavigationThemeTransition never fired and the passed transition info was dead. Element Transitions (EntranceThemeTransition) only play on first realisation, so cached pages didn't animate on re-show. Drive an explicit fade + slide-up storyboard per swap instead, and add an ADR on the singleton-vs-Frame.Navigate decision.
Falls back to IAudioSessionControl::GetIconPath (parsing the @file,-id shell reference, env-expanded, negative index = resource ID) when neither the exe nor the process window yields an icon. Fixes the blank System Sounds chip, which is hosted by taskhostw.exe (no icon) but reports AudioSrv.Dll,-203.
Replace the Win2D Gaussian blur for the now-playing strip's low-res
artwork with an in-app AcrylicBrush overlay, so the compositor does the
blur. High-res art still fills sharp; only frosted (low-res) art gets the
acrylic, whose theme-aware tint/luminosity darkens in dark mode and
lightens in light. The scrim is dropped over frosted art to avoid
double-darkening.
- Decode, black-bar trim and crop now run on BitmapDecoder (no Win2D).
- Drop the redundant now-playing blur-mode setting end to end.
- Fix section dividers staying dark in light mode: use {ThemeResource}
borders instead of a converter that snapshotted the app default theme
(the app themes per-element via RootGrid.RequestedTheme).
The now-playing backdrop no longer needs Win2D, leaving the taskbar transport-button glyph -> HICON renderer as its only user. Port that to GDI+ (System.Drawing.Common 10.0.0, already pulled transitively by H.NotifyIcon) and remove the Win2D package plus its winmd WACK-workaround target. GDI+ Format32bppArgb is straight alpha, so the un-premultiply step is gone too.
The context-menu show/hide volume toggle moved into the Customise panel; its label/glyph/command and the host callback chain were the only consumers and are now dead.
Strip mode: the band has no bracketing hairlines (its filled edges are the separator) and keeps the natural section spacing instead of butting the rows above and below. Fill-card-background mode keeps the lighter over-art dividers around it like every other section. - Clip the fill-mode art + frost/scrim stack with one rounded Border so the corners no longer leak bright artwork pixels (per-layer rounding left the acrylic's corner short of the art's). - Trim the seek-bar bottom padding by 6px so it matches the top inset.
Per-device tri-state overrides (follow global / on / off) for the now-playing strip, fill-card-background, app chips, app-chip metering, volume meter, peak-hold indicator, and rules section. Each device card resolves its own effective options (override ?? global), so chips, strips, meter, and rules honour them with no binding rewrites; build and tick passes gate per card. Edited from the card Customise dialog under a collapsed Overrides section; each global toggle in Settings shows an InfoBar with the override count, affected device names, and a clear-all button.
The card's root Grid had no Background, so right-clicks in the gaps between child elements fell through to the host Border and bubbled ContextRequested to the page's backdrop flyout. A Transparent background captures the whole card surface in the Grid's subtree.
CleanTitle/CleanArtist now drop any ()/[] group containing "Official" (e.g. "(Official Video)", "[Official Music Video]"), so SMTC titles read cleanly. Title cleaning no longer requires a non-empty artist.
1 task
hoobio
added a commit
that referenced
this pull request
Jun 6, 2026
## Summary Updates the README to match Earmark's broadened scope after the perf/polish release (#56). The tool grew from per-app routing into a fuller audio companion (live mixer, now-playing with media controls, taskbar controls, quick controls), and the data location moved to %AppData%. ## Changes - Reframe the intro: audio companion built around the rules engine, not just per-app routing. - Regroup Features into Routing rules / Devices dashboard / Now playing & media / App. - Correct "Where state lives": data now lives in %AppData%\Hoobi\Earmark (was Documents), with a note on channel subfolders. ## Testing - [x] Docs only; rendered markdown reviewed.
hoobio
pushed a commit
that referenced
this pull request
Jun 6, 2026
🤖 I have created a release *beep* *boop* --- ## [1.0.0](v0.2.0...v1.0.0) (2026-06-06) ### ⚠ BREAKING CHANGES * snappier startup, relocate data to %APPDATA%, lighter Mica * settings and rules now live under %APPDATA%\Earmark. Config saved by a pre-1.0 build under the old location is not migrated and must be recreated after upgrading. ### Features * ✨ add Now Playing media strip to device cards ([#55](#55)) ([94ec4f2](94ec4f2)) * add per-device display overrides ([cb4efd1](cb4efd1)) * add Quick Controls overlay ([#52](#52)) ([b6dd130](b6dd130)) * add taskbar thumbnail media controls and playback badge ([cb4efd1](cb4efd1)) * adopt WinUI TitleBar control with working back navigation ([cb4efd1](cb4efd1)) * channel-aware MSIX identity and DisplayName per build channel ([5bd1957](5bd1957)) * collapse nav pane on backdrop tap ([cb4efd1](cb4efd1)) * hide taskbar playback indicator after 30s paused ([cb4efd1](cb4efd1)) * now-playing leniency grace window and artwork cross-fade ([cb4efd1](cb4efd1)) * refresh rule summaries during in-place session reconcile ([cb4efd1](cb4efd1)) * resolve session icons from the IconPath fallback ([cb4efd1](cb4efd1)) * slide-in animation for quick controls windows ([cb4efd1](cb4efd1)) * strip '- Topic' suffix from now playing artist ([cb4efd1](cb4efd1)) * strip redundant artist prefix from now playing titles ([cb4efd1](cb4efd1)) * taskbar media controls, startup performance, and UI polish ([#56](#56)) ([cb4efd1](cb4efd1)) * theme-aware card surfaces, Mica uniformity, and tighter page ([cb4efd1](cb4efd1)) ### Bug Fixes * animate page transitions on every nav, not just first load ([cb4efd1](cb4efd1)) * keep card at row height as a floor when rules expand ([cb4efd1](cb4efd1)) * lower audible threshold so faint audio keeps app chips lit ([cb4efd1](cb4efd1)) * mask black flash on quick controls open with backdrop-matched ([cb4efd1](cb4efd1)) * MSIX Store-readiness - brand icons, identity, and Quick Controls polish ([#58](#58)) ([5bd1957](5bd1957)) * quick controls scrollbar gutter, disconnected dimming, scroll ([cb4efd1](cb4efd1)) * refine now-playing band layout in strip and fill modes ([cb4efd1](cb4efd1)) * render real brand icons for the Start tile, taskbar, and tray in ([5bd1957](5bd1957)) * roll up hosted webview sessions to owner apps ([#50](#50)) ([8d162b6](8d162b6)) * show device card menu on right-click, not backdrop menu ([cb4efd1](cb4efd1)) * stop replaying the Quick Controls slide-in on device state changes ([5bd1957](5bd1957)) * strip Official tags from now-playing title and artist ([cb4efd1](cb4efd1)) * suppress the Quick Controls right-click context menu ([5bd1957](5bd1957)) ### Performance Improvements * snappier startup, relocate data to %APPDATA%, lighter Mica ([cb4efd1](cb4efd1)) ### Documentation * remove shipped customization panel feature doc ([8d162b6](8d162b6)) * rewrite README for the audio companion scope ([#57](#57)) ([89343fb](89343fb)) ### Miscellaneous Chores * remove custom smooth-scroll and update AGENTS.md ([#53](#53)) ([82b639f](82b639f)) ### Code Refactoring * ♻️ slim down the Quick Controls overlay ([#54](#54)) ([9ad54c6](9ad54c6)) * remove unused volume-controls toggle from DeviceCard ([cb4efd1](cb4efd1)) * render now-playing backdrop with in-app acrylic ([cb4efd1](cb4efd1)) * stop persisting and restoring window size ([cb4efd1](cb4efd1)) * unify card section dividers and modernise now-playing slider ([cb4efd1](cb4efd1)) ### Build System * drop Win2D, render taskbar icons via System.Drawing ([cb4efd1](cb4efd1)) ### Continuous Integration * emit an unsigned-namespace test MSIX for sideload testing ([5bd1957](5bd1957)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: release-please-hoobi[bot] <279189756+release-please-hoobi[bot]@users.noreply.github.com>
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
A batch of startup-performance work and UI polish across the home, now-playing, quick-controls, and taskbar surfaces. No rule-engine or schema changes.
Changes
%APPDATA%, lighter MicaTitleBarcontrol with working back navigation; collapsible nav paneIconPathfallback; faint audio keeps app chips litSystem.DrawingTesting
dotnet test -p:Platform=x64)Checklist
feat: add per-device display overrides
feat: hide taskbar playback indicator after 30s paused
feat: resolve session icons from the IconPath fallback
feat: add taskbar thumbnail media controls and playback badge
feat: adopt WinUI TitleBar control with working back navigation
feat: refresh rule summaries during in-place session reconcile
feat: collapse nav pane on backdrop tap
feat: theme-aware card surfaces, Mica uniformity, and tighter page margins
feat: slide-in animation for quick controls windows
feat: now-playing leniency grace window and artwork cross-fade
feat: strip '- Topic' suffix from now playing artist
feat: strip redundant artist prefix from now playing titles
perf!: snappier startup, relocate data to %APPDATA%, lighter Mica
fix: strip Official tags from now-playing title and artist
fix: show device card menu on right-click, not backdrop menu
fix: refine now-playing band layout in strip and fill modes
fix: lower audible threshold so faint audio keeps app chips lit
fix: animate page transitions on every nav, not just first load
fix: keep card at row height as a floor when rules expand
fix: mask black flash on quick controls open with backdrop-matched reveal cover
fix: quick controls scrollbar gutter, disconnected dimming, scroll whitespace, native smooth scroll, click-away/Escape dismiss
refactor: render now-playing backdrop with in-app acrylic
refactor: unify card section dividers and modernise now-playing slider
refactor: stop persisting and restoring window size
refactor: remove unused volume-controls toggle from DeviceCard
build: drop Win2D, render taskbar icons via System.Drawing
BREAKING-CHANGE: settings and rules now live under %APPDATA%\Earmark. Config saved by a pre-1.0 build under the old location is not migrated and must be recreated after upgrading.