Skip to content

Latest commit

 

History

History
142 lines (92 loc) · 11.3 KB

File metadata and controls

142 lines (92 loc) · 11.3 KB

Changelog

v1.4.4

Changed

  • Apple silicon only — release builds are now arm64-only (ARCHS[sdk=macosx*] = arm64, EXCLUDED_ARCHS[sdk=macosx*] = x86_64 in project.yml). Apple's September 2026 guidance lets apps that require macOS 13+ drop Intel, and macOS 27 runs only on Apple silicon. Intel Macs should stay on v1.4.3.

Fixed

  • DDC on Macs with more than one display port (Mac mini, Mac Studio) — the port a display is attached to is now discovered instead of assumed. Apple silicon publishes one DCPAVServiceProxy per physical port (HDMI, each Thunderbolt) even when the port is empty; with a single monitor Glint always talked to the first proxy, so a monitor on the "other" port (e.g. a Mac mini driving a DisplayPort monitor over Thunderbolt) saw every read fail and both rows showed Not applicable. Candidate ports are now ordered (last port that answered → EDID UUID match in the IORegistry → positional guess → unclaimed ports) and probed with a real DDC read until one replies; the winner is remembered per display and re-discovered on display reconfiguration. Writes go through the same resolution so they can't land on an empty or neighbouring port. Ports another connected display would claim positionally are skipped unless the EDID says otherwise, so a monitor without DDC can't fall through to its neighbour.
  • Two compiler warnings cleared — the menu-bar visibility observer now asserts main-actor isolation (MainActor.assumeIsolated) instead of calling MainActor-isolated methods from a nonisolated closure, and the CoreAudio device-name lookup receives its +1 CFString as Unmanaged instead of forming a raw pointer to a CFString variable.

Added

  • Settings → "Support Future Development" (MillerKit 1.2.0): a heart row in the Enjoying Glint? block that opens wemiller.com/support — GitHub Sponsors, Ko-fi, a one-time tip.

Build

  • MillerKit pinned at 1.3.0Package.resolved had stayed at 1.2.0 after project.yml moved to from: "1.2.2" (structural funding-link gate), so every xcodebuild re-resolved the package and rewrote the lockfile, leaving the tree dirty after any build. The pin now records what the requirement actually resolves to; 1.3.0 itself only registers Kern in MillerKit's shared suite registry, nothing Glint-visible.

Docs

  • Support future development — the landing page and README gained a support block with GitHub Sponsors and Ko-fi links (plus a link to every way to support at wemiller.com/support). Glint stays free: no ads, no tracking, no subscription

v1.4.3

Fixed

  • Settings no longer duplicates Support — removed the redundant “Open Support in Its Own Window” button; support/feedback stay inline via MillerKit’s SupportSection. The detachable support window remains available from the menu bar Support… item.

v1.4.2

Changed

  • MillerKit 1.1.0 — real version display, working privacy link, and shared About presentation

v1.4.1

Icon

  • Liquid-glass app icon — the monitor-and-sun glyph is now a transparent Icon Composer layer over a purple manifest fill (taken from the original artwork's gradient), so macOS renders the same glass depth (shadow + translucency) as the rest of the suite. Previously the layer was a fully opaque square that occluded the fill and read as a flat tile.
  • Scripts/generate-assets.swift now emits the transparent glyph layer alongside the .icns and DMG assets

v1.4.0

Localization

  • Fully localized in 8 languages — German, Spanish, French, Italian, Japanese, Korean, Portuguese (Brazil), and Simplified Chinese, across the menu bar UI, settings, and support window

Added

  • Dedicated support window — help, feedback, and the rest of the app family in one place (via the shared MillerKit support kit)

Build

  • MillerKit now resolves from GitHub (blaineam/MillerKit 1.0.0) instead of a local sibling checkout, so CI builds no longer depend on the machine layout

v1.3.11

Icon

  • App icon background fills the full square — removed pre-baked rounded corners and transparency from icon generation scripts (generate-assets.swift, generate-web-assets.swift); the design now extends edge-to-edge and macOS applies its own squircle mask, eliminating visible transparent corners in Finder, Dock, and Spotlight

v1.3.10

Build

  • App icon now sourced from the asset catalog — removed the post-build .icns injection from Scripts/build-dmg.sh; the icon now comes exclusively from Assets.xcassets/AppIcon.appiconset as compiled by actool, eliminating a duplicate icon source that could drift from the bundled catalog
  • project.yml version alignedCFBundleShortVersionString had drifted to 1.3.8 in project.yml while shipped builds were 1.3.9; both project.yml and Info.plist are now in sync

v1.3.9

Icon

  • Refreshed app icon to match Apple's macOS guidelines — removed the 10% inset that was making the squircle float in extra padding, and scaled the monitor-with-glint logo up to fill the icon properly; affects the in-app icon, the DMG installer, and all web/portfolio icons
  • Bundle plist version aligned — the Info.plist CFBundleShortVersionString had drifted to 1.3.2 across several releases; now correctly reflects the released version

v1.3.8

  • Fix Swift 6 strict concurrency errors: Add @MainActor annotation to promptAccessibility() and wrap the OSD fade-out completion handler with MainActor.assumeIsolated to satisfy Sendable closure requirements
  • Runtime API resolution for future macOS resilience: IOAVService (Apple Silicon DDC) and DisplayServices (built-in brightness) are now resolved at runtime via dlsym/dlopen instead of link-time binding. If Apple removes or renames these private symbols in a future macOS, Glint still launches and falls back to IOKit APIs instead of crashing on startup
  • Runtime transport detection: DDC transport selection (IOAVService vs IOFramebuffer) is now based on runtime symbol availability instead of compile-time #if arch(arm64), making the app resilient to future hardware changes

v1.3.7

  • Write-only volume mode: New toggle in Settings that skips DDC volume reads entirely — initializes at 50% and tracks volume in memory, sending only DDC writes. Fixes monitors (e.g., some LG displays) where DDC volume reads always fail but writes work fine
  • Volume adjustment falls back to write-only automatically when ddc.adjust fails and the setting is enabled

v1.3.6

  • Exponential backoff DDC reads: Failed reads now retry up to 3 times with exponential backoff (100ms, 200ms, 400ms), fixing volume reads that fail after brightness reads on rate-limited LG monitors
  • Default max volume/brightness to 100: If a monitor reports a current value but a zero or missing max, Glint defaults max to 100 instead of showing broken sliders
  • Smart key interception: Brightness and volume keys are only intercepted when DDC successfully detected that capability on startup. If DDC volume reads fail, volume keys pass through to macOS as normal
  • Always intercept override: New per-control "Always intercept" toggles in Settings for monitors that respond to DDC writes but not reads

v1.3.5

  • Serial DDC queue: All I2C operations (reads and writes) now go through a serial DispatchQueue, preventing concurrent bus access that caused LG monitors to drop commands. Every operation enforces a 100ms cooldown before hitting the bus
  • Startup reliability: DDC retry loop no longer re-reads values that already succeeded — if brightness reads OK on the first attempt, only volume is retried. Retry delay increased from 100ms to 500ms to give LG monitors more recovery time
  • TTL read cache: 2-second read cache avoids hammering DDC reads on rapid key presses. Cache is updated after every successful write so subsequent adjustments stay accurate without extra reads

v1.3.4

  • TTL read cache for DDC: Adds a 2-second read cache to avoid hammering DDC reads on rate-limited monitors (e.g., LG). Rapid key presses reuse the cached value and write immediately; on cache miss a real DDC read is performed with an I2C settling delay before writing. Cache is updated after every successful write so subsequent adjustments stay accurate without extra reads
  • Volume adjust uses ddc.write: Volume adjustment now uses direct ddc.write calls with cached reads instead of raw ddc.read per keystroke, fixing volume control failures on monitors that rate-limit DDC commands

v1.3.3

  • Fix volume adjustment: Use ddc.read then ddc.write for volume changes instead of ddc.adjust which added an unnecessary 50ms delay between read and write

v1.3.2

  • DDC read retries on startup: Initial display refresh now retries DDC reads up to 3 times with 100ms delays — fixes "N/A" sliders on monitors that need time to respond after connection
  • I2C bus settling delay: Added 50ms delay between DDC read and write in adjust commands — fixes monitors (e.g., some LG displays) that drop writes arriving too quickly after a read
  • Adjust returns max value: DDC adjust now updates both current and max values in the display state, ensuring sliders and OSD always have correct ranges

v1.3.0

  • Debug logging: Optional debug log that records DDC commands, audio routing decisions, display detection, and I2C results to ~/Library/Application Support/Glint/debug.log — toggle in Settings with a button to reveal the log in Finder
  • Better audio/display name matching: Partial word-level matching for audio device names against display names (e.g., "LG HDR" matches "LG HDR 4K (2)")

v1.2.3

  • USB-C hub audio detection: Volume keys now correctly use DDC for monitors connected through USB-C hubs/docks by matching the audio device name against connected display names

v1.2.2

  • Fix About version: Settings now reads version from the app bundle instead of a hardcoded string

v1.2.1

  • Mute OSD: Mute key now shows a muted speaker icon when muting and the volume level when unmuting
  • Accessibility restart notice: Alert and settings view now inform users that Glint must be relaunched after enabling Accessibility access

v1.2.0

  • Smart volume routing: Volume keys now automatically use DDC when audio output is HDMI/DisplayPort, and system volume when using built-in speakers, headphones, USB, or Bluetooth — switches gracefully when you change output devices
  • Audio-aware mute: Mute key targets the correct output based on the active audio device

v1.1.0

  • Cursor-aware brightness: When sync is off, brightness keys now only adjust the display the cursor is on
  • Proper display sync: When sync is on, the first brightness key press forces all displays (built-in + externals) to match the cursor display's brightness before adjusting them together
  • Menu bar slider sync: Dragging a brightness slider in the menu bar popover now propagates to all displays when sync is enabled
  • OSD on correct screen: The brightness overlay now appears on the screen the cursor is on

v1.0.0

  • Initial release
  • DDC/CI brightness and volume control for external displays via keyboard media keys
  • Sync mode to keep built-in and external displays in lockstep
  • Subtle pill-style OSD overlay
  • Invisible mode (hide from menu bar and dock)
  • Launch at login
  • Menu bar popover with per-display brightness and volume sliders