Skip to content

Releases: pszypowicz/cyclist

Cyclist 0.5.0

Choose a tag to compare

@pszypowicz pszypowicz released this 17 Jul 20:48
0f02675

A concurrency rearchitecture: everything is measurably faster, and several long-standing races are fixed.

Faster switching

  • The window sweeps behind the switcher moved off the main thread onto a background queue with per-app parallelism, and their Accessibility reads are batched four-into-one. Healthy quick taps commit in ~140ms end to end (was ~215ms); an unresponsive app now costs its own timeout instead of stalling every keystroke system-wide (~354ms -> ~190ms with three hung apps, keyboard never blocked).
  • Cross-Space arrivals repaint almost immediately: window handles are cached across Spaces, so the purged-backing repaint lands in tens of milliseconds instead of a visible blank beat.
  • The Space-navigation settle floor was re-measured on macOS 26.5 and dropped from 250ms to 50ms between chained hops - multi-Space journeys are up to 200ms faster per hop.

Fixed

  • Rapid bouncing between a fullscreen and a normal window of the same app no longer derails to a third window or re-commits the current one.
  • Bare-wallpaper arrivals under fast bouncing are gone (hardened repaint with retries and a safety repeat).
  • A quick window-cycle right after a mouse app switch lists the frontmost app's windows, not the previously committed app's.
  • A delayed snapshot retry can no longer replay a stale quick-tap commit over a newer one.
  • The switcher panel no longer leaks - and slowly slows down - on display sleep/wake and resolution changes.
  • An app whose windows are all minimized no longer pays a 150ms retry on every window-cycle press (with minimized rows hidden).
  • A Space shortcut sharing a combo with a session key can no longer hijack list navigation.

Internals

  • "What is the user on right now?" is answered by one current-window authority instead of three overlapping mechanisms.
  • The release was audited by three independent review passes (dead code, correctness, efficiency); remaining watch-items were closed by measurement, with permanent debug telemetry (sweep timing, repaint attempts, panel selection) left in place.

Requirements

Unchanged: macOS 26 (Tahoe), Accessibility required, Screen Recording optional.

Cyclist 0.4.1

Choose a tag to compare

@pszypowicz pszypowicz released this 17 Jul 17:04
07c1bca

The menu bar icon becomes optional.

Optional menu bar icon

  • Settings > General gains "Show menu bar icon" (showMenuBarIcon in defaults). Cyclist keeps running without it; the change applies live, no restart.
  • Ways back while the icon is hidden: hold the switcher open and press , to open Settings (Cmd+Q there quits), or simply relaunch Cyclist - reopening the app now always presents the Settings window.

Requirements

Unchanged: macOS 26 (Tahoe), Accessibility required, Screen Recording optional.

Cyclist 0.4.0

Choose a tag to compare

@pszypowicz pszypowicz released this 17 Jul 15:55
1958db7

The switcher grows a real Settings window and rebindable shortcuts, and configuration moves to standard user defaults.

Settings window

  • The status menu slims to Settings, About, and Quit; everything else lives in a two-column Settings window. Cmd+, opens it while the switcher is held open, and Cmd+W / Cmd+Q work inside it.
  • The less obvious settings carry an info dot with a quick hover explanation.
  • Launch at Login lives there too and resyncs itself after changes made in System Settings > General > Login Items.
  • New About window with version and project links.

Rebindable shortcuts

  • The four global bindings - open switcher, cycle app windows, previous/next Space - are recordable in Settings: click the shortcut, press the new keys; Esc cancels. Shift stays the reverse key, so a binding needs a real modifier and shift-variants count as duplicates.
  • Keyboard Space navigation has an on/off switch alongside the trackpad-swipe one.

Configuration is user defaults

  • Every setting is a key under io.github.pszypowicz.Cyclist - the README documents the full table. defaults write applies to the running app immediately, rebinds included.
  • Breaking: the ~/.config/cyclist/cyclist.toml file is no longer read. Move any non-default values to defaults write (the README table maps them one to one).
  • The Enabled switch is gone: quitting Cyclist is the disable, and every native shortcut returns the moment it exits.

Fixes

  • The window-title cache evicts closed windows instead of growing for the whole boot session.
  • An AeroSpace request timeout no longer completes twice and desyncs the workspace cache refresh.
  • A shortcut recording now dies with the Settings window instead of swallowing keystrokes system-wide.
  • Less per-event work on the keystroke reject path in the event tap.

Requirements

Unchanged: macOS 26 (Tahoe), Accessibility required, Screen Recording optional.

Cyclist 0.3.1

Choose a tag to compare

@pszypowicz pszypowicz released this 15 Jul 20:24
469242e

Adds keyboard control of the open switcher list and evens out the panel spacing.

While the switcher is held open

  • Up/Down and vim j/k move the selection.
  • q quits the selected app, like native Cmd+Tab's Q; its rows leave the list and the session continues on the rest. Finder is gated the way the Dock and AltTab gate it - quittable only after defaults write com.apple.finder QuitMenuItem -bool true, otherwise it beeps and stays.
  • w closes the selected window.

Quit and close edit the live session in place: the selection clamps to a survivor, and the session ends only when nothing remains.

Fixes

  • The panel now keeps even top and bottom margins as the list grows (the height calculation was undercounting inter-row spacing and one content inset), and a visible panel resizes when rows are removed mid-session.
  • A brand-new window is ranked on its creation event, so a window revealed by a close or quit is never briefly unranked.

Requirements

Unchanged: macOS 13+, Accessibility required, Screen Recording optional.

Cyclist 0.3.0

Choose a tag to compare

@pszypowicz pszypowicz released this 15 Jul 19:58
f5086f0

Third beta. The switcher learns which window you used last, AeroSpace workspaces join Space navigation, and the hard signals moved to the WindowServer.

AeroSpace integration (optional)

  • With AeroSpace running, Ctrl+Left/Right walks workspace 1 ... N, fullscreen Spaces as one ring: workspace steps go over AeroSpace's socket, and crossing from a fullscreen Space lands on the adjacent workspace. Windows parked in hidden workspaces show as workspace N switcher rows and commit through a single AeroSpace focus command.
  • Detection is automatic, with a menu-bar toggle (default on). AeroSpace absent, quit, killed, or disabled via aerospace enable off - each reverts to plain native behavior before the next keypress, push-detected over the socket.

Window recency

  • The Cmd+Tab quick tap switches to the previous window, wherever it lives - bouncing between two windows of one app now works, across Spaces and workspaces alike.
  • Rows within an app sort by focus recency, and Cmd+` cycles in most-recently-used order and reaches windows in other Spaces (native fullscreen included), with a quick tap bouncing between the app's last two windows.

Faster and more precise

  • Focus tracking, Space-change detection, and real-window classification come from the WindowServer notification stream - immune to busy apps and broken Accessibility trees.
  • Space navigation is event-gated at a measured 250ms settle instead of a blanket 1.15s floor: sustained Ctrl+arrow chains step about 4x faster and arrivals confirm in ~60ms. The measurement mode ships in the binary (Cyclist --measure-swipe-floor) for revalidating after macOS updates.
  • Fullscreen apps no longer produce a phantom duplicate switcher row (the fullscreen toolbar companion window is filtered out via WindowServer records).

Requirements

Unchanged: macOS 13+, Accessibility required, Screen Recording optional (live titles for other-Space windows). The AeroSpace integration needs no additional permissions.

Cyclist 0.2.0

Choose a tag to compare

@pszypowicz pszypowicz released this 14 Jul 07:11

Second beta. Everything since the text-only Cmd+Tab MVP.

Highlights

  • Every window is its own switcher row (App - Window title), including windows in other Spaces and native fullscreen; selecting one jumps straight to its Space. Live titles for other-Space windows with the optional Screen Recording permission.
  • Cmd+` cycles the frontmost app's windows, minimized ones included.
  • Ctrl+Left/Right walks Spaces in Mission Control order - instantly, no animation - and focuses the top window when landing on a desktop. Native trackpad gestures are untouched; quit Cyclist and the native shortcuts work as before.

Reliability on macOS 26 (Tahoe)

  • Space switches no longer intermittently land on an empty desktop: synthetic swipe posting is paced and coalesced around a measured compositor limitation, arrival is verified against live state, and window focus follows the system's space-change notification, so keyboard focus lands together with the visual switch.
  • Logging moved to the unified logging system (subsystem io.github.pszypowicz.Cyclist). Debug diagnostics, including a pixel-level transition sentinel, cost nothing unless armed with log stream --level debug or log config.

Removed

  • Built-in 3-finger swipe handling - trackpad gestures belong to macOS.
  • The --goto-space CLI.

Requirements

macOS 13 or later; Accessibility permission required, Screen Recording optional. The app is signed with a personal development certificate, so installs outside the Homebrew tap need a manual Gatekeeper exception.