KiwiDesk changelog
Back to KiwiDesk19 releases since August 2026 · GitHub releases, checked Oct 26, 2026
3.2.0Latest
KiwiDesk is built in free time and is free to use for everyone. If it has earned a place on your Mac — a star on GitHub, a word to someone who tiles, or a coffee through GitHub Sponsors or Ko-fi — every one of those keeps it fruity.
KiwiDesk 3.2.0 lets each bar hide until you need it, keeps your setup the same on every Mac, and lets one layout or Space tile smaller windows than the rest.
Spotlight
- Bars that hide until you need them — Set each bar to Always, Auto or Hidden; ⌃⌥G and ⌃⌥H show a hiding one. {setting:settings.spaceBarStyle.visibility (master)} {symbol:menubar.arrow.up.rectangle}
- KiwiVision fades in — The window you leave now eases into the dim; choose how fast. {setting:appWide.visionFadeDuration} {symbol:binoculars}
- The App Bar shows what's on your screen — Windows you can see are lit; ones cut off or covered are dimmed. {symbol:eye}
- Your setup on every Mac — Keep KiwiDesk in step through iCloud Drive or a folder you pick. {setting:UserDefaults.general.syncFolder} {symbol:icloud}
- Smaller tiles where you want them — Give a layout, or a single Space, its own minimum width × height. {setting:settings.minWindowSizes (master)} {symbol:ruler}
- Take back one change at a time — Every unsaved change in Settings now has its own ↺ to undo it. {symbol:list.bullet.rectangle}
New
- New: each bar can now hide until you reach for it. KiwiShelf ▸ Show sets the Space Bar and the App Bar to Always, Auto (a thin mark that opens when the pointer rests on it) or Hidden, which ⌃⌥G and ⌃⌥H show over your windows. A hiding bar slides in from the screen edge, or grows, unfolds or fades in as KiwiShelf ▸ Reveal picks, with its timing under KiwiShelf ▸ Durations. Your bars stay as they were, and updating adds the two keys where they're free; change them in Shortcuts & Gestures ▸ Show & hide.
- New: keep your setup the same on every Mac. General ▸ Sync across Macs picks iCloud Drive or a folder: Compare and Copy… shows both sides before you keep one, and Keep in sync automatically copies each change across, asking you only when both Macs changed the same setting.
- New: windows can now tile smaller in one layout or Space than in the rest. Layout Defaults ▸ Minimum window size takes a width and a height, for every layout at once or each apart, and Spaces ▸ Customize… gives one Space its own; your current size carries over to every layout.
- New: the App Bar now shows which windows you can see. A window fully on screen is lit, one cut off by the screen's edge or covered by another is dimmed, and in Scrolling a cut-off column is marked on the side that still shows.
- New: resting the pointer on a Space the Space Bar shows as a count now lists its windows; click one to go straight to it.
- New: with KiwiVision on, the window you leave now fades into the dim instead of dimming at once. Fade duration and Fade curve are under KiwiVision ▸ Dim and blur, and a duration of 0 makes it instant again.
- New: Settings can now take back one change at a time. Every unsaved change has its own ↺, a shortcut you moved goes back together with the one it displaced, and Revert now also undoes changes made by a shortcut, the command line or an AI app.
Improved
- Grid columns and rows can now be resized with the size keys and by dragging the edge between two windows, like every other tiled layout.
- Moving focus past the last window now wraps to the first in Scrolling, Monocle and Track for a new setup or an init.lua that doesn't set it; a profile you've saved keeps what it had, and Layout Defaults ▸ Wrap focus changes it.
- Switching between busy macOS Desktops is now quicker: the focus border, the bars and your shortcuts no longer wait while KiwiDesk looks over the windows that arrived.
- The Hyper key card now has one Shortcuts use: ⌃⌥ | ✦ switch that moves every KiwiDesk shortcut onto Hyper, or back, in place of the one-time offer. When a key remap another app left behind keeps Hyper off, the card now names it, and offers Take Over… when it's the same remap KiwiDesk would set.
- KiwiHub's shortcuts side (⌃⌥K) now lists the shortcuts your init.lua binds, instead of only saying that init.lua manages them.
- The bars now animate with Reduce Motion on, as the Dock does: a hiding bar still slides in and the bars still expand and move into place, while windows keep moving without animation; the Animations card now says when Reduce Motion is the reason it's greyed.
- Every colour now lives in Looks & Animations ▸ Colors & glass, which replaces the Advanced Colors page, and the KiwiHub, KiwiShelf and KiwiVision keys now share one Show & hide card at the top of Shortcuts & Gestures.
Fixed
- With Reduce Motion on, windows now land at once and at their full size: a Stack reflows right after you open or close a window, and a window moved to another screen no longer keeps a wrong size.
- With the Dock set to hide, clicking it again no longer moves KiwiDesk's focus to the Dock's screen while the app you picked stays in front on another.
- A browser extension's popup, like Bitwarden's, no longer closes as it opens when the browser's App Rule points at a Space that isn't showing.
- With a Hyper key set but no shortcut using it, pressing the key no longer beeps; KiwiDesk now says that no shortcut uses Hyper.
- Switching from a Space with an App Bar to one without no longer leaves a dark strip past the Space Bar.
- Clicking beside a bar that doesn't fill its edge now reaches the window under it instead of landing on the bar's empty strip.
- The App Bar's floating mark now stays visible on a Boxed bar over light windows: it draws in full ink with a soft edge, and the gap before it marks the break.
- NoMachine's empty second window no longer takes a tile of its own beside the real one.
Lua & CLI
- If you write your own Lua config: space_bar.set_enabled is now space_bar.set_visibility, and monocle.set_app_bar_enabled and scroll.set_app_bar_enabled are now set_app_bar_visibility, each taking always, auto or hidden; animations.set_shelf_duration and animations.set_on_shelf are now animations.set_expand_duration and animations.set_on_expand, and saved configs move over on their own; each old name is refused with its replacement. set_min_window_size now takes a width, an optional height and an optional layout, and a single number still works.
- New: list_windows gives every window's frame, screen and whether it's in view, and focus_window <id> focuses one by id, switching Space if it has to; list_monitors now gives each screen's position and the area its Space lays windows out in.
- New: swap now takes window ids: swap <id> trades the focused window with any window, on another Space or screen too, swap <id> <id> trades two windows, swap <dir> <id> swaps a named window with its neighbour, and swap_here <id> brings a window into your slot.
- New verbs for this release's settings: space_bar.toggle_reveal, app_bar.toggle_reveal, kiwishelf.set_reveal_style (slide, grow, unfold or fade), kiwishelf.set_reveal_timeout, animations.set_reveal_duration, set_min_window_size_override, grid.set_column_weight, grid.set_row_weight, kiwivision.set_fade_duration and kiwivision.set_fade_curve. From the command line, revert_settings takes back unsaved live changes, take_over_hyper_remap adopts a matching leftover remap, and get_config_status reports Config Issues and the sync status, which kiwidesk mcp now reads to say why a change can't be kept.
- fix(bars): the shelf's glass follows its plate when it shrinks
- chore(site): sync release notes and feed for v3.1.0
- test(vision): count plate orders per shown screen
- feat(settings): revert one change from its diff row
- feat(settings): search results sized to the field, on Liquid Glass
- feat(bars): a collapsed Space peeks its apps on hover
- feat(bars): the App Bar shows visible, partly visible and hidden windows
- fix(tiling): place windows right under Reduce Motion
- feat(config): keep this Mac's files out of the config folder
- fix(bars): fit a glass's content on every resize of the glass
- feat(config): keep each Mac's Desktop memory in machine.json
- fix(bars): settle every gliding box in GlassBox.place
- perf(ax): read a Desktop switch's window lists off the main actor
- perf(ax): adopt a Desktop switch's arrivals from the off-main read
- fix(settings): keep the shut gestures strip's pictures still
- chore(agents): batch guard-prover mutations under one gate slot
- feat(config): bind Desktops by profile id, kept in bindings.json
- feat(config): latch a newer-format store read-only
- fix: round empty collapsed Space chip; shed back chip word when narrow
- feat(vision): ease the window focus leaves into KiwiVision's dim
- feat(bars): auto-hide the shelf until you reach for it (#761, Core)
- feat(config): compare and copy a setup with a sync folder
- fix(settings): fit icon picker cells to their grid column
- feat(settings): Advanced as action rows; compact controls trail; on/off is a checkbox
- fix(commands): ignore Dock clicks in the display follow
- chore(bar): update sketchybar-app-font to v3.0.11
- feat(config): keep a sync folder in step automatically (#2324 slice 3)
- feat: minimum window size per layout, as width × height
- fix(settings): line up every unchecked override readout
- feat(bars): each bar's own visibility — Always, Auto or Hidden
- feat(settings): fold the product shortcut cards into Show & hide
- feat(layout): give a Space its own minimum window size
- feat(settings): one control, one change in the pill and the sync sheet
- docs(settings): cite the icon cells' no-hover ruling
- feat(bars): give each hiding bar its own hover band
- feat(layout): size grid columns and rows by keyboard and mouse
- feat(config): one stored shortcut base every default row reads
- feat(settings): fold Advanced Colors into Looks & Animations
- feat(settings): one Shortcuts use switch in the Hyper key card
- refactor(settings): name the colour types after Colors & glass
- docs(site): point the guide tour at Colors & glass
- feat(site): read the voices from Sanity at build time
- fix(keys): name the mapping that refuses the hyper remap
- feat(settings): move a left-out shortcut's tombstone with the switch
- feat(settings): revert all also reverts live changes
- ci: catch a warning inside a macro expansion
- fix(state): an App Rule files no buttonless popup
- feat(keys): take over a leftover hyper remap on consent
- feat(settings): revert one binding, layer or lens from its row
- feat(ax): give a buttoned system dialog no escape
- fix(ax): count a window's own title element as no shadow child
- fix(keys): catch hyper with no shortcut and say why
- feat(shortcuts): list init.lua's shortcuts in KiwiHub
- feat(settings): name the windows Automatic floating floats
- feat(mcp): read Config Issues and the sync status, name a newer file
- feat(layout): wrap focus by default
- feat(commands): list window frames and focus a window by id
- chore(localization): translate the 3.2.0 strings
- fix(settings,bars): 3.2.0 eyeball fixes
- feat(bars): rework hiding — slide in from the edge, clicks pass through the empty shelf
- fix(settings): drop mouse moves while a popover hangs from Settings
- feat(settings): one glass surface for every Settings popover
- fix(bars): 3.2.0 eyeball nits — mark hover size, float mark weight, icon hover
- docs(roadmap): next on my list as of the 3.2.0 cut
- docs: owe the 3.2.0 cut its docs
- docs: leave the full suite of a PR-gated change to CI
- feat(commands): swap windows by id, across Spaces and screens
- fix(keys): take over a Hyper remap beside an identity entry
- feat(bars): unfold and fade reveals, one reveal duration, motion under Reduce Motion
- chore(release): stamp version 3.2.0
3.1.0
KiwiDesk is built in free time and is free to use for everyone. If it has earned a place on your Mac — a star on GitHub, a word to someone who tiles, or a coffee through GitHub Sponsors or Ko-fi — every one of those keeps it fruity.
KiwiDesk 3.1.0 adds one key to put a Space's window sizes back, and Settings now records Hyper shortcuts.
Spotlight
- Window sizes back in one key — Resized for a moment? ⌃⌥R returns the Space to your profile's sizes. {setting:keybinding.reset_sizes} {symbol:rectangle.split.3x1}
New
- New: ⌃⌥R puts back the sizes in the Space you're on — every window you resized there, by key or by dragging, returns to what your profile set. Updating adds the key where it's free and the action has no shortcut yet, as ✦R if you moved your letter shortcuts to Hyper; change or remove it in Shortcuts & Gestures ▸ Size & float.
Improved
- Switching to a Desktop that loads its own profile is now quicker, without the brief stall it could have on the way in.
Fixed
- With a Hyper key set, Settings now records Hyper shortcuts too: they already worked from init.lua and the CLI, but recording one in Settings kept only the key. Now holding the Hyper key adds ✦.
- docs(site): bring the landing, guide and compare pages up to 3.0.0 (merge after v3.0.0 publishes)
- chore(site): sync release notes and feed for v3.0.0
- chore(plugin): give the plugin the app icon for its listing
- feat(keys): Reset sizes in this Space on ⌃⌥R
- docs(guide): list KiwiVision's default key
- docs(limitations): a float stays under the window you focused
- perf(desktops): a bound Desktop switch sweeps its apps once
- chore(skills): the fixed desk is exactly fifteen windows
- fix(settings): record a held Hyper key in the shortcut recorder
- chore(release): stamp version 3.1.0
3.0.0Big update
KiwiDesk is built in free time and is free to use for everyone. If it has earned a place on your Mac — a star on GitHub, a word to someone who tiles, or a coffee through GitHub Sponsors or Ko-fi — every one of those keeps it fruity.
KiwiDesk 3.0.0 brings KiwiVision for focus, KiwiHub for windows and shortcuts, a layout cycle, and setup by asking your AI app.
Before you update: Space switches no longer slide — they're instant, and a screen without a Space Bar names the Space for a moment. The menu bar's Layout, Switch Profile and View Shortcuts… rows are now one Open KiwiHub… row.
Spotlight
- Everything but your focus fades back — ⌃⌥V dims everything else; a lens keeps the apps you pick clear. {setting:appWide.visionLenses} {symbol:binoculars}
- One panel for windows, shortcuts and layouts — ⌃⌥J finds a window, ⌃⌥K your shortcuts, ⌃⌥L a layout, profile or lens. {setting:keybinding.show_shortcuts} {symbol:macwindow}
- Step through your layouts — ⌃⌥C moves the Space you're on to its next layout, ⌃⌥⇧C back. {setting:config.modeCycle} {symbol:rectangle.3.group}
- Set KiwiDesk up by asking your AI app — Add it to Claude Desktop in a click; other AI apps get a setup prompt. {setting:(action) ai.setup.desktop} {symbol:brain.head.profile}
- Hold one key instead of several — Make Caps Lock or another key Hyper; move ⌃⌥ letter shortcuts to it. {setting:appWide.hyperKey} {symbol:capslock}
- Focus follows the pointer — Rest the pointer on a window to focus it; off until you turn it on. {setting:settings.mouse.hoverFocus} {symbol:cursorarrow}
New
- New: KiwiVision (⌃⌥V) dims and blurs everything but the window you're in. Settings ▸ KiwiVision sets how much, whether the wallpaper or the current app's other windows stay clear, which apps are never dimmed, and whether macOS switches to Dark while it's on.
- New: KiwiVision lenses keep the apps you pick clear, each on its own shortcut and in the profiles you choose; while one is on, KiwiDesk's focus keys stay on those apps. Make one with New Lens… in Settings ▸ KiwiVision.
- New: KiwiHub, one panel on ⌃⌥J, ⌃⌥K and ⌃⌥L. Jump to any window by typing its name (⇧↩ brings it to the Space you're on), see every shortcut, or pick a layout, profile or lens for the Space under the pointer; Tab steps between the three.
- New: ⌃⌥C switches the Space you're on to its next layout and ⌃⌥⇧C to the previous one, with a moment's picture of the cycle. Choose the layouts it walks under Shortcuts & Gestures ▸ Layout ▸ Layouts to cycle; it starts with BSP, Scrolling and Floating.
- New: set KiwiDesk up by asking your AI app. Settings ▸ AI adds KiwiDesk to Claude Desktop in one click or copies a setup prompt for Claude Code, Cursor or Codex, with ready-made prompts for your Spaces, a new look, app rules or a move from another window manager; setting changes stay temporary until you say keep.
- New: focus can follow the mouse — rest the pointer on a window and it takes the focus. Off by default; turn it on under Shortcuts & Gestures ▸ Mouse & trackpad ▸ Focus and the pointer.
- New: a Hyper key. Shortcuts & Gestures ▸ Hyper key turns Caps Lock, a modifier (left and right apart) or an F-key into an extra modifier no app uses, without Input Monitoring, and offers to move your ⌃⌥ letter shortcuts and Go to Desktop keys onto it. Quitting KiwiDesk gives the key back.
- New: a What's new link in Settings Home's footer opens the notes of any release since 2.0.0.
Improved
- Space switches are now instant and no longer slide; on a screen without a Space Bar a plate names the Space you arrived on for a moment. Turn it off under KiwiShelf ▸ Show ▸ Show the Space after a switch.
- A Monocle Space no longer flips a card when focus moves: the next window comes straight to the front, and the two flip settings are gone.
- The menu-bar menu now has one Open KiwiHub… row in place of Layout, Switch Profile and View Shortcuts…; it opens KiwiHub on its Layout, Profile and KiwiVision lines.
- Updating now adds ⌃⌥J, ⌃⌥L, ⌃⌥C, ⌃⌥⇧C and ⌃⌥V wherever the key is free and the action has no shortcut yet; change or remove them in Shortcuts & Gestures. ⌃⌥K still opens your shortcuts, now as KiwiHub's middle side.
- Scrolling and Monocle have new symbols in the Layout menu, the Space Bar and KiwiHub, so the two no longer look alike.
- A look now carries your animations too, so changing them on the shared look reaches every profile that wears it.
- Settings looks and responds more consistently: every button, palette, chip and menu lifts grey under the pointer, searchable lists move one kiwi highlight with both the pointer and the keys, and the font and app pickers match macOS's own pop-ups.
- Settings now lists changes made from outside it, by a shortcut, the command line or an AI app, under Live, not saved in the save pill, and Save no longer puts back a change made while Settings was open; Keep saves them into your profile.
Fixed
- An app that takes a few seconds to start, like Word, Xcode or VS Code, now takes you along to its App Rule's Space.
- Floating windows now stay above the tiles after a Space Bar or App Bar click or a keyboard focus move, and the focus border no longer slips under a floating window or goes missing on a floating sticky one.
- With the menu bar shown on hover, the window you were in no longer flickers while the pointer rests at the top of the screen on macOS 27.0.1.
- A shortcut on ⌃1 to ⌃9 now warns that macOS's Switch to Desktop shortcut takes that key.
Lua & CLI
- If you write your own Lua config: show_shortcuts is now kiwihub.show("shortcuts"), the slide's animations.set_on_space_change, animations.set_space_change_duration and set_space_switch_liquid_glass give way to set_space_cue, and animations.set_on_monocle_focus and animations.set_monocle_flip_duration are gone. Each old name is refused with its replacement, and shortcuts saved in Settings are renamed for you.
- New verbs: kiwivision.*, look.*, app_rule.*, shortcut.*, explain_window and explain_app, move_here, set_hyper_key, mouse.set_hover_focus and mouse.set_hover_focus_delay; kiwidesk mcp serves them to AI apps.
- kiwidesk completion zsh|bash|fish and kiwidesk watch are new, subscribe --reconnect survives a relaunch, and an app verb given an app's name now suggests its bundle id.
- chore: bring main into release/3.0.0
- feat(commands): add cycle_mode and the mode_cycle list
- fix(commands): spell cycle_mode's back step prev, listed first
- feat(profiles): add a per-profile mode_cycle override
- feat(commands): seed the layout cycle on ⌃⌥C / ⌃⌥⇧C with a Layout shortcuts group
- fix(gui): line up the Open applications reach column
- feat(commands): add show_layout_picker, the layout menu at the pointer
- feat(commands): seed the layout picker on ⌃⌥L
- feat(commands): show the cycle list after cycle_mode
- refactor(profiles): apply the behaviour overrides through one helper
- feat(gui): edit the layout cycle in Settings ▸ Shortcuts ▸ Layout
- feat(animation): pick how a Space switch shows itself
- chore: bring main into release/3.0.0
- feat(app): add Jump to window's rows, search and actions
- chore: bring main (2.3.0) into release/3.0.0
- feat(commands): add move_here, one window of an app moved here
- feat(gui): add the Jump to window panel
- feat(keys): seed Jump to window on ⌃⌥J
- feat(looks): animations join the shared look
- feat(gui): say how monocle differs from scrolling
- chore(site): sync release notes and feed for v2.3.1
- feat(animation): make a Space switch instant and drop the slide
- chore: bring main (2.3.1) into release/3.0.0
- fix(gui): key panels hand focus back cleanly
- feat(jump): pick a layout from the Jump to window panel
- feat(animation)!: remove the Monocle focus flip
- feat(commands): an app verb's refusal names the bundle id
- feat(gui): shortcut rows say what the key does
- fix(focus): return a menu-bar reveal's focus once the bar hides
- chore(agents): split the §5 table into per-subsystem sections
- chore: sync main into release/3.0.0 (§5 split, #2250)
- fix(gui): Monocle story steps the fan forward
- fix(focus): follow a slow cold launch into its app rule's space
- feat(gui): shortcuts join the key panel as its middle side
- test(ax): park the adoption heal's re-arm before counting its reads
- docs(limitations): a reopened app can switch Desktops
- feat(vision): KiwiVision's dim plate and its toggle
- feat(cli): add kiwidesk mcp, a stdio MCP server
- feat(vision): KiwiVision dim and glass blur
- feat(cli): keep an MCP session's setting changes
- feat(vision): switch the system appearance while KiwiVision is on
- feat(settings): add the AI page for kiwidesk mcp
- fix(service): refuse to install from a translocated copy
- feat(commands): name the key panel KiwiHub, one kiwihub.show verb
- feat(looks): add the look.* verbs
- test(settings): tie the AI grey to its button, the caption to its row
- feat(mcp): add the looks tool and the Make a new look prompt
- feat(settings): add the KiwiVision page and store its settings
- feat(app-rules): add the app_rule.* verbs and keep their rules
- refactor(borders): extract the WindowServer watch out of BorderManager
- feat(shortcuts): add the shortcut.* verbs
- feat(keys): add a Hyper key held through an F18 remap
- feat(settings): add the Hyper key recorder row
- feat(mcp): add the app_rules tool and the app rules and migration prompts
- fix(borders): ring a focused floating sticky visitor
- refactor(os): move the WindowServer event pump into OS
- feat(mcp): add explain_window, explain_app and the diagnose_window tool
- feat(vision): veil floats above the focused window
- fix(borders): keep the focus ring and floats on top after a focus change
- fix(vision): drop the float veils, dim a float as it lands
- fix(tests): never let a test run move the user's real windows
- feat(keys): offer to move the ⌃⌥ letter shortcuts to Hyper
- feat(vision): keep the wallpaper clear through a plate mask
- feat(vision): keep the current app's other windows clear
- fix(tests): never boot a test core
- build(site): update astro to 7.4 and patch dependencies
- build(lua): update vendored Lua to 5.5.1
- build(deps): update Sparkle to 2.10.0
- feat(vision): keep the apps you list never dimmed
- chore: sync main into release/3.0.0 (dependency updates)
- feat(cli): add shell completion, subscribe --reconnect and watch
- feat(app-rules): lead the Space and Float pickers with apps on screen
- fix(shortcuts): give the KiwiVision toggle row its card symbol
- feat(kiwihub): cap the panel at 400 pt on every side
- feat(mouse): focus the window the pointer rests on
- feat(vision): store KiwiVision lenses and read every setting through one resolver
- feat(gui): open any release's notes from Home's footer
- fix(keys): register macOS Switch to Desktop 1-9 as reserved chords
- feat(mcp): add the Claude Desktop extension and the Claude Code plugin
- feat(shortcuts): give KiwiVision its own shortcuts section
- feat(kiwihub): the View side — Layout, Profile and KiwiVision lines
- feat(kiwihub): fold digit ladders and mirrored pairs in the shortcuts overview
- feat(vision): turn a KiwiVision lens on (#2103 lens PR 2)
- feat(menu): one Open KiwiHub row replaces the quick menu's switches
- feat(mouse): tune hover focus's rest delay from Lua
- feat(gui): rename the Space Bar's Other Spaces row
- fix(profiles): never overwrite a config file a newer build wrote
- fix(mouse): explain hover focus's scrolling stand-down
- feat(kiwihub): a chip per KiwiVision lens on the View side
- fix(mouse): hover focus reaches the Settings window
- feat(vision): a lens applies only where its profile takes it
- fix(vision): see SketchyBar, so Never dimmed can keep it clear
- feat(gui): list live changes not saved in the save pill
- fix(kiwihub): chips hug their text; buttons join the footer row
- chore: sync main into release/3.0.0 (What's new link, #2318)
- feat(vision): a lens keeps the keys on its apps
- refactor(app-rules): a window title editor any list can mount
- feat(vision): a lens holds a stray landing under the haze
- feat(vision): lens shortcut rows and the rename and delete crossings
- docs: a Mission Control swipe-down moves the focus; docs-only changes take CI as their gate
- fix(ax): the visible-panel scan reads an untracked window's button
- fix(app-rules): the Float list reads a float rule as the engine does
- test(app): arrival debts age on the core clock; the cycle row's pick is tested
- feat(vision): the lens page's draft and Save (lens PR 7a)
- refactor: one rest door pays the float raise; the Desktop cue asks the shelf
- fix(l10n): zh-Hant names the layouts natively; ja takes a layout out
- feat(vision): the Settings lens page (lens PR 7b)
- feat(mcp): add the kiwivision tool and kiwivision.current
- test: remove the 3.0.0 audit's duplicate, vacuous and value-pin tests
- fix(kiwivision): Clear after and the Reminder grey when gated
- test: rewrite the 3.0.0 audit's value pins as shape assertions
- feat(kiwihub): KiwiVision line without Off, named Default, New Lens last
- feat(kiwihub): Save as New Profile… on the Profile line
- feat(kiwihub): the pointer lifts grey, keys and a click select
- feat(updates): the spotlight row count is a guideline, not a cap
- feat(layout): Scrolling and Monocle take new symbols
- fix(kiwihub): halve the bordered footer's vertical padding
- feat(settings): Keep the live, not saved rows from the save pill
- fix(kiwivision): KiwiHub reads as no own key window
- feat(kiwihub): leave a lens with no apps off the KiwiVision line
- feat(settings): bordered buttons lift grey on hover, everywhere
- fix(events): hover focus leaves a focused Settings window
- feat(settings): offer the hover focus delay in Mouse & trackpad
- fix(settings): button chips keep the bezel's shape; a lift promises the click
- chore: sync main into release/3.0.0 (Mission Control swipe-down, #2350)
- feat(settings): the shut gestures card shows every gesture's picture
- Merge release/3.0.0 into main
- docs(performance): 3.0.0 against 2.3.1 on the fixed desk
- fix(events): hover focus holds the window a focus change left the pointer on
- chore(bar): update sketchybar-app-font to v3.0.9
- chore(l10n): translate the 3.0.0 keys in all ten catalogs
- feat(settings): AI set up rows take the prompt row shape
- fix(settings): the AI setup intro is the card caption
- docs(plugin): name what the launcher runs, the privacy policy and support
- feat(settings): unify the hover lift across KiwiDesk's click targets
- feat(settings): one cursor for pointer and keys in searchable dropdowns
- chore(release): stamp version 3.0.0
2.3.1
KiwiDesk is built in free time and is free to use for everyone. If it has earned a place on your Mac — a star on GitHub, a word to someone who tiles, or a coffee through GitHub Sponsors or Ko-fi — every one of those keeps it fruity.
KiwiDesk 2.3.1 leaves Spotlight alone on macOS 27.
Fixed
- Spotlight stays where it opens on macOS 27 — KiwiDesk mistook Spotlight's search panel for one of your windows: typing nudged it down, and sometimes it opened in a corner of the screen. KiwiDesk now leaves it alone.
- chore(site): sync release notes and feed for v2.3.0
- chore(agents): curator leads with what the reader sees
- chore(site): bump the site-patch-and-minor group in /site with 5 updates by @dependabot[bot] in
- chore(bar): update sketchybar-app-font to v3.0.7 by @github-actions[bot] in
- ci(app-font): open the update PR with the sync PAT
- fix(ax): never manage Spotlight's panel on macOS 27
- chore(release): stamp version 2.3.1
2.3.0
KiwiDesk is built in free time and is free to use for everyone. If it has earned a place on your Mac — a star on GitHub, a word to someone who tiles, or a coffee through GitHub Sponsors or Ko-fi — every one of those keeps it fruity.
KiwiDesk 2.3.0 puts windows back after a restart, adds keys for moving between Spaces, and floats Settings windows on its own.
Spotlight
- Back where they were after a restart — When your Mac restarts and macOS reopens your apps, each window goes back to the Space it was in. {symbol:desktopcomputer}
- Keys for moving between Spaces — ⌃⌥⌘← and → step to the previous or next Space; ⌥⌘Tab jumps back to the Space you were just on, like a browser's Back button. Updated from an earlier version? Restore Defaults… in Shortcuts & Gestures brings the arrows. {setting:config.spaceHistory} {symbol:keyboard}
- Each screen can put its bars on its own edge — With two screens, the Space Bar can sit at the top of one and at the bottom of the other. {setting:settings.spaceBarStyle.edgeOverride[screen]} {symbol:display.2}
- Settings windows float on their own — Windows that can't be resized, like an app's Settings or Calculator, now float instead of being squeezed into a tile. If one floats that you'd rather tile, add its app under App Rules ▸ Tile. {setting:config.tileRules} {symbol:macwindow.on.rectangle}
New
- **After a restart of the Mac or a logout, your windows now go back
to the Spaces they were in**, and the notice under the menu-bar icon counts them back in.
- New keys for moving between Spaces: ⌃⌥⌘← / → step to the
previous or next Space, and ⌥⌘Tab / ⌥⌘⇧Tab go back and forward through the Spaces you visited, like a browser. An updated setup gets ⌥⌘Tab / ⌥⌘⇧Tab added; the arrows keep your swap until you restore the defaults (see below).
- Each screen can now put its bars on its own edge — the Space
Bar at the top of one screen and the bottom of another, say — under KiwiShelf ▸ Each bar ▸ Per screen.
- A Desktop switch KiwiDesk makes now shows the Desktop's number
for a moment; turn it off under Profiles ▸ Profiles per macOS Desktop.
- **An app's shortcut can now bring all of that app's windows into
the Space you're on**: pick Gather Windows as its action.
- **KiwiDesk now warns once when AeroSpace, Amethyst or OmniWM runs
beside it**, and can quit it for you.
Improved
- Some default shortcuts now sit on better keys: swap is now
⌃⌥⇧ + arrows, freeing ⌃⌥⌘ + arrows for the previous and next Space. Your keys stay as they are; to take the new ones, click Restore Defaults… in Shortcuts & Gestures. It resets only the Default layer, keeps shortcuts you made yourself unless they use one of those keys, and shows what it changes before you confirm.
- New default shortcuts now reach your setup when you update:
from this release on, each one is added where its key is free and you have no shortcut for that action yet. Nothing you set is changed, and one you remove isn't added back.
- **Windows that can't be resized, like many apps' Settings windows
or Calculator, now float on their own** instead of being squeezed into a tile. If one floats that you'd rather tile, add its app under App Rules ▸ Tile; App Rules ▸ Automatic floating turns the guess off altogether.
- ⌃⌥⇧⌘ + a number now goes to that macOS Desktop, added for each
Desktop whose shortcut is free; one you remove isn't added back.
- Quitting KiwiDesk now gathers floating windows too, and the
next launch puts each one back where it floated.
- Unsaved Settings edits no longer wait in a closed window:
closing Settings or quitting now asks whether to save them, and open dialogs close instead of holding up a quit.
- A Space can now have its own gaps, set in its Customize…
overrides on the Spaces page.
- Advanced Colours now groups colours by what they colour, so
one pick can recolour a whole group at once.
- The Monitors page is now called Screens, and KiwiDesk calls a
physical screen a screen in every language; searching for "monitor" still finds it.
- An empty temporary Space you visit and leave now goes away, and
temporary Spaces sort by number.
Fixed
- **A window you close with ⌘W or open with ⌘N is now arranged at
once** instead of waiting for the mouse to rest.
- **Switching macOS Desktops no longer freezes a busy desk for a
moment**, and the focus border slides away with its window.
- **Coming back to a Desktop now focuses the sticky window that
followed you**, and switching profiles away and back keeps every window in its Space.
- **Overlays that cover the whole screen, like Slack's huddle drawing
or a dictation HUD, are now left alone.**
- **Ghostty's configuration-error and update windows, and titled
windows of menu-bar apps, now float** instead of being ignored.
- **A floating window that fills the screen no longer hides the bars
as if it were a slide show**, and the focus border now fits a floating window that keeps its own size.
- **App Bar boxes no longer leave faint trails as they slide with the
Liquid Glass look**, and pop-up notices no longer clip their ends.
- **Settings no longer saves over an init.lua you changed in another
editor**, and it now says when a first Save moves your shortcuts and rules into the visual editor.
- A new laptop profile's Grid now holds four windows, two by two,
instead of piling the third onto the second.
- **Open at Login no longer registers a copy that can't start at
login**, such as one run straight from a download.
- **The detached preview card in Settings no longer judders while
you drag it.**
Lua & CLI
- space_bar.set_reserve and app_bar.set_reserve are new: with
reserve off, a bar draws over the windows instead of making room, so showing or hiding it moves no window.
- kiwidesk self_test is new, and reports which of the private
macOS calls KiwiDesk relies on this macOS still answers.
- chore(agents): add roadmap-planner
- chore(site): sync release notes and feed for v2.2.0
- ci: run CI on PRs into and pushes to release/3.0.0
- ci: skip the macOS jobs on a release stamp alone
- chore(agents): add a read-only copywriter
- fix(l10n): call a physical screen a screen; rename the Monitors page to Screens
- test(ax): give the wake-pull suite window ids no own panel holds
- feat(release): post the Spotlight and a counted close to Discord
- fix(gui): localize the binding name in the reach checklist
- feat(bar): split shown from reserved on both bars
- fix(gui): refuse an unstable copy as a login item and grey the tour checkbox
- feat(cli): add a read-only self_test of the private fast paths
- fix(state): restore the arrangement after a restart of the Mac
- chore(agents): drop the model column from the roadmap planner
- fix(l10n): carry the screen wording into every catalog
- fix(gui): centre the Screens picture and give the chips more room
- fix(state): gather floats at quit and give them back at launch
- feat(bar): resolve each bar's edge per screen
- feat(gui): name the Settings window after the area it shows
- fix(gui): close dialogs on quit and ask about unsaved Settings edits
- fix(tiling): deliver a float's capture at its origin and re-centre one with none
- feat(gui): edit each bar's edge per screen in Settings
- fix(gui): discard unsaved Settings edits on logout or restart
- feat(commands): reach every Space by key
- fix(profiles): record a Space's not-yet-arrived windows
- feat(app): warn once when another window manager runs
- feat(gui): set a Space's own gaps in its overrides
- fix(gui): call a Cmd-Tab or Option-Cmd-Esc binding dead
- feat(gui): keep the boot notice up while a restart restore places windows
- feat(desktop): name the Desktop a KiwiDesk switch lands on
- fix(gui): name both sides of a shortcut conflict in the GUI
- fix(bars): glide a Space box's glass and tint as one
- fix(bars): glide App Bar boxes and the shelf plate through their host
- fix(tiling): fold a Desktop switch's re-sync into one pass
- feat(keys): seed Go to Desktop on ⌃⌥⇧⌘ + digit
- fix(borders): keep a ring on its window's Desktop
- chore(l10n): translate the Settings leave prompt
- refactor(app): move the front-window seam beside windowIsOnScreen
- fix(state): retire a visited empty temporary Space, sort them
- fix(borders): keep the refusal pill's pop inside its panel
- test(gui): reach both fallbacks of the per-screen draft sets
- fix(state): give a carried sticky window its focus back on a return
- test(state): reflect DesktopMemory's window-keyed stores
- feat(commands): add gather, every window of an app into this Space
- feat(ax): float fixed-size windows, keep buttoned Dock-less ones
- test(events): reflect EventLoop's window-keyed stores
- fix(state): tell a show from a titled float by its AX subrole
- fix(borders): keep the sticky mark's pill pop inside its panel
- ci: relay outsider issues to the private planning repo
- ci: relay red CI runs to the private planning repo
- ci: add agent-ready draft PRs
- chore: park the agent-ready workflow
- feat(commands): let tile_rules and float_automatically tile a guess
- chore: drop the CI relay
- feat(gui): add the Automatic floating card to App Rules
- refactor(appearance): move ColorVision into Core
- fix(tiling): lay out the user's own close or open at once
- test(gui): close the automatic floating card's guard gaps
- feat(settings): Advanced Colours by role, with a colour per group
- feat(ax): ignore windows at the screen-saver level
- feat(gui): list the apps the guess floated in the Tile picker
- feat(ax): manage Ghostty's buttoned raised windows
- fix(profiles): tune a laptop's starter Grid two by two
- fix(gui): refuse a live Save after init.lua takes the config
- fix(gui): refuse a Lua editor Save over an init.lua edited outside
- fix(gui): say a Save adopts init.lua's settings before gui.json exists
- fix(gui): measure the preview card's drag in global space
- feat(keys): add a release's new default shortcuts on update
- feat(ax): manage Ghostty's update alert
- chore(release): stamp version 2.3.0
- docs(roadmap): refresh Next on my list after 2.3.0
2.2.0
KiwiDesk is built in free time and is free to use for everyone. If it has earned a place on your Mac — a star on GitHub, a word to someone who tiles, or a coffee through GitHub Sponsors or Ko-fi — every one of those keeps it fruity.
KiwiDesk 2.2.0 is about speed: Spaces, focus and startup no longer wait on a slow app, and Space switches now slide past in a snappy 300 ms.
Spotlight
- Keeps up under load — A Space switch now makes a third of the accessibility calls it did in 2.1.1. {symbol:gauge.with.dots.needle.67percent}
- Space switches slide — The Space you leave and the one you pick glide past on plates with each app's icon, in 300 ms. {setting:settings.animations.onSpaceChange} {symbol:rectangle.on.rectangle}
- Windows on hover — Rest the pointer on an app in the bars to list its windows, then click one to go there. {symbol:list.bullet.rectangle}
- Layers per profile — Choose which profiles a keyboard layer belongs to. {setting:config.layers[].reach} {symbol:keyboard}
New
- Space switches now slide: the Space you leave and the one you
pick glide past together on plates showing each app's icon, on by default at 300 ms, also in profiles saved before 2.2.0, since the old setting moved the windows themselves. KiwiDesk comes opinionated, but it's yours: turn it off or set its pace under Looks & Animations ▸ Animate Space switches. Reduce Motion keeps the switch instant.
- **Rest the pointer on an app in the bars for a list of its
windows**, the focused one checked; click a row to go straight to it.
- A keyboard layer can now choose which profiles it belongs to,
under Applies to in Shortcuts & Gestures.
- Shortcuts & Gestures now opens with a row of jump chips that
take you straight to a group.
- A slow start now shows a quiet notice under the menu-bar icon
until your windows are in place.
Improved
- **Switching Spaces, moving focus and starting up no longer wait
on a slow app**, like System Settings or a busy GPU, and a new app's first window tiles right away. A Space switch now makes about a third of the accessibility calls 2.1.1 made and moves a quarter of the windows; the performance page has the numbers.
- KiwiDesk no longer rearranges windows under your hand: a
window opening or closing while you drag waits until you rest.
- Focus shortcuts pressed quickly in a row now keep going
instead of stopping while the previous app comes forward.
- **A click on a Space Bar icon that stands for several windows now
steps through them**, and on another Space's icon goes there.
- The Space Bar's front app now keeps one length, so nothing
beside it shifts as focus moves, and it grows in and out as it comes and goes.
- Right-click menus in the bars now name the app at the top, and
the Space Bar's front app offers its window's actions too.
- **A floating window dropped past the bottom of the screen now
shrinks to fit** instead of hanging off it.
- Settings now reads more clearly in Dark Mode, and a few names
changed: KiwiShelf & Bars is now KiwiShelf, and the motion rows are Window duration and KiwiShelf duration.
- **Before an update changes a settings file, KiwiDesk now keeps a
copy** in ~/.config/KiwiDesk/migration-backups.
- **Granting Accessibility no longer rearranges your windows by
itself:** a new setup starts tiling when you press Start Tiling.
Fixed
- The focus border no longer stays over Mission Control on
macOS 27 or sits on a slide show, and after a Space switch it arrives with its window.
- **On a Scrolling Space, a window no longer jumps back and slides
in again** right after a Space switch.
- **Going to a Space that doesn't exist yet now shows it on the
Space Bar** instead of an empty desk.
- **Closing a window no longer sometimes takes you to the same
app's window on another Space.**
- **KiwiDesk started while the screen is locked now picks up your
windows after you unlock.**
- The right-most items of a scrolled App Bar now take clicks.
- **A floating window flicked up under the menu bar or the shelf
now comes back out.**
- **Deleting a keyboard layer now removes the shortcuts that switch
to it.**
- Opening Settings while it's open now keeps your page.
- The welcome tour's Looks step is now translated into every
language KiwiDesk speaks.
Lua & CLI
- If you write your own Lua config: pull_or_spawn is now
focus_or_spawn, the name for what it always did. Shortcuts you made in Settings are updated for you; a call in your own init.lua now fails and names focus_or_spawn.
- animations.set_on_space_change now defaults to on, and the
new animations.set_space_change_duration sets the slide's pace, 300 ms unless you set it. A config that calls the setter keeps its value.
2.1.1
KiwiDesk is built in free time and is free to use for everyone. If it has earned a place on your Mac — a star on GitHub, a word to someone who tiles, or a coffee through GitHub Sponsors or Ko-fi — every one of those keeps it fruity.
A small cleanup this time: a few quick findings I fixed while the bigger performance work is underway. Checking for updates now answers in KiwiDesk's own window, the front app on the Space Bar gets an indicator of its own, and fonts with old-style numbers sit straight on the bar.
Improved
- **The front app on the Space Bar now wears the active indicator
too** — its outline or edge mark, in the front app's colour unless you pick another under Advanced Colors ▸ Front app indicator.
- **Check for updates now answers in KiwiDesk's own update
window**, while it checks and when you're up to date, with this version's notes and Next on my list, now a tab of its own.
- Picking the Pill or Sakura look now also sets its own font,
Avenir Next or Hiragino Sans.
- **The Font weight slider now greys out for a font with fixed
weights only**, like Menlo or Apple Chancery, and shows the weight it draws instead of moving without effect.
- **Rounded chips on KiwiShelf now leave the same room at both
ends**, and an empty Space shown by a symbol is as round as a numbered one.
Fixed
- **Space numbers now sit centred in fonts with old-style
figures**, like Apple Chancery or Georgia, instead of low.
- Switching to an empty Space no longer leaves a dark box
where the front app was shown.
- chore(site): sync release notes and feed for v2.1.0
- fix(app): age the focus-report ledgers on one injected clock
- fix(bar): centre numbered Spaces on their figures; hide the front chip's tint
- feat(bar): give the Pill and Sakura looks their own faces
- feat(updates): one update window for every answer
- feat(updates): give the Next pane's Discord and Ko-fi lines their marks
- feat(gui): grey the font weight slider for fixed-face families
- feat(bar): front-app chip indicator and matching chip ends
- chore(release): stamp version 2.1.1
2.1.0
KiwiDesk is built in free time and is free to use for everyone. If it has earned a place on your Mac — a star on GitHub, a word to someone who tiles, or a coffee through GitHub Sponsors or Ko-fi — every one of those keeps it fruity.
KiwiDesk 2.1.0 makes KiwiShelf your own. Looks are ready-made shelf designs to start from: pick one, then change the font, the border, the glyph size, the colours and the edge of each bar until it is yours, and keep it as a Look of your own — kiwis come in green, gold and red, and your shelf in whatever you like. The Space Bar keeps the window you are in at the centre of its Space, and a Space made on the fly leaves when it empties. Plugging a screen in or out got smarter too: your windows go back where they were, and new ones wait together in a Space marked with a two-screen icon until their screen comes back. An update now leaves your windows where they are, and a long round of fixes rounds it off.
App shortcuts now do what they were made for even when macOS keeps an app running with no window — Safari after its red close button, say: the shortcut brings its window back instead of doing nothing. New here, or not yet through everything KiwiDesk does on a chord or a swipe? Press ⌃⌥K for the overview, or open Shortcuts & Gestures in Settings, where each gesture comes with its own little preview — this release's included: a right-click on KiwiShelf for a menu of what you clicked, and moving through your windows and your Spaces with a trackpad gesture or your mouse.
New
- Looks: ready-made and saved KiwiShelf designs — Glass,
Taskbar, Classic, Tiler, Pill and Sakura, each with its colours, where the bars sit, the focus border's shape and the gaps — on the page now called Looks & Animations, and as a step of the welcome tour. One look is shared across your profiles unless a profile keeps its own, and a new palette, Nightfall, joins the bundled ones.
- Each bar can now sit on its own edge — KiwiShelf ▸ Position
▸ Each bar — and on different edges each is its own shelf. New setups start with the Space Bar on top and the App Bar on the bottom; yours stay where they are.
- Right-click the KiwiShelf for a menu of what you clicked: a
Space's layout, its settings, New Space and Delete Space; an app's New Window, Move to Current Space, Float or Tile, App Rules…, Close Window and Quit; and KiwiShelf Settings, Looks and Advanced Colors at the end of every menu.
- Click an app glyph on the Space Bar to focus that window — a
glyph standing for several opens a menu of them — and hover a glyph or an App Bar item for its full title.
- **Hold ⌃⌥ and scroll to move focus window by window, ⌃⌥⌘ and
scroll to step between Spaces** — trackpad or mouse wheel — set up under the new Shortcuts & Gestures ▸ Mouse & trackpad, which also shows what the mouse and trackpad do, in moving pictures.
- Temporary Spaces: a Space you make on the fly — New Space on
the bar, or a shortcut to a Space that doesn't exist yet — is marked with an hourglass, goes away once its last window leaves, and is never saved unless you add it to the profile in Settings ▸ Spaces.
- The Space Bar gains Other Spaces — their apps, or just each
Space's name with a window count — a Space label that draws the layout in place of the name, a switch for grouping a Space's same-app windows, and a gap between glyphs.
- **KiwiShelf ▸ Style gains a Font and Font weight for the bars'
text, a Border around the plate or the boxes, a Glyph size and a Highlight width.**
- **A sheen on the focus border, the shelf's highlight and border,
and the drag borders** — a lighter or darker top edge, set under Looks & Animations ▸ Sheen, and on for everyone.
- Floating windows now wear a mark on the window, like sticky
ones (Gaps & Borders ▸ Show mark on floating windows), and the App Bar now lists a Space's floating windows after its tiled row.
- KiwiShelf now animates a Space switch: the App Bar grows out
of the Space Bar and shrinks back into it, a bar on an edge of its own fades in and out, the row dissolves between two Spaces that both show one, and App Bar groups slide together and apart. Looks & Animations ▸ Animate KiwiShelf and KiwiShelf duration set it, and Reduce Motion lands everything at once.
- What's new now ends with Next on my list — a dated list of
up to three things I'm working on next.
Improved
- Floating a tiled window now centres it at a usable size —
Float Window (⌃⌥F), or a Float rule saved over an open window — cascading when another float already sits there, and a window you float again returns to where it last floated.
- Installing an update now leaves your windows where they are
— Install and Relaunch from the update window, and `kiwidesk service restart` — sizes and scroll positions included; a quit still spreads them out.
- **On quit, windows now fill the screen in a balanced grid before
they pile up** — two side by side, four as a 2×2, the last one stretched over what is left — and entering or leaving the Floating layout does the same.
- The update window now has tabs — Highlights, New, Improved,
Fixed, Lua & CLI — and after Install, What's new opens again at once and says how far the start has got.
- **The Space Bar now keeps your focused window centred in each
Space's row**, with a +n on either side for the rest, and holds still while your pointer rests on it.
- Plugging a screen in or out now remembers your windows: a
window that was already open before you plugged in or out goes back to the Space it was in, and the ones opened since stay together in a held Space, marked with a two-screen icon on the Space Bar, that goes back to its screen when the screen does. Held Spaces keep their order and their hidden windows, survive a KiwiDesk restart, and a profile switch now holds any Space it has no name for while it has windows.
- **The alert sound and the quit grid's windows per pile are now
app-wide**, on General, applying without Save; the Behavior page is gone, and its mouse settings live under Shortcuts & Gestures.
- Tile Window now says why it can't — an App Rule, a dialog or
a missing Dock icon floats the window — and removing a Float rule now tiles its windows again.
- **The starter setup and the workflow presets are now tuned to
the shape of your screens** — an ultrawide scrolls wide, a portrait screen scrolls tall — and Visual Creative & Developer is now called Design Studio.
- The welcome tour can now be replayed any time from the
bottom of Settings Home, and its layout thumbnails, like the preset previews, play their layout once.
Fixed
- **Open or Focus now reopens an app that is running with no
window**, and lands on the window you used last — right after a Space switch it used to do nothing.
- Scrolling the shelf no longer stalls under a boxed Liquid
Glass bar.
- **A slide show or a borderless-fullscreen game now opens in
front**, and the bars get out of its way.
- **In a Scrolling Space, dragging the outer edge of the first or
last column now resizes it** instead of snapping back.
- **Windows on Spaces you aren't looking at no longer flash onto
the screen at launch**, and a Monocle Space's windows no longer come back at half size after a relaunch.
- **A floating window dragged onto another display now belongs to
that display's Space** — tiling it no longer sends it back across, and switching the old screen's Space no longer parks it.
- **A tiled window moved into a Floating Space no longer lands
partly off-screen**, and a floating window no longer hides behind the tiles after a move-and-follow.
- Orion's second profile now tiles, and its invisible preview
twins no longer take a slot or trade focus with their window.
- **A Space no longer gets a second digit shortcut after you
reorder Spaces**, and a duplicate already in your saved shortcuts is dropped once.
- A shortcut recorded in Settings now takes effect on Save,
like every other setting — it used to work at once and vanish on the next start.
- **A profile's memory of which windows sit in which Space now
survives a restart**, and quitting under one profile and starting under another no longer puts the first one's layouts on the second's Spaces.
- **A Space chip no longer keeps its hover after a click switched
Spaces**, a full bar's end items no longer touch the border, and switching Boxed to Plain no longer clips the items.
Lua & CLI
- If you write your own Lua config: make_auto is retired —
make_tiled does its job, and fails on a window a rule or detection floats; set_float_nudge becomes set_float_placement("center" | "keep"), a saved nudge-off reading as keep; kiwishelf.set_edge is space_bar.set_edge and app_bar.set_edge; space_bar.set_glyph_cap is space_bar.set_glyph_span; drag.set_ghost_border_width and drag.set_drop_zone_border_width are border.set_width, and drag.set_corner_radius is border.set_corner_style; and app_bar.set_content, monocle.set_app_bar_content and scroll.set_app_bar_content are gone, the App Bar always drawing icon and title. Each old call is reported in Config Issues with its replacement.
- The move and float verbs now take a window: move_to_space,
move_to_space_and_follow, make_floating, make_tiled and toggle_floating accept a window id from get_state as a last argument and act on that window instead of the focused one.
- New: new_window and close_window, with the same optional
window id — they press the app's own File ▸ New Window and the window's close button.
- create_space and delete_space now take a scope, session
(the default) or profile, which also writes the live profile's file; a Space created from a keybinding or the CLI is temporary.
- **set_refusal_sound, quit.set_layout and
quit.set_grid_target_depth now change the running value only** — the settings are app-wide in gui.json, and no profile carries them.
- chore(site): sync release notes and feed for v2.0.0
- chore(agents): a changelog bullet announces the change, never the state
- ci: the README badge reads main's pushes, and main's runs always finish
- feat(release): the Discord post names what it cut, with counts
- feat(site): a voices section and the GitHub star count
- ci(site): rebuild the site daily through a Pages deploy hook
- feat(profiles): screen-shaped starter setups
- fix(profiles): held Spaces keep the order they left with
- fix(profiles): a held Space's renumber carries its hidden windows
- fix(gui): say how a dormant profile can become the default
- fix(bar): a bar item's hover follows the pointer across renders
- fix(tiling): resize a scrolling row from either end column's outer edge
- feat(profiles): presets build on the screen's shape tuning
- feat(tiling): floating a tiled window centres it at a derived size
- fix(tiling): raise the float placement's long-axis floor to 800 pt
- feat(tiling): a float dropped on another display joins its Space
- feat(bar): a width for the active highlight
- feat(tiling): a re-floated window returns to its last floating frame
- feat(bar): a gap between app glyphs inside a Space
- feat(appearance): add the Nightfall palette
- fix(tiling): every engine frame retires the open size ask
- docs(tiling): toggle_floating flips the window's own float flag
- fix(bar): give the glyph gap the item gap's range shape
- fix(bar): name the App Font style option Symbols, not Glyphs
- feat(bar): an optional border around the plate or boxes
- feat(bar): item padding inside the thickness
- feat(bar): a font family and weight for bar text
- feat(site): Product Hunt launch banner and review link
- feat(gui): tabs in the update window
- fix(bar): set bar text on one baseline, caps centred on the item
- feat(bar): other Spaces show apps, a window count or minimal
- feat(gui): What's new narrates the relaunch after an update
- fix(tiling): place a tiled window moved into a floating space
- feat(bar): a glyph size in place of item padding
- feat(gui): thinner slider track, a glass knob that follows the drag
- feat(layout): the quit gather fills a balanced grid before it stacks
- feat(tiling): draw the Settings drag preview with Core's marker
- feat(borders): a signed sheen on the ring, shelf and drag borders
- feat: an in-place restart leaves the windows where they are
- feat(bar): a Space label option draws each Space's layout
- fix(bar): name the Space label's fallback as the name, shortened
- feat(bar): every Space Bar glyph is a click target
- feat(profiles): held Spaces survive a KiwiDesk restart
- feat(bar): an App Bar item shows its full title on hover
- feat(bar): looks, ready-made and saved KiwiShelf designs
- fix(bar): glass hands its items back frame-laid
- feat(gui): a Shortcuts & Gestures page with a Mouse & trackpad drawer
- feat(bar): each bar owns its edge; two edges split the shelf
- fix(localization): es/it/pt-BR name a border "contorno"
- feat(bar): looks carry the focus border's shape and the gaps
- fix(i18n): drag border/fill off help names the switch by key
- feat(borders): one width and corner style for every window stroke
- feat(onboarding): a looks step in the welcome tour
- feat(settings): alert sound and quit settings go app-wide on General
- fix(gui): close the KiwiShelf Each bar drawer with a divider
- feat(gui): the sheen slider reads as a darker/lighter scale
- chore(site): bump the site-patch-and-minor group in /site with 4 updates by @dependabot[bot] in
- test(exec): await the reap instead of a wall-clock poll
- chore(bar): re-vendor app font v3.0.4 by @github-actions[bot] in
- feat(gui): tour and preset thumbnails play their layout once
- fix(gui): Home's footer keeps a permanent door to the welcome tour
- feat(events): one shared scroll-wheel event tap for scroll gestures
- fix(localization): Stack's stack and Grid's grid take the mode's name
- fix(tiling): measure the placement ledger on an injected clock
- feat(profiles): the starter splits the bars — App Bar on the bottom
- feat(looks): Bloom, a soft split look like iPadOS
- fix(looks): glass is what a first run shows
- refactor(looks): rename Bloom to Sakura, and tint its palette to match
- fix(palettes): every bundled +n badge clears 4.5:1
- feat(events): ⌃⌥ + scroll moves focus window by window, and its Settings group
- fix(bar): pad a rounded item's ends so its glyphs clear the curve
- fix(commands): a follow switch raises the landing floats
- feat(events): ⌃⌥⌘ + scroll steps between Spaces, and its Settings row
- feat(bar): the Space Bar centres each chip's strip on the focus
- chore(site): bump undici from 8.10.0 to 8.11.2 in /site by @dependabot[bot] in
- feat(looks): a look owns its colours
- refactor(bar): read a Space chip's discs as before and after
- feat(bar): right-click the KiwiShelf for a menu of what you clicked
- feat(looks): share one look across profiles
- fix(looks): a preset preview wears the shared look
- fix(bar): dim an App Bar group badge with its item
- fix(tiling): leave a presentation where its app put it
- fix(bar): centre the shelf divider on what the sections draw
- perf(bar): scroll each shelf section as one run view
- fix(profiles): keep a held Space's windows through the profile restore
- feat(commands): the move and float verbs take a window id
- feat(bar): window rows on an app glyph's and App Bar item's menu
- refactor(bar): the App Bar always draws icon and title
- docs(localization): floating one window takes the native verb
- feat(bar): the Space Bar's grouping becomes a switch
- feat(bar): App Rules… on a window's menu lands on that app's rule
- feat(borders): mark floating windows on the window
- fix(keys): give a Space one digit chord per verb
- fix(keys): keep one chord per navigation action at every writer
- feat(bar): New Window and Close Window on a window's menu
- feat(updates): What's new shows "Next on my list" from ROADMAP.md
- feat(commands): float and tile become two states
- fix(events): adopt Orion's second profile and refuse its shadow windows
- fix(ax): New Window finds its item in every macOS language
- feat(settings): tell the swap and hold-over-Space drags as stories
- fix(keys): apply recorded shortcuts on Save, not before
- feat(tiling): a Float rule saved over a tiled window places it like ⌃⌥F
- chore(scripts): queue heavy gate steps behind one machine-wide lock
- fix(profiles): a profile's Space record survives a KiwiDesk restart
- feat(bar): list floating windows after the App Bar's row
- fix(profiles): a composed Standard keeps its own Space record
- feat(site): open the Simple page on the trailer
- chore(site): bump dompurify from 3.4.14 to 3.4.16 in /site by @dependabot[bot] in
- fix(bar): overflow keeps its end pads; App Bar groups glide
- test(tiling): pin screen topology in the restart and cue fixtures
- test: pin the primary screen in the remaining geometry fixtures
- fix(gui): store the hover help delay, at 0.25 s
- feat(spaces): temporary Spaces, and New and Delete Space on a Space chip
- fix(commands): open or focus reopens a windowless app and pulls the most recent window
- fix(bar): KiwiShelf motion on a Space switch — grow, fade, dissolve, and the shelf glide setting
- docs: refresh ROADMAP for the release after 2.1.0
- chore(release): stamp version 2.1.0
2.0.0Big update
KiwiDesk is built in free time and is free to use for everyone. If it has earned a place on your Mac — a star on GitHub, a word to someone who tiles, or a coffee through GitHub Sponsors or Ko-fi — every one of those keeps it fruity.
KiwiDesk 2.0.0 puts the Space Bar and the App Bar on one shelf, KiwiShelf: one edge, one look, one set of colours. It declutters the interface — settings the two bars each carried are now one — for a simpler, more consistent experience. Profiles take a firmer hold on your screens and Desktops — unplugging a screen keeps its Spaces until it comes back, a Desktop can load a profile for one particular screen setup, and App Rules and shortcuts say which profiles they apply to. KiwiDesk also brings its own update window, more Liquid Glass, a reworked App Rules page and a round of fixes.
Before you update: Your settings carry over on their own. The two bars now share one edge and one style, and where they differed the shelf takes the Space Bar's — so with the usual setup, the App Bar in a Monocle or Scrolling Space moves up to the top beside the Space Bar. Settings ▸ KiwiShelf & Bars moves the shelf.
New
- KiwiShelf now puts both bars on one shelf — one plate with a
divider between them, and when the shelf is full, drag the divider to give the Space Bar more room; double-click resets it.
- **A bar with more than fits now fades at its edge and shows
a count** you can click to page; the mouse wheel and the trackpad scroll it.
- New outer and inner margins set how far the shelf sits from
the screen edge and from your windows.
- Unplugging a screen now keeps its Spaces on the screen that
remains, windows and layouts included, marked ✱ — plug it back in and they go home. A held Space is never saved into a profile.
- A Desktop can now load a profile for one screen setup — your
desk's monitors, say — ahead of the profile bound to it for every setup with that many screens.
- **App Rules and shortcuts now say which profiles they apply
to:** All profiles, or the ones you tick, and a profile can leave a shared shortcut out.
- **Opening an app whose App Rule sends it to another Space now
takes you there** with its window.
- KiwiDesk now has its own update window, listing everything
changed since your version as New, Improved, Fixed and Lua & CLI; after an update, What's New shows the same.
- New: Install updates automatically, under Settings ▸
General, installs a downloaded update the next time KiwiDesk quits. It is off by default and never restarts KiwiDesk by itself.
- KiwiDesk now has a Discord community, and Settings Home now ends
in the community links — Discord, GitHub and Ko-fi — with the version, the update state and About below. Check for Updates… moved there from the menu bar menu, which shows Update Available… only when an update was found.
- **With the Space Bar off, the menu bar icon now shows the
Space** each screen is on, and the active layer when it isn't the default one.
- **With Liquid Glass on, the drag markers and the sticky mark
are now glass too**, each tinted by its own colour.
Improved
- **On Liquid Glass, the shelf's colour now fades from the
screen edge** toward your windows, so the glass reads lighter.
- Each screen setup now belongs to one profile — the last one you
saved or loaded with it — so connecting those screens loads the profile you expect.
- App Rules is now two lists, Open in a Space and Float, and
adding a rule starts by choosing which; a rule can no longer be one that does nothing.
- The Profiles page now counts screens and Spaces instead of
drawing them, deleting a profile asks first, and "make default" names the screen count it is for.
- **In Settings ▸ Spaces, + with an empty name now adds the next
free number**, and a name another Space already has now says so instead of silently reverting.
- A window you close and bring back now opens where you are, and
focused, like a new window — a deliberate choice: a window manager opens windows in front of you, and you can move them from there.
- **In Stack, dragging a window's edge along its column now
resizes it** instead of snapping back, as the keyboard does.
- **KiwiDesk now stays smooth while a browser or terminal
retitles its window** on every page load or command.
Fixed
- The bar no longer stays under the menu bar after turning
the menu bar's auto-hide back off.
- **Disconnecting a screen or a Vision Pro no longer briefly
loads the wrong profile** before the right one.
- **A window set to stay visible across Desktops now follows a
trackpad swipe** to another Desktop.
- An app's right-click menu no longer closes on its own when
an App Rule puts that app in another Space.
- **With the menu bar on auto-hide, reaching the top edge no
longer takes focus** away from the Settings window.
- ⌘W now closes the Settings window.
- A Space 1 you had renamed or deleted no longer comes back
on every launch.
- App icons now sit centred and whole in the bars, a thin Space
Bar included, and Adobe apps and others with a version in their name get their icon again.
Lua & CLI
- If you write your own Lua config: the bars' shared setters
— edge, alignment, thickness, background style and fit, Liquid Glass, corner roundness, item gap, font size, icon source, dim factor and the colours — move from space_bar.set_*, app_bar.set_*, monocle.set_app_bar_* and scroll.set_app_bar_* to kiwishelf.set_*. init.lua is not rewritten; each old call is reported in Config Issues with its replacement.
- item_size is retired — an App Bar's width follows its
title_cap, a Space Bar item fits its content — space_bar.set_title_cap is now space_bar.set_front_app_title_cap, and the gap active indicator is gone.
- New shelf setters: kiwishelf.set_minimum,
kiwishelf.set_order, kiwishelf.set_outer_margin and kiwishelf.set_inner_margin; drag.set_liquid_glass and sticky.set_liquid_glass join the Liquid Glass switch.
- reset_layout_sizing now returns the active Space, one Space
or all to the sizes your profile set.
- bind_profile_to_desktop now takes screens to scope a binding
to one setup, and save_profile and load_profile say when they took a screen setup from another profile.
- delete_space now names what would bring the Space back — a
profile, init.lua or your Settings.
- monitor_change now fires once the screens have settled,
rather than for each in-between report.
- chore(site): sync release notes and feed for v1.4.0
- chore: add the Contributor License Agreement and its PR check
- fix(gui): three strings said Open or Focus pulls the window over
- feat(gui): show the active Space in the menu bar item while the Space Bar is off
- test(scan): route the blanker through the one literal walker
- fix(gui): the Bars preview draws a Space's symbol icon as the symbol
- fix(gui): the main menu carries File ▸ Close so ⌘W closes the Settings window
- feat(onboarding): the tour says each Space's layout behaves differently and can be changed
- chore(site): bump the site-patch-and-minor group in /site with 4 updates by @dependabot[bot] in
- feat(gui): Home ends in the community links, the version and the update state; About is a sheet
- fix(bar): a thin Space Bar's text glyph stays whole and centred in its cell
- fix(bar): the App Bar anchors a glyph's ink, not its advance
- test(i18n): the label-specifier clause counts label arguments
- test(gui): the bespoke-container guard's list table is a census
- test(commands): a catalogued command must reach a dispatch arm
- fix(focus): a menu-bar reveal's activation is returned to the own window
- fix(focus): a window returning from a close takes the focus at its arrival
- feat(commands): delete_space names every source that re-creates the space
- feat(focus): a window you bring back lands where you are, like a new window
- feat(bars): per-bar outer and inner margins, one placement rule for both bars
- chore(bar): re-vendor app font v3.0.0 by @github-actions[bot] in
- fix(ax): a reach-enabled sticky window follows a trackpad Desktop switch
- feat(commands): reset_layout_sizing clears every Space's size adjustments
- docs(readme): cut to what the site does not say, one link line for the rest
- docs(localization): state each naming ladder once under the prose budget
- docs(cli): state each command once under the prose budget
- docs(limitations): one limitation, its root and its hatch per row
- docs(design-decisions): cut repetition and event-logging, never the argument
- docs(lua): state each contract once under the prose budget
- docs(index): one line per page, install in step with the README
- docs(translating): state each workflow step once under the prose budget
- docs(spaces): state the model once, without why or issue numbers
- docs(architecture): state each pipeline step once under the prose budget
- docs(ui-patterns): keep each convention once under the prose budget
- docs(localization): sweep system_shortcut.* against Apple's own loctables
- fix(localization): the App Bar cross-reference is one key per sentence
- docs(accepted-limitations): the identical-displays hatch owes a migration, not a re-pin
- docs(translating): correct the four claims the code contradicts
- docs(ui-patterns): correct the six values and pointers the code no longer matches
- docs(lua-reference): add the bsp and grid placement entries, settle the icon-source pair
- docs(design-decisions): correct ten entries whose claim no longer matches the tree
- fix(commands): an empty active Space refuses by name
- feat(tiling): stack cross-axis mouse drag moves the zone share
- docs(limitations): the #1215 marker carries the shipped-on-main prose
- perf(events): route the focus and title arms off the blocking AX call
- chore: sweep the compiler warnings to zero
- ci: hold the compiler-warning corpus at zero
- fix(gui): a rule must say something, and "Automatic" is not a rule
- test: sweep Tests/ to zero warnings and ratchet the test steps
- feat(tiling): follow a launched app into its app rule's space
- fix(state): an App Rule files no raised-layer popup
- chore: trim the issue templates and order the chooser
- fix(bar): match app-font prefix names; read the table from the font
- fix(settings): lay a bare Home card out like an empty preview card
- feat(profiles): a monitor set belongs to one profile
- feat(gui): split App Rules into a Space list and a Float list
- chore(gui): link the Discord server instead of the Telegram group
- feat(profiles): scope a Desktop binding to one screen setup
- fix(settings): open the Desktops card on a binding; name the count a default is for
- feat(profiles): say which profiles an App Rule applies to
- feat(profiles): say which profiles a shortcut applies to
- feat(profiles): confirm before deleting a profile
- feat(profiles): count screens and Spaces instead of drawing them
- feat(release): typed release-note sections
- feat(release): the feed carries a typed release's notes as data
- feat(release): announce a published release on Discord
- feat(updates): KiwiDesk's own update window
- feat(updates): What's new after an update
- feat(settings): Install updates automatically
- fix(state): retire the boot placeholder Space nobody declared
- feat(bars): KiwiShelf — both bars on one shelf
- fix(gui): say why a Space rename to a taken name reverts
- feat(gui): add a Space without naming it
- fix(bars): the hovered divider keeps its weight
- feat(bars): fade the glass tint from the shelf's edge
- fix(tiling): clear a menu bar the screen cache missed
- fix(profiles): settle a screen-count change before choosing a profile
- feat(profiles): hold a disconnected screen's Spaces, send them home on reconnect
- feat(glass): tinted Liquid Glass drag visuals and sticky mark
- ci: build and release with Xcode 27 GA on the xcode-27 runner
- docs: list bind_profile_to_desktop's optional screens where no marker reaches
- chore(release): stamp version 2.0.0
1.4.0
KiwiDesk is built in free time and is free to use for everyone. If it has earned a place on your Mac — a star on GitHub, a word to someone who tiles, or a coffee through GitHub Sponsors or Ko-fi — every one of those keeps it fruity.
KiwiDesk 1.4.0 makes ultrawide screens comfortable — a Scrolling Space says how many windows it shows, and the anchors put the focused window where they say — and brings profiles and macOS Desktops into step, with one profile per screen count and windows returning in the order you left them. Beside that, a card flip when focus moves in a Monocle Space, and a round of fixes.
Desktops and profiles
- A Desktop can hold one profile per screen count — bind a
one-screen and a two-screen profile to the same Desktop and the one matching the screens connected loads when you dock or undock. The Desktops card groups its rows by screen count and names the screen under each Desktop.
- **Switching to another Desktop and back keeps your windows in
order**, and a Track Space keeps its columns.
Windows and layouts
- A focus change in a Monocle Space flips a card instead of
cutting straight to the next window: the windows blur and a card turns from the outgoing app's icon to the incoming one's. On by default — *Flip between windows* and *Flip duration* are under Layout Defaults ▸ Monocle, and macOS's Reduce Motion keeps it off.
- A Scrolling slot of 50% is exactly two windows, gaps included,
and a *Windows on screen* stepper under the slot size sets the count directly; the split ratios gain ¼ ⅓ ½ ⅔ ¾ presets. A saved slot size moves by less than one gap.
- **The Left, Right, Top, Bottom and Center anchors now mean what
they say:** the focused window rests at that position even when the row is shorter than the screen, so the rest of the row can hang off the edge. If you'd rather have the screen always filled with windows, use Follow — it's unchanged, and still the default.
- If one window, fill the screen is a new toggle for Scrolling
and Stack, on by default. Off, a lone window keeps its slot size or master zone and the rest of the screen stays empty.
- In Track, a window with a fixed size no longer hogs the width
— the leftover goes to the columns beside it, which you can resize again, and switching Spaces and back keeps the arrangement.
Borders and gaps
- The unfocused border is visible again on the dark palettes —
six of the built-in palettes drew it too dark to see over dark wallpaper, and each takes a lighter grey now.
- Fit layout gaps makes room for the glow, so a focused
window's glow no longer bleeds onto its neighbour, and the button now lives in the Gaps card.
Settings and shortcuts
- ⌃⌥, opens Settings on a new setup, beside ⌃⌥K. An existing
setup gets it through Shortcuts ▸ Restore Defaults…
- The gap sliders and the Desktop binding rows stay live — the
sliders while the per-edge values differ (a value there sets all of them), the rows while you edit a stored profile, and Save keeps the binding.
- Rows with no effect are greyed and say why — Auto Glow Size
with the glow off, Liquid Glass while Reduce transparency is on.
- The icon picker for Spaces and layers opens on Symbols rather
than on whichever tab you left it. Furthermore, the picker's search is cleared when it's closed.
- On macOS 27, Settings' dropdowns keep their text grey — the
new OS tinted every pop-up's label green while Settings was the front window.
- chore(site): sync release notes and feed for v1.3.0
- fix(gui): Desktop binding rows stay live under every edit target
- fix(gui): grey the Liquid Glass row with its reason under Reduce transparency
- feat(keys): seed ⌃⌥, as Open Settings
- fix(state): a Desktop return keeps a row's order and its track columns
- fix(appearance): lift the unfocused ring to mid lightness per palette
- fix(gui): grey Auto Glow Size with the glow effect off
- fix(gui): the gap masters stay live and acknowledge while their edges differ
- fix(gui): the icon picker opens on Symbols in one resting shape
- docs: state that a macOS update cannot take KiwiDesk down
- site(de): an update can at most slow a fast path
- feat(layout): "If one window, fill the screen" toggle, default on
- feat(layout): center, start and end scrolling anchors are absolute
- fix(layout): a scrolling share is a share of the pitch (#1382 Core half)
- fix(borders): Fit layout gaps clears the glow, and lives in the Gaps card
- feat(gui): "Columns on screen" — a count stepper for the scrolling share
- fix(tiling): track heal honours learned ceilings, the clamp folds like the render, a switch re-issues without probing
- fix(gui): the count row says "Windows on screen"; Center's caption owns the cut
- feat(animation): Monocle focus change flips a drawn card over a blur
- feat(profiles): name the screen under each Desktop row
- feat(profiles): a Desktop holds one profile per screen count
- fix(build): ask for the release build's SDK stamp and read it back
- fix(gui): menu-style pickers neutralise their label on macOS 27
- chore(release): stamp version 1.4.0
1.3.0
KiwiDesk is built in free time and is free to use for everyone. If it has earned a place on your Mac — a star on GitHub, a word to someone who tiles, or a coffee through GitHub Sponsors or Ko-fi — every one of those keeps it fruity.
KiwiDesk 1.3.0 is the first release under the Business Source License 1.1 — free to use for everyone, business included; only offering it as a product or service is reserved, and each version becomes MIT after four years. Beyond that: Liquid Glass on by default, a Mac Checklist in Settings, windows that respect an app's own minimum size, a swipe that stays where you sent it, and a Settings window that comes to the front when asked.
Liquid Glass and the bars
- Liquid Glass is on by default on macOS 26, and it honours
Reduce transparency the moment you switch that on. A setup that had it off keeps it off.
- Both bars start at 40 pt thick on a new setup, on every screen
size, and the Thickness sliders now go down to 20 pt.
- The Space Bar shows which shortcut layer is active, leading
with the layer's icon while one other than the default is on — and scripts can hear the switch as a layer_change event.
Windows and layouts
- **An app's own minimum size is respected, and the resize pill
says whose limit you hit.** A split makes room for a window that won't go narrower instead of letting it overlap its neighbour, Track opens only as many tracks as fit, and *This app won't go smaller* names the app where *Minimum window size reached* still means the setting you can lower.
- **A double-clicked title bar or edge no longer knocks a tiled
window out of its slot**, nor does an app resizing itself — the window goes straight back, and a floating window that zooms is kept clear of the bars.
- **Switching a Space to Floating no longer leaves windows off
screen or piled on top of each other** — anything you couldn't reach is laid out in a grid.
- The Track limit is the number of tracks you see. A limit of 3
used to show four; the default is now 3, and saved configs are adjusted on first load so nothing moves on screen.
- Floating windows get the unfocused border too, and clicking
around a Floating Space no longer lifts a sticky window over the others.
Desktops and profiles
- A swipe to another Desktop no longer gets pulled back a second
later.
- **A Desktop binding fires only when its profile fits the screens
connected.** Bound to a one-screen profile with two screens plugged in, the Desktop takes the profile for that screen count instead, and the Desktops row says which count the binding is for.
Settings
- Settings opened from the menu bar comes to the front again,
including after you closed it once in a Scrolling Space.
- A Mac Checklist card lists the macOS settings a tiling window
manager fights — Stage Manager, rearranging Spaces by use, edge tiling — read live from your Mac, with the habits that make tiling stick. The guide link now lives at its foot, and the tour ends there.
- Search opens the drawer a setting hides in, and finds your
palettes by name.
- The Track shortcuts sit behind their own drawer — *Move
windows in the track layout*, below the Desktop one — instead of beside shortcuts every layout uses.
- chore(site): sync release notes and feed for v1.2.2
- feat(bars): ship Liquid Glass on by default
- fix(desktops): settle never re-asserts a focus the switch removed
- chore(site): say open source, not free
- chore(license): move to the Business Source License 1.1 from 1.3.0
- fix(profiles): migrate the Liquid Glass leaves the default flip left absent
- test: two settle-and-latch tests stop racing the runner's clock
- docs(user-guide): keep only what the GUI cannot answer, and add the prose budget
- docs(limitations): a Finder window left behind by a swipe stays in its row
- fix(settings): a closed Settings window reopened in scrolling takes focus
- chore(site): bump js-yaml from 4.3.1 to 4.3.2 in /site by @dependabot[bot] in
- feat(site): the hero trailer replaces the July demo clip in #demo
- build(packaging): ship the license texts in the bundle and open them from About
- feat(site): Terms of Service page in three locales
- fix(bars): honor Reduce transparency live at the glass homes
- test: the mouse-warp click stamps stop racing the runner's clock
- docs(scrolling): record that a short row does not stretch to fill its axis
- chore(license): the Additional Use Grant reaches every production use
- feat(bars): 40 pt default thickness and a slider floor derived from Core
- docs(license): argue the grant's line in the entry, retire the bare free on the privacy page
- fix(scrolling): a swap trades places on screen, panning only into view
- fix(commands): the Desktop raise gate asks a second compositor read
- fix(site): the trailer's end card no longer runs edge to edge
- fix(tiling): correct a resize nobody asked for on its own event
- fix(tiling): stamp a frame-set at enqueue so our own echo never reads as a resize
- fix(borders): the unfocused ring and the float-tier raise ask the effective float
- feat(layout): the track limit counts the overflow track, floored at 2
- fix(layouts): derive Track's automatic count from learned app minimums
- fix(profiles): a Desktop binding fires only for its profile's screen count
- fix(gui): a search hit inside General ▸ Advanced opens the drawer
- feat(brand): the link-preview card shows the product, not the logo
- docs(brand): the README and the Nerd hero carry the slogan
- feat(gui): the Track shortcuts sit behind a drawer below the Desktop one
- docs: mark the Track drawer's prose unreleased
- feat(gui): palette names in search's Made by you group
- feat(events): emit layer_change on the Lua and IPC event surface
- feat(gui): the search field offers the Guide before you type
- docs(site): the Simple page's title and kicker carry the slogan
- test(state): an active home never drops its own sticky — #1301 closes from source
- fix(profiles): heal a screen the resolve left with no space
- chore(site): bump the site-patch-and-minor group in /site with 4 updates by @dependabot[bot] in
- fix(gui): the greyed Focused window row links its reason beneath the grid
- test(tiling): the echo grace runs on an injected clock, frozen for every test core
- feat(bars): the Space Bar leads with the active shortcut layer
- fix(tiling): send the corroborating second ask instead of waiting for the layout
- feat(tiling): gather off-screen windows when a space enters floating mode
- chore(app): drop a quadrupled comment in the traveler re-home
- fix(tiling): heal a split store to a learned floor at retile
- feat(tiling): a monocle stack trips the floating gather
- chore(ci): retire the merge queue, require an up-to-date branch
- feat(commands): a refusal pill names the app where the app is the limit
- fix(settings): caption links draw in the ruled grey, not link blue
- feat(settings): the Mac Checklist card
- feat(settings): the checklist's foot is the one guide pointer
- feat(gui): fill the Settings search catalog behind every drawer
- fix(gui): Gaps & Borders' at-rest rows are at rest in the census
- chore(release): stamp version 1.3.0
1.2.2
A one-fix release: floating windows that come back where you left them.
Floating windows
- A floating window no longer gets stuck in the screen corner.
Switching spaces could lose where a floating window belonged — after a Desktop switch, a relaunch, or simply a slow app — and from then on it came back tucked into the bottom corner where hidden windows park. Its place now survives all three, and a window whose place is genuinely lost comes back centred on its screen instead of in the corner.
- docs(agents): a highlight bullet is short, and a site fix is not news
- chore(site): sync release notes and feed for v1.2.1
- fix(tiling): re-centre a float stranded at the stash corner
- chore(release): stamp version 1.2.2
1.2.1
A small release: Desktop switches that stay put, profiles that keep their arrangements, and an update you can actually see.
Desktops
- A swipe to another Desktop stays there instead of bouncing
you back a moment later, and the swipe back keeps the window macOS refocused.
- **Switching Desktops no longer reads or rewrites your profile
files.** A hand-edited profile takes effect at the next reload or apply.
Profiles
- A profile keeps the arrangement you left it with through a
Settings save, a preset, a discard, Reset All Settings and a backup restore — a window parked on another Desktop included.
Updates
- You are told when an update is waiting: an orange dot on
the menu-bar icon and an Update Available… row, instead of a window opened behind everything else.
Settings and the command line
- The Desktop shortcut drawers explain themselves with a ?
that says what a macOS Desktop is next to a KiwiDesk Space.
- **focus_desktop and move_to_desktop_and_follow return
switched**, false when the Desktop was already showing.
- feat(agents): a changelog-curator, and the rule it applies
- chore(site): sync release notes and feed for v1.2.0
- feat(site): mark unreleased docs, and retire the marks at release
- refactor(profiles): make currentName the one live-profile authority
- fix(profiles): a Desktop switch reads no profile from disk
- fix(profiles): an away window takes the incoming profile's Space
- docs(site): say Schreibtisch once in the German catalog
- fix(site): let the compare table breathe, and label its blocks
- fix(site): untrack site/node_modules, and close the gap that let it in
- chore(issues): retire the roadmap template, unlist the collector
- feat(settings): say what a macOS Desktop is, once
- test(settings): close three escapes in the Desktop help guard
- feat(site): say that KiwiDesk works with native macOS Desktops
- fix(commands): a Desktop switch that changes nothing reports itself
- fix(focus): a Desktop switch is not a close, and a raise across Desktops is a switch
- feat(updates): a gentle reminder when a scheduled check finds an update
- chore(release): stamp version 1.2.1
1.2.0
This release is about macOS Desktops. KiwiDesk now knows which windows live on the Desktops you are not looking at, keeps each Desktop's and each profile's Spaces apart, brings sticky windows along when you switch, and puts focus back where you left it when you come back. Around that: a keyboard preview you can read, one honest cue for every blocked resize, and several focus jumps that are gone — including the one that pulled you off a fullscreen video. Liquid Glass now covers every KiwiDesk surface from a single switch, and three long-standing translation defects are fixed.
Desktops, done properly
- Every profile owns its own Spaces. Two profiles' Space 1
used to be one Space, so switching profiles and back could merge an arrangement away for good. Each profile now records what its Spaces held when you leave it and restores them when you return. A brand-new Desktop picks a Space no other Desktop is showing instead of landing on one whose windows are all somewhere else.
- **A Desktop keeps its identity when Mission Control renumbers
it.** Adding, removing or dragging a Desktop — or plugging a screen in — shifts every Desktop number, and everything keyed by number silently pointed at a different Desktop. KiwiDesk now stamps each Desktop with its own identifier, so profile bindings and remembered Spaces stay with the Desktop they were made on.
- Windows on other Desktops are known, not forgotten.
KiwiDesk reads which windows each Desktop hosts, so a window that vanished because you switched Desktops is reported as away rather than closed, keeps its Space and slot for its return, and Open or Focus can reach it across Desktops. get_state lists them under away_windows, and startup no longer counts parked or system windows among them.
- The Space Bar shows the Desktop in front of you. Windows
parked by KiwiDesk in another Space are the bar's job; windows sitting on another macOS Desktop are not, and no longer appear.
- Sticky windows come with you across Desktops. A window
marked ∞ follows you to every Desktop; one marked 📌 follows across its screen's Desktops. On by default and switchable with sticky.set_desktop_reach, with a per-window override for the one window you want left behind.
- Coming back to a Desktop puts focus where you left it.
Returning used to jump focus to the first window in the row; KiwiDesk now remembers each Space's last focus per Desktop and hands it back at that window's own return.
- Move a window to a Desktop and into a Space in one verb.
move_to_desktop(3, "mail") and move_to_desktop_and_follow take an optional Space the window joins when it lands.
- **A ∞ window entering a floating Space on another screen moves
onto that screen**, scaled to it, instead of staying where its previous Space drew it — and its ∞ mark shows on the one bar that actually has it.
- **A new docs page explains how screens, Desktops, profiles and
Spaces relate**, with a diagram — the model the app assumed you already had.
Liquid Glass, and the bars
- Liquid Glass is one switch, and it covers everything. It
used to be an App Bar setting alone. It now lives in Colors & Animations and lays macOS's translucent material over the Space Bar, the App Bar and the shortcuts panel together, with each bar's Fill colour tinting its own material. The shortcuts panel stays untinted on purpose — a large panel summoned over the desktop reads best as clear glass. If your three surfaces are set differently today, turning the switch on adopts all three.
- The bars honour Reduce Motion. With the system setting on,
a bar no longer slides or fades — it just appears where it belongs. The affordance stays; only the motion goes.
Focus stops jumping
- KiwiDesk stops believing focus reports that are not yours.
Apps announce focus changes that are not system focus changes: a window re-focusing itself a second after KiwiDesk places it, a duplicate report landing after your next keypress, a small panel that takes the keyboard without bringing its app forward. Each one moved KiwiDesk's idea of focus off the window you were actually on — and at worst left every focus shortcut refused until you clicked a window to resync. All three are recognised now.
- A window that blinks out keeps its place. Some browsers
drop their window for half a second entering and leaving native fullscreen, and some apps stop reporting a window during fast focus changes. Both read as a close, so the window lost its slot and focus moved to a neighbour. Leaving a fullscreen video now returns you to the video.
- Clicking KiwiDesk's own Settings window focuses it. On a
scrolling Space, clicking another window pans Settings out of view — and clicking it again within two seconds did nothing at all.
Resizing tells you why it stopped
- **Every blocked resize draws a pill, and a drawn pill may
sound.** A resize press in a layout with no resizing, or on an axis the zone does not have, used to be cued by sound alone — invisible with sound off. One cue now covers every refusal.
- The pill lands on the window that cannot move. In BSP a
refusal named the focused window as at its minimum when a neighbour was the one stuck, sending you to resize the wrong window.
- A window alone in its zone says so. "Nothing to divide
here — try the other axis" and "This zone has nothing to divide" replace six silent cases and one message that was false; a one-window stack no longer shows a row of "Minimum window size reached" pills on a window filling the screen.
- Two more presses now answer properly. A native full-screen
window is refused, and says so, in every layout — it used to be silent in one and shove its neighbours around in another. And a window floating because its whole Space uses the floating layout now resizes like one, which until now only windows you had floated by hand did.
Shortcuts you can read
- The keyboard preview answers a real question now. Hover a
key to see every action on it, chord first, with what a collision costs spelled out — the red key finally says which two bindings collide. And the board draws the layer you are editing, so "is this key free here" is answered for the layer that will actually fire rather than for all of them at once.
- A conflict warning names the cost, not just the collision,
and reads macOS's live shortcut settings: a system chord you have turned off no longer counts as a conflict, and one you turned on does.
- Swap rides ⌃⌥⌘ plus an arrow; ⇧ keeps the digits. The
three-modifier claw for swapping is gone: ⌃⌥⌘ with an arrow swaps with a neighbour, ⇧ with a digit sends the window to that Space. Fresh installs get the new defaults; a keymap you edited is yours and does not move.
- Per-Desktop shortcut rows appear once you bind one. A
dozen unbound "Go to Desktop N" rows no longer sit in the Focus and Move cards on every Mac with several Desktops.
- The shortcuts panel says when it has more to show. On a
default install the panel is taller than its ceiling and scrolls, and nothing said so — the rows below the fold were simply not there as far as you could tell.
- Picking an app binds it, in one press. Choosing an app for
a shortcut no longer needs a second button afterwards, which is how app rules have always worked.
Settings
- Export Log… in General ▸ Advanced. Pick a time range, save
the file, attach it to a bug report — no terminal needed.
- Picking an app adds its rule immediately. The separate
"Add app rule" button is gone, and with it the half-added state that drew no icon.
- Keyboard navigation got shorter and quieter. Arriving in
an area focuses the page instead of the back chip (six presses fewer to the first field), a segmented control costs one Tab stop instead of one per segment, and the focus ring appears only when the keyboard asked for it — mouse clicks no longer draw one, the Space chip included.
- The save pill lists the screen changes the header claims.
Clicking it opened nothing when the only unsaved change was a screen setup drifting from the profile.
- The profile card's help states the rule correctly: the
main screen's Desktop selects the profile, and all four rungs of the selection ladder are there.
- "Save as new" says screen, and speaks every language. The
message called a screen a monitor and was missing from every non-English catalog.
- Bar titles default to ten characters. The bars show window
titles, and each item is sized from the widest, so the old 25-character default spent the bar before you chose anything.
- And a run of smaller fixes. The hex field in Advanced
Colors can be clicked into, the app picker finds apps in subfolders and both of its surfaces answer Escape alike, the Space chips in Monitors show they can be dragged, a profile card stays marked while you point at another, and Save is readable in light mode while Settings is inactive.
In your language
- Switching language now changes every label. Some lists —
the bars' Position and Alignment pickers, the shortcut recorder's help — kept whichever language was live the first time you opened that page, so the window came back part English and part German.
- Track shortcut rows read as sentences. "Move window to
next track" was assembled from a bare "next", which five languages cannot inflect into a sentence; each row is now translated whole.
- The shortcuts panel has one name. Everything pointing at
it said "shortcuts panel" while the panel announced itself to VoiceOver as "Shortcuts reference".
- chore(site): sync release notes and feed for v1.1.2 by @github-actions[bot] in
- feat(gui): picking an app adds its rule immediately
- feat(bars): default the bar title length to 10 characters
- fix(gui): land arrival focus on the page, not the back chip
- fix(gui): state a focus destination only when the keyboard asked
- fix(gui): a segmented control costs one Tab stop, not one per segment
- fix(gui): the space chip refuses click-born focus too
- fix(animation): port StrandDetector capture log to the onLog seam
- fix(ax): distrust a sweep removal the WindowServer still shows
- feat(keys): conflict verdicts read the live symbolic-hotkeys state
- feat(commands): sticky windows reach across Desktops
- revert: sticky windows reach across Desktops
- feat(commands): sticky windows follow across Desktops by carry
- fix(commands): open the carried arm on the carry's own stamp
- feat(gui): Export Log… in General ▸ Advanced
- fix(commands): promise the carry's flight from our own switch dispatch
- docs(readme): shorten the README and re-record the demo loop
- fix(commands): per-Desktop focus memory
- fix(commands): a focus honored while a return's debt stands retires it
- docs: every layout is fully reconfigurable
- fix(tiling): move a ∞ traveler onto a floating Space's screen
- fix(bars): a ∞ glyph sits on the active Space's screen only
- feat(state): per-Desktop census — know the windows on away Desktops
- fix(bars): the Space Bar draws the Desktop in front of you
- docs: explain how screens, Desktops, profiles and Spaces relate
- fix(state): the boot census does not seed a parked window
- docs: lua-reference no longer denies the Desktop move verbs
- fix(gui): the save pill lists the monitor drift the header claims
- fix(gui): the profile rule moves into the card's own help
- fix(gui): a conflict warning names the cost, not just the collision
- feat(profiles): a Desktop is its stamp, not its number
- feat(profiles): every Desktop and every profile owns its own Spaces
- fix(gui): the keyboard preview draws the layer you are editing
- feat(profiles): swap rides ⌃⌥⌘+arrows, ⇧ keeps the digits
- feat(gui): Desktop shortcut rows are an offer until one is bound
- feat(gui): hover a key to see every action on it
- fix(config): one refusal cue — every blocked action draws, a drawn pill may sound
- fix(events): self-raise stamps outlive their first echo
- feat(commands): the Desktop move verbs take a composed space target
- fix(commands): a bsp refusal names the window that cannot move
- fix(gui): the save-as-new message says screen, and speaks every language
- refactor(tiling): the bsp split's geometry gets its own home
- fix(events): distrust an app's focus of a window we just placed
- test(events): the hidden arm's active-Space gate gets a guard, and the bounce fixture its pin
- feat(commands): a window alone in its zone says so
- fix(events): a fullscreen transition's vanish is refused, never read as a close
- docs: the release build is a required check, so the template stops asking
- fix(gui): the save pill's Save owns its ink
- feat(gui): the Space chips say they can be picked up
- feat(shortcuts): picking an app adds it
- feat(gui): one escape, and a list that reaches a folder deeper
- fix(bars): the bars honour Reduce Motion
- fix(events): a click on our own tiled window is a click
- test(bars): the bar scan roots answer to the tree, not only to bars.md
- fix(localization): track rows are whole sentences
- fix(events): the mouse-button read is one injected seam
- fix(gui): the pointer stops erasing the pro-card marking
- fix(commands): resize reads the effective float
- fix(gui): the shortcuts panel cues its own fold
- fix(commands): resize refuses a full-screen focus once, and says so
- fix(localization): translate the three 1.2.0 sentences every locale lacked
- fix(bars): the glass tint has one channel, and it is capped
- feat(gui): the shortcuts panel takes glass, and KiwiDesk's accent
- fix(gui): a click that starts text editing is not a stray ring
- fix(bars): pin the Liquid Glass variant from the Fill, never per view
- feat(gui): one Liquid Glass setting for both bars and the shortcuts panel
- fix(bars): keep the glass tint beneath its plate across the span-backdrop arm
- fix(bars): the Space Bar's front segment renders into the glass run it hugs
- chore(site): bump the site-patch-and-minor group in /site with 5 updates by @dependabot[bot] in
- fix(gui): a localized value is computed per read, never stored
- fix(localization): the shortcuts panel has one name
- chore(bar): re-vendor app font v2.0.86 by @github-actions[bot] in
- ci: thread one real token through the release sync PR
- fix(events): a focus report counts only from the app macOS activated last
- chore(release): stamp version 1.2.0
1.1.2
Switching a layout from the menu bar and then saving in Settings used to undo the switch — that is fixed, and the menu row that makes a switch permanent now says what it does. BSP also picks a new default split, which changes how untouched setups tile.
Saving in Settings stopped undoing your layout
- Save no longer puts the old layout back. Switch a Space to
Monocle from the menu bar, then open Settings to change a gap and press Save: the Space used to snap back to whatever the profile held, and *that* is what got saved — the switch was destroyed by saving something unrelated. Save now touches only what you changed in Settings, so the gap is saved and the Monocle switch stays on screen, still temporary until you keep it. Changing a Space's layout in Settings itself is a real edit, and that one wins.
- The menu row is now "Keep Layout in Profile ‹name›". Same
action, honest name: a layout switched from the menu bar is temporary until you keep it, which is how macOS words this choice elsewhere.
- **That row lights up whenever any screen is on a temporary
layout**, not only the screen you are looking at. It writes the whole profile, so it used to grey itself out while another screen's menu said the layout was unsaved.
- Settings no longer narrates temporary layouts at all. The
menu bar's "not saved to profile" line is now the single place a temporary layout is announced — and Revert went back to being just "discard my edits".
BSP splits alternately now
- **New windows alternate horizontally, then vertically, as they
nest.** That alternation is what most people mean by BSP; the old default cut each area's longer side, which read as the layout misbehaving rather than as a choice. Both options are still there, in BSP's settings and in bsp.set_strategy.
- This changes how you tile if you never picked a strategy.
If you did pick one — in Settings or in your config — it is stored and nothing moves. Fresh installs and untouched setups get the new default.
Floating spaces respect your bars
- **A window in a Floating space is now pushed clear of the App
Bar and the Space Bar**, the same as a window you floated by hand. It could previously sit underneath one with its title bar covered, and nothing ever moved it back out.
Smaller things
- Settings shows just the version number. The build hash moved to
kiwidesk --version, which is where support asks for it.
- Release plumbing: the release notes and the update feed publish
themselves again, without a hand on the wheel.
- chore(site): sync release notes and feed for v1.1.1 by @github-actions[bot] in
- chore(scripts): make lint's soft file-size warnings opt-in
- chore(comments): trim settings and UI components to §2.8 budget (batch 6)
- chore(comments): trim core and settings to §2.8 budget (batch 8)
- chore(comments): trim core and gui components to §2.8 budget (batch 7)
- chore(site): bump the site-patch-and-minor group in /site with 4 updates by @dependabot[bot] in
- chore(comments): trim core and settings to §2.8 budget (batch 9)
- chore(comments): trim codebase to §2.8 budget (batch 10)
- docs(readme): add Settings screenshot and scrolling demo loop
- chore(bar): re-vendor app font v2.0.83 by @github-actions[bot] in
- chore(comments): trim core and gui to §2.8 budget (batch 11)
- docs(readme): reshoot the Settings screenshot at a narrower width
- chore(comments): trim core and gui to §2.8 budget (batch 12)
- ci: let the release sync PR start its own CI and land
- fix(tiling): clamp floating-MODE members clear of the bars
- chore(comments): trim remaining files to §2.8 budget (batch 13)
- fix(settings): Save commits the draft, temporary layouts stay temporary
- feat(layout): default the BSP split strategy to alternating
- feat(gui): show the semantic version only in Settings
- chore(release): stamp version 1.1.2
1.1.1
A small patch about focus: one fix for the moment your Mac wakes, one for the keyboard path in Settings. The rest is housekeeping — the site now names the sticky feature what Settings names it, a localization tool refuses a half-redirect it once obeyed silently, and a broad comment trim landed across the Settings tree.
Waking up
- Shortcuts work right after your Mac wakes. Waking or
unlocking used to restore your focused window on screen — ring, bars, everything — while macOS quietly kept another app in front, so every shortcut was denied until a rescue click produced a real focus change. The wake restore now actually hands that window the focus (and when it is gone, the window genuinely in front), and if macOS refuses the handoff, the first key press heals it instead of dying.
The Settings keyboard path
- Jumping between areas keeps the keyboard with you.
Following a cross-reference link, or picking a search result that lives in another area, left keyboard focus stranded at the top of the window. It now lands on the ← Home chip, exactly as opening an area from Home always did, so Tab keeps walking from where you are. (As before, full keyboard access needs System Settings ▸ Keyboard ▸ Keyboard navigation turned on.)
- chore(site): sync release notes and feed for v1.1.0 by @github-actions[bot] in
- feat(site): the comparison page, and the site work it surfaced
- docs(agents): add the §2 comment budget
- chore(comments): trim gui to the §2.8 budget (batch 1)
- chore: drop the local-gate checkbox from the PR template
- fix(core): pay the wake restore's focus for real
- ci: run the required checks on merge-group refs
- chore(comments): trim onboarding and settings census to §2.8 budget
- chore(comments): trim settings census and components (batch 3)
- chore(comments): trim bars and colors settings (batch 4)
- docs(agents): land PRs through the merge queue
- chore: quiet the local test gate
- docs(site): call sticky "Sticky", the word Settings already uses
- fix(localization): refuse merge-keys under any extract override
- chore(comments): trim settings components to §2.8 budget (batch 5)
- fix(gui): state a focus destination on area→area navigation
- docs(site): rule the dashboard-held build watch paths
- chore(release): stamp version 1.1.1
1.1.0
The release where resizing a window started telling you the truth, and where the keys got out of your way. Most of what changed you will notice without looking for it. It gets more technical as you read down — and four things need a minute of your attention, marked where they come up.
Resizing, made honest
This got the most attention of anything in the release, because nearly every complaint about it turned out to be the same thing: KiwiDesk was resizing something other than what you asked, or refusing for a reason that did not exist.
- A resize press acts on the focused window, measured from the size it is actually drawn at. Before, the first several presses could do nothing visible, or silently resize every neighbour instead.
- Holding the chord resizes continuously, at your display's refresh rate, rather than stepping along a key-repeat timer that got slower the longer you held it.
- A floating window grows and shrinks from both edges, keeps working when it is parked against the edge of the screen, and will not grow underneath a bar. Held resizing on a floating window now travels the whole distance you asked for — with Reduce Motion on, it used to deliver under a third of it.
- When an app refuses to go smaller or larger, you are told on the first press. "Maximum window size reached" is a message now, in your language, instead of ten silent presses followed by the window snapping back.
- Resizing stopped stalling. A pass that froze for up to two seconds and then jumped now runs clean; in the measured session, forty-two stalls became one.
- Scrolling spaces stopped sliding. Resizing no longer drags the focused window toward the leading edge, a slot cannot be grown past what is drawn, and a window resting against the trailing border keeps that border.
- Apps that fight back are handled. The Android emulator and its kind used to send tiling into an endless expand-and-snap loop about once a second. Now there is one adjustment when the window appears, and then the row settles.
A keyboard layout that gets out of the way — and how to take it up
The shipped shortcuts were re-measured against what macOS and common apps actually claim, and moved accordingly.
- Resizing has its own layer, ⌥⌘, on digits rather than arrows — ⌥⌘1/⌥⌘2 for width, ⌥⌘4/⌥⌘5 for height. Arrows were rejected because ⌥⌘ with arrows is next and previous tab in most browsers and terminals, and those have no menu to fall back on.
- ⇧ means one thing again. Sticky moved to ⌃⌥S for everywhere and ⌃⌥P for this screen only.
- The numeric keypad works. Keypad digits fire the same bindings as their number-row twins — so if you already have space shortcuts on ⌃⌥1 through ⌃⌥9, they start answering the keypad the moment you upgrade, with nothing to configure.
- Worth knowing: none of the other shortcut changes reach an existing install by themselves. The shipped set is seeded only into a configuration that has no shortcuts at all, so it never overwrites anything you or your Lua wrote. If you have been using KiwiDesk, your keys are exactly where you left them.
- Restore Defaults… is how you take them up, at the top of Settings ▸ Shortcuts. It puts back the set a fresh install would get — for your Desktops and your resize step, not a fixed list — including defaults added since you installed. Your own shortcuts are kept. The one exception is a shortcut of yours sitting on a key a default needs, which cannot stay without putting two bindings on one key; the confirmation counts those before you agree, and says so plainly when the answer is none. Settings search finds it under "restore", "defaults" or "reset".
- The guide now teaches how to choose a shortcut of your own — what makes a chord safe, why ⌃⌥ is the quiet corner, and the one thing worth doing before you commit to a new one. In English, German and Japanese.
Reduce Motion and VoiceOver
- Reduce Motion is honoured across Settings. Layout previews arrive instead of springing, and fifty-one animation sites that ignored the system setting now stand down with it.
- Starting VoiceOver no longer steals your focus to a different app a few seconds later.
- Drawer headers behave as one thing across fifteen drawers, and all of them join the VoiceOver headings rotor.
Start at login does one job now
- The switch installs the login item and nothing else. Crash supervision used to ride along with it, unasked. It is still available, deliberately, as kiwidesk service from the command line.
- If you relied on that supervision, turn it on explicitly after upgrading. Nothing else changes for you.
- Turning Start at login on while KiwiDesk is running no longer steals focus every ten seconds, indefinitely.
- The update prompt comes to the front when it is ready to install and restart, instead of waiting behind every other window where it could not be found.
KiwiDesk can move around macOS's Desktops
- Switching Desktops and sending windows between them now works — on stock macOS, with System Integrity Protection on. This was listed as impossible for most of KiwiDesk's life. Two new commands, focus_desktop and move_to_desktop, and the Space Bar and shortcut editor speak them like anything else.
- A switch KiwiDesk drives performs the real transition, instead of leaving two Desktops drawn on top of each other for a moment.
- Moving a window to another Desktop and following it lands your keyboard focus on that window, every time, rather than most of the time.
- A window sent to a Desktop on another screen stays there instead of springing back to where it came from.
- Switching Desktops settles immediately. It used to take five to ten seconds to stop rearranging, even switching to an empty one.
Scripting
- Every command describes itself. kiwidesk list_commands now documents all 262 — group, typed arguments, and a one-line summary each. kiwidesk help <command> works, and list_commands <group> filters instead of returning everything.
- Output is readable at a terminal and unchanged in a pipe. Pretty-printed when you are looking at it, the same compact line when a script is reading it. Keys are sorted either way.
- One rename needs your hand: animations.set_scroll_speed is now animations.set_scroll_duration. It always was the duration — raising it made scrolling slower — and the setting is renamed in the interface to match. Your stored configuration is migrated for you. Lua is not, on purpose: if your init.lua or one of your keybindings calls set_scroll_speed, it will fail loudly at the moment you press it, which is better than failing silently. Rewrite it once and it is done.
Also
- New installs open in Scrolling on every screen but the smallest, with a deliberate slot width instead of an automatic one. Existing setups are untouched.
- One word per concept, in every language. Width, floating, the Track unit, and "make it bigger" each had two words in at least one language and now have one. Japanese and Korean can now tell Go to Space from Move to Space, and German and Korean can tell the shortcuts a profile inherits from the ones KiwiDesk ships.
- The Restore Defaults confirmation speaks your language. It was English everywhere but English — at the one moment it is telling you what you are about to lose.
- Your profiles move to a newer format the first time this version saves one, which means 1.0.1 cannot read them afterwards. Nothing to worry about: kiwis only grow, they never shrink back. 🥝
- chore(site): sync release notes and feed for v1.0.1 by @github-actions[bot] in
- chore(site): sync release notes and feed for v1.0.1 by @github-actions[bot] in
- chore: weekly dependency PRs, and the VoiceOver limitation from #961
- fix(ci): remove prerelease flag from release draft creation
- ci: bump actions/upload-artifact from 6 to 7 by @dependabot[bot] in
- fix(i18n): remove obsolete vat section from imprint
- ci: bump actions/setup-node from 6 to 7 by @dependabot[bot] in
- feat(commands): drive macOS Desktops — focus_desktop and move_to_desktop
- fix(state): a window keeps the Desktop it was sent to across screens
- fix(updates): bring the install-and-restart prompt forward
- ci: bump actions/checkout from 6 to 7 by @dependabot[bot] in
- fix(test): await the dwell and settle timelines instead of polling a clock
- feat(profiles): a fresh install opens in Scrolling on every screen but the smallest
- fix(gui): a Settings drawer header reads as one
- test: a scanning guard pins the shape, never the value
- feat(onboarding): the tour names the keys it teaches, and the app points at the guide
- fix(commands): perform the Desktop switch's missing transition
- chore(github): let the org's default carry the sponsor button
- fix(cli): print JSON a person can read, in an order that holds
- feat(commands): a follow carries focus to the window it moved
- perf(events): gate the bulk reconcile on one WindowServer census
- feat(site): refresh landing hero copy and mouse support highlights
- feat(commands): the API surface describes itself (part 1 of #1033)
- feat: ask for a GitHub star where it earns it
- feat(site): make the download the guide's one install path
- fix(site): let the maker quote straddle the tint seam again
- fix(shortcuts): dim an away Desktop row in the ⌃⌥K panel too
- feat(commands): every command describes itself (fixes #1033)
- feat(site): give each landing mode its own URL
- fix(settings): name the animation and its duration one way each
- fix(tiling): survive comply-then-snap-back apps (Android emulator)
- perf(events): boot passes queue only apps they can act on
- fix(layout): a scrolling resize re-anchors the viewport
- test(layout): the vertical ceiling guard passed without growing
- build(site): declare @astrojs/markdown-remark and guard the docs pipeline (fixes #985)
- fix(commands): a scrolling grow refuses at a learned app maximum
- fix(events): return the focus an accessibility steal misdirects
- fix(tiling): a corroborated bound answers asks beyond it
- fix(commands): a resize press measures from the drawn span
- fix(commands): the scrolling press base reads the engine's frame
- chore(commands): drop the axis read #1065 left unread
- feat(keys): hold the resize chord to keep resizing
- fix(gui): honour Reduce Motion in the Settings window
- fix(app): a second launch reports success, so launchd rests
- docs: correct how crash supervision actually starts
- fix(gui): Reduce Motion reaches the .animation modifier too
- feat(gui): Settings owns the login item, the CLI owns crash supervision
- docs(rules): a needle refinement states what it trades
- fix(tiling): a learned bound informs the layout, never refuses a press
- perf(events): stop starving our own frame clock
- docs(site): native tabs on the Nerd grid, and a balanced last row
- feat(keys): a held resize chord glides at display rate
- feat(keys): make the numeric keypad bindable
- feat(keys): move resize to a dedicated ⌥⌘ size layer
- feat(animation): a floating held resize keeps all of its motion
- chore(i18n): one verb per catalog for the grow action
- feat(tiling): a floating resize splits its delta and pins at edges
- fix(i18n): scope the Size & float caption without naming a verb
- docs(keys): measure the ⌥⌘ digit base instead of citing Xcode
- chore(i18n): one word per concept for width, floating and Track
- feat(keys): give ⇧ one meaning — re-letter the sticky toggles
- feat(keys): restore the shipped shortcuts into an existing install
- docs(site): teach choosing a shortcut, in every language
- fix(i18n): give de and ko a word of their own for the base shortcuts
- feat(gui): declare Restore Defaults in the settings census
- i18n(keys): translate the Restore Defaults confirmation
- chore(release): stamp version 1.1.0
1.0.1
A small release with one thing to know if you script KiwiDesk. Nothing about how your windows behave changes.
One word for macOS Desktops, everywhere
- native_space is now desktop on the wire. The copy has said *Desktop* for macOS's desktops and *Space* for KiwiDesk's own since 0.9.7; the commands and events now say the same. If your init.lua binds profiles to Desktops, or a script listens for the switch event, update the spelling — the old names are gone, not aliased: KiwiDesk.bind_profile_to_native_space(n, profile) is now KiwiDesk.bind_profile_to_desktop(n, profile), the native_space_change event is now desktop_change, and kiwidesk get_state reports desktop instead of native_space.
- Bindings made in the Settings window need nothing from you. They live in KiwiDesk's own settings file, not in init.lua, and keep working as they are.
- chore(site): sync release notes and feed for v1.0.0 by @github-actions[bot] in
- feat(site): the changelog's download says which version it hands you
- feat(site): retire the beta framing now that 1.0 has shipped
- feat(docs): add GitHub Sponsors badge and refine version dot glow
- fix(test): await reveal timelines instead of polling a clock
- chore(site): refresh the npm tree and clear its four advisories
- feat(os): add the WMBridge wrapper for SkyLight's operation classes
- refactor: say Desktop on the whole macOS-Desktop wire
- chore(release): stamp version 1.0.1
1.0.0
The Kiwi is ripe. KiwiDesk is 1.0. 🥝
Ready is the headline
- 1.0 is not a feature dump, it is a verdict. Seven layouts, Lua configuration, profiles, per-Desktop setups, the App and Space Bars, and a Settings window you can drive end to end from the keyboard — all of it has been carrying real desks through the beta. Nothing about how your windows behave changes today, and that is exactly what a 1.0 should feel like: the boring release, arrived at on purpose.
Just download it already
- Homebrew is no longer the price of entry. Take the signed, notarized disk image from the KiwiDesk site, drag the kiwi into your Applications folder, and you are done. No terminal, no tap, no incantation.
- Same app whichever way you get it. Homebrew keeps one perk — it puts the kiwidesk command on your PATH — and from then on KiwiDesk quietly keeps itself up to date either way.
Also
- The site now argues for KiwiDesk the way the people using it do, by naming the everyday Mac annoyances it takes off your hands. It also says out loud that Settings can be driven entirely by VoiceOver and the keyboard, and the release-notes page no longer sprawls to the window edge.
- chore(site): sync release notes and feed for v0.9.10 by @github-actions[bot] in
- feat(site): promote the direct download and argue from the papercuts
- chore(release): stamp version 1.0.0