Skip to content

Darwin mediakeys#171

Closed
bjarneo wants to merge 2 commits intomainfrom
darwin-mediakeys
Closed

Darwin mediakeys#171
bjarneo wants to merge 2 commits intomainfrom
darwin-mediakeys

Conversation

@bjarneo
Copy link
Copy Markdown
Owner

@bjarneo bjarneo commented Apr 6, 2026

Extract a platform-agnostic MediaController interface from the MPRIS
integration so that media key support can be added per-platform without
modifying the core TUI code.

  • mediactl/ package: Controller interface (Update, EmitSeeked, Close),
    MainLoopRunner interface for controllers that need the main OS thread,
    and a self-registration registry via init()
  • MPRIS refactored to implement mediactl.Controller, self-registers via
    init() with blank import in main.go
  • TrackInfo and SetPositionMsg moved to shared packages (mediactl and
    internal/control) so platform code doesn't cross-import
  • Model uses []mediactl.Controller instead of *mpris.Service, with
    notifyMediaControllers() and emitSeeked() helpers replacing direct
    mpris calls
  • prog.Run() moved to a goroutine with mediactl.RunMainLoop() on the
    main thread, enabling macOS NSRunLoop (no-op on Linux)
  • Full macOS CGo scaffold: MPRemoteCommandCenter for receiving media
    key events, MPNowPlayingInfoCenter for Now Playing info, with change
    detection to skip redundant CGo calls on the per-second tick
  • Key handlers upgraded from notifyMPRIS() to notifyAll() so Lua
    plugins also receive state updates on keyboard actions
  • Notification hot path uses cached position/duration instead of
    re-acquiring the speaker lock

New:
Lock the main goroutine to OS thread 1 in init() and defer
MediaKeysInit to RunMainLoop so MPRemoteCommandCenter handlers
are registered on the correct thread for CFRunLoop delivery.

bjarneo added 2 commits April 6, 2026 09:04
Extract a platform-agnostic MediaController interface from the MPRIS
integration so that media key support can be added per-platform without
modifying the core TUI code.

- mediactl/ package: Controller interface (Update, EmitSeeked, Close),
  MainLoopRunner interface for controllers that need the main OS thread,
  and a self-registration registry via init()
- MPRIS refactored to implement mediactl.Controller, self-registers via
  init() with blank import in main.go
- TrackInfo and SetPositionMsg moved to shared packages (mediactl and
  internal/control) so platform code doesn't cross-import
- Model uses []mediactl.Controller instead of *mpris.Service, with
  notifyMediaControllers() and emitSeeked() helpers replacing direct
  mpris calls
- prog.Run() moved to a goroutine with mediactl.RunMainLoop() on the
  main thread, enabling macOS NSRunLoop (no-op on Linux)
- Full macOS CGo scaffold: MPRemoteCommandCenter for receiving media
  key events, MPNowPlayingInfoCenter for Now Playing info, with change
  detection to skip redundant CGo calls on the per-second tick
- Key handlers upgraded from notifyMPRIS() to notifyAll() so Lua
  plugins also receive state updates on keyboard actions
- Notification hot path uses cached position/duration instead of
  re-acquiring the speaker lock
Lock the main goroutine to OS thread 1 in init() and defer
MediaKeysInit to RunMainLoop so MPRemoteCommandCenter handlers
are registered on the correct thread for CFRunLoop delivery.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant