Windows is the released platform. macOS and Linux ship as previews.
Windows:
duja-setup-<version>.exeandduja-<version>-windows-x64.zip
are the released build. Developed and QA'd on real hardware.macOS (
.dmg) and Linux (.tar.gz) are unverified previews. They
are built, staged, checksummed, minisigned and provenance-attested by the same
pipeline as the Windows artifacts, and no one has ever run either one on the
hardware it targets. Every backend on those two platforms is verified by
types, pure tests, CI and cross-referenced primary sources only. Expect
defects that no amount of that catches.On Linux, run
dujactl doctorfirst. It prints the display server it
found, whether overlay dimming and gamma dimming are available this session,
and the displays it can see, so a missingi2c-devmodule or an unusable
compositor says so instead of looking like a hang. Two things it does not
tell you: whether your desktop has aStatusNotifierItemhost (without one
the tray icon simply never appears, and nothing reports that), and anything
about macOS, where the report is display information only.If a screen is left dim or discoloured, how you recover depends on the
transport, and it is worth reading before you need it:
- X11:
duja --restoreresets the gamma on every CRTC of your X screen.- Wayland:
duja --restorehas nothing to do and says so. It is not
broken - awlr-gamma-controlramp lives only as long as the process that
set it, so killing Duja is the recovery, and the compositor puts the
output back by itself even after a hard kill.- macOS:
duja --restoreis the only route, and there is no automatic
crash recovery behind it - the crash marker the other platforms write is
not written there. Both binaries live inside
Duja.app/Contents/MacOS/, so neither is on yourPATHwithout a symlink.Reports are the point of shipping these. A
quirk report
from a real Mac or a real Linux desktop is what moves those platforms off
preview. See SECURITY.md
for how to verify a download first.
[0.1.6] - 2026-08-08
Added
- app,dujactl: Open real macOS displays instead of stubbing them out (#90)
- platform,app: MacOS tray anchor geometry and the anchor-unit contract (#91)
- platform,app: Give the tray's OS hooks a macOS half (#99)
- app: Add the macOS gamma sink (#100)
- app: Run the tray on macOS (#102)
- xtask,ci: Package a universal Duja.app and ship it in a DMG (#104)
- core,panel,ddc,app: Give a macOS built-in panel its geometry (#105)
- core,ddc,panel,app: Drive linux monitors and backlights (#116)
- platform: Give linux an event pump, autostart and a browser (#118)
- dimmer: Decide what a linux session can dim, without naming one (#119)
- ddc,dujactl: Tell a linux user why their monitors are missing (#120)
- dimmer,panel,app: Give a linux display the rectangle it sits on (#122)
- dimmer: Give an x11 session a real overlay (#123)
- dimmer,app: Give an x11 session the sub-floor gamma channel (#124)
- dimmer: Put a layer-shell overlay on the wire (#130)
- dimmer: Give a wayland session its own gamma channel (#131)
- platform: Give the linux tray flyout a real x11 anchor (#132)
- app: Give linux the tray it has been building toward (#136)
- xtask: Give linux a shippable artifact (#140)
- app: Build the soak harness two perf budgets have cited since P4 (#146)
Changed
- app: Split the tray.rs god-module (#81)
- platform,app: Hoist the tray geometry into duja-platform
- app: Build the tray once the event loop is running (#94)
- core,ui,app: Drain the p6 checkpoint debt (#111)
- app: Give the tray a seam before it gains a second backend (#134)
Documentation
- status: Record the structural wave and refresh the test count (#83)
- status: Record P6 wave 2 and the two live-install defects (#97)
- ddc: Record why the macos edid skip must not consume a service (#108)
- Correct six release and support claims the p6 gate falsified (#110)
- status: Record the p6 gate results and close the phase (#112)
- adr: Decide the two reserved linux ADRs, and a third P7 forces (#115)
- deps: Decline x11rb 0.14 and record it as ADR-0023 (#129)
- Split the two files that had grown past being readable (#135)
- Re-triage what wave 5 changed, and drain the row it was told to (#137)
- Close p7 with the gate run and both releases held (#142)
- Plan p8, and say up front that v1.0.0 will be held (#143)
- Ship the ports as previews, and label them where a user looks
- Land what ADR-0024 made false, and shed 244 lines from plan.md
Fixed
- platform: Latch the macOS pump stop so a pre-run request is not lost
- app: Make --restore work on macOS, and say what it actually resets
- dujactl: Merge the built-in panel instead of listing it twice (#92)
- dujactl: Make doctor --report emit the report the docs promise (#95)
- dimmer,app: Fall back to overlay when Windows refuses a gamma ramp (#96)
- ddc,app: Stamp the mirror surface, not the display, on macOS (#98)
- dimmer,ui,app: Gate both gamma captions on the OS that has the limit (#103)
- ddc: Frame apple silicon ddc requests the way displays expect (#106)
- app: Stop a stale panic ack from greying a healthy display (#107)
- app: Re-assert gamma after the OS resets it (#109)
- platform: Harden the unix socket takeover and its state directory (#114)
- dimmer: An x11 overlay with no compositor is a black screen (#121)
- docs,ci: Repair 140 mojibake characters and a false lint rationale (#133)
- ui: A linux user was being told about a macos hardware quirk (#138)
- platform: Bound the x11 anchor now that it runs on the ui thread (#139)
- app: A clean quit no longer flattens gamma Duja never touched (#147)
- core: SECURITY.md promised a config size cap that never existed (#148)
- app: The soak printed to a console a release build does not have (#149)
Performance
- app: Recover 3.9 MB of binary, and gate it so it stays recovered (#144)