Compare commits

..
1889 Commits
Author SHA1 Message Date
semantic-release-bot 4ecfc4606f chore(release): 100.2.0 [skip ci]
# [100.2.0](https://github.com/KofTwentyTwo/CommandTabFree/compare/v100.1.0...v100.2.0) (2026-06-16)

### Features

* **updates:** enable Sparkle auto-update via GitHub Pages appcast ([45457cb](https://github.com/KofTwentyTwo/CommandTabFree/commit/45457cb))
2026-06-16 21:05:45 +00:00
james.maes 45457cb313 feat(updates): enable Sparkle auto-update via GitHub Pages appcast
Point DOMAIN at the repo's GitHub Pages site (serves the gh-pages appcast.xml), enable SUEnableAutomaticChecks, and remove the in-tree appcast skeleton (feed is published out-of-tree). Ships an auto-updating build.
2026-06-16 16:02:04 -05:00
james.maes 62e0226f01 ci: stop release tail clobbering .fork-sync-state cursor [skip ci]
Reset .fork-sync-state to v11.3.0 (last-synced upstream tag) and remove the release-tail step that overwrote it with the fork release tag, which would stall upstream-sync. Update SESSION-STATE/TODO/CICD-STATUS/README for the live signed+notarized v100.1.0 release.
2026-06-16 15:32:55 -05:00
github-actions[bot] 92254c021f chore(sync-state): advance to v100.1.0 [skip ci] 2026-06-16 19:48:28 +00:00
semantic-release-bot 0aca4d9400 chore(release): 100.1.0 [skip ci]
# [100.1.0](https://github.com/KofTwentyTwo/CommandTabFree/compare/v100.0.3...v100.1.0) (2026-06-16)

### Bug Fixes

* **ci:** build ad-hoc until Apple cert provisioned ([6070f0c](https://github.com/KofTwentyTwo/CommandTabFree/commit/6070f0c))
* **l10n:** regenerate base Localizable.strings from source ([d1e1b29](https://github.com/KofTwentyTwo/CommandTabFree/commit/d1e1b29))

### Features

* **release:** sign + notarize with fork Developer ID ([2f9fac1](https://github.com/KofTwentyTwo/CommandTabFree/commit/2f9fac1))
2026-06-16 19:48:19 +00:00
james.maes 2f9fac17b7 feat(release): sign + notarize with fork Developer ID
Set the fork Developer ID in config/local.xcconfig (Manual style + team), re-sign the vendored Sparkle helpers under it, and import the cert with an optional APPLE_P12_PASSWORD. Built, signed, and notarized (Accepted) locally before cutting.
2026-06-16 14:42:45 -05:00
james.maes 4a007e88c9 docs: add owner-gated TODO; tidy SESSION-STATE
Capture the owner-gated remaining work (publishing pipeline blockers) in docs/TODO.md; make SESSION-STATE HEAD reference hash-stable.
2026-06-16 12:55:22 -05:00
james.maes 885c52567d docs: record CI green + ad-hoc build fix + sync labels
Push CI is fully green (run 27634828800). NEXT SESSION blocker resolved; remaining work is owner-gated only.
2026-06-16 12:16:12 -05:00
james.maes 6070f0cbb9 fix(ci): build ad-hoc until Apple cert provisioned
Release build inherited upstream's Developer ID and failed on CI (exit 65, no cert). Build ad-hoc when the release gate is not signing-ready; build_app.sh now forwards xcodebuild overrides. Auto-switches to signed when the owner adds the cert.
2026-06-16 12:08:05 -05:00
james.maes d1e1b29623 fix(l10n): regenerate base Localizable.strings from source
Base strings drifted from source after the About redesign and brand sweep; regenerating via genstrings unblocks the generated-files CI gate. Dead paywall strings stay upstream-branded to keep merge surface minimal.
2026-06-15 15:22:49 -05:00
james.maes 2588101096 docs: correct CI/CD status + add NEXT SESSION handoff 2026-06-15 15:07:12 -05:00
james.maes 6313c295f3 docs: record CI/CD wiring + Guard B fix (green on unblocked) 2026-06-15 14:55:24 -05:00
james.maes d3e7529d91 ci: fix Guard B to match shipped de-paywall patch (guard-false-else + depaywall marker) 2026-06-15 14:52:09 -05:00
james.maes 287c4a07c4 ci: gate release tail on owner secrets (push CI green until then); sign_update --ed-key-file; commitlint sync-merge ignores; drop upstream-only scripts 2026-06-15 14:45:14 -05:00
james.maes eb95ad2d52 docs(readme): note .dmg/.zip direct-download install option 2026-06-15 14:31:18 -05:00
james.maes b9e871f176 chore: repo renamed alt-tab-free → CommandTabFree (update URLs); drop JetBrains sponsor from README 2026-06-15 14:13:53 -05:00
james.maes 39f10cfba3 docs: mark ⌘⇥ app icon as final (owner-approved), drop real-artwork TODO 2026-06-15 14:05:16 -05:00
james.maes 5b590bd6e5 docs: README install section + mark §3.1 brand/l10n/icon items done 2026-06-15 14:00:35 -05:00
james.maes 0b6d389842 docs: bump SESSION-STATE to v100.0.3 (full l10n rebrand) 2026-06-15 13:44:18 -05:00
james.maes adcd7c5f93 l10n: rebrand AltTab→CommandTabFree across all language tables (attribution kept) 2026-06-15 13:13:16 -05:00
james.maes b2cad34a6a docs: bump SESSION-STATE to v100.0.2 (menu icon, About redesign, l10n tidy) 2026-06-15 13:08:42 -05:00
james.maes 76ef4e49a5 l10n: rebrand AltTab→CommandTabFree in base+en strings (attribution kept) 2026-06-15 12:52:50 -05:00
james.maes acef128bbd feat(about): KofTwentyTwo identity + AltTab attribution links; drop Support button 2026-06-15 12:43:11 -05:00
james.maes 7f2a483ad2 brand: menu bar icons → command-tab (⌘⇥) glyph, matching app icon 2026-06-15 12:16:32 -05:00
james.maes 0b021beda7 chore: gitignore vendor/*/build (Xcode per-package output) 2026-06-15 11:58:47 -05:00
james.maes 4c169ef3d7 docs: record v100.0.1 release, brew tap, Sparkle key wiring + build gotcha 2026-06-15 11:57:32 -05:00
james.maes c7d2d9681e feat(sparkle): wire fork EdDSA public key; disable auto-checks 2026-06-15 11:42:28 -05:00
james.maes edf499d19e docs: session-state handoff (depaywall-free) 2026-06-15 09:53:20 -05:00
james.maes 98a023aa03 brand: placeholder app icon (command-tab glyph) + fix scheme product name to CommandTabFree.app 2026-06-15 08:57:37 -05:00
james.maesandClaude Opus 4.8 f5f9034d41 brand: rename user-facing AltTab → CommandTabFree, update About dialog (upstream attribution preserved)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 08:55:39 -05:00
james.maes e2429096d7 build: default CURRENT_PROJECT_VERSION=0.0.0 for local builds (App.version crash) 2026-06-15 08:51:15 -05:00
james.maes 4d82a684f3 chore: set fork identity — CommandTabFree / com.koftwentytwo.commandtabfree (frozen) 2026-06-10 17:03:12 -05:00
james.maes 6795ff43fb docs: mark Test scheme GREEN — 16 legacy paywall tests resolved (1a914c88) 2026-06-10 13:57:20 -05:00
james.maes 1a914c88f5 test: skip legacy paywall-behaviour tests (depaywall) — Test scheme green, anti-relock guards still active 2026-06-10 13:55:21 -05:00
james.maes 5c57cc738b docs: execution status + owner publish checklist (Test scheme RED on 16 legacy paywall tests — flagged BLOCKING) 2026-06-10 13:43:53 -05:00
james.maes 3dde8a91b6 chore: identity overlay + sync/guard/release CI scaffolding (placeholders flagged for owner) 2026-06-10 13:38:09 -05:00
james.maesandClaude Opus 4.8 4506c53958 test: anti-relock guards (pro never locked, incl. post-trial-expiry)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 13:32:00 -05:00
james.maes f3d7685984 depaywall: neutralize license gate, cookie, telemetry, and activate handler (src/pro left intact) 2026-06-10 13:29:52 -05:00
james.maes e243fb4bff docs: audit + republish/maintained-fork plans 2026-06-10 13:27:36 -05:00
semantic-release-bot 9fadf36bf8 chore(release): 11.3.0 [skip ci]
# [11.3.0](https://github.com/lwouis/alt-tab-macos/compare/v11.2.0...v11.3.0) (2026-06-04)

### Features

* better support adobe apps (closes [#5707](https://github.com/lwouis/alt-tab-macos/issues/5707)) ([f3fe535](https://github.com/lwouis/alt-tab-macos/commit/f3fe535))
2026-06-04 20:33:23 +00:00
lwouis f3fe535acb feat: better support adobe apps (closes #5707) 2026-06-04 21:56:59 +02:00
semantic-release-bot 8124cf5496 chore(release): 11.2.0 [skip ci]
# [11.2.0](https://github.com/lwouis/alt-tab-macos/compare/v11.1.0...v11.2.0) (2026-06-04)

### Bug Fixes

* always persist menubar icon removal from dragging ([#5654](https://github.com/lwouis/alt-tab-macos/issues/5654)) ([a354fde](https://github.com/lwouis/alt-tab-macos/commit/a354fde))
* better handle some shortcut conflicts (related to 3059dc23) ([cddc89d](https://github.com/lwouis/alt-tab-macos/commit/cddc89d))
* command+tab would sometimes not bind correctly (closes [#5653](https://github.com/lwouis/alt-tab-macos/issues/5653)) ([c75aac5](https://github.com/lwouis/alt-tab-macos/commit/c75aac5))
* focus issues with show-main-window setting (closes [#5684](https://github.com/lwouis/alt-tab-macos/issues/5684)) ([0899f61](https://github.com/lwouis/alt-tab-macos/commit/0899f61))
* improve processing of accessibility events (closes [#5665](https://github.com/lwouis/alt-tab-macos/issues/5665)) ([e0b1778](https://github.com/lwouis/alt-tab-macos/commit/e0b1778))
* only show screen recording callout when it's needed (closes [#5623](https://github.com/lwouis/alt-tab-macos/issues/5623)) ([9a9994b](https://github.com/lwouis/alt-tab-macos/commit/9a9994b))
* preserve switcher selection across reorders (closes [#5665](https://github.com/lwouis/alt-tab-macos/issues/5665)) ([5bd746d](https://github.com/lwouis/alt-tab-macos/commit/5bd746d))
* settings window search and controls editor edge-cases ([c143ec2](https://github.com/lwouis/alt-tab-macos/commit/c143ec2))
* text shortcuts like cmd+a work in search mode (closes [#5675](https://github.com/lwouis/alt-tab-macos/issues/5675)) ([d483c5a](https://github.com/lwouis/alt-tab-macos/commit/d483c5a))
* very minor memory leak ([7d60d55](https://github.com/lwouis/alt-tab-macos/commit/7d60d55))

### Features

* do not repeat title if window title is app name (closes [#5672](https://github.com/lwouis/alt-tab-macos/issues/5672)) ([30eb5f2](https://github.com/lwouis/alt-tab-macos/commit/30eb5f2))

### Performance Improvements

* carry (pid, wid) in AX subscription refcon to skip identity calls ([a39816e](https://github.com/lwouis/alt-tab-macos/commit/a39816e))
* improve performance of the settings window ([3059dc2](https://github.com/lwouis/alt-tab-macos/commit/3059dc2))
2026-06-04 11:59:20 +00:00
lwouis cddc89dd21 fix: better handle some shortcut conflicts (related to 3059dc23) 2026-06-04 13:55:22 +02:00
lwouis 83b5ddc091 refactor: move debug-menu into qa-menu, and update it 2026-06-03 21:18:31 +02:00
lwouis 7d60d55395 fix: very minor memory leak 2026-06-03 21:17:45 +02:00
lwouis e0b1778db7 fix: improve processing of accessibility events (closes #5665) 2026-06-01 08:34:12 +02:00
lwouis 9a9994bf28 fix: only show screen recording callout when it's needed (closes #5623) 2026-06-01 08:34:12 +02:00
lwouis a39816e303 perf: carry (pid, wid) in AX subscription refcon to skip identity calls
AXObserverAddNotification's refcon was always nil. Bake the owning identity into it at subscribe time so the AX callback gets (pid, wid) for free, instead of an element.pid()/cgWindowId() round-trip per event. Window-level subscriptions carry a real wid; app-level subscriptions carry wid 0, so focus/main/created still resolve their per-event subject window from the element. Notably this gives a reliable wid for kAXUIElementDestroyed, which previously had to query an already-dead element.
2026-05-30 21:51:13 +02:00
lwouis c143ec2f0c fix: settings window search and controls editor edge-cases 2026-05-30 19:38:20 +02:00
lwouis 83f8ae18fa refactor: remove very minor leak or flagged-as-leak 2026-05-28 21:04:48 +02:00
lwouis f006b26931 refactor: improve specs/tests coverage 2026-05-28 19:28:49 +02:00
lwouis e4a306dc8c refactor: prevent appkit rare crashes due to in-flight tooltips 2026-05-28 14:11:14 +02:00
lwouis c75aac585a fix: command+tab would sometimes not bind correctly (closes #5653) 2026-05-28 14:00:57 +02:00
lwouis 60cca89bb8 refactor: add specs and coverage; move tests close to files 2026-05-28 14:00:57 +02:00
lwouis 0899f61654 fix: focus issues with show-main-window setting (closes #5684) 2026-05-28 13:56:51 +02:00
lwouis 3059dc2356 perf: improve performance of the settings window 2026-05-28 13:56:50 +02:00
lwouis 5bd746d342 fix: preserve switcher selection across reorders (closes #5665)
Async AX events (focused-window changed, app activated) can fire during
the switcher's show path and reorder Windows.list under the panel. The
old updateSelectedWindow short-circuited to the initial-pick path
whenever the lowest-lastFocusOrder window changed mid-show, throwing
away the user's selectedTarget and re-picking the default. Visible slot
swap plus highlight jump; if the user released keys early they landed
on the wrong window.

Extract a pure-function kernel (SelectionResolver) covering the full
selection state machine and replace updateSelectedWindow with a thin
snapshot/decide/apply wrapper. The actual fix is dropping the
focusedWindowChangedWhileShowing arm of shouldSelectFromScratch: the
list still reorders (Photoshop finishing launch is fresh state the
user wants reflected), but the existing target-by-id lookup re-resolves
the user's pick at its new index instead of being skipped.

28 new SelectionResolverTests lock down every selection path: initial
pick rules, target preservation across reorders (#5665 regressions),
target removal, search-mode flags, edge cases.

Also adds minimal Appearance and SettingsSearchIndex stubs to Mocks.swift
so the unit-test target builds. ProBadgeView and LightLabel referenced
those types without the underlying source being in the test target.
2026-05-28 13:56:50 +02:00
lwouis 9a47672920 refactor: log results of carbon shortcut apis (#5653) 2026-05-28 13:56:49 +02:00
lwouis a354fdecc8 fix: always persist menubar icon removal from dragging (#5654) 2026-05-28 13:56:49 +02:00
lwouis d483c5aa88 fix: text shortcuts like cmd+a work in search mode (closes #5675) 2026-05-28 13:56:48 +02:00
lwouis 30eb5f2116 feat: do not repeat title if window title is app name (closes #5672) 2026-05-28 13:56:48 +02:00
semantic-release-bot 14acc0ce7d chore(release): 11.1.0 [skip ci]
# [11.1.0](https://github.com/lwouis/alt-tab-macos/compare/v11.0.1...v11.1.0) (2026-05-25)

### Bug Fixes

* better handle electron apps hidden windows (closes [#5449](https://github.com/lwouis/alt-tab-macos/issues/5449)) ([0434679](https://github.com/lwouis/alt-tab-macos/commit/0434679))
* improve tab detection (closes [#5618](https://github.com/lwouis/alt-tab-macos/issues/5618)) ([a8098c3](https://github.com/lwouis/alt-tab-macos/commit/a8098c3))
* rare crash when assigning shortcuts with arrow keys ([4977808](https://github.com/lwouis/alt-tab-macos/commit/4977808))
* rare crash when capturing window thumbnails ([f4a54c8](https://github.com/lwouis/alt-tab-macos/commit/f4a54c8))
* very rare crash on quit ([007edc6](https://github.com/lwouis/alt-tab-macos/commit/007edc6))

### Features

* support setups with non latin keyboard layouts (closes [#5607](https://github.com/lwouis/alt-tab-macos/issues/5607)) ([f0e195d](https://github.com/lwouis/alt-tab-macos/commit/f0e195d))
2026-05-25 11:42:42 +00:00
lwouis 04346790b8 fix: better handle electron apps hidden windows (closes #5449) 2026-05-25 11:37:54 +02:00
lwouis f49250aa45 refactor: silence swiftui logs when debugging 2026-05-25 10:53:39 +02:00
lwouis a8098c39db fix: improve tab detection (closes #5618) 2026-05-25 10:36:56 +02:00
lwouis f0e195d0de feat: support setups with non latin keyboard layouts (closes #5607) 2026-05-25 09:41:46 +02:00
lwouis 49778089ea fix: rare crash when assigning shortcuts with arrow keys 2026-05-25 09:35:27 +02:00
lwouis f4a54c8f1b fix: rare crash when capturing window thumbnails 2026-05-24 22:00:29 +02:00
lwouis 007edc624e fix: very rare crash on quit 2026-05-24 21:14:39 +02:00
lwouis b6af54425e refactor: remove references to poeditor files we removed 2026-05-24 17:41:34 +02:00
semantic-release-bot 146e2aec46 chore(release): 11.0.1 [skip ci]
## [11.0.1](https://github.com/lwouis/alt-tab-macos/compare/v11.0.0...v11.0.1) (2026-05-22)

### Bug Fixes

* cmd key could be stuck after switching (closes [#5650](https://github.com/lwouis/alt-tab-macos/issues/5650)) ([3a48a13](https://github.com/lwouis/alt-tab-macos/commit/3a48a13))
2026-05-22 17:12:59 +00:00
lwouis 3a48a13cb5 fix: cmd key could be stuck after switching (closes #5650) 2026-05-22 18:53:59 +02:00
lwouis 910288d149 ci: update github actions versions 2026-05-21 10:44:20 +02:00
semantic-release-bot 1f2b5a513e chore(release): 11.0.0 [skip ci]
# [11.0.0](https://github.com/lwouis/alt-tab-macos/compare/v10.12.0...v11.0.0) (2026-05-21)

### Features

* introducing alt-tab pro! ([9147a4a](https://github.com/lwouis/alt-tab-macos/commit/9147a4a)), closes [#5450](https://github.com/lwouis/alt-tab-macos/issues/5450) [#5539](https://github.com/lwouis/alt-tab-macos/issues/5539) [#5627](https://github.com/lwouis/alt-tab-macos/issues/5627) [#5509](https://github.com/lwouis/alt-tab-macos/issues/5509) [#5492](https://github.com/lwouis/alt-tab-macos/issues/5492) [#5585](https://github.com/lwouis/alt-tab-macos/issues/5585) [#5488](https://github.com/lwouis/alt-tab-macos/issues/5488) [#5583](https://github.com/lwouis/alt-tab-macos/issues/5583) [#5482](https://github.com/lwouis/alt-tab-macos/issues/5482) [#5313](https://github.com/lwouis/alt-tab-macos/issues/5313)

### BREAKING CHANGES

* announcement: https://github.com/lwouis/alt-tab-macos/discussions/5533

* improved performance, especially switcher responsiveness
* reduced battery usage even more
2026-05-21 08:28:52 +00:00
lwouis 9147a4a864 feat: introducing alt-tab pro!
BREAKING CHANGE: announcement: https://github.com/lwouis/alt-tab-macos/discussions/5533

* improved performance, especially switcher responsiveness
* reduced battery usage even more
* reduced ram usage (closes #5450, closes #5539, closes #5627)
* reduced app size even more
* polished many aspects of the ui; align more with liquid glass
* better handle "ghost" windows (closes #5509)
* fix issue with wrong window order (closes #5492)
* escape closes the switcher on tahoe (closes #5585)
* improve search matches (closes #5488)
* localizations trimmed and reviewed entirely (closes #5583)
* highlight matching app icons when searching, in addition to text
* better settings import/export
* reworked "send feedback" experience
* reworked exceptions ui (closes #5482)
* per-shortcut settings (closes #5313)
* rework about window
2026-05-21 10:21:25 +02:00
semantic-release-bot 317a485bcb chore(release): 10.12.0 [skip ci]
# [10.12.0](https://github.com/lwouis/alt-tab-macos/compare/v10.11.0...v10.12.0) (2026-04-13)

### Features

* remove the need to add email in feedback form ([da9a46b](https://github.com/lwouis/alt-tab-macos/commit/da9a46b))
* show usage stats in the about-window ([9c5b963](https://github.com/lwouis/alt-tab-macos/commit/9c5b963))
2026-04-13 09:03:24 +00:00
lwouis 20caf75096 ci: move appcast from github raw to website 2026-04-13 10:57:52 +02:00
lwouis 873aabec72 docs: add terms and privacy policies on website 2026-04-13 10:53:25 +02:00
lwouis da9a46bf49 feat: remove the need to add email in feedback form 2026-04-13 10:53:25 +02:00
lwouis 9c5b9630e8 feat: show usage stats in the about-window 2026-04-13 10:31:08 +02:00
semantic-release-bot 49a41bd66d chore(release): 10.11.0 [skip ci]
# [10.11.0](https://github.com/lwouis/alt-tab-macos/compare/v10.10.1...v10.11.0) (2026-04-08)

### Features

* add local usage stats for curious users ([8e07d26](https://github.com/lwouis/alt-tab-macos/commit/8e07d26))
2026-04-08 20:11:45 +00:00
lwouis 8e07d261b9 feat: add local usage stats for curious users 2026-04-08 22:02:28 +02:00
semantic-release-bot d222dbbb10 chore(release): 10.10.1 [skip ci]
## [10.10.1](https://github.com/lwouis/alt-tab-macos/compare/v10.10.0...v10.10.1) (2026-04-05)

### Bug Fixes

* about-alttab window would crash when opened (closes [#5491](https://github.com/lwouis/alt-tab-macos/issues/5491)) ([d5152fb](https://github.com/lwouis/alt-tab-macos/commit/d5152fb))
* rare crash sometimes when opening the app twice quickly ([47e6cbd](https://github.com/lwouis/alt-tab-macos/commit/47e6cbd))
* rare crash when scrolling some settings window views ([317d2ff](https://github.com/lwouis/alt-tab-macos/commit/317d2ff))
2026-04-05 15:40:34 +00:00
lwouis 47e6cbd987 fix: rare crash sometimes when opening the app twice quickly 2026-04-05 17:33:12 +02:00
lwouis 317d2ff78a fix: rare crash when scrolling some settings window views 2026-04-05 17:22:40 +02:00
lwouis d5152fba44 fix: about-alttab window would crash when opened (closes #5491) 2026-04-05 08:49:28 +02:00
lwouis 90cdd3544a ci: fix changelog broken by sitemap 2026-04-04 21:42:38 +02:00
lwouis 13340d82f6 ci: remove _redirects on cloudflare 2026-04-04 21:38:11 +02:00
semantic-release-bot 69f67ffeeb chore(release): 10.10.0 [skip ci]
# [10.10.0](https://github.com/lwouis/alt-tab-macos/compare/v10.9.0...v10.10.0) (2026-04-04)

### Bug Fixes

* better handle bugged apps with hidden windows (closes [#5296](https://github.com/lwouis/alt-tab-macos/issues/5296)) ([ff1e923](https://github.com/lwouis/alt-tab-macos/commit/ff1e923))
* improve reliability after sleep/wake ([1ab419d](https://github.com/lwouis/alt-tab-macos/commit/1ab419d))
* show more apps when adding an exception (closes [#5463](https://github.com/lwouis/alt-tab-macos/issues/5463)) ([41d608e](https://github.com/lwouis/alt-tab-macos/commit/41d608e))

### Features

* better recognizes tabbed windows ([170bd67](https://github.com/lwouis/alt-tab-macos/commit/170bd67))
* improve localizations ([fe6e52d](https://github.com/lwouis/alt-tab-macos/commit/fe6e52d))
* improved detection of windows and apps ([7a2a548](https://github.com/lwouis/alt-tab-macos/commit/7a2a548))
* update localizations ([ecafbe7](https://github.com/lwouis/alt-tab-macos/commit/ecafbe7))

### Performance Improvements

* improve badges retrieval ([edbbf20](https://github.com/lwouis/alt-tab-macos/commit/edbbf20))
2026-04-04 19:30:53 +00:00
lwouis fe6e52d691 feat: improve localizations 2026-04-04 21:26:45 +02:00
lwouis 6c35e10a66 ci: generate sitemap 2026-04-04 16:22:47 +02:00
lwouis 18b523e458 ci: migrate from netlify to cloudflare 2026-04-04 15:36:46 +02:00
lwouis 41d608efda fix: show more apps when adding an exception (closes #5463) 2026-03-29 18:22:52 +02:00
lwouis f1c59a2748 refactor: small improvements to concurrency 2026-03-28 17:21:10 +01:00
lwouis 0e897b0678 refactor: program main-menu instead of .xib
avoids SDK logs
not sure if easier to maintain though
2026-03-28 12:07:17 +01:00
lwouis 7a2a5482ae feat: improved detection of windows and apps
* find more windows and apps (e.g. apps that take 30s to launch)
* keep windows and apps more up-to-date
* more efficient, uses fewer resources
2026-03-28 11:57:48 +01:00
lwouis 170bd673e0 feat: better recognizes tabbed windows 2026-03-28 11:57:48 +01:00
lwouis ff1e92303a fix: better handle bugged apps with hidden windows (closes #5296) 2026-03-28 11:57:48 +01:00
lwouis edbbf2082c perf: improve badges retrieval 2026-03-28 11:57:48 +01:00
lwouis 1ab419dd09 fix: improve reliability after sleep/wake 2026-03-28 11:57:48 +01:00
lwouis 6bd5f26e1c refactor: improve logs for application discrimination 2026-03-24 11:35:05 +01:00
lwouis ecafbe7212 feat: update localizations 2026-03-22 18:51:57 +01:00
semantic-release-bot 173950af08 chore(release): 10.9.0 [skip ci]
# [10.9.0](https://github.com/lwouis/alt-tab-macos/compare/v10.8.0...v10.9.0) (2026-03-22)

### Bug Fixes

* panel may re-center when searching ([a1f8b18](https://github.com/lwouis/alt-tab-macos/commit/a1f8b18))

### Features

* new setting to not capture windows in background (closes [#5337](https://github.com/lwouis/alt-tab-macos/issues/5337)) ([5ed6c1d](https://github.com/lwouis/alt-tab-macos/commit/5ed6c1d)), closes [#5371](https://github.com/lwouis/alt-tab-macos/issues/5371)
* show better ui when there are no window (closes [#283](https://github.com/lwouis/alt-tab-macos/issues/283)) ([9f3e20a](https://github.com/lwouis/alt-tab-macos/commit/9f3e20a))
* update fr/en localizations ([630527e](https://github.com/lwouis/alt-tab-macos/commit/630527e))
2026-03-22 16:29:10 +00:00
lwouis 5ed6c1d9ce feat: new setting to not capture windows in background (closes #5337)
Also closes #5371
2026-03-22 17:19:19 +01:00
lwouis 630527e0b7 feat: update fr/en localizations 2026-03-22 17:19:19 +01:00
lwouis a1f8b18888 fix: panel may re-center when searching 2026-03-22 17:19:18 +01:00
lwouis 9f3e20a826 feat: show better ui when there are no window (closes #283) 2026-03-22 17:19:18 +01:00
lwouis dbc77fe214 ci: release notes should interpret markdown (closes #597) 2026-03-22 17:19:17 +01:00
semantic-release-bot be2de1ab83 chore(release): 10.8.0 [skip ci]
# [10.8.0](https://github.com/lwouis/alt-tab-macos/compare/v10.7.0...v10.8.0) (2026-03-20)

### Bug Fixes

* allow quitting multiple apps in a row (follow-up on [#5421](https://github.com/lwouis/alt-tab-macos/issues/5421)) ([56c1927](https://github.com/lwouis/alt-tab-macos/commit/56c1927))
* apps with no open window might not show up (closes [#5424](https://github.com/lwouis/alt-tab-macos/issues/5424)) ([8962ad1](https://github.com/lwouis/alt-tab-macos/commit/8962ad1))
* avoid repeating shortcut that was released (closes [#5429](https://github.com/lwouis/alt-tab-macos/issues/5429)) ([3b1c7c7](https://github.com/lwouis/alt-tab-macos/commit/3b1c7c7))
* switcher might show empty on rare occasions (closes [#5432](https://github.com/lwouis/alt-tab-macos/issues/5432)) ([6105bb3](https://github.com/lwouis/alt-tab-macos/commit/6105bb3))
* window order in the switcher might be incorrect ([#5346](https://github.com/lwouis/alt-tab-macos/issues/5346)) ([545d81d](https://github.com/lwouis/alt-tab-macos/commit/545d81d))

### Features

* allow next-window shortcut without modifiers (closes [#5433](https://github.com/lwouis/alt-tab-macos/issues/5433)) ([15ede93](https://github.com/lwouis/alt-tab-macos/commit/15ede93))
* stabilize ui during search (closes [#5431](https://github.com/lwouis/alt-tab-macos/issues/5431)) ([7dd11cf](https://github.com/lwouis/alt-tab-macos/commit/7dd11cf))
2026-03-20 20:57:34 +00:00
lwouis 56c1927584 fix: allow quitting multiple apps in a row (follow-up on #5421) 2026-03-20 21:52:24 +01:00
lwouis 7dd11cff01 feat: stabilize ui during search (closes #5431) 2026-03-20 21:52:24 +01:00
lwouis 15ede93868 feat: allow next-window shortcut without modifiers (closes #5433) 2026-03-20 21:52:23 +01:00
lwouis 4502e8bd15 refactor: improve logging of window discriminator logic 2026-03-20 21:52:23 +01:00
lwouis 6105bb30ad fix: switcher might show empty on rare occasions (closes #5432) 2026-03-20 21:52:22 +01:00
lwouis 545d81d872 fix: window order in the switcher might be incorrect (#5346) 2026-03-20 21:52:22 +01:00
lwouis 3b1c7c76a9 fix: avoid repeating shortcut that was released (closes #5429) 2026-03-19 21:11:06 +01:00
lwouis 8962ad1a54 fix: apps with no open window might not show up (closes #5424) 2026-03-16 19:44:17 +01:00
semantic-release-bot 39b818de11 chore(release): 10.7.0 [skip ci]
# [10.7.0](https://github.com/lwouis/alt-tab-macos/compare/v10.6.0...v10.7.0) (2026-03-15)

### Bug Fixes

* allow quitting multiple apps in a row (closes [#5421](https://github.com/lwouis/alt-tab-macos/issues/5421)) ([de9aaa1](https://github.com/lwouis/alt-tab-macos/commit/de9aaa1))
* avoid memory usage growth over time (closes [#5138](https://github.com/lwouis/alt-tab-macos/issues/5138)) ([739649a](https://github.com/lwouis/alt-tab-macos/commit/739649a))
* edit shortcuts in settings window search bar on first launch ([2adf741](https://github.com/lwouis/alt-tab-macos/commit/2adf741))
* prevent sheets from messing up thumbnails order ([#5346](https://github.com/lwouis/alt-tab-macos/issues/5346)) ([b008d63](https://github.com/lwouis/alt-tab-macos/commit/b008d63))
* thumbnails might be shown too small ([57c95a6](https://github.com/lwouis/alt-tab-macos/commit/57c95a6))

### Features

* reduce memory usage by storing fewer app icons ([b21168a](https://github.com/lwouis/alt-tab-macos/commit/b21168a))
2026-03-15 14:29:13 +00:00
lwouis b008d63928 fix: prevent sheets from messing up thumbnails order (#5346) 2026-03-15 15:19:38 +01:00
lwouis de9aaa1fc1 fix: allow quitting multiple apps in a row (closes #5421) 2026-03-15 15:15:07 +01:00
lwouis 739649a749 fix: avoid memory usage growth over time (closes #5138) 2026-03-14 18:44:57 +01:00
lwouis 2adf741355 fix: edit shortcuts in settings window search bar on first launch 2026-03-13 10:46:37 +01:00
lwouis ec763814a9 refactor: reduce ram usage by early returning when not visible 2026-03-13 10:27:00 +01:00
lwouis b21168a033 feat: reduce memory usage by storing fewer app icons 2026-03-13 10:22:04 +01:00
lwouis cf8a41528d refactor: throttling was not actually working 2026-03-12 17:15:24 +01:00
lwouis 57c95a6e35 fix: thumbnails might be shown too small 2026-03-12 11:24:47 +01:00
semantic-release-bot 17615d00a9 chore(release): 10.6.0 [skip ci]
# [10.6.0](https://github.com/lwouis/alt-tab-macos/compare/v10.5.0...v10.6.0) (2026-03-10)

### Bug Fixes

* allow edit shortcuts in the search bar (closes [#5308](https://github.com/lwouis/alt-tab-macos/issues/5308)) ([35ddbe7](https://github.com/lwouis/alt-tab-macos/commit/35ddbe7))
* better handle context menu in search bar ([9aea8f6](https://github.com/lwouis/alt-tab-macos/commit/9aea8f6))
* key repeat in search mode ([fd4e373](https://github.com/lwouis/alt-tab-macos/commit/fd4e373))
* preview may not update its position (closes [#5396](https://github.com/lwouis/alt-tab-macos/issues/5396)) ([dbadb2b](https://github.com/lwouis/alt-tab-macos/commit/dbadb2b))
* right-click and middle-click outside panel ([9969a07](https://github.com/lwouis/alt-tab-macos/commit/9969a07))
* show preview window on first shortcut press (closes [#5385](https://github.com/lwouis/alt-tab-macos/issues/5385)) ([106f7c9](https://github.com/lwouis/alt-tab-macos/commit/106f7c9))
* trackpad scrolling shouldn't also scroll on background apps ([cacb789](https://github.com/lwouis/alt-tab-macos/commit/cacb789))

### Features

* scrolling the settings update the sidebar (closes [#5400](https://github.com/lwouis/alt-tab-macos/issues/5400)) ([3b831d4](https://github.com/lwouis/alt-tab-macos/commit/3b831d4))
2026-03-10 20:49:15 +00:00
lwouis 35ddbe72ed fix: allow edit shortcuts in the search bar (closes #5308) 2026-03-10 21:33:46 +01:00
lwouis fd4e3734e8 fix: key repeat in search mode 2026-03-10 21:33:46 +01:00
lwouis cacb7891e7 fix: trackpad scrolling shouldn't also scroll on background apps 2026-03-10 21:33:44 +01:00
lwouis 9969a07b22 fix: right-click and middle-click outside panel 2026-03-10 21:33:25 +01:00
lwouis 9aea8f62c9 fix: better handle context menu in search bar 2026-03-10 21:33:00 +01:00
lwouis 106f7c90f9 fix: show preview window on first shortcut press (closes #5385) 2026-03-09 23:14:38 +01:00
lwouis 3b831d4e59 feat: scrolling the settings update the sidebar (closes #5400) 2026-03-09 23:09:46 +01:00
lwouis dbadb2b4e5 fix: preview may not update its position (closes #5396) 2026-03-09 16:34:17 +01:00
semantic-release-bot 7d0eb278bf chore(release): 10.5.0 [skip ci]
# [10.5.0](https://github.com/lwouis/alt-tab-macos/compare/v10.4.0...v10.5.0) (2026-03-08)

### Bug Fixes

* input with ime better interacts with search (closes [#5377](https://github.com/lwouis/alt-tab-macos/issues/5377)) ([15caa33](https://github.com/lwouis/alt-tab-macos/commit/15caa33))

### Features

* improved search results ([0f8d6f1](https://github.com/lwouis/alt-tab-macos/commit/0f8d6f1))
* refinements on mouse hover and dragging ([#5350](https://github.com/lwouis/alt-tab-macos/issues/5350)) ([643cc80](https://github.com/lwouis/alt-tab-macos/commit/643cc80))
2026-03-08 17:56:44 +00:00
lwouis 0f8d6f140a feat: improved search results 2026-03-08 18:49:58 +01:00
lwouis 15caa33a60 fix: input with ime better interacts with search (closes #5377) 2026-03-08 18:49:57 +01:00
lwouis d905617248 refactor: add log for menubar visibility change 2026-03-05 15:25:01 +01:00
lwouis 643cc80ae0 feat: refinements on mouse hover and dragging (#5350) 2026-03-05 15:25:00 +01:00
semantic-release-bot a867171a45 chore(release): 10.4.0 [skip ci]
# [10.4.0](https://github.com/lwouis/alt-tab-macos/compare/v10.3.0...v10.4.0) (2026-03-04)

### Bug Fixes

* clicking tiles required to release precisely (closes [#5373](https://github.com/lwouis/alt-tab-macos/issues/5373)) ([2c6c9fb](https://github.com/lwouis/alt-tab-macos/commit/2c6c9fb))
* issues when using multiple keyboard languages (closes [#2125](https://github.com/lwouis/alt-tab-macos/issues/2125)) ([ea7284b](https://github.com/lwouis/alt-tab-macos/commit/ea7284b))
* switcher may show windows in the wrong order (closes [#5346](https://github.com/lwouis/alt-tab-macos/issues/5346)) ([a632e42](https://github.com/lwouis/alt-tab-macos/commit/a632e42))

### Features

* add kazakh and improve all localizations ([0ad389a](https://github.com/lwouis/alt-tab-macos/commit/0ad389a))
* improve drag-and-drop over alttab (closes [#5350](https://github.com/lwouis/alt-tab-macos/issues/5350)) ([a809ffa](https://github.com/lwouis/alt-tab-macos/commit/a809ffa))
2026-03-04 18:43:30 +00:00
lwouis 2c6c9fb2cc fix: clicking tiles required to release precisely (closes #5373) 2026-03-04 19:37:39 +01:00
lwouis 0ad389aa6f feat: add kazakh and improve all localizations 2026-03-04 19:01:28 +01:00
lwouis a632e42fbc fix: switcher may show windows in the wrong order (closes #5346) 2026-03-04 11:45:58 +01:00
lwouis a809ffad61 feat: improve drag-and-drop over alttab (closes #5350) 2026-03-01 19:26:28 +01:00
lwouis ea7284b387 fix: issues when using multiple keyboard languages (closes #2125) 2026-03-01 16:45:30 +01:00
lwouis 37ba9662f1 docs: simplify website introduction page 2026-02-24 21:26:27 +01:00
lwouis 1f340a3590 ci: netlify deploy broke after they updated their ubuntu vm
make jekyll build use ruby 3 and more recent bundler, so it works on more recent VMs
2026-02-24 21:21:56 +01:00
semantic-release-bot f7368f0dfe chore(release): 10.3.0 [skip ci]
# [10.3.0](https://github.com/lwouis/alt-tab-macos/compare/v10.2.0...v10.3.0) (2026-02-24)

### Bug Fixes

* avoid clipping long settings window buttons (closes [#5320](https://github.com/lwouis/alt-tab-macos/issues/5320)) ([402b6f6](https://github.com/lwouis/alt-tab-macos/commit/402b6f6))
* closing a window would remove the thumbnail (closes [#5324](https://github.com/lwouis/alt-tab-macos/issues/5324)) ([451bbbe](https://github.com/lwouis/alt-tab-macos/commit/451bbbe))
* fade-out speed could show wrong value in rare cases ([f5e81fe](https://github.com/lwouis/alt-tab-macos/commit/f5e81fe))
* improve settings window on macos 10.13 ([5ce48c1](https://github.com/lwouis/alt-tab-macos/commit/5ce48c1))
* mouse hover would sometimes disappear ([8c7263e](https://github.com/lwouis/alt-tab-macos/commit/8c7263e))

### Features

* add ur/mr localizations + update all localizations ([dc538dc](https://github.com/lwouis/alt-tab-macos/commit/dc538dc))
* consolidate settings (closes [#1732](https://github.com/lwouis/alt-tab-macos/issues/1732)) ([219098d](https://github.com/lwouis/alt-tab-macos/commit/219098d))
* reduce app disk size ([3c95c6c](https://github.com/lwouis/alt-tab-macos/commit/3c95c6c))
2026-02-24 19:55:27 +00:00
lwouis dc538dc994 feat: add ur/mr localizations + update all localizations 2026-02-24 20:48:29 +01:00
lwouis 9f563bcec2 docs: release notes had bright titles in dark mode 2026-02-24 20:48:29 +01:00
lwouis 1ff8c9c19a docs: migrate faq to github discussions
also closes #5339
2026-02-24 20:48:28 +01:00
lwouis 810b7116cd chore: refresh controls ui on dark/light mode change 2026-02-24 20:48:28 +01:00
lwouis 3fb66d412a chore: derisk event handling (#5336)
* .listenOnly means we don't block event processing
* using CGEvent directly means we don't need main-thread to convert to NSEvent
2026-02-24 20:48:27 +01:00
lwouis 741b074134 chore: multiple shortcuts could be selected if scrolling 2026-02-24 20:48:27 +01:00
lwouis c3ef4bc87c chore: logs in the debug tools were hard to read in dark mode 2026-02-24 20:48:26 +01:00
lwouis f5e81fe8cd fix: fade-out speed could show wrong value in rare cases 2026-02-24 20:48:26 +01:00
lwouis 3c95c6c276 feat: reduce app disk size 2026-02-24 20:48:26 +01:00
lwouis f54aca3fd9 refactor: reuse nested-scrolling logic across controls and blacklist 2026-02-24 20:48:25 +01:00
lwouis 7220643c82 refactor: make migration code simpler 2026-02-24 20:48:25 +01:00
lwouis ede879f3d6 refactor: make language preferences drier 2026-02-24 20:48:24 +01:00
lwouis 8c7263e8f1 fix: mouse hover would sometimes disappear 2026-02-24 20:48:24 +01:00
lwouis 402b6f6ff1 fix: avoid clipping long settings window buttons (closes #5320) 2026-02-24 20:48:23 +01:00
lwouis 451bbbe035 fix: closing a window would remove the thumbnail (closes #5324) 2026-02-24 20:48:23 +01:00
lwouis db34a7eb8f refactor: use static vars/funcs as much as possible 2026-02-24 20:48:22 +01:00
lwouis 5ce48c18e6 fix: improve settings window on macos 10.13 2026-02-24 18:42:22 +01:00
lwouis 219098d6a3 feat: consolidate settings (closes #1732) 2026-02-24 18:42:21 +01:00
semantic-release-bot 5f87336f3f chore(release): 10.2.0 [skip ci]
# [10.2.0](https://github.com/lwouis/alt-tab-macos/compare/v10.1.0...v10.2.0) (2026-02-19)

### Bug Fixes

* improve settings ui on macos 10.13 ([#5255](https://github.com/lwouis/alt-tab-macos/issues/5255)) ([75347ad](https://github.com/lwouis/alt-tab-macos/commit/75347ad))
* rare crash when a window was opened ([28c4b12](https://github.com/lwouis/alt-tab-macos/commit/28c4b12))
* small issues when mouse hover is set to select (closes [#5292](https://github.com/lwouis/alt-tab-macos/issues/5292)) ([b9e0344](https://github.com/lwouis/alt-tab-macos/commit/b9e0344))
* sometimes the active app was not up-to-date (closes [#5291](https://github.com/lwouis/alt-tab-macos/issues/5291)) ([ea51d57](https://github.com/lwouis/alt-tab-macos/commit/ea51d57))

### Features

* add burmese + update all localizations ([f5e1014](https://github.com/lwouis/alt-tab-macos/commit/f5e1014))
* add new setting for auto size (closes [#3669](https://github.com/lwouis/alt-tab-macos/issues/3669)) ([c51376f](https://github.com/lwouis/alt-tab-macos/commit/c51376f))
* add setting to blacklist window by title (closes [#5299](https://github.com/lwouis/alt-tab-macos/issues/5299)) ([35eae11](https://github.com/lwouis/alt-tab-macos/commit/35eae11))
* can add running apps into blacklist (closes [#5268](https://github.com/lwouis/alt-tab-macos/issues/5268)) ([d5d6996](https://github.com/lwouis/alt-tab-macos/commit/d5d6996))
* remember position/size of secondary windows (closes [#5305](https://github.com/lwouis/alt-tab-macos/issues/5305)) ([4b85fb8](https://github.com/lwouis/alt-tab-macos/commit/4b85fb8))
2026-02-19 22:42:05 +00:00
lwouis f5e1014bce feat: add burmese + update all localizations 2026-02-19 23:34:57 +01:00
lwouis 75347adc8d fix: improve settings ui on macos 10.13 (#5255) 2026-02-19 23:34:56 +01:00
lwouis 35eae11389 feat: add setting to blacklist window by title (closes #5299) 2026-02-19 23:34:55 +01:00
lwouis 28c4b121ca fix: rare crash when a window was opened 2026-02-19 23:20:15 +01:00
lwouis d5d699659c feat: can add running apps into blacklist (closes #5268) 2026-02-19 23:20:14 +01:00
lwouis 4b85fb8cf7 feat: remember position/size of secondary windows (closes #5305) 2026-02-19 23:20:14 +01:00
lwouis c51376fd26 feat: add new setting for auto size (closes #3669) 2026-02-19 23:20:13 +01:00
lwouis b9e0344da4 fix: small issues when mouse hover is set to select (closes #5292) 2026-02-19 23:20:12 +01:00
lwouis ea51d57d3d fix: sometimes the active app was not up-to-date (closes #5291) 2026-02-19 23:20:12 +01:00
semantic-release-bot a7b7a79ece chore(release): 10.1.0 [skip ci]
# [10.1.0](https://github.com/lwouis/alt-tab-macos/compare/v10.0.0...v10.1.0) (2026-02-17)

### Bug Fixes

* better flow when last 2 windows are minimized (closes [#2159](https://github.com/lwouis/alt-tab-macos/issues/2159)) ([da6be20](https://github.com/lwouis/alt-tab-macos/commit/da6be20))
* issue with link drag-and-drop over the switcher (closes [#5292](https://github.com/lwouis/alt-tab-macos/issues/5292)) ([4e6361f](https://github.com/lwouis/alt-tab-macos/commit/4e6361f))
* trackpad gesture active when disabled (closes [#5301](https://github.com/lwouis/alt-tab-macos/issues/5301)) ([d074faa](https://github.com/lwouis/alt-tab-macos/commit/d074faa))

### Features

* allow settings export/import (closes [#4514](https://github.com/lwouis/alt-tab-macos/issues/4514)) ([69a9dfa](https://github.com/lwouis/alt-tab-macos/commit/69a9dfa))
2026-02-17 18:30:07 +00:00
lwouis 09789e297d refactor: remove unnecessary string 2026-02-17 18:24:48 +01:00
lwouis 69a9dfa41b feat: allow settings export/import (closes #4514) 2026-02-17 18:01:26 +01:00
lwouis 4e6361ff7b fix: issue with link drag-and-drop over the switcher (closes #5292) 2026-02-17 17:42:20 +01:00
lwouis 91d4a7781e refactor: update settings sidebar to liquid glass visuals 2026-02-17 17:42:18 +01:00
lwouis da6be203f0 fix: better flow when last 2 windows are minimized (closes #2159) 2026-02-17 11:45:55 +01:00
lwouis d074faafd1 fix: trackpad gesture active when disabled (closes #5301) 2026-02-17 10:38:08 +01:00
semantic-release-bot 39d7af8483 chore(release): 10.0.0 [skip ci]
# [10.0.0](https://github.com/lwouis/alt-tab-macos/compare/v9.0.0...v10.0.0) (2026-02-16)

### Bug Fixes

* app could crash in rare scenarios ([3de0276](https://github.com/lwouis/alt-tab-macos/commit/3de0276))
* launched app may not be seen as active (closes [#5291](https://github.com/lwouis/alt-tab-macos/issues/5291)) ([3e47ebe](https://github.com/lwouis/alt-tab-macos/commit/3e47ebe))
* quick switches could sometimes do nothing (closes [#5289](https://github.com/lwouis/alt-tab-macos/issues/5289)) ([82795d8](https://github.com/lwouis/alt-tab-macos/commit/82795d8))

### Features

* add debug tools ([07e4024](https://github.com/lwouis/alt-tab-macos/commit/07e4024))
* add fuzzy search mode (closes [#590](https://github.com/lwouis/alt-tab-macos/issues/590)) ([4e986f3](https://github.com/lwouis/alt-tab-macos/commit/4e986f3))
* allow up to 9 shortcuts ([#3882](https://github.com/lwouis/alt-tab-macos/issues/3882)) ([8cab3e1](https://github.com/lwouis/alt-tab-macos/commit/8cab3e1))
* new settings experience (closes [#5287](https://github.com/lwouis/alt-tab-macos/issues/5287)) ([3890beb](https://github.com/lwouis/alt-tab-macos/commit/3890beb))
* support app-icon badges with large numbers ([ceed334](https://github.com/lwouis/alt-tab-macos/commit/ceed334))
* support showing only non-visible spaces (closes [#1274](https://github.com/lwouis/alt-tab-macos/issues/1274)) ([51db0cb](https://github.com/lwouis/alt-tab-macos/commit/51db0cb))
* update bn localization ([3f1617c](https://github.com/lwouis/alt-tab-macos/commit/3f1617c))

### BREAKING CHANGES

* a whole new alt-tab experience by pressing "s". You can also set search as the default style in the settings
2026-02-16 23:04:53 +00:00
lwouis 2ee406c909 refactor: fix tests 2026-02-16 23:56:14 +01:00
lwouis 66db895dd3 refactor: missed some renames 2026-02-16 23:56:13 +01:00
lwouis 07e4024a9c feat: add debug tools 2026-02-16 23:56:13 +01:00
lwouis 8cab3e1f8b feat: allow up to 9 shortcuts (#3882) 2026-02-16 22:53:01 +01:00
lwouis 3f1617cba0 feat: update bn localization 2026-02-16 22:53:01 +01:00
lwouis 82795d845c fix: quick switches could sometimes do nothing (closes #5289) 2026-02-16 22:53:01 +01:00
lwouis 99201191f4 refactor: prevent ambiguous ids between apps and windows 2026-02-16 22:53:00 +01:00
lwouis 3de027644c fix: app could crash in rare scenarios
concurrency issues on preferences
2026-02-16 22:53:00 +01:00
lwouis 3e47ebec8e fix: launched app may not be seen as active (closes #5291) 2026-02-16 22:52:59 +01:00
lwouis 3890beb9d3 feat: new settings experience (closes #5287) 2026-02-16 22:52:58 +01:00
lwouis 93e2b35dc7 refactor: permissions window is lazily initialized 2026-02-16 22:52:57 +01:00
lwouis da21cb8e21 refactor: feedback window is lazily initialized 2026-02-16 22:52:57 +01:00
lwouis 14a0b716b6 refactor: preferences window is lazily initialized 2026-02-16 22:52:56 +01:00
Jakku Sakura 4e986f37a0 feat: add fuzzy search mode (closes #590)
BREAKING CHANGE: a whole new alt-tab experience by pressing "s". You can also set search as the default style in the settings
2026-02-16 22:52:56 +01:00
lwouis e3092b4299 chore: remove complex ai rules 2026-02-16 13:33:19 +01:00
lwouis ceed334b06 feat: support app-icon badges with large numbers 2026-02-16 13:33:18 +01:00
lwouis 51db0cb8e4 feat: support showing only non-visible spaces (closes #1274) 2026-02-16 13:33:18 +01:00
semantic-release-bot 3961f2a888 chore(release): 9.0.0 [skip ci]
# [9.0.0](https://github.com/lwouis/alt-tab-macos/compare/v8.3.4...v9.0.0) (2026-02-11)

### Bug Fixes

* missing thumbnails in rare cases ([3142590](https://github.com/lwouis/alt-tab-macos/commit/3142590))
* preserve scroll position in switcher if windows change ([fa9e4d0](https://github.com/lwouis/alt-tab-macos/commit/fa9e4d0))
* prevent macos 10.13 crash (closes [#5255](https://github.com/lwouis/alt-tab-macos/issues/5255)) ([d525d35](https://github.com/lwouis/alt-tab-macos/commit/d525d35))

### Features

* improve performance when many windows are open (closes [#5177](https://github.com/lwouis/alt-tab-macos/issues/5177)) ([5d0a92f](https://github.com/lwouis/alt-tab-macos/commit/5d0a92f))
* new thumbnails shadows in macos 26 style ([26d46e3](https://github.com/lwouis/alt-tab-macos/commit/26d46e3))
* update cs/el/fr/ru localizations ([2681218](https://github.com/lwouis/alt-tab-macos/commit/2681218))

### Performance Improvements

* better caanimation batching ([016052c](https://github.com/lwouis/alt-tab-macos/commit/016052c))
* cache expensive layout values ([904bd17](https://github.com/lwouis/alt-tab-macos/commit/904bd17))
* cache expensive layout values 2 ([13ed78b](https://github.com/lwouis/alt-tab-macos/commit/13ed78b))
* cache font from appearance ([305870b](https://github.com/lwouis/alt-tab-macos/commit/305870b))
* cache screen uuids and frontmost app ([a5135c5](https://github.com/lwouis/alt-tab-macos/commit/a5135c5))
* capture samplebuffer directly ([2bce0d2](https://github.com/lwouis/alt-tab-macos/commit/2bce0d2))
* create overlay view to optimize view count ([ec5802a](https://github.com/lwouis/alt-tab-macos/commit/ec5802a))
* do all mouse interactions globally instead of local tracking ([d89bc29](https://github.com/lwouis/alt-tab-macos/commit/d89bc29))
* have views under and over the thumbnailview ([b9637e5](https://github.com/lwouis/alt-tab-macos/commit/b9637e5))
* improve hiding the ui ([4f5e325](https://github.com/lwouis/alt-tab-macos/commit/4f5e325))
* merge mouseevents into cursorevents ([9edf312](https://github.com/lwouis/alt-tab-macos/commit/9edf312))
* move app icon capture to background queue ([5a35aa9](https://github.com/lwouis/alt-tab-macos/commit/5a35aa9))
* optim hangs from DebugMenu ([4b830e6](https://github.com/lwouis/alt-tab-macos/commit/4b830e6))
* prevent appkit work ([fefc491](https://github.com/lwouis/alt-tab-macos/commit/fefc491))
* prevent costly window recursive views update ([41e0e7c](https://github.com/lwouis/alt-tab-macos/commit/41e0e7c))
* prevent possible frequent permissions check ([216563b](https://github.com/lwouis/alt-tab-macos/commit/216563b))
* remove normalize-subview to avoid appkit work ([ce2dfc1](https://github.com/lwouis/alt-tab-macos/commit/ce2dfc1))
* simplify and combine views for better perf ([3a8c0f3](https://github.com/lwouis/alt-tab-macos/commit/3a8c0f3))
* small optimizations from profiling ([db314c9](https://github.com/lwouis/alt-tab-macos/commit/db314c9))
* throttle all window/app ax calls ([337e2fb](https://github.com/lwouis/alt-tab-macos/commit/337e2fb))
* update windows manually after 250s ([52530b2](https://github.com/lwouis/alt-tab-macos/commit/52530b2))
* use calayer instead of nsview for lightimageview ([7dec9da](https://github.com/lwouis/alt-tab-macos/commit/7dec9da))

### BREAKING CHANGES

* major performance improvements
2026-02-11 20:50:23 +00:00
lwouis 91d44e72df ci: workaround github actions bug by checking out more commits 2026-02-11 21:42:44 +01:00
lwouis 314259032d fix: missing thumbnails in rare cases 2026-02-11 21:35:41 +01:00
lwouis fa9e4d0ee1 fix: preserve scroll position in switcher if windows change 2026-02-11 21:35:41 +01:00
lwouis 6de7fee90c refactor: add bottom padding when scrolling in appicons appearance 2026-02-11 21:35:40 +01:00
lwouis f7226f681a refactor: fix windowless indicator position 2026-02-11 21:35:39 +01:00
lwouis 26d46e3768 feat: new thumbnails shadows in macos 26 style 2026-02-11 21:35:39 +01:00
lwouis 216563b635 perf: prevent possible frequent permissions check 2026-02-11 21:35:38 +01:00
lwouis 3f2f391c93 refactor: extract statusiconsview 2026-02-11 21:35:38 +01:00
lwouis 9edf31244a perf: merge mouseevents into cursorevents 2026-02-11 21:35:37 +01:00
lwouis d89bc29425 perf: do all mouse interactions globally instead of local tracking 2026-02-11 21:35:36 +01:00
lwouis d525d350fc fix: prevent macos 10.13 crash (closes #5255) 2026-02-11 21:35:36 +01:00
lwouis d1ba6bd333 chore: update periphery + remove dead code 2026-02-11 21:35:35 +01:00
lwouis 6695e9be9c refactor: rename to tiles 2026-02-11 21:35:35 +01:00
lwouis 396ef6f0b0 refactor: fix mouse hover right after switching space 2026-02-11 21:35:34 +01:00
lwouis b9637e5802 perf: have views under and over the thumbnailview 2026-02-11 21:35:34 +01:00
lwouis fe52511885 refactor: space indicator always rightmost 2026-02-11 21:35:33 +01:00
lwouis 337e2fbfec perf: throttle all window/app ax calls 2026-02-11 21:35:32 +01:00
lwouis 4f5e32593b perf: improve hiding the ui 2026-02-11 21:35:32 +01:00
lwouis db314c9948 perf: small optimizations from profiling 2026-02-11 21:35:31 +01:00
lwouis 7dec9da401 perf: use calayer instead of nsview for lightimageview 2026-02-11 21:35:31 +01:00
lwouis 3a8c0f3bee perf: simplify and combine views for better perf 2026-02-11 21:35:30 +01:00
lwouis ec5802a487 perf: create overlay view to optimize view count 2026-02-11 21:35:29 +01:00
lwouis fefc491ce5 perf: prevent appkit work 2026-02-11 21:35:29 +01:00
lwouis 41e0e7c688 perf: prevent costly window recursive views update 2026-02-11 21:35:28 +01:00
lwouis ce2dfc1f19 perf: remove normalize-subview to avoid appkit work 2026-02-11 21:35:28 +01:00
lwouis 13ed78bc23 perf: cache expensive layout values 2 2026-02-11 21:35:27 +01:00
lwouis 904bd17c53 perf: cache expensive layout values 2026-02-11 21:35:27 +01:00
lwouis 1f3a653faa refactor: add benchmarker 2026-02-11 21:35:26 +01:00
lwouis cd1d6574f7 chore: remove dead code 2026-02-11 21:35:26 +01:00
lwouis a5135c5560 perf: cache screen uuids and frontmost app 2026-02-11 21:35:25 +01:00
lwouis 2bce0d2d40 perf: capture samplebuffer directly 2026-02-11 21:35:24 +01:00
lwouis 016052ca14 perf: better caanimation batching 2026-02-11 21:35:24 +01:00
lwouis 305870b3ee perf: cache font from appearance 2026-02-11 21:35:23 +01:00
lwouis 52530b2d5c perf: update windows manually after 250s 2026-02-11 21:35:23 +01:00
lwouis 5a35aa95bc perf: move app icon capture to background queue 2026-02-11 21:35:22 +01:00
lwouis 53da0344bf refactor: avoid checking transparency on some images 2026-02-11 21:35:22 +01:00
lwouis f30d3760a1 refactor: codex perf improvements 2026-02-11 21:35:21 +01:00
lwouis fbcc3f5f02 refactor: improve manual window discovery 2026-02-11 21:35:21 +01:00
Christian Battaglia 5d0a92f3f7 feat: improve performance when many windows are open (closes #5177)
BREAKING CHANGE: major performance improvements
2026-02-11 21:35:18 +01:00
lwouis 4b830e6ba7 perf: optim hangs from DebugMenu 2026-02-08 10:30:48 +01:00
lwouis 698e5e8e0c chore: update periphery config 2026-02-08 10:30:47 +01:00
lwouis a4f5a23846 docs: add ai agents rules 2026-02-08 10:30:44 +01:00
lwouis 268121850d feat: update cs/el/fr/ru localizations 2026-02-08 10:23:16 +01:00
semantic-release-bot aeaf782feb chore(release): 8.3.4 [skip ci]
## [8.3.4](https://github.com/lwouis/alt-tab-macos/compare/v8.3.3...v8.3.4) (2026-01-31)

### Bug Fixes

* app could sometimes crash in the background ([ab704dc](https://github.com/lwouis/alt-tab-macos/commit/ab704dc)), closes [#5260](https://github.com/lwouis/alt-tab-macos/issues/5260)
* quitting apps by pressing q multiple times (closes [#5247](https://github.com/lwouis/alt-tab-macos/issues/5247)) ([21aeafd](https://github.com/lwouis/alt-tab-macos/commit/21aeafd))
2026-01-31 18:18:25 +00:00
lwouis 21aeafd8dd fix: quitting apps by pressing q multiple times (closes #5247) 2026-01-31 18:42:45 +01:00
lwouis ab704dc4be fix: app could sometimes crash in the background
closes #5260

appcenter showed that access to debugId() from main and non-main threa could crash the app. Making debugId a string that's set once at init simplifies everything and allows concurrent access from threads
2026-01-31 18:42:42 +01:00
lwouis 42c0a03ddc docs: improve website title 2026-01-25 22:34:53 +01:00
semantic-release-bot 550529f1fa chore(release): 8.3.3 [skip ci]
## [8.3.3](https://github.com/lwouis/alt-tab-macos/compare/v8.3.2...v8.3.3) (2026-01-25)

### Bug Fixes

* app icons could sometimes be invisible (closes [#5226](https://github.com/lwouis/alt-tab-macos/issues/5226)) ([23fbc01](https://github.com/lwouis/alt-tab-macos/commit/23fbc01))
* improve trackpad gesture detection (closes [#5203](https://github.com/lwouis/alt-tab-macos/issues/5203)) ([9b5e43e](https://github.com/lwouis/alt-tab-macos/commit/9b5e43e))
* switcher could sometimes show with no window pre-selected ([3e95f77](https://github.com/lwouis/alt-tab-macos/commit/3e95f77))
* title could be off-center in app-icons appearance (closes [#5235](https://github.com/lwouis/alt-tab-macos/issues/5235)) ([7fdfe4a](https://github.com/lwouis/alt-tab-macos/commit/7fdfe4a))
2026-01-25 21:24:33 +00:00
lwouis 23fbc01a0e fix: app icons could sometimes be invisible (closes #5226) 2026-01-25 22:19:02 +01:00
lwouis 56546571b6 docs: add frequently asked questions on website 2026-01-24 20:12:45 +01:00
lwouis e5c634e672 refactor: simplify v-center logic
no need for the complex bias thing. We round in the end. And up or down each have downsides, so let's pick the default without doing extra logic
2026-01-24 14:07:38 +01:00
lwouis 7fdfe4a9ee fix: title could be off-center in app-icons appearance (closes #5235) 2026-01-24 13:39:25 +01:00
lwouis 3e95f77cc0 fix: switcher could sometimes show with no window pre-selected 2026-01-24 13:39:24 +01:00
lwouis 9b5e43eec5 fix: improve trackpad gesture detection (closes #5203) 2026-01-23 18:27:42 +01:00
lwouis ac3c3740c2 chore: improve log 2026-01-23 18:18:27 +01:00
semantic-release-bot 35a67ddf16 chore(release): 8.3.2 [skip ci]
## [8.3.2](https://github.com/lwouis/alt-tab-macos/compare/v8.3.1...v8.3.2) (2026-01-22)

### Bug Fixes

* blacklisting fullscreen windows was not working (closes [#5228](https://github.com/lwouis/alt-tab-macos/issues/5228)) ([53815e0](https://github.com/lwouis/alt-tab-macos/commit/53815e0))
2026-01-22 23:34:13 +00:00
lwouis 53815e0f28 fix: blacklisting fullscreen windows was not working (closes #5228) 2026-01-23 00:24:53 +01:00
semantic-release-bot 7b7a73bd46 chore(release): 8.3.1 [skip ci]
## [8.3.1](https://github.com/lwouis/alt-tab-macos/compare/v8.3.0...v8.3.1) (2026-01-22)

### Bug Fixes

* chrome apps windows would not show in the switcher (closes [#5227](https://github.com/lwouis/alt-tab-macos/issues/5227)) ([bf3fa67](https://github.com/lwouis/alt-tab-macos/commit/bf3fa67))
2026-01-22 21:47:45 +00:00
lwouis bf3fa6734e fix: chrome apps windows would not show in the switcher (closes #5227) 2026-01-22 22:28:46 +01:00
semantic-release-bot be06aef6d7 chore(release): 8.3.0 [skip ci]
# [8.3.0](https://github.com/lwouis/alt-tab-macos/compare/v8.2.0...v8.3.0) (2026-01-20)

### Bug Fixes

* position of windowless indicator in thumbnails appearance ([d1fd1fd](https://github.com/lwouis/alt-tab-macos/commit/d1fd1fd))
* small memory leak when opening the switcher (closes [#4255](https://github.com/lwouis/alt-tab-macos/issues/4255)) ([0a6485e](https://github.com/lwouis/alt-tab-macos/commit/0a6485e))
* windows would sometimes not update their order (closes [#5207](https://github.com/lwouis/alt-tab-macos/issues/5207)) ([a3f2a54](https://github.com/lwouis/alt-tab-macos/commit/a3f2a54))

### Features

* increase apparition delay granularity (closes [#5210](https://github.com/lwouis/alt-tab-macos/issues/5210)) ([5b0df6b](https://github.com/lwouis/alt-tab-macos/commit/5b0df6b))
2026-01-20 17:59:06 +00:00
lwouis 3e27abd1e8 chore: improve log levels 2026-01-19 19:35:15 +01:00
lwouis 0a6485e024 fix: small memory leak when opening the switcher (closes #4255) 2026-01-19 19:35:14 +01:00
lwouis 5b0df6bd4c feat: increase apparition delay granularity (closes #5210) 2026-01-19 19:35:14 +01:00
lwouis a3f2a54f20 fix: windows would sometimes not update their order (closes #5207) 2026-01-19 19:35:13 +01:00
lwouis d1fd1fd9d0 fix: position of windowless indicator in thumbnails appearance 2026-01-17 00:06:10 +01:00
lwouis cd5fb46963 chore: silence build warnings from pods 2026-01-15 19:21:32 +01:00
semantic-release-bot 09ebff06ee chore(release): 8.2.0 [skip ci]
# [8.2.0](https://github.com/lwouis/alt-tab-macos/compare/v8.1.0...v8.2.0) (2026-01-15)

### Bug Fixes

* thumbnails could sometimes be stretched (closes [#5204](https://github.com/lwouis/alt-tab-macos/issues/5204)) ([ac24d6d](https://github.com/lwouis/alt-tab-macos/commit/ac24d6d))

### Features

* stop checking screen-recording permission after launch ([#5202](https://github.com/lwouis/alt-tab-macos/issues/5202)) ([f481d22](https://github.com/lwouis/alt-tab-macos/commit/f481d22))
2026-01-15 18:02:05 +00:00
lwouis ac24d6d148 fix: thumbnails could sometimes be stretched (closes #5204) 2026-01-15 18:01:08 +01:00
lwouis f481d22b75 feat: stop checking screen-recording permission after launch (#5202)
closes #5202

the permission check was expensive for the os, leading to higher energy usage, thus more battery drain
2026-01-15 15:47:33 +01:00
lwouis 149e3a5026 docs: improve changelog design 2026-01-15 14:42:42 +01:00
lwouis ef83525e9a docs: improve website on mobile 2026-01-15 14:42:41 +01:00
semantic-release-bot 56a042716e chore(release): 8.1.0 [skip ci]
# [8.1.0](https://github.com/lwouis/alt-tab-macos/compare/v8.0.0...v8.1.0) (2026-01-14)

### Bug Fixes

* allow f-keys as shortcuts-when-active (closes [#5166](https://github.com/lwouis/alt-tab-macos/issues/5166)) ([a0c9fee](https://github.com/lwouis/alt-tab-macos/commit/a0c9fee))
* avoid unintentional trackpad trigger (closes [#4278](https://github.com/lwouis/alt-tab-macos/issues/4278)) ([0539a3a](https://github.com/lwouis/alt-tab-macos/commit/0539a3a))
* better handle palm/fingers resting on the trackpad (closes [#5191](https://github.com/lwouis/alt-tab-macos/issues/5191)) ([9ed8a19](https://github.com/lwouis/alt-tab-macos/commit/9ed8a19))
* mitigate macos 15 bugs with screencapture-kit (closes [#5190](https://github.com/lwouis/alt-tab-macos/issues/5190)) ([b2f5c6c](https://github.com/lwouis/alt-tab-macos/commit/b2f5c6c))
* mouse hover detection for hidden/windowless apps ([7c64864](https://github.com/lwouis/alt-tab-macos/commit/7c64864))
* thumbnails could sometimes be the wrong size ([9d0b947](https://github.com/lwouis/alt-tab-macos/commit/9d0b947))

### Features

* add belarusian localization ([0fe722b](https://github.com/lwouis/alt-tab-macos/commit/0fe722b))
* improve accidental cursor movement ([74b5a11](https://github.com/lwouis/alt-tab-macos/commit/74b5a11)), closes [/github.com/lwouis/alt-tab-macos/issues/4278#issuecomment-3733280737](https://github.com//github.com/lwouis/alt-tab-macos/issues/4278/issues/issuecomment-3733280737)
* improve pl localization ([3b53ce7](https://github.com/lwouis/alt-tab-macos/commit/3b53ce7))
* show outline of windows hidden for privacy reasons (closes [#5172](https://github.com/lwouis/alt-tab-macos/issues/5172)) ([1090acf](https://github.com/lwouis/alt-tab-macos/commit/1090acf))
2026-01-14 23:19:39 +00:00
lwouis 0fe722bfba feat: add belarusian localization 2026-01-15 00:08:36 +01:00
lwouis 3b53ce77bb feat: improve pl localization 2026-01-15 00:08:36 +01:00
lwouis b2f5c6c4d5 fix: mitigate macos 15 bugs with screencapture-kit (closes #5190) 2026-01-15 00:08:35 +01:00
emptiestplace 7c64864c2f fix: mouse hover detection for hidden/windowless apps 2026-01-15 00:08:35 +01:00
lwouis 9d0b947a48 fix: thumbnails could sometimes be the wrong size
* fixes issues when the user has monitors with different DPI
* fixes issues where screenshots after a window is resized could be wrong (because of cached SCWindow having stale frame.size)
2026-01-15 00:08:34 +01:00
lwouis 9ed8a199b0 fix: better handle palm/fingers resting on the trackpad (closes #5191) 2026-01-15 00:08:34 +01:00
lwouis a0c9feefca fix: allow f-keys as shortcuts-when-active (closes #5166) 2026-01-15 00:08:33 +01:00
lwouis 1a2822d130 docs: website redesign 2026-01-14 00:09:51 +01:00
lwouis 44007195b7 docs: improve website and readme 2026-01-12 17:15:25 +01:00
lwouis 74b5a119d3 feat: improve accidental cursor movement
see https://github.com/lwouis/alt-tab-macos/issues/4278#issuecomment-3733280737
2026-01-11 14:55:26 +01:00
lwouis 0539a3ad49 fix: avoid unintentional trackpad trigger (closes #4278) 2026-01-11 14:55:26 +01:00
lwouis a06afd4bd2 refactor: remove unneeded views; simplify views 2026-01-11 14:55:25 +01:00
lwouis 1090acf3a5 feat: show outline of windows hidden for privacy reasons (closes #5172) 2026-01-07 19:16:14 +01:00
semantic-release-bot b8ba0f0888 chore(release): 8.0.0 [skip ci]
# [8.0.0](https://github.com/lwouis/alt-tab-macos/compare/v7.39.0...v8.0.0) (2026-01-06)

### Bug Fixes

* avoid macos bug where many permission dialogs pop (closes [#5106](https://github.com/lwouis/alt-tab-macos/issues/5106)) ([5c4199e](https://github.com/lwouis/alt-tab-macos/commit/5c4199e))

### Features

* improve memory image of showing app icons (closes [#5144](https://github.com/lwouis/alt-tab-macos/issues/5144)) ([bf58335](https://github.com/lwouis/alt-tab-macos/commit/bf58335))
* improve ta localization ([989b344](https://github.com/lwouis/alt-tab-macos/commit/989b344))
* improve thumbnails with screen-capture kit ([7821d7c](https://github.com/lwouis/alt-tab-macos/commit/7821d7c)), closes [#4255](https://github.com/lwouis/alt-tab-macos/issues/4255) [#3652](https://github.com/lwouis/alt-tab-macos/issues/3652)

### Performance Improvements

* debounce screen/space events to minimize work ([e2b4779](https://github.com/lwouis/alt-tab-macos/commit/e2b4779))

### BREAKING CHANGES

* Better thumbnails with ScreenCaptureKit for users on macOS >= 14
2026-01-06 18:36:28 +00:00
lwouis 989b344b1d feat: improve ta localization 2026-01-06 19:27:16 +01:00
lwouis bf58335bbe feat: improve memory image of showing app icons (closes #5144) 2026-01-05 23:12:36 +01:00
lwouis 5c4199ec74 fix: avoid macos bug where many permission dialogs pop (closes #5106) 2026-01-04 22:53:54 +01:00
lwouis 7821d7c979 feat: improve thumbnails with screen-capture kit
BREAKING CHANGE: Better thumbnails with ScreenCaptureKit for users on macOS >= 14

* No more WindowServer memory leaks (closes #4255)
* No more purple UI from macOS bothering users
* Fullscreen thumbnails contain top part (closes #3652)
* Thumbnails contain dialogs (e.g. Save/Print panel)
* Show thumbnails for off-screen windows
* Memory usage drastically reduced (e.g. don't save full-resolution if Preview feature is not used)
* Limitations of ScreenCaptureKit compared to private API: can't capture minimized/hidden/tabbed windows
2026-01-04 22:49:41 +01:00
lwouis e2b47790a9 perf: debounce screen/space events to minimize work 2026-01-04 14:18:17 +01:00
lwouis ff66a0664d chore: reduce link font size 2026-01-04 12:08:44 +01:00
semantic-release-bot 6d42bef7ec chore(release): 7.39.0 [skip ci]
# [7.39.0](https://github.com/lwouis/alt-tab-macos/compare/v7.38.1...v7.39.0) (2026-01-03)

### Bug Fixes

* avoid showing closed windows (closes [#3589](https://github.com/lwouis/alt-tab-macos/issues/3589)) ([894a69d](https://github.com/lwouis/alt-tab-macos/commit/894a69d)), closes [#4924](https://github.com/lwouis/alt-tab-macos/issues/4924)
* permission checks might freeze or restart the app (closes [#5112](https://github.com/lwouis/alt-tab-macos/issues/5112)) ([7906d63](https://github.com/lwouis/alt-tab-macos/commit/7906d63))
* permission window could steal focus (see [#3577](https://github.com/lwouis/alt-tab-macos/issues/3577)) ([2f875b3](https://github.com/lwouis/alt-tab-macos/commit/2f875b3))
* permissions window could look wrong in some languages like chinese ([914f91f](https://github.com/lwouis/alt-tab-macos/commit/914f91f)), closes [/github.com/lwouis/alt-tab-macos/issues/5112#issuecomment-3692769341](https://github.com//github.com/lwouis/alt-tab-macos/issues/5112/issues/issuecomment-3692769341)
* preview could sometimes be incorrectly positioned ([edc2f00](https://github.com/lwouis/alt-tab-macos/commit/edc2f00))
* show some hovering windows (e.g. zoom.app) (closes [#5140](https://github.com/lwouis/alt-tab-macos/issues/5140)) ([fcc6651](https://github.com/lwouis/alt-tab-macos/commit/fcc6651))
* thumbnails could sometimes have the wrong size ([55f3f59](https://github.com/lwouis/alt-tab-macos/commit/55f3f59))

### Features

* avoid occasional delays in showing the switcher (closes [#5109](https://github.com/lwouis/alt-tab-macos/issues/5109)) ([3c04a4c](https://github.com/lwouis/alt-tab-macos/commit/3c04a4c))
* improve nb/tr localizations ([5e842d5](https://github.com/lwouis/alt-tab-macos/commit/5e842d5))
* remove shadow around app icon appearance ([dda612c](https://github.com/lwouis/alt-tab-macos/commit/dda612c))

### Performance Improvements

* do login item and plist updates later to accelerate launch ([2f72c5d](https://github.com/lwouis/alt-tab-macos/commit/2f72c5d))
* don't compute diffs of running-apps; directly get new/old ([7ded01c](https://github.com/lwouis/alt-tab-macos/commit/7ded01c))
* improve mouse hover algo and core-animation side ([6103785](https://github.com/lwouis/alt-tab-macos/commit/6103785))
2026-01-03 18:23:00 +00:00
lwouis cca3423a59 ci: github action somehow misses 2 commits; adding more leeway 2026-01-03 19:18:44 +01:00
lwouis 5e842d5850 feat: improve nb/tr localizations 2026-01-03 19:18:43 +01:00
lwouis 0c724f3c7b refactor: various small improvements 2026-01-03 19:18:43 +01:00
lwouis 55f3f59208 fix: thumbnails could sometimes have the wrong size 2026-01-03 19:18:43 +01:00
lwouis edc2f00603 fix: preview could sometimes be incorrectly positioned 2026-01-03 19:18:42 +01:00
lwouis bcb130e7eb refactor: clarify names and organize tidier 2026-01-03 19:18:42 +01:00
lwouis d8de1e80b8 refactor: logs overall: lazy + reviewed them 1 by 1 for better dx 2026-01-03 19:18:41 +01:00
lwouis 610378525a perf: improve mouse hover algo and core-animation side 2026-01-03 18:09:19 +01:00
lwouis 2f72c5d6ae perf: do login item and plist updates later to accelerate launch 2026-01-03 18:09:19 +01:00
lwouis a62949f0dc refactor: add logs 2026-01-03 18:09:18 +01:00
lwouis 7ded01c277 perf: don't compute diffs of running-apps; directly get new/old 2026-01-03 18:09:18 +01:00
lwouis a45361321d chore: document why we check mouse events on main-thread 2026-01-03 18:09:17 +01:00
lwouis b7204f9694 refactor: repeatingKeyThread -> repeatingKeyQueue 2026-01-03 18:09:17 +01:00
lwouis b8a3b779e1 chore: document why we use kvo for processes diffing 2026-01-03 18:09:16 +01:00
lwouis 7906d630be fix: permission checks might freeze or restart the app (closes #5112) 2026-01-03 18:09:16 +01:00
lwouis 3c04a4ce15 feat: avoid occasional delays in showing the switcher (closes #5109) 2026-01-03 17:36:23 +01:00
lwouis 2f875b3bcb fix: permission window could steal focus (see #3577) 2025-12-28 18:47:02 +01:00
lwouis 914f91f9f7 fix: permissions window could look wrong in some languages like chinese
see https://github.com/lwouis/alt-tab-macos/issues/5112#issuecomment-3692769341
2025-12-28 18:47:01 +01:00
lwouis fcc6651b6a fix: show some hovering windows (e.g. zoom.app) (closes #5140) 2025-12-28 18:47:01 +01:00
lwouis dda612c15e feat: remove shadow around app icon appearance 2025-12-28 18:47:00 +01:00
lwouis 894a69d41f fix: avoid showing closed windows (closes #3589)
closes #4924
2025-12-20 01:14:30 +01:00
lwouis e2523f1d99 docs: remove dead link on website (closes #5134) 2025-12-20 01:14:29 +01:00
lwouis 6fa35ae35c chore: document tab detection experiments 2025-12-16 10:31:37 +01:00
semantic-release-bot d0a2d31b5a chore(release): 7.38.1 [skip ci]
## [7.38.1](https://github.com/lwouis/alt-tab-macos/compare/v7.38.0...v7.38.1) (2025-12-13)

### Bug Fixes

* could sometimes freeze on the permission window ([43838e1](https://github.com/lwouis/alt-tab-macos/commit/43838e1)), closes [#5112](https://github.com/lwouis/alt-tab-macos/issues/5112)
* prevent crash when sending a debug profile ([741e790](https://github.com/lwouis/alt-tab-macos/commit/741e790))
2025-12-13 19:15:21 +00:00
lwouis 43838e1ccc fix: could sometimes freeze on the permission window
#5112
2025-12-13 20:10:52 +01:00
lwouis 741e7902db fix: prevent crash when sending a debug profile 2025-12-07 23:45:42 +01:00
semantic-release-bot 6426d318fb chore(release): 7.38.0 [skip ci]
# [7.38.0](https://github.com/lwouis/alt-tab-macos/compare/v7.37.0...v7.38.0) (2025-12-07)

### Bug Fixes

* could sometimes freeze upon launch (closes [#5079](https://github.com/lwouis/alt-tab-macos/issues/5079)) ([ee27df7](https://github.com/lwouis/alt-tab-macos/commit/ee27df7))
* sending feedback with a debug-profile could sometimes crash ([e0ae29d](https://github.com/lwouis/alt-tab-macos/commit/e0ae29d))

### Features

* improve ca/es/ga/pt/pt-br/uk localizations ([8a98b4e](https://github.com/lwouis/alt-tab-macos/commit/8a98b4e))
* prevent mouse-hover when using trackpad swipes (closes [#5071](https://github.com/lwouis/alt-tab-macos/issues/5071)) ([b8ecd58](https://github.com/lwouis/alt-tab-macos/commit/b8ecd58))
2025-12-07 11:40:27 +00:00
lwouis 8a98b4ee40 feat: improve ca/es/ga/pt/pt-br/uk localizations 2025-12-07 12:35:22 +01:00
lwouis dcaac482de refactor: separate concerns and simplify 2025-12-06 15:17:31 +01:00
lwouis ee27df7680 fix: could sometimes freeze upon launch (closes #5079) 2025-12-06 12:59:29 +01:00
lwouis e0ae29d64a fix: sending feedback with a debug-profile could sometimes crash 2025-12-06 12:31:33 +01:00
lwouis db78e66451 refactor: consolidate classes, avoid free functions and variables 2025-12-06 12:31:32 +01:00
lwouis b8ecd58005 feat: prevent mouse-hover when using trackpad swipes (closes #5071) 2025-12-06 12:31:32 +01:00
lwouis 2725834c4a refactor: move free functions/variables into their class 2025-12-06 12:31:31 +01:00
semantic-release-bot 42cb2d5d88 chore(release): 7.37.0 [skip ci]
# [7.37.0](https://github.com/lwouis/alt-tab-macos/compare/v7.36.0...v7.37.0) (2025-11-28)

### Bug Fixes

* better crop app icons on macos < 26 (closes [#5080](https://github.com/lwouis/alt-tab-macos/issues/5080)) ([237bb1e](https://github.com/lwouis/alt-tab-macos/commit/237bb1e))

### Features

* improve portuguese localization ([3994429](https://github.com/lwouis/alt-tab-macos/commit/3994429))
* warn tahoe users of shortcut conflict with macos game-overlay ([911aad4](https://github.com/lwouis/alt-tab-macos/commit/911aad4)), closes [#5018](https://github.com/lwouis/alt-tab-macos/issues/5018)
2025-11-28 23:07:33 +00:00
lwouis 3994429b88 feat: improve portuguese localization 2025-11-29 00:03:28 +01:00
lwouis 237bb1e0d9 fix: better crop app icons on macos < 26 (closes #5080) 2025-11-29 00:03:27 +01:00
lwouis 911aad42cc feat: warn tahoe users of shortcut conflict with macos game-overlay
closes #5018
2025-11-29 00:03:27 +01:00
lwouis 36ded28ce4 chore: add input-source to debug profile 2025-11-27 19:31:19 +01:00
semantic-release-bot 9761bb91e9 chore(release): 7.36.0 [skip ci]
# [7.36.0](https://github.com/lwouis/alt-tab-macos/compare/v7.35.0...v7.36.0) (2025-11-25)

### Bug Fixes

* switcher could become broken after changing appearance ([d377b3d](https://github.com/lwouis/alt-tab-macos/commit/d377b3d)), closes [#5061](https://github.com/lwouis/alt-tab-macos/issues/5061)

### Features

* improve portuguese localization ([435a310](https://github.com/lwouis/alt-tab-macos/commit/435a310))
2025-11-25 08:56:30 +00:00
lwouis 435a310590 feat: improve portuguese localization 2025-11-25 09:51:59 +01:00
lwouis d377b3dbca fix: switcher could become broken after changing appearance
closes #5061
2025-11-25 09:51:57 +01:00
semantic-release-bot 850fe285b4 chore(release): 7.35.0 [skip ci]
# [7.35.0](https://github.com/lwouis/alt-tab-macos/compare/v7.34.0...v7.35.0) (2025-11-24)

### Bug Fixes

* app would sometimes crash on macos monterey (closes [#5051](https://github.com/lwouis/alt-tab-macos/issues/5051)) ([29e1cff](https://github.com/lwouis/alt-tab-macos/commit/29e1cff))
* better gesture recognition (closes [#5039](https://github.com/lwouis/alt-tab-macos/issues/5039)) ([1689954](https://github.com/lwouis/alt-tab-macos/commit/1689954))
* closing fullscreen window would glitch it (closes [#5029](https://github.com/lwouis/alt-tab-macos/issues/5029)) ([ee436cc](https://github.com/lwouis/alt-tab-macos/commit/ee436cc))

### Features

* add trackpad haptic feedback for better navigation (closes [#4763](https://github.com/lwouis/alt-tab-macos/issues/4763)) ([fb5dfc4](https://github.com/lwouis/alt-tab-macos/commit/fb5dfc4))
* better icon for feedback form (closes [#5013](https://github.com/lwouis/alt-tab-macos/issues/5013)) ([2c3373a](https://github.com/lwouis/alt-tab-macos/commit/2c3373a))
* improve portuguese localization ([c294ad0](https://github.com/lwouis/alt-tab-macos/commit/c294ad0))
2025-11-24 22:30:41 +00:00
lwouis 2adeb8dbcb chore: remove sparkle updater object from mainmenu
it could crash the app, if loading the xib was done inside main.async{}
it was not needed in the first place, despite what Sparkle does said
2025-11-24 18:07:51 +01:00
lwouis fb5dfc4399 feat: add trackpad haptic feedback for better navigation (closes #4763) 2025-11-24 15:42:58 +01:00
lwouis 29e1cff8f1 fix: app would sometimes crash on macos monterey (closes #5051) 2025-11-24 11:19:44 +01:00
lwouis 2c3373ae16 feat: better icon for feedback form (closes #5013) 2025-11-24 11:19:44 +01:00
lwouis c294ad0d4d feat: improve portuguese localization 2025-11-24 11:19:43 +01:00
lwouis ee436cc7cc fix: closing fullscreen window would glitch it (closes #5029) 2025-11-24 11:19:43 +01:00
lwouis 168995493f fix: better gesture recognition (closes #5039) 2025-11-24 11:19:42 +01:00
semantic-release-bot e477f8b3da chore(release): 7.34.0 [skip ci]
# [7.34.0](https://github.com/lwouis/alt-tab-macos/compare/v7.33.0...v7.34.0) (2025-11-20)

### Bug Fixes

* reduce memory footprint after running for a while (closes [#4255](https://github.com/lwouis/alt-tab-macos/issues/4255)) ([938b735](https://github.com/lwouis/alt-tab-macos/commit/938b735))

### Features

* improve localizations ([516329a](https://github.com/lwouis/alt-tab-macos/commit/516329a))
* improve responsiveness in showing switcher (closes [#4959](https://github.com/lwouis/alt-tab-macos/issues/4959)) ([a80721b](https://github.com/lwouis/alt-tab-macos/commit/a80721b))
2025-11-20 23:27:41 +00:00
lwouis 516329a408 feat: improve localizations 2025-11-21 00:21:07 +01:00
lwouis 938b7353ff fix: reduce memory footprint after running for a while (closes #4255) 2025-11-20 23:42:27 +01:00
lwouis a80721b2d3 feat: improve responsiveness in showing switcher (closes #4959) 2025-11-20 23:42:26 +01:00
lwouis 4e065b9a80 docs: add delight to website support page 2025-11-20 23:42:25 +01:00
lwouis aa8d7d02d1 chore: fix changelog title being removed from now on 2025-11-17 21:18:58 +01:00
semantic-release-bot 05b36fc58f chore(release): 7.33.0 [skip ci]
# [7.33.0](https://github.com/lwouis/alt-tab-macos/compare/v7.32.0...v7.33.0) (2025-11-16)

### Bug Fixes

* app icon was too small in titles-appearance large-size ([ffd0c75](https://github.com/lwouis/alt-tab-macos/commit/ffd0c75))
* take into account accent-color immediatly (closes [#4984](https://github.com/lwouis/alt-tab-macos/issues/4984)) ([011fdba](https://github.com/lwouis/alt-tab-macos/commit/011fdba))

### Features

* improve dealing with reserved/conflicting shortcuts ([fdf3134](https://github.com/lwouis/alt-tab-macos/commit/fdf3134)), closes [#3190](https://github.com/lwouis/alt-tab-macos/issues/3190) [#3288](https://github.com/lwouis/alt-tab-macos/issues/3288) [#1835](https://github.com/lwouis/alt-tab-macos/issues/1835) [#3826](https://github.com/lwouis/alt-tab-macos/issues/3826)
* improve nl/pl/uk localizations ([96caad4](https://github.com/lwouis/alt-tab-macos/commit/96caad4))
* improve trackpad multi-fingers swiping (closes [#4765](https://github.com/lwouis/alt-tab-macos/issues/4765)) ([d6196ec](https://github.com/lwouis/alt-tab-macos/commit/d6196ec))
* improve ux for titles-appearance (closes [#4975](https://github.com/lwouis/alt-tab-macos/issues/4975)) ([c352591](https://github.com/lwouis/alt-tab-macos/commit/c352591))
* macos tahoe improvements: menubar menu, feedback form, wording ([309cae3](https://github.com/lwouis/alt-tab-macos/commit/309cae3)), closes [#4986](https://github.com/lwouis/alt-tab-macos/issues/4986)
2025-11-16 17:57:31 +00:00
fhdufhdu d6196ecad8 feat: improve trackpad multi-fingers swiping (closes #4765) 2025-11-16 18:51:09 +01:00
lwouis 21a91421a6 docs: improve website menu 2025-11-16 18:51:08 +01:00
lwouis 272f51ad5b docs: remove auto-translation of release notes
closes #3933
2025-11-16 18:51:08 +01:00
lwouis c352591d72 feat: improve ux for titles-appearance (closes #4975) 2025-11-16 18:51:07 +01:00
lwouis 96caad46a5 feat: improve nl/pl/uk localizations 2025-11-16 18:51:07 +01:00
lwouis 309cae316b feat: macos tahoe improvements: menubar menu, feedback form, wording
closes #4986
2025-11-16 18:51:06 +01:00
lwouis ffd0c75e8b fix: app icon was too small in titles-appearance large-size 2025-11-15 19:14:38 +01:00
lwouis fdf313472c feat: improve dealing with reserved/conflicting shortcuts
(closes #3190, closes #3288, closes #1835, closes #3826)
2025-11-15 18:47:59 +01:00
lwouis 011fdba7d3 fix: take into account accent-color immediatly (closes #4984) 2025-11-12 19:07:37 +01:00
semantic-release-bot e5e8521ae3 chore(release): 7.32.0 [skip ci]
# [7.32.0](https://github.com/lwouis/alt-tab-macos/compare/v7.31.0...v7.32.0) (2025-11-10)

### Bug Fixes

* alt-tab could crash if asked to close one of its own window ([f46372b](https://github.com/lwouis/alt-tab-macos/commit/f46372b))
* could sometimes crash when navigating up or down (closes [#4110](https://github.com/lwouis/alt-tab-macos/issues/4110)) ([d2220c6](https://github.com/lwouis/alt-tab-macos/commit/d2220c6))

### Features

* improve pl/zh-hk localizations ([786e752](https://github.com/lwouis/alt-tab-macos/commit/786e752))
* improve responsiveness of showing the switcher ([689adc0](https://github.com/lwouis/alt-tab-macos/commit/689adc0))
* new look for tahoe and liquid glass (closes [#4658](https://github.com/lwouis/alt-tab-macos/issues/4658)) ([fab9d7c](https://github.com/lwouis/alt-tab-macos/commit/fab9d7c))
* titles appearance now resizes for better readability ([26d40e1](https://github.com/lwouis/alt-tab-macos/commit/26d40e1)), closes [#3882](https://github.com/lwouis/alt-tab-macos/issues/3882)
* update visuals for macos tahoe and liquid glass ([33c6615](https://github.com/lwouis/alt-tab-macos/commit/33c6615))

### Performance Improvements

* improve rendering performance by doing less work ([ec55ae8](https://github.com/lwouis/alt-tab-macos/commit/ec55ae8))
2025-11-10 19:56:49 +00:00
lwouis 786e752417 feat: improve pl/zh-hk localizations 2025-11-10 20:48:58 +01:00
lwouis d2220c68bd fix: could sometimes crash when navigating up or down (closes #4110) 2025-11-10 20:48:58 +01:00
lwouis 26d40e1149 feat: titles appearance now resizes for better readability
parts of #3882

also fixed a display of titles in every appearance, especially on first display of the switcher ui
2025-11-10 20:48:57 +01:00
lwouis 15a55e6e07 chore: minor cleanup 2025-11-09 09:40:08 +01:00
lwouis 32ab8d6573 chore: calculate nstextfield frame width better 2025-11-09 09:40:07 +01:00
lwouis ec55ae8b00 perf: improve rendering performance by doing less work 2025-11-09 09:40:07 +01:00
lwouis 689adc0a30 feat: improve responsiveness of showing the switcher 2025-11-09 09:40:06 +01:00
lwouis fab9d7c0ab feat: new look for tahoe and liquid glass (closes #4658) 2025-11-09 09:40:06 +01:00
lwouis 4aec2aa6da chore: improve debug build speed 2025-11-09 09:40:05 +01:00
lwouis f46372b97c fix: alt-tab could crash if asked to close one of its own window 2025-11-02 16:05:26 +01:00
lwouis 33c661505e feat: update visuals for macos tahoe and liquid glass 2025-11-02 12:37:03 +01:00
lwouis 91e16f7863 chore: improve readme 2025-11-02 00:31:57 +01:00
lwouis 55e8c331a6 chore: add debug widget to monitor queues 2025-10-30 11:19:24 +01:00
lwouis ae092cd1a7 chore: better logs 2025-10-30 11:17:44 +01:00
semantic-release-bot 122dc2ec0f chore(release): 7.31.0 [skip ci]
# [7.31.0](https://github.com/lwouis/alt-tab-macos/compare/v7.30.0...v7.31.0) (2025-10-26)

### Bug Fixes

* cmd+q would quit alt-tab instead of the selected app (closes [#4867](https://github.com/lwouis/alt-tab-macos/issues/4867)) ([247f635](https://github.com/lwouis/alt-tab-macos/commit/247f635)), closes [#4891](https://github.com/lwouis/alt-tab-macos/issues/4891)
* title was truncated in app-icons appearance (closes [#4860](https://github.com/lwouis/alt-tab-macos/issues/4860)) ([a1cfd1d](https://github.com/lwouis/alt-tab-macos/commit/a1cfd1d))

### Features

* improve ar/de/fr/kn/ru/zh-tw localizations ([173bc97](https://github.com/lwouis/alt-tab-macos/commit/173bc97))
* improve windows detection ([cab591e](https://github.com/lwouis/alt-tab-macos/commit/cab591e))
* new cli command to focus a window using focus order (closes [#4610](https://github.com/lwouis/alt-tab-macos/issues/4610)) ([84166ab](https://github.com/lwouis/alt-tab-macos/commit/84166ab))
* save resources trying to detect certain windows ([33e5acf](https://github.com/lwouis/alt-tab-macos/commit/33e5acf))
2025-10-26 16:45:18 +00:00
lwouis c25b918a51 chore: update xcbeautify to v3.0.0 2025-10-26 17:40:28 +01:00
lwouis 173bc97d0f feat: improve ar/de/fr/kn/ru/zh-tw localizations 2025-10-26 17:40:28 +01:00
lwouis 84166ab954 feat: new cli command to focus a window using focus order (closes #4610) 2025-10-26 17:40:27 +01:00
lwouis a1cfd1de25 fix: title was truncated in app-icons appearance (closes #4860)
fix was to update ci to use macos 15 and xcode 26, since the issue goes away when compiling with xcode 26, without any code change
2025-10-26 17:40:26 +01:00
lwouis 58fcae7af8 chore: improve podfile setup 2025-10-26 16:18:02 +01:00
lwouis 29f0a08391 chore: ignore cursor files 2025-10-26 16:18:01 +01:00
lwouis 2d683e7e46 docs: mention kind support from jetbrains 2025-10-26 16:17:54 +01:00
lwouis 247f6353b0 fix: cmd+q would quit alt-tab instead of the selected app (closes #4867)
closes #4891
2025-10-26 16:15:12 +01:00
lwouis 08e28fd0a5 refactor: improve launch logs 2025-10-26 16:15:11 +01:00
lwouis cab591eb48 feat: improve windows detection 2025-10-26 16:15:02 +01:00
lwouis 33e5acf0ea feat: save resources trying to detect certain windows 2025-09-24 20:21:20 +02:00
semantic-release-bot 15554ef767 chore(release): 7.30.0 [skip ci]
# [7.30.0](https://github.com/lwouis/alt-tab-macos/compare/v7.29.0...v7.30.0) (2025-09-23)

### Bug Fixes

* bring back pre-v7.28 performance (closes [#4805](https://github.com/lwouis/alt-tab-macos/issues/4805)) ([fb6110d](https://github.com/lwouis/alt-tab-macos/commit/fb6110d))

### Features

* improve nb/nl/zh-tw localizations ([a9cb03c](https://github.com/lwouis/alt-tab-macos/commit/a9cb03c))
2025-09-23 22:05:16 +00:00
lwouis a9cb03c26f feat: improve nb/nl/zh-tw localizations 2025-09-24 00:00:25 +02:00
lwouis fb6110d0eb fix: bring back pre-v7.28 performance (closes #4805) 2025-09-23 23:53:31 +02:00
semantic-release-bot c3ace1faff chore(release): 7.29.0 [skip ci]
# [7.29.0](https://github.com/lwouis/alt-tab-macos/compare/v7.28.0...v7.29.0) (2025-09-20)

### Bug Fixes

* windows order was not updating correctly (closes [#4754](https://github.com/lwouis/alt-tab-macos/issues/4754)) ([1316eb2](https://github.com/lwouis/alt-tab-macos/commit/1316eb2))

### Features

* improve fr/ja languages ([c5286c3](https://github.com/lwouis/alt-tab-macos/commit/c5286c3))
2025-09-20 13:15:32 +00:00
lwouis c5286c3a6e feat: improve fr/ja languages 2025-09-19 22:19:52 +02:00
lwouis 1316eb2769 fix: windows order was not updating correctly (closes #4754)
(regression introduced in v7.28.0)
2025-09-19 21:37:24 +02:00
semantic-release-bot 27909f1824 chore(release): 7.28.0 [skip ci]
# [7.28.0](https://github.com/lwouis/alt-tab-macos/compare/v7.27.0...v7.28.0) (2025-09-15)

### Bug Fixes

* focusing windows could fail after focusing a frozen app ([#4520](https://github.com/lwouis/alt-tab-macos/issues/4520)) ([591ce52](https://github.com/lwouis/alt-tab-macos/commit/591ce52))
* improve detection of windows (closes [#4405](https://github.com/lwouis/alt-tab-macos/issues/4405)) ([3c79840](https://github.com/lwouis/alt-tab-macos/commit/3c79840))
* keyboard selection now works with dragging + mouse hover ([be077f1](https://github.com/lwouis/alt-tab-macos/commit/be077f1)), closes [#4711](https://github.com/lwouis/alt-tab-macos/issues/4711)
* remove high-volume unactionable logs (closes [#4697](https://github.com/lwouis/alt-tab-macos/issues/4697)) ([e93e42f](https://github.com/lwouis/alt-tab-macos/commit/e93e42f))

### Features

* add gujarati localization ([4ebd990](https://github.com/lwouis/alt-tab-macos/commit/4ebd990))
* add hong-kong cantonese + improve other languages ([78c8525](https://github.com/lwouis/alt-tab-macos/commit/78c8525))
* add preference to show only non-active apps (closes [#4691](https://github.com/lwouis/alt-tab-macos/issues/4691)) ([4567550](https://github.com/lwouis/alt-tab-macos/commit/4567550))
* improve norwegian localization ([726e13e](https://github.com/lwouis/alt-tab-macos/commit/726e13e))
* more fine-grained cursor-follows-focus preference (closes [#4734](https://github.com/lwouis/alt-tab-macos/issues/4734)) ([985a681](https://github.com/lwouis/alt-tab-macos/commit/985a681))
2025-09-15 20:18:27 +00:00
lwouis 78c852514f feat: add hong-kong cantonese + improve other languages 2025-09-15 22:10:41 +02:00
lwouis 985a681d72 feat: more fine-grained cursor-follows-focus preference (closes #4734) 2025-09-15 22:10:41 +02:00
lwouis 3c79840a29 fix: improve detection of windows (closes #4405) 2025-08-29 22:04:39 +02:00
lwouis 95ee614d9f refactor: improve logging and subscribeToNotification 2025-08-29 18:52:01 +02:00
lwouis 591ce5274f fix: focusing windows could fail after focusing a frozen app (#4520)
also generally reworked and improved background work handling
2025-08-29 10:00:43 +02:00
lwouis 3f18951368 refactor: improve running-applications handler 2025-08-29 10:00:43 +02:00
lwouis be077f1a67 fix: keyboard selection now works with dragging + mouse hover
(closes #4711)
2025-08-27 19:50:33 +02:00
lwouis 1a4b53917d chore: fix localization scripts 2025-08-27 19:50:33 +02:00
lwouis 726e13edcd feat: improve norwegian localization 2025-08-27 19:50:32 +02:00
lwouis 4ebd990e30 feat: add gujarati localization 2025-08-27 19:50:32 +02:00
lwouis 4567550978 feat: add preference to show only non-active apps (closes #4691) 2025-08-27 19:50:32 +02:00
lwouis f489bd7d36 ci: bring back appcenter symbols upload until june 2026 2025-08-27 19:50:32 +02:00
lwouis e93e42f952 fix: remove high-volume unactionable logs (closes #4697) 2025-08-22 21:09:05 +02:00
semantic-release-bot 250c9c4bce chore(release): 7.27.0 [skip ci]
# [7.27.0](https://github.com/lwouis/alt-tab-macos/compare/v7.26.0...v7.27.0) (2025-08-12)

### Bug Fixes

* restore default command+tab if shortcut is unbound (closes [#4642](https://github.com/lwouis/alt-tab-macos/issues/4642)) ([f66c92a](https://github.com/lwouis/alt-tab-macos/commit/f66c92a))

### Features

* improve cs/th localizations ([aa46a62](https://github.com/lwouis/alt-tab-macos/commit/aa46a62))
* windowless apps can now be shown in focus-order (closes [#4653](https://github.com/lwouis/alt-tab-macos/issues/4653)) ([5db53b5](https://github.com/lwouis/alt-tab-macos/commit/5db53b5))
2025-08-12 20:02:54 +00:00
lwouis aa46a62457 feat: improve cs/th localizations 2025-08-12 16:33:17 +02:00
lwouis f66c92aefb fix: restore default command+tab if shortcut is unbound (closes #4642) 2025-08-12 16:26:32 +02:00
Inês Almeida a696611615 docs: fix broken link to private api documentation 2025-08-12 14:24:30 +02:00
lwouis 5db53b5a9e feat: windowless apps can now be shown in focus-order (closes #4653) 2025-08-11 11:41:05 +02:00
semantic-release-bot e9e732756e chore(release): 7.26.0 [skip ci]
# [7.26.0](https://github.com/lwouis/alt-tab-macos/compare/v7.25.0...v7.26.0) (2025-07-31)

### Bug Fixes

* ignore autodesk fusion internal panels (closes [#4578](https://github.com/lwouis/alt-tab-macos/issues/4578)) ([f67d182](https://github.com/lwouis/alt-tab-macos/commit/f67d182))

### Features

* improve da/fi/ga localizations ([f376529](https://github.com/lwouis/alt-tab-macos/commit/f376529))
* improve preference to show-apps-with-open-window (closes [#4485](https://github.com/lwouis/alt-tab-macos/issues/4485)) ([67f5098](https://github.com/lwouis/alt-tab-macos/commit/67f5098))
2025-07-31 17:55:19 +00:00
lwouis ca96b85352 ci: more portable unicode sorting for contributors 2025-07-31 19:48:59 +02:00
lwouis 67f5098c95 feat: improve preference to show-apps-with-open-window (closes #4485) 2025-07-31 12:01:32 +02:00
lwouis f37652942d feat: improve da/fi/ga localizations 2025-07-29 10:43:28 +02:00
Gregory f67d182a92 fix: ignore autodesk fusion internal panels (closes #4578) 2025-07-01 10:34:54 +02:00
semantic-release-bot b325cc75c0 chore(release): 7.25.0 [skip ci]
# [7.25.0](https://github.com/lwouis/alt-tab-macos/compare/v7.24.0...v7.25.0) (2025-06-14)

### Bug Fixes

* icons on thumbnails could sometimes be incorrect ([b4bc0b0](https://github.com/lwouis/alt-tab-macos/commit/b4bc0b0))

### Features

* new cli commands: --show, --detailed-list (closes [#4489](https://github.com/lwouis/alt-tab-macos/issues/4489)) ([b0ce899](https://github.com/lwouis/alt-tab-macos/commit/b0ce899))
2025-06-14 12:29:24 +00:00
lwouis 6cc76903b0 docs: update contributors list 2025-06-14 14:18:55 +02:00
lwouis b4bc0b006a fix: icons on thumbnails could sometimes be incorrect
example use-case: show a Finder window, and middle-click it. The next thumbnail under the mouse will not show its purple quit icon
2025-06-14 14:18:55 +02:00
lwouis b0ce899a71 feat: new cli commands: --show, --detailed-list (closes #4489) 2025-06-14 14:18:55 +02:00
semantic-release-bot bd162a9e08 chore(release): 7.24.0 [skip ci]
# [7.24.0](https://github.com/lwouis/alt-tab-macos/compare/v7.23.0...v7.24.0) (2025-05-05)

### Features

* clicking to focus windows/apps is now easier (closes [#4407](https://github.com/lwouis/alt-tab-macos/issues/4407)) ([397457c](https://github.com/lwouis/alt-tab-macos/commit/397457c))
* improve ca/pt/ro localizations ([8b7d69c](https://github.com/lwouis/alt-tab-macos/commit/8b7d69c))

### Performance Improvements

* avoid updating preview if not necessary ([518f8b4](https://github.com/lwouis/alt-tab-macos/commit/518f8b4))
2025-05-05 10:07:24 +00:00
lwouis 8b7d69c0ff feat: improve ca/pt/ro localizations 2025-05-05 12:02:25 +02:00
lwouis 518f8b402e perf: avoid updating preview if not necessary 2025-05-05 11:59:14 +02:00
lwouis 397457cacb feat: clicking to focus windows/apps is now easier (closes #4407) 2025-04-04 19:32:04 +02:00
semantic-release-bot eee0db133c chore(release): 7.23.0 [skip ci]
# [7.23.0](https://github.com/lwouis/alt-tab-macos/compare/v7.22.0...v7.23.0) (2025-04-01)

### Bug Fixes

* avoid crashing on uncommon keys in shortcuts (closes [#4379](https://github.com/lwouis/alt-tab-macos/issues/4379)) ([9d852ee](https://github.com/lwouis/alt-tab-macos/commit/9d852ee))
* window name would sometimes be empty (closes [#4350](https://github.com/lwouis/alt-tab-macos/issues/4350)) ([911c3c1](https://github.com/lwouis/alt-tab-macos/commit/911c3c1))

### Features

* improve hindi localization ([dec0519](https://github.com/lwouis/alt-tab-macos/commit/dec0519))
2025-04-01 21:38:28 +00:00
lwouis dec05198c7 feat: improve hindi localization 2025-04-01 23:31:45 +02:00
lwouis 911c3c17c5 fix: window name would sometimes be empty (closes #4350) 2025-04-01 10:43:24 +02:00
lwouis 9d852eee9c fix: avoid crashing on uncommon keys in shortcuts (closes #4379) 2025-03-31 12:09:04 +02:00
semantic-release-bot 17e1f1e4c7 chore(release): 7.22.0 [skip ci]
# [7.22.0](https://github.com/lwouis/alt-tab-macos/compare/v7.21.1...v7.22.0) (2025-03-30)

### Bug Fixes

* language switcher picked up as window ([f4f7d9a](https://github.com/lwouis/alt-tab-macos/commit/f4f7d9a))
* prevent rare crash ([4e35f9f](https://github.com/lwouis/alt-tab-macos/commit/4e35f9f))

### Features

* update ca/de/fr/ko/ru/tw localizations ([9b3f936](https://github.com/lwouis/alt-tab-macos/commit/9b3f936))
2025-03-30 00:58:26 +00:00
lwouis c0ac29fdd8 ci: remove appcenter upload 2025-03-30 01:51:26 +01:00
lwouis 9b3f93688e feat: update ca/de/fr/ko/ru/tw localizations 2025-03-30 01:34:58 +01:00
Yaros f4f7d9addc fix: language switcher picked up as window 2025-03-30 01:29:18 +01:00
lwouis 4e35f9f290 fix: prevent rare crash 2025-02-23 21:06:22 +01:00
semantic-release-bot 820b6ea3aa chore(release): 7.21.1 [skip ci]
## [7.21.1](https://github.com/lwouis/alt-tab-macos/compare/v7.21.0...v7.21.1) (2025-02-22)

### Bug Fixes

* update how feedback messages are sent ([647f900](https://github.com/lwouis/alt-tab-macos/commit/647f900))
2025-02-22 09:54:48 +00:00
lwouis 647f900b85 fix: update how feedback messages are sent 2025-02-22 10:50:11 +01:00
semantic-release-bot 6c0f97ffe9 chore(release): 7.21.0 [skip ci]
# [7.21.0](https://github.com/lwouis/alt-tab-macos/compare/v7.20.1...v7.21.0) (2025-02-21)

### Bug Fixes

* app would sometimes crash (closes [#4244](https://github.com/lwouis/alt-tab-macos/issues/4244)) ([d543393](https://github.com/lwouis/alt-tab-macos/commit/d543393))

### Features

* add lithuanian localization ([bc95b90](https://github.com/lwouis/alt-tab-macos/commit/bc95b90))
* improve chinese localization ([330ac54](https://github.com/lwouis/alt-tab-macos/commit/330ac54))
2025-02-21 21:33:37 +00:00
lwouis bc95b905af feat: add lithuanian localization 2025-02-21 22:27:58 +01:00
lwouis 330ac54c6f feat: improve chinese localization 2025-02-21 22:15:57 +01:00
lwouis 54249d03dd refactor: use new fine-grained token + better logs 2025-02-21 22:01:22 +01:00
lwouis d543393e3f fix: app would sometimes crash (closes #4244) 2025-02-21 21:20:29 +01:00
lwouis ee010de36c refactor: remove unused method 2025-02-20 22:44:26 +01:00
semantic-release-bot 3c7aaafa63 chore(release): 7.20.1 [skip ci]
## [7.20.1](https://github.com/lwouis/alt-tab-macos/compare/v7.20.0...v7.20.1) (2025-02-20)

### Bug Fixes

* may crash when changing space or screen ([b62cec0](https://github.com/lwouis/alt-tab-macos/commit/b62cec0))
2025-02-20 07:11:54 +00:00
lwouis b62cec0cdc fix: may crash when changing space or screen 2025-02-20 08:04:13 +01:00
semantic-release-bot a474660498 chore(release): 7.20.0 [skip ci]
# [7.20.0](https://github.com/lwouis/alt-tab-macos/compare/v7.19.1...v7.20.0) (2025-02-19)

### Bug Fixes

* better detect windows from other spaces (closes [#1324](https://github.com/lwouis/alt-tab-macos/issues/1324)) ([2cd8b96](https://github.com/lwouis/alt-tab-macos/commit/2cd8b96))
* colored circles would go away on ui refresh (closes [#4151](https://github.com/lwouis/alt-tab-macos/issues/4151)) ([dcea005](https://github.com/lwouis/alt-tab-macos/commit/dcea005))
* stage manager no longer skews the thumbnails (closes [#1731](https://github.com/lwouis/alt-tab-macos/issues/1731)) ([93defcd](https://github.com/lwouis/alt-tab-macos/commit/93defcd))
* window might be noted to be on the wrong space ([5413372](https://github.com/lwouis/alt-tab-macos/commit/5413372))

### Features

* add javanese localization ([8564ed2](https://github.com/lwouis/alt-tab-macos/commit/8564ed2))
* improve performance and lower resources consumption ([9d78700](https://github.com/lwouis/alt-tab-macos/commit/9d78700))
* improve thumbnails quality and performance (closes [#4183](https://github.com/lwouis/alt-tab-macos/issues/4183)) ([9d6fc68](https://github.com/lwouis/alt-tab-macos/commit/9d6fc68))
* improve window focusing action ([8dd63c7](https://github.com/lwouis/alt-tab-macos/commit/8dd63c7))
* update fr, kn, pt-br, uk localizations ([fd0411b](https://github.com/lwouis/alt-tab-macos/commit/fd0411b))
2025-02-19 17:48:16 +00:00
lwouis 6e2a5ff081 docs: sunset discord server 2025-02-19 18:40:52 +01:00
lwouis 8dd63c722f feat: improve window focusing action 2025-02-15 20:02:41 +01:00
lwouis e98dff325d refactor: use more accurate type for private apis 2025-02-14 21:46:09 +01:00
lwouis 8d93508062 chore: remove unused param from previous experiment 2025-02-13 11:49:30 +01:00
lwouis fd0411b508 feat: update fr, kn, pt-br, uk localizations 2025-02-13 11:49:30 +01:00
lwouis 8564ed255a feat: add javanese localization 2025-02-13 11:49:29 +01:00
lwouis 9d78700ab7 feat: improve performance and lower resources consumption
avoid unnecessary AX calls and batch calls when possible
2025-02-13 11:49:29 +01:00
lwouis c72fedbb30 refactor: update window fullscreen, size, position, on space change 2025-02-12 18:01:20 +01:00
lwouis e637c61cc9 refactor: debounce high-frequency window events 2025-02-12 18:01:20 +01:00
lwouis dae19ca067 refactor: clarify type and windowless state 2025-02-12 18:01:20 +01:00
lwouis 9d6fc68642 feat: improve thumbnails quality and performance (closes #4183) 2025-02-12 18:01:19 +01:00
lwouis 2cd8b96d38 fix: better detect windows from other spaces (closes #1324)
We found a workaround after more than 3 years of searching!
2025-02-12 18:01:19 +01:00
lwouis 541337259d fix: window might be noted to be on the wrong space 2025-02-03 21:55:47 +01:00
lwouis 93defcd3a7 fix: stage manager no longer skews the thumbnails (closes #1731) 2025-02-03 11:25:47 +01:00
lwouis 69edbbdf42 refactor: improve writing launch-agent and its logs 2025-01-24 10:42:57 +01:00
lwouis dcea005d8d fix: colored circles would go away on ui refresh (closes #4151) 2025-01-22 12:05:52 +01:00
lwouis cfd59d31a1 chore: use a longer datetime format in logs 2025-01-22 12:05:52 +01:00
semantic-release-bot f42ffa61d1 chore(release): 7.19.1 [skip ci]
## [7.19.1](https://github.com/lwouis/alt-tab-macos/compare/v7.19.0...v7.19.1) (2025-01-14)

### Bug Fixes

* a few labels were not displaying (closes [#4127](https://github.com/lwouis/alt-tab-macos/issues/4127)) ([0a22547](https://github.com/lwouis/alt-tab-macos/commit/0a22547))
2025-01-14 21:43:44 +00:00
lwouis 0a2254702f fix: a few labels were not displaying (closes #4127) 2025-01-14 22:37:09 +01:00
semantic-release-bot d02327af2d chore(release): 7.19.0 [skip ci]
# [7.19.0](https://github.com/lwouis/alt-tab-macos/compare/v7.18.1...v7.19.0) (2025-01-14)

### Features

* add preference to toggle animation of preview (closes [#4118](https://github.com/lwouis/alt-tab-macos/issues/4118)) ([c10ca2a](https://github.com/lwouis/alt-tab-macos/commit/c10ca2a))
* middle-click will now close windows and quit applications ([2f8c014](https://github.com/lwouis/alt-tab-macos/commit/2f8c014))
2025-01-14 17:37:05 +00:00
lwouis c10ca2a77e feat: add preference to toggle animation of preview (closes #4118) 2025-01-14 12:24:55 +01:00
lwouis 2f8c01418d feat: middle-click will now close windows and quit applications 2025-01-14 12:24:55 +01:00
semantic-release-bot 3a0c84a8f5 chore(release): 7.18.1 [skip ci]
## [7.18.1](https://github.com/lwouis/alt-tab-macos/compare/v7.18.0...v7.18.1) (2025-01-12)

### Bug Fixes

* don't check screen-recording permission if unnecessary ([f3b116e](https://github.com/lwouis/alt-tab-macos/commit/f3b116e)), closes [#4113](https://github.com/lwouis/alt-tab-macos/issues/4113)
* show shadows around thumbnails (closes [#4068](https://github.com/lwouis/alt-tab-macos/issues/4068)) ([597b443](https://github.com/lwouis/alt-tab-macos/commit/597b443))
2025-01-12 21:33:06 +00:00
lwouis 597b443796 fix: show shadows around thumbnails (closes #4068) 2025-01-12 22:25:45 +01:00
lwouis 0ea925289b docs: clarify what the screen-recording permission is used for 2025-01-12 22:25:45 +01:00
lwouis f3b116e47c fix: don't check screen-recording permission if unnecessary
closes #4113
2025-01-12 22:25:45 +01:00
lwouis 4c3ec7d067 refactor: use swift shorthand for optional check 2025-01-12 22:25:45 +01:00
lwouis 941d8afb9a chore: document why we use CGSHWCaptureWindowList 2025-01-12 22:25:45 +01:00
lwouis 8e41662088 chore: test out SCScreenshotManager.captureImage 2025-01-12 22:25:44 +01:00
semantic-release-bot 71bb2d889b chore(release): 7.18.0 [skip ci]
# [7.18.0](https://github.com/lwouis/alt-tab-macos/compare/v7.17.0...v7.18.0) (2025-01-07)

### Bug Fixes

* various issues with the app freezing or being slowly ([121515c](https://github.com/lwouis/alt-tab-macos/commit/121515c))
* window order on first display was wrong ([db5644e](https://github.com/lwouis/alt-tab-macos/commit/db5644e))
* window preview was not showing in titles style ([684cc66](https://github.com/lwouis/alt-tab-macos/commit/684cc66))

### Features

* improve polish localization ([c712473](https://github.com/lwouis/alt-tab-macos/commit/c712473))
2025-01-07 00:20:50 +00:00
lwouis c712473c7a feat: improve polish localization 2025-01-07 01:16:05 +01:00
lwouis 121515cbc7 fix: various issues with the app freezing or being slowly 2025-01-07 01:12:06 +01:00
lwouis 8b52dc8acb chore: add testbed file if i ever need to investigate again 2025-01-07 01:09:37 +01:00
lwouis db5644e058 fix: window order on first display was wrong 2025-01-06 23:29:15 +01:00
lwouis 684cc666d3 fix: window preview was not showing in titles style 2025-01-06 14:25:40 +01:00
lwouis dfff608ad1 docs: document cli usage on the website 2025-01-05 22:55:11 +01:00
semantic-release-bot f1c5ae73c2 chore(release): 7.17.0 [skip ci]
# [7.17.0](https://github.com/lwouis/alt-tab-macos/compare/v7.16.0...v7.17.0) (2025-01-05)

### Bug Fixes

* app icons could sometimes be at the wrong size ([d5d1311](https://github.com/lwouis/alt-tab-macos/commit/d5d1311))
* more robust screen-recording permission detection ([d85ec7b](https://github.com/lwouis/alt-tab-macos/commit/d85ec7b))

### Features

* handle cli commands: --list and --focus=window_id ([0f2c0e7](https://github.com/lwouis/alt-tab-macos/commit/0f2c0e7))
2025-01-05 18:28:55 +00:00
lwouis d85ec7bcfb fix: more robust screen-recording permission detection 2025-01-05 19:21:53 +01:00
lwouis 2855b1bb0b refactor: cache more runningapplication properties for perf 2025-01-05 19:21:53 +01:00
lwouis 2a616e2518 chore: remove unused xcode flag during run 2025-01-05 19:21:53 +01:00
lwouis d5d131185e fix: app icons could sometimes be at the wrong size 2025-01-05 19:21:53 +01:00
lwouis 0f2c0e794c feat: handle cli commands: --list and --focus=window_id 2025-01-05 19:21:53 +01:00
lwouis d4e697c0de docs: document why we don't see queue labels in instruments 2025-01-04 13:28:20 +01:00
semantic-release-bot 720dde1c06 chore(release): 7.16.0 [skip ci]
# [7.16.0](https://github.com/lwouis/alt-tab-macos/compare/v7.15.0...v7.16.0) (2025-01-04)

### Bug Fixes

* app badges could be incorrectly positioned on the very first launch ([c2ccccd](https://github.com/lwouis/alt-tab-macos/commit/c2ccccd))
* app-icons wouldn't show when permissions were skipped ([837fa03](https://github.com/lwouis/alt-tab-macos/commit/837fa03))
* screen recording warnings shouldn't appear with skipped permissions ([f027b47](https://github.com/lwouis/alt-tab-macos/commit/f027b47))

### Features

* improve performance by caching preferences better ([d653a54](https://github.com/lwouis/alt-tab-macos/commit/d653a54))
2025-01-04 01:31:33 +00:00
lwouis 1e017475ff refactor: improve naming 2025-01-04 02:24:03 +01:00
lwouis 95e51d1c27 refactor: more performant methods used 2025-01-04 01:36:15 +01:00
lwouis d653a54fc3 feat: improve performance by caching preferences better 2025-01-04 01:18:50 +01:00
lwouis c2ccccd093 fix: app badges could be incorrectly positioned on the very first launch 2025-01-04 01:08:36 +01:00
lwouis 837fa03f64 fix: app-icons wouldn't show when permissions were skipped
also cached NSScreen.preferred for performance
2025-01-03 23:40:01 +01:00
lwouis f027b4795f fix: screen recording warnings shouldn't appear with skipped permissions 2025-01-03 23:33:55 +01:00
lwouis 6ede54e3e0 refactor: avoid re-fetching runningapplication data for perf 2025-01-03 19:15:06 +01:00
lwouis 922d259193 chore: set xcode to be able to profile alttab 2025-01-03 19:13:17 +01:00
lwouis 56075b5766 refactor: split private apis for clarity 2025-01-03 16:10:40 +01:00
lwouis b0f02c6a36 refactor: separate protocol methods for clarity + clarify required init 2025-01-03 13:58:11 +01:00
lwouis de1326e118 refactor: separate protocol methods for clarity 2025-01-03 13:58:10 +01:00
lwouis 53d1d1fded refactor: reformat + app code inspect + split protocol 2025-01-03 13:58:10 +01:00
lwouis e17f427a5d refactor: reformat + app code inspect 2025-01-03 13:58:10 +01:00
lwouis df5af7d60c refactor: reformat 2025-01-03 13:58:10 +01:00
lwouis 702cb0d140 refactor: split privateapis into used and experiments 2025-01-03 13:58:10 +01:00
lwouis 9e415bff54 refactor: reformat 2025-01-03 13:58:08 +01:00
lwouis a696a0e0b2 chore: update swiftformat rules
swift format does a wrapping that i find too rough, so we can't really use it at the moment, unfortunately
2025-01-03 11:45:55 +01:00
lwouis 52026701e4 refactor: simplify 2025-01-03 11:45:55 +01:00
lwouis 7471488e33 refactor: split preferences and other reorganisation 2025-01-03 11:45:55 +01:00
lwouis 0ef8a0b2d4 refactor: organizing and separating things better 2025-01-03 11:45:54 +01:00
semantic-release-bot 76a72a5ead chore(release): 7.15.0 [skip ci]
# [7.15.0](https://github.com/lwouis/alt-tab-macos/compare/v7.14.1...v7.15.0) (2025-01-02)

### Bug Fixes

* better position preview for fullscreen windows (closes [#4051](https://github.com/lwouis/alt-tab-macos/issues/4051)) ([3b0cba4](https://github.com/lwouis/alt-tab-macos/commit/3b0cba4))
* layout was sometimes broken in app-icons style (closes [#4036](https://github.com/lwouis/alt-tab-macos/issues/4036)) ([be5eb26](https://github.com/lwouis/alt-tab-macos/commit/be5eb26))

### Features

* improve chinese-taiwanese localization ([dfcf9de](https://github.com/lwouis/alt-tab-macos/commit/dfcf9de))
* improve performance and order accuracy at launch ([fc6d636](https://github.com/lwouis/alt-tab-macos/commit/fc6d636))
* improve quality of thumbnails and performance ([a138a92](https://github.com/lwouis/alt-tab-macos/commit/a138a92))
* reduce space between app icon and window title ([295eb2b](https://github.com/lwouis/alt-tab-macos/commit/295eb2b))
* switcher displays faster; other performance improvements ([b51ff65](https://github.com/lwouis/alt-tab-macos/commit/b51ff65))
2025-01-02 18:33:18 +00:00
lwouis 3b0cba493b fix: better position preview for fullscreen windows (closes #4051) 2025-01-02 19:28:35 +01:00
lwouis bc9f97f852 chore: remove unchanging param 2025-01-02 19:28:35 +01:00
lwouis 295eb2bd60 feat: reduce space between app icon and window title 2025-01-02 19:28:35 +01:00
lwouis dfcf9de78e feat: improve chinese-taiwanese localization 2025-01-02 19:28:35 +01:00
lwouis fc6d63603a feat: improve performance and order accuracy at launch 2025-01-02 19:28:34 +01:00
lwouis 9156ad915a refactor: clarify a nstextfield workaround 2025-01-02 19:28:34 +01:00
lwouis a138a922ef feat: improve quality of thumbnails and performance 2025-01-02 19:28:34 +01:00
lwouis b51ff6583d feat: switcher displays faster; other performance improvements 2025-01-02 01:55:27 +01:00
lwouis 7207ad6da7 chore: variadic param was not passed correctly; logging was messy 2024-12-30 23:55:15 +01:00
lwouis e3fafbc6ff chore: migrations would play when debugging local builds 2024-12-30 23:43:50 +01:00
lwouis be5eb26385 fix: layout was sometimes broken in app-icons style (closes #4036) 2024-12-30 12:17:02 +01:00
lwouis e9b529a644 chore: clean up 2 values which are constant 2024-12-30 12:15:56 +01:00
lwouis 250a1bcc81 chore: organize codesign script 2024-12-30 11:12:52 +01:00
semantic-release-bot 96edb065d7 chore(release): 7.14.1 [skip ci]
## [7.14.1](https://github.com/lwouis/alt-tab-macos/compare/v7.14.0...v7.14.1) (2024-12-28)

### Bug Fixes

* improve label display in app-icons style ([7e501a4](https://github.com/lwouis/alt-tab-macos/commit/7e501a4))
* title would sometimes not show when mouse hovering ([dd05ba2](https://github.com/lwouis/alt-tab-macos/commit/dd05ba2))
2024-12-28 18:26:04 +00:00
lwouis 7e501a460a fix: improve label display in app-icons style 2024-12-28 19:20:15 +01:00
lwouis dd05ba239e fix: title would sometimes not show when mouse hovering
this would happen in AppIcons Style, when a window changed in the background, while AltTab was open
2024-12-28 19:20:14 +01:00
lwouis b373fc465b chore: use a constraint add-or-update helper to avoid conflicts 2024-12-28 19:20:14 +01:00
lwouis f92f7ca803 chore: fix new compilation errors from xcode 16.2 2024-12-28 19:20:14 +01:00
lwouis 51062a2499 ci: add add_terms script + organize scripts 2024-12-28 19:20:14 +01:00
semantic-release-bot 48a3967b82 chore(release): 7.14.0 [skip ci]
# [7.14.0](https://github.com/lwouis/alt-tab-macos/compare/v7.13.1...v7.14.0) (2024-12-26)

### Bug Fixes

* improve acknowledgments tab (closes [#4025](https://github.com/lwouis/alt-tab-macos/issues/4025)) ([db5500f](https://github.com/lwouis/alt-tab-macos/commit/db5500f))

### Features

* clear feedback form after submission (closes [#4026](https://github.com/lwouis/alt-tab-macos/issues/4026)) ([42bbd0f](https://github.com/lwouis/alt-tab-macos/commit/42bbd0f))
* improve chinese, irish, italian localizations ([18ef16f](https://github.com/lwouis/alt-tab-macos/commit/18ef16f))
* swipes can now be horizontal or vertical (closes [#4020](https://github.com/lwouis/alt-tab-macos/issues/4020)) ([fda3ada](https://github.com/lwouis/alt-tab-macos/commit/fda3ada))
2024-12-26 23:41:18 +00:00
lwouis 18ef16f6ee feat: improve chinese, irish, italian localizations 2024-12-27 00:33:05 +01:00
lwouis fda3ada055 feat: swipes can now be horizontal or vertical (closes #4020)
swipe recognition has also been improved in many ways
2024-12-27 00:33:05 +01:00
lwouis db5500f130 fix: improve acknowledgments tab (closes #4025) 2024-12-25 01:51:23 +01:00
lwouis 42bbd0fe01 feat: clear feedback form after submission (closes #4026) 2024-12-25 01:04:12 +01:00
lwouis b257752812 chore: make local setup work with openssl v3.x 2024-12-25 00:53:33 +01:00
lwouis 54b7c8d697 chore: update svg-to-png script 2024-12-24 15:32:57 +01:00
lwouis bcafd0790f chore: fix utils folder in pbxproj 2024-12-24 11:46:20 +01:00
semantic-release-bot e07da9cad9 chore(release): 7.13.1 [skip ci]
## [7.13.1](https://github.com/lwouis/alt-tab-macos/compare/v7.13.0...v7.13.1) (2024-12-24)

### Bug Fixes

* acknowledgments tab was hard to read in dark mode (closes [#4019](https://github.com/lwouis/alt-tab-macos/issues/4019)) ([4481d94](https://github.com/lwouis/alt-tab-macos/commit/4481d94))
* app crash from v7.13.0 (closes [#4016](https://github.com/lwouis/alt-tab-macos/issues/4016)) ([d3b5bef](https://github.com/lwouis/alt-tab-macos/commit/d3b5bef))
2024-12-24 09:02:02 +00:00
lwouis d3b5befe3e fix: app crash from v7.13.0 (closes #4016) 2024-12-24 09:55:20 +01:00
lwouis 4481d94fa2 fix: acknowledgments tab was hard to read in dark mode (closes #4019) 2024-12-24 09:55:20 +01:00
lwouis 982a6dd5f2 chore: improve project settings 2024-12-24 09:55:20 +01:00
semantic-release-bot 898fc8c13c chore(release): 7.13.0 [skip ci]
# [7.13.0](https://github.com/lwouis/alt-tab-macos/compare/v7.12.0...v7.13.0) (2024-12-24)

### Bug Fixes

* enabling previews with multiple screens could lead to flickering ([87a2b21](https://github.com/lwouis/alt-tab-macos/commit/87a2b21))
* prevent initial window lastFocusOrder overlaps ([d32f953](https://github.com/lwouis/alt-tab-macos/commit/d32f953))
* previews on multiple screens could get misplaced ([2a0a858](https://github.com/lwouis/alt-tab-macos/commit/2a0a858))
* titles could sometimes be covered when in small size ([c5e13cc](https://github.com/lwouis/alt-tab-macos/commit/c5e13cc))

### Features

* add fade-in for window previews (closes [#2456](https://github.com/lwouis/alt-tab-macos/issues/2456)) ([40c9a18](https://github.com/lwouis/alt-tab-macos/commit/40c9a18))
* allow vertical swipes as trigger (closes [#4012](https://github.com/lwouis/alt-tab-macos/issues/4012)) ([9adf64c](https://github.com/lwouis/alt-tab-macos/commit/9adf64c))
* improve localizations ([6d9059e](https://github.com/lwouis/alt-tab-macos/commit/6d9059e))
* reduce disk size of localizations ([9ec2762](https://github.com/lwouis/alt-tab-macos/commit/9ec2762))
* swiping won't wrap-around to other rows (closes [#3983](https://github.com/lwouis/alt-tab-macos/issues/3983)) ([6215b65](https://github.com/lwouis/alt-tab-macos/commit/6215b65))
2024-12-24 01:55:39 +00:00
lwouis 9ec2762bff feat: reduce disk size of localizations 2024-12-24 02:48:27 +01:00
lwouis 6d9059ee86 feat: improve localizations 2024-12-24 02:30:53 +01:00
lwouis ef6ab620fb refactor: replace titles with nstextfield for performance 2024-12-24 02:17:59 +01:00
lwouis ecf4cb15be chore: improve poeditor override scripts 2024-12-24 02:17:59 +01:00
lwouis c9d36b5bad chore: add script to upload local l10n context to poeditor 2024-12-24 02:17:59 +01:00
lwouis 9e932799ee refactor: use auto-released notification observer api 2024-12-24 02:17:59 +01:00
lwouis 6215b65ec9 feat: swiping won't wrap-around to other rows (closes #3983) 2024-12-24 02:17:58 +01:00
lwouis 9adf64c374 feat: allow vertical swipes as trigger (closes #4012) 2024-12-24 02:17:58 +01:00
Ben Delaney d32f9533e3 fix: prevent initial window lastFocusOrder overlaps
The `sortByLevel` method in the Windows class has been updated to determine window z-order properly across all visible spaces. It now sets the `lastFocusOrder` for each window, using a map from window IDs to their z-order position. Windows not present in the list are set to have `lastFocusOrder` of `Int.max`. Afterwards, windows are sorted by their `lastFocusOrder`, and these values are ensured to be monotonic, starting from 0.
2024-12-24 02:17:58 +01:00
Ben Delaney 2a0a8585df fix: previews on multiple screens could get misplaced 2024-12-24 02:17:58 +01:00
Ben Delaney 87a2b219a5 fix: enabling previews with multiple screens could lead to flickering 2024-12-24 02:17:58 +01:00
allsochen c5e13ccc84 fix: titles could sometimes be covered when in small size 2024-12-24 02:17:58 +01:00
lwouis 40c9a18be4 feat: add fade-in for window previews (closes #2456) 2024-12-12 21:38:39 +01:00
semantic-release-bot 8a4aa7908f chore(release): 7.12.0 [skip ci]
# [7.12.0](https://github.com/lwouis/alt-tab-macos/compare/v7.11.0...v7.12.0) (2024-12-11)

### Bug Fixes

* switcher could appear collapsed in titles style (closes [#3744](https://github.com/lwouis/alt-tab-macos/issues/3744)) ([60534bc](https://github.com/lwouis/alt-tab-macos/commit/60534bc))

### Features

* acknowledgments tab was slow to display (closes [#3957](https://github.com/lwouis/alt-tab-macos/issues/3957)) ([41ddd7c](https://github.com/lwouis/alt-tab-macos/commit/41ddd7c))
2024-12-11 20:59:03 +00:00
lwouis 82879e39e7 docs: update contributors 2024-12-11 21:53:55 +01:00
lwouis 60534bcfe3 fix: switcher could appear collapsed in titles style (closes #3744) 2024-12-11 21:51:09 +01:00
lwouis 41ddd7c1a6 feat: acknowledgments tab was slow to display (closes #3957) 2024-12-10 23:17:01 +01:00
semantic-release-bot 5601a556c9 chore(release): 7.11.0 [skip ci]
# [7.11.0](https://github.com/lwouis/alt-tab-macos/compare/v7.10.0...v7.11.0) (2024-12-09)

### Bug Fixes

* always show a window in show:apps mode (closes [#3950](https://github.com/lwouis/alt-tab-macos/issues/3950)) ([ac70fcc](https://github.com/lwouis/alt-tab-macos/commit/ac70fcc))

### Features

* decrease shortcuts from 5 to 3 ([d65f220](https://github.com/lwouis/alt-tab-macos/commit/d65f220))
* improve chinese localization ([764e0f3](https://github.com/lwouis/alt-tab-macos/commit/764e0f3))
* improve focus in show:apps mode (closes [#3951](https://github.com/lwouis/alt-tab-macos/issues/3951)) ([cb191d6](https://github.com/lwouis/alt-tab-macos/commit/cb191d6))
* support 3 or 4 finger swipes to use the app (closes [#730](https://github.com/lwouis/alt-tab-macos/issues/730)) ([903e758](https://github.com/lwouis/alt-tab-macos/commit/903e758))
* switcher will now show in "show desktop" mode (closes [#783](https://github.com/lwouis/alt-tab-macos/issues/783)) ([9b85f00](https://github.com/lwouis/alt-tab-macos/commit/9b85f00))
2024-12-09 23:06:18 +00:00
lwouis 764e0f3f25 feat: improve chinese localization 2024-12-09 23:52:41 +01:00
lwouis 3619807cb9 refactor: clean up trackpad-events 2024-12-09 23:52:40 +01:00
lwouis d65f220530 feat: decrease shortcuts from 5 to 3 2024-12-09 19:33:49 +01:00
Saswat Bhattacharya 903e758528 feat: support 3 or 4 finger swipes to use the app (closes #730) 2024-12-09 19:33:43 +01:00
lwouis 9b85f00564 feat: switcher will now show in "show desktop" mode (closes #783) 2024-12-09 14:12:06 +01:00
lwouis cb191d60f3 feat: improve focus in show:apps mode (closes #3951) 2024-12-09 14:12:06 +01:00
lwouis ac70fcc5f9 fix: always show a window in show:apps mode (closes #3950) 2024-12-08 18:16:15 +01:00
semantic-release-bot 68d24919b1 chore(release): 7.10.0 [skip ci]
# [7.10.0](https://github.com/lwouis/alt-tab-macos/compare/v7.9.0...v7.10.0) (2024-12-08)

### Features

* improve catalan localization ([7e199f6](https://github.com/lwouis/alt-tab-macos/commit/7e199f6))
* make it more clear how to hide the menubar icon (closes [#503](https://github.com/lwouis/alt-tab-macos/issues/503)) ([9ca0649](https://github.com/lwouis/alt-tab-macos/commit/9ca0649))
2024-12-08 11:36:49 +00:00
lwouis baa411d9c7 refactor: prefer for loop 2024-12-08 11:52:08 +01:00
lwouis 7e199f6815 feat: improve catalan localization 2024-12-08 11:52:08 +01:00
lwouis 9ca0649368 feat: make it more clear how to hide the menubar icon (closes #503) 2024-12-08 11:52:08 +01:00
semantic-release-bot 987b6b2f82 chore(release): 7.9.0 [skip ci]
# [7.9.0](https://github.com/lwouis/alt-tab-macos/compare/v7.8.0...v7.9.0) (2024-12-07)

### Features

* improve catalan and taiwanese localizations ([bf3a4dc](https://github.com/lwouis/alt-tab-macos/commit/bf3a4dc))
* try to avoid launching multiple instances at login (closes [#1840](https://github.com/lwouis/alt-tab-macos/issues/1840)) ([e4cfd85](https://github.com/lwouis/alt-tab-macos/commit/e4cfd85))
2024-12-07 17:17:52 +00:00
lwouis bf3a4dcc7a feat: improve catalan and taiwanese localizations 2024-12-07 18:12:47 +01:00
lwouis e4cfd85dc7 feat: try to avoid launching multiple instances at login (closes #1840) 2024-12-07 18:01:15 +01:00
lwouis 974b6a9ea2 docs: update sponsor links 2024-12-06 23:01:50 +01:00
semantic-release-bot 71345465cf chore(release): 7.8.0 [skip ci]
# [7.8.0](https://github.com/lwouis/alt-tab-macos/compare/v7.7.0...v7.8.0) (2024-12-06)

### Features

* bring back the cursor follow focus feature ([#3882](https://github.com/lwouis/alt-tab-macos/issues/3882)) ([73382db](https://github.com/lwouis/alt-tab-macos/commit/73382db))
* improve display of very small windows (closes [#3902](https://github.com/lwouis/alt-tab-macos/issues/3902)) ([9bafd03](https://github.com/lwouis/alt-tab-macos/commit/9bafd03))
* improve irish localization ([89c02c9](https://github.com/lwouis/alt-tab-macos/commit/89c02c9))
* switcher will show faster (closes [#3845](https://github.com/lwouis/alt-tab-macos/issues/3845)) ([b694c83](https://github.com/lwouis/alt-tab-macos/commit/b694c83))
2024-12-06 16:44:39 +00:00
lwouis 89c02c9a96 feat: improve irish localization 2024-12-06 17:39:20 +01:00
allsochen 73382db4a2 feat: bring back the cursor follow focus feature (#3882) 2024-12-06 17:39:20 +01:00
lwouis 9bafd037c3 feat: improve display of very small windows (closes #3902) 2024-12-06 17:28:25 +01:00
lwouis 57e3a369ae refactor: fix warnings and generally improve things 2024-12-06 17:28:25 +01:00
lwouis f0550d75b8 refactor: move logger class 2024-12-06 17:28:24 +01:00
lwouis b694c837b4 feat: switcher will show faster (closes #3845) 2024-12-05 10:45:31 +01:00
semantic-release-bot a083b06de0 chore(release): 7.7.0 [skip ci]
# [7.7.0](https://github.com/lwouis/alt-tab-macos/compare/v7.6.0...v7.7.0) (2024-12-03)

### Bug Fixes

* [after release: do nothing] was broken in v7.6.0 (closes [#3929](https://github.com/lwouis/alt-tab-macos/issues/3929)) ([83b5319](https://github.com/lwouis/alt-tab-macos/commit/83b5319))

### Features

* improve chinese localization ([17e9599](https://github.com/lwouis/alt-tab-macos/commit/17e9599))
* improve tooltips in preferences ([f97e9f9](https://github.com/lwouis/alt-tab-macos/commit/f97e9f9))
2024-12-03 23:27:02 +00:00
lwouis 17e9599976 feat: improve chinese localization 2024-12-04 00:20:42 +01:00
lwouis 487b96d7d3 refactor: prepare future off-main-thread keyboard handling 2024-12-04 00:19:55 +01:00
lwouis 83b5319433 fix: [after release: do nothing] was broken in v7.6.0 (closes #3929) 2024-12-04 00:19:53 +01:00
lwouis db305db392 refactor: avoid issues if we introduce more hold-shortcuts later 2024-12-03 22:00:39 +01:00
lwouis dfd5f9dd94 refactor: handle case where holdShortcutX doesn't exist 2024-12-03 21:58:43 +01:00
lwouis 8748d8b4e5 refactor: remove elasticity from vertical scrolling 2024-12-03 21:58:43 +01:00
lwouis f97e9f9333 feat: improve tooltips in preferences 2024-12-03 21:46:26 +01:00
lwouis 3c58c6bf5f refactor: performance improvements 2024-12-02 19:58:51 +01:00
lwouis a4899658df refactor: reuse logic in main.swift 2024-12-02 19:34:38 +01:00
lwouis 1053740723 ci: change steps order to fail faster on common cases 2024-12-01 22:32:18 +01:00
semantic-release-bot b0adfb97ad chore(release): 7.6.0 [skip ci]
# [7.6.0](https://github.com/lwouis/alt-tab-macos/compare/v7.5.0...v7.6.0) (2024-12-01)

### Features

* better display on some external monitors (closes [#3866](https://github.com/lwouis/alt-tab-macos/issues/3866)) ([165a669](https://github.com/lwouis/alt-tab-macos/commit/165a669))
* improve keyboard handling when macos is overwhelmed ([4a9b543](https://github.com/lwouis/alt-tab-macos/commit/4a9b543))
* improve korean localization ([22aafce](https://github.com/lwouis/alt-tab-macos/commit/22aafce))
2024-12-01 21:24:33 +00:00
lwouis d0d2314e9a ci: use universal binary for xcbeautify 2024-12-01 22:14:59 +01:00
lwouis 22aafce24e feat: improve korean localization 2024-12-01 22:14:59 +01:00
lwouis c02dfafa2a test: add local shortcut test 2024-12-01 22:14:59 +01:00
lwouis f8b22dc1ed refactor: simplify logger 2024-12-01 22:14:58 +01:00
lwouis 4a9b543a3a feat: improve keyboard handling when macos is overwhelmed 2024-12-01 22:14:58 +01:00
lwouis 1332a73189 ci: add xcbeautify to improve xcodebuild logs 2024-12-01 22:14:58 +01:00
lwouis 165a6695b9 feat: better display on some external monitors (closes #3866) 2024-12-01 22:14:58 +01:00
lwouis b816745830 test: add unit tests to the project with xctest 2024-12-01 22:14:58 +01:00
semantic-release-bot 0b198b4031 chore(release): 7.5.0 [skip ci]
# [7.5.0](https://github.com/lwouis/alt-tab-macos/compare/v7.4.0...v7.5.0) (2024-11-27)

### Features

* improve da, hu, tr localizations ([ffdab44](https://github.com/lwouis/alt-tab-macos/commit/ffdab44))
* in-app feedback form now requires a title ([05851fb](https://github.com/lwouis/alt-tab-macos/commit/05851fb))
* update switcher max-width to 90% of screen, like windows 11 ([a94eeb0](https://github.com/lwouis/alt-tab-macos/commit/a94eeb0))
2024-11-27 09:55:44 +00:00
lwouis ffdab44710 feat: improve da, hu, tr localizations 2024-11-27 10:42:11 +01:00
lwouis 3e423a14f4 refactor: observe mouse events from main thread: simpler/faster 2024-11-27 09:56:52 +01:00
lwouis f56c65df79 refactor: commit experimentations folder for posterity 2024-11-27 09:56:52 +01:00
lwouis c8eb0914b3 refactor: faster path when no apparition delay 2024-11-27 09:56:52 +01:00
lwouis 05851fb728 feat: in-app feedback form now requires a title 2024-11-23 09:01:05 +01:00
lwouis 5c12810d23 refactor: use .commonModes to avoid skipping events during scrolling 2024-11-23 09:01:05 +01:00
lwouis e11392d0af refactor: improve background threads init 2024-11-23 09:01:05 +01:00
lwouis e3f2da13f5 refactor: maintain mission-control state on the background thread 2024-11-19 20:40:45 +01:00
lwouis a94eeb023d feat: update switcher max-width to 90% of screen, like windows 11 2024-11-19 18:11:01 +01:00
lwouis 82162b167b docs: better document apple undocumented key-repeat system 2024-11-19 10:52:23 +01:00
semantic-release-bot 7100d251ec chore(release): 7.4.0 [skip ci]
# [7.4.0](https://github.com/lwouis/alt-tab-macos/compare/v7.3.0...v7.4.0) (2024-11-16)

### Bug Fixes

* permission callout could show even with permission granted ([9585c92](https://github.com/lwouis/alt-tab-macos/commit/9585c92)), closes [#3801](https://github.com/lwouis/alt-tab-macos/issues/3801)

### Features

* better switcher max-width at various monitor sizes ([49178b5](https://github.com/lwouis/alt-tab-macos/commit/49178b5))
* improve ar, de, el, hu, it, ko, pt localizations ([c4f98a1](https://github.com/lwouis/alt-tab-macos/commit/c4f98a1))
2024-11-16 15:47:38 +00:00
lwouis c4f98a10dc feat: improve ar, de, el, hu, it, ko, pt localizations 2024-11-16 16:42:41 +01:00
lwouis 9585c92629 fix: permission callout could show even with permission granted
closes #3801
2024-11-14 14:07:11 +01:00
lwouis 2594427e75 chore: clean up, typo 2024-11-11 21:16:16 +01:00
lwouis 49178b50b0 feat: better switcher max-width at various monitor sizes 2024-11-11 15:51:22 +01:00
semantic-release-bot 353a7c9c2b chore(release): 7.3.0 [skip ci]
# [7.3.0](https://github.com/lwouis/alt-tab-macos/compare/v7.2.0...v7.3.0) (2024-11-10)

### Bug Fixes

* better handle screen or space changes (closes [#1254](https://github.com/lwouis/alt-tab-macos/issues/1254), closes [#2983](https://github.com/lwouis/alt-tab-macos/issues/2983)) ([3c4aaf5](https://github.com/lwouis/alt-tab-macos/commit/3c4aaf5))
* potential issues with key repeats due to concurrency ([4cfe16a](https://github.com/lwouis/alt-tab-macos/commit/4cfe16a))
* switcher would not close, or cycle on its own (closes [#3117](https://github.com/lwouis/alt-tab-macos/issues/3117)) ([d430f83](https://github.com/lwouis/alt-tab-macos/commit/d430f83))
* works without screen-recording permissions (closes [#3819](https://github.com/lwouis/alt-tab-macos/issues/3819)) ([f7de2bb](https://github.com/lwouis/alt-tab-macos/commit/f7de2bb))

### Features

* can pass the --logs= flags at launch to show logs ([81eb07e](https://github.com/lwouis/alt-tab-macos/commit/81eb07e))
* improve el, fi, hi, it, pl, pt localizations ([a9614c1](https://github.com/lwouis/alt-tab-macos/commit/a9614c1))
2024-11-10 18:02:34 +00:00
lwouis a9614c15aa feat: improve el, fi, hi, it, pl, pt localizations 2024-11-10 18:57:08 +01:00
lwouis 690e2f6e85 chore: review all concurrency in the app 2024-11-10 18:57:08 +01:00
lwouis 16b9122f9e chore: tune timer tolerance for battery vs accuracy 2024-11-10 18:57:08 +01:00
lwouis 4cfe16a708 fix: potential issues with key repeats due to concurrency 2024-11-10 18:57:08 +01:00
lwouis 3c4aaf5bba fix: better handle screen or space changes (closes #1254, closes #2983) 2024-11-10 18:57:07 +01:00
lwouis bc2fe382a9 refactor: spaces refresh logic, logs, observers 2024-11-10 13:10:20 +01:00
lwouis a0fe1080f3 refactor: improve readability 2024-11-10 13:10:20 +01:00
lwouis 81eb07ee98 feat: can pass the --logs= flags at launch to show logs 2024-11-10 13:10:20 +01:00
lwouis f7de2bb6d9 fix: works without screen-recording permissions (closes #3819) 2024-11-10 13:10:20 +01:00
lwouis d430f835a4 fix: switcher would not close, or cycle on its own (closes #3117) 2024-11-08 09:25:19 +01:00
semantic-release-bot c0f0ce7df2 chore(release): 7.2.0 [skip ci]
# [7.2.0](https://github.com/lwouis/alt-tab-macos/compare/v7.1.1...v7.2.0) (2024-11-04)

### Features

* hide space labels when showing same-space windows ([88c1595](https://github.com/lwouis/alt-tab-macos/commit/88c1595)), closes [#3766](https://github.com/lwouis/alt-tab-macos/issues/3766)
* improve switcher layout and presentation ([545b5db](https://github.com/lwouis/alt-tab-macos/commit/545b5db))
2024-11-04 22:54:50 +00:00
lwouis d934fb41ab ci: fix npm cache step 2024-11-04 23:50:08 +01:00
lwouis d0739ce0f1 ci: update ci to macos 13 and xcode 14.2 2024-11-04 23:47:09 +01:00
allsochen 545b5db143 feat: improve switcher layout and presentation 2024-11-04 18:12:18 +01:00
lwouis 649a5cb86a chore: use preferred screen for preview instead of screen 0 2024-11-04 17:41:04 +01:00
lwouis 88c1595deb feat: hide space labels when showing same-space windows
follow-up to #3766
2024-11-04 17:38:12 +01:00
lwouis a8498bb7f6 ci: simplify ci and remove travis 2024-11-03 13:05:54 +01:00
lwouis d5fa496a20 ci: add npm cache on github actions 2024-11-03 13:05:54 +01:00
semantic-release-bot 9f86e8355d chore(release): 7.1.1 [skip ci]
## [7.1.1](https://github.com/lwouis/alt-tab-macos/compare/v7.1.0...v7.1.1) (2024-11-03)

### Bug Fixes

* blacklist could prevent app launch in v7.1.0 ([8f4784f](https://github.com/lwouis/alt-tab-macos/commit/8f4784f))
2024-11-03 00:28:24 +00:00
lwouis 8f4784f86d fix: blacklist could prevent app launch in v7.1.0 2024-11-03 01:23:48 +01:00
lwouis 696a489f43 docs: improve website accessibility and seo 2024-11-02 23:40:43 +01:00
lwouis 67d436cfc5 ci: brew autobumps the cask every 3h; remove from ci 2024-11-02 23:15:54 +01:00
lwouis a966de9f50 ci: replace cask-repair with bump-cask-pr 2024-11-02 23:11:25 +01:00
lwouis 9b7e8250bc ci: add env var for cask-repair 2024-11-02 22:47:58 +01:00
lwouis 7723c0149d docs: fix netlify deploy by reverting to previous lock file 2024-11-02 22:41:14 +01:00
semantic-release-bot 38c363162b chore(release): 7.1.0 [skip ci]
# [7.1.0](https://github.com/lwouis/alt-tab-macos/compare/v7.0.2...v7.1.0) (2024-11-02)

### Bug Fixes

* fixed the rounded corners when the mouse moves over the table ([dd379c4](https://github.com/lwouis/alt-tab-macos/commit/dd379c4))

### Features

* add irish localization ([19f59b2](https://github.com/lwouis/alt-tab-macos/commit/19f59b2))
* add language preference ([f33418e](https://github.com/lwouis/alt-tab-macos/commit/f33418e))
* allow to run the app without screen-recording permissions ([129d061](https://github.com/lwouis/alt-tab-macos/commit/129d061)), closes [#1082](https://github.com/lwouis/alt-tab-macos/issues/1082)
* hide space labels when showing same-space windows (closes [#3766](https://github.com/lwouis/alt-tab-macos/issues/3766)) ([ad64ced](https://github.com/lwouis/alt-tab-macos/commit/ad64ced))
* i18n ([d77fa67](https://github.com/lwouis/alt-tab-macos/commit/d77fa67))
* improve appearance at the different sizes ([2c857a6](https://github.com/lwouis/alt-tab-macos/commit/2c857a6))
* improve display of wide/tall thumbnails (closes [#3791](https://github.com/lwouis/alt-tab-macos/issues/3791)) ([45bbc93](https://github.com/lwouis/alt-tab-macos/commit/45bbc93))
* improve localizations ([9d1349b](https://github.com/lwouis/alt-tab-macos/commit/9d1349b))
2024-11-02 21:32:28 +00:00
lwouis 4a46c46253 ci: switch to github actions (#1241) 2024-11-02 22:27:34 +01:00
lwouis 9d1349b5aa feat: improve localizations 2024-11-02 21:45:13 +01:00
lwouis 2c857a6eb1 feat: improve appearance at the different sizes 2024-11-02 00:05:27 +01:00
lwouis ad64ced2df feat: hide space labels when showing same-space windows (closes #3766) 2024-11-02 00:05:27 +01:00
lwouis 81fb54cff5 chore: preload fewer recycled views ahead of time 2024-11-02 00:05:27 +01:00
lwouis 45bbc93bee feat: improve display of wide/tall thumbnails (closes #3791) 2024-11-02 00:05:27 +01:00
lwouis f9542f9214 chore: add jekyll vendor folder to gitignore 2024-10-31 22:57:53 +01:00
lwouis 60052b8ab7 chore: remove metal api checker from xcode runs 2024-10-31 22:57:53 +01:00
lwouis 7b9a6b4e9c docs: update website contents 2024-10-30 22:04:10 +01:00
lwouis 09ca2a6740 chore: improve language preference support 2024-10-29 14:54:51 +01:00
lwouis 20cd27e68d chore: better read preferences + remove unused ones 2024-10-28 21:29:36 +01:00
lwouis 129d061434 feat: allow to run the app without screen-recording permissions
closes #1082
2024-10-17 22:28:34 +02:00
lwouis 19f59b207f feat: add irish localization 2024-10-15 23:28:38 +02:00
lwouis 528028d41b ci: add poeditor upload script 2024-10-15 23:18:28 +02:00
allsochen d77fa67729 feat: i18n 2024-10-15 10:52:08 +02:00
allsochen f33418ec35 feat: add language preference 2024-10-15 10:52:07 +02:00
allsochen dd379c41c9 fix: fixed the rounded corners when the mouse moves over the table 2024-10-12 18:38:18 +02:00
semantic-release-bot 609a25119d chore(release): 7.0.2 [skip ci]
## [7.0.2](https://github.com/lwouis/alt-tab-macos/compare/v7.0.1...v7.0.2) (2024-10-12)

### Bug Fixes

* avoid crashing in some cases ([d46d903](https://github.com/lwouis/alt-tab-macos/commit/d46d903))
* block titles in preferences in rtl languages ([ea5574b](https://github.com/lwouis/alt-tab-macos/commit/ea5574b))
* preferences panel icons wouldnt show on old macos versions ([9258acf](https://github.com/lwouis/alt-tab-macos/commit/9258acf))
* show titles > application name, in thumbnails style (closes [#3667](https://github.com/lwouis/alt-tab-macos/issues/3667)) ([b4e97ea](https://github.com/lwouis/alt-tab-macos/commit/b4e97ea))
2024-10-12 11:10:07 +00:00
lwouis 9258acf765 fix: preferences panel icons wouldnt show on old macos versions 2024-10-12 12:56:12 +02:00
allsochen d46d90395c fix: avoid crashing in some cases 2024-10-12 12:43:56 +02:00
allsochen b4e97ead04 fix: show titles > application name, in thumbnails style (closes #3667) 2024-10-12 12:43:56 +02:00
ShlomoCode ea5574bfa5 fix: block titles in preferences in rtl languages 2024-10-12 12:43:55 +02:00
semantic-release-bot 5b6e8de9a1 chore(release): 7.0.1 [skip ci]
## [7.0.1](https://github.com/lwouis/alt-tab-macos/compare/v7.0.0...v7.0.1) (2024-10-11)

### Bug Fixes

* avoid crashing in rare cases ([9980ec6](https://github.com/lwouis/alt-tab-macos/commit/9980ec6))
2024-10-11 10:14:13 +00:00
lwouis 9980ec62fd fix: avoid crashing in rare cases 2024-10-11 12:00:12 +02:00
semantic-release-bot 8abb9b4358 chore(release): 7.0.0 [skip ci]
# [7.0.0](https://github.com/lwouis/alt-tab-macos/compare/v6.73.0...v7.0.0) (2024-10-09)

### Features

* major rehaul of the preferences! ([6d97cbd](https://github.com/lwouis/alt-tab-macos/commit/6d97cbd)), closes [#351](https://github.com/lwouis/alt-tab-macos/issues/351)

### BREAKING CHANGES

* The old preferences panel has been replaced with a brand new one

Preferences are now much simpler, full of visual illustrations, and should provide a much better experience. Pick between 3 styles (thumbnails, app-icons, titles), sizes, dark/light themes, high visibility options, and more!
2024-10-10 11:20:02 +02:00
lwouis 40c1c0ec02 chore: fix swiftc errors on xcode 13.6 2024-10-10 11:20:02 +02:00
lwouis f2bc95ffcc ci: print xcode version and swift version 2024-10-10 11:20:02 +02:00
lwouis 4b1fbb1243 ci: improve logs 2024-10-10 11:20:01 +02:00
lwouis e7c2a8b880 ci: temporarily disable l10n check 2024-10-10 11:20:01 +02:00
lwouis dbbe9e8b0e ci: do not install swiftformat on npm install 2024-10-10 11:20:01 +02:00
lwouis b26a12074f ci: upgrade node/npm version 2024-10-10 11:20:01 +02:00
allsochen 79f99bd4f1 feat: major rehaul of the preferences!
closes #351

BREAKING CHANGE: The old preferences panel has been replaced with a brand new one

Preferences are now much simpler, full of visual illustrations, and should provide a much better experience. Pick between 3 styles (thumbnails, app-icons, titles), sizes, dark/light themes, high visibility options, and more!
2024-10-10 11:19:39 +02:00
semantic-release-bot 38cfe3a23b chore(release): 6.73.0 [skip ci]
# [6.73.0](https://github.com/lwouis/alt-tab-macos/compare/v6.72.0...v6.73.0) (2024-10-08)

### Bug Fixes

* closing alttab windows gives focus to previous app (closes [#3577](https://github.com/lwouis/alt-tab-macos/issues/3577)) ([0e6f200](https://github.com/lwouis/alt-tab-macos/commit/0e6f200))
* detect passwords app (closes [#3545](https://github.com/lwouis/alt-tab-macos/issues/3545)) ([d0cd206](https://github.com/lwouis/alt-tab-macos/commit/d0cd206))
* dragging files onto windowless apps was inconsistent ([0a9fe9b](https://github.com/lwouis/alt-tab-macos/commit/0a9fe9b))
* finder would sometimes not be listed (closes [#3350](https://github.com/lwouis/alt-tab-macos/issues/3350)) ([eba5e42](https://github.com/lwouis/alt-tab-macos/commit/eba5e42))
* focusing an app could open another version of it ([9d5f11a](https://github.com/lwouis/alt-tab-macos/commit/9d5f11a))
* preview window could remain after focusing an app (closes [#3505](https://github.com/lwouis/alt-tab-macos/issues/3505)) ([e890a60](https://github.com/lwouis/alt-tab-macos/commit/e890a60))

### Features

* add kannada and malayalam and localizations ([5e27701](https://github.com/lwouis/alt-tab-macos/commit/5e27701))
2024-10-08 20:34:17 +00:00
lwouis 5e27701228 feat: add kannada and malayalam and localizations 2024-10-08 22:19:04 +02:00
lwouis 0a9fe9bb89 fix: dragging files onto windowless apps was inconsistent 2024-10-08 21:36:43 +02:00
decodism d0cd206f51 fix: detect passwords app (closes #3545) 2024-09-18 22:00:08 +02:00
lwouis 9d5f11aed5 fix: focusing an app could open another version of it 2024-09-11 09:22:13 +02:00
lwouis eba5e422bf fix: finder would sometimes not be listed (closes #3350) 2024-08-31 18:01:32 +02:00
lwouis 0e6f200efe fix: closing alttab windows gives focus to previous app (closes #3577) 2024-08-30 22:22:13 +02:00
lwouis e890a603c2 fix: preview window could remain after focusing an app (closes #3505) 2024-07-30 12:00:44 +02:00
semantic-release-bot 97951e7e8e chore(release): 6.72.0 [skip ci]
# [6.72.0](https://github.com/lwouis/alt-tab-macos/compare/v6.71.0...v6.72.0) (2024-07-14)

### Bug Fixes

* preferences window quit button supports right-to-left languages ([d3dfd54](https://github.com/lwouis/alt-tab-macos/commit/d3dfd54)), closes [#3487](https://github.com/lwouis/alt-tab-macos/issues/3487)

### Features

* don't show caps-lock indicator as a window (closes [#3171](https://github.com/lwouis/alt-tab-macos/issues/3171)) ([2e15732](https://github.com/lwouis/alt-tab-macos/commit/2e15732))
* improve da/he localizations ([3d98b64](https://github.com/lwouis/alt-tab-macos/commit/3d98b64))
2024-07-14 17:02:49 +00:00
lwouis 3d98b64a42 feat: improve da/he localizations 2024-07-14 18:48:11 +02:00
ShlomoCode d3dfd54f54 fix: preferences window quit button supports right-to-left languages
closes #3487
2024-07-14 18:15:45 +02:00
lwouis 2e15732f64 feat: don't show caps-lock indicator as a window (closes #3171)
this is a not a fix: it's a macos bug; we providing a workaround
2024-07-14 16:14:13 +02:00
lwouis 45f5c5368a ci: ensure website download link is always up-to-date 2024-07-08 17:05:53 +02:00
semantic-release-bot 012e3b5f3c chore(release): 6.71.0 [skip ci]
# [6.71.0](https://github.com/lwouis/alt-tab-macos/compare/v6.70.1...v6.71.0) (2024-07-06)

### Bug Fixes

* restore default cmd+tab shortcut when alt-tab crashes ([2c47b4e](https://github.com/lwouis/alt-tab-macos/commit/2c47b4e))
* showing permissions window would crash on macos < 10.15 ([bb5215c](https://github.com/lwouis/alt-tab-macos/commit/bb5215c)), closes [#3437](https://github.com/lwouis/alt-tab-macos/issues/3437)
* traffic light icons could appear half-transparent (closes [#2892](https://github.com/lwouis/alt-tab-macos/issues/2892)) ([1eef1e0](https://github.com/lwouis/alt-tab-macos/commit/1eef1e0))

### Features

* improve fr/he/it/ja/pt/sv localizations ([35521a5](https://github.com/lwouis/alt-tab-macos/commit/35521a5))
* show de-fullscreen button on fullscreen windows ([ad1e8d0](https://github.com/lwouis/alt-tab-macos/commit/ad1e8d0))
2024-07-06 10:30:19 +00:00
lwouis 35521a5214 feat: improve fr/he/it/ja/pt/sv localizations 2024-07-06 12:15:39 +02:00
allsochen ad1e8d03e4 feat: show de-fullscreen button on fullscreen windows 2024-07-06 12:15:37 +02:00
lwouis 1eef1e083d fix: traffic light icons could appear half-transparent (closes #2892) 2024-06-26 19:25:47 +02:00
lwouis bb5215c306 fix: showing permissions window would crash on macos < 10.15
closes #3437
2024-06-21 11:52:49 +02:00
lwouis 2c47b4e585 fix: restore default cmd+tab shortcut when alt-tab crashes 2024-06-21 11:52:36 +02:00
semantic-release-bot 4371eb7c39 chore(release): 6.70.1 [skip ci]
## [6.70.1](https://github.com/lwouis/alt-tab-macos/compare/v6.70.0...v6.70.1) (2024-06-01)

### Bug Fixes

* prevent crash introduced in v6.70.0 (closes [#3392](https://github.com/lwouis/alt-tab-macos/issues/3392)) ([e16a3d4](https://github.com/lwouis/alt-tab-macos/commit/e16a3d4))
2024-06-01 11:38:26 +00:00
lwouis e16a3d46b3 fix: prevent crash introduced in v6.70.0 (closes #3392) 2024-06-01 13:20:36 +02:00
semantic-release-bot 1a3996e73b chore(release): 6.70.0 [skip ci]
# [6.70.0](https://github.com/lwouis/alt-tab-macos/compare/v6.69.0...v6.70.0) (2024-05-29)

### Bug Fixes

* detect safari fullscreen windows better (closes [#3384](https://github.com/lwouis/alt-tab-macos/issues/3384)) ([c3006c6](https://github.com/lwouis/alt-tab-macos/commit/c3006c6))

### Features

* add utm-app to default blacklist ([523bcbb](https://github.com/lwouis/alt-tab-macos/commit/523bcbb))
2024-05-29 22:15:51 +00:00
lwouis c3006c69a6 fix: detect safari fullscreen windows better (closes #3384) 2024-05-29 23:49:23 +02:00
lwouis 523bcbb6e3 feat: add utm-app to default blacklist 2024-05-26 00:17:04 +02:00
semantic-release-bot 127ad155ba chore(release): 6.69.0 [skip ci]
# [6.69.0](https://github.com/lwouis/alt-tab-macos/compare/v6.68.0...v6.69.0) (2024-05-12)

### Bug Fixes

* only show standard windows of preview.app (closes [#3351](https://github.com/lwouis/alt-tab-macos/issues/3351)) ([6231977](https://github.com/lwouis/alt-tab-macos/commit/6231977))

### Features

* update fi, ja, ko, pt-br, th localizations ([14d287a](https://github.com/lwouis/alt-tab-macos/commit/14d287a))
2024-05-12 20:18:54 +00:00
lwouis 14d287afe3 feat: update fi, ja, ko, pt-br, th localizations 2024-05-12 22:04:07 +02:00
lwouis 6231977e70 fix: only show standard windows of preview.app (closes #3351) 2024-05-12 22:03:12 +02:00
semantic-release-bot 758b3e804e chore(release): 6.68.0 [skip ci]
# [6.68.0](https://github.com/lwouis/alt-tab-macos/compare/v6.67.0...v6.68.0) (2024-04-03)

### Bug Fixes

* preview.app window may not show when opening many docs ([31b5a3d](https://github.com/lwouis/alt-tab-macos/commit/31b5a3d)), closes [#3276](https://github.com/lwouis/alt-tab-macos/issues/3276)
* preview.app windows would sometimes not show (closes [#3275](https://github.com/lwouis/alt-tab-macos/issues/3275)) ([785cf9c](https://github.com/lwouis/alt-tab-macos/commit/785cf9c))

### Features

* improve ar/nb/nn/pl/tr/uk localizations ([67a6d81](https://github.com/lwouis/alt-tab-macos/commit/67a6d81))
* new thai and norwegian localizations (closes [#3260](https://github.com/lwouis/alt-tab-macos/issues/3260)) ([d9aa319](https://github.com/lwouis/alt-tab-macos/commit/d9aa319))
2024-04-03 19:30:58 +00:00
lwouis 67a6d8194d feat: improve ar/nb/nn/pl/tr/uk localizations 2024-04-03 21:16:30 +02:00
lwouis 31b5a3df77 fix: preview.app window may not show when opening many docs
(closes #3276)
2024-04-03 20:17:05 +02:00
lwouis 785cf9c73a fix: preview.app windows would sometimes not show (closes #3275) 2024-04-03 20:01:32 +02:00
lwouis d9aa319e2c feat: new thai and norwegian localizations (closes #3260) 2024-03-25 20:25:10 +01:00
Dmytro Pashchenko 141e7233ff docs: fix typo on ukrainian/russian languages on the website 2024-03-19 16:43:47 +01:00
semantic-release-bot 9ff25e7c3a chore(release): 6.67.0 [skip ci]
# [6.67.0](https://github.com/lwouis/alt-tab-macos/compare/v6.66.0...v6.67.0) (2024-03-15)

### Features

* add icelandic localization ([7df1432](https://github.com/lwouis/alt-tab-macos/commit/7df1432))
* improve ru/cn localizations ([c9fe54e](https://github.com/lwouis/alt-tab-macos/commit/c9fe54e))
* support autocad non-native windows ([#3219](https://github.com/lwouis/alt-tab-macos/issues/3219)) ([bbaef6c](https://github.com/lwouis/alt-tab-macos/commit/bbaef6c))
2024-03-15 17:33:32 +00:00
lwouis c9fe54ed29 feat: improve ru/cn localizations 2024-03-15 18:18:03 +01:00
lwouis bbaef6cf8e feat: support autocad non-native windows (#3219) 2024-03-15 18:18:01 +01:00
lwouis 7df1432744 feat: add icelandic localization 2024-03-15 18:13:45 +01:00
semantic-release-bot 6442d85c9f chore(release): 6.66.0 [skip ci]
# [6.66.0](https://github.com/lwouis/alt-tab-macos/compare/v6.65.0...v6.66.0) (2024-03-03)

### Bug Fixes

* alttab would crash after menubar icon was actioned with voiceover ([f7fdf3f](https://github.com/lwouis/alt-tab-macos/commit/f7fdf3f)), closes [#3211](https://github.com/lwouis/alt-tab-macos/issues/3211)

### Features

* improved ca/de/es/ko/nl/sv/vi/zh localizations ([f4ad2ea](https://github.com/lwouis/alt-tab-macos/commit/f4ad2ea))
2024-03-03 12:03:34 +00:00
lwouis f4ad2ea6c8 feat: improved ca/de/es/ko/nl/sv/vi/zh localizations 2024-03-03 12:49:05 +01:00
lwouis f7fdf3f987 fix: alttab would crash after menubar icon was actioned with voiceover
closes #3211
2024-03-03 12:45:07 +01:00
lwouis b8833b74eb refactor: fix inkscape bin path 2024-02-08 17:08:21 +01:00
lwouis bc29d1e86c refactor: apply compiler hints 2024-02-08 17:08:21 +01:00
lwouis 5ea9b8211e docs: improve website performance, and lazy-load images 2024-02-08 17:08:21 +01:00
semantic-release-bot 25f1881f85 chore(release): 6.65.0 [skip ci]
# [6.65.0](https://github.com/lwouis/alt-tab-macos/compare/v6.64.0...v6.65.0) (2024-01-29)

### Features

* update da/de/es/sv localizations ([c88426e](https://github.com/lwouis/alt-tab-macos/commit/c88426e))
* users can check status of required system permissions ([70ee681](https://github.com/lwouis/alt-tab-macos/commit/70ee681))
2024-01-29 17:14:13 +00:00
lwouis d819d8e8a1 ci: make localization process deterministic 2024-01-29 17:58:27 +01:00
lwouis db022a0688 docs: add links to support project 2024-01-29 14:26:43 +01:00
lwouis c88426e0b2 feat: update da/de/es/sv localizations 2024-01-23 23:16:48 +01:00
lwouis 4818345ce2 docs: add patreon to github sponsors 2024-01-23 23:14:06 +01:00
lwouis 70ee681757 feat: users can check status of required system permissions 2023-12-20 22:17:55 +01:00
lwouis 9e03d5f665 docs: add github sponsorship 2023-11-16 00:44:37 +01:00
semantic-release-bot 1561f2631a chore(release): 6.64.0 [skip ci]
# [6.64.0](https://github.com/lwouis/alt-tab-macos/compare/v6.63.0...v6.64.0) (2023-10-24)

### Bug Fixes

* don't absorb key up events after summon (closes [#2914](https://github.com/lwouis/alt-tab-macos/issues/2914)) ([3b0194d](https://github.com/lwouis/alt-tab-macos/commit/3b0194d))
* stop vim keys preference disabling on launch (closes [#2919](https://github.com/lwouis/alt-tab-macos/issues/2919)) ([53692ff](https://github.com/lwouis/alt-tab-macos/commit/53692ff))

### Features

* improve fr,de localizations ([c4ae549](https://github.com/lwouis/alt-tab-macos/commit/c4ae549))
2023-10-24 21:47:54 +00:00
lwouis c4ae5496e2 feat: improve fr,de localizations 2023-10-24 23:33:25 +02:00
lwouis 53692ffc7c fix: stop vim keys preference disabling on launch (closes #2919) 2023-10-24 23:28:45 +02:00
lwouis 3b0194d886 fix: don't absorb key up events after summon (closes #2914) 2023-10-24 23:28:45 +02:00
semantic-release-bot e75a1ff4fe chore(release): 6.63.0 [skip ci]
# [6.63.0](https://github.com/lwouis/alt-tab-macos/compare/v6.62.0...v6.63.0) (2023-10-20)

### Bug Fixes

* never screenshot windows if thumbnails are hidden ([5e7f44b](https://github.com/lwouis/alt-tab-macos/commit/5e7f44b))

### Features

* improve ca/ko/ku localizations ([865570f](https://github.com/lwouis/alt-tab-macos/commit/865570f))
2023-10-20 20:09:53 +00:00
lwouis 042c8061f6 refactor: clearer color code 2023-10-20 10:27:36 +02:00
lwouis 865570fa94 feat: improve ca/ko/ku localizations 2023-10-20 10:27:36 +02:00
Sean Kelly 5e7f44b5ca fix: never screenshot windows if thumbnails are hidden 2023-10-20 10:07:24 +02:00
semantic-release-bot 821161363e chore(release): 6.62.0 [skip ci]
# [6.62.0](https://github.com/lwouis/alt-tab-macos/compare/v6.61.0...v6.62.0) (2023-10-10)

### Bug Fixes

* better crossover windows detection ([3f64463](https://github.com/lwouis/alt-tab-macos/commit/3f64463))

### Features

* add tamil and croatian localizations ([e542da8](https://github.com/lwouis/alt-tab-macos/commit/e542da8))
* add vim key window navigation (closes [#1229](https://github.com/lwouis/alt-tab-macos/issues/1229)) ([5cf7f99](https://github.com/lwouis/alt-tab-macos/commit/5cf7f99))
* improve bg,es,he,hi,ko,uk,cn localizations ([31fb795](https://github.com/lwouis/alt-tab-macos/commit/31fb795))
2023-10-10 20:47:48 +00:00
lwouis e542da8c74 feat: add tamil and croatian localizations 2023-10-10 22:33:04 +02:00
lwouis 31fb795fd8 feat: improve bg,es,he,hi,ko,uk,cn localizations 2023-10-10 21:53:17 +02:00
Sai Chand 5cf7f99517 feat: add vim key window navigation (closes #1229) 2023-10-10 21:53:16 +02:00
Zachary Wander 3f64463580 fix: better crossover windows detection 2023-09-19 18:36:06 +02:00
semantic-release-bot 1a9f16a25a chore(release): 6.61.0 [skip ci]
# [6.61.0](https://github.com/lwouis/alt-tab-macos/compare/v6.60.0...v6.61.0) (2023-07-12)

### Bug Fixes

* better identify tabs on macos versions older than 13 ([3147a69](https://github.com/lwouis/alt-tab-macos/commit/3147a69)), closes [#2017](https://github.com/lwouis/alt-tab-macos/issues/2017)
* don't show empty color-slurp windows ([01b3a42](https://github.com/lwouis/alt-tab-macos/commit/01b3a42))

### Features

* improve german localization ([1084d87](https://github.com/lwouis/alt-tab-macos/commit/1084d87))
* improve support for crossover windows ([f9f1c19](https://github.com/lwouis/alt-tab-macos/commit/f9f1c19))
* improve support for scrcpy always-on-top windows ([0673381](https://github.com/lwouis/alt-tab-macos/commit/0673381))
* show the ui by right-clicking the menubar icon (closes [#2647](https://github.com/lwouis/alt-tab-macos/issues/2647)) ([63502d5](https://github.com/lwouis/alt-tab-macos/commit/63502d5))
2023-07-12 19:44:40 +00:00
Louis Pontoise 1084d87399 feat: improve german localization 2023-07-12 21:28:40 +02:00
decodism 3147a6989c fix: better identify tabs on macos versions older than 13
closes #2017
2023-07-12 21:25:00 +02:00
Louis Pontoise 63502d5f30 feat: show the ui by right-clicking the menubar icon (closes #2647) 2023-07-12 21:13:12 +02:00
Zachary Wander 06733812e6 feat: improve support for scrcpy always-on-top windows 2023-07-02 20:50:43 +02:00
Zachary Wander f9f1c19b84 feat: improve support for crossover windows 2023-07-02 20:50:43 +02:00
Zachary Wander 01b3a428d9 fix: don't show empty color-slurp windows 2023-06-25 11:37:25 +02:00
Louis Pontoise fd2f14ae2e refactor: simpler conditionals and comparisons 2023-06-25 11:36:57 +02:00
semantic-release-bot bf6c9121f4 chore(release): 6.60.0 [skip ci]
# [6.60.0](https://github.com/lwouis/alt-tab-macos/compare/v6.59.0...v6.60.0) (2023-06-23)

### Bug Fixes

* prevent flickering when switching to a previewed window ([b69f5f4](https://github.com/lwouis/alt-tab-macos/commit/b69f5f4)), closes [#2432](https://github.com/lwouis/alt-tab-macos/issues/2432)

### Features

* improve support for color-slurp windows ([8605b23](https://github.com/lwouis/alt-tab-macos/commit/8605b23))
* user can change window order in preferences (closes [#515](https://github.com/lwouis/alt-tab-macos/issues/515)) ([a67d123](https://github.com/lwouis/alt-tab-macos/commit/a67d123))
2023-06-23 22:03:23 +00:00
Louis Pontoise a67d1231de feat: user can change window order in preferences (closes #515) 2023-06-23 23:30:56 +02:00
Louis Pontoise b69f5f4b5f fix: prevent flickering when switching to a previewed window
(closes #2432)
2023-06-23 23:30:56 +02:00
Louis Pontoise 8605b23135 feat: improve support for color-slurp windows 2023-06-23 23:30:55 +02:00
Louis Pontoise 7d823dd61d ci: replace altool with notarytool
Apple will break altool notarization on Nov 2023, so we are forced to update our ci
2023-06-23 23:30:55 +02:00
semantic-release-bot 8152c3cebf chore(release): 6.59.0 [skip ci]
# [6.59.0](https://github.com/lwouis/alt-tab-macos/compare/v6.58.0...v6.59.0) (2023-06-04)

### Features

* show app icon for app with no open window (closes [#2561](https://github.com/lwouis/alt-tab-macos/issues/2561)) ([44a5630](https://github.com/lwouis/alt-tab-macos/commit/44a5630))
* update vietnamese localization ([7229b8a](https://github.com/lwouis/alt-tab-macos/commit/7229b8a))
2023-06-04 16:07:27 +00:00
Louis Pontoise 7229b8a0a0 feat: update vietnamese localization 2023-06-04 17:52:01 +02:00
Louis Pontoise 44a5630634 feat: show app icon for app with no open window (closes #2561) 2023-06-04 17:41:42 +02:00
semantic-release-bot 19a65050e8 chore(release): 6.58.0 [skip ci]
# [6.58.0](https://github.com/lwouis/alt-tab-macos/compare/v6.57.0...v6.58.0) (2023-05-15)

### Bug Fixes

* editing the blacklist could sometimes bug (closes [#2528](https://github.com/lwouis/alt-tab-macos/issues/2528)) ([f7f4430](https://github.com/lwouis/alt-tab-macos/commit/f7f4430))

### Features

* update dutch localization ([04948a2](https://github.com/lwouis/alt-tab-macos/commit/04948a2))
2023-05-15 20:58:37 +00:00
Louis Pontoise 04948a21f0 feat: update dutch localization 2023-05-15 22:43:40 +02:00
Louis Pontoise f7f4430be9 fix: editing the blacklist could sometimes bug (closes #2528) 2023-05-15 22:41:13 +02:00
Louis Pontoise e77f3ed44a ci: travis is running deploy steps on fail build recently
i've opened a ticket. it's definitely a bug on their side, but this workaround should fix the issue in the here-and-now
2023-05-14 01:21:52 +02:00
semantic-release-bot 180ba935b1 chore(release): 6.57.0 [skip ci]
# [6.57.0](https://github.com/lwouis/alt-tab-macos/compare/v6.56.0...v6.57.0) (2023-05-09)

### Bug Fixes

* drag-and-drop from a folder on the dock (closes [#706](https://github.com/lwouis/alt-tab-macos/issues/706)) ([ee6785f](https://github.com/lwouis/alt-tab-macos/commit/ee6785f))
* preview window wouldn't update in some cases ([537ba26](https://github.com/lwouis/alt-tab-macos/commit/537ba26))

### Features

* add shortcut to toggle fullscreen selected window (closes [#2521](https://github.com/lwouis/alt-tab-macos/issues/2521)) ([7327917](https://github.com/lwouis/alt-tab-macos/commit/7327917))
* add uzbek localization ([0e106e2](https://github.com/lwouis/alt-tab-macos/commit/0e106e2))
2023-05-09 21:19:32 +00:00
Louis Pontoise 0e106e263b feat: add uzbek localization 2023-05-09 22:59:56 +02:00
Louis Pontoise 7327917a81 feat: add shortcut to toggle fullscreen selected window (closes #2521) 2023-05-09 18:28:35 +02:00
Louis Pontoise c08dcd9fb5 docs: update landing website material 2023-05-02 11:14:13 +02:00
Louis Pontoise ee6785f6ab fix: drag-and-drop from a folder on the dock (closes #706) 2023-03-22 21:39:53 +01:00
decodism 537ba26645 fix: preview window wouldn't update in some cases 2023-03-17 17:25:16 +01:00
semantic-release-bot e604ee2440 chore(release): 6.56.0 [skip ci]
# [6.56.0](https://github.com/lwouis/alt-tab-macos/compare/v6.55.0...v6.56.0) (2023-03-16)

### Bug Fixes

* correctly show when an app is no longer assigned to all desktops ([10bbaa9](https://github.com/lwouis/alt-tab-macos/commit/10bbaa9)), closes [#2372](https://github.com/lwouis/alt-tab-macos/issues/2372)

### Features

* add option to preview selected window (closes [#967](https://github.com/lwouis/alt-tab-macos/issues/967)) ([6534a2d](https://github.com/lwouis/alt-tab-macos/commit/6534a2d))
2023-03-16 10:27:22 +00:00
decodism 6534a2d62e feat: add option to preview selected window (closes #967) 2023-03-16 11:13:09 +01:00
Louis Pontoise b5c3bedd14 docs: optimize landing website images, fix typos, credit appcenter pod 2023-03-02 11:16:54 +01:00
Louis Pontoise 10bbaa9217 fix: correctly show when an app is no longer assigned to all desktops
closes #2372
2023-02-27 15:21:17 +01:00
semantic-release-bot 455e16a88f chore(release): 6.55.0 [skip ci]
# [6.55.0](https://github.com/lwouis/alt-tab-macos/compare/v6.54.0...v6.55.0) (2023-02-23)

### Bug Fixes

* use plain number formatter for initial slider label ([7cab722](https://github.com/lwouis/alt-tab-macos/commit/7cab722))

### Features

* allow batch removal from the blacklist ([f53c070](https://github.com/lwouis/alt-tab-macos/commit/f53c070))
* allow to switch shortcuts while the ui is already open ([b99c988](https://github.com/lwouis/alt-tab-macos/commit/b99c988))
* improved german localization ([5d27a19](https://github.com/lwouis/alt-tab-macos/commit/5d27a19))
* show dock badges when they don't show a number (closes [#2356](https://github.com/lwouis/alt-tab-macos/issues/2356)) ([84752e0](https://github.com/lwouis/alt-tab-macos/commit/84752e0))
2023-02-23 18:39:26 +00:00
Louis Pontoise 5d27a19b38 feat: improved german localization 2023-02-23 19:21:31 +01:00
decodism 7cab722df3 fix: use plain number formatter for initial slider label 2023-02-23 19:11:55 +01:00
decodism b99c988970 feat: allow to switch shortcuts while the ui is already open 2023-02-22 19:43:53 +01:00
decodism f53c070ca1 feat: allow batch removal from the blacklist 2023-02-22 19:43:53 +01:00
Louis Pontoise 84752e0fef feat: show dock badges when they don't show a number (closes #2356) 2023-02-22 19:19:48 +01:00
semantic-release-bot 0d4e0f1dab chore(release): 6.54.0 [skip ci]
# [6.54.0](https://github.com/lwouis/alt-tab-macos/compare/v6.53.1...v6.54.0) (2023-02-20)

### Features

* improve selection background/border color contrast ([cea0cff](https://github.com/lwouis/alt-tab-macos/commit/cea0cff)), closes [#2352](https://github.com/lwouis/alt-tab-macos/issues/2352)
2023-02-20 18:21:02 +00:00
Louis Pontoise cea0cff2a7 feat: improve selection background/border color contrast
closes #2352
2023-02-20 19:01:17 +01:00
semantic-release-bot a60f1e13db chore(release): 6.53.1 [skip ci]
## [6.53.1](https://github.com/lwouis/alt-tab-macos/compare/v6.53.0...v6.53.1) (2023-02-12)

### Bug Fixes

* bring back mouse hover selection (closes [#2317](https://github.com/lwouis/alt-tab-macos/issues/2317)) ([abe2e0b](https://github.com/lwouis/alt-tab-macos/commit/abe2e0b))
2023-02-12 18:26:05 +00:00
decodism abe2e0b73b fix: bring back mouse hover selection (closes #2317) 2023-02-12 19:07:45 +01:00
semantic-release-bot f9bb33c49b chore(release): 6.53.0 [skip ci]
# [6.53.0](https://github.com/lwouis/alt-tab-macos/compare/v6.52.1...v6.53.0) (2023-02-09)

### Bug Fixes

* don't focus window when dropping a file on it ([c386a0c](https://github.com/lwouis/alt-tab-macos/commit/c386a0c))

### Features

* allow status item removal by dragging ([216c5d8](https://github.com/lwouis/alt-tab-macos/commit/216c5d8))
* improve localizations ([7a30b18](https://github.com/lwouis/alt-tab-macos/commit/7a30b18))
* separate mouse hover from keyboard selection ([3fb9a19](https://github.com/lwouis/alt-tab-macos/commit/3fb9a19)), closes [#2078](https://github.com/lwouis/alt-tab-macos/issues/2078) [#1617](https://github.com/lwouis/alt-tab-macos/issues/1617)
2023-02-09 20:59:15 +00:00
Louis Pontoise 7a30b18c20 feat: improve localizations 2023-02-09 21:18:54 +01:00
Louis Pontoise 3fb9a195f8 feat: separate mouse hover from keyboard selection
closes #2078, closes #1617
2023-02-09 20:31:47 +01:00
Louis Pontoise c386a0c439 fix: don't focus window when dropping a file on it 2023-02-09 20:23:09 +01:00
decodism 216c5d8b8e feat: allow status item removal by dragging 2023-01-30 16:51:26 +01:00
semantic-release-bot b57a39d8e8 chore(release): 6.52.1 [skip ci]
## [6.52.1](https://github.com/lwouis/alt-tab-macos/compare/v6.52.0...v6.52.1) (2022-12-28)
2022-12-28 23:57:29 +00:00
Louis Pontoise 8ba828885b ci: replace revoked github token 2022-12-29 00:41:44 +01:00
semantic-release-bot d2c38963c9 chore(release): 6.52.0 [skip ci]
# [6.52.0](https://github.com/lwouis/alt-tab-macos/compare/v6.51.0...v6.52.0) (2022-12-28)

### Bug Fixes

* scale app red badge with app icon size (closes [#559](https://github.com/lwouis/alt-tab-macos/issues/559)) ([4b2f134](https://github.com/lwouis/alt-tab-macos/commit/4b2f134))
* some tooltips would remain on screen (closes [#2190](https://github.com/lwouis/alt-tab-macos/issues/2190)) ([6526caa](https://github.com/lwouis/alt-tab-macos/commit/6526caa))

### Features

* add kurdish localization and improve russian/romanian ([8217ad8](https://github.com/lwouis/alt-tab-macos/commit/8217ad8))
* help support broken fl studio app (closes [#2174](https://github.com/lwouis/alt-tab-macos/issues/2174)) ([4f26bc2](https://github.com/lwouis/alt-tab-macos/commit/4f26bc2))
2022-12-28 23:12:15 +00:00
Louis Pontoise 59d00c1765 ci: make sort use utf8 on every machine 2022-12-28 23:55:09 +01:00
Louis Pontoise 8217ad8fa5 feat: add kurdish localization and improve russian/romanian 2022-12-28 19:46:37 +01:00
Louis Pontoise 4b2f134f32 fix: scale app red badge with app icon size (closes #559) 2022-12-28 19:33:08 +01:00
Louis Pontoise 6526caae30 fix: some tooltips would remain on screen (closes #2190) 2022-12-10 19:26:52 +01:00
Louis Pontoise 4f26bc20a0 feat: help support broken fl studio app (closes #2174) 2022-12-10 19:26:52 +01:00
semantic-release-bot 8b9b0b4fcb chore(release): 6.51.0 [skip ci]
# [6.51.0](https://github.com/lwouis/alt-tab-macos/compare/v6.50.0...v6.51.0) (2022-11-16)

### Bug Fixes

* fullscreening windows stopped working (closes [#2129](https://github.com/lwouis/alt-tab-macos/issues/2129)) ([a09dbbf](https://github.com/lwouis/alt-tab-macos/commit/a09dbbf))
* windows assigned to all spaces were not shown (closes [#2123](https://github.com/lwouis/alt-tab-macos/issues/2123)) ([82cfb62](https://github.com/lwouis/alt-tab-macos/commit/82cfb62))

### Features

* improve localizations ([d2d5016](https://github.com/lwouis/alt-tab-macos/commit/d2d5016))
2022-11-16 21:35:02 +00:00
Louis Pontoise d2d5016780 feat: improve localizations 2022-11-16 22:19:25 +01:00
Louis Pontoise a09dbbfd27 fix: fullscreening windows stopped working (closes #2129) 2022-11-16 22:19:24 +01:00
Louis Pontoise 82cfb62804 fix: windows assigned to all spaces were not shown (closes #2123) 2022-11-16 22:19:24 +01:00
semantic-release-bot ebf445e3e1 chore(release): 6.50.0 [skip ci]
# [6.50.0](https://github.com/lwouis/alt-tab-macos/compare/v6.49.0...v6.50.0) (2022-11-14)

### Bug Fixes

* don't show firefox tooltips as windows (closes [#2110](https://github.com/lwouis/alt-tab-macos/issues/2110)) ([bf905b1](https://github.com/lwouis/alt-tab-macos/commit/bf905b1))
* tabs show as separate windows sometimes on monterey (closes [#2017](https://github.com/lwouis/alt-tab-macos/issues/2017)) ([0965a78](https://github.com/lwouis/alt-tab-macos/commit/0965a78))

### Features

* avoid accidental press of the "reset preferences" button ([#2093](https://github.com/lwouis/alt-tab-macos/issues/2093)) ([f6fcac5](https://github.com/lwouis/alt-tab-macos/commit/f6fcac5))
* avoid confusion with native app-switcher (closes [#2080](https://github.com/lwouis/alt-tab-macos/issues/2080)) ([f906c0e](https://github.com/lwouis/alt-tab-macos/commit/f906c0e))
* improve localizations ([2123af3](https://github.com/lwouis/alt-tab-macos/commit/2123af3))
* show alttab on display with active menubar when needed ([#2107](https://github.com/lwouis/alt-tab-macos/issues/2107)) ([917e661](https://github.com/lwouis/alt-tab-macos/commit/917e661))
2022-11-14 17:53:58 +00:00
Louis Pontoise 2123af39a7 feat: improve localizations 2022-11-14 18:37:32 +01:00
Louis Pontoise 917e661e88 feat: show alttab on display with active menubar when needed (#2107)
closes #2107
2022-11-14 18:32:18 +01:00
Louis Pontoise bf905b1562 fix: don't show firefox tooltips as windows (closes #2110) 2022-11-13 18:23:06 +01:00
Louis Pontoise f6fcac5856 feat: avoid accidental press of the "reset preferences" button (#2093)
closes #2093
2022-11-08 18:46:17 +01:00
Louis Pontoise d4f11542f9 docs: update compatibility info 2022-11-07 22:44:48 +01:00
Louis Pontoise f906c0ecab feat: avoid confusion with native app-switcher (closes #2080) 2022-11-04 22:20:52 +01:00
Louis Pontoise 99f8adeb7d docs: add env info to new issue template 2022-11-04 18:56:56 +01:00
decodism 0965a78d46 fix: tabs show as separate windows sometimes on monterey (closes #2017) 2022-11-03 11:16:51 +01:00
semantic-release-bot fe38b53ff7 chore(release): 6.49.0 [skip ci]
# [6.49.0](https://github.com/lwouis/alt-tab-macos/compare/v6.48.0...v6.49.0) (2022-11-02)

### Bug Fixes

* command+backtick not working if stage manager is on (closes [#2053](https://github.com/lwouis/alt-tab-macos/issues/2053)) ([848ae5f](https://github.com/lwouis/alt-tab-macos/commit/848ae5f))
* crash when setting some shortcut combinations (closes [#2061](https://github.com/lwouis/alt-tab-macos/issues/2061)) ([8b2d659](https://github.com/lwouis/alt-tab-macos/commit/8b2d659))
* hide minimize and fullscreen thumbnail buttons for tabs ([b62c422](https://github.com/lwouis/alt-tab-macos/commit/b62c422))
* improve key repeat-rate when held (closes [#2026](https://github.com/lwouis/alt-tab-macos/issues/2026)) ([1821dea](https://github.com/lwouis/alt-tab-macos/commit/1821dea))
* key-above-tab on international keyboards (closes [#1190](https://github.com/lwouis/alt-tab-macos/issues/1190)) ([4c31740](https://github.com/lwouis/alt-tab-macos/commit/4c31740))
* thumbnails would sometimes be the wrong size ([1065c0d](https://github.com/lwouis/alt-tab-macos/commit/1065c0d))
* wrong focus after active app becomes windowless (closes [#2065](https://github.com/lwouis/alt-tab-macos/issues/2065)) ([281b3ed](https://github.com/lwouis/alt-tab-macos/commit/281b3ed))

### Features

* improve some localizations ([292e6b0](https://github.com/lwouis/alt-tab-macos/commit/292e6b0))
* play alert sound for unavailable thumbnail shortcuts ([fd84a9a](https://github.com/lwouis/alt-tab-macos/commit/fd84a9a))
* support adobe after effects non-standard windows (closes [#1982](https://github.com/lwouis/alt-tab-macos/issues/1982)) ([7b54873](https://github.com/lwouis/alt-tab-macos/commit/7b54873))
2022-11-02 19:49:20 +00:00
decodism 1065c0d440 fix: thumbnails would sometimes be the wrong size 2022-11-02 19:14:34 +01:00
decodism fd84a9a5fc feat: play alert sound for unavailable thumbnail shortcuts 2022-11-02 18:54:42 +01:00
decodism b62c422959 fix: hide minimize and fullscreen thumbnail buttons for tabs 2022-11-02 18:19:22 +01:00
Louis Pontoise f2305429c4 refactor: document more plist attributes 2022-11-02 18:15:43 +01:00
Louis Pontoise 292e6b0339 feat: improve some localizations 2022-11-02 16:49:31 +01:00
Louis Pontoise 7b54873f08 feat: support adobe after effects non-standard windows (closes #1982) 2022-11-02 16:49:30 +01:00
Louis Pontoise 281b3ed45b fix: wrong focus after active app becomes windowless (closes #2065) 2022-11-02 16:49:30 +01:00
Louis Pontoise 8b2d659000 fix: crash when setting some shortcut combinations (closes #2061) 2022-11-02 16:49:30 +01:00
Louis Pontoise 4c31740f25 fix: key-above-tab on international keyboards (closes #1190) 2022-11-02 16:49:30 +01:00
Louis Pontoise 848ae5fc9d fix: command+backtick not working if stage manager is on (closes #2053) 2022-11-02 16:49:30 +01:00
Louis Pontoise b5da4e00ca refactor: pass correct param to private api 2022-11-02 16:49:30 +01:00
Louis Pontoise 4c3688de12 refactor: use triple-slash for method documentation 2022-11-02 16:49:30 +01:00
Louis Pontoise 805660d4d1 refactor: remove unused variables/calls 2022-11-02 16:49:30 +01:00
Louis Pontoise 1821deaa73 fix: improve key repeat-rate when held (closes #2026) 2022-11-02 16:49:29 +01:00
semantic-release-bot c9fd9a2a46 chore(release): 6.48.0 [skip ci]
# [6.48.0](https://github.com/lwouis/alt-tab-macos/compare/v6.47.0...v6.48.0) (2022-10-27)

### Bug Fixes

* app name in system settings in macos 13 (closes [#2044](https://github.com/lwouis/alt-tab-macos/issues/2044)) ([02451e8](https://github.com/lwouis/alt-tab-macos/commit/02451e8))

### Features

* add 3 more shortcut tabs in the preferences (closes [#1064](https://github.com/lwouis/alt-tab-macos/issues/1064)) ([31bd0a6](https://github.com/lwouis/alt-tab-macos/commit/31bd0a6))
2022-10-27 09:31:16 +00:00
decodism 31bd0a6d68 feat: add 3 more shortcut tabs in the preferences (closes #1064) 2022-10-27 11:16:24 +02:00
Louis Pontoise c3162bbb1f refactor: remove hardcoded reference to bundleid 2022-10-27 11:16:24 +02:00
decodism 02451e8ec8 fix: app name in system settings in macos 13 (closes #2044) 2022-10-27 11:16:24 +02:00
semantic-release-bot bd21332c25 chore(release): 6.47.0 [skip ci]
# [6.47.0](https://github.com/lwouis/alt-tab-macos/compare/v6.46.1...v6.47.0) (2022-10-14)

### Bug Fixes

* alt-tab would show on the wrong screen (closes [#2003](https://github.com/lwouis/alt-tab-macos/issues/2003)) ([b72c4db](https://github.com/lwouis/alt-tab-macos/commit/b72c4db))
* discover windows when switching spaces ([#1324](https://github.com/lwouis/alt-tab-macos/issues/1324)) ([9c26d54](https://github.com/lwouis/alt-tab-macos/commit/9c26d54))
* shortcut tabs right margin ([d207f86](https://github.com/lwouis/alt-tab-macos/commit/d207f86))
* show finder file copy windows (closes [#1466](https://github.com/lwouis/alt-tab-macos/issues/1466)) ([c78481b](https://github.com/lwouis/alt-tab-macos/commit/c78481b))
* wrap thumbnail buttons when needed ([ea05c03](https://github.com/lwouis/alt-tab-macos/commit/ea05c03))

### Features

* improve many localizations and add romanian ([71f1609](https://github.com/lwouis/alt-tab-macos/commit/71f1609))
2022-10-14 21:46:04 +00:00
Louis Pontoise 71f1609467 feat: improve many localizations and add romanian 2022-10-14 23:33:07 +02:00
Louis Pontoise 5331bc630a ci: migrate to xcode 13.4 to align with local machine 2022-10-14 21:38:31 +02:00
decodism ea05c0327b fix: wrap thumbnail buttons when needed 2022-10-14 21:27:32 +02:00
decodism d207f86daa fix: shortcut tabs right margin 2022-10-14 21:24:03 +02:00
Louis Pontoise 9c26d54eda fix: discover windows when switching spaces (#1324) 2022-10-14 21:21:18 +02:00
Louis Pontoise b72c4db334 fix: alt-tab would show on the wrong screen (closes #2003) 2022-10-14 21:21:17 +02:00
Louis Pontoise 5830958478 ci: remove detailed logs 2022-10-06 23:43:03 +02:00
Louis Pontoise c78481b5b1 fix: show finder file copy windows (closes #1466)
also improve dealing with steam windows
2022-06-28 02:06:16 +09:00
ryenus 0af9e0f42e refactor: fix compilation error on xcode 13+ 2022-06-26 17:25:57 +09:00
semantic-release-bot 48b0b25974 chore(release): 6.46.1 [skip ci]
## [6.46.1](https://github.com/lwouis/alt-tab-macos/compare/v6.46.0...v6.46.1) (2022-06-24)

### Bug Fixes

* mouse-hover controls remained after closing a window (closes [#1730](https://github.com/lwouis/alt-tab-macos/issues/1730)) ([6bd303d](https://github.com/lwouis/alt-tab-macos/commit/6bd303d))
2022-06-24 10:17:25 +00:00
Louis Pontoise 6bd303d2e8 fix: mouse-hover controls remained after closing a window (closes #1730) 2022-06-24 18:58:52 +09:00
semantic-release-bot dbddcc1c10 chore(release): 6.46.0 [skip ci]
# [6.46.0](https://github.com/lwouis/alt-tab-macos/compare/v6.45.0...v6.46.0) (2022-06-23)

### Features

* add quit-app icon on mouse hover (closes [#1260](https://github.com/lwouis/alt-tab-macos/issues/1260)) ([5c3b503](https://github.com/lwouis/alt-tab-macos/commit/5c3b503))
* improved turkish localization ([bb4a2b9](https://github.com/lwouis/alt-tab-macos/commit/bb4a2b9))
2022-06-23 09:45:23 +00:00
Louis Pontoise bb4a2b9b97 feat: improved turkish localization 2022-06-23 18:31:20 +09:00
Louis Pontoise 5c3b5031d8 feat: add quit-app icon on mouse hover (closes #1260) 2022-06-23 18:31:20 +09:00
semantic-release-bot b460443e77 chore(release): 6.45.0 [skip ci]
# [6.45.0](https://github.com/lwouis/alt-tab-macos/compare/v6.44.0...v6.45.0) (2022-06-21)

### Bug Fixes

* better guess at focus order on launch (closes [#1694](https://github.com/lwouis/alt-tab-macos/issues/1694)) ([be8631e](https://github.com/lwouis/alt-tab-macos/commit/be8631e))
* may avoid rare crashes ([e32beea](https://github.com/lwouis/alt-tab-macos/commit/e32beea))

### Features

* add bengali localization ([2d32823](https://github.com/lwouis/alt-tab-macos/commit/2d32823))
* improve chinese and german localizations ([69bfb41](https://github.com/lwouis/alt-tab-macos/commit/69bfb41))
* improve tooltips on mouse hover (closes [#1661](https://github.com/lwouis/alt-tab-macos/issues/1661)) ([38262f1](https://github.com/lwouis/alt-tab-macos/commit/38262f1))
* quitting an app twice force-quits it (closes [#1529](https://github.com/lwouis/alt-tab-macos/issues/1529)) ([bfcbaac](https://github.com/lwouis/alt-tab-macos/commit/bfcbaac))
2022-06-21 17:24:58 +00:00
Louis Pontoise 69bfb4180c feat: improve chinese and german localizations 2022-06-22 01:32:44 +09:00
Louis Pontoise 2d32823db8 feat: add bengali localization 2022-06-22 01:31:43 +09:00
Louis Pontoise 38262f11b2 feat: improve tooltips on mouse hover (closes #1661) 2022-06-22 01:10:08 +09:00
Louis Pontoise e32beea00a fix: may avoid rare crashes 2022-06-22 01:04:36 +09:00
Louis Pontoise bfcbaacec7 feat: quitting an app twice force-quits it (closes #1529) 2022-06-20 22:04:08 +09:00
Louis Pontoise be8631e90c fix: better guess at focus order on launch (closes #1694) 2022-06-20 20:37:47 +09:00
semantic-release-bot 4198881815 chore(release): 6.44.0 [skip ci]
# [6.44.0](https://github.com/lwouis/alt-tab-macos/compare/v6.43.0...v6.44.0) (2022-06-19)

### Bug Fixes

* blacklist table colors were wrong in dark mode ([#1702](https://github.com/lwouis/alt-tab-macos/issues/1702)) ([95cc29f](https://github.com/lwouis/alt-tab-macos/commit/95cc29f))
* don't show space icon for apps ([#1700](https://github.com/lwouis/alt-tab-macos/issues/1700)) ([f7d070b](https://github.com/lwouis/alt-tab-macos/commit/f7d070b))
* round corners would be aliased after changing theme ([#1698](https://github.com/lwouis/alt-tab-macos/issues/1698)) ([9ae76a9](https://github.com/lwouis/alt-tab-macos/commit/9ae76a9))

### Features

* update german and turkish localizations ([b91696b](https://github.com/lwouis/alt-tab-macos/commit/b91696b))
2022-06-19 15:53:12 +00:00
Louis Pontoise b91696bc89 feat: update german and turkish localizations 2022-06-20 00:38:02 +09:00
Louis Pontoise f7d070b38c fix: don't show space icon for apps (#1700) 2022-06-20 00:38:02 +09:00
Louis Pontoise 95cc29fd9c fix: blacklist table colors were wrong in dark mode (#1702) 2022-06-20 00:38:02 +09:00
Louis Pontoise 9ae76a90fc fix: round corners would be aliased after changing theme (#1698) 2022-06-20 00:38:02 +09:00
semantic-release-bot 24b8617c54 chore(release): 6.43.0 [skip ci]
# [6.43.0](https://github.com/lwouis/alt-tab-macos/compare/v6.42.0...v6.43.0) (2022-06-14)

### Features

* improve blacklist ux (closes [#539](https://github.com/lwouis/alt-tab-macos/issues/539)) ([892a168](https://github.com/lwouis/alt-tab-macos/commit/892a168))
* improve german and chinese (tw) localizations ([5133641](https://github.com/lwouis/alt-tab-macos/commit/5133641))
2022-06-14 07:18:05 +00:00
Louis Pontoise 892a168ee7 feat: improve blacklist ux (closes #539) 2022-06-14 15:59:21 +09:00
Louis Pontoise 51336412c5 feat: improve german and chinese (tw) localizations 2022-06-14 15:59:20 +09:00
Louis Pontoise f38913b75c refactor: maybe fix crash on nil cgwindowid + fix warnings 2022-06-14 15:59:20 +09:00
semantic-release-bot ae35474130 chore(release): 6.42.0 [skip ci]
# [6.42.0](https://github.com/lwouis/alt-tab-macos/compare/v6.41.1...v6.42.0) (2022-06-07)

### Bug Fixes

* some windows would not show ([#1655](https://github.com/lwouis/alt-tab-macos/issues/1655)) ([6a6c80d](https://github.com/lwouis/alt-tab-macos/commit/6a6c80d))

### Features

* show tooltips on mouse hover on main window ([#1661](https://github.com/lwouis/alt-tab-macos/issues/1661)) ([bb5cc23](https://github.com/lwouis/alt-tab-macos/commit/bb5cc23))
2022-06-07 11:55:43 +00:00
Louis Pontoise bb5cc236a7 feat: show tooltips on mouse hover on main window (#1661) 2022-06-07 18:42:14 +09:00
Louis Pontoise 6a6c80d9a4 fix: some windows would not show (#1655) 2022-06-07 18:10:59 +09:00
s4na ae8f7964fa docs: update homebrew instructions for v2.7 2022-06-07 18:10:58 +09:00
semantic-release-bot 3630b17cde chore(release): 6.41.1 [skip ci]
## [6.41.1](https://github.com/lwouis/alt-tab-macos/compare/v6.41.0...v6.41.1) (2022-06-05)

### Bug Fixes

* tab detection got broken in v6.41.0 ([#1656](https://github.com/lwouis/alt-tab-macos/issues/1656)) ([95f97d3](https://github.com/lwouis/alt-tab-macos/commit/95f97d3))
2022-06-05 03:19:48 +00:00
Louis Pontoise 95f97d33af fix: tab detection got broken in v6.41.0 (#1656) 2022-06-05 12:00:14 +09:00
semantic-release-bot 1243de8010 chore(release): 6.41.0 [skip ci]
# [6.41.0](https://github.com/lwouis/alt-tab-macos/compare/v6.40.0...v6.41.0) (2022-06-01)

### Bug Fixes

* fade-out animation was broken from macos 11 ([#760](https://github.com/lwouis/alt-tab-macos/issues/760)) ([d701bc7](https://github.com/lwouis/alt-tab-macos/commit/d701bc7))
* menubar icons in preferences handle dark mode ([1653c16](https://github.com/lwouis/alt-tab-macos/commit/1653c16))

### Features

* add a button to reset the preferences ([#1275](https://github.com/lwouis/alt-tab-macos/issues/1275)) ([82e9ca9](https://github.com/lwouis/alt-tab-macos/commit/82e9ca9))
* add galician localization ([965b179](https://github.com/lwouis/alt-tab-macos/commit/965b179))
* improve windows detection ([de0497a](https://github.com/lwouis/alt-tab-macos/commit/de0497a))
* smoother rounded corners for the main window ([5d0fff2](https://github.com/lwouis/alt-tab-macos/commit/5d0fff2))
* update czech localization ([d7b6b7c](https://github.com/lwouis/alt-tab-macos/commit/d7b6b7c))
2022-06-01 10:31:20 +00:00
Louis Pontoise 965b179d56 feat: add galician localization 2022-06-01 19:10:53 +09:00
Louis Pontoise 5d0fff2276 feat: smoother rounded corners for the main window 2022-06-01 18:56:02 +09:00
Louis Pontoise d7b6b7c0ae feat: update czech localization 2022-06-01 01:22:16 +09:00
Louis Pontoise de0497a2dc feat: improve windows detection 2022-06-01 01:22:16 +09:00
Louis Pontoise 1653c16c65 fix: menubar icons in preferences handle dark mode 2022-06-01 01:22:16 +09:00
Louis Pontoise 88783b3f5f docs: typo on the website homepage 2022-06-01 01:22:16 +09:00
Zachary Wander d701bc7347 fix: fade-out animation was broken from macos 11 (#760) 2022-06-01 01:22:15 +09:00
Louis Pontoise 82e9ca93b6 feat: add a button to reset the preferences (#1275) 2022-05-28 19:13:42 +09:00
Louis Pontoise 5f99e7280a refactor: find method to dry code 2022-05-28 12:37:10 +09:00
semantic-release-bot f56bf3d41b chore(release): 6.40.0 [skip ci]
# [6.40.0](https://github.com/lwouis/alt-tab-macos/compare/v6.39.1...v6.40.0) (2022-05-27)

### Bug Fixes

* focusing alt-tab own windows could fail ([#759](https://github.com/lwouis/alt-tab-macos/issues/759)) ([08720d8](https://github.com/lwouis/alt-tab-macos/commit/08720d8))

### Features

* update spanish localization ([1ac0494](https://github.com/lwouis/alt-tab-macos/commit/1ac0494))
2022-05-27 17:53:39 +00:00
Louis Pontoise 1ac0494f96 feat: update spanish localization 2022-05-28 02:33:41 +09:00
Louis Pontoise 08720d8eeb fix: focusing alt-tab own windows could fail (#759) 2022-05-28 02:29:54 +09:00
semantic-release-bot c44057f47d chore(release): 6.39.1 [skip ci]
## [6.39.1](https://github.com/lwouis/alt-tab-macos/compare/v6.39.0...v6.39.1) (2022-05-26)

### Bug Fixes

* better tabs detection + fix issues with some apps (closes [#1540](https://github.com/lwouis/alt-tab-macos/issues/1540)) ([abd54b3](https://github.com/lwouis/alt-tab-macos/commit/abd54b3)), closes [#647](https://github.com/lwouis/alt-tab-macos/issues/647) [#718](https://github.com/lwouis/alt-tab-macos/issues/718)
2022-05-26 15:54:16 +00:00
Louis Pontoise abd54b3939 fix: better tabs detection + fix issues with some apps (closes #1540)
Maybe fixed #647 #718
2022-05-27 00:33:55 +09:00
semantic-release-bot 1a9fc593d1 chore(release): 6.39.0 [skip ci]
# [6.39.0](https://github.com/lwouis/alt-tab-macos/compare/v6.38.0...v6.39.0) (2022-05-26)

### Bug Fixes

* handle being quit through activity-monitor (closes [#1622](https://github.com/lwouis/alt-tab-macos/issues/1622)) ([69a5ffd](https://github.com/lwouis/alt-tab-macos/commit/69a5ffd))

### Features

* middle-click a thumbnail to close that window (closes [#1621](https://github.com/lwouis/alt-tab-macos/issues/1621)) ([bc4c0cc](https://github.com/lwouis/alt-tab-macos/commit/bc4c0cc))
* update contributors ([b1bf867](https://github.com/lwouis/alt-tab-macos/commit/b1bf867))
2022-05-26 13:58:07 +00:00
Louis Pontoise b1bf86724d feat: update contributors 2022-05-26 22:39:24 +09:00
Louis Pontoise bc4c0cc505 feat: middle-click a thumbnail to close that window (closes #1621) 2022-05-26 21:36:40 +09:00
Louis Pontoise 69a5ffd8b2 fix: handle being quit through activity-monitor (closes #1622) 2022-05-26 21:36:40 +09:00
semantic-release-bot e22f2f2e90 chore(release): 6.38.0 [skip ci]
# [6.38.0](https://github.com/lwouis/alt-tab-macos/compare/v6.37.1...v6.38.0) (2022-05-24)

### Bug Fixes

* better mouse hover behavior ([#1557](https://github.com/lwouis/alt-tab-macos/issues/1557)) ([d3cabc1](https://github.com/lwouis/alt-tab-macos/commit/d3cabc1))

### Features

* improve ukrainian, polish, albanian localization ([b02972b](https://github.com/lwouis/alt-tab-macos/commit/b02972b))
2022-05-24 15:12:35 +00:00
Louis Pontoise b02972b7ea feat: improve ukrainian, polish, albanian localization 2022-05-24 23:53:19 +09:00
Louis Pontoise d3cabc1c05 fix: better mouse hover behavior (#1557) 2022-05-24 23:48:45 +09:00
semantic-release-bot 634cf79916 chore(release): 6.37.1 [skip ci]
## [6.37.1](https://github.com/lwouis/alt-tab-macos/compare/v6.37.0...v6.37.1) (2022-05-12)

### Bug Fixes

* hovering thumbnails would make alttab laggy ([#1567](https://github.com/lwouis/alt-tab-macos/issues/1567)) ([7e66009](https://github.com/lwouis/alt-tab-macos/commit/7e66009))
2022-05-12 13:56:26 +00:00
Louis Pontoise 7e660091e0 fix: hovering thumbnails would make alttab laggy (#1567) 2022-05-12 22:33:23 +09:00
Louis Pontoise 296ced8e9b docs: improve website readability 2022-05-12 21:58:54 +09:00
semantic-release-bot 1226caca03 chore(release): 6.37.0 [skip ci]
# [6.37.0](https://github.com/lwouis/alt-tab-macos/compare/v6.36.2...v6.37.0) (2022-05-12)

### Bug Fixes

* prevent matlab freezing ([#890](https://github.com/lwouis/alt-tab-macos/issues/890)) ([0792838](https://github.com/lwouis/alt-tab-macos/commit/0792838))

### Features

* add albanian localization ([c22b364](https://github.com/lwouis/alt-tab-macos/commit/c22b364))
* improve chinese/taiwanese localizations ([f1c0244](https://github.com/lwouis/alt-tab-macos/commit/f1c0244))
2022-05-12 12:44:59 +00:00
Louis Pontoise f1c02442bc feat: improve chinese/taiwanese localizations 2022-05-12 21:25:22 +09:00
Louis Pontoise 52f8f513da docs: update website with more helpful info 2022-05-12 21:25:22 +09:00
Louis Pontoise c22b364ebe feat: add albanian localization 2022-05-12 21:04:41 +09:00
Louis Pontoise 0792838b16 fix: prevent matlab freezing (#890) 2022-05-12 19:25:37 +09:00
semantic-release-bot f16f6ea4d7 chore(release): 6.36.2 [skip ci]
## [6.36.2](https://github.com/lwouis/alt-tab-macos/compare/v6.36.1...v6.36.2) (2022-05-11)

### Bug Fixes

* hide window controls when another window is selected (closes [#1557](https://github.com/lwouis/alt-tab-macos/issues/1557)) ([2e9cc3b](https://github.com/lwouis/alt-tab-macos/commit/2e9cc3b))
2022-05-11 14:55:28 +00:00
Louis Pontoise 2e9cc3b581 fix: hide window controls when another window is selected (closes #1557) 2022-05-11 23:35:14 +09:00
Louis Pontoise 71543dc615 docs: link to nice launchd plist docs 2022-05-07 19:03:51 +09:00
semantic-release-bot f4f327e7d4 chore(release): 6.36.1 [skip ci]
## [6.36.1](https://github.com/lwouis/alt-tab-macos/compare/v6.36.0...v6.36.1) (2022-05-07)

### Bug Fixes

* better anti-aliasing on traffic-light icons ([022806b](https://github.com/lwouis/alt-tab-macos/commit/022806b))
* libre-office would freeze with 2 open windows (closes [#1508](https://github.com/lwouis/alt-tab-macos/issues/1508)) ([1bb9fd0](https://github.com/lwouis/alt-tab-macos/commit/1bb9fd0))
* switcher could select the wrong thumbnail (closes [#1198](https://github.com/lwouis/alt-tab-macos/issues/1198)) ([4c67778](https://github.com/lwouis/alt-tab-macos/commit/4c67778))
2022-05-07 09:34:14 +00:00
Louis Pontoise 4c6777862e fix: switcher could select the wrong thumbnail (closes #1198) 2022-05-07 18:15:07 +09:00
Louis Pontoise 7acee37607 refactor: update private apis 2022-05-07 18:06:09 +09:00
Louis Pontoise 1bb9fd04d8 fix: libre-office would freeze with 2 open windows (closes #1508) 2022-05-07 18:06:09 +09:00
Louis Pontoise 022806bea2 fix: better anti-aliasing on traffic-light icons 2022-05-07 18:06:09 +09:00
Louis Pontoise 55bbfe59e6 docs: document more use-cases 2022-05-07 18:06:08 +09:00
semantic-release-bot 52d7d21019 chore(release): 6.36.0 [skip ci]
# [6.36.0](https://github.com/lwouis/alt-tab-macos/compare/v6.35.0...v6.36.0) (2022-05-06)

### Features

* improve traffic-light icons (closes [#1542](https://github.com/lwouis/alt-tab-macos/issues/1542)) ([6974de0](https://github.com/lwouis/alt-tab-macos/commit/6974de0))
2022-05-06 17:53:13 +00:00
Louis Pontoise 6974de02ac feat: improve traffic-light icons (closes #1542) 2022-05-07 02:34:35 +09:00
semantic-release-bot d46bd8d10c chore(release): 6.35.0 [skip ci]
# [6.35.0](https://github.com/lwouis/alt-tab-macos/compare/v6.34.1...v6.35.0) (2022-05-05)

### Bug Fixes

* sometimes moved cursor on focus wrong (closes [#1087](https://github.com/lwouis/alt-tab-macos/issues/1087)) ([ed10201](https://github.com/lwouis/alt-tab-macos/commit/ed10201))

### Features

* update turkish localization ([9129ff6](https://github.com/lwouis/alt-tab-macos/commit/9129ff6))
2022-05-05 15:46:39 +00:00
Louis Pontoise 9129ff6e75 feat: update turkish localization 2022-05-06 00:26:21 +09:00
Louis Pontoise ed102015ad fix: sometimes moved cursor on focus wrong (closes #1087) 2022-05-05 00:59:38 +09:00
semantic-release-bot 26e2375bfb chore(release): 6.34.1 [skip ci]
## [6.34.1](https://github.com/lwouis/alt-tab-macos/compare/v6.34.0...v6.34.1) (2022-04-30)

### Bug Fixes

* custom shortcuts can use arrow keys (closes [#1376](https://github.com/lwouis/alt-tab-macos/issues/1376)) ([bb1de75](https://github.com/lwouis/alt-tab-macos/commit/bb1de75))
2022-04-30 15:50:29 +00:00
Louis Pontoise bb1de75128 fix: custom shortcuts can use arrow keys (closes #1376) 2022-05-01 00:31:13 +09:00
semantic-release-bot 254f238f82 chore(release): 6.34.0 [skip ci]
# [6.34.0](https://github.com/lwouis/alt-tab-macos/compare/v6.33.0...v6.34.0) (2022-04-28)

### Bug Fixes

* alt-tab could be relaunched in a loop (closes [#1367](https://github.com/lwouis/alt-tab-macos/issues/1367)) ([cdb461a](https://github.com/lwouis/alt-tab-macos/commit/cdb461a))
* reduce alt-tab cpu usage in some scenarios (closes [#1481](https://github.com/lwouis/alt-tab-macos/issues/1481)) ([0569ed0](https://github.com/lwouis/alt-tab-macos/commit/0569ed0))

### Features

* update indian and russian localizations ([85210e2](https://github.com/lwouis/alt-tab-macos/commit/85210e2))
2022-04-28 14:33:41 +00:00
Louis Pontoise 85210e2935 feat: update indian and russian localizations 2022-04-28 23:12:23 +09:00
Louis Pontoise cdb461ab68 fix: alt-tab could be relaunched in a loop (closes #1367) 2022-04-28 23:12:23 +09:00
Louis Pontoise 0569ed0f86 fix: reduce alt-tab cpu usage in some scenarios (closes #1481) 2022-04-28 23:12:23 +09:00
semantic-release-bot 64d1e8677e chore(release): 6.33.0 [skip ci]
# [6.33.0](https://github.com/lwouis/alt-tab-macos/compare/v6.32.0...v6.33.0) (2022-04-08)

### Features

* allow quitting finder for power users (closes [#1328](https://github.com/lwouis/alt-tab-macos/issues/1328)) ([9e46bd8](https://github.com/lwouis/alt-tab-macos/commit/9e46bd8))
2022-04-08 10:23:04 +00:00
Louis Pontoise 790f6440f3 docs: update contributor list 2022-04-08 18:01:21 +09:00
Louis Pontoise 9e46bd8e2c feat: allow quitting finder for power users (closes #1328) 2022-04-08 18:01:21 +09:00
semantic-release-bot 02590579df chore(release): 6.32.0 [skip ci]
# [6.32.0](https://github.com/lwouis/alt-tab-macos/compare/v6.31.0...v6.32.0) (2022-04-07)

### Bug Fixes

* issue with some apps launched before alt-tab ([f97cd74](https://github.com/lwouis/alt-tab-macos/commit/f97cd74))
* show window of some apps like jetbrains apps ([#1249](https://github.com/lwouis/alt-tab-macos/issues/1249) [#1079](https://github.com/lwouis/alt-tab-macos/issues/1079) [#1392](https://github.com/lwouis/alt-tab-macos/issues/1392)) ([0b85b09](https://github.com/lwouis/alt-tab-macos/commit/0b85b09))
* show windows of some defective apps like bear.app ([9b5cd42](https://github.com/lwouis/alt-tab-macos/commit/9b5cd42))

### Features

* add greek and estonian, and update other localizations ([fccae77](https://github.com/lwouis/alt-tab-macos/commit/fccae77))
2022-04-07 13:16:51 +00:00
Louis Pontoise fccae7734d feat: add greek and estonian, and update other localizations 2022-04-07 21:56:30 +09:00
metacodes f97cd74bd3 fix: issue with some apps launched before alt-tab 2022-04-07 21:05:19 +09:00
metacodes 9b5cd427e6 fix: show windows of some defective apps like bear.app 2022-04-07 21:05:19 +09:00
metacodes 0b85b09f62 fix: show window of some apps like jetbrains apps (#1249 #1079 #1392)
I am able to reproduce the issue by reinstall JetBrains AppCode. The first time I open AppCode after reinstall it, AltTab never show AppCode window. I debug the code on my Mac, I find that AltTab can get the event of app launched but never get the event of finishedLaunching. So I just remove the code runningApplication.isFinishedLaunching. After that, AltTab work well and the issue is fixed.
2022-04-07 21:05:18 +09:00
semantic-release-bot 6887291151 chore(release): 6.31.0 [skip ci]
# [6.31.0](https://github.com/lwouis/alt-tab-macos/compare/v6.30.0...v6.31.0) (2022-02-10)

### Features

* add hebrew localization ([26b72e3](https://github.com/lwouis/alt-tab-macos/commit/26b72e3))
2022-02-10 03:03:20 +00:00
Louis Pontoise 26b72e3792 feat: add hebrew localization 2022-02-10 11:44:39 +09:00
semantic-release-bot 2d042f2c44 chore(release): 6.30.0 [skip ci]
# [6.30.0](https://github.com/lwouis/alt-tab-macos/compare/v6.29.0...v6.30.0) (2022-02-05)

### Features

* add localization in danish, catalan, persian, serbian ([058a0f8](https://github.com/lwouis/alt-tab-macos/commit/058a0f8))
* allow cursor follow focus behavior ([be50758](https://github.com/lwouis/alt-tab-macos/commit/be50758))
* update some localizations ([17fbcc5](https://github.com/lwouis/alt-tab-macos/commit/17fbcc5))
2022-02-05 03:15:15 +00:00
Louis Pontoise 52c9e644b8 ci: dav protocol is no longer supported by apple 2022-02-05 11:55:24 +09:00
Louis Pontoise 058a0f82d3 feat: add localization in danish, catalan, persian, serbian 2022-02-05 01:56:27 +09:00
Louis Pontoise 17fbcc5f09 feat: update some localizations 2022-02-04 22:54:01 +09:00
Grzegorz Kazana be50758451 feat: allow cursor follow focus behavior 2022-02-04 22:54:01 +09:00
semantic-release-bot f5fc5ba813 chore(release): 6.29.0 [skip ci]
# [6.29.0](https://github.com/lwouis/alt-tab-macos/compare/v6.28.0...v6.29.0) (2021-12-01)

### Bug Fixes

* only make network calls to appcenter when necessary (closes [#1265](https://github.com/lwouis/alt-tab-macos/issues/1265)) ([79c2906](https://github.com/lwouis/alt-tab-macos/commit/79c2906))
* prevent setting min width to 0% in preferences (see [#1248](https://github.com/lwouis/alt-tab-macos/issues/1248)) ([467736c](https://github.com/lwouis/alt-tab-macos/commit/467736c))

### Features

* add apple screen sharing to default blacklist ([#1258](https://github.com/lwouis/alt-tab-macos/issues/1258)) ([d4780f6](https://github.com/lwouis/alt-tab-macos/commit/d4780f6))
* add vmware fusion to default blacklist (closes [#1258](https://github.com/lwouis/alt-tab-macos/issues/1258)) ([17f98b5](https://github.com/lwouis/alt-tab-macos/commit/17f98b5))
2021-12-01 16:02:14 +00:00
Louis Pontoise 64d4a78570 docs: update contributors 2021-12-02 00:41:04 +09:00
Zhenfu Shi d4780f61bc feat: add apple screen sharing to default blacklist (#1258) 2021-12-02 00:17:35 +09:00
Andre Borie 79c290603d fix: only make network calls to appcenter when necessary (closes #1265) 2021-12-02 00:12:47 +09:00
Louis Pontoise a6ea7a3950 ci: only build master/develop (pr builds were disabled on travis) 2021-12-02 00:12:47 +09:00
Zhenfu Shi 17f98b5c6b feat: add vmware fusion to default blacklist (closes #1258) 2021-12-02 00:12:47 +09:00
Louis Pontoise 467736ca2f fix: prevent setting min width to 0% in preferences (see #1248) 2021-12-02 00:12:47 +09:00
semantic-release-bot 74386d0c42 chore(release): 6.28.0 [skip ci]
# [6.28.0](https://github.com/lwouis/alt-tab-macos/compare/v6.27.1...v6.28.0) (2021-11-19)

### Bug Fixes

* would sometimes crash when opening preferences > appearance ([c66e106](https://github.com/lwouis/alt-tab-macos/commit/c66e106))

### Features

* native support for apple silicon (e.g. m1 mac) ([6f93130](https://github.com/lwouis/alt-tab-macos/commit/6f93130))
* support login-at-start on macos 11, 12, and m1 macs ([664c5b9](https://github.com/lwouis/alt-tab-macos/commit/664c5b9))
2021-11-19 14:41:15 +00:00
Louis Pontoise b51a790997 docs: update contributors 2021-11-19 23:22:38 +09:00
Louis Pontoise 6329cd35f9 ci: make release build on pull-requests as well 2021-11-19 23:06:31 +09:00
Martin Wilhelmi c66e106613 fix: would sometimes crash when opening preferences > appearance 2021-11-19 23:06:31 +09:00
Martin Wilhelmi 4368015435 ci: show architectures inside binary after build 2021-11-19 23:06:31 +09:00
Louis Pontoise 762b072c5e docs: fix error in qa scenario 2021-11-19 23:06:31 +09:00
Louis Pontoise 664c5b9628 feat: support login-at-start on macos 11, 12, and m1 macs 2021-11-19 23:06:31 +09:00
6f931305cc feat: native support for apple silicon (e.g. m1 mac)
Co-authored-by: Martin Wilhelmi <mnin@mnin.de>
Co-authored-by: Louis Pontoise <lwouis@gmail.com>
2021-11-19 23:06:31 +09:00
semantic-release-bot 92afb11668 chore(release): 6.27.1 [skip ci]
## [6.27.1](https://github.com/lwouis/alt-tab-macos/compare/v6.27.0...v6.27.1) (2021-11-13)

### Bug Fixes

* ghost windows in android studio (#closes 1224) ([b668928](https://github.com/lwouis/alt-tab-macos/commit/b668928))
2021-11-13 11:48:44 +00:00
Louis Pontoise b668928c89 fix: ghost windows in android studio (#closes 1224) 2021-11-13 20:28:12 +09:00
semantic-release-bot 3ad8619920 chore(release): 6.27.0 [skip ci]
# [6.27.0](https://github.com/lwouis/alt-tab-macos/compare/v6.26.0...v6.27.0) (2021-11-12)

### Bug Fixes

* display all windows from android studio ([e2d26f2](https://github.com/lwouis/alt-tab-macos/commit/e2d26f2))
* parallels windows wouldn't switch sometimes (closes [#1213](https://github.com/lwouis/alt-tab-macos/issues/1213)) ([21133ce](https://github.com/lwouis/alt-tab-macos/commit/21133ce))
* the app would sometimes freeze or lag (closes [#563](https://github.com/lwouis/alt-tab-macos/issues/563)) ([4a264ab](https://github.com/lwouis/alt-tab-macos/commit/4a264ab))

### Features

* improved spanish localization ([3709b62](https://github.com/lwouis/alt-tab-macos/commit/3709b62))
2021-11-12 17:54:14 +00:00
Louis Pontoise 3709b62084 feat: improved spanish localization 2021-11-13 02:35:18 +09:00
Louis Pontoise 1db15e041b refactor: split code to help pinpoint the issue in appcenter reports 2021-11-13 01:39:28 +09:00
Louis Pontoise f4eb6ff49d refactor: fix non-impactful compiler warnings 2021-11-13 01:39:28 +09:00
Zachary Wander 4a264abadd fix: the app would sometimes freeze or lag (closes #563) 2021-11-13 01:39:28 +09:00
Zachary Wander 21133ce118 fix: parallels windows wouldn't switch sometimes (closes #1213) 2021-11-13 01:39:28 +09:00
Zachary Wander e2d26f2abc fix: display all windows from android studio 2021-11-13 01:39:28 +09:00
semantic-release-bot 98c144efe8 chore(release): 6.26.0 [skip ci]
# [6.26.0](https://github.com/lwouis/alt-tab-macos/compare/v6.25.0...v6.26.0) (2021-10-13)

### Bug Fixes

* feedback form messages got broken by github ([1539727](https://github.com/lwouis/alt-tab-macos/commit/1539727))

### Features

* add bulgarian and improve arabic localizations ([f1be3cf](https://github.com/lwouis/alt-tab-macos/commit/f1be3cf))
2021-10-13 12:43:28 +00:00
Louis Pontoise f1be3cf3e3 feat: add bulgarian and improve arabic localizations 2021-10-13 21:24:45 +09:00
Louis Pontoise 1539727da1 fix: feedback form messages got broken by github 2021-10-13 21:24:45 +09:00
Louis Pontoise b55c9f1f6c docs: fix languages supported list on landing page 2021-10-13 21:24:45 +09:00
semantic-release-bot 9d2899d5b7 chore(release): 6.25.0 [skip ci]
# [6.25.0](https://github.com/lwouis/alt-tab-macos/compare/v6.24.0...v6.25.0) (2021-09-18)

### Bug Fixes

* "show on active screen" could show the wrong screen (closes [#1129](https://github.com/lwouis/alt-tab-macos/issues/1129)) ([23bbd64](https://github.com/lwouis/alt-tab-macos/commit/23bbd64))
* windows from the iina app would not show sometimes (closes [#1037](https://github.com/lwouis/alt-tab-macos/issues/1037)) ([47d283e](https://github.com/lwouis/alt-tab-macos/commit/47d283e))

### Features

* improve localization in hindi, arabic, vietnamese ([2905f7d](https://github.com/lwouis/alt-tab-macos/commit/2905f7d))
* improve voiceover and speech accessibility ([194e726](https://github.com/lwouis/alt-tab-macos/commit/194e726))
2021-09-18 14:24:26 +00:00
Louis Pontoise 2905f7d1aa feat: improve localization in hindi, arabic, vietnamese 2021-09-18 23:06:37 +09:00
Louis Pontoise 23bbd6498f fix: "show on active screen" could show the wrong screen (closes #1129) 2021-09-18 23:06:37 +09:00
Louis Pontoise 1ca7eb48db refactor: pre-emptively use pid instead of object references
no issue was reported, but pid should always be safer, so switching to it
2021-09-18 23:06:37 +09:00
Louis Pontoise 47d283eb61 fix: windows from the iina app would not show sometimes (closes #1037) 2021-09-18 23:06:37 +09:00
Louis Pontoise 194e7266bd feat: improve voiceover and speech accessibility 2021-09-18 23:06:37 +09:00
semantic-release-bot 2869603573 chore(release): 6.24.0 [skip ci]
# [6.24.0](https://github.com/lwouis/alt-tab-macos/compare/v6.23.0...v6.24.0) (2021-09-04)

### Bug Fixes

* main window would sometimes appear after a delay (closes [#1096](https://github.com/lwouis/alt-tab-macos/issues/1096)) ([8ab0e61](https://github.com/lwouis/alt-tab-macos/commit/8ab0e61))

### Features

* update dutch localization ([91821f7](https://github.com/lwouis/alt-tab-macos/commit/91821f7))
* update italian and turkish localizations ([5cd7b44](https://github.com/lwouis/alt-tab-macos/commit/5cd7b44))
2021-09-04 14:43:32 +00:00
Louis Pontoise 5cd7b44580 feat: update italian and turkish localizations 2021-09-04 23:27:55 +09:00
Louis Pontoise 8ab0e615c8 fix: main window would sometimes appear after a delay (closes #1096) 2021-09-04 23:27:55 +09:00
Louis Pontoise 9d2fd763e2 refactor: improve perf by getting pid once at init 2021-09-04 23:27:55 +09:00
Louis Pontoise 91821f7431 feat: update dutch localization 2021-09-04 23:27:55 +09:00
semantic-release-bot 3918c227c7 chore(release): 6.23.0 [skip ci]
# [6.23.0](https://github.com/lwouis/alt-tab-macos/compare/v6.22.1...v6.23.0) (2021-08-30)

### Bug Fixes

* fix situations from some crash reports ([c18aa4d](https://github.com/lwouis/alt-tab-macos/commit/c18aa4d))
* ghost popup windows in android studio (closes [#1056](https://github.com/lwouis/alt-tab-macos/issues/1056)) ([6f33e3a](https://github.com/lwouis/alt-tab-macos/commit/6f33e3a))
* hide window controls after a window is closed (closes [#925](https://github.com/lwouis/alt-tab-macos/issues/925)) ([0dad739](https://github.com/lwouis/alt-tab-macos/commit/0dad739))
* highlight right thumbnail when no window is focused (closes [#1044](https://github.com/lwouis/alt-tab-macos/issues/1044)) ([f4d3db7](https://github.com/lwouis/alt-tab-macos/commit/f4d3db7))
* showing windows of other screens when it shouldn't (closes [#1052](https://github.com/lwouis/alt-tab-macos/issues/1052)) ([b5b3c38](https://github.com/lwouis/alt-tab-macos/commit/b5b3c38))

### Features

* add vietnamese and luxembourgish localizations ([749db12](https://github.com/lwouis/alt-tab-macos/commit/749db12))
* improve french, portuguese and chinese localizations ([a7026a4](https://github.com/lwouis/alt-tab-macos/commit/a7026a4))
* remove "active space" from filter list ([4623e5b](https://github.com/lwouis/alt-tab-macos/commit/4623e5b))
* support voiceover + "speak items under the cursor" (closes [#1070](https://github.com/lwouis/alt-tab-macos/issues/1070)) ([c7911f3](https://github.com/lwouis/alt-tab-macos/commit/c7911f3))
2021-08-30 17:12:14 +00:00
Louis Pontoise f4d3db790e fix: highlight right thumbnail when no window is focused (closes #1044) 2021-08-31 01:36:15 +09:00
Louis Pontoise 4623e5b7c4 feat: remove "active space" from filter list 2021-08-31 01:36:15 +09:00
Louis Pontoise b5b3c38fec fix: showing windows of other screens when it shouldn't (closes #1052) 2021-08-31 01:36:15 +09:00
Louis Pontoise 749db12bbd feat: add vietnamese and luxembourgish localizations 2021-08-31 01:36:15 +09:00
Louis Pontoise a7026a4f24 feat: improve french, portuguese and chinese localizations 2021-08-30 23:19:43 +09:00
Louis Pontoise c7911f3f5c feat: support voiceover + "speak items under the cursor" (closes #1070) 2021-08-30 23:19:43 +09:00
Louis Pontoise c18aa4d91c fix: fix situations from some crash reports 2021-08-30 23:19:43 +09:00
Afzal Najam 6f33e3ae9f fix: ghost popup windows in android studio (closes #1056) 2021-08-30 23:19:41 +09:00
Allen Guan 46566a4fb5 docs: fix typo in Introduction 2021-07-29 12:33:06 +09:00
Louis Pontoise 0dad739b15 fix: hide window controls after a window is closed (closes #925) 2021-05-26 23:44:34 +09:00
Louis Pontoise c59368c601 docs: clarify compatibility on the landing website (#211) 2021-05-26 23:44:33 +09:00
semantic-release-bot 44ac1e1012 chore(release): 6.22.1 [skip ci]
## [6.22.1](https://github.com/lwouis/alt-tab-macos/compare/v6.22.0...v6.22.1) (2021-05-12)

### Bug Fixes

* certain jetbrain apps windows were not shown (closes [#948](https://github.com/lwouis/alt-tab-macos/issues/948)) ([5958107](https://github.com/lwouis/alt-tab-macos/commit/5958107))
2021-05-12 11:04:39 +00:00
Louis Pontoise 5958107cd9 fix: certain jetbrain apps windows were not shown (closes #948) 2021-05-12 17:28:49 +09:00
semantic-release-bot 25d36c8c2e chore(release): 6.22.0 [skip ci]
# [6.22.0](https://github.com/lwouis/alt-tab-macos/compare/v6.21.2...v6.22.0) (2021-05-10)

### Bug Fixes

* remove jetbrain app non-windows (closes [#885](https://github.com/lwouis/alt-tab-macos/issues/885)) ([a368af3](https://github.com/lwouis/alt-tab-macos/commit/a368af3))

### Features

* add citrix viewer in the default blacklist (see [#381](https://github.com/lwouis/alt-tab-macos/issues/381)) ([e630acf](https://github.com/lwouis/alt-tab-macos/commit/e630acf))
2021-05-10 18:44:47 +00:00
Louis Pontoise a368af3f01 fix: remove jetbrain app non-windows (closes #885) 2021-05-10 16:43:25 +09:00
Louis Pontoise e630acffe0 feat: add citrix viewer in the default blacklist (see #381) 2021-05-10 16:43:25 +09:00
semantic-release-bot dbd252a95c chore(release): 6.21.2 [skip ci]
## [6.21.2](https://github.com/lwouis/alt-tab-macos/compare/v6.21.1...v6.21.2) (2021-04-20)

### Bug Fixes

* selected thumbnail was sometimes wrong (closes [#926](https://github.com/lwouis/alt-tab-macos/issues/926)) ([1da3f32](https://github.com/lwouis/alt-tab-macos/commit/1da3f32))
2021-04-20 12:13:41 +00:00
Louis Pontoise 1da3f3219c fix: selected thumbnail was sometimes wrong (closes #926) 2021-04-20 20:54:29 +09:00
semantic-release-bot a880b3d830 chore(release): 6.21.1 [skip ci]
## [6.21.1](https://github.com/lwouis/alt-tab-macos/compare/v6.21.0...v6.21.1) (2021-04-19)

### Bug Fixes

* crash on launch on a new install (closes [#928](https://github.com/lwouis/alt-tab-macos/issues/928)) ([bed3351](https://github.com/lwouis/alt-tab-macos/commit/bed3351))
2021-04-19 14:17:16 +00:00
Louis Pontoise bed335132b fix: crash on launch on a new install (closes #928) 2021-04-19 22:33:48 +09:00
semantic-release-bot 6734379500 chore(release): 6.21.0 [skip ci]
# [6.21.0](https://github.com/lwouis/alt-tab-macos/compare/v6.20.0...v6.21.0) (2021-04-17)

### Bug Fixes

* apps could steal key focus from alt-tab main window ([#719](https://github.com/lwouis/alt-tab-macos/issues/719) [#916](https://github.com/lwouis/alt-tab-macos/issues/916)) ([6be72f3](https://github.com/lwouis/alt-tab-macos/commit/6be72f3))

### Features

* update korean location ([c1fc40d](https://github.com/lwouis/alt-tab-macos/commit/c1fc40d))
2021-04-17 11:27:38 +00:00
Louis Pontoise c1fc40d523 feat: update korean location 2021-04-17 20:07:30 +09:00
Louis Pontoise 6be72f36d7 fix: apps could steal key focus from alt-tab main window (#719 #916)
(closes #719, closes #916)
2021-04-17 20:07:30 +09:00
semantic-release-bot 682cd1ea8b chore(release): 6.20.0 [skip ci]
# [6.20.0](https://github.com/lwouis/alt-tab-macos/compare/v6.19.0...v6.20.0) (2021-04-15)

### Bug Fixes

* broken preferences window toolbar on macos 11 (closes [#914](https://github.com/lwouis/alt-tab-macos/issues/914)) ([1539030](https://github.com/lwouis/alt-tab-macos/commit/1539030))

### Features

* update contributors ([9847038](https://github.com/lwouis/alt-tab-macos/commit/9847038))
2021-04-15 10:44:16 +00:00
Louis Pontoise 9847038f26 feat: update contributors 2021-04-15 19:25:05 +09:00
Louis Pontoise 1539030469 fix: broken preferences window toolbar on macos 11 (closes #914) 2021-04-15 19:25:05 +09:00
semantic-release-bot 4e57c13a7e chore(release): 6.19.0 [skip ci]
# [6.19.0](https://github.com/lwouis/alt-tab-macos/compare/v6.18.1...v6.19.0) (2021-04-14)

### Bug Fixes

* correct Wikipedia link ([5a41561](https://github.com/lwouis/alt-tab-macos/commit/5a41561))
* intellij fullscreen windows sometimes not showing ([#824](https://github.com/lwouis/alt-tab-macos/issues/824)) ([4dcb6bb](https://github.com/lwouis/alt-tab-macos/commit/4dcb6bb))
* rare crash when the ui was kept open during space transition ([e869900](https://github.com/lwouis/alt-tab-macos/commit/e869900))

### Features

* added NICE DCV to the don't show list ([3a98628](https://github.com/lwouis/alt-tab-macos/commit/3a98628))
* update german, russian, swedish localization ([6f1a27a](https://github.com/lwouis/alt-tab-macos/commit/6f1a27a))
* update korean, polish, and brazilian localizations ([5bc8f82](https://github.com/lwouis/alt-tab-macos/commit/5bc8f82))
2021-04-14 07:50:00 +00:00
Louis Pontoise 5bc8f82015 feat: update korean, polish, and brazilian localizations 2021-04-14 16:33:40 +09:00
Hugh Lilly 5a41561261 fix: correct Wikipedia link 2021-04-14 16:33:40 +09:00
Marco Mastropaolo 3a9862899a feat: added NICE DCV to the don't show list 2021-04-14 16:33:40 +09:00
Louis Pontoise 6e4eb295dc docs: fix discord link 2021-04-14 16:33:40 +09:00
Louis Pontoise 96904ee917 ci: bump macos/xcode to match local dev env better 2021-04-02 18:12:51 +09:00
Ali Karbassi 01683af8ef docs: update homebrew instructions for newer versions 2021-04-02 18:10:01 +09:00
Louis Pontoise 6f1a27a84d feat: update german, russian, swedish localization 2021-04-02 02:06:49 +09:00
Louis Pontoise 4dcb6bbbc0 fix: intellij fullscreen windows sometimes not showing (#824) 2021-04-02 02:06:49 +09:00
Louis Pontoise e86990065d fix: rare crash when the ui was kept open during space transition 2021-04-01 01:06:41 +09:00
semantic-release-bot 4ee7d22dc0 chore(release): 6.18.1 [skip ci]
## [6.18.1](https://github.com/lwouis/alt-tab-macos/compare/v6.18.0...v6.18.1) (2021-03-13)

### Bug Fixes

* force new release ([1a098af](https://github.com/lwouis/alt-tab-macos/commit/1a098af))
2021-03-13 15:44:27 +00:00
Louis Pontoise 1a098afc9f fix: force new release 2021-03-14 00:28:19 +09:00
semantic-release-bot a7f353c8d6 chore(release): 6.18.0 [skip ci]
# [6.18.0](https://github.com/lwouis/alt-tab-macos/compare/v6.17.0...v6.18.0) (2021-03-13)

### Bug Fixes

* more robust handling of custom shortcuts ([339aeaa](https://github.com/lwouis/alt-tab-macos/commit/339aeaa))
* windows launched already fullscreen sometimes didn't show ([#824](https://github.com/lwouis/alt-tab-macos/issues/824)) ([62b43f2](https://github.com/lwouis/alt-tab-macos/commit/62b43f2))

### Features

* avoid disabling native command-tab (closes [#834](https://github.com/lwouis/alt-tab-macos/issues/834)) ([fb51c5d](https://github.com/lwouis/alt-tab-macos/commit/fb51c5d))
* update contributors list ([5c7aa38](https://github.com/lwouis/alt-tab-macos/commit/5c7aa38))
2021-03-13 15:08:03 +00:00
Louis Pontoise 5c7aa38312 feat: update contributors list 2021-03-13 23:52:42 +09:00
Louis Pontoise 339aeaabe6 fix: more robust handling of custom shortcuts
* user was able to set a nextWindowShortcut which contained modifiers from holdShortcut
* detection of conflicts was incorrect in some cases, mostly because holdShortcut and nextWindowShortcut should be treated as 1 shortcut
* after the user forces a shortcut to apply, resetting the existing one with the same keys, it wouldn't save to UserDefaults
* forcing the holdShortcut to replace another holdShortcut would reset it, even though holdShortcut should always be set with some value
2021-03-13 23:52:42 +09:00
Louis Pontoise 62b43f21d6 fix: windows launched already fullscreen sometimes didn't show (#824)
closes #824
2021-03-13 23:52:42 +09:00
Louis Pontoise 5971642aa4 refactor: make method static 2021-03-13 23:52:42 +09:00
Louis Pontoise fb51c5d14b feat: avoid disabling native command-tab (closes #834) 2021-03-13 23:52:42 +09:00
semantic-release-bot 5390e411cc chore(release): 6.17.0 [skip ci]
# [6.17.0](https://github.com/lwouis/alt-tab-macos/compare/v6.16.0...v6.17.0) (2021-02-26)

### Features

* space number start at 1 instead of 0 ([#838](https://github.com/lwouis/alt-tab-macos/issues/838)) ([200dafa](https://github.com/lwouis/alt-tab-macos/commit/200dafa))
2021-02-26 03:03:47 +00:00
Louis Pontoise 200dafa24a feat: space number start at 1 instead of 0 (#838) 2021-02-26 11:47:58 +09:00
Louis Pontoise 2a36f89345 refactor: add more details in feedback report 2021-02-26 11:47:58 +09:00
semantic-release-bot f866f42d81 chore(release): 6.16.0 [skip ci]
# [6.16.0](https://github.com/lwouis/alt-tab-macos/compare/v6.15.3...v6.16.0) (2021-02-24)

### Features

* remove unused localized text ([e7ef15b](https://github.com/lwouis/alt-tab-macos/commit/e7ef15b))
* tell users about conflicting shortcuts (close [#832](https://github.com/lwouis/alt-tab-macos/issues/832)) ([b345648](https://github.com/lwouis/alt-tab-macos/commit/b345648))
2021-02-24 17:24:08 +00:00
Louis Pontoise e7ef15bc64 feat: remove unused localized text 2021-02-25 02:05:10 +09:00
Louis Pontoise b3456481ae feat: tell users about conflicting shortcuts (close #832) 2021-02-25 02:05:10 +09:00
semantic-release-bot 914f55af9f chore(release): 6.15.3 [skip ci]
## [6.15.3](https://github.com/lwouis/alt-tab-macos/compare/v6.15.2...v6.15.3) (2021-02-23)

### Bug Fixes

* better permission revocation detection ([f6d75fb](https://github.com/lwouis/alt-tab-macos/commit/f6d75fb))
2021-02-23 16:33:54 +00:00
Louis Pontoise f6d75fb8ff fix: better permission revocation detection 2021-02-24 01:14:51 +09:00
semantic-release-bot 599852d5a1 chore(release): 6.15.2 [skip ci]
## [6.15.2](https://github.com/lwouis/alt-tab-macos/compare/v6.15.1...v6.15.2) (2021-02-23)

### Bug Fixes

* avoid restarting alt-tab in some rare scenarios ([#825](https://github.com/lwouis/alt-tab-macos/issues/825)) ([4003df4](https://github.com/lwouis/alt-tab-macos/commit/4003df4))
* show windows of apps launched hidden ([#390](https://github.com/lwouis/alt-tab-macos/issues/390)) ([eb5d019](https://github.com/lwouis/alt-tab-macos/commit/eb5d019))
2021-02-23 14:57:54 +00:00
Louis Pontoise eb5d0196ba fix: show windows of apps launched hidden (#390) 2021-02-23 23:41:59 +09:00
Louis Pontoise 4003df41e1 fix: avoid restarting alt-tab in some rare scenarios (#825) 2021-02-23 23:41:59 +09:00
semantic-release-bot 58025aff52 chore(release): 6.15.1 [skip ci]
## [6.15.1](https://github.com/lwouis/alt-tab-macos/compare/v6.15.0...v6.15.1) (2021-02-16)

### Bug Fixes

* didn't show skim app windows (closes [#772](https://github.com/lwouis/alt-tab-macos/issues/772)) ([fed2eb6](https://github.com/lwouis/alt-tab-macos/commit/fed2eb6))
* issues with the app mediathekview (closes [#822](https://github.com/lwouis/alt-tab-macos/issues/822)) ([0181547](https://github.com/lwouis/alt-tab-macos/commit/0181547))
* live2d cubism editor stuck on startup (closes [#813](https://github.com/lwouis/alt-tab-macos/issues/813)) ([ee5c44f](https://github.com/lwouis/alt-tab-macos/commit/ee5c44f))
2021-02-16 06:25:00 +00:00
Louis Pontoise d535de6cd1 ci: only build master branch 2021-02-16 15:08:27 +09:00
Louis Pontoise 0181547ae8 fix: issues with the app mediathekview (closes #822) 2021-02-16 15:08:27 +09:00
Louis Pontoise ee5c44fd96 fix: live2d cubism editor stuck on startup (closes #813) 2021-02-16 15:08:27 +09:00
Louis Pontoise fed2eb63e0 fix: didn't show skim app windows (closes #772) 2021-02-16 15:08:27 +09:00
Louis Pontoise c3af30a721 refactor: remove unnecessary entitlement 2021-02-16 15:08:27 +09:00
semantic-release-bot 21f1a9c02e chore(release): 6.15.0 [skip ci]
# [6.15.0](https://github.com/lwouis/alt-tab-macos/compare/v6.14.0...v6.15.0) (2021-02-02)

### Bug Fixes

* show vlc fullscreen video (closes [#792](https://github.com/lwouis/alt-tab-macos/issues/792)) ([e675fab](https://github.com/lwouis/alt-tab-macos/commit/e675fab))

### Features

* update russian localization ([909c123](https://github.com/lwouis/alt-tab-macos/commit/909c123))
2021-02-02 07:27:15 +00:00
Louis Pontoise 909c123122 feat: update russian localization 2021-02-02 16:08:39 +09:00
Louis Pontoise e675fab31c fix: show vlc fullscreen video (closes #792) 2021-02-02 16:08:39 +09:00
semantic-release-bot 8d3063adfd chore(release): 6.14.0 [skip ci]
# [6.14.0](https://github.com/lwouis/alt-tab-macos/compare/v6.13.0...v6.14.0) (2021-02-01)

### Bug Fixes

* crash in very rare data-race ([e9e61af](https://github.com/lwouis/alt-tab-macos/commit/e9e61af)), closes [#1](https://github.com/lwouis/alt-tab-macos/issues/1)
* didn't show windows on same screen (closes [#794](https://github.com/lwouis/alt-tab-macos/issues/794)) ([b02e8be](https://github.com/lwouis/alt-tab-macos/commit/b02e8be))

### Features

* update korean, portuguese, swedish localizations ([81a33b8](https://github.com/lwouis/alt-tab-macos/commit/81a33b8))
2021-02-01 17:11:44 +00:00
Louis Pontoise 81a33b85d7 feat: update korean, portuguese, swedish localizations
also update contributors
2021-02-02 01:55:26 +09:00
Louis Pontoise e9e61afc6a fix: crash in very rare data-race
Most common crash in AppCenter for v6.12.0:
closure #1 () -> () in static AltTab.Windows.refreshThumbnailsAsync(__C.NSScreen, Swift.Int) -> ()
2021-02-02 01:55:26 +09:00
Louis Pontoise b02e8be802 fix: didn't show windows on same screen (closes #794) 2021-02-02 01:55:26 +09:00
semantic-release-bot 0e4987da94 chore(release): 6.13.0 [skip ci]
# [6.13.0](https://github.com/lwouis/alt-tab-macos/compare/v6.12.0...v6.13.0) (2021-01-25)

### Bug Fixes

* app would sometimes quit while in the background (closes [#704](https://github.com/lwouis/alt-tab-macos/issues/704)) ([d621ce5](https://github.com/lwouis/alt-tab-macos/commit/d621ce5))
* disable standard tab detection for all JetBrains apps ([25343ea](https://github.com/lwouis/alt-tab-macos/commit/25343ea)), closes [#716](https://github.com/lwouis/alt-tab-macos/issues/716)
* prevent macos 11 from terminating alt-tab randomly ([2447140](https://github.com/lwouis/alt-tab-macos/commit/2447140))
* restarting the app would sometimes fail to start again ([56d47fc](https://github.com/lwouis/alt-tab-macos/commit/56d47fc))
* show window controls, even when mouse hover option is disabled ([c256933](https://github.com/lwouis/alt-tab-macos/commit/c256933))

### Features

* add app category meta-data ([96572a8](https://github.com/lwouis/alt-tab-macos/commit/96572a8))
* add swedish and czech localizations ([00e95d6](https://github.com/lwouis/alt-tab-macos/commit/00e95d6))
* add ukrainian localization ([e576ca1](https://github.com/lwouis/alt-tab-macos/commit/e576ca1))
* display windows partially on screen correctly (closes [#727](https://github.com/lwouis/alt-tab-macos/issues/727)) ([2f92936](https://github.com/lwouis/alt-tab-macos/commit/2f92936))
* show window partially on-screen (closes [#727](https://github.com/lwouis/alt-tab-macos/issues/727)) ([b121162](https://github.com/lwouis/alt-tab-macos/commit/b121162))
* update japanese, turkish, chinese localizations ([7226c25](https://github.com/lwouis/alt-tab-macos/commit/7226c25))
2021-01-25 15:18:20 +00:00
Louis Pontoise d621ce5c50 fix: app would sometimes quit while in the background (closes #704) 2021-01-26 00:01:55 +09:00
Louis Pontoise 56d47fc61c fix: restarting the app would sometimes fail to start again 2021-01-26 00:01:55 +09:00
Louis Pontoise 96572a8008 feat: add app category meta-data 2021-01-26 00:01:55 +09:00
Louis Pontoise 9eda3ee9b1 chore: remove debug logs 2021-01-26 00:01:55 +09:00
Louis Pontoise 00e95d6825 feat: add swedish and czech localizations 2021-01-26 00:01:55 +09:00
Aarni Koskela f67406ff05 chore(ci): ensure l10n projects exist 2021-01-26 00:01:55 +09:00
Aarni Koskela 25343ea177 fix: disable standard tab detection for all JetBrains apps
Not just EAPs; those EAPs have been promoted into standard apps.

Should fix #716
2021-01-26 00:01:55 +09:00
Louis Pontoise e576ca1298 feat: add ukrainian localization 2021-01-26 00:01:55 +09:00
Louis Pontoise 2f92936848 feat: display windows partially on screen correctly (closes #727) 2021-01-26 00:01:55 +09:00
Louis Pontoise 2447140146 fix: prevent macos 11 from terminating alt-tab randomly 2021-01-26 00:01:55 +09:00
Sam Denty c2569336ca fix: show window controls, even when mouse hover option is disabled 2021-01-26 00:01:55 +09:00
Louis Pontoise 7226c25ed7 feat: update japanese, turkish, chinese localizations 2021-01-26 00:01:55 +09:00
Louis Pontoise b121162134 feat: show window partially on-screen (closes #727) 2021-01-26 00:01:55 +09:00
semantic-release-bot b8ad95cdf4 chore(release): 6.12.0 [skip ci]
# [6.12.0](https://github.com/lwouis/alt-tab-macos/compare/v6.11.0...v6.12.0) (2020-11-17)

### Bug Fixes

* window was not shown after closing tab (closes [#696](https://github.com/lwouis/alt-tab-macos/issues/696)) ([a7e96f2](https://github.com/lwouis/alt-tab-macos/commit/a7e96f2))

### Features

* add slovak localization ([06027dc](https://github.com/lwouis/alt-tab-macos/commit/06027dc))
2020-11-17 16:51:42 +00:00
Louis Pontoise 06027dc193 feat: add slovak localization 2020-11-18 01:29:44 +09:00
Louis Pontoise a7e96f2621 fix: window was not shown after closing tab (closes #696) 2020-11-18 01:29:44 +09:00
semantic-release-bot 4676758d7f chore(release): 6.11.0 [skip ci]
# [6.11.0](https://github.com/lwouis/alt-tab-macos/compare/v6.10.0...v6.11.0) (2020-11-11)

### Bug Fixes

* some windows would not be shown in fullscreen app (closes [#688](https://github.com/lwouis/alt-tab-macos/issues/688)) ([5f9caed](https://github.com/lwouis/alt-tab-macos/commit/5f9caed))

### Features

* add preference to show visible spaces (closes [#583](https://github.com/lwouis/alt-tab-macos/issues/583)) ([545437e](https://github.com/lwouis/alt-tab-macos/commit/545437e))
* added slovenian localization ([8b22d41](https://github.com/lwouis/alt-tab-macos/commit/8b22d41))
2020-11-11 15:48:44 +00:00
Louis Pontoise 5f9caed280 fix: some windows would not be shown in fullscreen app (closes #688) 2020-11-12 00:30:27 +09:00
Louis Pontoise 8b22d4128e feat: added slovenian localization 2020-11-12 00:30:27 +09:00
Louis Pontoise 545437e43e feat: add preference to show visible spaces (closes #583) 2020-11-12 00:30:27 +09:00
semantic-release-bot d021be1336 chore(release): 6.10.0 [skip ci]
# [6.10.0](https://github.com/lwouis/alt-tab-macos/compare/v6.9.0...v6.10.0) (2020-11-09)

### Bug Fixes

* some apps were not showing (closes [#677](https://github.com/lwouis/alt-tab-macos/issues/677), closes [#679](https://github.com/lwouis/alt-tab-macos/issues/679)) ([e0fa680](https://github.com/lwouis/alt-tab-macos/commit/e0fa680))

### Features

* improve french, hungarian and polish localizations ([bf21a4e](https://github.com/lwouis/alt-tab-macos/commit/bf21a4e))
2020-11-09 17:36:59 +00:00
Louis Pontoise bf21a4edce feat: improve french, hungarian and polish localizations 2020-11-10 02:19:20 +09:00
Louis Pontoise e0fa68036e fix: some apps were not showing (closes #677, closes #679) 2020-11-10 02:19:20 +09:00
semantic-release-bot cde1adc664 chore(release): 6.9.0 [skip ci]
# [6.9.0](https://github.com/lwouis/alt-tab-macos/compare/v6.8.0...v6.9.0) (2020-10-27)

### Features

* don't show glitchy windows from non-native apps (closes [#562](https://github.com/lwouis/alt-tab-macos/issues/562)) ([84dbaa0](https://github.com/lwouis/alt-tab-macos/commit/84dbaa0)), closes [#456](https://github.com/lwouis/alt-tab-macos/issues/456)
* update chinese localization ([9240040](https://github.com/lwouis/alt-tab-macos/commit/9240040))
* update french localization ([e9a6f54](https://github.com/lwouis/alt-tab-macos/commit/e9a6f54))
2020-10-27 14:00:15 +00:00
Louis Pontoise 84dbaa06aa feat: don't show glitchy windows from non-native apps (closes #562)
See #456
2020-10-27 22:42:49 +09:00
Louis Pontoise 9240040ae6 feat: update chinese localization 2020-10-27 22:42:49 +09:00
Louis Pontoise e9a6f54355 feat: update french localization 2020-10-27 14:17:45 +09:00
semantic-release-bot e4f2c4b140 chore(release): 6.8.0 [skip ci]
# [6.8.0](https://github.com/lwouis/alt-tab-macos/compare/v6.7.4...v6.8.0) (2020-10-26)

### Bug Fixes

* rare crash at launch during permissions grant ([6120418](https://github.com/lwouis/alt-tab-macos/commit/6120418))

### Features

* update dutch localization ([8cf9954](https://github.com/lwouis/alt-tab-macos/commit/8cf9954))
2020-10-26 17:11:23 +00:00
Louis Pontoise 8cf9954a57 feat: update dutch localization 2020-10-27 01:44:59 +09:00
Louis Pontoise 8771fffe8d ci: trigger builds on all branches 2020-10-27 01:44:59 +09:00
Louis Pontoise 6120418d70 fix: rare crash at launch during permissions grant 2020-10-27 01:44:59 +09:00
semantic-release-bot 72b6250b36 chore(release): 6.7.4 [skip ci]
## [6.7.4](https://github.com/lwouis/alt-tab-macos/compare/v6.7.3...v6.7.4) (2020-10-15)

### Bug Fixes

* shortcuts temporarily stuck in intellij eap (closes [#652](https://github.com/lwouis/alt-tab-macos/issues/652)) ([7c171c2](https://github.com/lwouis/alt-tab-macos/commit/7c171c2))
* show the android emulator (closes [#653](https://github.com/lwouis/alt-tab-macos/issues/653)) ([16c7a93](https://github.com/lwouis/alt-tab-macos/commit/16c7a93))
2020-10-15 14:56:59 +00:00
Louis Pontoise 7c171c26cb fix: shortcuts temporarily stuck in intellij eap (closes #652) 2020-10-15 23:39:13 +09:00
Louis Pontoise 16c7a9319a fix: show the android emulator (closes #653) 2020-10-15 23:39:13 +09:00
semantic-release-bot d825efa1f1 chore(release): 6.7.3 [skip ci]
## [6.7.3](https://github.com/lwouis/alt-tab-macos/compare/v6.7.2...v6.7.3) (2020-10-10)

### Bug Fixes

* apparition delay preference would sometimes not be respected ([3019dd5](https://github.com/lwouis/alt-tab-macos/commit/3019dd5))
* ui would sometimes stay open (closes [#588](https://github.com/lwouis/alt-tab-macos/issues/588)) ([8912c70](https://github.com/lwouis/alt-tab-macos/commit/8912c70))
2020-10-10 04:55:37 +00:00
Louis Pontoise 8912c70bcd fix: ui would sometimes stay open (closes #588) 2020-10-10 13:39:17 +09:00
Louis Pontoise 3019dd58d7 fix: apparition delay preference would sometimes not be respected 2020-10-10 13:39:17 +09:00
semantic-release-bot c1a0b052af chore(release): 6.7.2 [skip ci]
## [6.7.2](https://github.com/lwouis/alt-tab-macos/compare/v6.7.1...v6.7.2) (2020-10-06)

### Bug Fixes

* crash in rare unknown scenario scenario ([08581f5](https://github.com/lwouis/alt-tab-macos/commit/08581f5))
* crash on blacklisted app with main shortcut cleared ([c3f0686](https://github.com/lwouis/alt-tab-macos/commit/c3f0686))
* ignore more non-user-facing apps (xpc processes) ([8417564](https://github.com/lwouis/alt-tab-macos/commit/8417564))
* key repeat rate was too fast on high fps monitors (closes [#633](https://github.com/lwouis/alt-tab-macos/issues/633)) ([b408f14](https://github.com/lwouis/alt-tab-macos/commit/b408f14))
* keynote was not showing while in slideshow mode (closes [#636](https://github.com/lwouis/alt-tab-macos/issues/636)) ([ec7b69f](https://github.com/lwouis/alt-tab-macos/commit/ec7b69f))
* space transition sometimes absorbed the shortcut (closes [#588](https://github.com/lwouis/alt-tab-macos/issues/588)) ([5e6a0c2](https://github.com/lwouis/alt-tab-macos/commit/5e6a0c2))
2020-10-06 17:29:26 +00:00
Louis Pontoise 08581f50c3 fix: crash in rare unknown scenario scenario 2020-10-07 02:10:30 +09:00
Louis Pontoise c3f0686fd1 fix: crash on blacklisted app with main shortcut cleared 2020-10-07 02:10:30 +09:00
Louis Pontoise 5d9bc8e6b7 docs: add new contributor 2020-10-07 02:10:30 +09:00
Louis Pontoise 5e6a0c2bb6 fix: space transition sometimes absorbed the shortcut (closes #588) 2020-10-07 02:10:30 +09:00
Louis Pontoise ec7b69f4fc fix: keynote was not showing while in slideshow mode (closes #636) 2020-10-07 02:10:30 +09:00
Louis Pontoise b408f14956 fix: key repeat rate was too fast on high fps monitors (closes #633) 2020-10-07 02:10:30 +09:00
Louis Pontoise 84175640f7 fix: ignore more non-user-facing apps (xpc processes) 2020-10-07 02:10:30 +09:00
Louis Pontoise cd0d53d6bc refactor: clean up comments from incorrect copy-pastes 2020-10-07 02:10:30 +09:00
semantic-release-bot 1e030c391b chore(release): 6.7.1 [skip ci]
## [6.7.1](https://github.com/lwouis/alt-tab-macos/compare/v6.7.0...v6.7.1) (2020-09-27)

### Bug Fixes

* crashes when some shortcuts was set to nothing ([9b3e4b1](https://github.com/lwouis/alt-tab-macos/commit/9b3e4b1))
2020-09-27 17:08:24 +00:00
Louis Pontoise 9b3e4b180d fix: crashes when some shortcuts was set to nothing 2020-09-28 01:50:58 +09:00
semantic-release-bot 484411040d chore(release): 6.7.0 [skip ci]
# [6.7.0](https://github.com/lwouis/alt-tab-macos/compare/v6.6.0...v6.7.0) (2020-09-25)

### Bug Fixes

* cpu usage higher than normal for 2min after quitting an app ([2f4c56c](https://github.com/lwouis/alt-tab-macos/commit/2f4c56c))
* crash on launch in some rare scenarios (closes [#615](https://github.com/lwouis/alt-tab-macos/issues/615)) ([5d4b2b0](https://github.com/lwouis/alt-tab-macos/commit/5d4b2b0))

### Features

* make shortcuts repeat when held down (closes [#556](https://github.com/lwouis/alt-tab-macos/issues/556)) ([6803b02](https://github.com/lwouis/alt-tab-macos/commit/6803b02))
* show openboard window ([#621](https://github.com/lwouis/alt-tab-macos/issues/621)) ([5b35601](https://github.com/lwouis/alt-tab-macos/commit/5b35601))
* update japanese and portuguese (brazil) localizations ([85638df](https://github.com/lwouis/alt-tab-macos/commit/85638df))
* update russian localization ([40ef009](https://github.com/lwouis/alt-tab-macos/commit/40ef009))
2020-09-25 10:30:52 +00:00
Louis Pontoise 85638dfcc5 feat: update japanese and portuguese (brazil) localizations 2020-09-25 19:15:15 +09:00
Louis Pontoise 5b3560121a feat: show openboard window (#621) 2020-09-25 19:15:15 +09:00
Louis Pontoise 2f4c56c9dd fix: cpu usage higher than normal for 2min after quitting an app 2020-09-25 19:15:15 +09:00
Louis Pontoise 40ef0091b7 feat: update russian localization 2020-09-25 19:15:15 +09:00
Louis Pontoise 5d4b2b0a40 fix: crash on launch in some rare scenarios (closes #615) 2020-09-25 19:15:15 +09:00
Louis Pontoise 6803b0232e feat: make shortcuts repeat when held down (closes #556) 2020-09-25 19:15:15 +09:00
semantic-release-bot fca2d1282b chore(release): 6.6.0 [skip ci]
# [6.6.0](https://github.com/lwouis/alt-tab-macos/compare/v6.5.0...v6.6.0) (2020-09-14)

### Bug Fixes

* app would sometimes crash at launch (closes [#607](https://github.com/lwouis/alt-tab-macos/issues/607)) ([7288013](https://github.com/lwouis/alt-tab-macos/commit/7288013))

### Features

* update japanese localization ([473e08f](https://github.com/lwouis/alt-tab-macos/commit/473e08f))
2020-09-14 13:29:06 +00:00
Louis Pontoise 7288013691 fix: app would sometimes crash at launch (closes #607) 2020-09-14 22:11:20 +09:00
Louis Pontoise 473e08fd01 feat: update japanese localization 2020-09-14 22:11:20 +09:00
semantic-release-bot b9aa35a9af chore(release): 6.5.0 [skip ci]
# [6.5.0](https://github.com/lwouis/alt-tab-macos/compare/v6.4.0...v6.5.0) (2020-09-09)

### Bug Fixes

* ui would take time to display sometimes (see [#563](https://github.com/lwouis/alt-tab-macos/issues/563)) ([7efc806](https://github.com/lwouis/alt-tab-macos/commit/7efc806))

### Features

* update russian and dutch localizations ([eaa0cc9](https://github.com/lwouis/alt-tab-macos/commit/eaa0cc9))
2020-09-09 15:05:15 +00:00
Louis Pontoise eaa0cc9688 feat: update russian and dutch localizations 2020-09-09 23:44:16 +09:00
Louis Pontoise 7efc806a89 fix: ui would take time to display sometimes (see #563) 2020-09-09 23:44:16 +09:00
semantic-release-bot d61739996f chore(release): 6.4.0 [skip ci]
# [6.4.0](https://github.com/lwouis/alt-tab-macos/compare/v6.3.0...v6.4.0) (2020-09-08)

### Features

* update chinese, korean, and german localizations ([1514eca](https://github.com/lwouis/alt-tab-macos/commit/1514eca))

### Performance Improvements

* guaranty app nap is not interfering ([4895ee7](https://github.com/lwouis/alt-tab-macos/commit/4895ee7))
* prevent random freezes of the ui ([#563](https://github.com/lwouis/alt-tab-macos/issues/563)) ([e208da9](https://github.com/lwouis/alt-tab-macos/commit/e208da9))
2020-09-08 16:06:17 +00:00
Louis Pontoise 1514eca893 feat: update chinese, korean, and german localizations 2020-09-09 00:42:47 +09:00
Louis Pontoise 4895ee797f perf: guaranty app nap is not interfering 2020-09-08 23:29:32 +09:00
Louis Pontoise e208da91da perf: prevent random freezes of the ui (#563)
timers were on the main thread, creating indeterministic freezes
2020-09-08 23:29:32 +09:00
semantic-release-bot 7b304903ee chore(release): 6.3.0 [skip ci]
# [6.3.0](https://github.com/lwouis/alt-tab-macos/compare/v6.2.0...v6.3.0) (2020-09-08)

### Bug Fixes

* adobe audition windows were not showing up (closes [#581](https://github.com/lwouis/alt-tab-macos/issues/581)) ([6edced0](https://github.com/lwouis/alt-tab-macos/commit/6edced0))
* crash from appcenter in rare scenario ([c49a2bc](https://github.com/lwouis/alt-tab-macos/commit/c49a2bc)), closes [#1](https://github.com/lwouis/alt-tab-macos/issues/1)
* load app badges asynchronously to avoid system lag (closes [#563](https://github.com/lwouis/alt-tab-macos/issues/563)) ([29eff03](https://github.com/lwouis/alt-tab-macos/commit/29eff03))
* prevent rare crash seen in app center ([6ca58b1](https://github.com/lwouis/alt-tab-macos/commit/6ca58b1))

### Features

* show minimized/hidden windows last in the list (closes [#289](https://github.com/lwouis/alt-tab-macos/issues/289)) ([4fea943](https://github.com/lwouis/alt-tab-macos/commit/4fea943))
* split max screen size preference into width/height (closes [#579](https://github.com/lwouis/alt-tab-macos/issues/579)) ([6e2e5b4](https://github.com/lwouis/alt-tab-macos/commit/6e2e5b4))
* update es, ja, ko, nl, pt, pt-br localizations ([af5ed9b](https://github.com/lwouis/alt-tab-macos/commit/af5ed9b))
2020-09-08 11:02:03 +00:00
Louis Pontoise c49a2bcd4b fix: crash from appcenter in rare scenario
Stack trace:

closure #1 () -> () in AltTab.(windowDestroyed in _3E1A2D100A6A10BAACF80B17AC9C41B5)(__C.AXUIElementRef) throws -> () Windows.swift:43
reabstraction thunk helper from @escaping @callee_guaranteed () -> () to @escaping @callee_unowned @convention(block) () -> () <compiler-generated>:0
2020-09-08 19:44:35 +09:00
Louis Pontoise 6edced005a fix: adobe audition windows were not showing up (closes #581) 2020-09-08 19:44:35 +09:00
Louis Pontoise 29eff03e70 fix: load app badges asynchronously to avoid system lag (closes #563) 2020-09-08 19:44:35 +09:00
Louis Pontoise 4fea9431cd feat: show minimized/hidden windows last in the list (closes #289) 2020-09-08 19:44:35 +09:00
Louis Pontoise 79989a1dad refactor: increase perf warning value to reduce noise 2020-09-08 19:44:35 +09:00
Louis Pontoise 6e2e5b47fc feat: split max screen size preference into width/height (closes #579) 2020-09-08 19:44:35 +09:00
Louis Pontoise af5ed9b213 feat: update es, ja, ko, nl, pt, pt-br localizations 2020-09-08 19:44:35 +09:00
Louis Pontoise 6ca58b1ddb fix: prevent rare crash seen in app center
Stacktrace:

function signature specialization <Arg[1] = Dead> of generic specialization <[__C.AXUIElementRef]> of (extension in AltTab):__C.AXUIElementRef.attribute<A>(Swift.String, A.Type) throws -> A? AXUIElement.swift:36
2020-09-08 19:44:35 +09:00
semantic-release-bot 6ed97c4542 chore(release): 6.2.0 [skip ci]
# [6.2.0](https://github.com/lwouis/alt-tab-macos/compare/v6.1.0...v6.2.0) (2020-09-04)

### Bug Fixes

* apps would not quit properly sometimes (regression from 10b2c71) ([41384d9](https://github.com/lwouis/alt-tab-macos/commit/41384d9))
* avoid random delay after releasing shortcut (closes [#563](https://github.com/lwouis/alt-tab-macos/issues/563)) ([cbc4c39](https://github.com/lwouis/alt-tab-macos/commit/cbc4c39))
* crash on launch if the user didn't have sf symbols font ([58e9026](https://github.com/lwouis/alt-tab-macos/commit/58e9026))
* focused wrong window in rare scenario ([66820a1](https://github.com/lwouis/alt-tab-macos/commit/66820a1))
* issue when selecting windowless app from fullscreen window ([657c9e5](https://github.com/lwouis/alt-tab-macos/commit/657c9e5))
* smoother behavior when summoned during a space transition ([e6ded6c](https://github.com/lwouis/alt-tab-macos/commit/e6ded6c))
* thumbnail sizes could be wrong when switching between screens ([e13a263](https://github.com/lwouis/alt-tab-macos/commit/e13a263))
* triggering alt-tab during space transition failed (closes [#566](https://github.com/lwouis/alt-tab-macos/issues/566)) ([d66d788](https://github.com/lwouis/alt-tab-macos/commit/d66d788))
* windowless apps would rarely show despite the blacklist ([355225b](https://github.com/lwouis/alt-tab-macos/commit/355225b))
* workaround a quick in photoshop (closes [#571](https://github.com/lwouis/alt-tab-macos/issues/571)) ([7218418](https://github.com/lwouis/alt-tab-macos/commit/7218418))

### Features

* allow per-shortcut release action preference (closes [#573](https://github.com/lwouis/alt-tab-macos/issues/573)) ([2a9c33b](https://github.com/lwouis/alt-tab-macos/commit/2a9c33b))
* first blacklist can now match prefixes instead of full ids ([10693d0](https://github.com/lwouis/alt-tab-macos/commit/10693d0))
* new preference to hide thumbnails (closes [#384](https://github.com/lwouis/alt-tab-macos/issues/384)) ([877c93c](https://github.com/lwouis/alt-tab-macos/commit/877c93c))
* show about item in menubar menu (closes [#574](https://github.com/lwouis/alt-tab-macos/issues/574)) ([78d1d8f](https://github.com/lwouis/alt-tab-macos/commit/78d1d8f))
* show apps with no open window (closes [#397](https://github.com/lwouis/alt-tab-macos/issues/397)) ([f0fa02c](https://github.com/lwouis/alt-tab-macos/commit/f0fa02c))
* update fi, hu, nl, pl, ru, zn-tw localizations ([df3010a](https://github.com/lwouis/alt-tab-macos/commit/df3010a))
* update japanese and korean localizations ([2a2368d](https://github.com/lwouis/alt-tab-macos/commit/2a2368d))

### Performance Improvements

* add preferences cache to reduce app latency by a few ms ([17863b5](https://github.com/lwouis/alt-tab-macos/commit/17863b5))
* menubar takes a few frame less to compute ([3b7350f](https://github.com/lwouis/alt-tab-macos/commit/3b7350f))
* reduce image assets size even further using optimage ([63d8545](https://github.com/lwouis/alt-tab-macos/commit/63d8545))
2020-09-04 19:19:00 +00:00
Louis Pontoise 355225badb fix: windowless apps would rarely show despite the blacklist 2020-09-05 04:01:32 +09:00
Louis Pontoise 2a9c33b078 feat: allow per-shortcut release action preference (closes #573) 2020-09-05 04:01:32 +09:00
Louis Pontoise 7218418f6d fix: workaround a quick in photoshop (closes #571) 2020-09-05 04:01:32 +09:00
Louis Pontoise 0c0c2d7f31 docs: update website screenshots 2020-09-05 04:01:32 +09:00
Louis Pontoise 3b7350f853 perf: menubar takes a few frame less to compute 2020-09-05 04:01:32 +09:00
Louis Pontoise cbc4c39aa5 fix: avoid random delay after releasing shortcut (closes #563) 2020-09-05 04:01:32 +09:00
Louis Pontoise 78d1d8f6fd feat: show about item in menubar menu (closes #574) 2020-09-05 04:01:32 +09:00
Louis Pontoise 2a2368d67b feat: update japanese and korean localizations 2020-09-05 04:01:32 +09:00
Louis Pontoise 17863b53a2 perf: add preferences cache to reduce app latency by a few ms 2020-09-05 04:01:32 +09:00
Louis Pontoise 10693d0346 feat: first blacklist can now match prefixes instead of full ids 2020-09-05 04:01:32 +09:00
Louis Pontoise e6ded6c79b fix: smoother behavior when summoned during a space transition 2020-09-05 04:01:32 +09:00
Louis Pontoise 66820a1e63 fix: focused wrong window in rare scenario 2020-09-05 04:01:32 +09:00
Louis Pontoise 63d85453b0 perf: reduce image assets size even further using optimage 2020-09-05 04:01:32 +09:00
Louis Pontoise d66d7887f5 fix: triggering alt-tab during space transition failed (closes #566) 2020-09-05 04:01:32 +09:00
Louis Pontoise 41384d9066 fix: apps would not quit properly sometimes (regression from 10b2c71) 2020-09-05 04:01:32 +09:00
Louis Pontoise 657c9e5e8b fix: issue when selecting windowless app from fullscreen window 2020-09-05 04:01:32 +09:00
Louis Pontoise 58e902600a fix: crash on launch if the user didn't have sf symbols font 2020-09-05 04:01:32 +09:00
Louis Pontoise 877c93c8a2 feat: new preference to hide thumbnails (closes #384) 2020-09-05 04:01:32 +09:00
Louis Pontoise df3010a3c8 feat: update fi, hu, nl, pl, ru, zn-tw localizations 2020-09-05 04:01:32 +09:00
Louis Pontoise f0fa02c4a2 feat: show apps with no open window (closes #397) 2020-09-05 04:01:32 +09:00
Louis Pontoise dc8b363e57 refactor: remove minor warnings 2020-09-05 04:01:32 +09:00
Louis Pontoise e13a263b08 fix: thumbnail sizes could be wrong when switching between screens 2020-09-05 04:01:32 +09:00
semantic-release-bot 6db893c4e7 chore(release): 6.1.0 [skip ci]
# [6.1.0](https://github.com/lwouis/alt-tab-macos/compare/v6.0.0...v6.1.0) (2020-08-31)

### Bug Fixes

* crash when user click a specific spot of shortcut ui (closes [#495](https://github.com/lwouis/alt-tab-macos/issues/495)) ([959a8ae](https://github.com/lwouis/alt-tab-macos/commit/959a8ae))
* focusing alt-tab own windows with alt-tab had jank (closes [#501](https://github.com/lwouis/alt-tab-macos/issues/501)) ([c927920](https://github.com/lwouis/alt-tab-macos/commit/c927920))
* some users have corrupted preferences, crashing on launch ([3062566](https://github.com/lwouis/alt-tab-macos/commit/3062566))

### Features

* add polish localization ([9fd25df](https://github.com/lwouis/alt-tab-macos/commit/9fd25df))
* update indonesian localization ([4ee875b](https://github.com/lwouis/alt-tab-macos/commit/4ee875b))

### Performance Improvements

* compress the 3 colored circle icons ([20e474b](https://github.com/lwouis/alt-tab-macos/commit/20e474b))
2020-08-31 06:09:59 +00:00
Louis Pontoise 4ee875bcd7 feat: update indonesian localization 2020-08-31 14:53:57 +09:00
Louis Pontoise 9fd25dfc0b feat: add polish localization 2020-08-31 14:41:16 +09:00
Louis Pontoise 959a8aea55 fix: crash when user click a specific spot of shortcut ui (closes #495) 2020-08-31 14:41:16 +09:00
Louis Pontoise c927920070 fix: focusing alt-tab own windows with alt-tab had jank (closes #501) 2020-08-31 14:41:16 +09:00
Louis Pontoise 30625662a2 fix: some users have corrupted preferences, crashing on launch 2020-08-31 14:41:16 +09:00
Louis Pontoise 20e474b6f5 perf: compress the 3 colored circle icons 2020-08-31 14:41:16 +09:00
semantic-release-bot aaa69c2d22 chore(release): 6.0.0 [skip ci]
# [6.0.0](https://github.com/lwouis/alt-tab-macos/compare/v5.3.0...v6.0.0) (2020-08-27)

### Bug Fixes

* alt-tab own windows were not shown in alt-tab (closes [#555](https://github.com/lwouis/alt-tab-macos/issues/555)) ([8bcbc04](https://github.com/lwouis/alt-tab-macos/commit/8bcbc04))
* clicking the main window would steal focus ([de02e5b](https://github.com/lwouis/alt-tab-macos/commit/de02e5b))
* display firefox develop edition fullscreen windows (closes [#558](https://github.com/lwouis/alt-tab-macos/issues/558)) ([3250d37](https://github.com/lwouis/alt-tab-macos/commit/3250d37))
* guarantee alt-tab window is always up-to-date on display ([be4c5f1](https://github.com/lwouis/alt-tab-macos/commit/be4c5f1))
* ignore zombie processes ([50c8c82](https://github.com/lwouis/alt-tab-macos/commit/50c8c82))
* moving some of the preferences sliders was very laggy ([a552c4c](https://github.com/lwouis/alt-tab-macos/commit/a552c4c))
* shortcuts stop working if active app is quit (closes [#557](https://github.com/lwouis/alt-tab-macos/issues/557)) ([023561d](https://github.com/lwouis/alt-tab-macos/commit/023561d))

### Features

* display quickly even with many open windows (closes [#171](https://github.com/lwouis/alt-tab-macos/issues/171)) ([da16a0b](https://github.com/lwouis/alt-tab-macos/commit/da16a0b))
* improve the 3 colored buttons when hovering (closes [#516](https://github.com/lwouis/alt-tab-macos/issues/516)) ([3ddedff](https://github.com/lwouis/alt-tab-macos/commit/3ddedff))
* update chinese localization ([e150a9a](https://github.com/lwouis/alt-tab-macos/commit/e150a9a))

### Performance Improvements

* alt-tab appears quicker when summoned ([c2bb896](https://github.com/lwouis/alt-tab-macos/commit/c2bb896))
* main window appears (a few frames) faster on trigger ([2bc09e6](https://github.com/lwouis/alt-tab-macos/commit/2bc09e6))

### BREAKING CHANGES

* the window thumbnails are now updated *after* the UI is shown. AltTab will first display its window, with the first 3 thumbnails up-to-date, then asynchronously update the rest of the thumbnails one-by-one. This improves the experience of users with lots of windows open.
2020-08-27 15:07:29 +00:00
Louis Pontoise af48951d09 docs: add new contributor 2020-08-27 23:49:54 +09:00
Louis Pontoise 3250d37557 fix: display firefox develop edition fullscreen windows (closes #558) 2020-08-27 22:44:40 +09:00
Louis Pontoise 20e9d1579d refactor: don't observe new windows before their app is ready 2020-08-27 22:44:40 +09:00
Louis Pontoise e150a9a4ed feat: update chinese localization 2020-08-27 22:44:40 +09:00
Louis Pontoise 50c8c82767 fix: ignore zombie processes 2020-08-27 22:44:40 +09:00
Louis Pontoise 023561d3aa fix: shortcuts stop working if active app is quit (closes #557) 2020-08-27 22:44:40 +09:00
Louis Pontoise a552c4c43a fix: moving some of the preferences sliders was very laggy 2020-08-27 22:44:40 +09:00
Louis Pontoise 8bcbc04164 fix: alt-tab own windows were not shown in alt-tab (closes #555) 2020-08-27 22:44:40 +09:00
Louis Pontoise be4c5f1903 fix: guarantee alt-tab window is always up-to-date on display 2020-08-27 22:44:40 +09:00
Louis Pontoise c2bb89625e perf: alt-tab appears quicker when summoned 2020-08-27 22:44:40 +09:00
Louis Pontoise de02e5b83f fix: clicking the main window would steal focus 2020-08-27 22:44:40 +09:00
Louis Pontoise 3ddedff978 feat: improve the 3 colored buttons when hovering (closes #516) 2020-08-27 22:44:40 +09:00
Louis Pontoise 790e8d9b05 refactor: bring colors closer to actual 2020-08-27 22:44:40 +09:00
Louis Pontoise bf34132618 refactor: re-organize icon resources 2020-08-27 22:44:40 +09:00
mindfulsource 29ad962bcc refactor: add window control icons
see https://github.com/lwouis/macos-traffic-light-buttons-as-SVG
2020-08-27 22:44:40 +09:00
Louis Pontoise da16a0b8f9 feat: display quickly even with many open windows (closes #171)
BREAKING CHANGE: the window thumbnails are now updated *after* the UI is shown. AltTab will first display its window, with the first 3 thumbnails up-to-date, then asynchronously update the rest of the thumbnails one-by-one. This improves the experience of users with lots of windows open.
2020-08-27 22:44:40 +09:00
Louis Pontoise 2bc09e64b2 perf: main window appears (a few frames) faster on trigger 2020-08-27 22:44:40 +09:00
semantic-release-bot bc16ca56f9 chore(release): 5.3.0 [skip ci]
# [5.3.0](https://github.com/lwouis/alt-tab-macos/compare/v5.2.0...v5.3.0) (2020-08-25)

### Bug Fixes

* app badges would sometimes not be up-to-date ([8ad03a5](https://github.com/lwouis/alt-tab-macos/commit/8ad03a5))
* rare crash when alt-tab is triggered when the dock isn't running ([9c02ceb](https://github.com/lwouis/alt-tab-macos/commit/9c02ceb))
* second blacklist was too tall on some systems ([522633b](https://github.com/lwouis/alt-tab-macos/commit/522633b))
* the ui would not hide if capslock was active (closes [#551](https://github.com/lwouis/alt-tab-macos/issues/551)) ([b4b82b2](https://github.com/lwouis/alt-tab-macos/commit/b4b82b2))

### Features

* add norwegian localization ([c344da7](https://github.com/lwouis/alt-tab-macos/commit/c344da7))
* blacklist mcafee safari host by default (closes [#386](https://github.com/lwouis/alt-tab-macos/issues/386)) ([a7ef4c7](https://github.com/lwouis/alt-tab-macos/commit/a7ef4c7))
2020-08-25 18:06:22 +00:00
Louis Pontoise 522633b2eb fix: second blacklist was too tall on some systems 2020-08-26 02:45:04 +09:00
Louis Pontoise c344da700b feat: add norwegian localization 2020-08-26 02:45:04 +09:00
Louis Pontoise b4b82b24c6 fix: the ui would not hide if capslock was active (closes #551) 2020-08-26 02:45:04 +09:00
Louis Pontoise 8ad03a5976 fix: app badges would sometimes not be up-to-date 2020-08-26 02:45:04 +09:00
Louis Pontoise a7ef4c7554 feat: blacklist mcafee safari host by default (closes #386) 2020-08-26 02:45:04 +09:00
Louis Pontoise 9c02cebdfc fix: rare crash when alt-tab is triggered when the dock isn't running 2020-08-26 02:45:04 +09:00
semantic-release-bot 1452602c44 chore(release): 5.2.0 [skip ci]
# [5.2.0](https://github.com/lwouis/alt-tab-macos/compare/v5.1.0...v5.2.0) (2020-08-24)

### Bug Fixes

* books.app windows were not always showing (closes [#481](https://github.com/lwouis/alt-tab-macos/issues/481)) ([9e92dfa](https://github.com/lwouis/alt-tab-macos/commit/9e92dfa))

### Features

* blacklisting apps can use start of the bundle id (closes [#549](https://github.com/lwouis/alt-tab-macos/issues/549)) ([de9cf46](https://github.com/lwouis/alt-tab-macos/commit/de9cf46))
* update french and portuguese localizations ([7a02ea5](https://github.com/lwouis/alt-tab-macos/commit/7a02ea5))

### Performance Improvements

* remove no-longer-used localization strings ([ce7836a](https://github.com/lwouis/alt-tab-macos/commit/ce7836a))
2020-08-24 17:16:17 +00:00
Louis Pontoise 9e92dfaefd fix: books.app windows were not always showing (closes #481) 2020-08-25 01:58:35 +09:00
Louis Pontoise ce7836a6f0 perf: remove no-longer-used localization strings 2020-08-25 01:58:35 +09:00
Louis Pontoise 7a02ea5be7 feat: update french and portuguese localizations 2020-08-25 01:58:35 +09:00
Louis Pontoise de9cf46746 feat: blacklisting apps can use start of the bundle id (closes #549)
Also handle Parallels better
2020-08-25 01:58:35 +09:00
semantic-release-bot 8399f845d6 chore(release): 5.1.0 [skip ci]
# [5.1.0](https://github.com/lwouis/alt-tab-macos/compare/v5.0.0...v5.1.0) (2020-08-20)

### Bug Fixes

* sometimes crashed when opening the preferences window (closes [#543](https://github.com/lwouis/alt-tab-macos/issues/543)) ([0f3c91a](https://github.com/lwouis/alt-tab-macos/commit/0f3c91a))

### Features

* update korean and portuguese localizations ([32ff753](https://github.com/lwouis/alt-tab-macos/commit/32ff753))

### Performance Improvements

* fix very small memory leaks ([8b7da21](https://github.com/lwouis/alt-tab-macos/commit/8b7da21))
2020-08-20 11:11:44 +00:00
Louis Pontoise 32ff753cbd feat: update korean and portuguese localizations 2020-08-20 19:55:56 +09:00
Louis Pontoise 0f3c91a182 fix: sometimes crashed when opening the preferences window (closes #543) 2020-08-20 19:55:56 +09:00
Louis Pontoise 8b7da216fb perf: fix very small memory leaks 2020-08-20 19:55:56 +09:00
Louis Pontoise c531e52650 docs: remove mention of preferences library 2020-08-20 19:55:56 +09:00
semantic-release-bot 034d490eed chore(release): 5.0.0 [skip ci]
# [5.0.0](https://github.com/lwouis/alt-tab-macos/compare/v4.19.0...v5.0.0) (2020-08-18)

### Bug Fixes

* app icon was not showing on macos 10.12 (see [#522](https://github.com/lwouis/alt-tab-macos/issues/522)) ([2a45dec](https://github.com/lwouis/alt-tab-macos/commit/2a45dec))
* battle.net installer and wow were not showing in alt-tab ([793b10b](https://github.com/lwouis/alt-tab-macos/commit/793b10b)), closes [#536](https://github.com/lwouis/alt-tab-macos/issues/536)
* portuguese from portugal was shown to brazil users ([e54c2de](https://github.com/lwouis/alt-tab-macos/commit/e54c2de))
* rare crash when the os was not providing the current space id ([cf05044](https://github.com/lwouis/alt-tab-macos/commit/cf05044))
* rewrote the preference window to fix crashes and jank (closes [#502](https://github.com/lwouis/alt-tab-macos/issues/502)) ([f9f5b8a](https://github.com/lwouis/alt-tab-macos/commit/f9f5b8a))

### Features

* change default key to select window from `return` to `space` ([eec694e](https://github.com/lwouis/alt-tab-macos/commit/eec694e))
* complete rewrite of the keyboard support (closes [#157](https://github.com/lwouis/alt-tab-macos/issues/157)) ([d3253ba](https://github.com/lwouis/alt-tab-macos/commit/d3253ba))
* show notification badges on top of app icons (closes [#523](https://github.com/lwouis/alt-tab-macos/issues/523)) ([fb62834](https://github.com/lwouis/alt-tab-macos/commit/fb62834))
* update portuguese (brazil) localization ([726acd3](https://github.com/lwouis/alt-tab-macos/commit/726acd3))
* updated japanese localization ([36c7b0a](https://github.com/lwouis/alt-tab-macos/commit/36c7b0a))

### BREAKING CHANGES

* the previous keyboard support implementation was not working if any app on the system activated Secure Input and didn't turn it off. This is a major hurdle for most global shortcut apps. This update introduces a new implementation which is unaffected by Secure Input. AltTab shortcuts should now work reliably
2020-08-18 14:53:04 +00:00
Louis Pontoise 36c7b0a1b9 feat: updated japanese localization 2020-08-18 23:35:13 +09:00
Louis Pontoise e54c2de7d8 fix: portuguese from portugal was shown to brazil users 2020-08-18 23:35:13 +09:00
Louis Pontoise 793b10b862 fix: battle.net installer and wow were not showing in alt-tab
(closes #536)
2020-08-18 23:35:13 +09:00
Louis Pontoise eec694eae2 feat: change default key to select window from return to space 2020-08-18 23:35:13 +09:00
Louis Pontoise f9f5b8ae7e fix: rewrote the preference window to fix crashes and jank (closes #502) 2020-08-18 23:35:13 +09:00
Louis Pontoise cf0504437b fix: rare crash when the os was not providing the current space id 2020-08-18 23:35:13 +09:00
Louis Pontoise 726acd35a4 feat: update portuguese (brazil) localization 2020-08-18 23:35:13 +09:00
Louis Pontoise fb628341d1 feat: show notification badges on top of app icons (closes #523) 2020-08-18 23:35:13 +09:00
Louis Pontoise d3253ba4e1 feat: complete rewrite of the keyboard support (closes #157)
BREAKING CHANGE: the previous keyboard support implementation was not working if any app on the system activated Secure Input and didn't turn it off. This is a major hurdle for most global shortcut apps. This update introduces a new implementation which is unaffected by Secure Input. AltTab shortcuts should now work reliably
2020-08-18 23:35:13 +09:00
Louis Pontoise 2a45dec92a fix: app icon was not showing on macos 10.12 (see #522) 2020-08-18 23:35:13 +09:00
semantic-release-bot ef83aa44f3 chore(release): 4.19.0 [skip ci]
# [4.19.0](https://github.com/lwouis/alt-tab-macos/compare/v4.18.0...v4.19.0) (2020-08-11)

### Bug Fixes

* checkboxes not showing properly on macos 10.13 (see [#507](https://github.com/lwouis/alt-tab-macos/issues/507)) ([43a9cb1](https://github.com/lwouis/alt-tab-macos/commit/43a9cb1))
* menubar icon not showing on macos 10.13 (closes [#507](https://github.com/lwouis/alt-tab-macos/issues/507)) ([2fa0b8a](https://github.com/lwouis/alt-tab-macos/commit/2fa0b8a))

### Features

* update portuguese (brazil) and chinese (simplified) localizations ([2b1b5fa](https://github.com/lwouis/alt-tab-macos/commit/2b1b5fa))
2020-08-11 16:41:23 +00:00
Louis Pontoise 2b1b5fac9a feat: update portuguese (brazil) and chinese (simplified) localizations 2020-08-12 01:18:52 +09:00
Louis Pontoise 43a9cb1644 fix: checkboxes not showing properly on macos 10.13 (see #507) 2020-08-12 01:18:52 +09:00
Louis Pontoise 2fa0b8ac52 fix: menubar icon not showing on macos 10.13 (closes #507) 2020-08-12 01:18:52 +09:00
Louis Pontoise 76dbdf03fe refactor: support portuguese 2020-08-12 01:18:52 +09:00
semantic-release-bot 49cca525bf chore(release): 4.18.0 [skip ci]
# [4.18.0](https://github.com/lwouis/alt-tab-macos/compare/v4.17.2...v4.18.0) (2020-08-11)

### Bug Fixes

* "no menubar icon" preference has correct height ([025053d](https://github.com/lwouis/alt-tab-macos/commit/025053d))

### Features

* add portuguese localization ([fd705b4](https://github.com/lwouis/alt-tab-macos/commit/fd705b4))
* update portuguese (brazil) and russian localizations ([2cebaaa](https://github.com/lwouis/alt-tab-macos/commit/2cebaaa))
2020-08-11 04:17:49 +00:00
Louis Pontoise 2cebaaa211 feat: update portuguese (brazil) and russian localizations 2020-08-11 13:01:09 +09:00
Louis Pontoise fd705b4763 feat: add portuguese localization 2020-08-11 13:01:09 +09:00
Louis Pontoise 025053dd21 fix: "no menubar icon" preference has correct height 2020-08-11 13:01:09 +09:00
Louis Pontoise ba7edf7515 docs: fix broken link and remove obsolete explanation 2020-08-11 13:01:09 +09:00
semantic-release-bot bc84d8c868 chore(release): 4.17.2 [skip ci]
## [4.17.2](https://github.com/lwouis/alt-tab-macos/compare/v4.17.1...v4.17.2) (2020-08-07)

### Bug Fixes

* shortcut 2 was showing shortcut 1 value after restart (closes [#500](https://github.com/lwouis/alt-tab-macos/issues/500)) ([74ed25d](https://github.com/lwouis/alt-tab-macos/commit/74ed25d))
2020-08-07 09:03:21 +00:00
Louis Pontoise 74ed25de17 fix: shortcut 2 was showing shortcut 1 value after restart (closes #500) 2020-08-07 17:48:42 +09:00
semantic-release-bot 63ec94f435 chore(release): 4.17.1 [skip ci]
## [4.17.1](https://github.com/lwouis/alt-tab-macos/compare/v4.17.0...v4.17.1) (2020-08-07)

### Bug Fixes

* in dark mode, the colored menubar icon was too bright ([845ae5c](https://github.com/lwouis/alt-tab-macos/commit/845ae5c))
* preference window tab icons adapt to dark mode (closes [#498](https://github.com/lwouis/alt-tab-macos/issues/498)) ([0c44c50](https://github.com/lwouis/alt-tab-macos/commit/0c44c50))
2020-08-07 08:33:52 +00:00
Louis Pontoise 845ae5c64b fix: in dark mode, the colored menubar icon was too bright 2020-08-07 17:17:42 +09:00
Louis Pontoise 0c44c5035c fix: preference window tab icons adapt to dark mode (closes #498) 2020-08-07 17:17:42 +09:00
semantic-release-bot 4b624d2fc5 chore(release): 4.17.0 [skip ci]
# [4.17.0](https://github.com/lwouis/alt-tab-macos/compare/v4.16.0...v4.17.0) (2020-08-07)

### Bug Fixes

* rare crash when started at login ([80945c8](https://github.com/lwouis/alt-tab-macos/commit/80945c8))

### Features

* update korean localization ([640bad8](https://github.com/lwouis/alt-tab-macos/commit/640bad8))
2020-08-07 05:16:51 +00:00
Louis Pontoise 640bad87c9 feat: update korean localization 2020-08-07 14:01:40 +09:00
Louis Pontoise 80945c8af3 fix: rare crash when started at login 2020-08-07 13:14:26 +09:00
semantic-release-bot 7eab1f8962 chore(release): 4.16.0 [skip ci]
# [4.16.0](https://github.com/lwouis/alt-tab-macos/compare/v4.15.0...v4.16.0) (2020-08-06)

### Bug Fixes

* removing shortcut 2 was not working properly (see [#493](https://github.com/lwouis/alt-tab-macos/issues/493)) ([fcdf40a](https://github.com/lwouis/alt-tab-macos/commit/fcdf40a))
* shortcut would not register if capslock was on (closes [#493](https://github.com/lwouis/alt-tab-macos/issues/493)) ([9db0fe4](https://github.com/lwouis/alt-tab-macos/commit/9db0fe4))

### Features

* let users minimize the preferences window ([2a0adf0](https://github.com/lwouis/alt-tab-macos/commit/2a0adf0))
2020-08-06 21:27:08 +00:00
Louis Pontoise 9db0fe40a0 fix: shortcut would not register if capslock was on (closes #493) 2020-08-07 06:11:45 +09:00
Louis Pontoise 2a0adf0ea0 feat: let users minimize the preferences window 2020-08-07 06:11:45 +09:00
Louis Pontoise fcdf40a03c fix: removing shortcut 2 was not working properly (see #493) 2020-08-07 06:11:45 +09:00
semantic-release-bot 92a8abf991 chore(release): 4.15.0 [skip ci]
# [4.15.0](https://github.com/lwouis/alt-tab-macos/compare/v4.14.0...v4.15.0) (2020-08-06)

### Features

* add new colorful menubar icon ([8f5c2a0](https://github.com/lwouis/alt-tab-macos/commit/8f5c2a0))

### Performance Improvements

* reduce size of app icon (closes [#169](https://github.com/lwouis/alt-tab-macos/issues/169)) ([bb49302](https://github.com/lwouis/alt-tab-macos/commit/bb49302))
2020-08-06 16:50:17 +00:00
Louis Pontoise 8f5c2a08bb feat: add new colorful menubar icon 2020-08-07 01:34:21 +09:00
Louis Pontoise bb493028f7 perf: reduce size of app icon (closes #169) 2020-08-07 01:34:21 +09:00
semantic-release-bot 8a95186794 chore(release): 4.14.0 [skip ci]
# [4.14.0](https://github.com/lwouis/alt-tab-macos/compare/v4.13.1...v4.14.0) (2020-08-06)

### Bug Fixes

* rare crash at launch ([461840e](https://github.com/lwouis/alt-tab-macos/commit/461840e))

### Features

* can now pick between multiple menubar icons (closes [#191](https://github.com/lwouis/alt-tab-macos/issues/191)) ([30f0322](https://github.com/lwouis/alt-tab-macos/commit/30f0322))
2020-08-06 14:34:36 +00:00
Louis Pontoise 30f03228a1 feat: can now pick between multiple menubar icons (closes #191) 2020-08-06 23:17:38 +09:00
Louis Pontoise 461840ef3d fix: rare crash at launch 2020-08-06 23:17:38 +09:00
semantic-release-bot a7247da478 chore(release): 4.13.1 [skip ci]
## [4.13.1](https://github.com/lwouis/alt-tab-macos/compare/v4.13.0...v4.13.1) (2020-08-05)

### Bug Fixes

* increase app icon size in about tab ([94a0cd8](https://github.com/lwouis/alt-tab-macos/commit/94a0cd8))
* preference window now always appears centered ([e770f18](https://github.com/lwouis/alt-tab-macos/commit/e770f18))
2020-08-05 20:35:10 +00:00
Louis Pontoise e770f186c6 fix: preference window now always appears centered 2020-08-06 05:19:20 +09:00
Louis Pontoise 94a0cd8a1e fix: increase app icon size in about tab 2020-08-06 05:19:20 +09:00
Louis Pontoise b323e464ba docs: add more qa scenarios 2020-08-06 05:19:20 +09:00
semantic-release-bot 5dd1be542d chore(release): 4.13.0 [skip ci]
# [4.13.0](https://github.com/lwouis/alt-tab-macos/compare/v4.12.2...v4.13.0) (2020-08-05)

### Features

* even more flexible controls (closes [#458](https://github.com/lwouis/alt-tab-macos/issues/458), closes [#463](https://github.com/lwouis/alt-tab-macos/issues/463)) ([a990bbe](https://github.com/lwouis/alt-tab-macos/commit/a990bbe))
* new icons for the preferences window tabs ([b20c71c](https://github.com/lwouis/alt-tab-macos/commit/b20c71c))

### Performance Improvements

* reduced size of app ([2df0c22](https://github.com/lwouis/alt-tab-macos/commit/2df0c22))
2020-08-05 19:34:29 +00:00
Louis Pontoise 2df0c221c2 perf: reduced size of app 2020-08-06 04:18:53 +09:00
Louis Pontoise b20c71c896 feat: new icons for the preferences window tabs 2020-08-06 04:18:53 +09:00
Louis Pontoise a990bbef9c feat: even more flexible controls (closes #458, closes #463) 2020-08-06 04:18:53 +09:00
semantic-release-bot 79ae6cab4c chore(release): 4.12.2 [skip ci]
## [4.12.2](https://github.com/lwouis/alt-tab-macos/compare/v4.12.1...v4.12.2) (2020-08-04)

### Bug Fixes

* rare crash at launch if the app previously crashed ([6444732](https://github.com/lwouis/alt-tab-macos/commit/6444732))
* rare crash when being started twice quickly at login ([a6365fb](https://github.com/lwouis/alt-tab-macos/commit/a6365fb))
2020-08-04 15:00:37 +00:00
Louis Pontoise a6365fb9a0 fix: rare crash when being started twice quickly at login 2020-08-04 23:42:28 +09:00
Louis Pontoise 6444732bc5 fix: rare crash at launch if the app previously crashed 2020-08-04 23:42:28 +09:00
semantic-release-bot 6505ca5a39 chore(release): 4.12.1 [skip ci]
## [4.12.1](https://github.com/lwouis/alt-tab-macos/compare/v4.12.0...v4.12.1) (2020-08-03)

### Bug Fixes

* occasional wrong window order after focusing a window (closes [#484](https://github.com/lwouis/alt-tab-macos/issues/484)) ([d6b1fb4](https://github.com/lwouis/alt-tab-macos/commit/d6b1fb4))
2020-08-03 18:25:39 +00:00
Louis Pontoise d6b1fb480d fix: occasional wrong window order after focusing a window (closes #484) 2020-08-04 03:08:46 +09:00
semantic-release-bot 34c1754b65 chore(release): 4.12.0 [skip ci]
# [4.12.0](https://github.com/lwouis/alt-tab-macos/compare/v4.11.1...v4.12.0) (2020-08-03)

### Features

* better default shortcuts on non-us keyboards (closes [#480](https://github.com/lwouis/alt-tab-macos/issues/480)) ([ea52111](https://github.com/lwouis/alt-tab-macos/commit/ea52111))
* update german, korean, chinese localizations ([fcbc89e](https://github.com/lwouis/alt-tab-macos/commit/fcbc89e))

### Performance Improvements

* slightly less latency for keyboard/mouse/os events ([28fb5f4](https://github.com/lwouis/alt-tab-macos/commit/28fb5f4))
* slightly reduce energy usage ([26e840c](https://github.com/lwouis/alt-tab-macos/commit/26e840c))
2020-08-03 16:02:49 +00:00
Louis Pontoise fcbc89ef65 feat: update german, korean, chinese localizations 2020-08-04 00:47:01 +09:00
Louis Pontoise ea52111c1a feat: better default shortcuts on non-us keyboards (closes #480) 2020-08-04 00:47:01 +09:00
Louis Pontoise 28fb5f4afa perf: slightly less latency for keyboard/mouse/os events 2020-08-04 00:47:01 +09:00
Louis Pontoise 26e840c1e7 perf: slightly reduce energy usage 2020-08-04 00:47:01 +09:00
semantic-release-bot 9d8781f69b chore(release): 4.11.1 [skip ci]
## [4.11.1](https://github.com/lwouis/alt-tab-macos/compare/v4.11.0...v4.11.1) (2020-07-30)

### Bug Fixes

* rare crash at launch if the app previously crashed ([12c27f1](https://github.com/lwouis/alt-tab-macos/commit/12c27f1))
* rare crash when user cycles while all windows get closed ([e901ca3](https://github.com/lwouis/alt-tab-macos/commit/e901ca3))
2020-07-30 11:21:22 +00:00
Louis Pontoise 4fe6002fc3 refactor: disable swizzling in favor of manual forwarding
see https://github.com/microsoft/appcenter-sdk-apple/issues/2137
2020-07-30 20:03:38 +09:00
Louis Pontoise e901ca3c7d fix: rare crash when user cycles while all windows get closed 2020-07-30 20:03:38 +09:00
Louis Pontoise 12c27f137f fix: rare crash at launch if the app previously crashed 2020-07-30 20:03:38 +09:00
semantic-release-bot 8c1ba9fe23 chore(release): 4.11.0 [skip ci]
# [4.11.0](https://github.com/lwouis/alt-tab-macos/compare/v4.10.0...v4.11.0) (2020-07-29)

### Bug Fixes

* crash if accessibility permission is granted then removed quickly ([0bca1e0](https://github.com/lwouis/alt-tab-macos/commit/0bca1e0))
* prevent macos restoring the app (conflict with login items) ([62037a0](https://github.com/lwouis/alt-tab-macos/commit/62037a0))
* rare crash at launch if the app previously crashed ([69168f9](https://github.com/lwouis/alt-tab-macos/commit/69168f9))
* rare crash when the os doesn't return the main screen uuid ([2232f81](https://github.com/lwouis/alt-tab-macos/commit/2232f81))

### Features

* update korean localization ([d31e369](https://github.com/lwouis/alt-tab-macos/commit/d31e369))
2020-07-29 19:00:34 +00:00
Louis Pontoise d31e369ef2 feat: update korean localization 2020-07-30 03:44:38 +09:00
Louis Pontoise 150fef68a5 refactor: cleaner layout for update policies 2020-07-30 03:44:38 +09:00
Louis Pontoise 0bca1e0869 fix: crash if accessibility permission is granted then removed quickly 2020-07-30 03:44:38 +09:00
Louis Pontoise de81b27fc3 refactor: potentially fixes a crash
function signature specialization <Arg[0] = Dead, Arg[3] = Dead> of AltTab.(keyboardHandler in _49D6ED7A14CE97405B1E63D2519515EC)(proxy: Swift.OpaquePointer, type: __C.CGEventType, cgEvent: __C.CGEventRef, userInfo: Swift.UnsafeMutableRawPointer?) -> Swift.Unmanaged<__C.CGEventRef>?
2020-07-30 03:44:38 +09:00
Louis Pontoise 2232f81bed fix: rare crash when the os doesn't return the main screen uuid 2020-07-30 03:44:38 +09:00
Louis Pontoise 69168f92cd fix: rare crash at launch if the app previously crashed 2020-07-30 03:44:38 +09:00
Louis Pontoise 62037a0102 fix: prevent macos restoring the app (conflict with login items) 2020-07-30 03:44:38 +09:00
semantic-release-bot 644ccf544c chore(release): 4.10.0 [skip ci]
# [4.10.0](https://github.com/lwouis/alt-tab-macos/compare/v4.9.1...v4.10.0) (2020-07-28)

### Features

* preference to hide colored circles on mouse hover (closes [#460](https://github.com/lwouis/alt-tab-macos/issues/460)) ([02776f0](https://github.com/lwouis/alt-tab-macos/commit/02776f0))
* preference to hide windows status icons (closes [#467](https://github.com/lwouis/alt-tab-macos/issues/467)) ([d305eb8](https://github.com/lwouis/alt-tab-macos/commit/d305eb8))
* update korean, chinese, russian localizations ([685bd10](https://github.com/lwouis/alt-tab-macos/commit/685bd10))
2020-07-28 15:37:36 +00:00
Louis Pontoise 31f6c3e1ce refactor: update localizations with new terms 2020-07-29 00:20:16 +09:00
Louis Pontoise 02780073ff docs: update contributors list 2020-07-29 00:20:16 +09:00
Louis Pontoise 685bd10639 feat: update korean, chinese, russian localizations 2020-07-29 00:20:16 +09:00
Louis Pontoise d305eb8e8f feat: preference to hide windows status icons (closes #467) 2020-07-29 00:20:16 +09:00
Louis Pontoise 02776f044c feat: preference to hide colored circles on mouse hover (closes #460) 2020-07-29 00:20:16 +09:00
semantic-release-bot ee02f25264 chore(release): 4.9.1 [skip ci]
## [4.9.1](https://github.com/lwouis/alt-tab-macos/compare/v4.9.0...v4.9.1) (2020-07-22)

### Bug Fixes

* occasional crash when updating some preferences ([3d36cb7](https://github.com/lwouis/alt-tab-macos/commit/3d36cb7))
2020-07-22 16:04:50 +00:00
Louis Pontoise 3d36cb7d6f fix: occasional crash when updating some preferences 2020-07-23 00:48:52 +09:00
semantic-release-bot c5ab19c677 chore(release): 4.9.0 [skip ci]
# [4.9.0](https://github.com/lwouis/alt-tab-macos/compare/v4.8.1...v4.9.0) (2020-07-22)

### Bug Fixes

* dr.betotte app wasn't listed in alt-tab (closes [#455](https://github.com/lwouis/alt-tab-macos/issues/455)) ([85b5ee7](https://github.com/lwouis/alt-tab-macos/commit/85b5ee7))
* occasional crash when focusing a window (closes [#459](https://github.com/lwouis/alt-tab-macos/issues/459)) ([19be9a1](https://github.com/lwouis/alt-tab-macos/commit/19be9a1))
* occasional crash when no there are no open window (closes [#459](https://github.com/lwouis/alt-tab-macos/issues/459)) ([6df92da](https://github.com/lwouis/alt-tab-macos/commit/6df92da))

### Features

* after a crash, suggest to send a crash report (closes [#132](https://github.com/lwouis/alt-tab-macos/issues/132)) ([a8970dd](https://github.com/lwouis/alt-tab-macos/commit/a8970dd))
2020-07-22 14:42:20 +00:00
Louis Pontoise 1de39a0049 refactor: fix inconsequential warnings 2020-07-22 23:19:45 +09:00
Louis Pontoise 19be9a174a fix: occasional crash when focusing a window (closes #459) 2020-07-22 23:19:45 +09:00
Louis Pontoise 6df92da76f fix: occasional crash when no there are no open window (closes #459) 2020-07-22 23:19:45 +09:00
Louis Pontoise a8970ddf71 feat: after a crash, suggest to send a crash report (closes #132)
also updated many localications
2020-07-22 23:19:45 +09:00
Louis Pontoise 85b5ee7653 fix: dr.betotte app wasn't listed in alt-tab (closes #455) 2020-07-22 23:19:45 +09:00
semantic-release-bot 19f058df97 chore(release): 4.8.1 [skip ci]
## [4.8.1](https://github.com/lwouis/alt-tab-macos/compare/v4.8.0...v4.8.1) (2020-07-21)

### Bug Fixes

* rare crash when clicking while alt-tab is open ([#439](https://github.com/lwouis/alt-tab-macos/issues/439)) ([b3c6031](https://github.com/lwouis/alt-tab-macos/commit/b3c6031))
2020-07-21 18:24:57 +00:00
Louis Pontoise b3c6031b3f fix: rare crash when clicking while alt-tab is open (#439) 2020-07-22 03:08:16 +09:00
semantic-release-bot be0cb8c92f chore(release): 4.8.0 [skip ci]
# [4.8.0](https://github.com/lwouis/alt-tab-macos/compare/v4.7.2...v4.8.0) (2020-07-21)

### Features

* hovering thumbnails reveals icons to close/min/max windows ([#9](https://github.com/lwouis/alt-tab-macos/issues/9)) ([11e0d2a](https://github.com/lwouis/alt-tab-macos/commit/11e0d2a))
2020-07-21 16:39:03 +00:00
Louis Pontoise 11e0d2aac3 feat: hovering thumbnails reveals icons to close/min/max windows (#9) 2020-07-22 01:23:25 +09:00
semantic-release-bot 586bb6e5e6 chore(release): 4.7.2 [skip ci]
## [4.7.2](https://github.com/lwouis/alt-tab-macos/compare/v4.7.1...v4.7.2) (2020-07-21)

### Bug Fixes

* dvdfab app wasn't listed in alt-tab (closes [#450](https://github.com/lwouis/alt-tab-macos/issues/450)) ([13e41ab](https://github.com/lwouis/alt-tab-macos/commit/13e41ab))
2020-07-21 09:40:48 +00:00
Louis Pontoise 13e41abb65 fix: dvdfab app wasn't listed in alt-tab (closes #450) 2020-07-21 18:26:54 +09:00
semantic-release-bot a2c5012654 chore(release): 4.7.1 [skip ci]
## [4.7.1](https://github.com/lwouis/alt-tab-macos/compare/v4.7.0...v4.7.1) (2020-07-21)

### Bug Fixes

* sanguosha game wasn't listed in alt-tab (closes [#441](https://github.com/lwouis/alt-tab-macos/issues/441)) ([e67b075](https://github.com/lwouis/alt-tab-macos/commit/e67b075))
2020-07-21 08:18:02 +00:00
Louis Pontoise e67b07572d fix: sanguosha game wasn't listed in alt-tab (closes #441) 2020-07-21 16:51:45 +09:00
semantic-release-bot 1b956b3862 chore(release): 4.7.0 [skip ci]
# [4.7.0](https://github.com/lwouis/alt-tab-macos/compare/v4.6.0...v4.7.0) (2020-07-20)

### Bug Fixes

* android emulator not showing because of blacklist (closes [#444](https://github.com/lwouis/alt-tab-macos/issues/444)) ([60bf384](https://github.com/lwouis/alt-tab-macos/commit/60bf384))

### Features

* add second shortcut to active the app (closes [#237](https://github.com/lwouis/alt-tab-macos/issues/237)) ([a6285ba](https://github.com/lwouis/alt-tab-macos/commit/a6285ba))
* default layout based on screen aspect ratio (closes [#436](https://github.com/lwouis/alt-tab-macos/issues/436)) ([11fb95d](https://github.com/lwouis/alt-tab-macos/commit/11fb95d))
* easier back-cycling shortcut ([#420](https://github.com/lwouis/alt-tab-macos/issues/420)) ([a31544d](https://github.com/lwouis/alt-tab-macos/commit/a31544d))
* updated german and hungarian localizations ([7a23046](https://github.com/lwouis/alt-tab-macos/commit/7a23046))
2020-07-20 22:25:06 +00:00
Louis Pontoise 60bf384e43 fix: android emulator not showing because of blacklist (closes #444) 2020-07-21 07:10:54 +09:00
Louis Pontoise bf7db193c9 ci: update xcode to match local version 2020-07-21 07:10:54 +09:00
Louis Pontoise d7208a684d refactor: fix warmings 2020-07-21 07:10:54 +09:00
Louis Pontoise a6285ba27c feat: add second shortcut to active the app (closes #237) 2020-07-21 07:10:54 +09:00
Louis Pontoise cf7b07625a refactor: add indonesian in xcode conf 2020-07-21 07:10:54 +09:00
Louis Pontoise a31544d092 feat: easier back-cycling shortcut (#420)
fix: correct layout for right-to-left languages
2020-07-21 07:10:54 +09:00
Louis Pontoise 7a23046015 feat: updated german and hungarian localizations 2020-07-21 07:10:54 +09:00
Louis Pontoise 11fb95d1d0 feat: default layout based on screen aspect ratio (closes #436) 2020-07-21 07:10:54 +09:00
semantic-release-bot dc0371aa1a chore(release): 4.6.0 [skip ci]
# [4.6.0](https://github.com/lwouis/alt-tab-macos/compare/v4.5.0...v4.6.0) (2020-07-20)

### Features

* add indonesian and luxembourgish localizations ([d3432a9](https://github.com/lwouis/alt-tab-macos/commit/d3432a9))
* updating german, french, korean localizations ([53a2f5f](https://github.com/lwouis/alt-tab-macos/commit/53a2f5f))
2020-07-20 02:06:21 +00:00
Louis Pontoise 53a2f5f2b6 feat: updating german, french, korean localizations 2020-07-20 10:54:32 +09:00
Louis Pontoise d3432a99fe feat: add indonesian and luxembourgish localizations 2020-07-20 10:54:32 +09:00
Louis Pontoise 9474c35cdd docs: small mistakes on the website (closes #442) 2020-07-20 10:54:32 +09:00
semantic-release-bot c21170d574 chore(release): 4.5.0 [skip ci]
# [4.5.0](https://github.com/lwouis/alt-tab-macos/compare/v4.4.0...v4.5.0) (2020-07-17)

### Bug Fixes

* alt-tab preferences panel was sometimes not listed ([e25716b](https://github.com/lwouis/alt-tab-macos/commit/e25716b))
* launch crash on macOS versions < 10.15 ([d817545](https://github.com/lwouis/alt-tab-macos/commit/d817545))

### Features

* allow backlisting apps, with 2 different types of blacklist ([d32951f](https://github.com/lwouis/alt-tab-macos/commit/d32951f)), closes [#239](https://github.com/lwouis/alt-tab-macos/issues/239)
2020-07-17 18:47:55 +00:00
Louis Pontoise d32951f06f feat: allow backlisting apps, with 2 different types of blacklist
closes #239
2020-07-18 03:33:49 +09:00
Louis Pontoise d8175450a7 fix: launch crash on macOS versions < 10.15 2020-07-18 03:33:49 +09:00
Louis Pontoise e25716b38d fix: alt-tab preferences panel was sometimes not listed 2020-07-18 03:33:49 +09:00
Louis Pontoise ce1be11995 refactor: add link to good docs 2020-07-18 03:33:49 +09:00
Louis Pontoise 7437f0df51 refactor: fixes random segfaults while compiling locally 2020-07-18 03:33:49 +09:00
semantic-release-bot eee5d178e2 chore(release): 4.4.0 [skip ci]
# [4.4.0](https://github.com/lwouis/alt-tab-macos/compare/v4.3.0...v4.4.0) (2020-07-15)

### Bug Fixes

* update chinese localization ([95d75d3](https://github.com/lwouis/alt-tab-macos/commit/95d75d3))

### Features

* add preference for title truncation style ([3bddd7e](https://github.com/lwouis/alt-tab-macos/commit/3bddd7e))
* click outside alt-tab main window to cancel (closes [#341](https://github.com/lwouis/alt-tab-macos/issues/341)) ([1fc620d](https://github.com/lwouis/alt-tab-macos/commit/1fc620d))
2020-07-15 17:43:39 +00:00
Louis Pontoise 3bddd7ea17 feat: add preference for title truncation style
some users may prefer the window titles to be truncated in the middle, or at the start
2020-07-16 02:17:27 +09:00
Louis Pontoise 1fc620d405 feat: click outside alt-tab main window to cancel (closes #341)
* also fix issue where clicking a thumbnail would give alt-tab focus, removing it from the app currently focused
* also use click on a thumbnail to focus it instead of only mouse-down
2020-07-16 02:17:27 +09:00
Louis Pontoise 95d75d3c85 fix: update chinese localization 2020-07-16 02:17:27 +09:00
semantic-release-bot 0c753005f3 chore(release): 4.3.0 [skip ci]
# [4.3.0](https://github.com/lwouis/alt-tab-macos/compare/v4.2.0...v4.3.0) (2020-07-14)

### Features

* better system permissions onboarding (closes [#127](https://github.com/lwouis/alt-tab-macos/issues/127)) ([6ef0a6f](https://github.com/lwouis/alt-tab-macos/commit/6ef0a6f))
2020-07-14 13:23:48 +00:00
Louis Pontoise 6ef0a6f9e8 feat: better system permissions onboarding (closes #127) 2020-07-14 22:11:11 +09:00
Louis Pontoise 6d16b57f63 docs: update contributors list 2020-07-14 22:11:11 +09:00
semantic-release-bot 4c25d01aa2 chore(release): 4.2.0 [skip ci]
# [4.2.0](https://github.com/lwouis/alt-tab-macos/compare/v4.1.7...v4.2.0) (2020-07-11)

### Bug Fixes

* further chinese and french localizations ([99668ae](https://github.com/lwouis/alt-tab-macos/commit/99668ae))
* further chinese/korean/french localizations ([d638eb0](https://github.com/lwouis/alt-tab-macos/commit/d638eb0))

### Features

* add preference to hide menubar icon (closes [#103](https://github.com/lwouis/alt-tab-macos/issues/103)) ([6635117](https://github.com/lwouis/alt-tab-macos/commit/6635117))
2020-07-11 19:17:29 +00:00
Louis Pontoise 398524fa33 docs: add another alternative app to landing page 2020-07-12 03:41:20 +09:00
Louis Pontoise d638eb08c6 fix: further chinese/korean/french localizations 2020-07-12 03:41:20 +09:00
Louis Pontoise 99668ae93a fix: further chinese and french localizations 2020-07-12 03:41:20 +09:00
Louis Pontoise c76796014a docs: add new contributor 2020-07-12 03:41:20 +09:00
Licardo ae3c911968 refactor: made buttons code more uniform 2020-07-12 03:41:20 +09:00
Licardo 663511754b feat: add preference to hide menubar icon (closes #103) 2020-07-12 03:41:20 +09:00
Licardo b1477fc670 refactor: ignore local self-signed certificate files 2020-07-12 03:41:20 +09:00
semantic-release-bot 6f9b814bed chore(release): 4.1.7 [skip ci]
## [4.1.7](https://github.com/lwouis/alt-tab-macos/compare/v4.1.6...v4.1.7) (2020-07-10)

### Bug Fixes

* on some machines, deadlocks happened at launch ([e2181c8](https://github.com/lwouis/alt-tab-macos/commit/e2181c8))
* reduce cpu utilization at launch ([5306a4b](https://github.com/lwouis/alt-tab-macos/commit/5306a4b))
* typo in chinese localization ([363ed3d](https://github.com/lwouis/alt-tab-macos/commit/363ed3d))
2020-07-10 18:46:29 +00:00
Louis Pontoise 363ed3d3d8 fix: typo in chinese localization 2020-07-11 03:31:50 +09:00
Louis Pontoise 3da02b36d0 ci: disable pod install as it is undeterministic 2020-07-11 03:31:50 +09:00
Louis Pontoise e2181c8756 fix: on some machines, deadlocks happened at launch 2020-07-11 03:31:50 +09:00
Louis Pontoise 126eca5c35 docs: add contributors to the app (closes #296)
Also better present the third-party libraries, with links and less noise from the licenses text
2020-07-11 03:31:50 +09:00
Louis Pontoise d08e7f7b67 docs: adding more related apps to the website 2020-07-11 03:31:50 +09:00
Louis Pontoise 5306a4b95c fix: reduce cpu utilization at launch 2020-07-11 03:31:50 +09:00
semantic-release-bot 5b2edfb84b chore(release): 4.1.6 [skip ci]
## [4.1.6](https://github.com/lwouis/alt-tab-macos/compare/v4.1.5...v4.1.6) (2020-07-08)

### Bug Fixes

* potential crash in very rare data-race scenario ([4ff5d89](https://github.com/lwouis/alt-tab-macos/commit/4ff5d89))
* tabs would sometimes show as separate windows (closes [#383](https://github.com/lwouis/alt-tab-macos/issues/383)) ([c03d48f](https://github.com/lwouis/alt-tab-macos/commit/c03d48f))
* update korean localization ([ecdeed8](https://github.com/lwouis/alt-tab-macos/commit/ecdeed8))
2020-07-08 11:44:20 +00:00
Louis Pontoise 2a6b33dcff docs: updating contribution guide 2020-07-08 20:30:46 +09:00
Louis Pontoise ecdeed80b8 fix: update korean localization 2020-07-08 20:30:46 +09:00
Louis Pontoise 6de5d69f06 docs: document a new private api which listens to system events 2020-07-08 20:30:46 +09:00
Louis Pontoise c03d48f239 fix: tabs would sometimes show as separate windows (closes #383) 2020-07-08 20:30:46 +09:00
Louis Pontoise 4ff5d89429 fix: potential crash in very rare data-race scenario 2020-07-08 20:30:46 +09:00
Louis Pontoise b9fef455b6 docs: added more related/alternative apps on the homepage 2020-07-08 20:30:46 +09:00
semantic-release-bot 0fbe038ab1 chore(release): 4.1.5 [skip ci]
## [4.1.5](https://github.com/lwouis/alt-tab-macos/compare/v4.1.4...v4.1.5) (2020-07-03)

### Bug Fixes

* improve perf by only refreshing shown thumbnails (closes [#393](https://github.com/lwouis/alt-tab-macos/issues/393)) ([3c453f9](https://github.com/lwouis/alt-tab-macos/commit/3c453f9))
* update dutch and russian localizations ([ff96bc3](https://github.com/lwouis/alt-tab-macos/commit/ff96bc3))
2020-07-03 05:15:48 +00:00
Louis Pontoise ff96bc3170 fix: update dutch and russian localizations 2020-07-03 14:04:59 +09:00
Louis Pontoise b2cced8bb1 docs: document .icns creation process from .iconset 2020-07-03 14:04:59 +09:00
Louis Pontoise 3c453f91ed fix: improve perf by only refreshing shown thumbnails (closes #393) 2020-07-03 14:04:59 +09:00
semantic-release-bot 1097aa22c9 chore(release): 4.1.4 [skip ci]
## [4.1.4](https://github.com/lwouis/alt-tab-macos/compare/v4.1.3...v4.1.4) (2020-06-23)
2020-06-23 16:57:47 +00:00
Louis Pontoise 610ae8e404 docs: update github contributor list 2020-06-24 01:46:13 +09:00
Louis Pontoise 76458a7f08 docs: clarify that feedback will be made public (closed #260) 2020-06-24 01:46:13 +09:00
semantic-release-bot 64cfc0b9c6 chore(release): 4.1.3 [skip ci]
## [4.1.3](https://github.com/lwouis/alt-tab-macos/compare/v4.1.2...v4.1.3) (2020-06-16)

### Bug Fixes

* rare crash if shortcut is pressed early during launch ([265c7a6](https://github.com/lwouis/alt-tab-macos/commit/265c7a6))
* show android emulator window (closes [#376](https://github.com/lwouis/alt-tab-macos/issues/376)) ([bb8a5ce](https://github.com/lwouis/alt-tab-macos/commit/bb8a5ce))
* show windows of apps without a bundle (e.g. not .app) ([fd0623a](https://github.com/lwouis/alt-tab-macos/commit/fd0623a))
2020-06-16 04:40:05 +00:00
Louis Pontoise 265c7a6c34 fix: rare crash if shortcut is pressed early during launch 2020-06-16 13:30:10 +09:00
Louis Pontoise bb8a5ceaa9 fix: show android emulator window (closes #376) 2020-06-16 13:30:10 +09:00
Louis Pontoise fd0623a706 fix: show windows of apps without a bundle (e.g. not .app) 2020-06-16 13:30:10 +09:00
semantic-release-bot b9d5784716 chore(release): 4.1.2 [skip ci]
## [4.1.2](https://github.com/lwouis/alt-tab-macos/compare/v4.1.1...v4.1.2) (2020-06-09)

### Bug Fixes

* releasing the shortcut works even with other modifiers pressed ([23b17c1](https://github.com/lwouis/alt-tab-macos/commit/23b17c1)), closes [#230](https://github.com/lwouis/alt-tab-macos/issues/230)
2020-06-09 09:44:59 +00:00
Louis Pontoise 25d7a9beaa docs: update contributors list 2020-06-09 18:34:32 +09:00
Louis Pontoise 23b17c1e2a fix: releasing the shortcut works even with other modifiers pressed
closes #230
2020-06-09 18:34:32 +09:00
Louis Pontoise 0e283649e6 refactor: remove unnecessary try-s and warnings 2020-06-09 18:34:32 +09:00
semantic-release-bot 0843d7f53c chore(release): 4.1.1 [skip ci]
## [4.1.1](https://github.com/lwouis/alt-tab-macos/compare/v4.1.0...v4.1.1) (2020-06-07)

### Bug Fixes

* mouse hover during scroll bounce produced visual jank (closes [#259](https://github.com/lwouis/alt-tab-macos/issues/259)) ([c7e5daa](https://github.com/lwouis/alt-tab-macos/commit/c7e5daa))
* sometimes switching apps wouldn't be noticed ([96a6ae6](https://github.com/lwouis/alt-tab-macos/commit/96a6ae6))
* update korean localizations ([cec2756](https://github.com/lwouis/alt-tab-macos/commit/cec2756))
2020-06-07 14:53:09 +00:00
Louis Pontoise cec2756255 fix: update korean localizations 2020-06-07 23:43:40 +09:00
Louis Pontoise 2773551438 docs: update contributors list 2020-06-07 23:43:40 +09:00
Louis Pontoise 96a6ae6e07 fix: sometimes switching apps wouldn't be noticed
NSRunningApplication.init(processIdentifier: pid) sometimes returns nil for Chrome, even though I see that the pid exist in Activity Monitor and is actually Chrome. I think the constructor is thread-unsafe, and should be called from the main thread only, thus I refactored to make that possible
2020-06-07 23:43:40 +09:00
Louis Pontoise c7e5daa357 fix: mouse hover during scroll bounce produced visual jank (closes #259) 2020-06-07 23:43:40 +09:00
semantic-release-bot da574975ac chore(release): 4.1.0 [skip ci]
# [4.1.0](https://github.com/lwouis/alt-tab-macos/compare/v4.0.1...v4.1.0) (2020-05-28)

### Features

* prevent users from quitting finder (closes [#362](https://github.com/lwouis/alt-tab-macos/issues/362)) ([a1338c0](https://github.com/lwouis/alt-tab-macos/commit/a1338c0))
2020-05-28 17:10:51 +00:00
Louis Pontoise a1338c0051 feat: prevent users from quitting finder (closes #362) 2020-05-29 02:00:29 +09:00
semantic-release-bot c6c421ed56 chore(release): 4.0.1 [skip ci]
## [4.0.1](https://github.com/lwouis/alt-tab-macos/compare/v4.0.0...v4.0.1) (2020-05-28)

### Bug Fixes

* firefox fullscreen videos are not listed (closes [#360](https://github.com/lwouis/alt-tab-macos/issues/360)) ([ce63367](https://github.com/lwouis/alt-tab-macos/commit/ce63367))
* updated chinese/french/russian localizations ([797ed42](https://github.com/lwouis/alt-tab-macos/commit/797ed42))
2020-05-28 16:47:07 +00:00
Louis Pontoise ce63367b82 fix: firefox fullscreen videos are not listed (closes #360) 2020-05-29 01:29:19 +09:00
Louis Pontoise 797ed42220 fix: updated chinese/french/russian localizations 2020-05-29 01:29:19 +09:00
semantic-release-bot 3e4bcde993 chore(release): 4.0.0 [skip ci]
# [4.0.0](https://github.com/lwouis/alt-tab-macos/compare/v3.24.1...v4.0.0) (2020-05-25)

### Bug Fixes

* center-aligned layout was sometimes broken (closes [#352](https://github.com/lwouis/alt-tab-macos/issues/352)) ([e25dcd2](https://github.com/lwouis/alt-tab-macos/commit/e25dcd2))
* crash in some rare scenarios with lots of windows ([a859347](https://github.com/lwouis/alt-tab-macos/commit/a859347))
* potentially fix shortcuts not working sometimes ([8d833f5](https://github.com/lwouis/alt-tab-macos/commit/8d833f5))
* rework all multi-threading to handle complex scenarios ([d144476](https://github.com/lwouis/alt-tab-macos/commit/d144476)), closes [#348](https://github.com/lwouis/alt-tab-macos/issues/348) [#157](https://github.com/lwouis/alt-tab-macos/issues/157) [#342](https://github.com/lwouis/alt-tab-macos/issues/342) [#93](https://github.com/lwouis/alt-tab-macos/issues/93)
* sometimes windows titles use the wrong font ([fa1095e](https://github.com/lwouis/alt-tab-macos/commit/fa1095e))
* update japanese localization ([acef0b2](https://github.com/lwouis/alt-tab-macos/commit/acef0b2))

### BREAKING CHANGES

* this rework should fix all sorts of issues when OS events happen in parallel: new windows, new apps, user shortcuts, etc. Here are example of use-cases that should work great now, without, and very quickly:

* AltTab is open and an app/window is launched/quit
* A window is minimized/deminimized, and while the animation is playing, the user invokes AltTab
* An app starts and takes a long time to boot (e.g. Gimp)
* An app becomes unresponsive, yet AltTab is unaffected and remains interactive while still processing the state of the window while its parent app finally stops being frozen
2020-05-25 17:38:23 +00:00
Louis Pontoise acef0b264a fix: update japanese localization 2020-05-26 02:29:25 +09:00
Louis Pontoise e25dcd2146 fix: center-aligned layout was sometimes broken (closes #352) 2020-05-26 02:29:25 +09:00
Louis Pontoise a8593477ea fix: crash in some rare scenarios with lots of windows 2020-05-26 02:29:25 +09:00
Louis Pontoise d144476691 fix: rework all multi-threading to handle complex scenarios
BREAKING CHANGE: this rework should fix all sorts of issues when OS events happen in parallel: new windows, new apps, user shortcuts, etc. Here are example of use-cases that should work great now, without, and very quickly:

* AltTab is open and an app/window is launched/quit
* A window is minimized/deminimized, and while the animation is playing, the user invokes AltTab
* An app starts and takes a long time to boot (e.g. Gimp)
* An app becomes unresponsive, yet AltTab is unaffected and remains interactive while still processing the state of the window while its parent app finally stops being frozen

closes #348, closes #157, closes #342, closes #93
2020-05-26 02:29:25 +09:00
Louis Pontoise 8d833f5163 fix: potentially fix shortcuts not working sometimes
Also potentially fixed crashes as some shortcuts would execute code that should run on the main thread, from other threads
2020-05-26 02:29:25 +09:00
Louis Pontoise fa1095e83c fix: sometimes windows titles use the wrong font 2020-05-26 02:29:25 +09:00
Louis Pontoise 3ffe23079f docs: fix layout overflow on website on mobile 2020-05-26 02:29:25 +09:00
semantic-release-bot 694a42d9b7 chore(release): 3.24.1 [skip ci]
## [3.24.1](https://github.com/lwouis/alt-tab-macos/compare/v3.24.0...v3.24.1) (2020-05-22)

### Bug Fixes

* localized release notes were not working ([125da44](https://github.com/lwouis/alt-tab-macos/commit/125da44))
2020-05-22 11:37:39 +00:00
Louis Pontoise 125da4422b fix: localized release notes were not working
updated sparkle to handle google translate iframes correctly
2020-05-22 20:27:45 +09:00
semantic-release-bot 7cc506a53e chore(release): 3.24.0 [skip ci]
# [3.24.0](https://github.com/lwouis/alt-tab-macos/compare/v3.23.2...v3.24.0) (2020-05-21)

### Bug Fixes

* don't freeze when invoked while unity is recompiling (closes [#342](https://github.com/lwouis/alt-tab-macos/issues/342)) ([41cb701](https://github.com/lwouis/alt-tab-macos/commit/41cb701)), closes [#292](https://github.com/lwouis/alt-tab-macos/issues/292) [#200](https://github.com/lwouis/alt-tab-macos/issues/200)
* don't freeze when sending a command to an frozen window ([408b800](https://github.com/lwouis/alt-tab-macos/commit/408b800))
* show windows which are opened in fullscreen (closes [#335](https://github.com/lwouis/alt-tab-macos/issues/335)) ([2674c8f](https://github.com/lwouis/alt-tab-macos/commit/2674c8f))

### Features

* show indicator for fullscreen windows ([0138cd1](https://github.com/lwouis/alt-tab-macos/commit/0138cd1))
2020-05-21 12:11:31 +00:00
Louis Pontoise 0138cd17b1 feat: show indicator for fullscreen windows
Also:

* preference to show or not fullscreen windows
* new indicator for hidden windows
2020-05-21 21:02:19 +09:00
Louis Pontoise 2674c8f8db fix: show windows which are opened in fullscreen (closes #335) 2020-05-21 21:02:19 +09:00
Louis Pontoise 408b800a23 fix: don't freeze when sending a command to an frozen window 2020-05-21 21:02:19 +09:00
Louis Pontoise 41cb701979 fix: don't freeze when invoked while unity is recompiling (closes #342)
Revert "fix: don't display invalid windows (may fix #292 #200)"

This reverts commit 1bca012f
2020-05-21 21:02:19 +09:00
semantic-release-bot bc26fa066a chore(release): 3.23.2 [skip ci]
## [3.23.2](https://github.com/lwouis/alt-tab-macos/compare/v3.23.1...v3.23.2) (2020-05-21)

### Bug Fixes

* better handle apps that start as background processes ([49816ab](https://github.com/lwouis/alt-tab-macos/commit/49816ab))
* update contributors ([b303d2f](https://github.com/lwouis/alt-tab-macos/commit/b303d2f))
* update german localization ([b047443](https://github.com/lwouis/alt-tab-macos/commit/b047443))
2020-05-21 03:35:54 +00:00
Louis Pontoise b303d2fbe0 fix: update contributors 2020-05-21 12:24:42 +09:00
Louis Pontoise b047443f6c fix: update german localization 2020-05-21 12:24:42 +09:00
Louis Pontoise 02702152f1 ci: ignore 0% completion localizations on poeditor 2020-05-21 12:24:41 +09:00
Louis Pontoise 49816ab320 fix: better handle apps that start as background processes
some apps start with .activationPolicy == .prohibited and then transition to != .prohibited later on. We now observe that attribute evolution, instead of hardcoding exceptions for some apps. For the initial filtering of processes, we now takes every process that is not an XPC process, as all others could spawn windows down the line
2020-05-21 12:24:37 +09:00
semantic-release-bot 86aad6d68b chore(release): 3.23.1 [skip ci]
## [3.23.1](https://github.com/lwouis/alt-tab-macos/compare/v3.23.0...v3.23.1) (2020-05-13)

### Bug Fixes

* duplicate windows shown after login (closes [#292](https://github.com/lwouis/alt-tab-macos/issues/292)) ([804b7e2](https://github.com/lwouis/alt-tab-macos/commit/804b7e2))
* update russian, chinese, chinese (tw) localizations ([bf97f53](https://github.com/lwouis/alt-tab-macos/commit/bf97f53))
2020-05-13 04:28:44 +00:00
Louis Pontoise bf97f537ec fix: update russian, chinese, chinese (tw) localizations 2020-05-13 13:19:32 +09:00
Louis Pontoise 804b7e2aa4 fix: duplicate windows shown after login (closes #292) 2020-05-13 13:19:32 +09:00
semantic-release-bot ab7632068c chore(release): 3.23.0 [skip ci]
# [3.23.0](https://github.com/lwouis/alt-tab-macos/compare/v3.22.6...v3.23.0) (2020-05-11)

### Bug Fixes

* update korean localization ([34e6877](https://github.com/lwouis/alt-tab-macos/commit/34e6877))

### Features

* localize release notes using google translate ([1927f2c](https://github.com/lwouis/alt-tab-macos/commit/1927f2c))
2020-05-11 14:56:19 +00:00
Louis Pontoise 34e6877c09 fix: update korean localization 2020-05-11 23:45:51 +09:00
Louis Pontoise 1927f2cbf0 feat: localize release notes using google translate 2020-05-11 23:45:51 +09:00
semantic-release-bot 9f5328b7c8 chore(release): 3.22.6 [skip ci]
## [3.22.6](https://github.com/lwouis/alt-tab-macos/compare/v3.22.5...v3.22.6) (2020-05-10)

### Bug Fixes

* exotic scenario where the os reports no main screen (closes [#330](https://github.com/lwouis/alt-tab-macos/issues/330)) ([f83ef40](https://github.com/lwouis/alt-tab-macos/commit/f83ef40))
2020-05-10 19:58:54 +00:00
Louis Pontoise f83ef40c42 fix: exotic scenario where the os reports no main screen (closes #330) 2020-05-11 04:50:26 +09:00
semantic-release-bot d843781d7a chore(release): 3.22.5 [skip ci]
## [3.22.5](https://github.com/lwouis/alt-tab-macos/compare/v3.22.4...v3.22.5) (2020-05-10)

### Bug Fixes

* implement a 2min timeout for unresponsive apps (closes [#274](https://github.com/lwouis/alt-tab-macos/issues/274)) ([7ab7c82](https://github.com/lwouis/alt-tab-macos/commit/7ab7c82))
2020-05-10 18:46:33 +00:00
Louis Pontoise 7ab7c82acf fix: implement a 2min timeout for unresponsive apps (closes #274) 2020-05-11 03:37:22 +09:00
semantic-release-bot b0ff902672 chore(release): 3.22.4 [skip ci]
## [3.22.4](https://github.com/lwouis/alt-tab-macos/compare/v3.22.3...v3.22.4) (2020-05-10)

### Bug Fixes

* update korean localization ([0b61bce](https://github.com/lwouis/alt-tab-macos/commit/0b61bce))
* workaround some odd bug that's breaking protege.app (closes [#314](https://github.com/lwouis/alt-tab-macos/issues/314)) ([8f4efdf](https://github.com/lwouis/alt-tab-macos/commit/8f4efdf))
2020-05-10 14:45:20 +00:00
Louis Pontoise 0b61bce3a6 fix: update korean localization 2020-05-10 23:36:20 +09:00
Louis Pontoise 8f4efdfa97 fix: workaround some odd bug that's breaking protege.app (closes #314) 2020-05-10 23:36:20 +09:00
semantic-release-bot 2729426aec chore(release): 3.22.3 [skip ci]
## [3.22.3](https://github.com/lwouis/alt-tab-macos/compare/v3.22.2...v3.22.3) (2020-05-10)
2020-05-10 03:43:06 +00:00
Louis Pontoise 6b4007a045 ci: call a webhook to redeploy the website
the issue with netlify building on master changes is that semantic-release creates a second commit with the updated changelog. Netlify only triggers on the first commit, with an obsolete changelog. The second commit doesn't trigger Netlify, so we must manually trigger it using their webhook. This way the changelog built is *after* semantic-release, with the latest releases
2020-05-10 12:34:22 +09:00
semantic-release-bot cb7a740288 chore(release): 3.22.2 [skip ci]
## [3.22.2](https://github.com/lwouis/alt-tab-macos/compare/v3.22.1...v3.22.2) (2020-05-10)

### Bug Fixes

* auto-update was pointing to the wrong release notes url ([b5f1499](https://github.com/lwouis/alt-tab-macos/commit/b5f1499))
* crash on launch trying to open a file that was renamed ([52b8666](https://github.com/lwouis/alt-tab-macos/commit/52b8666))
2020-05-10 03:14:29 +00:00
Louis Pontoise b5f14994f2 fix: auto-update was pointing to the wrong release notes url 2020-05-10 12:05:33 +09:00
Louis Pontoise 52b8666d0b fix: crash on launch trying to open a file that was renamed 2020-05-10 12:05:33 +09:00
semantic-release-bot bceb849409 chore(release): 3.22.1 [skip ci]
## [3.22.1](https://github.com/lwouis/alt-tab-macos/compare/v3.22.0...v3.22.1) (2020-05-10)
2020-05-10 02:46:36 +00:00
Louis Pontoise 8f798b4ddc docs: faster website by adding turbolinks and inlining css 2020-05-10 11:36:53 +09:00
Louis Pontoise 33473d61a2 docs: fix release notes page title 2020-05-10 11:36:53 +09:00
Louis Pontoise 04275432f0 docs: better layout for website on small mobile screens 2020-05-10 11:36:53 +09:00
semantic-release-bot 9a676983ff chore(release): 3.22.0 [skip ci]
# [3.22.0](https://github.com/lwouis/alt-tab-macos/compare/v3.21.2...v3.22.0) (2020-05-10)

### Features

* add preference: fade out animation for the main ui (closes [#234](https://github.com/lwouis/alt-tab-macos/issues/234)) ([ee30725](https://github.com/lwouis/alt-tab-macos/commit/ee30725))
2020-05-10 01:27:50 +00:00
Louis Pontoise dd173115b3 docs: fix broken screenshot on the readme 2020-05-10 10:18:12 +09:00
Louis Pontoise c9dc597381 ci: add missing empty localizations 2020-05-10 10:18:10 +09:00
lwouis 83cda5034b ci: add issue templates 2020-05-10 10:06:10 +09:00
Louis Pontoise 717d7a9ec8 ci: replace pr greeter with pr template (closes #282) 2020-05-10 10:06:10 +09:00
Louis Pontoise c27e6d3757 docs: add a new website to showcase the app 2020-05-10 10:06:10 +09:00
Louis Pontoise ee307259c4 feat: add preference: fade out animation for the main ui (closes #234) 2020-05-10 10:06:10 +09:00
semantic-release-bot 257b8a369c chore(release): 3.21.2 [skip ci]
## [3.21.2](https://github.com/lwouis/alt-tab-macos/compare/v3.21.1...v3.21.2) (2020-05-08)

### Bug Fixes

* improved chinese localization ([3269a26](https://github.com/lwouis/alt-tab-macos/commit/3269a26))
* update cocoapod for letsmove ([0068dd2](https://github.com/lwouis/alt-tab-macos/commit/0068dd2))
2020-05-08 17:09:51 +00:00
Louis Pontoise 194fe157b3 ci: ensure generated files are up-to-dates during ci 2020-05-09 02:00:42 +09:00
Louis Pontoise 1a28cfa552 refactor: updating to cocoapods 1.9.1 to match ci 2020-05-09 02:00:42 +09:00
Louis Pontoise c56e1a614b ci: only build on master and pull-requests 2020-05-09 02:00:42 +09:00
Louis Pontoise 0068dd25d5 fix: update cocoapod for letsmove 2020-05-09 02:00:42 +09:00
Louis Pontoise d544ff3b7a refactor: make l10n script fork->join properly 2020-05-09 02:00:42 +09:00
Louis Pontoise 2df72af809 docs: move changelog to docs folder 2020-05-09 02:00:42 +09:00
Louis Pontoise 9a04c275cb docs: add a list of contributors 2020-05-09 02:00:42 +09:00
Louis Pontoise 3269a26ad9 fix: improved chinese localization 2020-05-09 02:00:42 +09:00
Louis Pontoise 906a308c54 refactor: remove warnings and simplify code 2020-05-09 02:00:42 +09:00
semantic-release-bot 86ca245c10 chore(release): 3.21.1 [skip ci]
## [3.21.1](https://github.com/lwouis/alt-tab-macos/compare/v3.21.0...v3.21.1) (2020-05-08)

### Bug Fixes

* arrow keys shortcuts for right-to-left languages ([33b7094](https://github.com/lwouis/alt-tab-macos/commit/33b7094))
* thumbnails layout issues (especially in right-to-left languages) ([f3cb544](https://github.com/lwouis/alt-tab-macos/commit/f3cb544))
2020-05-08 11:23:12 +00:00
Louis Pontoise f3cb544fb5 fix: thumbnails layout issues (especially in right-to-left languages) 2020-05-08 19:40:22 +09:00
Louis Pontoise 6f04c96afb refactor: more descriptive function name 2020-05-08 19:40:22 +09:00
Louis Pontoise 33b7094d8f fix: arrow keys shortcuts for right-to-left languages 2020-05-08 19:40:22 +09:00
semantic-release-bot 7e35d7c0e3 chore(release): 3.21.0 [skip ci]
# [3.21.0](https://github.com/lwouis/alt-tab-macos/compare/v3.20.0...v3.21.0) (2020-05-07)

### Features

* localize the main ui for right-to-left languages ([c9e72ee](https://github.com/lwouis/alt-tab-macos/commit/c9e72ee))
2020-05-07 20:23:07 +00:00
Louis Pontoise c9e72ee8d5 feat: localize the main ui for right-to-left languages 2020-05-08 05:14:17 +09:00
Louis Pontoise b9092312c7 refactor: minor cleanup 2020-05-08 05:14:17 +09:00
Louis Pontoise 10abb7ae78 docs: update supported languages on the readme 2020-05-08 05:14:17 +09:00
semantic-release-bot 2e9808d673 chore(release): 3.20.0 [skip ci]
# [3.20.0](https://github.com/lwouis/alt-tab-macos/compare/v3.19.2...v3.20.0) (2020-05-07)

### Bug Fixes

* thumbnails have a minimum width to help with tall windows ([a60750c](https://github.com/lwouis/alt-tab-macos/commit/a60750c))

### Features

* smarter padding around thumbnails (closes [#126](https://github.com/lwouis/alt-tab-macos/issues/126)) ([a94582f](https://github.com/lwouis/alt-tab-macos/commit/a94582f))
2020-05-07 18:39:55 +00:00
Louis Pontoise a94582f7f6 feat: smarter padding around thumbnails (closes #126) 2020-05-08 03:29:38 +09:00
Louis Pontoise a60750c415 fix: thumbnails have a minimum width to help with tall windows
this was a regression introduced around the rewrite from NSCollectionView to custom NSView where i missed the minimum width bit
2020-05-08 03:29:38 +09:00
Louis Pontoise 29d384552b docs: add more details to inline comment 2020-05-08 03:29:38 +09:00
Louis Pontoise fe010b0d88 docs: extract new localization for poeditor 2020-05-08 03:29:38 +09:00
Louis Pontoise 7f6943cd0f docs: more use-cases for qa 2020-05-08 03:29:38 +09:00
semantic-release-bot 175f962a28 chore(release): 3.19.2 [skip ci]
## [3.19.2](https://github.com/lwouis/alt-tab-macos/compare/v3.19.1...v3.19.2) (2020-05-07)

### Bug Fixes

* would not correctly show windows/tabs from other spaces ([873f985](https://github.com/lwouis/alt-tab-macos/commit/873f985))
2020-05-07 05:19:31 +00:00
Louis Pontoise 873f98525e fix: would not correctly show windows/tabs from other spaces 2020-05-07 14:11:22 +09:00
semantic-release-bot 6681a85111 chore(release): 3.19.1 [skip ci]
## [3.19.1](https://github.com/lwouis/alt-tab-macos/compare/v3.19.0...v3.19.1) (2020-05-06)

### Bug Fixes

* fast shortcut press would fail to switch windows ([2ee5eb5](https://github.com/lwouis/alt-tab-macos/commit/2ee5eb5))
2020-05-06 17:44:08 +00:00
Louis Pontoise 2ee5eb5a96 fix: fast shortcut press would fail to switch windows
With many windows open, and a blazing fast shortcut press, AltTab would fail to switch as it would queue the focus task before the cycling task
2020-05-07 02:35:45 +09:00
semantic-release-bot 2399698748 chore(release): 3.19.0 [skip ci]
# [3.19.0](https://github.com/lwouis/alt-tab-macos/compare/v3.18.0...v3.19.0) (2020-05-06)

### Bug Fixes

* don't display invalid windows (may fix [#292](https://github.com/lwouis/alt-tab-macos/issues/292) [#200](https://github.com/lwouis/alt-tab-macos/issues/200)) ([1bca012](https://github.com/lwouis/alt-tab-macos/commit/1bca012))
* don't display tabbed windows (closes [#258](https://github.com/lwouis/alt-tab-macos/issues/258)) ([8419ad9](https://github.com/lwouis/alt-tab-macos/commit/8419ad9))
* update french localization ([445980a](https://github.com/lwouis/alt-tab-macos/commit/445980a))

### Features

* add dutch localization ([b8eb0b4](https://github.com/lwouis/alt-tab-macos/commit/b8eb0b4))
* add preference: show standard tabs as windows ([3a11cc6](https://github.com/lwouis/alt-tab-macos/commit/3a11cc6))
2020-05-06 17:11:04 +00:00
Louis Pontoise 1bca012faa fix: don't display invalid windows (may fix #292 #200) 2020-05-07 02:00:45 +09:00
Louis Pontoise 3a11cc6dbd feat: add preference: show standard tabs as windows 2020-05-07 02:00:45 +09:00
Louis Pontoise 8419ad9fce fix: don't display tabbed windows (closes #258) 2020-05-07 02:00:45 +09:00
Louis Pontoise b8eb0b4f32 feat: add dutch localization 2020-05-07 02:00:45 +09:00
Louis Pontoise 445980ac7d fix: update french localization 2020-05-07 02:00:45 +09:00
semantic-release-bot 6ac0c252d5 chore(release): 3.18.0 [skip ci]
# [3.18.0](https://github.com/lwouis/alt-tab-macos/compare/v3.17.2...v3.18.0) (2020-05-05)

### Bug Fixes

* activate shortcuts without updating their userdefaults ([6aad3e7](https://github.com/lwouis/alt-tab-macos/commit/6aad3e7))
* can close feedback window with escape key ([05fb4a2](https://github.com/lwouis/alt-tab-macos/commit/05fb4a2))
* correctly display right-to-left languages ([89f2df4](https://github.com/lwouis/alt-tab-macos/commit/89f2df4))
* more robust preference migrations (closes [#220](https://github.com/lwouis/alt-tab-macos/issues/220)) ([bf857e8](https://github.com/lwouis/alt-tab-macos/commit/bf857e8))

### Features

* add arabic localization ([0a1bb6e](https://github.com/lwouis/alt-tab-macos/commit/0a1bb6e))
* check for updates weekly instead of daily ([02920a7](https://github.com/lwouis/alt-tab-macos/commit/02920a7)), closes [#295](https://github.com/lwouis/alt-tab-macos/issues/295)
* update german localization ([1925777](https://github.com/lwouis/alt-tab-macos/commit/1925777))
2020-05-05 19:43:48 +00:00
Louis Pontoise 0a1bb6edef feat: add arabic localization 2020-05-06 04:34:58 +09:00
Louis Pontoise 89f2df4fe5 fix: correctly display right-to-left languages 2020-05-06 04:34:58 +09:00
Louis Pontoise 37d8c98503 docs: list more tricky scenarios for qa 2020-05-06 04:34:58 +09:00
Louis Pontoise 05fb4a2dff fix: can close feedback window with escape key 2020-05-06 04:34:58 +09:00
Louis Pontoise 19257773ec feat: update german localization 2020-05-06 04:34:58 +09:00
Louis Pontoise 02920a77df feat: check for updates weekly instead of daily
closes #295
2020-05-06 04:34:58 +09:00
Louis Pontoise bf857e8f25 fix: more robust preference migrations (closes #220) 2020-05-06 04:34:58 +09:00
Louis Pontoise 6aad3e7724 fix: activate shortcuts without updating their userdefaults 2020-05-06 04:34:58 +09:00
semantic-release-bot b3ba94fe0f chore(release): 3.17.2 [skip ci]
## [3.17.2](https://github.com/lwouis/alt-tab-macos/compare/v3.17.1...v3.17.2) (2020-05-05)

### Bug Fixes

* fit preferences tabs on small screens ([6096ce5](https://github.com/lwouis/alt-tab-macos/commit/6096ce5))
2020-05-05 09:48:20 +00:00
Louis Pontoise 0f24d6f88e refactor: add subscription loops to debug profile 2020-05-05 18:38:41 +09:00
Louis Pontoise 6096ce50d4 fix: fit preferences tabs on small screens 2020-05-05 18:38:41 +09:00
semantic-release-bot ea2b3fa8d0 chore(release): 3.17.1 [skip ci]
## [3.17.1](https://github.com/lwouis/alt-tab-macos/compare/v3.17.0...v3.17.1) (2020-04-29)

### Bug Fixes

* plug some minor memory leaks ([0de7a55](https://github.com/lwouis/alt-tab-macos/commit/0de7a55))
* use windows nominal resolution for better performance ([a7cc3be](https://github.com/lwouis/alt-tab-macos/commit/a7cc3be))
2020-04-29 18:09:21 +00:00
Louis Pontoise a7cc3bed0c fix: use windows nominal resolution for better performance 2020-04-30 01:36:38 +09:00
Louis Pontoise ad8d870364 fixup! fix: plug some minor memory leaks 2020-04-30 01:36:38 +09:00
Louis Pontoise 0de7a5515c fix: plug some minor memory leaks 2020-04-30 01:36:38 +09:00
semantic-release-bot 5a4f206bb4 chore(release): 3.17.0 [skip ci]
# [3.17.0](https://github.com/lwouis/alt-tab-macos/compare/v3.16.3...v3.17.0) (2020-04-27)

### Bug Fixes

* shift key + scroll should scroll the ui ([d64a6a5](https://github.com/lwouis/alt-tab-macos/commit/d64a6a5))
* update russian localization ([942c4d7](https://github.com/lwouis/alt-tab-macos/commit/942c4d7))

### Features

* navigate with up/down arrow keys (closes [#270](https://github.com/lwouis/alt-tab-macos/issues/270)) ([cc61ed4](https://github.com/lwouis/alt-tab-macos/commit/cc61ed4))
2020-04-27 10:10:34 +00:00
Louis Pontoise 942c4d7df3 fix: update russian localization 2020-04-27 19:01:51 +09:00
Louis Pontoise cc61ed4607 feat: navigate with up/down arrow keys (closes #270) 2020-04-27 19:01:51 +09:00
Louis Pontoise d64a6a520a fix: shift key + scroll should scroll the ui 2020-04-27 19:01:51 +09:00
Louis Pontoise 3420a60332 refactor: remove unused code 2020-04-27 19:01:51 +09:00
Louis Pontoise d8506ed192 refactor: migrate to swift 5 2020-04-27 19:01:51 +09:00
semantic-release-bot 9370b2dcee chore(release): 3.16.3 [skip ci]
## [3.16.3](https://github.com/lwouis/alt-tab-macos/compare/v3.16.2...v3.16.3) (2020-04-25)

### Bug Fixes

* suggest moving the app to the global applications folder ([91e31da](https://github.com/lwouis/alt-tab-macos/commit/91e31da)), closes [#267](https://github.com/lwouis/alt-tab-macos/issues/267)
2020-04-25 16:46:16 +00:00
Louis Pontoise 91e31da876 fix: suggest moving the app to the global applications folder
closes #267
2020-04-26 01:37:23 +09:00
Louis Pontoise 9540a9eb84 refactor: add cpu/mem utilization to debug report 2020-04-26 01:37:23 +09:00
semantic-release-bot b75ee9ba20 chore(release): 3.16.2 [skip ci]
## [3.16.2](https://github.com/lwouis/alt-tab-macos/compare/v3.16.1...v3.16.2) (2020-04-25)

### Bug Fixes

* removing accessibility permission breaks keyboard inputs ([0da3d33](https://github.com/lwouis/alt-tab-macos/commit/0da3d33)), closes [#269](https://github.com/lwouis/alt-tab-macos/issues/269)
2020-04-25 03:01:32 +00:00
Louis Pontoise 7ca8c52629 refactor: add todo and fix indentation 2020-04-25 11:53:04 +09:00
Louis Pontoise 0da3d33340 fix: removing accessibility permission breaks keyboard inputs
closes #269
2020-04-25 11:53:04 +09:00
semantic-release-bot ef6ee72286 chore(release): 3.16.1 [skip ci]
## [3.16.1](https://github.com/lwouis/alt-tab-macos/compare/v3.16.0...v3.16.1) (2020-04-24)

### Bug Fixes

* app could sometimes crash on closing the ui ([61db5b4](https://github.com/lwouis/alt-tab-macos/commit/61db5b4))
2020-04-24 23:01:28 +00:00
Louis Pontoise 30c656ee03 refactor: missing russian l10n files in xcodeproj 2020-04-25 07:52:13 +09:00
Louis Pontoise 61db5b4fb6 fix: app could sometimes crash on closing the ui 2020-04-25 07:52:13 +09:00
semantic-release-bot 5f828f61b3 chore(release): 3.16.0 [skip ci]
# [3.16.0](https://github.com/lwouis/alt-tab-macos/compare/v3.15.0...v3.16.0) (2020-04-24)

### Features

* added russian localization ([f0971c2](https://github.com/lwouis/alt-tab-macos/commit/f0971c2))
2020-04-24 01:49:22 +00:00
Louis Pontoise f0971c21e7 feat: added russian localization 2020-04-24 10:34:21 +09:00
semantic-release-bot 61f341c741 chore(release): 3.15.0 [skip ci]
# [3.15.0](https://github.com/lwouis/alt-tab-macos/compare/v3.14.0...v3.15.0) (2020-04-23)

### Bug Fixes

* debug profile spaces count was incorrect ([e98d401](https://github.com/lwouis/alt-tab-macos/commit/e98d401))
* handle windows assigned to all spaces (closes [#266](https://github.com/lwouis/alt-tab-macos/issues/266)) ([e35fe6b](https://github.com/lwouis/alt-tab-macos/commit/e35fe6b))

### Features

* add warning for email-less feedback ([1acd918](https://github.com/lwouis/alt-tab-macos/commit/1acd918))
2020-04-23 18:33:15 +00:00
Louis Pontoise 66a3469264 refactor: add windows count to debug profile 2020-04-24 02:44:12 +09:00
Louis Pontoise e98d401dc5 fix: debug profile spaces count was incorrect 2020-04-24 02:44:12 +09:00
Louis Pontoise e35fe6b6c8 fix: handle windows assigned to all spaces (closes #266) 2020-04-24 02:44:12 +09:00
Louis Pontoise 1acd918511 feat: add warning for email-less feedback 2020-04-24 02:44:12 +09:00
semantic-release-bot 0bdf56bf63 chore(release): 3.14.0 [skip ci]
# [3.14.0](https://github.com/lwouis/alt-tab-macos/compare/v3.13.0...v3.14.0) (2020-04-22)

### Features

* add portuguese and finish japanese localizations ([d1ab72f](https://github.com/lwouis/alt-tab-macos/commit/d1ab72f))
* update all localizations ([a2dd46d](https://github.com/lwouis/alt-tab-macos/commit/a2dd46d))
2020-04-22 18:13:41 +00:00
Louis Pontoise a2dd46db55 feat: update all localizations
complete italian, turkish, korean using automated translation
fix punctuation issues and make punctuation language-specific instead of hardcoded to English style
2020-04-23 03:04:26 +09:00
Louis Pontoise b90ad066ce docs: improve readme a bit 2020-04-23 03:04:26 +09:00
Louis Pontoise d1ab72fa94 feat: add portuguese and finish japanese localizations
also fix the codes for Chinese locales
2020-04-23 03:04:26 +09:00
semantic-release-bot 31adc14c71 chore(release): 3.13.0 [skip ci]
# [3.13.0](https://github.com/lwouis/alt-tab-macos/compare/v3.12.0...v3.13.0) (2020-04-21)

### Bug Fixes

* showed rows with 1 too-few windows sometimes (see [#256](https://github.com/lwouis/alt-tab-macos/issues/256)) ([0eac086](https://github.com/lwouis/alt-tab-macos/commit/0eac086))

### Features

* add hungarian localization ([ba7b5d3](https://github.com/lwouis/alt-tab-macos/commit/ba7b5d3))
2020-04-21 11:48:40 +00:00
Louis Pontoise ba7b5d3f1d feat: add hungarian localization 2020-04-21 20:40:05 +09:00
Louis Pontoise 13c1cb0d00 refactor: clean and reorder l10n alphabetically 2020-04-21 20:40:05 +09:00
Louis Pontoise be71137a39 refactor: separate global event handling code 2020-04-21 20:40:05 +09:00
Louis Pontoise 0eac0867c0 fix: showed rows with 1 too-few windows sometimes (see #256) 2020-04-21 20:40:05 +09:00
Louis Pontoise c3749a871a refactor: simplify concurrency and shortcuts code 2020-04-21 20:40:05 +09:00
semantic-release-bot 13b2844196 chore(release): 3.12.0 [skip ci]
# [3.12.0](https://github.com/lwouis/alt-tab-macos/compare/v3.11.0...v3.12.0) (2020-04-20)

### Bug Fixes

* updated localizations ([eec6912](https://github.com/lwouis/alt-tab-macos/commit/eec6912))

### Features

* collapsible debug profile in feedback report ([d6960d5](https://github.com/lwouis/alt-tab-macos/commit/d6960d5))
2020-04-20 13:14:38 +00:00
Louis Pontoise eec691293a fix: updated localizations
* Added new translations for: german, chinese (simplified), chinese (taiwan)
* Fixed punctuation in English, French, Italian
2020-04-20 22:05:57 +09:00
Louis Pontoise d6960d5eb5 feat: collapsible debug profile in feedback report 2020-04-20 22:05:57 +09:00
Louis Pontoise 941a101320 refactor: update localizations (also imported in poeditor.com) 2020-04-20 22:05:57 +09:00
semantic-release-bot 7a7a88c901 chore(release): 3.11.0 [skip ci]
# [3.11.0](https://github.com/lwouis/alt-tab-macos/compare/v3.10.0...v3.11.0) (2020-04-19)

### Features

* add app quit shortcut ([7a94e4a](https://github.com/lwouis/alt-tab-macos/commit/7a94e4a))
* add close window shortcut ([8da8af8](https://github.com/lwouis/alt-tab-macos/commit/8da8af8))
* add hide/show app shortcut ([6be1c2c](https://github.com/lwouis/alt-tab-macos/commit/6be1c2c))
* add min/demin window shortcut ([2b752ef](https://github.com/lwouis/alt-tab-macos/commit/2b752ef))
* add preference: display the ui on screen including menu bar ([156957c](https://github.com/lwouis/alt-tab-macos/commit/156957c))
* faster initial display of some windows ([3286570](https://github.com/lwouis/alt-tab-macos/commit/3286570))
2020-04-19 16:58:00 +00:00
Daniel Montesinos 156957c376 feat: add preference: display the ui on screen including menu bar 2020-04-20 01:49:25 +09:00
Louis Pontoise 6be1c2ccca feat: add hide/show app shortcut 2020-04-20 01:49:25 +09:00
Louis Pontoise 2b752efb72 feat: add min/demin window shortcut 2020-04-20 01:49:25 +09:00
Louis Pontoise 7a94e4a124 feat: add app quit shortcut 2020-04-20 01:49:25 +09:00
Louis Pontoise b140243b19 refactor: change order of preferences tabs 2020-04-20 01:49:25 +09:00
Louis Pontoise 32865706a6 feat: faster initial display of some windows 2020-04-20 01:49:25 +09:00
Louis Pontoise 8da8af8fc3 feat: add close window shortcut 2020-04-20 01:49:25 +09:00
Louis Pontoise 9d531dd487 refactor: remove Pods files from .pbxproj 2020-04-20 01:49:25 +09:00
semantic-release-bot 740f5fb271 chore(release): 3.10.0 [skip ci]
# [3.10.0](https://github.com/lwouis/alt-tab-macos/compare/v3.9.1...v3.10.0) (2020-04-19)

### Bug Fixes

* issues with preferences window on mojave (closes [#233](https://github.com/lwouis/alt-tab-macos/issues/233)) ([8d7f121](https://github.com/lwouis/alt-tab-macos/commit/8d7f121))

### Features

* trim fonticon to reduce app size (closes [#168](https://github.com/lwouis/alt-tab-macos/issues/168)) ([0d27cf7](https://github.com/lwouis/alt-tab-macos/commit/0d27cf7))
2020-04-19 09:01:00 +00:00
Louis Pontoise 8d7f121f3d fix: issues with preferences window on mojave (closes #233) 2020-04-19 17:53:15 +09:00
Louis Pontoise 0d27cf77a4 feat: trim fonticon to reduce app size (closes #168) 2020-04-19 17:53:15 +09:00
semantic-release-bot 81afaff9bb chore(release): 3.9.1 [skip ci]
## [3.9.1](https://github.com/lwouis/alt-tab-macos/compare/v3.9.0...v3.9.1) (2020-04-18)

### Bug Fixes

* show windows from steam app (closes [#236](https://github.com/lwouis/alt-tab-macos/issues/236)) ([d17c9d5](https://github.com/lwouis/alt-tab-macos/commit/d17c9d5))
* thumbnails layout was wrong sometimes ([06c6f48](https://github.com/lwouis/alt-tab-macos/commit/06c6f48))
2020-04-18 18:39:40 +00:00
Louis Pontoise 06c6f480bc fix: thumbnails layout was wrong sometimes
this is a regression introduced by 4eb9db0
2020-04-19 03:32:24 +09:00
Louis Pontoise d17c9d5493 fix: show windows from steam app (closes #236) 2020-04-19 03:32:24 +09:00
semantic-release-bot 935d556b1e chore(release): 3.9.0 [skip ci]
# [3.9.0](https://github.com/lwouis/alt-tab-macos/compare/v3.8.0...v3.9.0) (2020-04-18)

### Features

* allow shortcuts to be modifiers-only (closes [#243](https://github.com/lwouis/alt-tab-macos/issues/243)) ([d4be095](https://github.com/lwouis/alt-tab-macos/commit/d4be095))
2020-04-18 16:37:33 +00:00
Louis Pontoise d4be0954d7 feat: allow shortcuts to be modifiers-only (closes #243) 2020-04-19 01:29:54 +09:00
Louis Pontoise 2e0c096612 refactor: commit dependencies to secure access to them 2020-04-19 01:29:54 +09:00
semantic-release-bot e89ae7226e chore(release): 3.8.0 [skip ci]
# [3.8.0](https://github.com/lwouis/alt-tab-macos/compare/v3.7.3...v3.8.0) (2020-04-18)

### Bug Fixes

* clearer debug profile (i.e. no "optional") ([e2b94f7](https://github.com/lwouis/alt-tab-macos/commit/e2b94f7))

### Features

* add acknowledgments for third-party software (closes [#177](https://github.com/lwouis/alt-tab-macos/issues/177)) ([9398cff](https://github.com/lwouis/alt-tab-macos/commit/9398cff))
* remove runtime checker for better perf ([e9ce575](https://github.com/lwouis/alt-tab-macos/commit/e9ce575))
2020-04-18 15:45:13 +00:00
Louis Pontoise 9398cff1e9 feat: add acknowledgments for third-party software (closes #177) 2020-04-19 00:37:21 +09:00
Louis Pontoise 4faf31bd71 refactor: fix compiler warnings 2020-04-19 00:37:21 +09:00
Louis Pontoise e9ce575048 feat: remove runtime checker for better perf 2020-04-19 00:37:21 +09:00
Louis Pontoise ad05783753 refactor: faster swift compilation 2020-04-19 00:37:21 +09:00
Louis Pontoise dd20639ee1 refactor: add acknowledgments file to docs folder 2020-04-19 00:37:21 +09:00
Louis Pontoise 41e9b98ea9 refactor: add missing project files 2020-04-19 00:37:21 +09:00
Louis Pontoise e2b94f79e8 fix: clearer debug profile (i.e. no "optional") 2020-04-19 00:37:21 +09:00
semantic-release-bot 2023ea62cb chore(release): 3.7.3 [skip ci]
## [3.7.3](https://github.com/lwouis/alt-tab-macos/compare/v3.7.2...v3.7.3) (2020-04-09)

### Bug Fixes

* typos in korean and chinese labels (closes [#228](https://github.com/lwouis/alt-tab-macos/issues/228)) ([c655675](https://github.com/lwouis/alt-tab-macos/commit/c655675))
2020-04-09 07:51:35 +00:00
Louis Pontoise c655675508 fix: typos in korean and chinese labels (closes #228) 2020-04-09 16:41:36 +09:00
semantic-release-bot 4bfebf0562 chore(release): 3.7.2 [skip ci]
## [3.7.2](https://github.com/lwouis/alt-tab-macos/compare/v3.7.1...v3.7.2) (2020-04-09)

### Bug Fixes

* scrollbar works with all system preferences options (closes [#196](https://github.com/lwouis/alt-tab-macos/issues/196)) ([3289d3a](https://github.com/lwouis/alt-tab-macos/commit/3289d3a))
* some preferences were inactive but appeared active ([51ad28d](https://github.com/lwouis/alt-tab-macos/commit/51ad28d))
2020-04-09 06:03:30 +00:00
Louis Pontoise 3289d3ad99 fix: scrollbar works with all system preferences options (closes #196) 2020-04-09 14:56:14 +09:00
Louis Pontoise 51ad28dc09 fix: some preferences were inactive but appeared active 2020-04-09 14:56:14 +09:00
semantic-release-bot d2fbafa36e chore(release): 3.7.1 [skip ci]
## [3.7.1](https://github.com/lwouis/alt-tab-macos/compare/v3.7.0...v3.7.1) (2020-04-08)

### Bug Fixes

* better handling of preference migration (up/down) ([078c359](https://github.com/lwouis/alt-tab-macos/commit/078c359))
* hiding window should be on main thread ([767f900](https://github.com/lwouis/alt-tab-macos/commit/767f900))
* scrollbar only shows on scroll (closes [#196](https://github.com/lwouis/alt-tab-macos/issues/196)) ([c2abff0](https://github.com/lwouis/alt-tab-macos/commit/c2abff0))
* updated localizations, especially Spanish ([bd92828](https://github.com/lwouis/alt-tab-macos/commit/bd92828))
2020-04-08 18:33:15 +00:00
Louis Pontoise c2abff0617 fix: scrollbar only shows on scroll (closes #196) 2020-04-09 03:23:55 +09:00
Louis Pontoise 767f90029e fix: hiding window should be on main thread 2020-04-09 03:23:55 +09:00
Louis Pontoise bd92828d42 fix: updated localizations, especially Spanish 2020-04-09 03:23:55 +09:00
Louis Pontoise 078c359d3d fix: better handling of preference migration (up/down) 2020-04-09 03:23:55 +09:00
semantic-release-bot 178d1bcb5c chore(release): 3.7.0 [skip ci]
# [3.7.0](https://github.com/lwouis/alt-tab-macos/compare/v3.6.2...v3.7.0) (2020-04-08)

### Bug Fixes

* avoid crash when upgrading due to old preferences (closes [#222](https://github.com/lwouis/alt-tab-macos/issues/222)) ([66a2bd8](https://github.com/lwouis/alt-tab-macos/commit/66a2bd8))

### Features

* add dark-mode in the debug profile on reports ([a54eb77](https://github.com/lwouis/alt-tab-macos/commit/a54eb77))
2020-04-08 15:14:12 +00:00
Louis Pontoise 66a2bd8797 fix: avoid crash when upgrading due to old preferences (closes #222) 2020-04-09 00:04:18 +09:00
Louis Pontoise a54eb77b18 feat: add dark-mode in the debug profile on reports 2020-04-09 00:04:18 +09:00
semantic-release-bot b99b40fc02 chore(release): 3.6.2 [skip ci]
## [3.6.2](https://github.com/lwouis/alt-tab-macos/compare/v3.6.1...v3.6.2) (2020-04-08)

### Bug Fixes

* avoid text flickering on main ui (closes [#197](https://github.com/lwouis/alt-tab-macos/issues/197)) ([4eb9db0](https://github.com/lwouis/alt-tab-macos/commit/4eb9db0))
* dropdown preferences crashed in non-english (closes [#217](https://github.com/lwouis/alt-tab-macos/issues/217)) ([5447d5f](https://github.com/lwouis/alt-tab-macos/commit/5447d5f))
2020-04-08 10:37:16 +00:00
Louis Pontoise 5447d5fc21 fix: dropdown preferences crashed in non-english (closes #217) 2020-04-08 19:28:53 +09:00
Louis Pontoise 4eb9db049b fix: avoid text flickering on main ui (closes #197) 2020-04-08 19:28:53 +09:00
semantic-release-bot 584b3cd397 chore(release): 3.6.1 [skip ci]
## [3.6.1](https://github.com/lwouis/alt-tab-macos/compare/v3.6.0...v3.6.1) (2020-04-08)

### Bug Fixes

* prevent hold/release shortcut from being empty ([1158a32](https://github.com/lwouis/alt-tab-macos/commit/1158a32))
2020-04-08 07:25:47 +00:00
Louis Pontoise 1158a32126 fix: prevent hold/release shortcut from being empty 2020-04-08 16:18:00 +09:00
semantic-release-bot 5019349104 chore(release): 3.6.0 [skip ci]
# [3.6.0](https://github.com/lwouis/alt-tab-macos/compare/v3.5.0...v3.6.0) (2020-04-07)

### Bug Fixes

* focus correct window after app quits (see [#213](https://github.com/lwouis/alt-tab-macos/issues/213)) ([7f27cb9](https://github.com/lwouis/alt-tab-macos/commit/7f27cb9))
* workaround the bug in parsec (closes [#206](https://github.com/lwouis/alt-tab-macos/issues/206)) ([59c6afc](https://github.com/lwouis/alt-tab-macos/commit/59c6afc))

### Features

* let users disable shortcuts ([5b03415](https://github.com/lwouis/alt-tab-macos/commit/5b03415))
* updated localization for 7 languages ([bc2a38b](https://github.com/lwouis/alt-tab-macos/commit/bc2a38b))
2020-04-07 09:14:27 +00:00
Louis Pontoise 59c6afcf61 fix: workaround the bug in parsec (closes #206) 2020-04-07 18:06:26 +09:00
Louis Pontoise 5b0341539c feat: let users disable shortcuts 2020-04-07 18:06:26 +09:00
Louis Pontoise 7f27cb950b fix: focus correct window after app quits (see #213) 2020-04-07 18:06:26 +09:00
Louis Pontoise bc2a38b616 feat: updated localization for 7 languages 2020-04-07 18:06:26 +09:00
semantic-release-bot cf9b959044 chore(release): 3.5.0 [skip ci]
# [3.5.0](https://github.com/lwouis/alt-tab-macos/compare/v3.4.1...v3.5.0) (2020-04-05)

### Bug Fixes

* **readme:** sort language list and add Finnish ([42dbd30](https://github.com/lwouis/alt-tab-macos/commit/42dbd30))

### Features

* **i18n:** add Finnish localization ([770d472](https://github.com/lwouis/alt-tab-macos/commit/770d472))
2020-04-05 13:35:24 +00:00
Aarni Koskela 42dbd30323 fix(readme): sort language list and add Finnish
All language names are non-capitalized in Finnish, but
I assume this list is in title case, so it's not the correct "suomi".
2020-04-05 22:28:21 +09:00
Aarni Koskela 770d472759 feat(i18n): add Finnish localization 2020-04-05 22:28:21 +09:00
semantic-release-bot 4a7a472adb chore(release): 3.4.1 [skip ci]
## [3.4.1](https://github.com/lwouis/alt-tab-macos/compare/v3.4.0...v3.4.1) (2020-04-05)
2020-04-05 13:20:14 +00:00
Louis Pontoise 27a4c37250 ci: fix build on pr from forks 2020-04-05 21:58:24 +09:00
semantic-release-bot b5c81388d3 chore(release): 3.4.0 [skip ci]
# [3.4.0](https://github.com/lwouis/alt-tab-macos/compare/v3.3.3...v3.4.0) (2020-04-03)

### Features

* updated some localizations ([b38d688](https://github.com/lwouis/alt-tab-macos/commit/b38d688))
2020-04-03 06:51:15 +00:00
Louis Pontoise b38d688a14 feat: updated some localizations 2020-04-03 15:43:46 +09:00
Louis Pontoise 7ce3a6f576 refactor: removed unused variable 2020-04-03 15:43:46 +09:00
semantic-release-bot a9586bc185 chore(release): 3.3.3 [skip ci]
## [3.3.3](https://github.com/lwouis/alt-tab-macos/compare/v3.3.2...v3.3.3) (2020-04-03)

### Bug Fixes

* "show all screens" pref was not respected (closes [#204](https://github.com/lwouis/alt-tab-macos/issues/204)) ([d4c13c4](https://github.com/lwouis/alt-tab-macos/commit/d4c13c4))
2020-04-03 04:18:29 +00:00
Louis Pontoise d4c13c458b fix: "show all screens" pref was not respected (closes #204) 2020-04-03 13:11:14 +09:00
semantic-release-bot 6d3faa9619 chore(release): 3.3.2 [skip ci]
## [3.3.2](https://github.com/lwouis/alt-tab-macos/compare/v3.3.1...v3.3.2) (2020-04-02)

### Bug Fixes

* crashed if an invalid login item existed (closes [#202](https://github.com/lwouis/alt-tab-macos/issues/202)) ([48d5d63](https://github.com/lwouis/alt-tab-macos/commit/48d5d63))
2020-04-02 16:23:17 +00:00
Louis Pontoise 48d5d6305e fix: crashed if an invalid login item existed (closes #202) 2020-04-03 01:15:44 +09:00
semantic-release-bot 19b742a073 chore(release): 3.3.1 [skip ci]
## [3.3.1](https://github.com/lwouis/alt-tab-macos/compare/v3.3.0...v3.3.1) (2020-04-02)

### Bug Fixes

* blind fix trying to guess root cause of [#202](https://github.com/lwouis/alt-tab-macos/issues/202) ([fb4fe11](https://github.com/lwouis/alt-tab-macos/commit/fb4fe11))
* checkboxes preferences were unchecked initially ([b091282](https://github.com/lwouis/alt-tab-macos/commit/b091282))
2020-04-02 12:33:51 +00:00
Louis Pontoise fb4fe11327 fix: blind fix trying to guess root cause of #202 2020-04-02 21:26:59 +09:00
Louis Pontoise b091282b54 fix: checkboxes preferences were unchecked initially 2020-04-02 21:26:59 +09:00
semantic-release-bot 4915b5703f chore(release): 3.3.0 [skip ci]
# [3.3.0](https://github.com/lwouis/alt-tab-macos/compare/v3.2.1...v3.3.0) (2020-04-02)

### Bug Fixes

* .strings encoding should be utf-8 ([7109b08](https://github.com/lwouis/alt-tab-macos/commit/7109b08))
* avoid having multiple login items ([65816a2](https://github.com/lwouis/alt-tab-macos/commit/65816a2))
* preferences would not be live (closes [#188](https://github.com/lwouis/alt-tab-macos/issues/188)) ([d5b74a1](https://github.com/lwouis/alt-tab-macos/commit/d5b74a1)), closes [#194](https://github.com/lwouis/alt-tab-macos/issues/194)
* simpler/better window focus ([574a640](https://github.com/lwouis/alt-tab-macos/commit/574a640))

### Features

* localized in 5 new languages ([48bb3df](https://github.com/lwouis/alt-tab-macos/commit/48bb3df))
* more flexible shortcuts (closes [#72](https://github.com/lwouis/alt-tab-macos/issues/72)) ([5eade75](https://github.com/lwouis/alt-tab-macos/commit/5eade75)), closes [#50](https://github.com/lwouis/alt-tab-macos/issues/50) [#125](https://github.com/lwouis/alt-tab-macos/issues/125) [#133](https://github.com/lwouis/alt-tab-macos/issues/133)
2020-04-02 10:46:57 +00:00
Louis Pontoise 5c51decf69 refactor: commit reference l10n file and script 2020-04-02 19:39:39 +09:00
Louis Pontoise 5eade75983 feat: more flexible shortcuts (closes #72)
closes #50, closes #125, closes #133
2020-04-02 19:39:39 +09:00
Louis Pontoise 48bb3df240 feat: localized in 5 new languages
Italiano, Türkçe, 汉语, 臺語, 한국어
2020-04-02 19:39:39 +09:00
Louis Pontoise 7109b08881 fix: .strings encoding should be utf-8 2020-04-02 19:39:39 +09:00
Louis Pontoise b0f7ce6050 docs: add l10n extraction command 2020-04-02 19:39:39 +09:00
Louis Pontoise 442c1ee2f3 docs: add contributors list 2020-04-02 19:39:39 +09:00
Louis Pontoise ef35a120f9 refactor: remove redundant autoreleasepool 2020-04-02 19:39:39 +09:00
Louis Pontoise c7f03daea9 refactor: add global app object to avoid casting 2020-04-02 19:39:39 +09:00
Louis Pontoise df8818dd30 docs: local dev should use debug build (closes #192) 2020-04-02 19:39:39 +09:00
Louis Pontoise d5b74a1afe fix: preferences would not be live (closes #188)
closes #194
2020-04-02 19:39:39 +09:00
Louis Pontoise 574a6401b9 fix: simpler/better window focus 2020-04-02 19:39:39 +09:00
Louis Pontoise 65816a270f fix: avoid having multiple login items 2020-04-02 19:39:39 +09:00
semantic-release-bot bc3f612f7a chore(release): 3.2.1 [skip ci]
## [3.2.1](https://github.com/lwouis/alt-tab-macos/compare/v3.2.0...v3.2.1) (2020-03-25)

### Bug Fixes

* chrome shortcuts apps don't show up (closes [#185](https://github.com/lwouis/alt-tab-macos/issues/185)) ([0b35ebf](https://github.com/lwouis/alt-tab-macos/commit/0b35ebf))
* don't hang waiting for faulty apps to reply (closes [#182](https://github.com/lwouis/alt-tab-macos/issues/182)) ([246cf69](https://github.com/lwouis/alt-tab-macos/commit/246cf69))
* hidden apps windows don't show hidden icon ([6e190bf](https://github.com/lwouis/alt-tab-macos/commit/6e190bf))
2020-03-25 05:50:35 +00:00
Louis Pontoise 0b35ebf0ff fix: chrome shortcuts apps don't show up (closes #185) 2020-03-25 14:41:18 +09:00
Louis Pontoise 6e190bf941 fix: hidden apps windows don't show hidden icon 2020-03-25 14:41:18 +09:00
Louis Pontoise 246cf69310 fix: don't hang waiting for faulty apps to reply (closes #182) 2020-03-25 14:41:18 +09:00
semantic-release-bot 9110f6947f chore(release): 3.2.0 [skip ci]
# [3.2.0](https://github.com/lwouis/alt-tab-macos/compare/v3.1.3...v3.2.0) (2020-03-24)

### Bug Fixes

* refresh both thumbnails on focus switch in bg ([4fee590](https://github.com/lwouis/alt-tab-macos/commit/4fee590))
* things in background properly reflect in ui ([fdf1524](https://github.com/lwouis/alt-tab-macos/commit/fdf1524))

### Features

* faster ui (closes [#171](https://github.com/lwouis/alt-tab-macos/issues/171), closes [#128](https://github.com/lwouis/alt-tab-macos/issues/128), closes [#89](https://github.com/lwouis/alt-tab-macos/issues/89)) ([311beef](https://github.com/lwouis/alt-tab-macos/commit/311beef))
2020-03-24 11:09:22 +00:00
Louis Pontoise 0223b55fc1 refactor: performance optimizations and clarity 2020-03-24 19:37:45 +09:00
Louis Pontoise 4fee5902b0 fix: refresh both thumbnails on focus switch in bg 2020-03-24 19:37:45 +09:00
Louis Pontoise 357c616930 refactor: small corrections 2020-03-24 19:37:45 +09:00
Louis Pontoise fdf1524137 fix: things in background properly reflect in ui 2020-03-24 19:37:45 +09:00
Louis Pontoise 311beef3cf feat: faster ui (closes #171, closes #128, closes #89)
* Replaced the NSCollectionView with a custom NSView. Benefit includes simpler code, and control over recycling logic.
* In cases where the user has many open windows, replaced the downscaling strategy with a scrollable view
* Added a preference: align thumbnails to the left or center
2020-03-24 19:37:45 +09:00
semantic-release-bot 2008025302 chore(release): 3.1.3 [skip ci]
## [3.1.3](https://github.com/lwouis/alt-tab-macos/compare/v3.1.2...v3.1.3) (2020-03-12)
2020-03-12 08:32:30 +00:00
Louis Pontoise f653337c83 docs: clarify how to contribute and add qa docs 2020-03-12 17:23:58 +09:00
semantic-release-bot 906129dfd6 chore(release): 3.1.2 [skip ci]
## [3.1.2](https://github.com/lwouis/alt-tab-macos/compare/v3.1.1...v3.1.2) (2020-03-12)

### Bug Fixes

* send feedback crashed the app on submit (closes [#172](https://github.com/lwouis/alt-tab-macos/issues/172)) ([c34b8a5](https://github.com/lwouis/alt-tab-macos/commit/c34b8a5))
2020-03-12 03:15:59 +00:00
Louis Pontoise c34b8a51b8 fix: send feedback crashed the app on submit (closes #172) 2020-03-12 12:07:09 +09:00
semantic-release-bot 2e500b5797 chore(release): 3.1.1 [skip ci]
## [3.1.1](https://github.com/lwouis/alt-tab-macos/compare/v3.1.0...v3.1.1) (2020-03-11)

### Bug Fixes

* don't observe daemons to avoid infinite loops (closes [#170](https://github.com/lwouis/alt-tab-macos/issues/170)) ([e40f859](https://github.com/lwouis/alt-tab-macos/commit/e40f859))
* show alt-tab own windows in the thumbnail panel ([6018a53](https://github.com/lwouis/alt-tab-macos/commit/6018a53))
2020-03-11 16:03:55 +00:00
Louis Pontoise e40f859c3a fix: don't observe daemons to avoid infinite loops (closes #170)
There is a risk of not showing some windows, like CopyQ, but the reward is less risk of trying to observe some buggy daemon process that will never succeed
2020-03-12 00:20:05 +09:00
Louis Pontoise 6018a531e8 fix: show alt-tab own windows in the thumbnail panel 2020-03-12 00:18:55 +09:00
semantic-release-bot 8962489989 chore(release): 3.1.0 [skip ci]
# [3.1.0](https://github.com/lwouis/alt-tab-macos/compare/v3.0.5...v3.1.0) (2020-03-10)

### Bug Fixes

* better subscription retry logic ([3a80cab](https://github.com/lwouis/alt-tab-macos/commit/3a80cab))

### Features

* output plist file as binary for better perf ([29a9f59](https://github.com/lwouis/alt-tab-macos/commit/29a9f59))
2020-03-10 17:21:33 +00:00
Louis Pontoise 3da3b9f662 docs: document homebrew install 2020-03-11 02:04:43 +09:00
Louis Pontoise 3a80caba99 fix: better subscription retry logic 2020-03-11 02:04:43 +09:00
Louis Pontoise e03cac426b refactor: better xcode conf 2020-03-11 02:04:42 +09:00
Louis Pontoise 29a9f59340 feat: output plist file as binary for better perf 2020-03-11 02:04:42 +09:00
semantic-release-bot 23a059d4d9 chore(release): 3.0.5 [skip ci]
## [3.0.5](https://github.com/lwouis/alt-tab-macos/compare/v3.0.4...v3.0.5) (2020-03-10)

### Bug Fixes

* remove script from bundle ([4a8301e](https://github.com/lwouis/alt-tab-macos/commit/4a8301e))
2020-03-10 14:03:53 +00:00
Louis Pontoise 4a8301e922 fix: remove script from bundle 2020-03-10 22:53:15 +09:00
Louis Pontoise 456a8409b1 docs: updated readme 2020-03-10 22:53:14 +09:00
semantic-release-bot 485a4a63a0 chore(release): 3.0.4 [skip ci]
## [3.0.4](https://github.com/lwouis/alt-tab-macos/compare/v3.0.3...v3.0.4) (2020-03-10)
2020-03-10 12:48:40 +00:00
Louis Pontoise 502e297e07 ci: fix cask-repair ssh access issue 3 2020-03-10 20:48:12 +09:00
semantic-release-bot 3584338e48 chore(release): 3.0.3 [skip ci]
## [3.0.3](https://github.com/lwouis/alt-tab-macos/compare/v3.0.2...v3.0.3) (2020-03-10)
2020-03-10 11:10:42 +00:00
Louis Pontoise 6daf2b3282 ci: fix cask-repair ssh access issue 2 2020-03-10 20:00:13 +09:00
semantic-release-bot 9e3d240f50 chore(release): 3.0.2 [skip ci]
## [3.0.2](https://github.com/lwouis/alt-tab-macos/compare/v3.0.1...v3.0.2) (2020-03-10)
2020-03-10 10:19:11 +00:00
Louis Pontoise a1de01dcab ci: fix cask-repair ssh access issue 2020-03-10 19:09:42 +09:00
semantic-release-bot 7a3aef742e chore(release): 3.0.1 [skip ci]
## [3.0.1](https://github.com/lwouis/alt-tab-macos/compare/v3.0.0...v3.0.1) (2020-03-10)
2020-03-10 09:34:52 +00:00
Louis Pontoise 70917e2de0 ci: better caching and allow ssh to github.com for cask-repair 2020-03-10 18:24:59 +09:00
semantic-release-bot 50dad4aa3a chore(release): 3.0.0 [skip ci]
# [3.0.0](https://github.com/lwouis/alt-tab-macos/compare/v2.3.4...v3.0.0) (2020-03-10)

### Bug Fixes

* a title change often means the content has change ([b8d6bc9](https://github.com/lwouis/alt-tab-macos/commit/b8d6bc9))
* add rough downscaling when there are many windows (closes [#69](https://github.com/lwouis/alt-tab-macos/issues/69)) ([ced5ee6](https://github.com/lwouis/alt-tab-macos/commit/ced5ee6))
* added releases link and aligned layout left on tab 3 ([6bb73dc](https://github.com/lwouis/alt-tab-macos/commit/6bb73dc))
* also codesign debug builds ([a5f9911](https://github.com/lwouis/alt-tab-macos/commit/a5f9911))
* app launched while in fullscreen shows first window ([c5cbcdb](https://github.com/lwouis/alt-tab-macos/commit/c5cbcdb)), closes [/github.com/lwouis/alt-tab-macos/pull/114#issuecomment-576384795](https://github.com//github.com/lwouis/alt-tab-macos/pull/114/issues/issuecomment-576384795)
* auto-update preferences sync with os from launch ([b3fb222](https://github.com/lwouis/alt-tab-macos/commit/b3fb222))
* avoid rendering if app is not used ([fdddb0f](https://github.com/lwouis/alt-tab-macos/commit/fdddb0f))
* better float rounding = sharper cell contents ([9a96e49](https://github.com/lwouis/alt-tab-macos/commit/9a96e49))
* better focus/order for preferences (closes [#80](https://github.com/lwouis/alt-tab-macos/issues/80)) ([4a8bdeb](https://github.com/lwouis/alt-tab-macos/commit/4a8bdeb))
* better textareas ([efc9bd3](https://github.com/lwouis/alt-tab-macos/commit/efc9bd3))
* bring back the window delay that regressed with v2 ([bb95e55](https://github.com/lwouis/alt-tab-macos/commit/bb95e55))
* compare correctly since pid can go away when an app dies ([4ded030](https://github.com/lwouis/alt-tab-macos/commit/4ded030))
* compiler warnings ([1faa74c](https://github.com/lwouis/alt-tab-macos/commit/1faa74c))
* cpu and memory leaks (see discussion in [#117](https://github.com/lwouis/alt-tab-macos/issues/117)) ([52626aa](https://github.com/lwouis/alt-tab-macos/commit/52626aa))
* dock being shown was blocking alt-tab ([2826a1b](https://github.com/lwouis/alt-tab-macos/commit/2826a1b))
* don't show floating windows + efficiencies ([3f8e3ea](https://github.com/lwouis/alt-tab-macos/commit/3f8e3ea))
* don't show ui on fast trigger ([f8e1b00](https://github.com/lwouis/alt-tab-macos/commit/f8e1b00))
* don't trigger ui refreshes if the app is not active ([b9a0152](https://github.com/lwouis/alt-tab-macos/commit/b9a0152))
* don't upscale thumbnails of small windows ([0bc7472](https://github.com/lwouis/alt-tab-macos/commit/0bc7472))
* feedback token injected during ci ([effdc5f](https://github.com/lwouis/alt-tab-macos/commit/effdc5f))
* getting sparkle ready for release ([9f1f522](https://github.com/lwouis/alt-tab-macos/commit/9f1f522))
* handle on-all-spaces windows better ([4abe9f3](https://github.com/lwouis/alt-tab-macos/commit/4abe9f3))
* ignore build folder ([a2bb19f](https://github.com/lwouis/alt-tab-macos/commit/a2bb19f))
* ignore trigger shortcuts if mission control is active ([b03b0aa](https://github.com/lwouis/alt-tab-macos/commit/b03b0aa))
* initial discovery when single space was glitching the os ([3cd4b6d](https://github.com/lwouis/alt-tab-macos/commit/3cd4b6d))
* keyboard shortcuts didn't work without a menu ([cf92dc1](https://github.com/lwouis/alt-tab-macos/commit/cf92dc1))
* layout is now correct; also removed layout preferences for now ([a1b5266](https://github.com/lwouis/alt-tab-macos/commit/a1b5266))
* layout regression introduced by eed0353 ([bdc41be](https://github.com/lwouis/alt-tab-macos/commit/bdc41be))
* layout was incorrect resulting in thumbnails clipping ([fd906f4](https://github.com/lwouis/alt-tab-macos/commit/fd906f4))
* letsmove was not active on release builds ([6ac0658](https://github.com/lwouis/alt-tab-macos/commit/6ac0658))
* list temporary AXDialog windows like activity monitor ([51a8838](https://github.com/lwouis/alt-tab-macos/commit/51a8838))
* more robust screen-recording permission check ([ce574a2](https://github.com/lwouis/alt-tab-macos/commit/ce574a2))
* notarization issues ([d125dd3](https://github.com/lwouis/alt-tab-macos/commit/d125dd3))
* observer leak would throw and crash the app sometimes ([9ca28eb](https://github.com/lwouis/alt-tab-macos/commit/9ca28eb))
* only test permissions on the correct os versions ([4612e37](https://github.com/lwouis/alt-tab-macos/commit/4612e37))
* open alt-tab during space transitions (closes [#92](https://github.com/lwouis/alt-tab-macos/issues/92)) ([141562d](https://github.com/lwouis/alt-tab-macos/commit/141562d))
* prevent visual flickering (closes [#115](https://github.com/lwouis/alt-tab-macos/issues/115)) ([9a8c83e](https://github.com/lwouis/alt-tab-macos/commit/9a8c83e))
* quitting apps was not properly removing apps from the list ([10b2c71](https://github.com/lwouis/alt-tab-macos/commit/10b2c71))
* quitting multiple apps would refresh the ui multiple times ([bfc2700](https://github.com/lwouis/alt-tab-macos/commit/bfc2700))
* regression on collectionviewitem titles (not showing) ([8cb6d86](https://github.com/lwouis/alt-tab-macos/commit/8cb6d86))
* remove debug colors ([e588d55](https://github.com/lwouis/alt-tab-macos/commit/e588d55))
* remove unnecessary/wrong layout code ([9e719e6](https://github.com/lwouis/alt-tab-macos/commit/9e719e6))
* sharper images on non-retina displays ([1bb4d2a](https://github.com/lwouis/alt-tab-macos/commit/1bb4d2a))
* smaller payload for the icons ([bddb6fa](https://github.com/lwouis/alt-tab-macos/commit/bddb6fa))
* some apps have messy launch behavior ([7eb216d](https://github.com/lwouis/alt-tab-macos/commit/7eb216d)), closes [/github.com/lwouis/alt-tab-macos/issues/117#issuecomment-583868046](https://github.com//github.com/lwouis/alt-tab-macos/issues/117/issues/issuecomment-583868046)
* some apps should retry observing until it works ([0c731f4](https://github.com/lwouis/alt-tab-macos/commit/0c731f4))
* using floor() everywhere to avoid blurry rendering ([2a36196](https://github.com/lwouis/alt-tab-macos/commit/2a36196))

### Code Refactoring

* complete rework of the internals ([547311e](https://github.com/lwouis/alt-tab-macos/commit/547311e)), closes [#93](https://github.com/lwouis/alt-tab-macos/issues/93) [#24](https://github.com/lwouis/alt-tab-macos/issues/24) [#117](https://github.com/lwouis/alt-tab-macos/issues/117) [/github.com/lwouis/alt-tab-macos/issues/45#issuecomment-571898826](https://github.com//github.com/lwouis/alt-tab-macos/issues/45/issues/issuecomment-571898826)

### Features

* add an app icon and menubar icon (closes [#38](https://github.com/lwouis/alt-tab-macos/issues/38)) ([a345dae](https://github.com/lwouis/alt-tab-macos/commit/a345dae))
* add back the preferences for the new layout algo ([d52eb6d](https://github.com/lwouis/alt-tab-macos/commit/d52eb6d))
* add debug profile to feedback message ([a14f965](https://github.com/lwouis/alt-tab-macos/commit/a14f965))
* add feedback button on about window ([4046136](https://github.com/lwouis/alt-tab-macos/commit/4046136))
* add in-app feedback form (closes [#145](https://github.com/lwouis/alt-tab-macos/issues/145)) ([725a030](https://github.com/lwouis/alt-tab-macos/commit/725a030))
* add licence to about page ([cb66b79](https://github.com/lwouis/alt-tab-macos/commit/cb66b79))
* add preference to start at login (closes [#159](https://github.com/lwouis/alt-tab-macos/issues/159)) ([982fe6c](https://github.com/lwouis/alt-tab-macos/commit/982fe6c))
* adding cocoapods and letsmove/sparkle ([606bae7](https://github.com/lwouis/alt-tab-macos/commit/606bae7))
* better packing; tall thumbnails are 1/2 the width of wide ones ([e34e3b1](https://github.com/lwouis/alt-tab-macos/commit/e34e3b1))
* bump major version ([3c3b18c](https://github.com/lwouis/alt-tab-macos/commit/3c3b18c))
* cleaner layout and explanation text ([fd3e768](https://github.com/lwouis/alt-tab-macos/commit/fd3e768))
* debug build has code-signing to preserve permissions ([34a32f3](https://github.com/lwouis/alt-tab-macos/commit/34a32f3))
* divide preferences by topic (closes [#130](https://github.com/lwouis/alt-tab-macos/issues/130)) ([291f872](https://github.com/lwouis/alt-tab-macos/commit/291f872))
* drag-and-drop files on the ui (closes [#74](https://github.com/lwouis/alt-tab-macos/issues/74)) ([e1e3633](https://github.com/lwouis/alt-tab-macos/commit/e1e3633))
* german and spanish localization ([6c440a7](https://github.com/lwouis/alt-tab-macos/commit/6c440a7))
* improved translations ([debd3ae](https://github.com/lwouis/alt-tab-macos/commit/debd3ae))
* integrate sparkle for auto-updates (closes [#131](https://github.com/lwouis/alt-tab-macos/issues/131)) ([069382c](https://github.com/lwouis/alt-tab-macos/commit/069382c))
* localization (closes [#134](https://github.com/lwouis/alt-tab-macos/issues/134)) ([36e4bb0](https://github.com/lwouis/alt-tab-macos/commit/36e4bb0))
* make system calls more parallel (closes [#160](https://github.com/lwouis/alt-tab-macos/issues/160)) ([a29b39f](https://github.com/lwouis/alt-tab-macos/commit/a29b39f))
* migrate to standard os-backed preferences (closes [#161](https://github.com/lwouis/alt-tab-macos/issues/161)) ([e28c43f](https://github.com/lwouis/alt-tab-macos/commit/e28c43f))
* more appealing presentation + minor refac ([67f291d](https://github.com/lwouis/alt-tab-macos/commit/67f291d))
* nicer layout for about preferences ([03a5f77](https://github.com/lwouis/alt-tab-macos/commit/03a5f77))
* quit button is clearer with explicit mention of the name ([6b6d748](https://github.com/lwouis/alt-tab-macos/commit/6b6d748))
* replace default copyright with correct licence ([60b49ea](https://github.com/lwouis/alt-tab-macos/commit/60b49ea))
* separating the quit button as it is a special case ([9fa0c06](https://github.com/lwouis/alt-tab-macos/commit/9fa0c06))
* slightly increase contrast (mitigates [#82](https://github.com/lwouis/alt-tab-macos/issues/82)) ([291770e](https://github.com/lwouis/alt-tab-macos/commit/291770e))
* support macos "sudden termination" ([671fdab](https://github.com/lwouis/alt-tab-macos/commit/671fdab)), closes [/developer.apple.com/documentation/foundation/processinfo#1651129](https://github.com//developer.apple.com/documentation/foundation/processinfo/issues/1651129)

### BREAKING CHANGES

* bump major version
* Instead of asking the OS about the state of the whole system on trigger (what we do today; hard to do fast), or asking the state of the whole system on a timer (what HyperSwitch does today; inaccurate) - instead of one of 2 approaches, v3 observes the Accessibility events such as "an app was launched", "a window was closed". This means we build a cache as we receive these events in the background, and when the user trigger the app, we can show accurate state of the windows instantly.

Of course there is no free lunch, so this approach has its own issues. However from my work on it from the past week, I'm very optimistic! The thing I'm the most excited about actually is not the perf (because on my machine even v2 is instant; I have a recent macbook and no 4k displays), but the fact that we will finally have the thumbnails in order of recently-used to least-recently-used, instead of the order of their stack (z-index) on the desktop. It's a big difference! There are many more limitations that are no longer applying also with this approach.
2020-03-10 09:03:53 +00:00
Louis Pontoise ea6c5f28b6 ci: remove interactive prompt from cask-repair 2020-03-10 17:57:39 +09:00
Louis Pontoise c4823357c7 refactor: simpler code 2020-03-10 17:56:55 +09:00
Louis Pontoise c853604647 ci: store cask-repair locally for faster builds 2020-03-10 17:56:54 +09:00
semantic-release-bot fe46faaf90 chore(release): 3.0.0 [skip ci]
# [3.0.0](https://github.com/lwouis/alt-tab-macos/compare/v2.3.4...v3.0.0) (2020-03-10)

### Bug Fixes

* a title change often means the content has change ([b8d6bc9](https://github.com/lwouis/alt-tab-macos/commit/b8d6bc9))
* add rough downscaling when there are many windows (closes [#69](https://github.com/lwouis/alt-tab-macos/issues/69)) ([ced5ee6](https://github.com/lwouis/alt-tab-macos/commit/ced5ee6))
* added releases link and aligned layout left on tab 3 ([6bb73dc](https://github.com/lwouis/alt-tab-macos/commit/6bb73dc))
* also codesign debug builds ([a5f9911](https://github.com/lwouis/alt-tab-macos/commit/a5f9911))
* app launched while in fullscreen shows first window ([c5cbcdb](https://github.com/lwouis/alt-tab-macos/commit/c5cbcdb)), closes [/github.com/lwouis/alt-tab-macos/pull/114#issuecomment-576384795](https://github.com//github.com/lwouis/alt-tab-macos/pull/114/issues/issuecomment-576384795)
* auto-update preferences sync with os from launch ([b3fb222](https://github.com/lwouis/alt-tab-macos/commit/b3fb222))
* avoid rendering if app is not used ([fdddb0f](https://github.com/lwouis/alt-tab-macos/commit/fdddb0f))
* better float rounding = sharper cell contents ([9a96e49](https://github.com/lwouis/alt-tab-macos/commit/9a96e49))
* better focus/order for preferences (closes [#80](https://github.com/lwouis/alt-tab-macos/issues/80)) ([4a8bdeb](https://github.com/lwouis/alt-tab-macos/commit/4a8bdeb))
* better textareas ([efc9bd3](https://github.com/lwouis/alt-tab-macos/commit/efc9bd3))
* bring back the window delay that regressed with v2 ([bb95e55](https://github.com/lwouis/alt-tab-macos/commit/bb95e55))
* compare correctly since pid can go away when an app dies ([4ded030](https://github.com/lwouis/alt-tab-macos/commit/4ded030))
* compiler warnings ([1faa74c](https://github.com/lwouis/alt-tab-macos/commit/1faa74c))
* cpu and memory leaks (see discussion in [#117](https://github.com/lwouis/alt-tab-macos/issues/117)) ([52626aa](https://github.com/lwouis/alt-tab-macos/commit/52626aa))
* dock being shown was blocking alt-tab ([2826a1b](https://github.com/lwouis/alt-tab-macos/commit/2826a1b))
* don't show floating windows + efficiencies ([3f8e3ea](https://github.com/lwouis/alt-tab-macos/commit/3f8e3ea))
* don't show ui on fast trigger ([f8e1b00](https://github.com/lwouis/alt-tab-macos/commit/f8e1b00))
* don't trigger ui refreshes if the app is not active ([b9a0152](https://github.com/lwouis/alt-tab-macos/commit/b9a0152))
* don't upscale thumbnails of small windows ([0bc7472](https://github.com/lwouis/alt-tab-macos/commit/0bc7472))
* feedback token injected during ci ([effdc5f](https://github.com/lwouis/alt-tab-macos/commit/effdc5f))
* getting sparkle ready for release ([9f1f522](https://github.com/lwouis/alt-tab-macos/commit/9f1f522))
* handle on-all-spaces windows better ([4abe9f3](https://github.com/lwouis/alt-tab-macos/commit/4abe9f3))
* ignore build folder ([a2bb19f](https://github.com/lwouis/alt-tab-macos/commit/a2bb19f))
* ignore trigger shortcuts if mission control is active ([b03b0aa](https://github.com/lwouis/alt-tab-macos/commit/b03b0aa))
* initial discovery when single space was glitching the os ([3cd4b6d](https://github.com/lwouis/alt-tab-macos/commit/3cd4b6d))
* keyboard shortcuts didn't work without a menu ([cf92dc1](https://github.com/lwouis/alt-tab-macos/commit/cf92dc1))
* layout is now correct; also removed layout preferences for now ([a1b5266](https://github.com/lwouis/alt-tab-macos/commit/a1b5266))
* layout regression introduced by eed0353 ([bdc41be](https://github.com/lwouis/alt-tab-macos/commit/bdc41be))
* layout was incorrect resulting in thumbnails clipping ([fd906f4](https://github.com/lwouis/alt-tab-macos/commit/fd906f4))
* letsmove was not active on release builds ([6ac0658](https://github.com/lwouis/alt-tab-macos/commit/6ac0658))
* list temporary AXDialog windows like activity monitor ([51a8838](https://github.com/lwouis/alt-tab-macos/commit/51a8838))
* more robust screen-recording permission check ([ce574a2](https://github.com/lwouis/alt-tab-macos/commit/ce574a2))
* notarization issues ([d125dd3](https://github.com/lwouis/alt-tab-macos/commit/d125dd3))
* observer leak would throw and crash the app sometimes ([9ca28eb](https://github.com/lwouis/alt-tab-macos/commit/9ca28eb))
* only test permissions on the correct os versions ([4612e37](https://github.com/lwouis/alt-tab-macos/commit/4612e37))
* open alt-tab during space transitions (closes [#92](https://github.com/lwouis/alt-tab-macos/issues/92)) ([141562d](https://github.com/lwouis/alt-tab-macos/commit/141562d))
* prevent visual flickering (closes [#115](https://github.com/lwouis/alt-tab-macos/issues/115)) ([9a8c83e](https://github.com/lwouis/alt-tab-macos/commit/9a8c83e))
* quitting apps was not properly removing apps from the list ([10b2c71](https://github.com/lwouis/alt-tab-macos/commit/10b2c71))
* quitting multiple apps would refresh the ui multiple times ([bfc2700](https://github.com/lwouis/alt-tab-macos/commit/bfc2700))
* regression on collectionviewitem titles (not showing) ([8cb6d86](https://github.com/lwouis/alt-tab-macos/commit/8cb6d86))
* remove debug colors ([e588d55](https://github.com/lwouis/alt-tab-macos/commit/e588d55))
* remove unnecessary/wrong layout code ([9e719e6](https://github.com/lwouis/alt-tab-macos/commit/9e719e6))
* sharper images on non-retina displays ([1bb4d2a](https://github.com/lwouis/alt-tab-macos/commit/1bb4d2a))
* smaller payload for the icons ([bddb6fa](https://github.com/lwouis/alt-tab-macos/commit/bddb6fa))
* some apps have messy launch behavior ([7eb216d](https://github.com/lwouis/alt-tab-macos/commit/7eb216d)), closes [/github.com/lwouis/alt-tab-macos/issues/117#issuecomment-583868046](https://github.com//github.com/lwouis/alt-tab-macos/issues/117/issues/issuecomment-583868046)
* some apps should retry observing until it works ([0c731f4](https://github.com/lwouis/alt-tab-macos/commit/0c731f4))
* using floor() everywhere to avoid blurry rendering ([2a36196](https://github.com/lwouis/alt-tab-macos/commit/2a36196))

### Code Refactoring

* complete rework of the internals ([547311e](https://github.com/lwouis/alt-tab-macos/commit/547311e)), closes [#93](https://github.com/lwouis/alt-tab-macos/issues/93) [#24](https://github.com/lwouis/alt-tab-macos/issues/24) [#117](https://github.com/lwouis/alt-tab-macos/issues/117) [/github.com/lwouis/alt-tab-macos/issues/45#issuecomment-571898826](https://github.com//github.com/lwouis/alt-tab-macos/issues/45/issues/issuecomment-571898826)

### Features

* add an app icon and menubar icon (closes [#38](https://github.com/lwouis/alt-tab-macos/issues/38)) ([a345dae](https://github.com/lwouis/alt-tab-macos/commit/a345dae))
* add back the preferences for the new layout algo ([d52eb6d](https://github.com/lwouis/alt-tab-macos/commit/d52eb6d))
* add debug profile to feedback message ([a14f965](https://github.com/lwouis/alt-tab-macos/commit/a14f965))
* add feedback button on about window ([4046136](https://github.com/lwouis/alt-tab-macos/commit/4046136))
* add in-app feedback form (closes [#145](https://github.com/lwouis/alt-tab-macos/issues/145)) ([725a030](https://github.com/lwouis/alt-tab-macos/commit/725a030))
* add licence to about page ([cb66b79](https://github.com/lwouis/alt-tab-macos/commit/cb66b79))
* add preference to start at login (closes [#159](https://github.com/lwouis/alt-tab-macos/issues/159)) ([982fe6c](https://github.com/lwouis/alt-tab-macos/commit/982fe6c))
* adding cocoapods and letsmove/sparkle ([606bae7](https://github.com/lwouis/alt-tab-macos/commit/606bae7))
* better packing; tall thumbnails are 1/2 the width of wide ones ([e34e3b1](https://github.com/lwouis/alt-tab-macos/commit/e34e3b1))
* bump major version ([3c3b18c](https://github.com/lwouis/alt-tab-macos/commit/3c3b18c))
* cleaner layout and explanation text ([fd3e768](https://github.com/lwouis/alt-tab-macos/commit/fd3e768))
* debug build has code-signing to preserve permissions ([34a32f3](https://github.com/lwouis/alt-tab-macos/commit/34a32f3))
* divide preferences by topic (closes [#130](https://github.com/lwouis/alt-tab-macos/issues/130)) ([291f872](https://github.com/lwouis/alt-tab-macos/commit/291f872))
* drag-and-drop files on the ui (closes [#74](https://github.com/lwouis/alt-tab-macos/issues/74)) ([e1e3633](https://github.com/lwouis/alt-tab-macos/commit/e1e3633))
* german and spanish localization ([6c440a7](https://github.com/lwouis/alt-tab-macos/commit/6c440a7))
* improved translations ([debd3ae](https://github.com/lwouis/alt-tab-macos/commit/debd3ae))
* integrate sparkle for auto-updates (closes [#131](https://github.com/lwouis/alt-tab-macos/issues/131)) ([069382c](https://github.com/lwouis/alt-tab-macos/commit/069382c))
* localization (closes [#134](https://github.com/lwouis/alt-tab-macos/issues/134)) ([36e4bb0](https://github.com/lwouis/alt-tab-macos/commit/36e4bb0))
* make system calls more parallel (closes [#160](https://github.com/lwouis/alt-tab-macos/issues/160)) ([a29b39f](https://github.com/lwouis/alt-tab-macos/commit/a29b39f))
* migrate to standard os-backed preferences (closes [#161](https://github.com/lwouis/alt-tab-macos/issues/161)) ([e28c43f](https://github.com/lwouis/alt-tab-macos/commit/e28c43f))
* more appealing presentation + minor refac ([67f291d](https://github.com/lwouis/alt-tab-macos/commit/67f291d))
* nicer layout for about preferences ([03a5f77](https://github.com/lwouis/alt-tab-macos/commit/03a5f77))
* quit button is clearer with explicit mention of the name ([6b6d748](https://github.com/lwouis/alt-tab-macos/commit/6b6d748))
* replace default copyright with correct licence ([60b49ea](https://github.com/lwouis/alt-tab-macos/commit/60b49ea))
* separating the quit button as it is a special case ([9fa0c06](https://github.com/lwouis/alt-tab-macos/commit/9fa0c06))
* slightly increase contrast (mitigates [#82](https://github.com/lwouis/alt-tab-macos/issues/82)) ([291770e](https://github.com/lwouis/alt-tab-macos/commit/291770e))
* support macos "sudden termination" ([671fdab](https://github.com/lwouis/alt-tab-macos/commit/671fdab)), closes [/developer.apple.com/documentation/foundation/processinfo#1651129](https://github.com//developer.apple.com/documentation/foundation/processinfo/issues/1651129)

### BREAKING CHANGES

* bump major version
* Instead of asking the OS about the state of the whole system on trigger (what we do today; hard to do fast), or asking the state of the whole system on a timer (what HyperSwitch does today; inaccurate) - instead of one of 2 approaches, v3 observes the Accessibility events such as "an app was launched", "a window was closed". This means we build a cache as we receive these events in the background, and when the user trigger the app, we can show accurate state of the windows instantly.

Of course there is no free lunch, so this approach has its own issues. However from my work on it from the past week, I'm very optimistic! The thing I'm the most excited about actually is not the perf (because on my machine even v2 is instant; I have a recent macbook and no 4k displays), but the fact that we will finally have the thumbnails in order of recently-used to least-recently-used, instead of the order of their stack (z-index) on the desktop. It's a big difference! There are many more limitations that are no longer applying also with this approach.
2020-03-10 08:50:50 +00:00
Louis Pontoise 73dc300ed3 ci: fix cached cask-repair 3 2020-03-10 17:38:27 +09:00
semantic-release-bot 464bf0ecd7 chore(release): 3.0.0 [skip ci]
# [3.0.0](https://github.com/lwouis/alt-tab-macos/compare/v2.3.4...v3.0.0) (2020-03-10)

### Bug Fixes

* a title change often means the content has change ([b8d6bc9](https://github.com/lwouis/alt-tab-macos/commit/b8d6bc9))
* add rough downscaling when there are many windows (closes [#69](https://github.com/lwouis/alt-tab-macos/issues/69)) ([ced5ee6](https://github.com/lwouis/alt-tab-macos/commit/ced5ee6))
* added releases link and aligned layout left on tab 3 ([6bb73dc](https://github.com/lwouis/alt-tab-macos/commit/6bb73dc))
* also codesign debug builds ([a5f9911](https://github.com/lwouis/alt-tab-macos/commit/a5f9911))
* app launched while in fullscreen shows first window ([c5cbcdb](https://github.com/lwouis/alt-tab-macos/commit/c5cbcdb)), closes [/github.com/lwouis/alt-tab-macos/pull/114#issuecomment-576384795](https://github.com//github.com/lwouis/alt-tab-macos/pull/114/issues/issuecomment-576384795)
* auto-update preferences sync with os from launch ([b3fb222](https://github.com/lwouis/alt-tab-macos/commit/b3fb222))
* avoid rendering if app is not used ([fdddb0f](https://github.com/lwouis/alt-tab-macos/commit/fdddb0f))
* better float rounding = sharper cell contents ([9a96e49](https://github.com/lwouis/alt-tab-macos/commit/9a96e49))
* better focus/order for preferences (closes [#80](https://github.com/lwouis/alt-tab-macos/issues/80)) ([4a8bdeb](https://github.com/lwouis/alt-tab-macos/commit/4a8bdeb))
* better textareas ([efc9bd3](https://github.com/lwouis/alt-tab-macos/commit/efc9bd3))
* bring back the window delay that regressed with v2 ([bb95e55](https://github.com/lwouis/alt-tab-macos/commit/bb95e55))
* compare correctly since pid can go away when an app dies ([4ded030](https://github.com/lwouis/alt-tab-macos/commit/4ded030))
* compiler warnings ([1faa74c](https://github.com/lwouis/alt-tab-macos/commit/1faa74c))
* cpu and memory leaks (see discussion in [#117](https://github.com/lwouis/alt-tab-macos/issues/117)) ([52626aa](https://github.com/lwouis/alt-tab-macos/commit/52626aa))
* dock being shown was blocking alt-tab ([2826a1b](https://github.com/lwouis/alt-tab-macos/commit/2826a1b))
* don't show floating windows + efficiencies ([3f8e3ea](https://github.com/lwouis/alt-tab-macos/commit/3f8e3ea))
* don't show ui on fast trigger ([f8e1b00](https://github.com/lwouis/alt-tab-macos/commit/f8e1b00))
* don't trigger ui refreshes if the app is not active ([b9a0152](https://github.com/lwouis/alt-tab-macos/commit/b9a0152))
* don't upscale thumbnails of small windows ([0bc7472](https://github.com/lwouis/alt-tab-macos/commit/0bc7472))
* feedback token injected during ci ([effdc5f](https://github.com/lwouis/alt-tab-macos/commit/effdc5f))
* getting sparkle ready for release ([9f1f522](https://github.com/lwouis/alt-tab-macos/commit/9f1f522))
* handle on-all-spaces windows better ([4abe9f3](https://github.com/lwouis/alt-tab-macos/commit/4abe9f3))
* ignore build folder ([a2bb19f](https://github.com/lwouis/alt-tab-macos/commit/a2bb19f))
* ignore trigger shortcuts if mission control is active ([b03b0aa](https://github.com/lwouis/alt-tab-macos/commit/b03b0aa))
* initial discovery when single space was glitching the os ([3cd4b6d](https://github.com/lwouis/alt-tab-macos/commit/3cd4b6d))
* keyboard shortcuts didn't work without a menu ([cf92dc1](https://github.com/lwouis/alt-tab-macos/commit/cf92dc1))
* layout is now correct; also removed layout preferences for now ([a1b5266](https://github.com/lwouis/alt-tab-macos/commit/a1b5266))
* layout regression introduced by eed0353 ([bdc41be](https://github.com/lwouis/alt-tab-macos/commit/bdc41be))
* layout was incorrect resulting in thumbnails clipping ([fd906f4](https://github.com/lwouis/alt-tab-macos/commit/fd906f4))
* letsmove was not active on release builds ([6ac0658](https://github.com/lwouis/alt-tab-macos/commit/6ac0658))
* list temporary AXDialog windows like activity monitor ([51a8838](https://github.com/lwouis/alt-tab-macos/commit/51a8838))
* more robust screen-recording permission check ([ce574a2](https://github.com/lwouis/alt-tab-macos/commit/ce574a2))
* notarization issues ([d125dd3](https://github.com/lwouis/alt-tab-macos/commit/d125dd3))
* observer leak would throw and crash the app sometimes ([9ca28eb](https://github.com/lwouis/alt-tab-macos/commit/9ca28eb))
* only test permissions on the correct os versions ([4612e37](https://github.com/lwouis/alt-tab-macos/commit/4612e37))
* open alt-tab during space transitions (closes [#92](https://github.com/lwouis/alt-tab-macos/issues/92)) ([141562d](https://github.com/lwouis/alt-tab-macos/commit/141562d))
* prevent visual flickering (closes [#115](https://github.com/lwouis/alt-tab-macos/issues/115)) ([9a8c83e](https://github.com/lwouis/alt-tab-macos/commit/9a8c83e))
* quitting apps was not properly removing apps from the list ([10b2c71](https://github.com/lwouis/alt-tab-macos/commit/10b2c71))
* quitting multiple apps would refresh the ui multiple times ([bfc2700](https://github.com/lwouis/alt-tab-macos/commit/bfc2700))
* regression on collectionviewitem titles (not showing) ([8cb6d86](https://github.com/lwouis/alt-tab-macos/commit/8cb6d86))
* remove debug colors ([e588d55](https://github.com/lwouis/alt-tab-macos/commit/e588d55))
* remove unnecessary/wrong layout code ([9e719e6](https://github.com/lwouis/alt-tab-macos/commit/9e719e6))
* sharper images on non-retina displays ([1bb4d2a](https://github.com/lwouis/alt-tab-macos/commit/1bb4d2a))
* smaller payload for the icons ([bddb6fa](https://github.com/lwouis/alt-tab-macos/commit/bddb6fa))
* some apps have messy launch behavior ([7eb216d](https://github.com/lwouis/alt-tab-macos/commit/7eb216d)), closes [/github.com/lwouis/alt-tab-macos/issues/117#issuecomment-583868046](https://github.com//github.com/lwouis/alt-tab-macos/issues/117/issues/issuecomment-583868046)
* some apps should retry observing until it works ([0c731f4](https://github.com/lwouis/alt-tab-macos/commit/0c731f4))
* using floor() everywhere to avoid blurry rendering ([2a36196](https://github.com/lwouis/alt-tab-macos/commit/2a36196))

### Code Refactoring

* complete rework of the internals ([547311e](https://github.com/lwouis/alt-tab-macos/commit/547311e)), closes [#93](https://github.com/lwouis/alt-tab-macos/issues/93) [#24](https://github.com/lwouis/alt-tab-macos/issues/24) [#117](https://github.com/lwouis/alt-tab-macos/issues/117) [/github.com/lwouis/alt-tab-macos/issues/45#issuecomment-571898826](https://github.com//github.com/lwouis/alt-tab-macos/issues/45/issues/issuecomment-571898826)

### Features

* add an app icon and menubar icon (closes [#38](https://github.com/lwouis/alt-tab-macos/issues/38)) ([a345dae](https://github.com/lwouis/alt-tab-macos/commit/a345dae))
* add back the preferences for the new layout algo ([d52eb6d](https://github.com/lwouis/alt-tab-macos/commit/d52eb6d))
* add debug profile to feedback message ([a14f965](https://github.com/lwouis/alt-tab-macos/commit/a14f965))
* add feedback button on about window ([4046136](https://github.com/lwouis/alt-tab-macos/commit/4046136))
* add in-app feedback form (closes [#145](https://github.com/lwouis/alt-tab-macos/issues/145)) ([725a030](https://github.com/lwouis/alt-tab-macos/commit/725a030))
* add licence to about page ([cb66b79](https://github.com/lwouis/alt-tab-macos/commit/cb66b79))
* add preference to start at login (closes [#159](https://github.com/lwouis/alt-tab-macos/issues/159)) ([982fe6c](https://github.com/lwouis/alt-tab-macos/commit/982fe6c))
* adding cocoapods and letsmove/sparkle ([606bae7](https://github.com/lwouis/alt-tab-macos/commit/606bae7))
* better packing; tall thumbnails are 1/2 the width of wide ones ([e34e3b1](https://github.com/lwouis/alt-tab-macos/commit/e34e3b1))
* bump major version ([3c3b18c](https://github.com/lwouis/alt-tab-macos/commit/3c3b18c))
* cleaner layout and explanation text ([fd3e768](https://github.com/lwouis/alt-tab-macos/commit/fd3e768))
* debug build has code-signing to preserve permissions ([34a32f3](https://github.com/lwouis/alt-tab-macos/commit/34a32f3))
* divide preferences by topic (closes [#130](https://github.com/lwouis/alt-tab-macos/issues/130)) ([291f872](https://github.com/lwouis/alt-tab-macos/commit/291f872))
* drag-and-drop files on the ui (closes [#74](https://github.com/lwouis/alt-tab-macos/issues/74)) ([e1e3633](https://github.com/lwouis/alt-tab-macos/commit/e1e3633))
* german and spanish localization ([6c440a7](https://github.com/lwouis/alt-tab-macos/commit/6c440a7))
* improved translations ([debd3ae](https://github.com/lwouis/alt-tab-macos/commit/debd3ae))
* integrate sparkle for auto-updates (closes [#131](https://github.com/lwouis/alt-tab-macos/issues/131)) ([069382c](https://github.com/lwouis/alt-tab-macos/commit/069382c))
* localization (closes [#134](https://github.com/lwouis/alt-tab-macos/issues/134)) ([36e4bb0](https://github.com/lwouis/alt-tab-macos/commit/36e4bb0))
* make system calls more parallel (closes [#160](https://github.com/lwouis/alt-tab-macos/issues/160)) ([a29b39f](https://github.com/lwouis/alt-tab-macos/commit/a29b39f))
* migrate to standard os-backed preferences (closes [#161](https://github.com/lwouis/alt-tab-macos/issues/161)) ([e28c43f](https://github.com/lwouis/alt-tab-macos/commit/e28c43f))
* more appealing presentation + minor refac ([67f291d](https://github.com/lwouis/alt-tab-macos/commit/67f291d))
* nicer layout for about preferences ([03a5f77](https://github.com/lwouis/alt-tab-macos/commit/03a5f77))
* quit button is clearer with explicit mention of the name ([6b6d748](https://github.com/lwouis/alt-tab-macos/commit/6b6d748))
* replace default copyright with correct licence ([60b49ea](https://github.com/lwouis/alt-tab-macos/commit/60b49ea))
* separating the quit button as it is a special case ([9fa0c06](https://github.com/lwouis/alt-tab-macos/commit/9fa0c06))
* slightly increase contrast (mitigates [#82](https://github.com/lwouis/alt-tab-macos/issues/82)) ([291770e](https://github.com/lwouis/alt-tab-macos/commit/291770e))
* support macos "sudden termination" ([671fdab](https://github.com/lwouis/alt-tab-macos/commit/671fdab)), closes [/developer.apple.com/documentation/foundation/processinfo#1651129](https://github.com//developer.apple.com/documentation/foundation/processinfo/issues/1651129)

### BREAKING CHANGES

* bump major version
* Instead of asking the OS about the state of the whole system on trigger (what we do today; hard to do fast), or asking the state of the whole system on a timer (what HyperSwitch does today; inaccurate) - instead of one of 2 approaches, v3 observes the Accessibility events such as "an app was launched", "a window was closed". This means we build a cache as we receive these events in the background, and when the user trigger the app, we can show accurate state of the windows instantly.

Of course there is no free lunch, so this approach has its own issues. However from my work on it from the past week, I'm very optimistic! The thing I'm the most excited about actually is not the perf (because on my machine even v2 is instant; I have a recent macbook and no 4k displays), but the fact that we will finally have the thumbnails in order of recently-used to least-recently-used, instead of the order of their stack (z-index) on the desktop. It's a big difference! There are many more limitations that are no longer applying also with this approach.
2020-03-10 08:30:37 +00:00
Louis Pontoise c31252726c ci: fix cached cask-repair 2 2020-03-10 17:25:07 +09:00
semantic-release-bot bce17cb7d9 chore(release): 3.0.0 [skip ci]
# [3.0.0](https://github.com/lwouis/alt-tab-macos/compare/v2.3.4...v3.0.0) (2020-03-10)

### Bug Fixes

* a title change often means the content has change ([b8d6bc9](https://github.com/lwouis/alt-tab-macos/commit/b8d6bc9))
* add rough downscaling when there are many windows (closes [#69](https://github.com/lwouis/alt-tab-macos/issues/69)) ([ced5ee6](https://github.com/lwouis/alt-tab-macos/commit/ced5ee6))
* added releases link and aligned layout left on tab 3 ([6bb73dc](https://github.com/lwouis/alt-tab-macos/commit/6bb73dc))
* also codesign debug builds ([a5f9911](https://github.com/lwouis/alt-tab-macos/commit/a5f9911))
* app launched while in fullscreen shows first window ([c5cbcdb](https://github.com/lwouis/alt-tab-macos/commit/c5cbcdb)), closes [/github.com/lwouis/alt-tab-macos/pull/114#issuecomment-576384795](https://github.com//github.com/lwouis/alt-tab-macos/pull/114/issues/issuecomment-576384795)
* auto-update preferences sync with os from launch ([b3fb222](https://github.com/lwouis/alt-tab-macos/commit/b3fb222))
* avoid rendering if app is not used ([fdddb0f](https://github.com/lwouis/alt-tab-macos/commit/fdddb0f))
* better float rounding = sharper cell contents ([9a96e49](https://github.com/lwouis/alt-tab-macos/commit/9a96e49))
* better focus/order for preferences (closes [#80](https://github.com/lwouis/alt-tab-macos/issues/80)) ([4a8bdeb](https://github.com/lwouis/alt-tab-macos/commit/4a8bdeb))
* better textareas ([efc9bd3](https://github.com/lwouis/alt-tab-macos/commit/efc9bd3))
* bring back the window delay that regressed with v2 ([bb95e55](https://github.com/lwouis/alt-tab-macos/commit/bb95e55))
* compare correctly since pid can go away when an app dies ([4ded030](https://github.com/lwouis/alt-tab-macos/commit/4ded030))
* compiler warnings ([1faa74c](https://github.com/lwouis/alt-tab-macos/commit/1faa74c))
* cpu and memory leaks (see discussion in [#117](https://github.com/lwouis/alt-tab-macos/issues/117)) ([52626aa](https://github.com/lwouis/alt-tab-macos/commit/52626aa))
* dock being shown was blocking alt-tab ([2826a1b](https://github.com/lwouis/alt-tab-macos/commit/2826a1b))
* don't show floating windows + efficiencies ([3f8e3ea](https://github.com/lwouis/alt-tab-macos/commit/3f8e3ea))
* don't show ui on fast trigger ([f8e1b00](https://github.com/lwouis/alt-tab-macos/commit/f8e1b00))
* don't trigger ui refreshes if the app is not active ([b9a0152](https://github.com/lwouis/alt-tab-macos/commit/b9a0152))
* don't upscale thumbnails of small windows ([0bc7472](https://github.com/lwouis/alt-tab-macos/commit/0bc7472))
* feedback token injected during ci ([effdc5f](https://github.com/lwouis/alt-tab-macos/commit/effdc5f))
* getting sparkle ready for release ([9f1f522](https://github.com/lwouis/alt-tab-macos/commit/9f1f522))
* handle on-all-spaces windows better ([4abe9f3](https://github.com/lwouis/alt-tab-macos/commit/4abe9f3))
* ignore build folder ([a2bb19f](https://github.com/lwouis/alt-tab-macos/commit/a2bb19f))
* ignore trigger shortcuts if mission control is active ([b03b0aa](https://github.com/lwouis/alt-tab-macos/commit/b03b0aa))
* initial discovery when single space was glitching the os ([3cd4b6d](https://github.com/lwouis/alt-tab-macos/commit/3cd4b6d))
* keyboard shortcuts didn't work without a menu ([cf92dc1](https://github.com/lwouis/alt-tab-macos/commit/cf92dc1))
* layout is now correct; also removed layout preferences for now ([a1b5266](https://github.com/lwouis/alt-tab-macos/commit/a1b5266))
* layout regression introduced by eed0353 ([bdc41be](https://github.com/lwouis/alt-tab-macos/commit/bdc41be))
* layout was incorrect resulting in thumbnails clipping ([fd906f4](https://github.com/lwouis/alt-tab-macos/commit/fd906f4))
* letsmove was not active on release builds ([6ac0658](https://github.com/lwouis/alt-tab-macos/commit/6ac0658))
* list temporary AXDialog windows like activity monitor ([51a8838](https://github.com/lwouis/alt-tab-macos/commit/51a8838))
* more robust screen-recording permission check ([ce574a2](https://github.com/lwouis/alt-tab-macos/commit/ce574a2))
* notarization issues ([d125dd3](https://github.com/lwouis/alt-tab-macos/commit/d125dd3))
* observer leak would throw and crash the app sometimes ([9ca28eb](https://github.com/lwouis/alt-tab-macos/commit/9ca28eb))
* only test permissions on the correct os versions ([4612e37](https://github.com/lwouis/alt-tab-macos/commit/4612e37))
* open alt-tab during space transitions (closes [#92](https://github.com/lwouis/alt-tab-macos/issues/92)) ([141562d](https://github.com/lwouis/alt-tab-macos/commit/141562d))
* prevent visual flickering (closes [#115](https://github.com/lwouis/alt-tab-macos/issues/115)) ([9a8c83e](https://github.com/lwouis/alt-tab-macos/commit/9a8c83e))
* quitting apps was not properly removing apps from the list ([10b2c71](https://github.com/lwouis/alt-tab-macos/commit/10b2c71))
* quitting multiple apps would refresh the ui multiple times ([bfc2700](https://github.com/lwouis/alt-tab-macos/commit/bfc2700))
* regression on collectionviewitem titles (not showing) ([8cb6d86](https://github.com/lwouis/alt-tab-macos/commit/8cb6d86))
* remove debug colors ([e588d55](https://github.com/lwouis/alt-tab-macos/commit/e588d55))
* remove unnecessary/wrong layout code ([9e719e6](https://github.com/lwouis/alt-tab-macos/commit/9e719e6))
* sharper images on non-retina displays ([1bb4d2a](https://github.com/lwouis/alt-tab-macos/commit/1bb4d2a))
* smaller payload for the icons ([bddb6fa](https://github.com/lwouis/alt-tab-macos/commit/bddb6fa))
* some apps have messy launch behavior ([7eb216d](https://github.com/lwouis/alt-tab-macos/commit/7eb216d)), closes [/github.com/lwouis/alt-tab-macos/issues/117#issuecomment-583868046](https://github.com//github.com/lwouis/alt-tab-macos/issues/117/issues/issuecomment-583868046)
* some apps should retry observing until it works ([0c731f4](https://github.com/lwouis/alt-tab-macos/commit/0c731f4))
* using floor() everywhere to avoid blurry rendering ([2a36196](https://github.com/lwouis/alt-tab-macos/commit/2a36196))

### Code Refactoring

* complete rework of the internals ([547311e](https://github.com/lwouis/alt-tab-macos/commit/547311e)), closes [#93](https://github.com/lwouis/alt-tab-macos/issues/93) [#24](https://github.com/lwouis/alt-tab-macos/issues/24) [#117](https://github.com/lwouis/alt-tab-macos/issues/117) [/github.com/lwouis/alt-tab-macos/issues/45#issuecomment-571898826](https://github.com//github.com/lwouis/alt-tab-macos/issues/45/issues/issuecomment-571898826)

### Features

* add an app icon and menubar icon (closes [#38](https://github.com/lwouis/alt-tab-macos/issues/38)) ([a345dae](https://github.com/lwouis/alt-tab-macos/commit/a345dae))
* add back the preferences for the new layout algo ([d52eb6d](https://github.com/lwouis/alt-tab-macos/commit/d52eb6d))
* add debug profile to feedback message ([a14f965](https://github.com/lwouis/alt-tab-macos/commit/a14f965))
* add feedback button on about window ([4046136](https://github.com/lwouis/alt-tab-macos/commit/4046136))
* add in-app feedback form (closes [#145](https://github.com/lwouis/alt-tab-macos/issues/145)) ([725a030](https://github.com/lwouis/alt-tab-macos/commit/725a030))
* add licence to about page ([cb66b79](https://github.com/lwouis/alt-tab-macos/commit/cb66b79))
* add preference to start at login (closes [#159](https://github.com/lwouis/alt-tab-macos/issues/159)) ([982fe6c](https://github.com/lwouis/alt-tab-macos/commit/982fe6c))
* adding cocoapods and letsmove/sparkle ([606bae7](https://github.com/lwouis/alt-tab-macos/commit/606bae7))
* better packing; tall thumbnails are 1/2 the width of wide ones ([e34e3b1](https://github.com/lwouis/alt-tab-macos/commit/e34e3b1))
* bump major version ([3c3b18c](https://github.com/lwouis/alt-tab-macos/commit/3c3b18c))
* cleaner layout and explanation text ([fd3e768](https://github.com/lwouis/alt-tab-macos/commit/fd3e768))
* debug build has code-signing to preserve permissions ([34a32f3](https://github.com/lwouis/alt-tab-macos/commit/34a32f3))
* divide preferences by topic (closes [#130](https://github.com/lwouis/alt-tab-macos/issues/130)) ([291f872](https://github.com/lwouis/alt-tab-macos/commit/291f872))
* drag-and-drop files on the ui (closes [#74](https://github.com/lwouis/alt-tab-macos/issues/74)) ([e1e3633](https://github.com/lwouis/alt-tab-macos/commit/e1e3633))
* german and spanish localization ([6c440a7](https://github.com/lwouis/alt-tab-macos/commit/6c440a7))
* improved translations ([debd3ae](https://github.com/lwouis/alt-tab-macos/commit/debd3ae))
* integrate sparkle for auto-updates (closes [#131](https://github.com/lwouis/alt-tab-macos/issues/131)) ([069382c](https://github.com/lwouis/alt-tab-macos/commit/069382c))
* localization (closes [#134](https://github.com/lwouis/alt-tab-macos/issues/134)) ([36e4bb0](https://github.com/lwouis/alt-tab-macos/commit/36e4bb0))
* make system calls more parallel (closes [#160](https://github.com/lwouis/alt-tab-macos/issues/160)) ([a29b39f](https://github.com/lwouis/alt-tab-macos/commit/a29b39f))
* migrate to standard os-backed preferences (closes [#161](https://github.com/lwouis/alt-tab-macos/issues/161)) ([e28c43f](https://github.com/lwouis/alt-tab-macos/commit/e28c43f))
* more appealing presentation + minor refac ([67f291d](https://github.com/lwouis/alt-tab-macos/commit/67f291d))
* nicer layout for about preferences ([03a5f77](https://github.com/lwouis/alt-tab-macos/commit/03a5f77))
* quit button is clearer with explicit mention of the name ([6b6d748](https://github.com/lwouis/alt-tab-macos/commit/6b6d748))
* replace default copyright with correct licence ([60b49ea](https://github.com/lwouis/alt-tab-macos/commit/60b49ea))
* separating the quit button as it is a special case ([9fa0c06](https://github.com/lwouis/alt-tab-macos/commit/9fa0c06))
* slightly increase contrast (mitigates [#82](https://github.com/lwouis/alt-tab-macos/issues/82)) ([291770e](https://github.com/lwouis/alt-tab-macos/commit/291770e))
* support macos "sudden termination" ([671fdab](https://github.com/lwouis/alt-tab-macos/commit/671fdab)), closes [/developer.apple.com/documentation/foundation/processinfo#1651129](https://github.com//developer.apple.com/documentation/foundation/processinfo/issues/1651129)

### BREAKING CHANGES

* bump major version
* Instead of asking the OS about the state of the whole system on trigger (what we do today; hard to do fast), or asking the state of the whole system on a timer (what HyperSwitch does today; inaccurate) - instead of one of 2 approaches, v3 observes the Accessibility events such as "an app was launched", "a window was closed". This means we build a cache as we receive these events in the background, and when the user trigger the app, we can show accurate state of the windows instantly.

Of course there is no free lunch, so this approach has its own issues. However from my work on it from the past week, I'm very optimistic! The thing I'm the most excited about actually is not the perf (because on my machine even v2 is instant; I have a recent macbook and no 4k displays), but the fact that we will finally have the thumbnails in order of recently-used to least-recently-used, instead of the order of their stack (z-index) on the desktop. It's a big difference! There are many more limitations that are no longer applying also with this approach.
2020-03-10 08:21:31 +00:00
Louis Pontoise 9ee04f9b4b ci: fix cached cask-repair 2020-03-10 17:14:19 +09:00
semantic-release-bot 73e9d972bb chore(release): 3.0.0 [skip ci]
# [3.0.0](https://github.com/lwouis/alt-tab-macos/compare/v2.3.4...v3.0.0) (2020-03-10)

### Bug Fixes

* a title change often means the content has change ([b8d6bc9](https://github.com/lwouis/alt-tab-macos/commit/b8d6bc9))
* add rough downscaling when there are many windows (closes [#69](https://github.com/lwouis/alt-tab-macos/issues/69)) ([ced5ee6](https://github.com/lwouis/alt-tab-macos/commit/ced5ee6))
* added releases link and aligned layout left on tab 3 ([6bb73dc](https://github.com/lwouis/alt-tab-macos/commit/6bb73dc))
* also codesign debug builds ([a5f9911](https://github.com/lwouis/alt-tab-macos/commit/a5f9911))
* app launched while in fullscreen shows first window ([c5cbcdb](https://github.com/lwouis/alt-tab-macos/commit/c5cbcdb)), closes [/github.com/lwouis/alt-tab-macos/pull/114#issuecomment-576384795](https://github.com//github.com/lwouis/alt-tab-macos/pull/114/issues/issuecomment-576384795)
* auto-update preferences sync with os from launch ([b3fb222](https://github.com/lwouis/alt-tab-macos/commit/b3fb222))
* avoid rendering if app is not used ([fdddb0f](https://github.com/lwouis/alt-tab-macos/commit/fdddb0f))
* better float rounding = sharper cell contents ([9a96e49](https://github.com/lwouis/alt-tab-macos/commit/9a96e49))
* better focus/order for preferences (closes [#80](https://github.com/lwouis/alt-tab-macos/issues/80)) ([4a8bdeb](https://github.com/lwouis/alt-tab-macos/commit/4a8bdeb))
* better textareas ([efc9bd3](https://github.com/lwouis/alt-tab-macos/commit/efc9bd3))
* bring back the window delay that regressed with v2 ([bb95e55](https://github.com/lwouis/alt-tab-macos/commit/bb95e55))
* compare correctly since pid can go away when an app dies ([4ded030](https://github.com/lwouis/alt-tab-macos/commit/4ded030))
* compiler warnings ([1faa74c](https://github.com/lwouis/alt-tab-macos/commit/1faa74c))
* cpu and memory leaks (see discussion in [#117](https://github.com/lwouis/alt-tab-macos/issues/117)) ([52626aa](https://github.com/lwouis/alt-tab-macos/commit/52626aa))
* dock being shown was blocking alt-tab ([2826a1b](https://github.com/lwouis/alt-tab-macos/commit/2826a1b))
* don't show floating windows + efficiencies ([3f8e3ea](https://github.com/lwouis/alt-tab-macos/commit/3f8e3ea))
* don't show ui on fast trigger ([f8e1b00](https://github.com/lwouis/alt-tab-macos/commit/f8e1b00))
* don't trigger ui refreshes if the app is not active ([b9a0152](https://github.com/lwouis/alt-tab-macos/commit/b9a0152))
* don't upscale thumbnails of small windows ([0bc7472](https://github.com/lwouis/alt-tab-macos/commit/0bc7472))
* feedback token injected during ci ([effdc5f](https://github.com/lwouis/alt-tab-macos/commit/effdc5f))
* getting sparkle ready for release ([9f1f522](https://github.com/lwouis/alt-tab-macos/commit/9f1f522))
* handle on-all-spaces windows better ([4abe9f3](https://github.com/lwouis/alt-tab-macos/commit/4abe9f3))
* ignore build folder ([a2bb19f](https://github.com/lwouis/alt-tab-macos/commit/a2bb19f))
* ignore trigger shortcuts if mission control is active ([b03b0aa](https://github.com/lwouis/alt-tab-macos/commit/b03b0aa))
* initial discovery when single space was glitching the os ([3cd4b6d](https://github.com/lwouis/alt-tab-macos/commit/3cd4b6d))
* keyboard shortcuts didn't work without a menu ([cf92dc1](https://github.com/lwouis/alt-tab-macos/commit/cf92dc1))
* layout is now correct; also removed layout preferences for now ([a1b5266](https://github.com/lwouis/alt-tab-macos/commit/a1b5266))
* layout regression introduced by eed0353 ([bdc41be](https://github.com/lwouis/alt-tab-macos/commit/bdc41be))
* layout was incorrect resulting in thumbnails clipping ([fd906f4](https://github.com/lwouis/alt-tab-macos/commit/fd906f4))
* letsmove was not active on release builds ([6ac0658](https://github.com/lwouis/alt-tab-macos/commit/6ac0658))
* list temporary AXDialog windows like activity monitor ([51a8838](https://github.com/lwouis/alt-tab-macos/commit/51a8838))
* more robust screen-recording permission check ([ce574a2](https://github.com/lwouis/alt-tab-macos/commit/ce574a2))
* notarization issues ([d125dd3](https://github.com/lwouis/alt-tab-macos/commit/d125dd3))
* observer leak would throw and crash the app sometimes ([9ca28eb](https://github.com/lwouis/alt-tab-macos/commit/9ca28eb))
* only test permissions on the correct os versions ([4612e37](https://github.com/lwouis/alt-tab-macos/commit/4612e37))
* open alt-tab during space transitions (closes [#92](https://github.com/lwouis/alt-tab-macos/issues/92)) ([141562d](https://github.com/lwouis/alt-tab-macos/commit/141562d))
* prevent visual flickering (closes [#115](https://github.com/lwouis/alt-tab-macos/issues/115)) ([9a8c83e](https://github.com/lwouis/alt-tab-macos/commit/9a8c83e))
* quitting apps was not properly removing apps from the list ([10b2c71](https://github.com/lwouis/alt-tab-macos/commit/10b2c71))
* quitting multiple apps would refresh the ui multiple times ([bfc2700](https://github.com/lwouis/alt-tab-macos/commit/bfc2700))
* regression on collectionviewitem titles (not showing) ([8cb6d86](https://github.com/lwouis/alt-tab-macos/commit/8cb6d86))
* remove debug colors ([e588d55](https://github.com/lwouis/alt-tab-macos/commit/e588d55))
* remove unnecessary/wrong layout code ([9e719e6](https://github.com/lwouis/alt-tab-macos/commit/9e719e6))
* sharper images on non-retina displays ([1bb4d2a](https://github.com/lwouis/alt-tab-macos/commit/1bb4d2a))
* smaller payload for the icons ([bddb6fa](https://github.com/lwouis/alt-tab-macos/commit/bddb6fa))
* some apps have messy launch behavior ([7eb216d](https://github.com/lwouis/alt-tab-macos/commit/7eb216d)), closes [/github.com/lwouis/alt-tab-macos/issues/117#issuecomment-583868046](https://github.com//github.com/lwouis/alt-tab-macos/issues/117/issues/issuecomment-583868046)
* some apps should retry observing until it works ([0c731f4](https://github.com/lwouis/alt-tab-macos/commit/0c731f4))
* using floor() everywhere to avoid blurry rendering ([2a36196](https://github.com/lwouis/alt-tab-macos/commit/2a36196))

### Code Refactoring

* complete rework of the internals ([547311e](https://github.com/lwouis/alt-tab-macos/commit/547311e)), closes [#93](https://github.com/lwouis/alt-tab-macos/issues/93) [#24](https://github.com/lwouis/alt-tab-macos/issues/24) [#117](https://github.com/lwouis/alt-tab-macos/issues/117) [/github.com/lwouis/alt-tab-macos/issues/45#issuecomment-571898826](https://github.com//github.com/lwouis/alt-tab-macos/issues/45/issues/issuecomment-571898826)

### Features

* add an app icon and menubar icon (closes [#38](https://github.com/lwouis/alt-tab-macos/issues/38)) ([a345dae](https://github.com/lwouis/alt-tab-macos/commit/a345dae))
* add back the preferences for the new layout algo ([d52eb6d](https://github.com/lwouis/alt-tab-macos/commit/d52eb6d))
* add debug profile to feedback message ([a14f965](https://github.com/lwouis/alt-tab-macos/commit/a14f965))
* add feedback button on about window ([4046136](https://github.com/lwouis/alt-tab-macos/commit/4046136))
* add in-app feedback form (closes [#145](https://github.com/lwouis/alt-tab-macos/issues/145)) ([725a030](https://github.com/lwouis/alt-tab-macos/commit/725a030))
* add licence to about page ([cb66b79](https://github.com/lwouis/alt-tab-macos/commit/cb66b79))
* add preference to start at login (closes [#159](https://github.com/lwouis/alt-tab-macos/issues/159)) ([982fe6c](https://github.com/lwouis/alt-tab-macos/commit/982fe6c))
* adding cocoapods and letsmove/sparkle ([606bae7](https://github.com/lwouis/alt-tab-macos/commit/606bae7))
* better packing; tall thumbnails are 1/2 the width of wide ones ([e34e3b1](https://github.com/lwouis/alt-tab-macos/commit/e34e3b1))
* bump major version ([3c3b18c](https://github.com/lwouis/alt-tab-macos/commit/3c3b18c))
* cleaner layout and explanation text ([fd3e768](https://github.com/lwouis/alt-tab-macos/commit/fd3e768))
* debug build has code-signing to preserve permissions ([34a32f3](https://github.com/lwouis/alt-tab-macos/commit/34a32f3))
* divide preferences by topic (closes [#130](https://github.com/lwouis/alt-tab-macos/issues/130)) ([291f872](https://github.com/lwouis/alt-tab-macos/commit/291f872))
* drag-and-drop files on the ui (closes [#74](https://github.com/lwouis/alt-tab-macos/issues/74)) ([e1e3633](https://github.com/lwouis/alt-tab-macos/commit/e1e3633))
* german and spanish localization ([6c440a7](https://github.com/lwouis/alt-tab-macos/commit/6c440a7))
* improved translations ([debd3ae](https://github.com/lwouis/alt-tab-macos/commit/debd3ae))
* integrate sparkle for auto-updates (closes [#131](https://github.com/lwouis/alt-tab-macos/issues/131)) ([069382c](https://github.com/lwouis/alt-tab-macos/commit/069382c))
* localization (closes [#134](https://github.com/lwouis/alt-tab-macos/issues/134)) ([36e4bb0](https://github.com/lwouis/alt-tab-macos/commit/36e4bb0))
* make system calls more parallel (closes [#160](https://github.com/lwouis/alt-tab-macos/issues/160)) ([a29b39f](https://github.com/lwouis/alt-tab-macos/commit/a29b39f))
* migrate to standard os-backed preferences (closes [#161](https://github.com/lwouis/alt-tab-macos/issues/161)) ([e28c43f](https://github.com/lwouis/alt-tab-macos/commit/e28c43f))
* more appealing presentation + minor refac ([67f291d](https://github.com/lwouis/alt-tab-macos/commit/67f291d))
* nicer layout for about preferences ([03a5f77](https://github.com/lwouis/alt-tab-macos/commit/03a5f77))
* quit button is clearer with explicit mention of the name ([6b6d748](https://github.com/lwouis/alt-tab-macos/commit/6b6d748))
* replace default copyright with correct licence ([60b49ea](https://github.com/lwouis/alt-tab-macos/commit/60b49ea))
* separating the quit button as it is a special case ([9fa0c06](https://github.com/lwouis/alt-tab-macos/commit/9fa0c06))
* slightly increase contrast (mitigates [#82](https://github.com/lwouis/alt-tab-macos/issues/82)) ([291770e](https://github.com/lwouis/alt-tab-macos/commit/291770e))
* support macos "sudden termination" ([671fdab](https://github.com/lwouis/alt-tab-macos/commit/671fdab)), closes [/developer.apple.com/documentation/foundation/processinfo#1651129](https://github.com//developer.apple.com/documentation/foundation/processinfo/issues/1651129)

### BREAKING CHANGES

* bump major version
* Instead of asking the OS about the state of the whole system on trigger (what we do today; hard to do fast), or asking the state of the whole system on a timer (what HyperSwitch does today; inaccurate) - instead of one of 2 approaches, v3 observes the Accessibility events such as "an app was launched", "a window was closed". This means we build a cache as we receive these events in the background, and when the user trigger the app, we can show accurate state of the windows instantly.

Of course there is no free lunch, so this approach has its own issues. However from my work on it from the past week, I'm very optimistic! The thing I'm the most excited about actually is not the perf (because on my machine even v2 is instant; I have a recent macbook and no 4k displays), but the fact that we will finally have the thumbnails in order of recently-used to least-recently-used, instead of the order of their stack (z-index) on the desktop. It's a big difference! There are many more limitations that are no longer applying also with this approach.
2020-03-10 08:10:47 +00:00
Louis Pontoise 6883e86d19 ci: fix travis not deploying on github releases + caching 2020-03-10 17:04:37 +09:00
semantic-release-bot 79aa5bbe00 chore(release): 3.0.0 [skip ci]
# [3.0.0](https://github.com/lwouis/alt-tab-macos/compare/v2.3.4...v3.0.0) (2020-03-10)

### Bug Fixes

* a title change often means the content has change ([b8d6bc9](https://github.com/lwouis/alt-tab-macos/commit/b8d6bc9))
* add rough downscaling when there are many windows (closes [#69](https://github.com/lwouis/alt-tab-macos/issues/69)) ([ced5ee6](https://github.com/lwouis/alt-tab-macos/commit/ced5ee6))
* added releases link and aligned layout left on tab 3 ([6bb73dc](https://github.com/lwouis/alt-tab-macos/commit/6bb73dc))
* also codesign debug builds ([a5f9911](https://github.com/lwouis/alt-tab-macos/commit/a5f9911))
* app launched while in fullscreen shows first window ([c5cbcdb](https://github.com/lwouis/alt-tab-macos/commit/c5cbcdb)), closes [/github.com/lwouis/alt-tab-macos/pull/114#issuecomment-576384795](https://github.com//github.com/lwouis/alt-tab-macos/pull/114/issues/issuecomment-576384795)
* auto-update preferences sync with os from launch ([b3fb222](https://github.com/lwouis/alt-tab-macos/commit/b3fb222))
* avoid rendering if app is not used ([fdddb0f](https://github.com/lwouis/alt-tab-macos/commit/fdddb0f))
* better float rounding = sharper cell contents ([9a96e49](https://github.com/lwouis/alt-tab-macos/commit/9a96e49))
* better focus/order for preferences (closes [#80](https://github.com/lwouis/alt-tab-macos/issues/80)) ([4a8bdeb](https://github.com/lwouis/alt-tab-macos/commit/4a8bdeb))
* better textareas ([efc9bd3](https://github.com/lwouis/alt-tab-macos/commit/efc9bd3))
* bring back the window delay that regressed with v2 ([bb95e55](https://github.com/lwouis/alt-tab-macos/commit/bb95e55))
* compare correctly since pid can go away when an app dies ([4ded030](https://github.com/lwouis/alt-tab-macos/commit/4ded030))
* compiler warnings ([1faa74c](https://github.com/lwouis/alt-tab-macos/commit/1faa74c))
* cpu and memory leaks (see discussion in [#117](https://github.com/lwouis/alt-tab-macos/issues/117)) ([52626aa](https://github.com/lwouis/alt-tab-macos/commit/52626aa))
* dock being shown was blocking alt-tab ([2826a1b](https://github.com/lwouis/alt-tab-macos/commit/2826a1b))
* don't show floating windows + efficiencies ([3f8e3ea](https://github.com/lwouis/alt-tab-macos/commit/3f8e3ea))
* don't show ui on fast trigger ([f8e1b00](https://github.com/lwouis/alt-tab-macos/commit/f8e1b00))
* don't trigger ui refreshes if the app is not active ([b9a0152](https://github.com/lwouis/alt-tab-macos/commit/b9a0152))
* don't upscale thumbnails of small windows ([0bc7472](https://github.com/lwouis/alt-tab-macos/commit/0bc7472))
* feedback token injected during ci ([effdc5f](https://github.com/lwouis/alt-tab-macos/commit/effdc5f))
* getting sparkle ready for release ([9f1f522](https://github.com/lwouis/alt-tab-macos/commit/9f1f522))
* handle on-all-spaces windows better ([4abe9f3](https://github.com/lwouis/alt-tab-macos/commit/4abe9f3))
* ignore build folder ([a2bb19f](https://github.com/lwouis/alt-tab-macos/commit/a2bb19f))
* ignore trigger shortcuts if mission control is active ([b03b0aa](https://github.com/lwouis/alt-tab-macos/commit/b03b0aa))
* initial discovery when single space was glitching the os ([3cd4b6d](https://github.com/lwouis/alt-tab-macos/commit/3cd4b6d))
* keyboard shortcuts didn't work without a menu ([cf92dc1](https://github.com/lwouis/alt-tab-macos/commit/cf92dc1))
* layout is now correct; also removed layout preferences for now ([a1b5266](https://github.com/lwouis/alt-tab-macos/commit/a1b5266))
* layout regression introduced by eed0353 ([bdc41be](https://github.com/lwouis/alt-tab-macos/commit/bdc41be))
* layout was incorrect resulting in thumbnails clipping ([fd906f4](https://github.com/lwouis/alt-tab-macos/commit/fd906f4))
* letsmove was not active on release builds ([6ac0658](https://github.com/lwouis/alt-tab-macos/commit/6ac0658))
* list temporary AXDialog windows like activity monitor ([51a8838](https://github.com/lwouis/alt-tab-macos/commit/51a8838))
* more robust screen-recording permission check ([ce574a2](https://github.com/lwouis/alt-tab-macos/commit/ce574a2))
* notarization issues ([d125dd3](https://github.com/lwouis/alt-tab-macos/commit/d125dd3))
* observer leak would throw and crash the app sometimes ([9ca28eb](https://github.com/lwouis/alt-tab-macos/commit/9ca28eb))
* only test permissions on the correct os versions ([4612e37](https://github.com/lwouis/alt-tab-macos/commit/4612e37))
* open alt-tab during space transitions (closes [#92](https://github.com/lwouis/alt-tab-macos/issues/92)) ([141562d](https://github.com/lwouis/alt-tab-macos/commit/141562d))
* prevent visual flickering (closes [#115](https://github.com/lwouis/alt-tab-macos/issues/115)) ([9a8c83e](https://github.com/lwouis/alt-tab-macos/commit/9a8c83e))
* quitting apps was not properly removing apps from the list ([10b2c71](https://github.com/lwouis/alt-tab-macos/commit/10b2c71))
* quitting multiple apps would refresh the ui multiple times ([bfc2700](https://github.com/lwouis/alt-tab-macos/commit/bfc2700))
* regression on collectionviewitem titles (not showing) ([8cb6d86](https://github.com/lwouis/alt-tab-macos/commit/8cb6d86))
* remove debug colors ([e588d55](https://github.com/lwouis/alt-tab-macos/commit/e588d55))
* remove unnecessary/wrong layout code ([9e719e6](https://github.com/lwouis/alt-tab-macos/commit/9e719e6))
* sharper images on non-retina displays ([1bb4d2a](https://github.com/lwouis/alt-tab-macos/commit/1bb4d2a))
* smaller payload for the icons ([bddb6fa](https://github.com/lwouis/alt-tab-macos/commit/bddb6fa))
* some apps have messy launch behavior ([7eb216d](https://github.com/lwouis/alt-tab-macos/commit/7eb216d)), closes [/github.com/lwouis/alt-tab-macos/issues/117#issuecomment-583868046](https://github.com//github.com/lwouis/alt-tab-macos/issues/117/issues/issuecomment-583868046)
* some apps should retry observing until it works ([0c731f4](https://github.com/lwouis/alt-tab-macos/commit/0c731f4))
* using floor() everywhere to avoid blurry rendering ([2a36196](https://github.com/lwouis/alt-tab-macos/commit/2a36196))

### Code Refactoring

* complete rework of the internals ([547311e](https://github.com/lwouis/alt-tab-macos/commit/547311e)), closes [#93](https://github.com/lwouis/alt-tab-macos/issues/93) [#24](https://github.com/lwouis/alt-tab-macos/issues/24) [#117](https://github.com/lwouis/alt-tab-macos/issues/117) [/github.com/lwouis/alt-tab-macos/issues/45#issuecomment-571898826](https://github.com//github.com/lwouis/alt-tab-macos/issues/45/issues/issuecomment-571898826)

### Features

* add an app icon and menubar icon (closes [#38](https://github.com/lwouis/alt-tab-macos/issues/38)) ([a345dae](https://github.com/lwouis/alt-tab-macos/commit/a345dae))
* add back the preferences for the new layout algo ([d52eb6d](https://github.com/lwouis/alt-tab-macos/commit/d52eb6d))
* add debug profile to feedback message ([a14f965](https://github.com/lwouis/alt-tab-macos/commit/a14f965))
* add feedback button on about window ([4046136](https://github.com/lwouis/alt-tab-macos/commit/4046136))
* add in-app feedback form (closes [#145](https://github.com/lwouis/alt-tab-macos/issues/145)) ([725a030](https://github.com/lwouis/alt-tab-macos/commit/725a030))
* add licence to about page ([cb66b79](https://github.com/lwouis/alt-tab-macos/commit/cb66b79))
* add preference to start at login (closes [#159](https://github.com/lwouis/alt-tab-macos/issues/159)) ([982fe6c](https://github.com/lwouis/alt-tab-macos/commit/982fe6c))
* adding cocoapods and letsmove/sparkle ([606bae7](https://github.com/lwouis/alt-tab-macos/commit/606bae7))
* better packing; tall thumbnails are 1/2 the width of wide ones ([e34e3b1](https://github.com/lwouis/alt-tab-macos/commit/e34e3b1))
* bump major version ([3c3b18c](https://github.com/lwouis/alt-tab-macos/commit/3c3b18c))
* cleaner layout and explanation text ([fd3e768](https://github.com/lwouis/alt-tab-macos/commit/fd3e768))
* debug build has code-signing to preserve permissions ([34a32f3](https://github.com/lwouis/alt-tab-macos/commit/34a32f3))
* divide preferences by topic (closes [#130](https://github.com/lwouis/alt-tab-macos/issues/130)) ([291f872](https://github.com/lwouis/alt-tab-macos/commit/291f872))
* drag-and-drop files on the ui (closes [#74](https://github.com/lwouis/alt-tab-macos/issues/74)) ([e1e3633](https://github.com/lwouis/alt-tab-macos/commit/e1e3633))
* german and spanish localization ([6c440a7](https://github.com/lwouis/alt-tab-macos/commit/6c440a7))
* improved translations ([debd3ae](https://github.com/lwouis/alt-tab-macos/commit/debd3ae))
* integrate sparkle for auto-updates (closes [#131](https://github.com/lwouis/alt-tab-macos/issues/131)) ([069382c](https://github.com/lwouis/alt-tab-macos/commit/069382c))
* localization (closes [#134](https://github.com/lwouis/alt-tab-macos/issues/134)) ([36e4bb0](https://github.com/lwouis/alt-tab-macos/commit/36e4bb0))
* make system calls more parallel (closes [#160](https://github.com/lwouis/alt-tab-macos/issues/160)) ([a29b39f](https://github.com/lwouis/alt-tab-macos/commit/a29b39f))
* migrate to standard os-backed preferences (closes [#161](https://github.com/lwouis/alt-tab-macos/issues/161)) ([e28c43f](https://github.com/lwouis/alt-tab-macos/commit/e28c43f))
* more appealing presentation + minor refac ([67f291d](https://github.com/lwouis/alt-tab-macos/commit/67f291d))
* nicer layout for about preferences ([03a5f77](https://github.com/lwouis/alt-tab-macos/commit/03a5f77))
* quit button is clearer with explicit mention of the name ([6b6d748](https://github.com/lwouis/alt-tab-macos/commit/6b6d748))
* replace default copyright with correct licence ([60b49ea](https://github.com/lwouis/alt-tab-macos/commit/60b49ea))
* separating the quit button as it is a special case ([9fa0c06](https://github.com/lwouis/alt-tab-macos/commit/9fa0c06))
* slightly increase contrast (mitigates [#82](https://github.com/lwouis/alt-tab-macos/issues/82)) ([291770e](https://github.com/lwouis/alt-tab-macos/commit/291770e))
* support macos "sudden termination" ([671fdab](https://github.com/lwouis/alt-tab-macos/commit/671fdab)), closes [/developer.apple.com/documentation/foundation/processinfo#1651129](https://github.com//developer.apple.com/documentation/foundation/processinfo/issues/1651129)

### BREAKING CHANGES

* bump major version
* Instead of asking the OS about the state of the whole system on trigger (what we do today; hard to do fast), or asking the state of the whole system on a timer (what HyperSwitch does today; inaccurate) - instead of one of 2 approaches, v3 observes the Accessibility events such as "an app was launched", "a window was closed". This means we build a cache as we receive these events in the background, and when the user trigger the app, we can show accurate state of the windows instantly.

Of course there is no free lunch, so this approach has its own issues. However from my work on it from the past week, I'm very optimistic! The thing I'm the most excited about actually is not the perf (because on my machine even v2 is instant; I have a recent macbook and no 4k displays), but the fact that we will finally have the thumbnails in order of recently-used to least-recently-used, instead of the order of their stack (z-index) on the desktop. It's a big difference! There are many more limitations that are no longer applying also with this approach.
2020-03-10 07:53:10 +00:00
Louis Pontoise 308db52567 ci: cask-repair should happen after deploy 2020-03-10 16:43:47 +09:00
Louis Pontoise bfaff30536 ci: homebrew on travis needs update
see https://travis-ci.community/t/macos-build-fails-because-of-homebrew-bundle-unknown-command/7296/10
2020-03-10 16:25:19 +09:00
Louis Pontoise 203dbfc69b ci: codesign inside main .app, not in the pods folder 2020-03-10 16:13:47 +09:00
Louis Pontoise 55558e9336 ci: fix travis xcode build path 2 2020-03-10 15:34:30 +09:00
Louis Pontoise b249703291 ci: fix travis xcode build path 2020-03-10 15:27:05 +09:00
Louis Pontoise 33bb2ce98f ci: travis stop-on-error was broken
see https://github.com/travis-ci/travis-ci/issues/1066
2020-03-10 15:20:55 +09:00
Louis Pontoise 3c3b18c152 feat: bump major version
BREAKING CHANGE: bump major version
2020-03-10 15:08:01 +09:00
Louis Pontoise cb38ffac2f ci: force travis to stop on error 2020-03-10 14:59:07 +09:00
Louis Pontoise 6c6f3faaa9 ci: travis ignores IDEDerivedDataPathOverride; use derivedDataPath 2020-03-10 14:59:07 +09:00
Louis Pontoise 9ab1182b2e ci: install cask-repair dependency 2020-03-10 14:59:07 +09:00
semantic-release-bot 8331d75f94 chore(release): 2.4.0 [skip ci]
# [2.4.0](https://github.com/lwouis/alt-tab-macos/compare/v2.3.4...v2.4.0) (2020-03-10)

### Bug Fixes

* a title change often means the content has change ([b8d6bc9](https://github.com/lwouis/alt-tab-macos/commit/b8d6bc9))
* add rough downscaling when there are many windows (closes [#69](https://github.com/lwouis/alt-tab-macos/issues/69)) ([ced5ee6](https://github.com/lwouis/alt-tab-macos/commit/ced5ee6))
* added releases link and aligned layout left on tab 3 ([6bb73dc](https://github.com/lwouis/alt-tab-macos/commit/6bb73dc))
* also codesign debug builds ([a5f9911](https://github.com/lwouis/alt-tab-macos/commit/a5f9911))
* app launched while in fullscreen shows first window ([c5cbcdb](https://github.com/lwouis/alt-tab-macos/commit/c5cbcdb)), closes [/github.com/lwouis/alt-tab-macos/pull/114#issuecomment-576384795](https://github.com//github.com/lwouis/alt-tab-macos/pull/114/issues/issuecomment-576384795)
* auto-update preferences sync with os from launch ([b3fb222](https://github.com/lwouis/alt-tab-macos/commit/b3fb222))
* avoid rendering if app is not used ([fdddb0f](https://github.com/lwouis/alt-tab-macos/commit/fdddb0f))
* better float rounding = sharper cell contents ([9a96e49](https://github.com/lwouis/alt-tab-macos/commit/9a96e49))
* better focus/order for preferences (closes [#80](https://github.com/lwouis/alt-tab-macos/issues/80)) ([4a8bdeb](https://github.com/lwouis/alt-tab-macos/commit/4a8bdeb))
* better textareas ([efc9bd3](https://github.com/lwouis/alt-tab-macos/commit/efc9bd3))
* bring back the window delay that regressed with v2 ([bb95e55](https://github.com/lwouis/alt-tab-macos/commit/bb95e55))
* compare correctly since pid can go away when an app dies ([4ded030](https://github.com/lwouis/alt-tab-macos/commit/4ded030))
* compiler warnings ([1faa74c](https://github.com/lwouis/alt-tab-macos/commit/1faa74c))
* cpu and memory leaks (see discussion in [#117](https://github.com/lwouis/alt-tab-macos/issues/117)) ([52626aa](https://github.com/lwouis/alt-tab-macos/commit/52626aa))
* dock being shown was blocking alt-tab ([2826a1b](https://github.com/lwouis/alt-tab-macos/commit/2826a1b))
* don't show floating windows + efficiencies ([3f8e3ea](https://github.com/lwouis/alt-tab-macos/commit/3f8e3ea))
* don't show ui on fast trigger ([f8e1b00](https://github.com/lwouis/alt-tab-macos/commit/f8e1b00))
* don't trigger ui refreshes if the app is not active ([b9a0152](https://github.com/lwouis/alt-tab-macos/commit/b9a0152))
* don't upscale thumbnails of small windows ([0bc7472](https://github.com/lwouis/alt-tab-macos/commit/0bc7472))
* feedback token injected during ci ([effdc5f](https://github.com/lwouis/alt-tab-macos/commit/effdc5f))
* getting sparkle ready for release ([9f1f522](https://github.com/lwouis/alt-tab-macos/commit/9f1f522))
* handle on-all-spaces windows better ([4abe9f3](https://github.com/lwouis/alt-tab-macos/commit/4abe9f3))
* ignore build folder ([a2bb19f](https://github.com/lwouis/alt-tab-macos/commit/a2bb19f))
* ignore trigger shortcuts if mission control is active ([b03b0aa](https://github.com/lwouis/alt-tab-macos/commit/b03b0aa))
* initial discovery when single space was glitching the os ([3cd4b6d](https://github.com/lwouis/alt-tab-macos/commit/3cd4b6d))
* keyboard shortcuts didn't work without a menu ([cf92dc1](https://github.com/lwouis/alt-tab-macos/commit/cf92dc1))
* layout is now correct; also removed layout preferences for now ([a1b5266](https://github.com/lwouis/alt-tab-macos/commit/a1b5266))
* layout regression introduced by eed0353 ([bdc41be](https://github.com/lwouis/alt-tab-macos/commit/bdc41be))
* layout was incorrect resulting in thumbnails clipping ([fd906f4](https://github.com/lwouis/alt-tab-macos/commit/fd906f4))
* letsmove was not active on release builds ([6ac0658](https://github.com/lwouis/alt-tab-macos/commit/6ac0658))
* list temporary AXDialog windows like activity monitor ([51a8838](https://github.com/lwouis/alt-tab-macos/commit/51a8838))
* more robust screen-recording permission check ([ce574a2](https://github.com/lwouis/alt-tab-macos/commit/ce574a2))
* notarization issues ([d125dd3](https://github.com/lwouis/alt-tab-macos/commit/d125dd3))
* observer leak would throw and crash the app sometimes ([9ca28eb](https://github.com/lwouis/alt-tab-macos/commit/9ca28eb))
* only test permissions on the correct os versions ([4612e37](https://github.com/lwouis/alt-tab-macos/commit/4612e37))
* open alt-tab during space transitions (closes [#92](https://github.com/lwouis/alt-tab-macos/issues/92)) ([141562d](https://github.com/lwouis/alt-tab-macos/commit/141562d))
* prevent visual flickering (closes [#115](https://github.com/lwouis/alt-tab-macos/issues/115)) ([9a8c83e](https://github.com/lwouis/alt-tab-macos/commit/9a8c83e))
* quitting apps was not properly removing apps from the list ([10b2c71](https://github.com/lwouis/alt-tab-macos/commit/10b2c71))
* quitting multiple apps would refresh the ui multiple times ([bfc2700](https://github.com/lwouis/alt-tab-macos/commit/bfc2700))
* regression on collectionviewitem titles (not showing) ([8cb6d86](https://github.com/lwouis/alt-tab-macos/commit/8cb6d86))
* remove debug colors ([e588d55](https://github.com/lwouis/alt-tab-macos/commit/e588d55))
* remove unnecessary/wrong layout code ([9e719e6](https://github.com/lwouis/alt-tab-macos/commit/9e719e6))
* sharper images on non-retina displays ([1bb4d2a](https://github.com/lwouis/alt-tab-macos/commit/1bb4d2a))
* smaller payload for the icons ([bddb6fa](https://github.com/lwouis/alt-tab-macos/commit/bddb6fa))
* some apps have messy launch behavior ([7eb216d](https://github.com/lwouis/alt-tab-macos/commit/7eb216d)), closes [/github.com/lwouis/alt-tab-macos/issues/117#issuecomment-583868046](https://github.com//github.com/lwouis/alt-tab-macos/issues/117/issues/issuecomment-583868046)
* some apps should retry observing until it works ([0c731f4](https://github.com/lwouis/alt-tab-macos/commit/0c731f4))
* using floor() everywhere to avoid blurry rendering ([2a36196](https://github.com/lwouis/alt-tab-macos/commit/2a36196))

### Code Refactoring

* complete rework of the internals ([547311e](https://github.com/lwouis/alt-tab-macos/commit/547311e)), closes [#93](https://github.com/lwouis/alt-tab-macos/issues/93) [#24](https://github.com/lwouis/alt-tab-macos/issues/24) [#117](https://github.com/lwouis/alt-tab-macos/issues/117) [/github.com/lwouis/alt-tab-macos/issues/45#issuecomment-571898826](https://github.com//github.com/lwouis/alt-tab-macos/issues/45/issues/issuecomment-571898826)

### Features

* add an app icon and menubar icon (closes [#38](https://github.com/lwouis/alt-tab-macos/issues/38)) ([a345dae](https://github.com/lwouis/alt-tab-macos/commit/a345dae))
* add back the preferences for the new layout algo ([d52eb6d](https://github.com/lwouis/alt-tab-macos/commit/d52eb6d))
* add debug profile to feedback message ([a14f965](https://github.com/lwouis/alt-tab-macos/commit/a14f965))
* add feedback button on about window ([4046136](https://github.com/lwouis/alt-tab-macos/commit/4046136))
* add in-app feedback form (closes [#145](https://github.com/lwouis/alt-tab-macos/issues/145)) ([725a030](https://github.com/lwouis/alt-tab-macos/commit/725a030))
* add licence to about page ([cb66b79](https://github.com/lwouis/alt-tab-macos/commit/cb66b79))
* add preference to start at login (closes [#159](https://github.com/lwouis/alt-tab-macos/issues/159)) ([982fe6c](https://github.com/lwouis/alt-tab-macos/commit/982fe6c))
* adding cocoapods and letsmove/sparkle ([606bae7](https://github.com/lwouis/alt-tab-macos/commit/606bae7))
* better packing; tall thumbnails are 1/2 the width of wide ones ([e34e3b1](https://github.com/lwouis/alt-tab-macos/commit/e34e3b1))
* cleaner layout and explanation text ([fd3e768](https://github.com/lwouis/alt-tab-macos/commit/fd3e768))
* debug build has code-signing to preserve permissions ([34a32f3](https://github.com/lwouis/alt-tab-macos/commit/34a32f3))
* divide preferences by topic (closes [#130](https://github.com/lwouis/alt-tab-macos/issues/130)) ([291f872](https://github.com/lwouis/alt-tab-macos/commit/291f872))
* drag-and-drop files on the ui (closes [#74](https://github.com/lwouis/alt-tab-macos/issues/74)) ([e1e3633](https://github.com/lwouis/alt-tab-macos/commit/e1e3633))
* german and spanish localization ([6c440a7](https://github.com/lwouis/alt-tab-macos/commit/6c440a7))
* improved translations ([debd3ae](https://github.com/lwouis/alt-tab-macos/commit/debd3ae))
* integrate sparkle for auto-updates (closes [#131](https://github.com/lwouis/alt-tab-macos/issues/131)) ([069382c](https://github.com/lwouis/alt-tab-macos/commit/069382c))
* localization (closes [#134](https://github.com/lwouis/alt-tab-macos/issues/134)) ([36e4bb0](https://github.com/lwouis/alt-tab-macos/commit/36e4bb0))
* make system calls more parallel (closes [#160](https://github.com/lwouis/alt-tab-macos/issues/160)) ([a29b39f](https://github.com/lwouis/alt-tab-macos/commit/a29b39f))
* migrate to standard os-backed preferences (closes [#161](https://github.com/lwouis/alt-tab-macos/issues/161)) ([e28c43f](https://github.com/lwouis/alt-tab-macos/commit/e28c43f))
* more appealing presentation + minor refac ([67f291d](https://github.com/lwouis/alt-tab-macos/commit/67f291d))
* nicer layout for about preferences ([03a5f77](https://github.com/lwouis/alt-tab-macos/commit/03a5f77))
* quit button is clearer with explicit mention of the name ([6b6d748](https://github.com/lwouis/alt-tab-macos/commit/6b6d748))
* replace default copyright with correct licence ([60b49ea](https://github.com/lwouis/alt-tab-macos/commit/60b49ea))
* separating the quit button as it is a special case ([9fa0c06](https://github.com/lwouis/alt-tab-macos/commit/9fa0c06))
* slightly increase contrast (mitigates [#82](https://github.com/lwouis/alt-tab-macos/issues/82)) ([291770e](https://github.com/lwouis/alt-tab-macos/commit/291770e))
* support macos "sudden termination" ([671fdab](https://github.com/lwouis/alt-tab-macos/commit/671fdab)), closes [/developer.apple.com/documentation/foundation/processinfo#1651129](https://github.com//developer.apple.com/documentation/foundation/processinfo/issues/1651129)

### BREAKING CHANGES

* Instead of asking the OS about the state of the whole system on trigger (what we do today; hard to do fast), or asking the state of the whole system on a timer (what HyperSwitch does today; inaccurate) - instead of one of 2 approaches, v3 observes the Accessibility events such as "an app was launched", "a window was closed". This means we build a cache as we receive these events in the background, and when the user trigger the app, we can show accurate state of the windows instantly.

Of course there is no free lunch, so this approach has its own issues. However from my work on it from the past week, I'm very optimistic! The thing I'm the most excited about actually is not the perf (because on my machine even v2 is instant; I have a recent macbook and no 4k displays), but the fact that we will finally have the thumbnails in order of recently-used to least-recently-used, instead of the order of their stack (z-index) on the desktop. It's a big difference! There are many more limitations that are no longer applying also with this approach.
2020-03-10 05:03:56 +00:00
Louis Pontoise 9e719e6984 fix: remove unnecessary/wrong layout code 2020-03-10 14:00:37 +09:00
Louis Pontoise 1bb4d2a1c8 fix: sharper images on non-retina displays 2020-03-10 14:00:37 +09:00
Louis Pontoise a2bb19ffcb fix: ignore build folder 2020-03-10 14:00:37 +09:00
Louis Pontoise 982fe6cf3a feat: add preference to start at login (closes #159) 2020-03-10 14:00:37 +09:00
Louis Pontoise bddb6fa5bd fix: smaller payload for the icons 2020-03-10 14:00:37 +09:00
Louis Pontoise a345dae361 feat: add an app icon and menubar icon (closes #38) 2020-03-10 14:00:37 +09:00
Louis Pontoise 51a88382d1 fix: list temporary AXDialog windows like activity monitor 2020-03-10 14:00:37 +09:00
Louis Pontoise 946d81276f refactor: remove debug logs 2020-03-10 14:00:37 +09:00
Louis Pontoise 52626aa724 fix: cpu and memory leaks (see discussion in #117) 2020-03-10 14:00:37 +09:00
Louis Pontoise b3fb222d7f fix: auto-update preferences sync with os from launch 2020-03-10 14:00:37 +09:00
Louis Pontoise f950083061 refactor: correctly append to build settings from pods 2020-03-10 14:00:37 +09:00
Louis Pontoise 531a362790 refactor: remove unused protocol 2020-03-10 14:00:37 +09:00
louis.pontoise a526f5d447 docs: add a guide to navigate the project for newcomers 2020-03-10 14:00:37 +09:00
louis.pontoise 528c57fc28 refactor: move resources to top level 2020-03-10 14:00:37 +09:00
louis.pontoise effdc5f467 fix: feedback token injected during ci
Github expires token in source code so we have to hide it away in CI (for now)
2020-03-10 14:00:37 +09:00
louis.pontoise debd3aecb8 feat: improved translations 2020-03-10 14:00:37 +09:00
louis.pontoise 9f1f522306 fix: getting sparkle ready for release 2020-03-10 14:00:37 +09:00
louis.pontoise a5f9911e36 fix: also codesign debug builds 2020-03-10 14:00:37 +09:00
louis.pontoise dcff55aecf refactor: less unnecessary logs 2020-03-10 14:00:37 +09:00
louis.pontoise 45ea3c4a83 ci: added missing pod install 2020-03-10 14:00:37 +09:00
louis.pontoise bd7deb12dc ci: adding back missing codesign cert 2020-03-10 14:00:37 +09:00
louis.pontoise 700e09e2ff ci: only 1 build, not 1 for each env var 2020-03-10 14:00:37 +09:00
louis.pontoise 6ac0658b32 fix: letsmove was not active on release builds 2020-03-10 14:00:37 +09:00
louis.pontoise ec35884068 ci: schemes should be shared and versioned 2020-03-10 14:00:37 +09:00
louis.pontoise d125dd3ae9 fix: notarization issues 2020-03-10 14:00:37 +09:00
louis.pontoise 80f378b117 ci: big refac to finally rationalize the xcode mess
XCode project/workspace/configurations/target/pods have been in a mess for a while. Some changes done to address that:

* remove alt-tab-macos/ which was confusing
* ci/ becomes scripts/ as these can be used locally too
* added 3 xcconfig files to set aside important parameters so we stop passing flags around or modifying the huge pbxproj
2020-03-10 14:00:37 +09:00
louis.pontoise 9ec9aacf47 ci: more logs from altool to follow progress 2020-03-10 14:00:37 +09:00
louis.pontoise bdc41bea46 fix: layout regression introduced by eed0353 2020-03-10 14:00:37 +09:00
louis.pontoise 3fc899eeda refactor: remove non-resources 2020-03-10 14:00:37 +09:00
louis.pontoise a29b39fc87 feat: make system calls more parallel (closes #160) 2020-03-10 14:00:37 +09:00
louis.pontoise e28c43f227 feat: migrate to standard os-backed preferences (closes #161) 2020-03-10 14:00:37 +09:00
louis.pontoise 069382c119 feat: integrate sparkle for auto-updates (closes #131) 2020-03-10 14:00:37 +09:00
louis.pontoise 606bae7e71 feat: adding cocoapods and letsmove/sparkle 2020-03-10 14:00:37 +09:00
louis.pontoise e1e3633148 feat: drag-and-drop files on the ui (closes #74) 2020-03-10 14:00:37 +09:00
louis.pontoise 7eb216d43c fix: some apps have messy launch behavior
See discussion: https://github.com/lwouis/alt-tab-macos/issues/117#issuecomment-583868046
2020-03-10 14:00:37 +09:00
louis.pontoise 6c440a7926 feat: german and spanish localization 2020-03-10 14:00:37 +09:00
louis.pontoise 36e4bb06de feat: localization (closes #134) 2020-03-10 14:00:37 +09:00
louis.pontoise cb66b79582 feat: add licence to about page
Also use data from Info.plist to make it more DRY
2020-03-10 14:00:37 +09:00
louis.pontoise efc9bd3d3e fix: better textareas 2020-03-10 14:00:37 +09:00
louis.pontoise cf92dc1e71 fix: keyboard shortcuts didn't work without a menu 2020-03-10 14:00:37 +09:00
louis.pontoise 60b49ead4e feat: replace default copyright with correct licence 2020-03-10 14:00:37 +09:00
louis.pontoise fd3e7680f4 feat: cleaner layout and explanation text 2020-03-10 14:00:37 +09:00
louis.pontoise a14f96550b feat: add debug profile to feedback message 2020-03-10 14:00:37 +09:00
louis.pontoise 671fdabe79 feat: support macos "sudden termination"
More info: https://developer.apple.com/documentation/foundation/processinfo#1651129
2020-03-10 14:00:37 +09:00
louis.pontoise 404613607c feat: add feedback button on about window 2020-03-10 14:00:37 +09:00
louis.pontoise 67f291d1fe feat: more appealing presentation + minor refac 2020-03-10 14:00:37 +09:00
louis.pontoise 9fa0c06a9f feat: separating the quit button as it is a special case 2020-03-10 14:00:37 +09:00
louis.pontoise 6b6d7481ac feat: quit button is clearer with explicit mention of the name 2020-03-10 14:00:37 +09:00
louis.pontoise 8cb6d86d4c fix: regression on collectionviewitem titles (not showing) 2020-03-10 14:00:37 +09:00
louis.pontoise 725a030abe feat: add in-app feedback form (closes #145) 2020-03-10 14:00:37 +09:00
louis.pontoise b687613f91 refactor: remove unnecessary protocol 2020-03-10 14:00:37 +09:00
louis.pontoise dab2ce5fd7 refactor: organize the ui code hierarchically 2020-03-10 14:00:37 +09:00
louis.pontoise 03a5f77b99 feat: nicer layout for about preferences 2020-03-10 14:00:37 +09:00
louis.pontoise 6bb73dce92 fix: added releases link and aligned layout left on tab 3 2020-03-10 14:00:37 +09:00
louis.pontoise 0762e28eda refactor: factorize code in extension 2020-03-10 14:00:37 +09:00
louis.pontoise 291f872d3d feat: divide preferences by topic (closes #130) 2020-03-10 14:00:37 +09:00
louis.pontoise d52eb6d074 feat: add back the preferences for the new layout algo 2020-03-10 14:00:37 +09:00
louis.pontoise 89977d78ee ci: more packed layout by default 2020-03-10 14:00:37 +09:00
louis.pontoise e34e3b171f feat: better packing; tall thumbnails are 1/2 the width of wide ones 2020-03-10 14:00:37 +09:00
louis.pontoise 0bc7472d17 fix: don't upscale thumbnails of small windows 2020-03-10 14:00:37 +09:00
louis.pontoise 01e33b0950 ci: sign releases with apple dev certificate (closes #13) 2020-03-10 14:00:37 +09:00
louis.pontoise 00c630d1ed ci: remove travis warning by updating keys 2020-03-10 14:00:37 +09:00
louis.pontoise d59061398e ci: display env vars at the beginning of a build 2020-03-10 14:00:37 +09:00
louis.pontoise ce574a2678 fix: more robust screen-recording permission check 2020-03-10 14:00:37 +09:00
louis.pontoise 34a32f329d feat: debug build has code-signing to preserve permissions 2020-03-10 14:00:37 +09:00
louis.pontoise 4612e37721 fix: only test permissions on the correct os versions 2020-03-10 14:00:37 +09:00
louis.pontoise 9a96e4988a fix: better float rounding = sharper cell contents 2020-03-10 14:00:37 +09:00
louis.pontoise 1faa74c7c5 fix: compiler warnings 2020-03-10 14:00:37 +09:00
louis.pontoise c5cbcdbe97 fix: app launched while in fullscreen shows first window
see https://github.com/lwouis/alt-tab-macos/pull/114#issuecomment-576384795
2020-03-10 14:00:37 +09:00
louis.pontoise 0c731f4889 fix: some apps should retry observing until it works 2020-03-10 14:00:37 +09:00
louis.pontoise 8b97bf89b5 ci: update homebrew cask for new releases (closes #75) 2020-03-10 14:00:37 +09:00
louis.pontoise 291770e363 feat: slightly increase contrast (mitigates #82) 2020-03-10 14:00:37 +09:00
louis.pontoise fd906f46fb fix: layout was incorrect resulting in thumbnails clipping 2020-03-10 14:00:37 +09:00
louis.pontoise 2a36196661 fix: using floor() everywhere to avoid blurry rendering 2020-03-10 14:00:37 +09:00
louis.pontoise e588d55ecd fix: remove debug colors 2020-03-10 14:00:37 +09:00
louis.pontoise ced5ee60c1 fix: add rough downscaling when there are many windows (closes #69) 2020-03-10 14:00:37 +09:00
louis.pontoise 314801ce99 refactor: minor syntax change 2020-03-10 14:00:37 +09:00
louis.pontoise a1b5266937 fix: layout is now correct; also removed layout preferences for now 2020-03-10 14:00:37 +09:00
louis.pontoise bb95e55e02 fix: bring back the window delay that regressed with v2 2020-03-10 14:00:37 +09:00
louis.pontoise fdddb0f8ed fix: avoid rendering if app is not used 2020-03-10 14:00:37 +09:00
louis.pontoise 3f8e3eab9b fix: don't show floating windows + efficiencies 2020-03-10 14:00:37 +09:00
louis.pontoise 141562de04 fix: open alt-tab during space transitions (closes #92) 2020-03-10 14:00:37 +09:00
louis.pontoise f8e1b00985 fix: don't show ui on fast trigger 2020-03-10 14:00:37 +09:00
louis.pontoise b8d6bc999f fix: a title change often means the content has change 2020-03-10 14:00:37 +09:00
louis.pontoise 3cd4b6d068 fix: initial discovery when single space was glitching the os 2020-03-10 14:00:37 +09:00
louis.pontoise a3c0fe820f refactor: factorize and document 2020-03-10 14:00:37 +09:00
louis.pontoise 4abe9f31ec fix: handle on-all-spaces windows better 2020-03-10 14:00:37 +09:00
louis.pontoise 4a8bdebacc fix: better focus/order for preferences (closes #80) 2020-03-10 14:00:37 +09:00
louis.pontoise 2826a1b872 fix: dock being shown was blocking alt-tab 2020-03-10 14:00:37 +09:00
louis.pontoise 4ded030a35 fix: compare correctly since pid can go away when an app dies 2020-03-10 14:00:37 +09:00
louis.pontoise 5877f34fe4 refactor: cleaner code 2020-03-10 14:00:37 +09:00
louis.pontoise 10b2c714ca fix: quitting apps was not properly removing apps from the list
Instead of using the PSN, we now use .equals() to compare 2 NSRunningApplication as recommended by Apple docs
2020-03-10 14:00:37 +09:00
louis.pontoise bfc27008cc fix: quitting multiple apps would refresh the ui multiple times 2020-03-10 14:00:37 +09:00
louis.pontoise 9ca28eb2d8 fix: observer leak would throw and crash the app sometimes 2020-03-10 14:00:37 +09:00
louis.pontoise 9a8c83e39d fix: prevent visual flickering (closes #115) 2020-03-10 14:00:37 +09:00
louis.pontoise b9a0152f85 fix: don't trigger ui refreshes if the app is not active 2020-03-10 14:00:37 +09:00
louis.pontoise b03b0aa22e fix: ignore trigger shortcuts if mission control is active 2020-03-10 14:00:37 +09:00
louis.pontoise 547311ea5d refactor: complete rework of the internals
closes #93 closes #24 closes #117

BREAKING CHANGE: Instead of asking the OS about the state of the whole system on trigger (what we do today; hard to do fast), or asking the state of the whole system on a timer (what HyperSwitch does today; inaccurate) - instead of one of 2 approaches, v3 observes the Accessibility events such as "an app was launched", "a window was closed". This means we build a cache as we receive these events in the background, and when the user trigger the app, we can show accurate state of the windows instantly.

Of course there is no free lunch, so this approach has its own issues. However from my work on it from the past week, I'm very optimistic! The thing I'm the most excited about actually is not the perf (because on my machine even v2 is instant; I have a recent macbook and no 4k displays), but the fact that we will finally have the thumbnails in order of recently-used to least-recently-used, instead of the order of their stack (z-index) on the desktop. It's a big difference! There are many more limitations that are no longer applying also with this approach.

More context: https://github.com/lwouis/alt-tab-macos/issues/45#issuecomment-571898826
2020-03-10 14:00:37 +09:00
semantic-release-bot 22354da5ea chore(release): 2.3.4 [skip ci]
## [2.3.4](https://github.com/lwouis/alt-tab-macos/compare/v2.3.3...v2.3.4) (2020-01-22)

### Bug Fixes

* escape key was absorbed by the inactive app (closes [#123](https://github.com/lwouis/alt-tab-macos/issues/123)) ([5260619](https://github.com/lwouis/alt-tab-macos/commit/5260619))
2020-01-22 10:55:32 +00:00
louis.pontoise 5260619fe1 fix: escape key was absorbed by the inactive app (closes #123) 2020-01-22 19:51:48 +09:00
semantic-release-bot 97798c3443 chore(release): 2.3.3 [skip ci]
## [2.3.3](https://github.com/lwouis/alt-tab-macos/compare/v2.3.2...v2.3.3) (2020-01-21)

### Bug Fixes

* touch bar's escape key works on mbp 15 2019 (closes [#119](https://github.com/lwouis/alt-tab-macos/issues/119)) ([eda6b7e](https://github.com/lwouis/alt-tab-macos/commit/eda6b7e))
2020-01-21 00:30:22 +00:00
Phung Tuan Hoang eda6b7e9d9 fix: touch bar's escape key works on mbp 15 2019 (closes #119) 2020-01-21 09:27:47 +09:00
semantic-release-bot 5b8a9110db chore(release): 2.3.2 [skip ci]
## [2.3.2](https://github.com/lwouis/alt-tab-macos/compare/v2.3.1...v2.3.2) (2020-01-05)

### Bug Fixes

* app crashes when no windows are open ([cecc53a](https://github.com/lwouis/alt-tab-macos/commit/cecc53a))
2020-01-05 04:32:51 +00:00
Robinhuett cecc53a0e0 fix: app crashes when no windows are open 2020-01-05 13:30:21 +09:00
semantic-release-bot 4317bedd9f chore(release): 2.3.1 [skip ci]
## [2.3.1](https://github.com/lwouis/alt-tab-macos/compare/v2.3.0...v2.3.1) (2020-01-04)

### Bug Fixes

* selecting windows theme shows an error (closes [#109](https://github.com/lwouis/alt-tab-macos/issues/109)) ([01163c6](https://github.com/lwouis/alt-tab-macos/commit/01163c6))
2020-01-04 15:34:51 +00:00
louis.pontoise 01163c69fc fix: selecting windows theme shows an error (closes #109) 2020-01-05 00:32:13 +09:00
louis.pontoise 9f46e6561a docs: document private apis better for offscreen windows 2020-01-05 00:32:13 +09:00
semantic-release-bot efc27e915d chore(release): 2.3.0 [skip ci]
# [2.3.0](https://github.com/lwouis/alt-tab-macos/compare/v2.2.0...v2.3.0) (2020-01-04)

### Features

* handle hidden app windows (closes [#108](https://github.com/lwouis/alt-tab-macos/issues/108)) ([6fcf092](https://github.com/lwouis/alt-tab-macos/commit/6fcf092))
2020-01-04 13:59:39 +00:00
louis.pontoise 6fcf092690 feat: handle hidden app windows (closes #108) 2020-01-04 22:57:06 +09:00
semantic-release-bot fdb132779c chore(release): 2.2.0 [skip ci]
# [2.2.0](https://github.com/lwouis/alt-tab-macos/compare/v2.1.0...v2.2.0) (2020-01-03)

### Bug Fixes

* follow-up on pr-104; minimized windows are not on another space ([998c763](https://github.com/lwouis/alt-tab-macos/commit/998c763))

### Features

* **ux:** add option to hide the space number label ([51a193c](https://github.com/lwouis/alt-tab-macos/commit/51a193c))
2020-01-03 12:42:45 +00:00
louis.pontoise 998c76334e fix: follow-up on pr-104; minimized windows are not on another space 2020-01-03 21:40:06 +09:00
Aarni Koskela 51a193c1d4 feat(ux): add option to hide the space number label 2020-01-03 21:40:06 +09:00
semantic-release-bot 2adefd0830 chore(release): 2.1.0 [skip ci]
# [2.1.0](https://github.com/lwouis/alt-tab-macos/compare/v2.0.3...v2.1.0) (2020-01-03)

### Bug Fixes

* **ux:** simplify tool menu ([de7f428](https://github.com/lwouis/alt-tab-macos/commit/de7f428))
* issue in pr-104 where app would not show properly ([4d19015](https://github.com/lwouis/alt-tab-macos/commit/4d19015))
* small ux change on pr-104 ([6d2741a](https://github.com/lwouis/alt-tab-macos/commit/6d2741a))

### Features

* add menu option to pop up the selector window ([78428dc](https://github.com/lwouis/alt-tab-macos/commit/78428dc))
2020-01-03 11:21:24 +00:00
louis.pontoise 6d2741a766 fix: small ux change on pr-104 2020-01-03 20:18:31 +09:00
louis.pontoise 4d190150ac fix: issue in pr-104 where app would not show properly 2020-01-03 20:18:31 +09:00
Aarni Koskela 78428dc309 feat: add menu option to pop up the selector window 2020-01-03 20:18:31 +09:00
Aarni Koskela de7f428ba1 fix(ux): simplify tool menu 2020-01-03 20:18:31 +09:00
semantic-release-bot 15eb37b40e chore(release): 2.0.3 [skip ci]
## [2.0.3](https://github.com/lwouis/alt-tab-macos/compare/v2.0.2...v2.0.3) (2020-01-03)

### Bug Fixes

* better filtering of "actual" windows (closes 102) ([fcdce9c](https://github.com/lwouis/alt-tab-macos/commit/fcdce9c))
2020-01-03 10:47:07 +00:00
louis.pontoise fcdce9cbac fix: better filtering of "actual" windows (closes 102) 2020-01-03 19:44:26 +09:00
semantic-release-bot c69123b3d4 chore(release): 2.0.2 [skip ci]
## [2.0.2](https://github.com/lwouis/alt-tab-macos/compare/v2.0.1...v2.0.2) (2019-12-30)

### Bug Fixes

* space numbers are correctly removed if single space ([45ad43f](https://github.com/lwouis/alt-tab-macos/commit/45ad43f))
2019-12-30 09:39:53 +00:00
louis.pontoise 45ad43f347 fix: space numbers are correctly removed if single space 2019-12-30 18:37:22 +09:00
semantic-release-bot 1e210c382a chore(release): 2.0.1 [skip ci]
## [2.0.1](https://github.com/lwouis/alt-tab-macos/compare/v2.0.0...v2.0.1) (2019-12-30)

### Bug Fixes

* app crashes when invoked when there is 0 window (closes [#95](https://github.com/lwouis/alt-tab-macos/issues/95)) ([921590a](https://github.com/lwouis/alt-tab-macos/commit/921590a))
2019-12-30 00:52:30 +00:00
louis.pontoise 921590aec5 fix: app crashes when invoked when there is 0 window (closes #95) 2019-12-30 09:49:56 +09:00
semantic-release-bot 9c218f0cf7 chore(release): 2.0.0 [skip ci]
# [2.0.0](https://github.com/lwouis/alt-tab-macos/compare/v1.14.4...v2.0.0) (2019-12-27)

### Features

* display other spaces/minimized windows (closes [#14](https://github.com/lwouis/alt-tab-macos/issues/14)) ([3f5ea25](https://github.com/lwouis/alt-tab-macos/commit/3f5ea25)), closes [#11](https://github.com/lwouis/alt-tab-macos/issues/11) [#45](https://github.com/lwouis/alt-tab-macos/issues/45) [#62](https://github.com/lwouis/alt-tab-macos/issues/62)

### BREAKING CHANGES

* this brings huge changes to core parts of the codebase. It introduces the use of private APIs that hopefully are should be compatible from macOS 10.12+, but I couldn't test them. I reviewed the whole codebase to clean and improve on performance and readability
2019-12-27 05:50:21 +00:00
louis.pontoise 3f5ea25154 feat: display other spaces/minimized windows (closes #14)
Also closes #11 closes #45 closes #62

BREAKING CHANGE: this brings huge changes to core parts of the codebase. It introduces the use of private APIs that hopefully are should be compatible from macOS 10.12+, but I couldn't test them. I reviewed the whole codebase to clean and improve on performance and readability
2019-12-27 14:47:51 +09:00
semantic-release-bot b50fa5bd92 chore(release): 1.14.4 [skip ci]
## [1.14.4](https://github.com/lwouis/alt-tab-macos/compare/v1.14.3...v1.14.4) (2019-12-24)
2019-12-24 05:57:50 +00:00
louis.pontoise 74edb28108 docs: clarify which macos versions are supported 2019-12-24 14:55:11 +09:00
semantic-release-bot 87647b9507 chore(release): 1.14.3 [skip ci]
## [1.14.3](https://github.com/lwouis/alt-tab-macos/compare/v1.14.2...v1.14.3) (2019-11-12)

### Bug Fixes

* code compile compatibility with old macos ([10552a0](https://github.com/lwouis/alt-tab-macos/commit/10552a0))
2019-11-12 04:09:35 +00:00
Mariusz Bieniek 10552a017a fix: code compile compatibility with old macos
- .zero in Int/Int32/UInt32 is missing here
2019-11-12 13:07:03 +09:00
semantic-release-bot bdb51b604e chore(release): 1.14.2 [skip ci]
## [1.14.2](https://github.com/lwouis/alt-tab-macos/compare/v1.14.1...v1.14.2) (2019-11-11)
2019-11-11 06:22:17 +00:00
Louis Pontoise b363ba636d refactor: wrap cg and ax apis into classes to clarify codebase 2019-11-11 15:18:54 +09:00
semantic-release-bot 08549b4df4 chore(release): 1.14.1 [skip ci]
## [1.14.1](https://github.com/lwouis/alt-tab-macos/compare/v1.14.0...v1.14.1) (2019-11-11)

### Bug Fixes

* handle preference files with deprecated keys ([eabc327](https://github.com/lwouis/alt-tab-macos/commit/eabc327))
2019-11-11 06:15:42 +00:00
Louis Pontoise eabc327edc fix: handle preference files with deprecated keys 2019-11-11 15:12:54 +09:00
semantic-release-bot 95d882101d chore(release): 1.14.0 [skip ci]
# [1.14.0](https://github.com/lwouis/alt-tab-macos/compare/v1.13.0...v1.14.0) (2019-11-11)

### Features

* merge previous preferences onto new defaults (closes [#73](https://github.com/lwouis/alt-tab-macos/issues/73)) ([7ec3a50](https://github.com/lwouis/alt-tab-macos/commit/7ec3a50))
* reading preferences on disk will reset file if error (closes [#73](https://github.com/lwouis/alt-tab-macos/issues/73)) ([39677fe](https://github.com/lwouis/alt-tab-macos/commit/39677fe))
2019-11-11 06:05:08 +00:00
Louis Pontoise 7ec3a50f22 feat: merge previous preferences onto new defaults (closes #73) 2019-11-11 15:02:19 +09:00
Louis Pontoise 39677fe542 feat: reading preferences on disk will reset file if error (closes #73) 2019-11-11 14:39:40 +09:00
semantic-release-bot d275fc03ff chore(release): 1.13.0 [skip ci]
# [1.13.0](https://github.com/lwouis/alt-tab-macos/compare/v1.12.3...v1.13.0) (2019-11-11)

### Features

* improved PreferencesPanel UX, partially implements [#49](https://github.com/lwouis/alt-tab-macos/issues/49) ([59fc712](https://github.com/lwouis/alt-tab-macos/commit/59fc712))
* improved PreferencesPanel UX, partially implements [#49](https://github.com/lwouis/alt-tab-macos/issues/49) ([fa4d150](https://github.com/lwouis/alt-tab-macos/commit/fa4d150))
* improves PreferencesPanel UX, partially implements [#49](https://github.com/lwouis/alt-tab-macos/issues/49) ([21a4587](https://github.com/lwouis/alt-tab-macos/commit/21a4587))
* improves PreferencesPanel UX, partially implements [#49](https://github.com/lwouis/alt-tab-macos/issues/49) ([65327c2](https://github.com/lwouis/alt-tab-macos/commit/65327c2))
2019-11-11 00:12:07 +00:00
Mariusz Bieniek 21a4587e77 feat: improves PreferencesPanel UX, partially implements #49
implements requested changes from Code-Review and contains also refactoring, additions & improvements
- PreferencesPanel: does not handle NSApp.activate & .deactivate anymore
- PreferencesPanel: maxThumbnailsPerRow & windowDisplayDelay are now sliders
- PreferencesPanel: Sliders do not use tickmarks anymore (to allow finer settings)
- PreferencesPanel: tweaked Sliders min/max values
- PreferencesPanel: adds Hyperlink to KeyCodes Reference as suffix for Tab key control (with additional required sub-class of NSTextField)
- PreferencesPanel: adds makeSuffix() method for code clarity
2019-11-11 09:09:36 +09:00
Mariusz Bieniek 65327c2b89 feat: improves PreferencesPanel UX, partially implements #49
implements requested changes from Code-Review and contains also refactoring and more features and improvements
- Application Wide: changes all exceptions to NSError (required for error handling via sheet in panel)
- PreferencesPanel: adds display of current value of Sliders
- PreferencesPanel: adds validation with visualisation for TextFields (whitelist for KeyCode and ranges for maxScreenUsage & windowDisplayDelay) during editing, window open and close
- PreferencesPanel: adds error sheet (in-window modal) at all known possible errors to display error information and ask the user how to proceed
- PreferencesPanel: removes Restart button (and relaunch code in Application)
- PreferencesPanel: adds Preferences being now live
- PreferencesPanel: removes invisibleText workaround
- PreferencesPanel: adds TextField value save on each keyDown event (if valid and changed)
- PreferencesPanel: adds window activation/deactivation
- PreferencesPanel: changes label texts of some Preferences
- ...
2019-11-11 09:09:36 +09:00
Mariusz Bieniek 59fc712086 feat: improved PreferencesPanel UX, partially implements #49
- ux/code: adds sliders (maxScreenUsage, iconSize, fontHeight)
- ux: defined sensible min/max/step values for sliders
- code: fixes panelWidth (panel and its content did not grow correctly)
- code: removes inputsMap (NSControl.identifier is now used for that)
- code: adds makeLabelWithProvidedControl() as a helper to create labeled controls with a optional suffix
- code: removes dropdownDidChange() & textDidEndEditing() -> combined in controlDidEndEditing()
- code: adds controlDidEndEditing() as an universal .action for NSControl elements
  - adds a restore of values in UI and Preferences if there is an issue while saving a Preference
- code: adds another little code clarity improvements
2019-11-11 09:09:36 +09:00
Mariusz Bieniek fa4d1506b9 feat: improved PreferencesPanel UX, partially implements #49
- ux: first pass on UI
- ux: groups available preferences by keys-, visual-, behaviour-preferences (vertical separation without labels)
- ux: adds Restart action
- code: removes unused variables
- code: PreferencesPanel is no longer a Delegate of an view child
2019-11-11 09:09:36 +09:00
semantic-release-bot 177d2cf049 chore(release): 1.12.3 [skip ci]
## [1.12.3](https://github.com/lwouis/alt-tab-macos/compare/v1.12.2...v1.12.3) (2019-11-10)
2019-11-10 09:24:02 +00:00
Louis Pontoise 42ef511329 docs: add discord server for community discussions (closes #79) 2019-11-10 18:21:19 +09:00
semantic-release-bot 91029f791f chore(release): 1.12.2 [skip ci]
## [1.12.2](https://github.com/lwouis/alt-tab-macos/compare/v1.12.1...v1.12.2) (2019-11-06)
2019-11-06 01:27:54 +00:00
Louis Pontoise a429b41465 refactor: add .github to xcode project so it's visible in the ide 2019-11-06 10:24:53 +09:00
semantic-release-bot 9089efc147 chore(release): 1.12.1 [skip ci]
## [1.12.1](https://github.com/lwouis/alt-tab-macos/compare/v1.12.0...v1.12.1) (2019-11-06)
2019-11-06 01:15:26 +00:00
Louis Pontoise ee1d7f864b ci: pr greeter doesn't handle multilines properly so using 1 line 2019-11-06 10:12:53 +09:00
semantic-release-bot e7d444f842 chore(release): 1.12.0 [skip ci]
# [1.12.0](https://github.com/lwouis/alt-tab-macos/compare/v1.11.3...v1.12.0) (2019-11-01)

### Features

* windows on mouse screen, implements [#28](https://github.com/lwouis/alt-tab-macos/issues/28) ([b841ec7](https://github.com/lwouis/alt-tab-macos/commit/b841ec7))
* windows on mouse screen, implements [#28](https://github.com/lwouis/alt-tab-macos/issues/28) ([6c93047](https://github.com/lwouis/alt-tab-macos/commit/6c93047)), closes [#66](https://github.com/lwouis/alt-tab-macos/issues/66) [#59](https://github.com/lwouis/alt-tab-macos/issues/59) [#66](https://github.com/lwouis/alt-tab-macos/issues/66) [#66](https://github.com/lwouis/alt-tab-macos/issues/66)
2019-11-01 14:23:29 +00:00
Louis Pontoise b841ec7a57 feat: windows on mouse screen, implements #28
squash of pull-request corrections and improvements

refactor: better mimic apple centering

Also use enum instead of bool to self-document the interface

docs: clarify the show-on-screen preference wording

Discussion on this SO (https://stackoverflow.com/a/864432/2249756) seem to indicate that .main is not the screen with the menubar, however in my tests, it is always that window. I think macOS changed the behavior of .main without updating the documentation

refactor: shorter method names as swift promotes + removed debug code

fix: all methods in screen should use visibleFrame not frame

refactor: (hopefully) made code intent clearer

fix: panel and collection layout now use dynamic screen variable

fix: fix vertical origin from 4c44100f196
2019-11-01 23:20:53 +09:00
Mariusz Bieniek 6c9304735a feat: windows on mouse screen, implements #28
squash of implementation for pull-request #66 and review
- adds a new Preference to use the main screen (keyboard focus) or mouse location screen
- honors that preference for thumbnail generation and display of all panels
- increases the Preferences version
- widens PreferencesPanel width and input sizing to allow 3 characters, issue #59 minimal adjustment

feat: windows on mouse screen: changes from pull request #66 code review

- corrections, improvements & refactoring

feat: windows on mouse screen: additional changes for pull request #66

- Screen.preferredScreenOverride: removed
- instead currentScreen gets provided or updated now at all required places before triggering UI summon calculations
  - ThumbnailsPanel.computeThumbnails(): re-creates collectionViewLayout instead of invalidating it
- Screen.showCenteredFrontPanel(): useAppleVerticalOffset applies now only if the NSWindow frame is smaller than 2/3 of visibleFrame
2019-11-01 23:20:53 +09:00
semantic-release-bot a184ad5309 chore(release): 1.11.3 [skip ci]
## [1.11.3](https://github.com/lwouis/alt-tab-macos/compare/v1.11.2...v1.11.3) (2019-10-30)
2019-10-30 13:59:50 +00:00
Louis Pontoise a6a64b782a ci: improve greeting message 2019-10-30 22:56:59 +09:00
semantic-release-bot 5f64297e95 chore(release): 1.11.2 [skip ci]
## [1.11.2](https://github.com/lwouis/alt-tab-macos/compare/v1.11.1...v1.11.2) (2019-10-30)
2019-10-30 13:37:10 +00:00
Louis Pontoise 0266a38645 ci: add github action to instruct contributors on new PR 2019-10-30 22:34:02 +09:00
semantic-release-bot 902330c0d0 chore(release): 1.11.1 [skip ci]
## [1.11.1](https://github.com/lwouis/alt-tab-macos/compare/v1.11.0...v1.11.1) (2019-10-30)
2019-10-30 13:16:21 +00:00
Hugo Locurcio 2a02c2465c docs: improve readme formatting 2019-10-30 22:13:42 +09:00
semantic-release-bot 83ddb35435 chore(release): 1.11.0 [skip ci]
# [1.11.0](https://github.com/lwouis/alt-tab-macos/compare/v1.10.0...v1.11.0) (2019-10-28)

### Bug Fixes

* app was no longer absorbing its shortcut key events properly ([4976267](https://github.com/lwouis/alt-tab-macos/commit/4976267))
* don't let the app bellow get the meta keyUp event ([7f12f41](https://github.com/lwouis/alt-tab-macos/commit/7f12f41))

### Features

* allows more than one metaKeyCode ([7e21974](https://github.com/lwouis/alt-tab-macos/commit/7e21974))
2019-10-28 09:29:55 +00:00
Louis Pontoise 4976267a82 fix: app was no longer absorbing its shortcut key events properly
Regression was introduced by a4a0a9be2e
2019-10-28 18:26:39 +09:00
Louis Pontoise 7f12f4146e fix: don't let the app bellow get the meta keyUp event 2019-10-28 18:21:22 +09:00
Mariusz Bieniek 7e21974ebf feat: allows more than one metaKeyCode
metaKeyCodes is now an array and is provided with both keycodes for option, control and command. This fixes two issues:
- UI stayed open when the user did open it with the secondary metaKey keyCode (the UI got toggled by the modifierFlags check) and the user had to click the proper metaKeyCode to close it again
- PC keyboards (all of them? i observed this on a Logitech K740) send the secondary keyCode for the command and option keys so the application did not work for this setup
2019-10-28 18:20:14 +09:00
Mariusz Bieniek 479778662d refactor: removes KeyCode enum and uses apple provided definition 2019-10-28 18:10:06 +09:00
semantic-release-bot bcf6c13c72 chore(release): 1.10.0 [skip ci]
# [1.10.0](https://github.com/lwouis/alt-tab-macos/compare/v1.9.8...v1.10.0) (2019-10-28)

### Features

* don't show the UI on very fast shortcut triggers from the user ([4b5fa1a](https://github.com/lwouis/alt-tab-macos/commit/4b5fa1a))
2019-10-28 08:26:34 +00:00
gcbw 64049d932c docs: add switch as an alternative 2019-10-28 17:23:53 +09:00
Louis Pontoise a4a0a9be2e refactor: keyboard event listening should be read-only 2019-10-28 17:23:49 +09:00
Louis Pontoise 4b5fa1a9db feat: don't show the UI on very fast shortcut triggers from the user
By listening to keyboard events from another thread, that thread is able to cancel tasks scheduled on the main UI thread. This means that if the user activates the app, and very quickly release the keys to focus the other window, that key release event may be processed before the main UI thread tasks have finished. The keyboard processing thread may then cancel the UI work resulting in the UI not showing, which is good here
2019-10-28 17:22:04 +09:00
semantic-release-bot a5873d557a chore(release): 1.9.8 [skip ci]
## [1.9.8](https://github.com/lwouis/alt-tab-macos/compare/v1.9.7...v1.9.8) (2019-10-28)

### Bug Fixes

* adds missing return statements ([4b517ff](https://github.com/lwouis/alt-tab-macos/commit/4b517ff))
2019-10-28 07:51:15 +00:00
Mariusz Bieniek 4b517ff5b9 fix: adds missing return statements
so the project builds without any compile errors on macOS high sierra (10.13.x)
2019-10-28 16:48:46 +09:00
semantic-release-bot d9a23c21bd chore(release): 1.9.7 [skip ci]
## [1.9.7](https://github.com/lwouis/alt-tab-macos/compare/v1.9.6...v1.9.7) (2019-10-27)

### Bug Fixes

* remove broken meta keys from preferences (closes [#61](https://github.com/lwouis/alt-tab-macos/issues/61)) ([5517e7a](https://github.com/lwouis/alt-tab-macos/commit/5517e7a))
2019-10-27 23:17:43 +00:00
Louis Pontoise 5517e7a931 fix: remove broken meta keys from preferences (closes #61) 2019-10-28 08:15:12 +09:00
semantic-release-bot 46c16305b0 chore(release): 1.9.6 [skip ci]
## [1.9.6](https://github.com/lwouis/alt-tab-macos/compare/v1.9.5...v1.9.6) (2019-10-26)

### Bug Fixes

* removed logic on meta key press and better app summon logic ([8ac6a51](https://github.com/lwouis/alt-tab-macos/commit/8ac6a51))
2019-10-26 13:52:30 +00:00
Louis Pontoise 6f5f4d08c7 docs: add window-switcher as an alternative 2019-10-26 22:50:00 +09:00
Louis Pontoise 8ac6a51b2f fix: removed logic on meta key press and better app summon logic 2019-10-26 22:49:59 +09:00
semantic-release-bot 088b7123c0 chore(release): 1.9.5 [skip ci]
## [1.9.5](https://github.com/lwouis/alt-tab-macos/compare/v1.9.4...v1.9.5) (2019-10-25)

### Bug Fixes

* option key was broken as a meta key ([e59d51d](https://github.com/lwouis/alt-tab-macos/commit/e59d51d))
2019-10-25 17:05:57 +00:00
Louis Pontoise e59d51ddab fix: option key was broken as a meta key
Bug was introduced in b6e4826e40
2019-10-26 02:02:01 +09:00
semantic-release-bot c7af429b8f chore(release): 1.9.4 [skip ci]
## [1.9.4](https://github.com/lwouis/alt-tab-macos/compare/v1.9.3...v1.9.4) (2019-10-25)

### Bug Fixes

* app was broken for new installs because of the tab keyCode ([51e9aee](https://github.com/lwouis/alt-tab-macos/commit/51e9aee))
2019-10-25 16:17:15 +00:00
Louis Pontoise 51e9aeef05 fix: app was broken for new installs because of the tab keyCode
Bug was introduced in b6e4826e40
2019-10-26 01:12:25 +09:00
semantic-release-bot e51379a575 chore(release): 1.9.3 [skip ci]
## [1.9.3](https://github.com/lwouis/alt-tab-macos/compare/v1.9.2...v1.9.3) (2019-10-25)
2019-10-25 15:49:29 +00:00
Adam Nemecek 828c85dfc0 refactor: remove unneeded symbols 2019-10-26 00:41:14 +09:00
semantic-release-bot 009c0e7337 chore(release): 1.9.2 [skip ci]
## [1.9.2](https://github.com/lwouis/alt-tab-macos/compare/v1.9.1...v1.9.2) (2019-10-25)
2019-10-25 15:39:56 +00:00
Laxman Damera 1ec0168fec docs: fix wikipedia link 2019-10-26 00:34:25 +09:00
Louis Pontoise bfbf9fe3aa docs: better alternatives section 2019-10-26 00:34:25 +09:00
semantic-release-bot fd105e4164 chore(release): 1.9.1 [skip ci]
## [1.9.1](https://github.com/lwouis/alt-tab-macos/compare/v1.9.0...v1.9.1) (2019-10-25)
2019-10-25 15:13:31 +00:00
Louis Pontoise 2611d6e1a5 docs: update readme with up-to-date screenshots and clearer explanations 2019-10-26 00:08:26 +09:00
semantic-release-bot b07588a354 chore(release): 1.9.0 [skip ci]
# [1.9.0](https://github.com/lwouis/alt-tab-macos/compare/v1.8.1...v1.9.0) (2019-10-25)

### Features

* hovering with the mouse highlights cells (closes [#34](https://github.com/lwouis/alt-tab-macos/issues/34)) ([f20ada6](https://github.com/lwouis/alt-tab-macos/commit/f20ada6))
2019-10-25 12:06:44 +00:00
Louis Pontoise f20ada68d2 feat: hovering with the mouse highlights cells (closes #34) 2019-10-25 21:04:00 +09:00
semantic-release-bot a149ba658f chore(release): 1.8.1 [skip ci]
## [1.8.1](https://github.com/lwouis/alt-tab-macos/compare/v1.8.0...v1.8.1) (2019-10-25)

### Bug Fixes

* meta+arrow activates only if meta+tab was first pressed ([aa5f748](https://github.com/lwouis/alt-tab-macos/commit/aa5f748))
2019-10-25 11:23:39 +00:00
Louis Pontoise aa5f748fa9 fix: meta+arrow activates only if meta+tab was first pressed
Also potentially meta+other_key would be absorbed by the app and not propagated to the focused app
2019-10-25 20:20:53 +09:00
Louis Pontoise cd52663def refactor: simple closure on one line for readability 2019-10-25 20:20:53 +09:00
semantic-release-bot 2e45475a32 chore(release): 1.8.0 [skip ci]
# [1.8.0](https://github.com/lwouis/alt-tab-macos/compare/v1.7.2...v1.8.0) (2019-10-25)

### Features

* use arrow keys to navigate the UI (closes [#53](https://github.com/lwouis/alt-tab-macos/issues/53)) ([1049a50](https://github.com/lwouis/alt-tab-macos/commit/1049a50))
2019-10-25 10:19:55 +00:00
Louis Pontoise 1049a50451 feat: use arrow keys to navigate the UI (closes #53) 2019-10-25 19:17:12 +09:00
Louis Pontoise 3d5f5bac73 refactor: clarify code 2019-10-25 19:11:07 +09:00
Louis Pontoise 5471a179f8 refactor: clearer function names and organization 2019-10-25 18:15:39 +09:00
Louis Pontoise 5a74797345 refactor: clearer sub-functions 2019-10-25 17:51:25 +09:00
Louis Pontoise dbda22c9b7 refactor: optional parameter labels 2019-10-25 17:51:25 +09:00
semantic-release-bot b2da8d810e chore(release): 1.7.2 [skip ci]
## [1.7.2](https://github.com/lwouis/alt-tab-macos/compare/v1.7.1...v1.7.2) (2019-10-25)

### Bug Fixes

* increased contrast to help with dark backgrounds ([8458113](https://github.com/lwouis/alt-tab-macos/commit/8458113))
2019-10-25 06:17:08 +00:00
Louis Pontoise 845811347a fix: increased contrast to help with dark backgrounds 2019-10-25 15:14:35 +09:00
Louis Pontoise f00131ddd0 refactor: move preference code in the same file 2019-10-25 15:14:34 +09:00
semantic-release-bot ee9ba59978 chore(release): 1.7.1 [skip ci]
## [1.7.1](https://github.com/lwouis/alt-tab-macos/compare/v1.7.0...v1.7.1) (2019-10-25)

### Bug Fixes

* remove flickr due to current app losing focus when AltTab appears ([98273de](https://github.com/lwouis/alt-tab-macos/commit/98273de))
2019-10-25 05:55:06 +00:00
Louis Pontoise 98273de106 fix: remove flickr due to current app losing focus when AltTab appears 2019-10-25 14:52:32 +09:00
Louis Pontoise defb2a2991 refactor: moved messy code to dedicated classes/files 2019-10-25 14:52:32 +09:00
Louis Pontoise 77bb69c132 refactor: moved local constant to a preference 2019-10-25 14:52:31 +09:00
Louis Pontoise c2c10f5bdd refactor: move extensions in a dedicated file as they are global 2019-10-25 14:52:30 +09:00
Louis Pontoise 88d0872c56 refactor: clearer comments 2019-10-25 14:52:30 +09:00
Louis Pontoise bb943bf9ae chore: licence.md was missing from the xcode project 2019-10-25 14:52:29 +09:00
semantic-release-bot e101dda9f1 chore(release): 1.7.0 [skip ci]
# [1.7.0](https://github.com/lwouis/alt-tab-macos/compare/v1.6.1...v1.7.0) (2019-10-25)

### Bug Fixes

* don't crash when the OS doesn't return an icon ([ce6f6aa](https://github.com/lwouis/alt-tab-macos/commit/ce6f6aa))

### Features

* close main window when (meta and) escape is pressed (closes [#44](https://github.com/lwouis/alt-tab-macos/issues/44)) ([b6e4826](https://github.com/lwouis/alt-tab-macos/commit/b6e4826))
2019-10-25 04:05:41 +00:00
Louis Pontoise e669906059 refactor: extracted ad-hoc maps into a clearer system for macro prefs 2019-10-25 13:03:03 +09:00
Louis Pontoise b6e4826e40 feat: close main window when (meta and) escape is pressed (closes #44)
Also added a KeyCode class to make keycode management nicer
2019-10-25 13:03:03 +09:00
Louis Pontoise ce6f6aa223 fix: don't crash when the OS doesn't return an icon 2019-10-25 13:03:02 +09:00
semantic-release-bot 14713f0063 chore(release): 1.6.1 [skip ci]
## [1.6.1](https://github.com/lwouis/alt-tab-macos/compare/v1.6.0...v1.6.1) (2019-10-24)
2019-10-24 15:39:28 +00:00
Louis Pontoise dcb934c423 chore: better error messages 2019-10-25 00:21:21 +09:00
semantic-release-bot 14413b0a0d chore(release): 1.6.0 [skip ci]
# [1.6.0](https://github.com/lwouis/alt-tab-macos/compare/v1.5.1...v1.6.0) (2019-10-24)

### Features

* add mac theme and improve preferences (closes [#21](https://github.com/lwouis/alt-tab-macos/issues/21)) ([4a5bbe9](https://github.com/lwouis/alt-tab-macos/commit/4a5bbe9))
2019-10-24 14:56:43 +00:00
Louis Pontoise 4a5bbe9d1c feat: add mac theme and improve preferences (closes #21) 2019-10-24 23:40:21 +09:00
Louis Pontoise 0a164c731c chore: removed unused image class
This class was actually providing worse quality, even at high settings, than NSImageView, and for way worse performance
2019-10-24 23:37:32 +09:00
semantic-release-bot 8d25631573 chore(release): 1.5.1 [skip ci]
## [1.5.1](https://github.com/lwouis/alt-tab-macos/compare/v1.5.0...v1.5.1) (2019-10-24)
2019-10-24 00:14:50 +00:00
Louis Pontoise 67505d488b docs: explain how to use the JSON preferences file (closes #43) 2019-10-24 09:12:00 +09:00
semantic-release-bot fc7bfb06a0 chore(release): 1.5.0 [skip ci]
# [1.5.0](https://github.com/lwouis/alt-tab-macos/compare/v1.4.7...v1.5.0) (2019-10-23)

### Features

* add panel to set user preferences (closes [#8](https://github.com/lwouis/alt-tab-macos/issues/8)) ([a994825](https://github.com/lwouis/alt-tab-macos/commit/a994825))
2019-10-23 14:21:11 +00:00
Louis Pontoise a99482525b feat: add panel to set user preferences (closes #8) 2019-10-23 23:00:49 +09:00
semantic-release-bot 5ddd2f95fd chore(release): 1.4.7 [skip ci]
## [1.4.7](https://github.com/lwouis/alt-tab-macos/compare/v1.4.6...v1.4.7) (2019-10-23)
2019-10-23 13:50:43 +00:00
Louis Pontoise a4410a4f3e ci: remove release steps for PR and non-master branches 2019-10-23 22:37:02 +09:00
semantic-release-bot 3dee75b0e8 chore(release): 1.4.6 [skip ci]
## [1.4.6](https://github.com/lwouis/alt-tab-macos/compare/v1.4.5...v1.4.6) (2019-10-23)
2019-10-23 13:18:00 +00:00
Louis Pontoise 58886650c4 docs: add correct version to app meta-data (closes #47) 2019-10-23 22:09:59 +09:00
semantic-release-bot 7ff17b5882 chore(release): 1.4.5 [skip ci]
## [1.4.5](https://github.com/lwouis/alt-tab-macos/compare/v1.4.4...v1.4.5) (2019-10-17)

### Bug Fixes

* handle new Screen Recording permission on Catalina (closes [#29](https://github.com/lwouis/alt-tab-macos/issues/29)) ([cbfa586](https://github.com/lwouis/alt-tab-macos/commit/cbfa586))
2019-10-17 15:39:38 +00:00
shaked cbfa5869d9 fix: handle new Screen Recording permission on Catalina (closes #29)
This is a light rework of the work from https://github.com/lwouis/alt-tab-macos/pull/33
2019-10-18 00:31:09 +09:00
semantic-release-bot ee85a2f2b2 chore(release): 1.4.4 [skip ci]
## [1.4.4](https://github.com/lwouis/alt-tab-macos/compare/v1.4.3...v1.4.4) (2019-10-17)

### Bug Fixes

* better decide which windows to show the user (closes [#15](https://github.com/lwouis/alt-tab-macos/issues/15) [#30](https://github.com/lwouis/alt-tab-macos/issues/30)) ([f150b7e](https://github.com/lwouis/alt-tab-macos/commit/f150b7e))
2019-10-17 12:43:58 +00:00
Louis Pontoise f150b7e3dc fix: better decide which windows to show the user (closes #15 #30) 2019-10-17 21:40:56 +09:00
Louis Pontoise 80a883c7d4 docs: comment collection debug statements to ease investigations 2019-10-17 21:40:55 +09:00
Louis Pontoise 3dceee00d5 docs: better error message for accessiblity permission issue 2019-10-17 21:40:55 +09:00
semantic-release-bot 5b08c28f53 chore(release): 1.4.3 [skip ci]
## [1.4.3](https://github.com/lwouis/alt-tab-macos/compare/v1.4.2...v1.4.3) (2019-10-17)
2019-10-17 10:18:47 +00:00
Louis Pontoise bf74cfb32f docs: fix the latest release link
it was broken by adding version numbers to release archives
2019-10-17 19:14:59 +09:00
semantic-release-bot 09d3fc6d2c chore(release): 1.4.2 [skip ci]
## [1.4.2](https://github.com/lwouis/alt-tab-macos/compare/v1.4.1...v1.4.2) (2019-10-17)

### Bug Fixes

* travis should release versioned archives (follow-up to de6ad7f83) ([5538bbd](https://github.com/lwouis/alt-tab-macos/commit/5538bbd))
2019-10-17 07:54:47 +00:00
Louis Pontoise 5538bbdcd2 fix: travis should release versioned archives (follow-up to de6ad7f83) 2019-10-17 16:51:53 +09:00
semantic-release-bot 367b002579 chore(release): 1.4.1 [skip ci]
## [1.4.1](https://github.com/lwouis/alt-tab-macos/compare/v1.4.0...v1.4.1) (2019-10-17)

### Bug Fixes

* travis should release versioned archives (follow-up to de6ad7f83) ([15fcbc9](https://github.com/lwouis/alt-tab-macos/commit/15fcbc9))
2019-10-17 07:48:03 +00:00
Louis Pontoise 15fcbc9670 fix: travis should release versioned archives (follow-up to de6ad7f83) 2019-10-17 16:45:03 +09:00
Louis Pontoise 027711c51a ci: semantic-release already ignores PRs internally (reverts 8171c237) 2019-10-17 16:45:03 +09:00
semantic-release-bot 107406566c chore(release): 1.4.0 [skip ci]
# [1.4.0](https://github.com/lwouis/alt-tab-macos/compare/v1.3.0...v1.4.0) (2019-10-17)

### Features

* add version to the app menubar and release archives (closes [#36](https://github.com/lwouis/alt-tab-macos/issues/36)) ([de6ad7f](https://github.com/lwouis/alt-tab-macos/commit/de6ad7f))
2019-10-17 07:38:05 +00:00
Louis Pontoise de6ad7f83a feat: add version to the app menubar and release archives (closes #36) 2019-10-17 16:35:04 +09:00
semantic-release-bot d80ab88b4d chore(release): 1.3.0 [skip ci]
# [1.3.0](https://github.com/lwouis/alt-tab-macos/compare/v1.2.1...v1.3.0) (2019-10-16)

### Bug Fixes

* upgrade scenario didn't work properly ([f864a25](https://github.com/lwouis/alt-tab-macos/commit/f864a25))

### Features

* add window display delay as a preference ([e52326b](https://github.com/lwouis/alt-tab-macos/commit/e52326b))
2019-10-16 17:25:40 +00:00
Louis Pontoise e52326b781 feat: add window display delay as a preference 2019-10-17 02:15:45 +09:00
Louis Pontoise f864a252ea fix: upgrade scenario didn't work properly 2019-10-17 02:15:45 +09:00
semantic-release-bot fa5a369b64 chore(release): 1.2.1 [skip ci]
## [1.2.1](https://github.com/lwouis/alt-tab-macos/compare/v1.2.0...v1.2.1) (2019-10-16)
2019-10-16 17:08:20 +00:00
Louis Pontoise 8171c23796 ci: only release on master; not PRs 2019-10-17 01:55:12 +09:00
semantic-release-bot 215171063d chore(release): 1.2.0 [skip ci]
# [1.2.0](https://github.com/lwouis/alt-tab-macos/compare/v1.1.0...v1.2.0) (2019-10-16)

### Features

* support macOS 10.11+ (closes [#27](https://github.com/lwouis/alt-tab-macos/issues/27)) ([d0face2](https://github.com/lwouis/alt-tab-macos/commit/d0face2))
2019-10-16 16:48:37 +00:00
Louis Pontoise d0face21ad feat: support macOS 10.11+ (closes #27) 2019-10-17 01:14:24 +09:00
semantic-release-bot 2640258e4c chore(release): 1.1.0 [skip ci]
# [1.1.0](https://github.com/lwouis/alt-tab-macos/compare/v1.0.12...v1.1.0) (2019-10-16)

### Features

* preferences can be changed through JSON file ([64cb6f0](https://github.com/lwouis/alt-tab-macos/commit/64cb6f0))
2019-10-16 12:38:46 +00:00
Louis Pontoise 64cb6f067d feat: preferences can be changed through JSON file
* removed unused Resources from the bundle
* thumbnails quality is now a preference
2019-10-16 21:34:58 +09:00
semantic-release-bot f56fd59042 chore(release): 1.0.12 [skip ci]
## [1.0.12](https://github.com/lwouis/alt-tab-macos/compare/v1.0.11...v1.0.12) (2019-10-15)
2019-10-15 11:45:49 +00:00
Louis Pontoise 60560f5269 docs: adding alternatives 2019-10-15 20:42:51 +09:00
Louis Pontoise 9a93a4adc6 docs: adding GPLv3 licence 2019-10-15 20:42:50 +09:00
semantic-release-bot aeb4a4d776 chore(release): 1.0.11 [skip ci]
## [1.0.11](https://github.com/lwouis/alt-tab-macos/compare/v1.0.10...v1.0.11) (2019-10-04)

### Bug Fixes

* keyboard events don't stop being listened to (closes [#18](https://github.com/lwouis/alt-tab-macos/issues/18)) ([75db5e9](https://github.com/lwouis/alt-tab-macos/commit/75db5e9))
2019-10-04 06:22:12 +00:00
Louis Pontoise 75db5e9ac7 fix: keyboard events don't stop being listened to (closes #18) 2019-10-04 15:19:23 +09:00
semantic-release-bot f9f4565d7d chore(release): 1.0.10 [skip ci]
## [1.0.10](https://github.com/lwouis/alt-tab-macos/compare/v1.0.9...v1.0.10) (2019-09-30)

### Bug Fixes

* don't crash when focusing an app that was closed (closes [#19](https://github.com/lwouis/alt-tab-macos/issues/19)) ([6b5e426](https://github.com/lwouis/alt-tab-macos/commit/6b5e426))
2019-09-30 02:59:09 +00:00
Louis Pontoise 6b5e426e05 fix: don't crash when focusing an app that was closed (closes #19) 2019-09-30 11:56:13 +09:00
semantic-release-bot 8773b1dceb chore(release): 1.0.9 [skip ci]
## [1.0.9](https://github.com/lwouis/alt-tab-macos/compare/v1.0.8...v1.0.9) (2019-09-16)

### Bug Fixes

* crash when windows changed between the CG and the AX calls ([2fa140f](https://github.com/lwouis/alt-tab-macos/commit/2fa140f))
* don't crash when the nsevent contructor fails ([6f61354](https://github.com/lwouis/alt-tab-macos/commit/6f61354))
2019-09-16 10:58:20 +00:00
Louis Pontoise 2fa140f027 fix: crash when windows changed between the CG and the AX calls 2019-09-16 19:55:27 +09:00
Louis Pontoise 6f613547c4 fix: don't crash when the nsevent contructor fails
Error was:

alt-tab-macos[17018:919870] unrecognized type is 4294967294
alt-tab-macos[17018:919870] *** Assertion failure in -[NSEvent _initWithCGEvent:eventRef:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/AppKit/AppKit-1671.60.107/AppKit.subproj/NSEvent.m:1977
alt-tab-macos[17018:919870] Invalid parameter not satisfying: _type > 0 && _type <= kCGSLastEventType
2019-09-16 19:55:27 +09:00
semantic-release-bot ba9379b041 chore(release): 1.0.8 [skip ci]
## [1.0.8](https://github.com/lwouis/alt-tab-macos/compare/v1.0.7...v1.0.8) (2019-09-02)

### Bug Fixes

* should not alter focus when displayed (closes [#16](https://github.com/lwouis/alt-tab-macos/issues/16)) ([376a21b](https://github.com/lwouis/alt-tab-macos/commit/376a21b))
2019-09-02 02:15:10 +00:00
Louis Pontoise 376a21bba1 fix: should not alter focus when displayed (closes #16) 2019-09-02 11:12:25 +09:00
semantic-release-bot 0aa330b2dd chore(release): 1.0.7 [skip ci]
## [1.0.7](https://github.com/lwouis/alt-tab-macos/compare/v1.0.6...v1.0.7) (2019-08-30)

### Bug Fixes

* alt-shift-tab as first shortcut works properly (closes [#10](https://github.com/lwouis/alt-tab-macos/issues/10)) ([87a0a3c](https://github.com/lwouis/alt-tab-macos/commit/87a0a3c))
2019-08-30 04:51:43 +00:00
Louis Pontoise 87a0a3c277 fix: alt-shift-tab as first shortcut works properly (closes #10) 2019-08-30 13:49:12 +09:00
Louis Pontoise 8a4627435a docs: explicit the windows matching assumption 2019-08-30 13:49:11 +09:00
Louis Pontoise 8b907aca40 docs: add changelog to xcode project 2019-08-30 13:49:11 +09:00
semantic-release-bot 0bf0604a0b chore(release): 1.0.6 [skip ci]
## [1.0.6](https://github.com/lwouis/alt-tab-macos/compare/v1.0.5...v1.0.6) (2019-08-29)

### Bug Fixes

* better heuristic for windows of same app (closes [#12](https://github.com/lwouis/alt-tab-macos/issues/12)) ([a4cc11b](https://github.com/lwouis/alt-tab-macos/commit/a4cc11b))
2019-08-29 17:07:27 +00:00
Louis Pontoise a4cc11b470 fix: better heuristic for windows of same app (closes #12) 2019-08-30 02:03:41 +09:00
semantic-release-bot d41bff7a36 chore(release): 1.0.5 [skip ci]
## [1.0.5](https://github.com/lwouis/alt-tab-macos/compare/v1.0.4...v1.0.5) (2019-08-28)
2019-08-28 08:44:18 +00:00
lwouis aad041b744 docs: fix typo in README 2019-08-28 17:41:36 +09:00
semantic-release-bot 994747f03e chore(release): 1.0.4 [skip ci]
## [1.0.4](https://github.com/lwouis/alt-tab-macos/compare/v1.0.3...v1.0.4) (2019-08-28)
2019-08-28 06:58:54 +00:00
Louis Pontoise babe3848b8 docs: link to latest release and links to full-size images 2019-08-28 15:56:13 +09:00
semantic-release-bot 5e952f8e5b chore(release): 1.0.3 [skip ci]
## [1.0.3](https://github.com/lwouis/alt-tab-macos/compare/v1.0.2...v1.0.3) (2019-08-28)
2019-08-28 06:46:53 +00:00
Louis Pontoise 080db1d736 ci: fix github release 2019-08-28 15:44:07 +09:00
Louis Pontoise 5cf630a206 ci: fix github release 2019-08-28 13:59:48 +09:00
semantic-release-bot e6688a3947 chore(release): 1.0.2 [skip ci]
## [1.0.2](https://github.com/lwouis/alt-tab-macos/compare/v1.0.1...v1.0.2) (2019-08-28)
2019-08-28 02:50:42 +00:00
Louis Pontoise 2cdfc4eb2e ci: fix github release 2019-08-28 11:48:10 +09:00
semantic-release-bot ca54ffec05 chore(release): 1.0.1 [skip ci]
## [1.0.1](https://github.com/lwouis/alt-tab-macos/compare/v1.0.0...v1.0.1) (2019-08-28)
2019-08-28 02:45:08 +00:00
Louis Pontoise f485aa3353 ci: fix github release 2019-08-28 11:42:31 +09:00
semantic-release-bot 0250a699bb chore(release): 1.0.0 [skip ci]
# 1.0.0 (2019-08-27)

### Features

* documented the project and reduced image sizes ([930c82d](https://github.com/lwouis/alt-tab-macos/commit/930c82d))
* mvp ([be59936](https://github.com/lwouis/alt-tab-macos/commit/be59936))
2019-08-27 16:23:04 +00:00
Louis Pontoise dceef7bfd6 ci: setup semantic-release and travisCI 2019-08-28 01:10:38 +09:00
Louis Pontoise 930c82df86 feat: documented the project and reduced image sizes 2019-08-27 20:50:13 +09:00
Louis Pontoise 3248b436af refactor: clearer file hierarchy 2019-08-27 20:04:06 +09:00
Louis Pontoise be59936601 feat: mvp 2019-08-27 19:46:53 +09:00
1248 changed files with 143805 additions and 52 deletions

No files matched your search

+193
View File
@@ -0,0 +1,193 @@
---
name: assets-optimization
description: Audit and optimize every image asset shipped with AltTab. Apply the right format per asset class (PDF for vectors, HEIC for raster) and the right post-processing (strip Figma cruft from PDFs, extract SF Symbols as minimal vector PDFs, encode raster sources to HEIC at q50 with visual review). Use whenever new assets are added, when the bundle size needs shrinking, or whenever you want a full assets audit.
---
# /assets-optimization — AltTab asset audit and optimization
## Goal
Every byte that ships in `AltTab.app/Contents/Resources/` should justify itself. Vectors stay vector, rasters compress to HEIC, and neither carries metadata, color profiles, accessibility tags, or producer signatures that AppKit doesn't use.
This skill applies a known-good pipeline to each asset class. It is opinionated about the right format and the right encoder for each kind of content.
## When to use
- A designer drops new exports into `~/Desktop/` or `resources/`.
- Someone asks "why is the bundle so big?".
- After adding a new icon, illustration, app icon variant, or menubar variant.
- Periodic audit when nothing else is broken.
## Step 1: Inventory
Run a one-shot enumeration so you know what you're working with:
```sh
find resources -type f \( -iname '*.pdf' -o -iname '*.png' -o -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.heic' -o -iname '*.svg' -o -iname '*.icns' \) \
-exec ls -la {} \; | awk '{printf "%8d %s\n", $5, $9}' | sort -k2
```
Group what you see by directory. For AltTab the relevant buckets are:
- `resources/icons/menubar/` — small template icons shown in the macOS menubar.
- `resources/icons/tabs/` — Preferences sidebar icons (template, sized ~13pt).
- `resources/icons/permission-window/` — first-launch permission window icons (~32pt).
- `resources/icons/app/` — the macOS app icon (`.icns` + `.iconset/`). **Don't touch** — `.icns` is required by the bundle and Apple's tooling produces near-optimal output already.
- `resources/illustrations/` — the appearance-tab preview thumbnails. Raster (screenshots inside).
For each asset, decide what category it falls into:
| Source content | Right format | Why |
|---|---|---|
| Custom vector design (Figma/Sketch/Illustrator) | **PDF** | macOS 10.13 doesn't accept SVG; PDF is the universal vector container AppKit reads natively. |
| SF Symbol (Apple system glyph) | **Font glyph** in the bundled `SF-Pro-Text-Regular.otf` subset | Render via `NSImage.fromSymbol(.foo, pointSize:)` (or as text via the `Symbols` enum). Smaller than per-icon PDFs, picks up Apple's latest glyph refinements automatically when the developer updates SF Symbols.app. |
| Photographic / screenshot-heavy | **HEIC** | HEIC at q50 beats JPEG by ~30% at the same perceptual quality. |
| Tiny pixel-precise UI sprite | **PNG @2x** | Below ~40×40px the PDF overhead exceeds the bitmap savings. PNG wins. |
| App icon (the macOS bundle one) | **`.icns`** | Required by `CFBundleIconFile`. |
If an asset is in the wrong format, flag it. If it's in the right format but unoptimized, run the matching pipeline below.
## Step 2: Vector PDFs — Figma exports
Figma's "Export → PDF" output is bloated. For each menubar/illustration/icon vector PDF that came from Figma, you can strip ~50–75% of the bytes without losing a single rendered pixel.
What Figma adds that AppKit doesn't need:
1. **Embedded ICC color profile** (`/ICCBased ...`, ~3.2 KB compressed). Replace every `[/ICCBased N R]` reference with `/DeviceRGB` (or `/DeviceGray` for monochrome). Patches needed in:
- the page `Resources/ColorSpace` dict
- every Form XObject's `Resources/ColorSpace` dict (these are streams, not plain dicts — pikepdf's `pdf.objects` will only catch them if you accept both `Dictionary` and `Stream`)
- every Image XObject's direct `/ColorSpace` key
- every Shading dict inside `Pattern` entries (Figma's color icons use 8+ patterns, each with its own `/ColorSpace N R` reference)
2. **`/Metadata`** XMP packet (~830 B) — Figma's XML manifest.
3. **`/StructTreeRoot`, `/ParentTree`, `/StructElem`** — accessibility tags ("Document" / "Part" structural roles). AppKit's PDF renderer ignores them.
4. **`/Info` dict** — `Producer="Figma"`, `Title="Menubar 22x22@1x white"`. In Figma's exports the Info dict sometimes lives **inline inside the Catalog** rather than at the trailer level, so deleting `pdf.docinfo` isn't enough — also `del root[Name('/Info')]`.
5. **`/Lang`, `/MarkInfo`, `/Annots`, `/StructParents`, `/Tabs`** — empty or trivial page-level entries.
6. **`/ProcSet [/PDF]`** — deprecated since PDF 1.4.
Use the script:
```sh
python3 scripts/assets/optimize_figma_pdf.py resources/icons/menubar/*.pdf
```
It edits in place and prints the savings per file. After running, also pipe through `mutool clean -ggg -z` and `qpdf --object-streams=generate --recompress-flate --compression-level=9` for the final 1–2% squeeze.
Verify each file still renders by sips'ing it back to PNG and eyeballing:
```sh
for f in resources/icons/menubar/*.pdf; do
sips -s format png "$f" --out "/tmp/$(basename $f .pdf).png" -Z 300 >/dev/null 2>&1
done
```
Open the PNGs in Preview to confirm nothing visual changed.
## Step 3: SF Symbols via font subset
Every SF Symbol shipped in AltTab — switcher status icons, sidebar tab icons, button icons, permission/feedback icons — is rendered as a text glyph from a subsetted SF Pro Text font. There are no SF-Symbol PDFs in the bundle.
How it works: SF Symbols are glyphs in the Private Use Area of SF Pro Text. Apple's `SF-Pro-Text-Regular.otf` contains every symbol they've ever shipped. We subset it down to just the codepoints AltTab needs (currently ~36 glyphs, ~17 KB) into `resources/SF-Pro-Text-Regular.otf`, and register it via `Info.plist:ATSApplicationFontsPath = ""`. At runtime, `NSFont(name: "SF Pro Text", size:)` resolves to the bundled subset on macOS <11 (where the system font isn't installed) and to the system font on macOS 11+, with identical glyph appearance either way.
To add a new SF Symbol:
1. Open [SF Symbols.app](https://developer.apple.com/sf-symbols/), search for the symbol, press **Cmd-C** to copy the symbol character to the clipboard. (Apple's name→codepoint mapping is not exposed via public API, and the SF Pro Text font's cmap uses `uniXXXXXX.medium`-style names rather than semantic ones, so this manual lookup is the authoritative path.)
2. Paste the character into a new case on the `Symbols` enum in [src/switcher/main-window/TileFontIconView.swift](src/switcher/main-window/TileFontIconView.swift) — e.g., `case foo = "􀝥" // SF Symbol name`.
3. Paste the same character at the end of the `--text=` argument in [scripts/assets/subset_font.sh](scripts/assets/subset_font.sh).
4. Run `bash scripts/assets/subset_font.sh`. It reads `/Library/Fonts/SF-Pro-Text-Regular.otf` (installed by SF Symbols.app — a standard developer prerequisite) and writes the regenerated subset to `resources/SF-Pro-Text-Regular.otf`. Picks up Apple's latest glyph refinements automatically.
5. Use it in code: `NSImage.fromSymbol(.foo, pointSize: 14)` returns a template `NSImage`; or `TileFontIconView(symbol: .foo, ...)` for the cached-attributed-string path in the switcher hot loop.
The script runs `pyftsubset` via the project's pipenv environment. Warnings about `MERG`/`meta`/`trak` tables being dropped are normal — those tables aren't relevant to glyph rendering.
### Historical note: SF Symbols via PDF (deprecated, scripts removed)
A previous pipeline shipped each SF Symbol as a per-glyph PDF in `resources/icons/`. The pipeline lives only in git history now (`scripts/assets/export_sf_symbol_pdf.swift` was deleted alongside the migrated PDFs). The technique is worth knowing in case a future need arises (e.g., a multi-color symbol that fonts can't represent):
- The naive route — `NSImage(systemSymbolName:).draw(in:)` against a PDF `CGContext` — produces a **black rectangle**, because Quartz emits `image-mask + fill-rectangle` operators where the rectangle paints over the mask. AppKit bug at the PDF emission level; `paletteColors` config does not fix it.
- The working route was to extract the symbol's vector path directly via private selectors that have been stable across macOS 11–15:
`NSImage(systemSymbolName:).representations[0] (NSSymbolImageRep) → .perform("vectorGlyph") (CUINamedVectorGlyph) → .perform("CGPath") (real CGPath)`.
- The CGPath lives in CUI's internal coordinate space (~2× display points, Y-down) — scale to fit the canvas and flip Y. Walk the path via `CGPath.applyWithBlock` and emit raw PDF operators (`m`, `l`, `c`, `h`, `f`). Non-zero winding fill. Fill with DeviceGray (`0 g`), **not** `NSColor.black.cgColor`, which drags in a ~3.4 KB ICC color profile.
- Final PDF wrapper: 4 objects (Catalog, Pages, Page, Content), no `/Info`, no `/Metadata`, no `/Resources/ColorSpace`. ~750–1800 bytes per icon.
Git: see commit `990c1e79` ("feat: pro improve assets") for the PDF pipeline as-it-was; subsequent commit migrated the SF-Symbol PDFs back to font glyphs.
## Step 4: Raster → HEIC at q50
For anything raster (illustration thumbnails, screenshots inside an icon, anything photographic), HEIC at quality 50 is the baseline. q50 is roughly 50% smaller than JPEG at perceptually-equivalent quality, and at the small display sizes used in this app the artifacts are invisible.
Pipeline (built-in to macOS via `sips`):
```sh
sips -Z 1000 -s format heic -s formatOptions 50 input.png --out output.heic
```
- `-Z 1000` resizes the longest edge to 1000px **preserving aspect ratio**. AltTab's illustration display is 500pt wide, so 1000px is the correct @2x ship size. Anything larger wastes bytes; anything smaller looks soft on Retina.
- `formatOptions 50` is the quality. q50 was chosen after a side-by-side comparison at q20/q35/q50/q65/q80 — q50 was the lowest setting where text in screenshots stayed legible and gradient backgrounds didn't band.
Use the script for batch conversion:
```sh
bash scripts/assets/encode_heic.sh ~/Desktop 1000 50
```
That walks all PNG/JPEG files in the source directory, resizes to longest-edge 1000px at q50 HEIC, writes outputs to `/tmp/heic-out/`.
### Visual review (mandatory)
Before swapping the new HEICs into `resources/`, **always** decode a representative sample back to PNG and visually compare against the source:
```sh
sips -s format png /tmp/heic-out/sample.heic --out /tmp/sample-decoded.png >/dev/null 2>&1
open /tmp/sample-decoded.png /Users/you/Desktop/sample.png
```
Pick the visually most demanding file from the batch — usually one with the most text or the strongest gradients. Confirm:
- No banding in flat color regions
- Text edges still crisp at native display size
- No haloing around anti-aliased edges
- Color rendition matches
If anything looks degraded, bump quality to q60 or q65 and re-batch. The user, not the script, is the final arbiter — show them the sample with sizes before committing.
### Bumping quality
If q50 isn't acceptable, the next quality steps are q60 and q65 — beyond that, returns diminish quickly. q80 is the previous default in this repo and roughly 2× the bytes of q50 for no visible improvement on AltTab's content.
## Step 5: pbxproj registration
Whenever you change the file extension of a resource (.jpg → .heic, .png → .pdf, etc.), update [alt-tab-macos.xcodeproj/project.pbxproj](alt-tab-macos.xcodeproj/project.pbxproj). The places that need patching:
1. **PBXBuildFile section** — comment + the comment inside `fileRef = ... /* name.ext */`.
2. **PBXFileReference section** — comment, `lastKnownFileType` (e.g. `image.pdf`, `image.heic`, `image.png`), and `path = "name.ext"`.
3. **PBXGroup section** — the file's entry inside its parent group's `children`.
4. **PBXResourcesBuildPhase section** — the entry in the main app target's `files`.
For pure extension swaps (no new files), `sed -i '' 's|old\.ext|new.ext|g'` plus a `lastKnownFileType` substitution covers it. For new files, generate new 24-char uppercase-hex object IDs (`python3 -c "import secrets; print(secrets.token_hex(12).upper())"`) and insert in all four places.
If you removed an asset entirely (file deleted from disk), delete its 4 entries from pbxproj — otherwise the build fails with "missing file" or ships dangling references.
## Step 6: Verify
```sh
bash ai/build.sh # must show ** BUILD SUCCEEDED **
bash ai/run.sh # launch the app and visually inspect every asset
```
Walk through every UI surface that loads an asset:
- Menubar icon (default + the two alternates from Preferences → General → Menubar icon)
- Preferences sidebar — 4 tab icons (SF Symbol on macOS 11+, bundled PDF below)
- Permissions window — open by revoking a permission
- Preferences → Appearance — illustration thumbnails change per show/hide row
Compare `git diff --stat` before committing. Asset replacements should net negative on bundle size.
## Reporting
After the run, report:
- File-by-file before/after sizes for everything that changed.
- Total bundle delta in KB.
- Any files left untouched and why (e.g., `app.icns` — bundle-required format).
- The encoder settings used (especially HEIC quality if not q50, so the next person knows).
- Anything the visual review revealed (e.g., "had to bump to q60 for `thumbnails_dark` because gradient banding at q50").
+65
View File
@@ -0,0 +1,65 @@
---
name: audit-specs-tests
description: Audit the AltTab test suite for spec/test/code consistency. For every co-located triad in `src/` (`Foo.swift` + `FooSpecs.md` + `FooTests.swift`), it cross-checks that each XCTest method has a matching scenario line in the spec and vice-versa, flags drift between a scenario's description and the test's doc-comment, and reports orphan tests, orphan scenarios, and unpaired files. Use after adding or editing any `*Tests.swift` / `*Specs.md`, before committing a test change, or to get an overall health check of the suite.
---
# /audit-specs-tests
## Project context
AltTab co-locates tests and a living spec next to the source they cover. The convention (see the plan in `.claude/plans/` and `src/pro/license/` as a worked example) is a **triad** per concept:
```
src/<feature>/
├── Foo.swift # production / kernel (app target, or app+test for kernels)
├── FooSpecs.md # the living spec (not compiled)
└── FooTests.swift # XCTest (unit-tests target only)
```
The spec is **documentation tied 1:1 to the test methods**. Its `## Test scenarios` section lists every test, grouped, as:
```markdown
### A. <Group name>
- **testAFooDoesBar** — one-line description of what it pins.
```
This skill's job is to keep the three in sync: every `func test…` ⇔ exactly one `- **test…** —` spec line, descriptions roughly agree, and no triad is missing a leg.
## What counts as a triad
Pair by base name in the **same folder**: `<Base>Tests.swift` ⇔ `<Base>Specs.md`. A `<Base>.swift` (or a kernel like `SelectionResolver.swift`, `SearchTestable.swift`) in the folder is the code under test, but a spec may legitimately cover several classes (e.g. `LicenseManagerSpecs.md` documents `Clock`/`Keychain`/`LicenseAPI` too) — so a missing same-name `.swift` is a note, not an error.
## Workflow
1. **Enumerate.** Find all test and spec files:
```sh
find src -name '*Tests.swift' | sort
find src -name '*Specs.md' | sort
```
Also list any test files still under `unit-tests/` and flag them as **not yet migrated** (the target end-state is zero test files outside `src/`).
2. **For each `*Tests.swift`, extract the test methods and their doc-comments.** Test names:
```sh
grep -nE '^\s*func test[A-Za-z0-9_]+\(' src/<path>/FooTests.swift
```
For each, capture the immediately-preceding `///` or `//` comment lines (the test's intent) and the enclosing `// MARK: -` group. Note methods wrapped in `#if DEBUG`.
3. **For each `*Specs.md`, parse the scenario index.** In the `## Test scenarios` section, collect every `### <Group>` heading and every `- **testName** — description` bullet. Build the set of spec-listed test names and their descriptions.
4. **Cross-check each triad and classify findings:**
- **Orphan test** — `func testX` exists but no `- **testX** —` line in the spec. (Most common drift; spec is stale.)
- **Orphan scenario** — spec lists `testX` but no `func testX` in the suite. (Test deleted/renamed; spec stale.)
- **Group mismatch** — a test's `// MARK:` group and its spec `###` group disagree (readability drift, not fatal).
- **Description drift** — the spec bullet and the test's doc-comment describe materially different behavior. Judge semantically, don't string-match; only flag real divergence.
- **Unpaired file** — a `*Tests.swift` with no `*Specs.md` (or vice-versa).
5. **Lighter code check (kernels only).** For decision-kernel files (`*Testable.swift`, `*Resolver.swift`), list `public`/`static` entry-point functions and `enum … Decision` cases, and flag any with no scenario referencing them — a hint that a branch is undocumented/untested. Skip this for AppKit-coupled production files (intentionally not unit-tested here).
6. **Optionally repair.** If asked, regenerate a spec's `## Test scenarios` section from the live test methods + their doc-comments (preserving the existing `### Group` order where it matches `// MARK:` sections). Never invent behavior — only restate what the test asserts. Do not edit `*Tests.swift` from this skill.
## Reporting
- A per-triad status table: `folder/Base` · #tests · #scenarios · status (✅ in sync / ⚠️ drift / ❌ unpaired).
- A punch list grouped by finding type (orphan tests, orphan scenarios, description drift, unpaired, undocumented kernel branches), each with the file + line.
- The count of test files still outside `src/` (migration progress).
- If nothing is wrong, say so plainly. Then offer to fix the drift (regenerate stale spec scenario indexes) and list exactly which files would change.
+63
View File
@@ -0,0 +1,63 @@
---
name: coverage-explore
description: Measure AltTab test coverage and record it as documentation. Runs the Test scheme with coverage into a throwaway result bundle, parses the per-file/region report, refreshes the per-feature badge atop each `*Specs.md` and the root `src/coverage.md` table, then suggests the highest-value missing tests. These two markdown outputs are the ONLY stored coverage — no lcov/html/xcresult is kept, and routine test runs don't gather coverage. Use to refresh coverage docs, find untested kernel branches, or decide what to test next.
---
# /coverage-explore
## Project context
AltTab follows the **Humble Object** pattern: logic lives in dependency-free **decision kernels**
(`SelectionResolver.swift`, `SearchModeResolver.swift`, the `*Testable.swift` files) compiled into the
`unit-tests` target and tested in isolation; the AppKit layer (windows, views, event taps) is kept thin
and is deliberately *not* unit-tested. So coverage is meaningful **per kernel / per feature-source** —
those should trend to ~100%, every decision branch exercised — and an aggregate app-wide % is not a
goal.
**Coverage is documentation here, not a build artifact.** The only stored coverage is:
1. the per-feature badge (`> **Line coverage:** …`) atop each `*Specs.md`, and
2. the root **`src/coverage.md`** table.
There is intentionally **nothing else**: no lcov, no HTML, no committed `.xcresult`, and coverage is
**not** gathered on routine runs (`scripts/run_tests.sh`, CI, or Xcode) — only when this skill runs it.
(Coverage isn't usefully viewable in IntelliJ, so there's no IDE-integration artifact to maintain.)
## Workflow
1. **Measure into a throwaway bundle** (then delete it — store nothing technical):
```sh
rm -rf /tmp/altcov.xcresult
set -o pipefail && xcodebuild test \
-project alt-tab-macos.xcodeproj -scheme Test -configuration Release \
-enableCodeCoverage YES -resultBundlePath /tmp/altcov.xcresult | scripts/xcbeautify
```
If the build is red, stop and report — coverage on a failing suite is meaningless.
2. **Parse** `xcrun xccov view --report --json /tmp/altcov.xcresult`. Each `targets[].files[]` has
`path`, `lineCoverage`, `coveredLines`, `executableLines`, `functions[]`. For line-by-line counts of
one file while investigating a gap: `xcrun xccov view --file <abs-path> /tmp/altcov.xcresult`.
3. **Refresh `src/coverage.md`.** Rewrite the table with every `src/` file (excluding `*Tests.swift`)
that the test target compiles, sorted worst-coverage-first, as `| NN% (cov/exec) | \`path\` |`.
Keep the header note explaining the Humble-Object scope and that this + the badges are the only
stored coverage. Update the "updated" date.
4. **Offer to refresh the per-spec badges.** For each `<Base>Specs.md` whose `<Base>.swift` (or kernel)
is in the report, propose updating its `> **Line coverage:** …` line with the new % + today's date.
Ask first; only apply the ones the user accepts. Keep honest notes where a file is intentionally
partial (e.g. `PreferencesMigrations.swift`).
5. **Rank gaps & suggest tests.** For kernels below 100%, list the uncovered functions/regions, map each
to the behavior it represents (read the source), and write ready-to-paste additions: a
`- **testGroupScenario** — …` spec line + a short XCTest stub in that suite's builder style. Don't add
tests automatically unless asked.
6. **Clean up:** `rm -rf /tmp/altcov.xcresult`. Leave no technical coverage files in the tree.
## Reporting
- Headline: a small ascending table of kernel `lineCoverage`, and the delta vs the previous `src/coverage.md`.
- Ranked gap list: file → uncovered function/branch → the behavior it represents.
- Suggested scenarios (spec lines + test stubs) for the top gaps.
- State exactly what was rewritten (`src/coverage.md`, which badges). Flag files that are partial *by
design* (AppKit glue, excluded migrations) so a low number isn't mistaken for a problem.
@@ -0,0 +1,75 @@
---
name: translate-missing-l10n
description: Translate missing l10n strings for AltTab using Claude's multilingual ability. Refreshes the source `Localizable.strings` from current Swift code, finds keys missing in each `<lang>.lproj/Localizable.strings`, translates them, then writes them back via `scripts/l10n/apply_translations.ts`.
---
# /translate-missing-l10n
## Project context
AltTab is a macOS app that helps switch between windows, similar to the Windows alt-tab experience. The strings to translate are mostly Settings UI — some tooltips, dialogs, and general user guidance.
## Target languages (20)
`de, ja, fr, es, zh-CN, pt-BR, nl, ko, it, pl, ar, zh-HK, vi, tr, sv, th, zh-TW, he, id, ru`
(`en` is the source — handled automatically by the apply step.)
## Translation guidelines
- **Format specifiers must be preserved exactly**: `%@`, `%d`, `%1$@`, `%2$@`, `\n`, `\t`. The number and order of specifiers in the translation must match the source. Positional and unindexed forms are interchangeable (`%@ %@` ≡ `%1$@ %2$@`), but the count must match.
- **Do not translate proper nouns**: "AltTab", "macOS", "Mission Control", "Spaces", "Dock".
- **Do not translate modifier key names**: "Cmd", "Option", "Alt", "Shift", "Ctrl", "Control", "Fn", "Command".
- **Use Apple's official platform terminology** for the target locale where one exists. For example, prefer the term Apple uses in macOS System Settings for that locale ("Réglages" vs "Préférences" in French) over a literal translation.
- **Match the source brevity**. Settings strings are short; the translation should be short too. Prefer concise, idiomatic phrasing over literal grammatical completeness.
- **Match macOS tone**: neutral, direct, no exclamation marks unless the source has them.
- **Comments in the source file are engineer guidance, not user-visible text**. Use them to disambiguate meaning, but never include them in the translation.
## Workflow
1. **Refresh the source.** Run:
```sh
bash scripts/l10n/extract_l10n_strings.sh
```
This regenerates `resources/l10n/Localizable.strings` from the current Swift code via `genstrings`.
2. **Parse the source.** Read `resources/l10n/Localizable.strings`. Each entry has the shape:
```
/* engineer comment */
"key" = "value";
```
Build the ordered list of `(comment, key, value)` triples. The `value` for the source is usually identical to `key`, but may include positional indices (`%1$@`, `%2$@`) when there are multiple specifiers.
3. **Compute missing keys per language.** For each of the 20 target languages, read `resources/l10n/<lang>.lproj/Localizable.strings`. Each line is `"key" = "translation";`. A key is **missing** if it's present in the source but either (a) absent from the target file, or (b) present with an empty or whitespace-only value. Treat (b) the same as (a) — produce a real translation.
4. **Stop if nothing is missing.** Report and exit.
5. **Translate.** For each language, produce a translation for each missing key, applying the guidelines above. Do not invent keys; only translate keys that appear in the source. Group your work into batches of 5–10 languages per call to keep individual outputs manageable.
6. **Apply each batch.** Write the batch to a fresh file under `/tmp` (not committed) with this shape:
```json
{
"fr": { "About %@": "À propos de %@", "Quit": "Quitter" },
"ja": { "About %@": "%@について" }
}
```
Then run:
```sh
npx ts-node scripts/l10n/apply_translations.ts /tmp/batch-NN.json
```
The helper:
- Validates format specifiers — translations whose specifier set doesn't match the source value are rejected with a clear error and **not merged**.
- Always rewrites `en.lproj/Localizable.strings` from source **keys** (each entry written as `"key" = "key";` for symmetry) — no need to include `en` in your batch. This avoids leaking genstrings-rewritten values like `%1$@` into the English file when the original source key uses plain `%@`.
- Rewrites each `<lang>.lproj/Localizable.strings` using source order: existing translations are preserved, new translations merged in, and keys no longer in the source are pruned.
- Exits with code `2` if any entries were rejected.
7. **Handle rejections.** If `apply_translations.ts` reports format-specifier mismatches, fix those translations and re-run only the affected language(s) in a follow-up batch. Do not move on while rejections are outstanding.
## Reporting
After the run, report:
- Number of languages processed.
- Total translations produced and merged.
- Any entries you intentionally left untranslated (e.g., the source was already a proper noun) — list them so the user can decide.
- Any format-specifier rejections that required manual fixes.
+1
View File
@@ -0,0 +1 @@
v11.3.0
+9
View File
@@ -0,0 +1,9 @@
# alt-tab-free [depaywall]: upstream's FUNDING.yml routed the GitHub "Sponsor" button on the fork's
# repo to lwouis (github: lwouis / patreon: alt_tab_macos / ko_fi: alt_tab / a lwouis PayPal button) —
# i.e. every donation would have gone to the author the fork just de-paywalled (PLAN §3.5). It has
# been emptied so NO sponsor button renders and no donation routes to the upstream author.
#
# OWNER-OVERRIDABLE-BEFORE-PUBLISH: to accept sponsorships for THIS fork, uncomment and fill in your
# own handles (do NOT re-add lwouis's). Otherwise leave this file empty / delete it.
# github: <fork-owner-handle>
# custom: ["https://<fork-domain>/donate"]
+29
View File
@@ -0,0 +1,29 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is. What happened, and what you think should have happened.
**Screenshots / video**
Add screenshots to help explain your problem. You can also record your screen to show the bug in action. That is *really* helpful!
**Steps to reproduce the bug**
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Your environment**
* AltTab version:
* macOS version:
* Other relevant info: e.g. using external keyboard, multiple monitors, etc
@@ -0,0 +1,17 @@
---
name: Feature suggestion
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
---
**Is your feature suggestion related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
+10
View File
@@ -0,0 +1,10 @@
---
name: Other
about: Share something that's not a bug report, and not a feature suggestion
title: ''
labels: ''
assignees: ''
---
+4
View File
@@ -0,0 +1,4 @@
Thank you for opening a PR! Please make sure that:
* The title and description of the PR convey what the change is about, by mentioning the ticket it addresses for instance.
* The commits messages [follow the convention](https://www.conventionalcommits.org/en/v1.0.0-beta.4/#summary), so your PR can be merged.
+208
View File
@@ -0,0 +1,208 @@
# alt-tab-free: fork-owned CI/CD workflow (diverged from upstream lwouis/alt-tab-macos).
# Upstream's ci_cd.yml fires `on: push: branches: [master]` ONLY and is the sole workflow,
# so this fork ADDS a `pull_request:` trigger to gate the sync PR pre-merge (see PLAN §4.2),
# gates every release/push-only step under `if: github.event_name == 'push'`, and wires the
# anti-relock + conflict-marker greps as the FIRST push-job steps so a relocked or conflicted
# tree aborts BEFORE update_appcast.sh (Sparkle sign), semantic-release (tag push), and the
# gh-release. This file is in the §6.2 "keep ours" recurring-conflict set — on an upstream
# ci_cd.yml change, reconcile manually and re-confirm the `pull_request:` trigger survives.
on:
push:
branches:
- master
# alt-tab-free [depaywall]: PR trigger so the sync PR runs the guards pre-merge (PLAN §4.2).
# A separate fork-owned .github/workflows/guard.yml ALSO runs the guards on pull_request, so a
# careless upstream-conflict resolution that strips this trigger cannot silently disarm the gate.
pull_request:
branches:
- master
# alt-tab-free [depaywall]: GitHub defaults GITHUB_TOKEN to read-only since 2023; semantic-release
# (@semantic-release/git) pushes commits+tags to master and softprops/action-gh-release creates the
# release — both need contents:write, else they 403 and the appcast enclosure 404s for auto-update
# (PLAN §4.3).
permissions:
contents: write
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
APPCENTER_SECRET: ${{ secrets.APPCENTER_SECRET }}
APPCENTER_TOKEN: ${{ secrets.APPCENTER_TOKEN }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_P12_CERTIFICATE: ${{ secrets.APPLE_P12_CERTIFICATE }}
# alt-tab-free [depaywall]: optional .p12 export password (empty if exported password-less).
# Not part of the release-gate AND — the cert import tolerates an empty password.
APPLE_P12_PASSWORD: ${{ secrets.APPLE_P12_PASSWORD }}
SPARKLE_ED_PRIVATE_KEY: ${{ secrets.SPARKLE_ED_PRIVATE_KEY }}
GITHUB_EVENT_BEFORE: ${{ github.event.before }}
GITHUB_EVENT_AFTER: ${{ github.event.after }}
BUILD_DIR: ${{ github.workspace }}
XCODE_BUILD_PATH: DerivedData/Build/Products/Release
VERSION_FILE: VERSION.txt
# alt-tab-free [depaywall]: must equal PRODUCT_NAME in config/local.xcconfig
# (PLAN §3.1/§4.3) or the build/package/appcast scripts mismatch the artifact.
APP_NAME: CommandTabFree
jobs:
build:
runs-on: macos-15 # all options: https://github.com/actions/runner-images/tree/main
environment: production
steps:
# - env:
# GITHUB_CONTEXT: ${{ toJSON(github) }}
# run: echo "$GITHUB_CONTEXT"
- id: pre-checkout
env:
COMMITS: ${{ toJson(github.event.commits) }}
run: |
if [[ "${{ github.event_name }}" == "push" ]]; then
COUNT=$(( $(echo "$COMMITS" | jq length) + 30 ))
else
COUNT=1
fi
echo "fetch-depth=$COUNT" >> "$GITHUB_OUTPUT"
- uses: actions/checkout@v6
with:
fetch-depth: ${{ steps.pre-checkout.outputs.fetch-depth }}
# alt-tab-free [depaywall]: Guard B + Guard C run FIRST on the push job (before run_tests.sh,
# and therefore before update_appcast.sh's Sparkle sign + semantic-release's tag push) so a
# relock or a still-conflicted tree aborts the job BEFORE any irreversible side-effect (PLAN
# §4.4 "Where the guards run"). They are near-instant target-independent greps, so running them
# first is free. They also run on the PR path for the fastest red signal. A second copy sits
# just before action-gh-release as belt-and-suspenders.
- name: anti-relock — verify de-paywall marker present (Guard B)
run: |
grep -q 'depaywall' src/pro/license/LicenseManager.swift \
|| { echo "PAYWALL RELOCKED: depaywall marker missing from computeState()"; exit 1; }
# The marker proves the patch is present; pair with the if-false wrap the patch introduces.
# A bare `return .pro` grep is NOT load-bearing (it matches the unpatched line 187 too).
grep -Eq 'guard[[:space:]]+false[[:space:]]+else' src/pro/license/LicenseManager.swift \
|| { echo "PAYWALL RELOCKED: 'guard false else' (forced .pro) missing from computeState()"; exit 1; }
- name: anti-conflict — no unresolved merge markers (Guard C)
run: |
if git -c grep.lineNumber=false grep -nE '^(<<<<<<<|=======|>>>>>>>)' -- . ':(exclude)docs/'; then
echo "UNRESOLVED CONFLICT MARKERS present — resolve before merge/release"; exit 1
fi
# alt-tab-free [depaywall]: release-readiness gate (PLAN §3.3/§4.3 owner-secret checklist).
# The fork ships unsigned/ad-hoc until the OWNER provisions the Apple Developer ID cert and the
# Sparkle key. We do NOT hard-fail when those secrets are absent — that would make every push
# RED on a fork that is correctly built but not yet signing-provisioned. Instead we compute a
# boolean from secret presence and SKIP the sign/notarize/appcast/release tail cleanly when it
# is false. The build + Guard A (run_tests.sh) still run on push, so push CI is GREEN today and
# the release tail FLIPS ON automatically the moment the owner adds the secrets. Secrets are not
# available in step-level `if:` directly, so map them to env and emit an output here.
- name: release-gate — are signing/notarization secrets present?
id: release-gate
env:
HAS_P12: ${{ secrets.APPLE_P12_CERTIFICATE != '' }}
HAS_APPLE_ID: ${{ secrets.APPLE_ID != '' }}
HAS_APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD != '' }}
HAS_APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID != '' }}
HAS_SPARKLE_KEY: ${{ secrets.SPARKLE_ED_PRIVATE_KEY != '' }}
run: |
set -euo pipefail
if [ "$HAS_P12" = "true" ] && [ "$HAS_APPLE_ID" = "true" ] \
&& [ "$HAS_APPLE_PASSWORD" = "true" ] && [ "$HAS_APPLE_TEAM_ID" = "true" ] \
&& [ "$HAS_SPARKLE_KEY" = "true" ]; then
echo "signing-ready=true" >> "$GITHUB_OUTPUT"
echo "All signing/notarization/Sparkle secrets present — release tail WILL run on push."
else
echo "signing-ready=false" >> "$GITHUB_OUTPUT"
echo "::warning::Signing/notarization/Sparkle secrets absent — release tail (codesign/notarize/appcast/semantic-release/gh-release) is SKIPPED. Build + Guard A still run. Provision APPLE_P12_CERTIFICATE / APPLE_ID / APPLE_PASSWORD / APPLE_TEAM_ID / SPARKLE_ED_PRIVATE_KEY in the 'production' Environment to enable releases (PLAN §3.3/§3.4)."
fi
- uses: actions/setup-node@v6
with:
node-version: 16 # PLAN §4.3: keep node-16; the package.json engines mismatch only warns
cache: 'npm'
- run: sudo xcode-select -s /Applications/Xcode_26.0.1.app/Contents/Developer
- run: scripts/print_env.sh
- run: npm ci
# alt-tab-free [depaywall]: commitlint is gated to the push path. On push it lints the whole
# pushed range, which drags in upstream's non-conforming messages on a `chore(sync)` merge —
# this is handled by an `ignores` predicate in commitlint.config.js (PLAN §4.3) that drops the
# synthetic merge commit and upstream's own messages; do NOT break commitlint on --no-ff merges.
# $GITHUB_EVENT_BEFORE/AFTER are push-context (empty on pull_request), so a PR-safe variant runs
# below on the PR path instead.
- run: npx commitlint --from "$GITHUB_EVENT_BEFORE" --to "$GITHUB_EVENT_AFTER" --verbose
if: github.event_name == 'push'
# alt-tab-free [depaywall]: PR-safe commitlint — lints base..head (valid on pull_request),
# paired with the commitlint.config.js `ignores` predicate (PLAN §4.2/§4.3).
- run: npx commitlint --from "${{ github.event.pull_request.base.sha }}" --to "${{ github.sha }}" --verbose
if: github.event_name == 'pull_request'
# Runs on both push and PR: catches an un-regenerated l10n/generated-file diff (PLAN §4.2/§4.5).
- run: scripts/ensure_generated_files_are_up_to_date.sh
# alt-tab-free [depaywall]: release-path — a semantic-release dry-run against a PR head is
# meaningless and can mis-bump, so gate to push (PLAN §4.2).
- run: scripts/determine_next_version.sh
if: github.event_name == 'push'
- run: scripts/replace_environment_variables_in_app.sh
if: github.event_name == 'push'
# codesign needs APPLE_P12_CERTIFICATE — gated on signing-ready so a not-yet-provisioned fork
# does not RED on the missing-cert import (PLAN §3.3/§4.3).
- run: scripts/codesign/setup_ci_master.sh
if: github.event_name == 'push' && steps.release-gate.outputs.signing-ready == 'true'
# Guard A — the anti-relock unit test (appended to LicenseManagerTests.swift). Runs on both
# push and PR (no secrets needed); on the push path it sits before the sign/tag steps below
# so a relock fails BEFORE any irreversible side-effect (PLAN §4.4). This is what keeps push
# CI GREEN today on the signing-unprovisioned fork.
- run: scripts/run_tests.sh
# alt-tab-free [depaywall]: build the Release product to prove the tree compiles. The fork
# inherits upstream's Developer ID via config/release.xcconfig (CODE_SIGN_IDENTITY), which is
# absent on CI until the owner provisions the Apple cert — so when the release gate is NOT
# signing-ready we build AD-HOC (CODE_SIGN_IDENTITY=-, signing not required, no timestamp) to
# prove the tree compiles without a cert. When the owner adds the secrets AND sets the fork's
# Developer ID in config/local.xcconfig, this builds signed for the release tail (PLAN §3.3/§4.3).
- name: build app (signed — owner cert provisioned)
if: github.event_name == 'push' && steps.release-gate.outputs.signing-ready == 'true'
run: scripts/build_app.sh
- name: build app (ad-hoc — until signing-provisioned)
if: github.event_name == 'push' && steps.release-gate.outputs.signing-ready != 'true'
run: scripts/build_app.sh CODE_SIGN_IDENTITY=- CODE_SIGNING_REQUIRED=NO OTHER_CODE_SIGN_FLAGS=--timestamp=none
# --- Release tail: requires the owner's Apple Developer ID + Sparkle secrets. Skipped cleanly
# (NOT failed) when they are absent, so push CI stays GREEN until the owner provisions them. ---
- run: scripts/package_and_notarize_release.sh
if: github.event_name == 'push' && steps.release-gate.outputs.signing-ready == 'true'
# alt-tab-free [depaywall]: upload_symbols_to_appcenter.sh REMOVED — telemetry is off (PLAN §3.4).
- run: scripts/update_appcast.sh
if: github.event_name == 'push' && steps.release-gate.outputs.signing-ready == 'true'
# alt-tab-free [depaywall]: update_readme_and_website.sh REMOVED — it queried the UPSTREAM
# lwouis/alt-tab-macos GitHub API for stars/downloads and rewrote docs/contributors.md from the
# UPSTREAM contributor graph (semantic mismatch for the fork) and dispatched the lwouis website.
# Cosmetic only; dropped per PLAN §4.0/§4.3 (alongside update_website.sh, already removed).
- run: npx semantic-release
if: github.event_name == 'push' && steps.release-gate.outputs.signing-ready == 'true'
- id: set_release_info
run: scripts/extract_latest_changelog.sh
if: github.event_name == 'push' && steps.release-gate.outputs.signing-ready == 'true'
# alt-tab-free [depaywall]: belt-and-suspenders copy of Guard B + Guard C immediately before the
# release is created. The load-bearing copy is at the top of the job (pre-tag-push); this second
# copy guards the gh-release object itself (PLAN §4.4).
- name: anti-relock + anti-conflict re-check (belt-and-suspenders)
if: github.event_name == 'push' && steps.release-gate.outputs.signing-ready == 'true'
run: |
grep -q 'depaywall' src/pro/license/LicenseManager.swift \
|| { echo "PAYWALL RELOCKED: depaywall marker missing from computeState()"; exit 1; }
grep -Eq 'guard[[:space:]]+false[[:space:]]+else' src/pro/license/LicenseManager.swift \
|| { echo "PAYWALL RELOCKED: 'guard false else' (forced .pro) missing from computeState()"; exit 1; }
if git -c grep.lineNumber=false grep -nE '^(<<<<<<<|=======|>>>>>>>)' -- . ':(exclude)docs/'; then
echo "UNRESOLVED CONFLICT MARKERS present — resolve before release"; exit 1
fi
# alt-tab-free [depaywall]: point the release at THIS fork's repo via the ambient GITHUB_TOKEN
# (release.config.js has no @semantic-release/github plugin, so softprops is the sole release
# creator — PLAN §4.3). repository defaults to ${{ github.repository }} = the fork.
- uses: softprops/action-gh-release@v3
if: github.event_name == 'push' && steps.release-gate.outputs.signing-ready == 'true'
with:
repository: ${{ github.repository }}
token: ${{ secrets.GITHUB_TOKEN }}
tag_name: ${{ steps.set_release_info.outputs.tag_name }}
body: ${{ steps.set_release_info.outputs.body }}
files: ${{ env.XCODE_BUILD_PATH }}/*.zip
# alt-tab-free [depaywall]: the release tail intentionally does NOT advance .fork-sync-state.
# That file is the UPSTREAM-sync cursor — the last-synced UPSTREAM tag (e.g. v11.3.0), read by
# upstream_sync.yml to pick "the oldest upstream tag strictly newer than it." The fork versions
# independently (semantic-release cuts v100.x), so a prior revision's step that wrote the FORK
# release tag here set the cursor to v100.x — after which no upstream tag is ever "newer" and
# upstream-sync would silently never fire. The cursor must instead be advanced by the
# upstream-sync merge flow, recording the UPSTREAM tag it synced (to be wired with
# upstream_sync.yml — PLAN §4.2). Until then .fork-sync-state stays at the last real upstream tag.
# alt-tab-free [depaywall]: update_website.sh (lwouis website dispatch) REMOVED (PLAN §3.4/§4.2).
+94
View File
@@ -0,0 +1,94 @@
# alt-tab-free — anti-relock guard workflow (docs/PLAN-maintained-fork.md §4.4)
#
# A SEPARATE, fork-owned workflow that runs the anti-relock guards on every PR,
# INDEPENDENTLY of ci_cd.yml. Rationale (§4.4): ci_cd.yml is the file most likely to take an
# upstream conflict, and a careless "keep ours/theirs" resolution could silently strip its
# pull_request: trigger or its release-step gating — at which point the in-ci_cd.yml guards
# would stop gating PRs with NO error. A guard workflow that does NOT inherit ci_cd.yml's
# trigger survives that. This is the reviewer's primary green/red signal on a sync PR.
#
# Three guards, each fails the job LOUDLY:
# A — the Test scheme (the mock-injected anti-relock unit tests in LicenseManagerTests.swift)
# B — a target-independent grep that the de-paywall flip is still present in computeState()
# C — a tree-wide grep that no unresolved git conflict markers survive into a merge/release
#
# Defense-in-depth note: Guards B + C are ALSO wired into ci_cd.yml as the FIRST push-job
# steps (CI agent owns that) so a relock/conflict-laden tree aborts the release BEFORE the tag
# is pushed or the binary signed, even if this PR gate is ever missing/misconfigured (§4.4).
name: guard
on:
pull_request:
branches: [master]
permissions:
contents: read
jobs:
# Guards B + C are near-instant greps; run them on cheap ubuntu so a relock or a still-
# conflicted tree fails FAST, before the expensive macOS Guard-A job even starts (§4.5).
grep-guards:
name: anti-relock greps (B + C)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
# GUARD B — verify the de-paywall flip is still present at the single state producer.
# §4.4 pitfall: a bare `return .pro` grep MATCHES THE UNPATCHED FILE (computeState() already
# contains `return .pro` in the keychain-valid branch on a fully relocked tree), so it is NOT
# load-bearing. The load-bearing signals are (1) the `depaywall` marker comment, which exists
# ONLY because the fork added it, AND (2) the `if false { … }` wrap that the patch introduces
# around the original (now dead) body. Both are absent on an unpatched/relocked upstream file.
- name: Guard B — de-paywall marker + if-false wrap present in computeState()
run: |
set -euo pipefail
F=src/pro/license/LicenseManager.swift
if [ ! -f "$F" ]; then
echo "::error::Guard B: $F not found — chokepoint moved? Refresh the de-paywall patch (§6.2)."
exit 1
fi
grep -q 'depaywall' "$F" || {
echo "::error::PAYWALL RELOCKED: 'depaywall' marker missing from $F — the de-paywall flip was lost in a merge. Refresh the patch (§6.2)."
exit 1
}
grep -Eq 'guard[[:space:]]+false[[:space:]]+else' "$F" || {
echo "::error::PAYWALL RELOCKED: 'if false { … }' wrap missing from $F — the de-paywall body-suppress was lost. Refresh the patch (§6.2)."
exit 1
}
echo "Guard B OK: de-paywall marker + if-false wrap present in $F."
# GUARD C — no unresolved git conflict markers anywhere in the tree. The §4.2 sync cron
# deliberately commits a conflicted tree (markers + --no-verify) for a human to resolve;
# nothing else guarantees the human removed EVERY marker before merge. A markers-laden
# commit merged to master becomes a permanent ancestor of the published tag (un-compilable
# source), contradicting §5(1). Exclude docs/ so this plan's own literal marker examples
# don't trip the grep.
- name: Guard C — no unresolved merge conflict markers
run: |
set -euo pipefail
if git -c grep.lineNumber=false grep -nE '^(<<<<<<<|=======|>>>>>>>)' -- . ':(exclude)docs/'; then
echo "::error::UNRESOLVED CONFLICT MARKERS present — resolve before merge/release (§4.4 Guard C)."
exit 1
fi
echo "Guard C OK: no unresolved conflict markers."
# GUARD A — the behavioral anti-relock unit tests (mock-injected LicenseManager) via the Test
# scheme. §4.4: this MUST run on macos-15 with the pinned Xcode — run_tests.sh is `xcodebuild
# test`, which cannot run on ubuntu. If left on ubuntu, Guard A silently degrades to greps-only
# and the behavioral relock test never executes (the exact silent-disarming class this plan
# guards against). Bootstrap assertion (§4.4): on the deliberately-relocked acceptance PR,
# confirm THIS job produced a real test result that is RED on the relock — not just the greps.
unit-tests:
name: anti-relock unit tests (A)
runs-on: macos-15 # MUST match ci_cd.yml — `xcodebuild test` needs the pinned Xcode
steps:
- uses: actions/checkout@v6
# Pin the same Xcode as ci_cd.yml (§4.5 bootstrap invariant — re-pin on every upstream bump).
- run: sudo xcode-select -s /Applications/Xcode_26.0.1.app/Contents/Developer
# run_tests.sh runs the `Test` scheme (-configuration Release), which includes the
# appended anti-relock tests in src/pro/license/LicenseManagerTests.swift:
# testDepaywallProNeverLocked — load-bearing `state == .pro` assert
# testDepaywallStillProAfterTrialExpiry — discriminating (expired-trial) assert
# A relock makes computeState() fall back to computeTrialState() and these go RED.
- name: Guard A — run the Test scheme (anti-relock unit tests)
run: scripts/run_tests.sh
+226
View File
@@ -0,0 +1,226 @@
# alt-tab-free — upstream sync workflow (docs/PLAN-maintained-fork.md §4.2)
#
# Polls lwouis/alt-tab-macos for new release tags and opens a reviewable sync PR.
# Selects the OLDEST upstream tag strictly newer than the last-merged tag recorded in
# `.fork-sync-state` (NOT "newest tag minus --is-ancestor"). This is the §4.2
# never-drop-commits invariant: `.fork-sync-state` advances ONLY when a sync PR merges to
# master (a ci_cd.yml push-job step — owned by the CI agent), so a sync PR that is
# closed-without-merge or abandoned can never silently skip its tag — that tag stays "next"
# until it is actually merged. This subsumes the old `merge-base --is-ancestor` guard.
#
# A release is cut only when a human merges the PR to master (ci_cd.yml on: push). This
# workflow never releases; it only opens the PR for review.
name: upstream-sync
on:
# §4.2 cron-durability note: the in-repo `schedule:` SILENTLY auto-disables after 60 days
# of repo inactivity (no error, no notification). It is kept here as belt-and-suspenders.
# The RECOMMENDED PRIMARY trigger is an EXTERNAL scheduler hitting `repository_dispatch`
# carrying the SYNC_BOT_TOKEN (immune to the 60-day rule, and composes with the
# workflow-re-trigger token). See ownerActions / §4.2.
schedule:
- cron: '0 7 * * *' # daily; cheap, idempotent
workflow_dispatch: {}
repository_dispatch:
types: [upstream-sync] # external-scheduler entry point (§4.2 primary durability path)
# GITHUB_TOKEN is read-only by default; opening a PR + pushing a branch need these.
permissions:
contents: write
pull-requests: write
jobs:
sync:
runs-on: ubuntu-latest # pure git, no Xcode
env:
# CRITICAL (§4.2 BLOCKING) — do NOT use ${{ github.token }} here. By GitHub's documented
# recursion-prevention rule, a branch push / PR authored with the default GITHUB_TOKEN
# does NOT trigger other workflows — so guard.yml and ci_cd.yml's pull_request: checks
# would NEVER fire on the sync PR and the entire pre-merge gate would silently never run.
# SYNC_BOT_TOKEN MUST be a fork-owned credential that re-triggers workflows: a GitHub App
# installation token (preferred — least-privilege, short-lived) or a fork-owned PAT.
GH_TOKEN: ${{ secrets.SYNC_BOT_TOKEN }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
# Persist the fork-owned credential (NOT the default GITHUB_TOKEN) as the push
# credential, so the branch push below re-triggers guard.yml / ci_cd.yml PR checks.
token: ${{ secrets.SYNC_BOT_TOKEN }}
- name: Fail closed if SYNC_BOT_TOKEN is missing
run: |
# §4.2: without the workflow-re-triggering token the pre-merge gate is silently
# disarmed. Fail loudly here rather than open a check-less PR.
if [ -z "${SYNC_BOT_TOKEN:-}" ]; then
echo "::error::SYNC_BOT_TOKEN is not set. Refusing to open a check-less sync PR (§4.2)."
echo "Provision a GitHub App installation token (preferred) or fork-owned PAT as SYNC_BOT_TOKEN."
exit 1
fi
env:
SYNC_BOT_TOKEN: ${{ secrets.SYNC_BOT_TOKEN }}
- name: Add upstream + fetch tags
run: |
set -euo pipefail
git remote add upstream https://github.com/lwouis/alt-tab-macos.git || true
git fetch upstream --tags --force
- name: Verify sync labels exist (§4.2 — fail closed, never treat empty as "no open sync")
run: |
set -euo pipefail
# Guard 2 below and the §0.1 trip-wire query `sync` / `conflict` / `chokepoint-refresh`.
# `gh pr list --label <missing>` returns an EMPTY LIST, not an error, for a label that
# was never created — so on a fresh repo Guard 2 would silently no-op. Fail closed if a
# required label is absent; the bootstrap (§6.1) creates them with `gh label create`.
missing=0
for L in sync conflict chokepoint-refresh; do
if ! gh label list --json name --jq '.[].name' | grep -qxF "$L"; then
echo "::error::Required label '$L' is missing. Create it at bootstrap (§6.1): gh label create $L"
missing=1
fi
done
[ "$missing" -eq 0 ] || exit 1
- name: Select oldest upstream tag strictly newer than .fork-sync-state
id: tag
run: |
set -euo pipefail
# State-file-driven selection (§4.2): NOT "newest tag minus --is-ancestor".
last_synced="$(tr -d '[:space:]' < .fork-sync-state)"
if [ -z "$last_synced" ]; then
echo "::error::.fork-sync-state is empty; seed it with the last-merged upstream tag (e.g. v11.3.0)."
exit 1
fi
echo "Last synced (from .fork-sync-state): $last_synced"
# UPSTREAM-ONLY enumeration: `git tag -l 'v*'` would also match the FORK's OWN
# semantic-release tags (the fork cuts vX.Y.Z every sync — §4.3), so list tags from
# the upstream remote explicitly. Sort by version; keep only tags strictly newer than
# the recorded one; take the OLDEST of those (resolve-in-order — §4.2).
all_newer="$(git ls-remote --tags --refs upstream 'v*' \
| awk -F/ '{print $NF}' \
| sort -V \
| awk -v last="$last_synced" '
$0 == last { seen = 1; next }
seen { print }
')"
# Fallback for the case where last_synced is not itself present upstream: take every
# tag that sorts strictly after it.
if [ -z "$all_newer" ]; then
all_newer="$(git ls-remote --tags --refs upstream 'v*' \
| awk -F/ '{print $NF}' \
| sort -V \
| awk -v last="$last_synced" '{ if ($0 != last) print $0 }' \
| while read -r t; do
# keep only tags that sort AFTER last_synced
if [ "$(printf '%s\n%s\n' "$last" "$t" | sort -V | tail -1)" = "$t" ] && [ "$t" != "$last" ]; then
echo "$t"
fi
done)"
fi
next="$(printf '%s\n' "$all_newer" | sed '/^$/d' | head -1)"
if [ -z "$next" ]; then
echo "Up to date: no upstream tag newer than $last_synced."
echo "skip=true" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "Next tag to sync (oldest strictly newer): $next"
# Guard — a prior sync is still OPEN (resolve-in-order, §4.2): do NOT open a new PR
# while any sync/* PR is unmerged. A backlog pauses syncing until the human merges it;
# this is the never-drop-commits behavior. The liveness alert keys off the stalled flag.
# `gh pr list --label sync` fails closed because the label existence was verified above.
open_sync="$(gh pr list --state open --label sync --json number,headRefName,createdAt \
--jq 'sort_by(.createdAt) | .[0] // empty')"
if [ -n "$open_sync" ]; then
echo "A prior sync PR is still open (resolve-in-order): $open_sync"
echo "skip=true" >> "$GITHUB_OUTPUT"
echo "stalled=true" >> "$GITHUB_OUTPUT" # liveness alert keys off this (§4.2)
exit 0
fi
echo "latest=$next" >> "$GITHUB_OUTPUT"
- name: Merge onto a sync branch (real merge commit, conventional message)
if: steps.tag.outputs.skip != 'true'
id: merge
run: |
set -euo pipefail
TAG='${{ steps.tag.outputs.latest }}'
git config user.name "fork-sync-bot"
git config user.email "fork-sync-bot@users.noreply.github.com"
git switch -c "sync/${TAG}"
# NO --no-commit: let git author a REAL merge commit with a CONVENTIONAL message so
# commitlint / @semantic-release/commit-analyzer stay happy (§4.3). On conflict, commit
# the conflicted tree (markers included, --no-verify) so the PR shows the markers for a
# human to resolve; Guard C (guard.yml + ci_cd.yml) then blocks it from ever shipping.
if git merge --no-ff -m "chore(sync): merge upstream ${TAG}" "${TAG}"; then
conflicts=false
else
git add -A
git commit --no-verify \
-m "chore(sync): merge upstream ${TAG} (CONFLICTS — resolve before merge)"
conflicts=true
fi
echo "conflicts=${conflicts}" >> "$GITHUB_OUTPUT"
# §0.1 trip-wire A — surface chokepoint churn as a per-sync signal. A nonzero count
# means an upstream change touched a de-paywall chokepoint file in this merge range
# (last-synced tag .. new tag); the PR is labeled `chokepoint-refresh` (below) so the
# trip-wire is a single query, not a memory exercise.
CHOKEPOINTS="src/pro/license/LicenseManager.swift src/pro/ProFeature.swift src/preferences/PreferenceDefinition.swift src/pro/scheduling/ProTransitionManager.swift src/pro/license/LicenseCookie.swift src/vendors/AppCenterCrashes.swift"
LAST_SYNCED="$(tr -d '[:space:]' < .fork-sync-state)"
churn="$(git rev-list --count "${LAST_SYNCED}..${TAG}" -- $CHOKEPOINTS 2>/dev/null || echo 0)"
# Also flag if the merge left a conflict in any chokepoint file (the conflicted commit
# is HEAD; compare against its first parent HEAD~1 = the pre-merge master tip).
chokepoint_conflict=0
if git diff --name-only HEAD~1 HEAD 2>/dev/null | grep -qE 'LicenseManager\.swift|ProFeature\.swift|PreferenceDefinition\.swift|ProTransitionManager\.swift|LicenseCookie\.swift|AppCenterCrashes\.swift'; then
if [ "${conflicts:-false}" = "true" ]; then
chokepoint_conflict=1
fi
fi
echo "churn=${churn}" >> "$GITHUB_OUTPUT"
echo "chokepoint_conflict=${chokepoint_conflict}" >> "$GITHUB_OUTPUT"
git push origin "HEAD:sync/${TAG}"
- name: Open PR
if: steps.tag.outputs.skip != 'true'
run: |
set -euo pipefail
TAG='${{ steps.tag.outputs.latest }}'
CHURN='${{ steps.merge.outputs.churn }}'
CONFLICTS='${{ steps.merge.outputs.conflicts }}'
CHOKEPOINT_CONFLICT='${{ steps.merge.outputs.chokepoint_conflict }}'
# Label fail-closed (§4.2): conflict -> `sync,conflict`, else `sync`.
if [ "$CONFLICTS" = "true" ]; then
LABELS="sync,conflict"
else
LABELS="sync"
fi
BODY="Automated upstream sync to \`${TAG}\`.
Selected as the OLDEST upstream tag strictly newer than \`.fork-sync-state\` (§4.2).
Verify the guard.yml + ci_cd.yml PR checks are GREEN (anti-relock test + marker/conflict greps) before merge.
If checks did not appear, SYNC_BOT_TOKEN is mis-set to the default GITHUB_TOKEN — the gate is disarmed (§4.2).
Chokepoint-churn count for this merge range: ${CHURN} (nonzero => de-paywall chokepoint touched, see §0.1 trip-wire A).
NEVER close this PR to defer it — \`.fork-sync-state\` only advances on MERGE, so leaving it OPEN keeps this tag 'next'; closing it would silently skip the tag (§4.2 / §6.2)."
gh pr create \
--head "sync/${TAG}" \
--base master \
--title "sync: merge upstream ${TAG}" \
--body "$BODY" \
--label "$LABELS"
# §0.1 trip-wire A — auto-apply `chokepoint-refresh` from CI when a chokepoint file
# changed or conflicted, so the trip-wire tally never depends on a human remembering.
if [ "${CHURN:-0}" -gt 0 ] || [ "${CHOKEPOINT_CONFLICT:-0}" = "1" ]; then
gh pr edit "sync/${TAG}" --add-label chokepoint-refresh || true
fi
+25
View File
@@ -0,0 +1,25 @@
/.idea/
xcuserdata/
/.vscode/
/buildServer.json
WorkspaceSettings.xcsettings
IDEWorkspaceChecks.plist
/node_modules/
/DerivedData/
/build/
/vendor/*/.build/
/vendor/*/build/
/vendor/*/.swiftpm/
/vendor/*/Package.resolved
.DS_Store
codesign.conf
codesign.crt
codesign.key
codesign.p12
/.claude/*
!/.claude/skills/
/scripts/l10n/missing-translations.json
/ai/output/
# alt-tab-free [depaywall]: the Sparkle feed is published OUT OF TREE to the gh-pages branch by
# scripts/update_appcast.sh; the in-tree appcast.xml is removed (PLAN §3.3).
/appcast.xml
+6
View File
@@ -0,0 +1,6 @@
project: alt-tab-macos.xcodeproj
schemes:
- Release
index_exclude:
- vendor/**
- src/api-wrappers/private-apis/**
+10
View File
@@ -0,0 +1,10 @@
# rules: https://github.com/nicklockwood/SwiftFormat/blob/main/Rules.md
--swiftversion 5.8
--maxwidth 110
--nowrapoperators .,==,!=,<,>,>=,<=
--wrapternary before-operators
--disable andOperator
--disable wrapConditionalBodies
--disable wrapLoopBodies
--disable wrapMultilineStatementBraces
+10
View File
@@ -0,0 +1,10 @@
# **/*.swift: Matches all .swift files in the current directory and all its subdirectories.
# src/**/*.swift: Matches all .swift files in the src directory and all its subdirectories.
# !node_modules/**: Excludes all files in the node_modules directory and all its subdirectories.
Generated/**
**/PrivateApis.swift
# We will open a new branch to deal with code format issues at the next release.
**/*
+14
View File
@@ -0,0 +1,14 @@
# macOS development
- Don't use xcode directly to develop
- Use pure swift 5.8 code to make the app. No interface builder. No SwiftUI.
- Aim for compact code. Within methods, don't have groups of statements separated with newlines. No inline comments for simple code. Instead, split statements into sub-methods.
- Use guard closes as much as possible to separate the happy-path under them
- Organize source files into folders. Folders should group files that change together, at the same pace (e.g. one feature)
- Favor low latency and responsiveness. Reuse objects, avoid wasting memory or I/O.
# Workflow
- Copy commands from ai/build.sh and run them, to confirm compilation works after you're done with implementing a change
# License / Keychain invariant
- The app's Developer ID, TeamID, and bundle ID must remain stable across builds. Keychain items are tied to the code signature; changing any of these orphans every user's stored license key and forces mass re-activation. If a rotation is unavoidable, plan a migration first (e.g., a backup-restore handler, or `kSecAttrAccessGroup` with a stable group identifier).
- Do not introduce legacy `SecKeychain*` API or `kSecAccessControl` (biometric/PIN gating) into license code — both can trigger Keychain password prompts, which is bad UX for license activation.
+1
View File
@@ -0,0 +1 @@
@include ./AGENTS.md
+84
View File
@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- ===== Bundle identity (required by macOS / App Store) ===== -->
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleIconFile</key>
<string>app.icns</string>
<key>NSHumanReadableCopyright</key>
<string>GPL-3.0 licence</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<!-- ===== Versioning (substituted from xcconfig; CI overrides via config/local.xcconfig) ===== -->
<key>CFBundleShortVersionString</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<!-- ===== Launch behavior (read by LaunchServices before app starts) ===== -->
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>LSUIElement</key>
<string>true</string>
<key>NSPrincipalClass</key>
<string>AppCenterApplication</string>
<key>NSSupportsAutomaticTermination</key>
<string>false</string>
<key>NSSupportsSuddenTermination</key>
<string>false</string>
<key>ATSApplicationFontsPath</key>
<string></string>
<!-- ===== URL scheme registration (LaunchServices dispatches $(PRODUCT_BUNDLE_IDENTIFIER):// to us) ===== -->
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>CFBundleURLName</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleURLSchemes</key>
<array>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
</array>
</dict>
</array>
<!-- ===== Sparkle (auto-update framework — reads these directly from the bundle) ===== -->
<key>SUPublicEDKey</key>
<!-- Fork EdDSA public key for Sparkle update verification. The matching private key
is held as CI secret SPARKLE_ED_PRIVATE_KEY (see docs/EXECUTION-STATUS.md §3.3).
Auto-checks stay off (below) until DOMAIN serves a real appcast host. -->
<string>1YfoCJDk/T8GQx1Gpf3O4ApFgDkBiN6oe/z/Kfnxs/M=</string>
<key>SUEnableAutomaticChecks</key>
<!-- alt-tab-free: enabled 2026-06-16 — DOMAIN serves the appcast on GitHub Pages (gh-pages). -->
<string>true</string>
<key>SUScheduledCheckInterval</key>
<string>604800</string>
<!-- ===== AppCenter (crash reporter — read by AppCenterApplication superclass at init) ===== -->
<key>AppCenterApplicationForwarderEnabled</key>
<string>0</string>
<!-- ===== Build-time secrets (substituted from xcconfig; override per-dev via config/local.xcconfig) ===== -->
<key>AppCenterSecret</key>
<string>$(APPCENTER_SECRET)</string>
<key>Domain</key>
<string>$(DOMAIN)</string>
<key>ApiDomain</key>
<string>$(API_DOMAIN)</string>
</dict>
</plist>
+674
View File
@@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
+34
View File
@@ -0,0 +1,34 @@
# NOTICE — Statement of Changes (GPL-3.0 §5(a))
This file carries the prominent notice, required by GNU GPL v3.0 §5(a), that this work
has been modified, and gives the relevant date. It is a **living document**: whenever a
sync from upstream changes this fork's modification surface, update the change list and
the date below (see `docs/PLAN-maintained-fork.md` §6.2).
**Forked from:** [lwouis/alt-tab-macos](https://github.com/lwouis/alt-tab-macos) v11.3.0,
© Louis Pontoise, licensed GPL-3.0.
**Modified by:** the CommandTabFree fork. This fork neutralizes the AltTab Pro paywall so that
all features are free.
**Date of modification:** 2026-06-10.
**License:** CommandTabFree is released under the **GNU General Public License v3.0**, the same
license as upstream. The full license text is in [`LICENCE.md`](LICENCE.md), which is kept
byte-for-byte identical to upstream and is never edited.
## Changes made in this fork
- **`LicenseManager.computeState`** (`src/pro/license/LicenseManager.swift`) — forced to
return `.pro`, opening every Pro feature gate. This is the single live license-state
producer, so this one change unlocks all paywalled features.
- **`LicenseCookie.syncLicenseCookie`** (`src/pro/license/LicenseCookie.swift`) — made a
no-op, so no license cookie is written to the upstream domain.
- **`AppCenterCrash.init`** (`src/vendors/AppCenterCrashes.swift`) — telemetry disabled;
AppCenter is never started.
- **`App.handleCustomUrl`** (`src/App.swift`) — the `activate` deep-link handler is
disabled, so a crafted `…://activate?license_key=…` URL can no longer POST the machine
hardware fingerprint to a license backend.
The upstream copyright, contributor credits (`docs/contributors.md`), and third-party
acknowledgments (`docs/acknowledgments.md`) are retained unchanged.
+17
View File
@@ -0,0 +1,17 @@
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
[packages]
fonttools = "==4.8.1"
googletrans = "==3.0.0"
[requires]
python_version = "3.6"
[scripts]
font2png = "scripts/convert_font_to_png.sh"
translate = "python scripts/l10n/google_translate_all_terms_locally.py resources/l10n --retry_translate"
Generated
+127
View File
@@ -0,0 +1,127 @@
{
"_meta": {
"hash": {
"sha256": "3646221352b85667ac21f1b528dc8b29f56ff1e24cb97e7eaba79b5040c78e21"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.6"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"certifi": {
"hashes": [
"sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407",
"sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5"
],
"markers": "python_version >= '3.7'",
"version": "==2025.8.3"
},
"chardet": {
"hashes": [
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
],
"version": "==3.0.4"
},
"fonttools": {
"hashes": [
"sha256:596c0e8399c650dbf1048b7ca6fc7b12bd79a7db0981f3b87743de8c2b7512de",
"sha256:6d241d319ea9eae4c4ee27cbd1db8656dbd496dd9aa884401debfab3a4c7d82b"
],
"index": "pypi",
"markers": "python_version >= '3.6'",
"version": "==4.8.1"
},
"googletrans": {
"hashes": [
"sha256:44caeea42d91ff6ead5c2d49db2b88de66c45c2fe874c8ec03eb9b4ceb3a533d"
],
"index": "pypi",
"version": "==3.0.0"
},
"h11": {
"hashes": [
"sha256:33d4bca7be0fa039f4e84d50ab00531047e53d6ee8ffbc83501ea602c169cae1",
"sha256:4bc6d6a1238b7615b266ada57e0618568066f57dd6fa967d1290ec9309b2f2f1"
],
"version": "==0.9.0"
},
"h2": {
"hashes": [
"sha256:61e0f6601fa709f35cdb730863b4e5ec7ad449792add80d1410d4174ed139af5",
"sha256:875f41ebd6f2c44781259005b157faed1a5031df3ae5aa7bcb4628a6c0782f14"
],
"version": "==3.2.0"
},
"hpack": {
"hashes": [
"sha256:0edd79eda27a53ba5be2dfabf3b15780928a0dff6eb0c60a3d6767720e970c89",
"sha256:8eec9c1f4bfae3408a3f30500261f7e6a65912dc138526ea054f9ad98892e9d2"
],
"version": "==3.0.0"
},
"hstspreload": {
"hashes": [
"sha256:02bd5b0885b62f0d5239ca6c6876ffcad8d9c08dc97cee54292598141a16e9dc",
"sha256:346552a807b3a1762376de8ecce097544e7fcd64fb64231b4652da52f86fa6f1"
],
"markers": "python_version >= '3.6'",
"version": "==2025.1.1"
},
"httpcore": {
"hashes": [
"sha256:9850fe97a166a794d7e920590d5ec49a05488884c9fc8b5dba8561effab0c2a0",
"sha256:ecc5949310d9dae4de64648a4ce529f86df1f232ce23dcfefe737c24d21dfbe9"
],
"markers": "python_version >= '3.6'",
"version": "==0.9.1"
},
"httpx": {
"hashes": [
"sha256:32d930858eab677bc29a742aaa4f096de259f1c78c68a90ad11f5c3c04f08335",
"sha256:3642bd13e90b80ba8a243a730275eb10a4c26ec96f5fc16b87e458d4ab21efae"
],
"markers": "python_version >= '3.6'",
"version": "==0.13.3"
},
"hyperframe": {
"hashes": [
"sha256:5187962cb16dcc078f23cb5a4b110098d546c3f41ff2d4038a9896893bbd0b40",
"sha256:a9f5c17f2cc3c719b917c4f33ed1c61bd1f8dfac4b1bd23b7c80b3400971b41f"
],
"version": "==5.2.0"
},
"idna": {
"hashes": [
"sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6",
"sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==2.10"
},
"rfc3986": {
"hashes": [
"sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835",
"sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"
],
"version": "==1.5.0"
},
"sniffio": {
"hashes": [
"sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2",
"sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"
],
"markers": "python_version >= '3.7'",
"version": "==1.3.1"
}
},
"develop": {}
}
+62
View File
@@ -0,0 +1,62 @@
# CommandTabFree
**CommandTabFree is a fork of [AltTab](https://github.com/lwouis/alt-tab-macos)
(github.com/lwouis/alt-tab-macos), © Louis Pontoise, licensed GPL-3.0.**
This fork neutralizes the AltTab Pro paywall — **all features are free.** It is
**not affiliated with, sponsored by, or endorsed by** the original author. "AltTab"
is used here only to credit the upstream project (nominative fair use); CommandTabFree
is a separate, independently-distributed build.
CommandTabFree is itself released under the **GNU General Public License v3.0** — the same
license as upstream. See [`LICENCE.md`](LICENCE.md) for the full text and
[`NOTICE.md`](NOTICE.md) for the GPL §5(a) statement of changes made in this fork.
## Install
```sh
brew install --cask koftwentytwo/tap/commandtabfree
```
CommandTabFree is **signed and notarized** (as of v100.1.0), so it launches cleanly through
Gatekeeper — no right-click-**Open** workaround needed. Install via the Homebrew cask above, or
download the **`.dmg`** (or `.zip`) from the
[Releases](https://github.com/KofTwentyTwo/CommandTabFree/releases) page and drag CommandTabFree
to Applications. On first launch, grant **Accessibility** and **Screen Recording** in System
Settings. Universal binary (Apple Silicon + Intel), macOS 10.13+.
## Based on AltTab by Louis Pontoise
This software is built on AltTab (`lwouis/alt-tab-macos`) by Louis Pontoise and its
contributors. All of upstream's copyright, attribution, contributor credits
([`docs/contributors.md`](docs/contributors.md)), and third-party acknowledgments
([`docs/acknowledgments.md`](docs/acknowledgments.md)) are retained unchanged. The
only functional change this fork makes is removing the Pro paywall so every feature
is available for free; see [`NOTICE.md`](NOTICE.md) for the precise change list.
## Corresponding source (GPL-3.0 §6)
The complete corresponding source for every released binary is this repository at the
matching release tag:
```
https://github.com/KofTwentyTwo/CommandTabFree
```
For a given release `vX.Y.Z`, the source is the repository tree at that tag, including
the committed build configuration. Only signing/notarization secrets (the Developer ID
certificate, the Sparkle EdDSA private key, and Apple notarization credentials) are
deliberately not conveyed; GPL-3.0 does not require these to be distributed.
---
<!--
Below: upstream credit. CommandTabFree is a fork of AltTab by Louis Pontoise.
This links to the original project for attribution, not as a download CTA for this fork.
-->
<div align="center">
CommandTabFree is a free, GPL-3.0 fork of <a href="https://github.com/lwouis/alt-tab-macos">AltTab</a> by Louis Pontoise.
</div>
+7
View File
@@ -0,0 +1,7 @@
#!/bin/bash
xcodebuild \
-project alt-tab-macos.xcodeproj \
-scheme Debug \
-configuration Debug \
-derivedDataPath DerivedData
+16
View File
@@ -0,0 +1,16 @@
#!/bin/bash
profileFile="/tmp/profile_$(date +%Y%m%d_%H%M%S)"
xcrun xctrace record \
--instrument 'Time Profiler' \
--time-limit 20s \
--no-prompt --quiet \
--output "$profileFile".trace \
--launch -- \
DerivedData/Build/Products/Debug/AltTab.app --benchmark showUi 3
xcrun xctrace export \
--input "$profileFile".trace \
--xpath '/trace-toc/run[@number="1"]/data/table[@schema="time-profile"]' \
--output "$profileFile".xml
Executable
+3
View File
@@ -0,0 +1,3 @@
#!/bin/bash
DerivedData/Build/Products/Debug/AltTab.app/Contents/MacOS/AltTab --logs=debug --benchmark showUi 3
+2
View File
@@ -0,0 +1,2 @@
#import "AppCenterApplication.h"
#import "ObjCExceptionCatcher.h"
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1620"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D04BA5E73DAF232ADE11C97A"
BuildableName = "CommandTabFree.app"
BlueprintName = "alt-tab-macos"
ReferencedContainer = "container:alt-tab-macos.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "BF0C873EC188A7EBBCF4310D"
BuildableName = "unit-tests.xctest"
BlueprintName = "unit-tests"
ReferencedContainer = "container:alt-tab-macos.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "NO"
debugServiceExtension = "internal"
enableGPUValidationMode = "1"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D04BA5E73DAF232ADE11C97A"
BuildableName = "CommandTabFree.app"
BlueprintName = "alt-tab-macos"
ReferencedContainer = "container:alt-tab-macos.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<CommandLineArguments>
<CommandLineArgument
argument = "--logs=debug"
isEnabled = "YES">
</CommandLineArgument>
</CommandLineArguments>
<LocationScenarioReference
identifier = "com.apple.dt.IDEFoundation.CurrentLocationScenarioIdentifier"
referenceType = "1">
</LocationScenarioReference>
</LaunchAction>
<ProfileAction
buildConfiguration = "Debug"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D04BA5E73DAF232ADE11C97A"
BuildableName = "CommandTabFree.app"
BlueprintName = "alt-tab-macos"
ReferencedContainer = "container:alt-tab-macos.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Debug"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1130"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D04BA5E73DAF232ADE11C97A"
BuildableName = "CommandTabFree.app"
BlueprintName = "alt-tab-macos"
ReferencedContainer = "container:alt-tab-macos.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
disableMainThreadChecker = "YES"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D04BA5E73DAF232ADE11C97A"
BuildableName = "CommandTabFree.app"
BlueprintName = "alt-tab-macos"
ReferencedContainer = "container:alt-tab-macos.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<LocationScenarioReference
identifier = "com.apple.dt.IDEFoundation.CurrentLocationScenarioIdentifier"
referenceType = "1">
</LocationScenarioReference>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Release">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1620"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "BF0C873EC188A7EBBCF4310D"
BuildableName = "unit-tests.xctest"
BlueprintName = "unit-tests"
ReferencedContainer = "container:alt-tab-macos.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "NO">
<EnvironmentVariables>
<EnvironmentVariable
key = ""
value = ""
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
<Testables>
<TestableReference
skipped = "NO"
parallelizable = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "BF0C873EC188A7EBBCF4310D"
BuildableName = "unit-tests.xctest"
BlueprintName = "unit-tests"
ReferencedContainer = "container:alt-tab-macos.xcodeproj">
</BuildableReference>
<LocationScenarioReference
identifier = "com.apple.dt.IDEFoundation.CurrentLocationScenarioIdentifier"
referenceType = "1">
</LocationScenarioReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<LocationScenarioReference
identifier = "com.apple.dt.IDEFoundation.CurrentLocationScenarioIdentifier"
referenceType = "1">
</LocationScenarioReference>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
+10
View File
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<false/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
</dict>
</plist>
-52
View File
@@ -1,52 +0,0 @@
<?xml version="1.0" standalone="yes"?>
<rss xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" version="2.0">
<channel>
<title>alt-tab-free</title>
<language>en</language>
<item>
<title>Version 100.1.0</title>
<pubDate>Tue, 16 Jun 2026 19:48:09 +0000</pubDate>
<description>Corresponding source (GPL-3.0): https://github.com/KofTwentyTwo/CommandTabFree/archive/refs/tags/v100.1.0.tar.gz</description>
<sparkle:minimumSystemVersion>10.13</sparkle:minimumSystemVersion>
<sparkle:releaseNotesLink>https://github.com/KofTwentyTwo/CommandTabFree/releases/tag/v100.1.0</sparkle:releaseNotesLink>
<enclosure
url="https://github.com/KofTwentyTwo/CommandTabFree/releases/download/v100.1.0/CommandTabFree-100.1.0.zip"
sparkle:version="100.1.0"
sparkle:shortVersionString="100.1.0"
sparkle:edSignature="5QC/UsEOhct3HiXfsC2tqWSibsegSzwmYQ+WoFnzNzM8PBqs8lPUyDQtzIMQ763NLjdxN1kO5ycf65GmhwG0BA==" length="8384035"
type="application/octet-stream"/>
</item>
<item>
<title>Version 100.2.0</title>
<pubDate>Tue, 16 Jun 2026 21:05:39 +0000</pubDate>
<description>Corresponding source (GPL-3.0): https://github.com/KofTwentyTwo/CommandTabFree/archive/refs/tags/v100.2.0.tar.gz</description>
<sparkle:minimumSystemVersion>10.13</sparkle:minimumSystemVersion>
<sparkle:releaseNotesLink>https://github.com/KofTwentyTwo/CommandTabFree/releases/tag/v100.2.0</sparkle:releaseNotesLink>
<enclosure
url="https://github.com/KofTwentyTwo/CommandTabFree/releases/download/v100.2.0/CommandTabFree-100.2.0.zip"
sparkle:version="100.2.0"
sparkle:shortVersionString="100.2.0"
sparkle:edSignature="1mswtH3y+i+xzIxCFCQos37Z+aePvGInt0+5FIDFi+p8LU4QRIA6ro3g9WGS3MhYATyOtQ/Mbgg8BzpGlbrMCw==" length="8384111"
type="application/octet-stream"/>
</item>
<item>
<title>Version 100.2.1</title>
<pubDate>Tue, 16 Jun 2026 21:21:13 +0000</pubDate>
<description>Corresponding source (GPL-3.0): https://github.com/KofTwentyTwo/CommandTabFree/archive/refs/tags/v100.2.1.tar.gz</description>
<sparkle:minimumSystemVersion>10.13</sparkle:minimumSystemVersion>
<sparkle:releaseNotesLink>https://github.com/KofTwentyTwo/CommandTabFree/releases/tag/v100.2.1</sparkle:releaseNotesLink>
<enclosure
url="https://github.com/KofTwentyTwo/CommandTabFree/releases/download/v100.2.1/CommandTabFree-100.2.1.zip"
sparkle:version="100.2.1"
sparkle:shortVersionString="100.2.1"
sparkle:edSignature="uS6lohQf8BGHLuC+I7uCKQv/jg4357tK3COkt92wiiyfUJpSiRXKM/9ghARBWKzEZ+oAu6gaIw5A2jhrbHjfCQ==" length="8384034"
type="application/octet-stream"/>
</item>
</channel>
</rss>
+3712
View File
File diff suppressed because it is too large. Load diff
+15
View File
@@ -0,0 +1,15 @@
// alt-tab-free [depaywall]: commitlint config with an `ignores` predicate so a `chore(sync): merge
// upstream` PR (and the upstream commits it drags in through the merge's second parent) does NOT fail
// commitlint and block the release job (PLAN §4.3). ci_cd.yml lints the WHOLE pushed range on push and
// base..head on a PR, both of which include upstream's own (non-conventional) messages on a sync merge.
// `defaultIgnores: true` keeps config-conventional's built-in "Merge …" ignore; the predicates below
// drop the synthetic merge subject and any "Merge …" / "Revert …" line we don't author.
module.exports = {
extends: ['@commitlint/config-conventional'],
defaultIgnores: true,
ignores: [
(msg) => /^chore\(sync\): merge upstream /.test(msg), // our synthetic merge commit (§4.2)
(msg) => /^Merge /.test(msg), // belt-and-suspenders (merge commits)
(msg) => /^Revert /.test(msg), // upstream revert subjects
],
}
+21
View File
@@ -0,0 +1,21 @@
// docs: https://help.apple.com/xcode/mac/11.4/#/itcaec37c2a6
PRODUCT_NAME = AltTab
PRODUCT_BUNDLE_IDENTIFIER = com.lwouis.alt-tab-macos
MACOSX_DEPLOYMENT_TARGET = 10.13
SWIFT_VERSION = 5.8 // xcode 14.2 translates this to 5.0; xcode 16.2 as 5.8
SWIFT_TREAT_WARNINGS_AS_ERRORS = YES
INFOPLIST_FILE = Info.plist
CODE_SIGN_ENTITLEMENTS = alt_tab_macos.entitlements
FRAMEWORK_SEARCH_PATHS[config=*] = $(inherited) /System/Library/PrivateFrameworks // for SkyLight.framework
LD_RUNPATH_SEARCH_PATHS = @executable_path/../Frameworks // load embedded frameworks at runtime; Xcode's SPM machinery adds the absolute PackageFrameworks path automatically before this, which is fine in Debug and stale-but-harmless in Release on customer machines
ENABLE_HARDENED_RUNTIME = YES // for notarization
APPLY_RULES_IN_COPY_FILES = YES
INFOPLIST_OUTPUT_FORMAT = binary
PLIST_FILE_OUTPUT_FORMAT = binary
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES
SWIFT_OBJC_BRIDGING_HEADER = alt-tab-macos-Bridging-Header.h
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES
DEAD_CODE_STRIPPING = YES
DOMAIN = alt-tab.app
API_DOMAIN = alt-tab.app/api
+13
View File
@@ -0,0 +1,13 @@
// docs: https://help.apple.com/xcode/mac/11.4/#/itcaec37c2a6
#include "base.xcconfig"
CODE_SIGN_IDENTITY = Local Self-Signed
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG // for macro `#if DEBUG`
OTHER_SWIFT_FLAGS = -driver-time-compilation -Xfrontend -warn-long-function-bodies=250 -Xfrontend -warn-long-expression-type-checking=250 // find slow compilation areas
OTHER_CODE_SIGN_FLAGS = --timestamp=none
SWIFT_COMPILATION_MODE = incremental
ENABLE_DEBUG_DYLIB = NO // skip the debug dylib loader (we don't use SwiftUI Previews); silences [PreviewsAgentExecutorLibrary] startup chatter
// Per-developer overrides (CODE_SIGN_IDENTITY, APPCENTER_SECRET, DOMAIN, API_DOMAIN, …).
#include? "local.xcconfig"
+54
View File
@@ -0,0 +1,54 @@
// =============================================================================
// alt-tab-free — fork identity overlay (committed; see docs/PLAN-maintained-fork.md §3.1)
// =============================================================================
//
// This file is #include?'d LAST by config/release.xcconfig and config/debug.xcconfig,
// so "last assignment wins": every value below overrides config/base.xcconfig WITHOUT
// editing base.xcconfig (which upstream churns). Net pbxproj/base.xcconfig edits: zero.
//
// >>> OWNER MUST SET REAL VALUES BEFORE PUBLISH <<<
// Every placeholder below is OWNER-OVERRIDABLE-BEFORE-PUBLISH and is clearly marked.
// Until these are real, the fork will NOT notarize, auto-update, or serve a working
// feedback/appcast endpoint. See ownerActionsNeeded in the scaffolding report.
//
// KEYCHAIN-SUITE INVARIANT (BLOCKING): PRODUCT_BUNDLE_IDENTIFIER below derives the
// keychain + UserDefaults suite names (LicenseManager.swift:4-5 read App.bundleIdentifier).
// PICK THE FORK'S BUNDLE ID ONCE AND FREEZE IT. Any later change orphans every user's
// stored prefs/state. See §3.1 OWNER DECISION (a)=fresh id / (b)=reuse+migrate.
// =============================================================================
// --- App identity (overrides base.xcconfig :3 / :4) ---
// DECIDED 2026-06-10 (KofTwentyTwo). The bundle id is FROZEN — never change it
// (keychain + UserDefaults suite names derive from it; changing it orphans every user's state).
PRODUCT_NAME = CommandTabFree
PRODUCT_BUNDLE_IDENTIFIER = com.koftwentytwo.commandtabfree
// Local dev default for the build version. Info.plist's CFBundleVersion/CFBundleShortVersionString
// are $(CURRENT_PROJECT_VERSION); CI's replace_environment_variables_in_app.sh APPENDS the real
// release value (which wins by xcconfig last-assignment). Without this, a plain local build leaves
// the version empty and App.version (src/App.swift:14, `as! String`) crashes on launch.
CURRENT_PROJECT_VERSION = 0.0.0
// --- Hosts (overrides base.xcconfig :20-21) ---
// DOMAIN serves the Sparkle appcast at https://<DOMAIN>/appcast.xml. Set 2026-06-16 to the repo's
// GitHub Pages site (gh-pages branch, published by scripts/update_appcast.sh). A kof22.com custom
// domain can be added later — GitHub redirects the github.io URL, so shipped builds keep updating.
// (/support still 404s here — harmless until a support page exists.)
DOMAIN = koftwentytwo.github.io/CommandTabFree
// API_DOMAIN drives the user-feedback POST (FeedbackWindow) — left NON-routable: feedback is deferred
// (§3.4). The activate fingerprint POST is closed separately at the handleCustomUrl handler.
API_DOMAIN = fork.invalid/api
// --- Code signing (overrides release.xcconfig :5) ---
// Fork Developer ID — signed, notarizable builds (PLAN §3.3 / §4.6). Set 2026-06-16.
// The vendored Sparkle helpers (vendor/Sparkle/Helpers/*) are re-signed under this SAME
// identity (a committed change) — required or notarization rejects the nested code.
// Manual style + TEAM_ID so the headless CI runner signs without an Xcode-managed account.
CODE_SIGN_IDENTITY = Developer ID Application: James Maes (2X834TJ5MA)
CODE_SIGN_STYLE = Manual
TEAM_ID = 2X834TJ5MA
// --- Telemetry off (overrides base.xcconfig; AppCenter no-ops on empty secret) ---
// Intentionally empty: telemetry is disabled (reinforced by Edit 3, §2).
// CI must NOT re-append an APPCENTER_SECRET line (see scripts/replace_environment_variables_in_app.sh).
APPCENTER_SECRET =
+21
View File
@@ -0,0 +1,21 @@
// docs: https://help.apple.com/xcode/mac/11.4/#/itcaec37c2a6
#include "base.xcconfig"
CODE_SIGN_IDENTITY = Developer ID Application: Louis Pontoise (QXD7GW8FHY)
CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO // for notarization
OTHER_CODE_SIGN_FLAGS = --timestamp --deep --options runtime // for notarization
SWIFT_COMPILATION_MODE = wholemodule
SWIFT_OPTIMIZATION_LEVEL = -O
GCC_OPTIMIZATION_LEVEL = s // optimize for size; Xcode default for Release but explicit
LLVM_LTO = YES_THIN // ThinLTO: cross-module DCE + inlining across all static-linked .o (host + AppCenter + ShortcutRecorder)
STRIP_SWIFT_SYMBOLS = YES // explicit; Xcode default for Release
DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
CLANG_DEBUG_INFORMATION_LEVEL = line-tables-only // shrinks dSYM for clang/Obj-C; no Swift equivalent ships in Xcode
DEPLOYMENT_POSTPROCESSING = YES
COPY_PHASE_STRIP = YES
STRIP_INSTALLED_PRODUCT = YES
STRIP_STYLE = all
// Per-developer overrides (CODE_SIGN_IDENTITY, APPCENTER_SECRET, DOMAIN, API_DOMAIN, …).
#include? "local.xcconfig"
+13
View File
@@ -0,0 +1,13 @@
// docs: https://help.apple.com/xcode/mac/11.4/#/itcaec37c2a6
SWIFT_VERSION = 5.8
SWIFT_TREAT_WARNINGS_AS_ERRORS = YES
MACOSX_DEPLOYMENT_TARGET = 10.13
CODE_SIGNING_REQUIRED = NO // no need for codesign
CODE_SIGNING_ALLOWED = NO // no need for codesign
ONLY_ACTIVE_ARCH = YES // only need to run on the host machine
ENABLE_BITCODE = NO
GCC_GENERATE_TEST_COVERAGE_FILES = NO
GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = NO
TEST_ATTACHMENT_LOGGING = NO
DEAD_CODE_STRIPPING = YES
+7
View File
@@ -0,0 +1,7 @@
// docs: https://help.apple.com/xcode/mac/11.4/#/itcaec37c2a6
#include "test-base.xcconfig"
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG // for macro `#if DEBUG`
OTHER_SWIFT_FLAGS = -driver-time-compilation -Xfrontend -warn-long-function-bodies=250 -Xfrontend -warn-long-expression-type-checking=250 // find slow compilation areas
SWIFT_COMPILATION_MODE = incremental
+6
View File
@@ -0,0 +1,6 @@
// docs: https://help.apple.com/xcode/mac/11.4/#/itcaec37c2a6
#include "test-base.xcconfig"
DEBUG_INFORMATION_FORMAT = none // we don't need dSYM files
GCC_GENERATE_DEBUGGING_SYMBOLS = NO // we don't need dSYM files
+227
View File
@@ -0,0 +1,227 @@
# alt-tab-free — Master Paywall Audit
> **Purpose.** This is the authoritative, read-this-first overview of the codebase, the paywall grafted onto it, and the complete surface that must be removed to ship a fully-free build. It summarizes nine deep-dive sections under [`docs/audit/`](audit/) and the completeness review; follow the links for line-by-line detail.
>
> **Audit date / commit basis:** repo at `master` (HEAD `9fadf36b`, v11.3.0). All `file:line` references are against this snapshot.
>
> **Status legend:** **KEEP** = legitimate app, must survive · **CUT** = paywall, remove · **REWRITE** = touched by both, hand-edit · **FLAG** = owner decision.
---
## 1. What this project is, and the licensing position
**alt-tab-free** ([github.com/KofTwentyTwo/CommandTabFree](https://github.com/KofTwentyTwo/CommandTabFree)) is a re-host of the popular open-source macOS window switcher **AltTab** ([github.com/lwouis/alt-tab-macos](https://github.com/lwouis/alt-tab-macos)). It is a pure Swift 5.8 AppKit application — no SwiftUI, no Interface Builder (per [`AGENTS.md`](../AGENTS.md)).
### It is not a diverged fork — it is upstream + a paywall commit
Git history shows every recent commit is authored by upstream author `lwouis` (34/40) or `semantic-release-bot` (6/40); **zero commits by the alt-tab-free owner**. The entire paywall was introduced upstream in a single commit `9147a4a8` *"feat: introducing alt-tab pro!"* (v11.0.0, 2026-04-05), a 1869-file change that also did a large repo-wide folder reorg. `src/pro/` did not exist before it and has only ever been touched by 3 commits. All branding is still upstream's: bundle id `com.lwouis.alt-tab-macos`, name AltTab, domain `alt-tab.app`, repo `lwouis/alt-tab-macos`, Sparkle `SUPublicEDKey`, AppCenter secret. (See [`09-telemetry-and-upstream.md`](audit/09-telemetry-and-upstream.md).)
### Licensing: republishing a free build is permitted, with one obligation
The project is **GPL-3.0** ([`LICENCE.md`](../LICENCE.md):1 — *"GNU GENERAL PUBLIC LICENSE Version 3"*). Under GPL-3 you may modify and redistribute, including a build with all paywall code removed. **The obligation:** you must offer the complete corresponding source of your modified version under GPL-3 to your users (typically by publishing the fork's repo). The GPL-3 copyright string in `Info.plist:20-21` is correct and must stay. The paywall itself was GPL-3 code upstream, so its removal carries no additional license burden.
> **Strategic alternative (owner decision).** Because upstream is alive and GPL-3, rebasing the free build on the **pre-paywall upstream tag v10.12.0** (commit `317a485b`) yields the same unlocked feature set with no paywall to extract, at the cost of losing post-v11 fixes unless cherry-picked. The rest of this document assumes **in-place removal** from the current v11.x snapshot.
---
## 2. High-level architecture (the legitimate app)
This is the app that survives removal. Deep dive: [`01-core-architecture.md`](audit/01-core-architecture.md), [`02-switcher-ui.md`](audit/02-switcher-ui.md).
### Startup (two-phase, permission-gated)
- Entry point is top-level code in [`src/main.swift`](../src/main.swift) (**not** `@main`/`@NSApplicationMain`): CLI fast-path → signal/exception handlers → `App.shared.run()` (`main.swift:23`). `main.swift` is paywall-free.
- `App` (`src/App.swift:7`) subclasses `AppCenterApplication` (this is *why* removing AppCenter touches the principal class — see §5) and is its own `NSApplicationDelegate`.
- **Phase A** — `applicationDidFinishLaunching` (`App.swift:435-463`): wires logging, Preferences, the license callbacks, and starts a permission-polling timer.
- **Phase B** — `App.continueAppLaunchAfterPermissionsAreGranted` (`App.swift:383-431`): invoked **once** from `SystemPermissions.checkPermissionsPreStartup` (`SystemPermissions.swift:77`) only after Accessibility + Screen-Recording permissions pass. It creates the background threads/queues, switcher panels, menubar, main menu, and installs every macOS hook.
- The **phase-A → phase-B handoff is the critical launch path and is paywall-free.**
### macOS integration hooks (all paywall-free)
- Keyboard: `cghid` CGEvent tap + Carbon `RegisterEventHotKey` (`KeyboardEvents.swift:104-152`).
- Windows: AX observers with refcon-encoded `(pid,wid)` identity (`AccessibilityEvents.swift`), dispatched through a bounded retry executor (`AXCallScheduler.swift`).
- App lifecycle: KVO on `NSWorkspace.runningApplications` (`RunningApplicationsEvents.swift:6-10`).
- Threading owned by `BackgroundWork` (dedicated CFRunLoop threads + bounded operation queues, ~45-thread budget). **`src/macos/` and `BackgroundWork` contain zero License/Pro references** (grep-verified).
### Switcher UI
Event-driven: each `Window` subscribes to AX notifications → `Windows.findOrCreate` (`Windows.swift:390`), gated by `WindowDiscriminator.isActualWindow`, into the canonical `Windows.list`. Pure unit-tested kernels (`SelectionResolver`, `SearchModeResolver`, `WindowFilterResolver`, `WindowOrderResolver`) are separated from imperative wrappers and **never call pro code** — gating is passed in as a `Bool`. Rendering is a static `TilesView` engine with a 20-`TileView` recycled pool (`TilesView.swift:35`); focus uses private SkyLight APIs (`Window.swift:245-288`).
### Preferences
Everything stored as strings in `UserDefaults.standard`, macro (enum) prefs as stringified `CaseIterable` index, read through `CachedUserDefaults`, written through `Preferences.set` firing one `PreferencesEvents.preferenceChanged` hook. The **core preferences plumbing is paywall-independent** — only the feature-gating layer on top is paywall (see §3).
### Build / release / update
Raw `xcodebuild` over `alt-tab-macos.xcodeproj` (3 schemes), settings layered via `config/*.xcconfig`. Releases are fully automated by `semantic-release` on push to master. Signed with upstream Developer ID *Louis Pontoise (QXD7GW8FHY)*, notarized via bundled `notarytool`. Auto-update via embedded **Sparkle 2.9.1**, feed `https://alt-tab.app/appcast.xml`, EdDSA-signed. Crash reporting via Microsoft **AppCenter** (Crashes module only; opt-in; EoL). Deep dive: [`08-build-release-distribution.md`](audit/08-build-release-distribution.md), [`09-telemetry-and-upstream.md`](audit/09-telemetry-and-upstream.md).
---
## 3. The paywall, anatomized
The paywall lives **almost entirely under [`src/pro/`](../src/pro/)** and is grafted onto the spine at a small, well-defined set of call sites. Four subsystems:
### 3a. License subsystem — `src/pro/license/` ([`04-license-subsystem.md`](audit/04-license-subsystem.md))
`LicenseManager.shared` is the **single source of truth** for entitlement. It computes a flat 4-case `LicenseState` enum — `.trial(daysRemaining:)`, `.pro`, `.proExpired`, `.trialExpired` (`LicenseState.swift:14-19`); there is no `.lifetime` case (lifetime is `.pro` + variant slug `"pro_lifetime"`, `LicenseManager.swift:25`). A **14-day trial** starts on first launch (`LicenseManager.swift:17,192-200`).
- The master gate **`isProLocked`** (`LicenseManager.swift:67-72`) is `true` for `.proExpired`/`.trialExpired`, `false` for `.pro`/`.trial`. Every settings intercept, the write-bounce, the shortcut cap, and `ProFeature.attemptUse()` consult it.
- `activate(_:)` (`LicenseManager.swift:104-140`) does all-or-nothing Keychain writes with rollback, then flips `state = .pro`. `RemoteLicenseClient` (`RemoteLicenseClient.swift`) POSTs activate/validate/deactivate to **`https://alt-tab.app/api/v1/license`** (`Endpoints.swift:11`), sending a machine fingerprint (`MachineFingerprint.swift:9-20`, IOPlatformUUID) + trial-start timestamp. Revalidation is throttled to 30 days.
- Keychain service: **`com.lwouis.alt-tab-macos.license`** (`LicenseManager.swift:4`); a parallel UserDefaults suite of the same name holds `trialStartDate`, `lastValidation`, `customerEmail`.
- `LicenseCookie.swift:5-22` writes a per-tier `license` cookie on `.alt-tab.app` so the Sparkle appcast can be tier-tailored.
### 3b. Trial-nag "Pro Transition" scheduler — `src/pro/scheduling/` ([`05-trial-nag-scheduling.md`](audit/05-trial-nag-scheduling.md))
A self-contained Day1→Day35 upsell-escalation engine. Coordinator `ProTransitionManager` (singleton) + timed `ProTransitionScheduler` (persisted `DispatchWorkItem`) + persisted `ProTransitionState` (all `hasSeen*` flags + `remembered*` Pro indices, in the `.license` UserDefaults suite) + pure, 100%-unit-tested `ProTransitionManagerTestable` state machine. The coordinator emits abstract `ProPromptAction` cases through `onAction`; `ProPromptHost` maps each to a concrete Day-X window/popover so the coordinator stays AppKit-free.
- **Soft nags** (never block): `[A]` Day1 Welcome (fires immediately on first launch), `[H]` Day4 Tour, `[B]` Day12 Heads-Up, `[D]` Day15 Proactive, `[F]` Day21, `[G]` Day35, plus a Days13-14 menubar badge dot.
- **Hard gate arms at Day15 expiry:** `onProLockEngaged()` (`ProTransitionState.swift:73-79`) snapshots degradable Pro prefs to `remembered*` and downgrades stored values to free equivalents; the three hard-gated features then route through a free-pass ladder (`ProTransitionManager.swift:226-242`): first post-expiry attempt = `.freePass` (allow once, queue `[C]` Full Upgrade) → `.showFullUpgrade` → `.showHardGatePopover` `[E]` forever.
- Prompts only fire 10:00-11:30 or 15:30-17:00; give-up at Day49.
### 3c. Feature gating — `ProFeature.swift` + `PreferenceDefinition.swift` ([`03-preferences-and-gating.md`](audit/03-preferences-and-gating.md), [`06-profeature-and-copy.md`](audit/06-profeature-and-copy.md))
Two complementary mechanisms:
1. **Degradable preferences** — declared as 6 `ProGatedPreferences` definitions (`PreferenceDefinition.swift:103-164`): 3 globals (`appearanceStyle`, `appearanceSize`, `shortcutStyle`) + their 3 shortcut-0 overrides. Each carries a `freeEquivalent`, a `rememberedKey`, and an `isProValue` predicate. `PreferenceDefinition.read()` (`:32-44`) is the hot-path getter; while locked it returns the free equivalent. Pro getters in `Preferences.swift` route through these (`:129,130,155,313,319,330`).
2. **Hard-gated runtime actions** — no backing preference, gated at use-time via `ProFeature.attemptUse()` (`ProFeature.swift:74-83`): `extraShortcut(index:)`, `searchInSwitcher`, `lockSearchInSwitcher`. Call sites: `ShortcutAction.swift:56`, `TilesView.swift:79,92`.
Write-side enforcement bounces any setter that lands a Pro value into a gated key while locked, to the Upgrade tab (`PreferencesEvents.swift:62-64`). Free users are hard-capped at **1 shortcut** (`ControlsTab.swift:589-592`). The registered defaults already hold the Pro values (e.g. `appearanceSize=.auto`), so **removing the gate auto-unlocks everything with no default changes.**
### 3d. Upsell UI — `src/pro/ui/` + Settings/Menubar entanglement ([`07-pro-ui-and-menubar.md`](audit/07-pro-ui-and-menubar.md))
Reusable AppKit upsell primitives (none contain license logic; they only render): `ProPromptHost` (dispatch hub), `ProPromptPopover`/`ProPromptWindow` (shared chrome), `ProPromptHeader`, `ProGradientButton` (gradient buy CTA), `UsageStatHeroView` (a "your usage so far" stat block), and `ProBadgeView.swift` (misleadingly named — holds 5 types incl. the `ProGradient` utility enum, `NotAdvisedButton`, and the "Pro" pill). These are also consumed by **Settings** (the persistent Get-Pro gradient pill `UpgradeButton`, the in-window Upgrade view, `ProBadgeView` badges on gated rows, and the "Pro" search-index keyword), which is why `src/pro/ui/` can only be deleted after Settings consumers are cut.
---
## 4. The complete set of Pro-gated features (what becomes free)
There are **two degradable groups + three hard-gated actions**, marketed as four headline features. After removal, all are unconditionally available.
| Feature (marketing copy) | Kind | Free (locked) value | Pro value | Gate mechanism | Definition |
|---|---|---|---|---|---|
| **App Icons & Titles styles** (`appearanceStyle`) | Degradable + hard-gated | `thumbnails` (0) | `appIcons` (1) / `titles` (2) | `read()` downgrade + first-summon `[C]` | `PreferenceDefinition.swift:103-109`; `Preferences.swift:129` |
| **Auto Size** (`appearanceSize`) | Degradable | `medium` (1) | `auto` (3) | `read()` downgrade only | `PreferenceDefinition.swift:111-117`; `Preferences.swift:130` |
| **Search on release** (`shortcutStyle`) | Degradable + hard-gated | `doNothingOnRelease`/`focusOnRelease` | `searchOnRelease` (2) | `read()` downgrade + first-summon `[C]` | `PreferenceDefinition.swift:119-125`; `Preferences.swift:155` |
| ↳ same three as **shortcut-0 overrides** | Degradable | free equivalents | Pro values | `read()` downgrade | `PreferenceDefinition.swift:130-164`; `Preferences.swift:313,319,330` |
| **Up to 9 keyboard shortcuts** (extra slots ≥ 2) | Hard-gated | capped at **1** shortcut | up to 9 | `ProFeature.attemptUse()` + `addShortcutSlot` cap | `ProFeature.swift:14`; `ShortcutAction.swift:56`; `ControlsTab.swift:589-592` |
| **Search — find a window by typing** | Hard-gated | blocked | available | `ProFeature.attemptUse()` | `ProFeature.swift:15`; `TilesView.swift:92` |
| **Lock-search in switcher** | Hard-gated | blocked | available | `ProFeature.attemptUse()` | `ProFeature.swift:16`; `TilesView.swift:79` |
Marketing copy: `ProFeatureCopy.swift` (4 strings); the comparison table that advertises them is `Day1WelcomeLetterWindow.swift:77-80`. Note **preview-selected-window is NOT actually Pro-gated** (`Preferences.effectivePreviewSelectedWindow` reads the raw bool, gated only by Screen-Recording permission) — leave it alone.
---
## 5. The complete removal surface
**Removal strategy (consensus across all sections):** *delete `src/pro/` as a unit, then fix the consumers that reference it.* The lowest-risk staged approach is to first force `LicenseManager.isProLocked = false` / `isProAvailable = true` (every gate becomes a pass-through with no other edits), then progressively excise. The list below — grouped by file — is the full set of edits required for a clean build, incorporating the completeness review's additional items and build-break risks. **Bold flags** mark items the deep sections under-weighted.
### `src/pro/` — delete wholesale (CUT)
- `src/pro/license/` — `LicenseManager`, `LicenseState`, `LicenseAPI`, `RemoteLicenseClient`, `LicenseCookie`, `Keychain`, `MachineFingerprint`, `Clock`, `LicenseManagerSpecs.md`, `LicenseManagerTests.swift`.
- `src/pro/scheduling/` — `ProTransitionManager`, `ProTransitionScheduler`, `ProTransitionState`, `ProTransitionManagerTestable`, all `Day*.swift` windows/popovers, `ProTransitionTests.swift`, `ProTransitionSpecs.md`.
- `src/pro/ui/` — `ProPromptHost`, `ProPromptPopover`, `ProPromptWindow`, `ProPromptHeader`, `ProGradientButton`, `UsageStatHeroView`, `ProBadgeView.swift` (all 5 types). **Delete only AFTER the Settings consumers below are removed.**
- `src/pro/` root — `ProFeature.swift`, `ProFeatureCopy.swift`, `ProConversionCopy.swift`, `UsageStats.swift` / `UsageStatsTestable.swift` (local-only; feeds only upsell copy).
### `src/App.swift` (REWRITE — the spine wiring)
- Selectors `upgradeToProAction` / `openAccountAction` / `supportProjectAction` (`:25-27`) and methods `upgradeToPro` / `openAccount` / `supportProject` (`:111-121`) — remove (Menubar-only consumers).
- `hideUi` `onSwitcherDismissed()` (`:78`) and `showUiOrCycleSelection` `onSwitcherShown()` (`:328`) — remove the single Pro line each (switcher hot path).
- First-launch welcome entanglement (`:189-233`): `willShowDay1WelcomeOnAppLaunch` (`:205-208`) + deferral observer referencing `Day1WelcomeLetterWindow` (`:194-218`). **Simplify to always call `showAndCenterSettingsWindowOnFirstLaunch`; the welcome window and its `willCloseNotification` observer must be removed together or Settings never shows on first launch.**
- Phase-B Pro wiring `onAction` / `onAppLaunchComplete` (`:428-429`) — remove (all other phase-B wiring stays).
- License callback block (`:448-460`): `onBeforeProUnlock`, the `onStateChanged` fan-out (`refreshLicenseMenuItems`, `syncLicenseCookie`, `onLicenseStateChanged`, `UpgradeTab.refreshStatus`, `refreshUpgradeButton`, `proLockStateDidChange` post), `LicenseManager.initialize()`. The cleanest 13-line cut point. Keep `resetPreferencesDependentComponents` (`:51-53`) — it's used elsewhere; just drop the caller.
- Custom-URL handler `application(_:open:)` + `handleCustomUrl` (`:465-490`) — remove wholesale (exists only for the `<bundleid>://activate` deep link; the registered scheme is `$(PRODUCT_BUNDLE_IDENTIFIER)` = `com.lwouis.alt-tab-macos://`, NOT a literal `alt-tab://`). **Also drop the URL scheme from `Info.plist` (`CFBundleURLSchemes`, :53-56).**
### `src/Menubar.swift` (REWRITE)
- License item vars (`:8-10`), the Get Pro / My Account / Support adds + view assignment (`:46-50`), `refreshLicenseMenuItems` (`:84-107`), `toggleUpgradeMenuItem` (`:109-118`).
- `UpgradeMenuItemView` gradient pill incl. trial "days remaining" copy (`:235-390`; copy at `:370-375`) — delete; only consumer is `:47`.
- Badge dot: `badgeDotLayer` (`:187`), `updateBadgeDotOverlay` (`:202-227`) gated on `ProTransitionManager.shouldShowBadgeDot` (`:205`), and its call inside `loadPreferredIcon` (`:196`).
- `menuWillOpen` (`:392-399`): drop `LicenseManager.shared.refreshState()` (`:396`); **keep `refreshPermissionCallout()` (`:397`).**
- **`updateContent(_ state: LicenseState)` (`:357`) hard-depends on the `LicenseState` enum type — goes away with `UpgradeMenuItemView`. Keep `menubarIconCallback` (`:155-164`), used by non-pro callers.**
### `src/preferences/` (REWRITE)
- `PreferenceDefinition.swift` — delete entirely; **it is also a unit-test-target member (`project.pbxproj:1979`), so a broken getter fails app AND test compile.**
- `Preferences.swift` — rewrite the 3 gated getters (`:129,130,155`) and 3 index-0 override branches (`:313,319,330`) to read raw values; remove `overrideRememberedKey` + `ProTransitionState` cleanup in `removeOverride` (`:282-298`).
- `PreferencesEvents.swift:62-64` — delete the `isProLocked && isStoredValuePro` bounce.
- `PreferencesMigrations.swift:20` — remove the `ProTransitionState.markFreshInstallIfUnknown` call (the only paywall coupling in migrations; **the real symbol, distinct from the self-contained stub in `PreferencesMigrationsTests.swift:356`**).
- `LabelAndControl.swift` — strip `proGatedIndices` param + intercept (`:74-116`, esp. `:86-92`).
- `AppearanceTab.swift` — `proLockStateDidChange` observer (`:414-419`), `proGatedAppearanceStyleIndices` (`:462,700-703`), `ProBadge.attach` (`:463,481,575,688-698`), `wrapShortcutStyleProLockIntercept` (`:585-598`), `wrapAppearanceSizeProLockIntercept` (`:662-679`), `refreshProLockUi` (`:705+`).
- `ShortcutEditor.swift` — `proGatedIndices` (`:429,437,449,459`), segmented + radios locked intercepts (`:599-607,705-711`).
- `ControlsTab.swift` — `proLockStateDidChange` observer (`:141`), `row.setProBadge` for index≥1 (`:515`), the `addShortcutSlot` shortcut cap (`:589-592`).
- `ShortcutsWhenActiveSheet.swift` — `ProBadge` on search/lock-search rows (`:25,51,54,63-69`).
### `src/preferences/settings-window/SettingsWindow.swift` — **the most license-entangled non-pro file outside Menubar/UpgradeTab (REWRITE — under-weighted by §7)**
- `UpgradeButton` class (`:133-214`, a `ProGradientButton` subclass reading `LicenseManager.state`/`.isLifetimeVariant`/`.customerEmail`/`.trial`/`.proExpired`); instance `:303`; state `:308-311`; `setupUpgradeButton` + `upgradeButtonClicked` (`:401,507-526`).
- `showUpgradeView` / `hideUpgradeView` embedding `UpgradeTab.initTab` (`:1066,1122-1161`); `refreshUpgradeButton` (`:1163-1165`, called from `App.swift:454` and `UpgradeTab:214`).
- `windowDidBecomeKey` → `LicenseManager.refreshState` + `UpgradeTab.refreshStatus` + shine animation (`:1243-1254`); `UpgradeTab.cleanup` in `windowWillClose` (`:1266`).
- Settings-search registers `ProBadgeView → "Pro"` (`:679-680`); `refreshEmailTooltip` + `hasSecondLine` read `.pro`/`customerEmail` (`:196,206-207`).
### Other Settings / secondary windows (REWRITE)
- `SidebarList.swift` — `private var proBadge: ProBadgeView?` (`:93`) and `setProBadge` instantiating `ProBadgeView` (`:244-258`).
- `UpgradeTab.swift` — delete the whole tab; **`ProHeroButton: ProGradientButton` (`:493`) + `usageHero`/`heroButton`/`makeHeroButton` (`:5-6,37-38,160-161`); `activateLicense`/`deactivateLicense`/`deactivateInstance` + `LicenseAPIError.seatLimitExceeded` seat-management UI (`:322-405`) — full activation UI, §4 listed only `LicenseManager`/`RemoteLicenseClient`.**
- `DebugProfile.swift:17` — `LicenseManager.shared.state.debugProfileLabel` (extension at `LicenseState.swift:14`). **This feeds `FeedbackWindow`, which is being kept — hand-edit (drop the License line), do not delete the file.**
### `src/debug/QAMenu.swift` (REWRITE)
- The DEBUG manual triggers/resets (`:170-241`) directly instantiate every Day-X window and poke `LicenseManager`/manager flags — must be removed/updated in lockstep or the **DEBUG build won't compile.**
### Build / distribution / telemetry (REWRITE / FLAG — see [`08`](audit/08-build-release-distribution.md), [`09`](audit/09-telemetry-and-upstream.md))
- `Endpoints.swift` — `licenseApiBaseUrl` (`:11`), `checkoutUrl` (`:9`), `accountUrl` (`:10`) become dead. `feedbackUrl` (`:12`) and `supportUrl` (`:8`) are not paywall — owner decides.
- **Identity (mandatory regardless of removal):** the upstream Developer ID cannot be used. Change bundle id (`config/base.xcconfig:4`; also hardcoded `Mocks.swift:133` and unit-test ids `project.pbxproj:2477/2542`), signing cert (`release.xcconfig:5`), generate a NEW Sparkle EdDSA keypair (`Info.plist:62 SUPublicEDKey` + CI `$SPARKLE_ED_PRIVATE_KEY`), repoint feed/download/website URLs (`base.xcconfig:20-21`, `update_appcast.sh:16,18`, `App.repository` `App.swift:16`), truncate the upstream-signed `appcast.xml`.
- **AppCenter removal touches the app's principal class:** `App` subclasses `AppCenterApplication` (`App.swift:7`), `Info.plist:36-37 NSPrincipalClass=AppCenterApplication`, `alt-tab-macos-Bridging-Header.h:1`. Removing AppCenter requires choosing a replacement principal class / reverting to `NSApplication`, or **the app won't launch and won't compile.** Also: `src/vendors/AppCenterCrashes.swift`, `Secrets.appCenterSecret`, `scripts/upload_symbols_to_appcenter.sh`, `ci_cd.yml:56`.
- `.github/FUNDING.yml` and the website repository-dispatch (`update_website.sh:5 → lwouis/alt-tab-website`) point at upstream — repoint or remove.
### `alt-tab-macos.xcodeproj/project.pbxproj` — **mechanical but build-fatal (REWRITE)**
Every `src/pro` file (and `Endpoints`/`Secrets`/`AppCenter`) has a `PBXBuildFile` + `PBXFileReference` + `PBXGroup` child + `PBXSourcesBuildPhase` membership (~102 in-Sources pro entries; app phase ~1830, test phase ~1902; incl. `PreferenceDefinition.swift:1979`). **`Clock`/`Keychain`/`LicenseAPI`/`MachineFingerprint`/`ProTransitionManagerTestable` each have TWO build-file UUIDs (app + test) — both must be removed.** Any file deleted on disk but left referenced breaks at project-load/link.
### Test target (REWRITE)
`LicenseManagerTests`, `ProTransitionTests`, `ProTransitionManagerTestable`, `UsageStatsMessageTests`, `ProBadgeViewSegmentTests`, and `_test-support/Mocks.swift` (ProBadgeView stub + `ShortcutStylePreference` mock + bundle id `:133`) all break if pro symbols vanish — update/remove in lockstep.
### Build-break risk summary (the hard dependencies)
| Symbol being deleted | Non-pro / under-weighted consumers that break first |
|---|---|
| `LicenseState` enum | `Menubar.swift:357` (`updateContent` param), `DebugProfile.swift:17` (`.debugProfileLabel`) |
| `LicenseManager.shared` | `SettingsWindow.swift:162,164,167,196,206-207,1246`; `UpgradeTab.swift:220-405` |
| `ProGradientButton` (superclass) | `UpgradeButton` (`SettingsWindow.swift:133`), `ProHeroButton` (`UpgradeTab.swift:493`), `ProGradient.makeLayer` (`Menubar.swift:247`) |
| `ProBadgeView` | `SidebarList.swift:93,254`, `SettingsWindow.swift:679`, Appearance/Controls/ShortcutsWhenActiveSheet tabs |
| `ProGatedPreferences` / `PreferenceDefinition` | `Preferences.swift:129,130,155`; also a test-target member → fails app + test compile |
| `AppCenterApplication` | `App.swift:7` superclass + Bridging-Header + `Info.plist` NSPrincipalClass |
| `Day1WelcomeLetterWindow` | `App.swift:213` first-launch deferral observer |
| `ProTransitionState.markFreshInstallIfUnknown` | `PreferencesMigrations.swift:20` (real symbol) |
---
## 6. Notable findings, risks, and open questions
### Findings
- **The paywall is well-isolated.** Outside `src/pro/`, the entire spine coupling is ~13 lines in `App.swift` (`:448-460`) plus discrete blocks in `Menubar`, `Settings`, and the gating layer. The launch path, switcher kernels, macOS hooks, threading, and core preferences are all paywall-free.
- **Defaults already hold Pro values.** Removing the gate auto-unlocks features with no default changes (`appearanceSize=.auto`, etc.).
- **`.proExpired` is effectively dead code** in this build: `versionLimitedVariants` is empty (`LicenseManager.swift:28`), so no `.pro` variant ever expires by version.
- **No third-party analytics SDK.** Only telemetry is AppCenter Crashes (opt-in, EoL); `UsageStats` is local-only and never networked.
### Risks
- **In-place upgrade data loss.** Users who passed trial expiry on the paywalled build have stored prefs already downgraded to free equivalents, with the original Pro index parked in `proTransition.remembered*` keys (in the `.license` UserDefaults suite). After removal, `read()` no longer restores them → silent loss of their prior Pro selection. A **new bundle id** (clean UserDefaults domain) sidesteps this; otherwise add a one-time migration copying `remembered*` indices back to base keys before deleting `proTransition.*`.
- **`state.didSet` fires `onStateChanged`.** If you hardcode `state = .pro` at init, ensure the hook tolerates being invoked (or unset it) — otherwise it can re-enter paywall code you intend to delete.
- **Keychain/signing invariant is MOOT for a free build.** Removing `src/pro` removes all Keychain license usage, so changing bundle id / Developer ID has nothing to orphan — but the **identity change is still mandatory** because the upstream Developer ID cannot be used. (Per [`AGENTS.md`](../AGENTS.md), do not rotate identity while licensing is retained.)
- **Do NOT `git revert 9147a4a8`.** It mixes the paywall with a 1869-file folder reorg; removal must be by deleting `src/pro/` and untangling the wiring, then confirming the build links (`ai/build.sh`).
### Open questions (owner decisions)
1. **New bundle id vs in-place?** Determines whether the `remembered*` migration above is needed.
2. **Keep "Support this project"** (donation link, upstream precedent) and the feedback feature? Both are non-paywall but currently route through paywall-adjacent code / upstream endpoints (`Endpoints.supportUrl`, `Endpoints.feedbackUrl` → `alt-tab.app`, whose server side is not in this repo).
3. **Auto-update story.** A fork cannot ship updates against the upstream `SUPublicEDKey` / `alt-tab.app/appcast.xml` without owning that domain and lwouis's private key. Stand up own host + EdDSA key, or strip Sparkle.
4. **Keep crash diagnostics?** Remove AppCenter entirely (most privacy-aligned, but requires a replacement principal class) vs repoint to a self-owned AppCenter app (EoL).
5. **Rebase on pre-paywall v10.12.0** vs in-place removal — both yield the same unlocked feature set.
---
*Deep-dive sections: [`01-core-architecture`](audit/01-core-architecture.md) · [`02-switcher-ui`](audit/02-switcher-ui.md) · [`03-preferences-and-gating`](audit/03-preferences-and-gating.md) · [`04-license-subsystem`](audit/04-license-subsystem.md) · [`05-trial-nag-scheduling`](audit/05-trial-nag-scheduling.md) · [`06-profeature-and-copy`](audit/06-profeature-and-copy.md) · [`07-pro-ui-and-menubar`](audit/07-pro-ui-and-menubar.md) · [`08-build-release-distribution`](audit/08-build-release-distribution.md) · [`09-telemetry-and-upstream`](audit/09-telemetry-and-upstream.md)*
+98
View File
@@ -0,0 +1,98 @@
# CI/CD readiness — CommandTabFree (fork of lwouis/alt-tab-macos)
**Date:** 2026-06-16 **Branch:** `master` **Repo:** `KofTwentyTwo/CommandTabFree` (public)
**Status:** full release pipeline **proven** on the real runner — signed + notarized **v100.1.0** released (run `27643432063`, Developer ID `James Maes (2X834TJ5MA)`, `spctl`-accepted + stapled). Non-release pushes stay green via the ad-hoc build path (run `27634828800`).
**Authoritative design:** `docs/PLAN-maintained-fork.md` §4; owner checklist `docs/EXECUTION-STATUS.md` §3.4/§3.5.
This is the state after the CI-fix pass. The pass applied only **safe, owner-secret-independent**
adaptations so that **push CI is GREEN today** on the not-yet-signing-provisioned fork, while the
release tail **flips on automatically** the moment the owner adds the Apple/Sparkle secrets. No secret
values were invented; no DOMAIN fabricated; notarization is not enabled without a cert.
---
## What changed in this pass
| File | Change |
|---|---|
| `.github/workflows/ci_cd.yml` | Added a `release-gate` step that emits `signing-ready` from secret presence (`APPLE_P12_CERTIFICATE`/`APPLE_ID`/`APPLE_PASSWORD`/`APPLE_TEAM_ID`/`SPARKLE_ED_PRIVATE_KEY`). Gated codesign/notarize/appcast/semantic-release/extract-changelog/gh-release/sync-state-advance behind `push && signing-ready=='true'`. Removed the `update_readme_and_website.sh` step (queried the **upstream** lwouis API — semantic mismatch, cosmetic). |
| `scripts/update_appcast.sh` | `sign_update -s $KEY` (DEPRECATED; per `--help` "no longer supported for newly generated keys" — would reject the fork's fresh EdDSA key) → `printf '%s' "$SPARKLE_ED_PRIVATE_KEY" \| sign_update --ed-key-file -`. No `-p` (default output is the `sparkle:edSignature/length` attr pair the enclosure needs; verified). Key now off the argv. |
| `commitlint.config.js` | Added `defaultIgnores: true` + `ignores` predicates (drop `chore(sync): merge upstream …`, `Merge …`, `Revert …`) so a sync merge's dragged-in upstream messages don't fail commitlint and block the release job (PLAN §4.3). |
| `scripts/update_readme_and_website.sh` | **Removed** — hardcoded `lwouis/alt-tab-macos` API + `lwouis` contributor graph; cosmetic SVG stats; no live caller after the workflow edit. |
| `scripts/update_website.sh` | **Removed** — dispatched to upstream `lwouis/alt-tab-website`; already had no live caller. |
| `scripts/upload_symbols_to_appcenter.sh` | **Removed** — hardcoded upstream AppCenter org; telemetry is off (PLAN §3.4); no live caller. |
All three workflow YAMLs validate (`yaml.safe_load` OK); `commitlint.config.js` loads in node.
---
## (A) WORKING / green NOW, without any owner secret
These run on every push and PR and need no Apple/Sparkle/DOMAIN/bot secret. They are what makes push
CI GREEN today (vs. the prior all-14-runs-RED state — note that RED was a *missing depaywall marker*,
already fixed on this branch; this pass ensures it does not go RED again on missing secrets).
| Capability | Where | Confidence |
|---|---|---|
| **Guard A** anti-relock unit tests (`run_tests.sh`, Test scheme) | `ci_cd.yml` push+PR; `guard.yml` PR (macos-15) | High — verified GREEN in EXECUTION-STATUS §2.2 (493 exec, 16 skipped, 0 fail) |
| **Guard B** de-paywall marker + `if false` wrap grep | `ci_cd.yml` first push step + PR; `guard.yml` PR | High — marker present at `LicenseManager.swift:177` |
| **Guard C** unresolved-conflict-marker grep | `ci_cd.yml` first push step + PR; `guard.yml` PR | High |
| **Compile the full tree** (`build_app.sh`, **ad-hoc**) | `ci_cd.yml` push | Verified GREEN on CI (run 27634828800). NOTE: the bare `build_app.sh` inherits upstream's Developer ID from `config/release.xcconfig:5` and fails with exit 65 on CI; the build step now runs ad-hoc (`CODE_SIGN_IDENTITY=-`) when `release-gate` is not signing-ready, and signed otherwise. `build_app.sh` forwards xcodebuild overrides via `"$@"`. |
| **commitlint** (push range + PR base..head, with `ignores`) | `ci_cd.yml` | Med-High — `ignores` should absorb upstream merge msgs; confirm on FIRST real sync PR |
| **generated-files-up-to-date** check | `ci_cd.yml` push+PR | High |
| **semantic-release dry-run** version compute (`determine_next_version.sh`) | `ci_cd.yml` push | High — dry-run, no push, no secret |
| **Release tail SKIPS cleanly** when secrets absent (warning, not failure) | `ci_cd.yml` `release-gate` | High — `signing-ready=false` path emits `::warning::` and skips |
> Note: full GREEN on the GitHub-hosted **macos-15** runner with **Xcode 26.0.1** is now CONFIRMED by a
> real run (`27634828800`, commit `6070f0cb`): gate + `run_tests.sh` + ad-hoc `build_app.sh` all pass and
> the release tail skips cleanly on absent secrets.
## (B) READY — flips ON automatically when the owner adds secret X
No further code change needed; the gate enables these the moment the secret(s) exist in the `production`
Environment.
| Capability | Enabling secret(s) | Gated step(s) |
|---|---|---|
| Code-sign keychain import | `APPLE_P12_CERTIFICATE` | `setup_ci_master.sh` |
| Notarize + staple | `APPLE_ID` + `APPLE_PASSWORD` + `APPLE_TEAM_ID` | `package_and_notarize_release.sh` |
| Sparkle appcast sign + publish to gh-pages | `SPARKLE_ED_PRIVATE_KEY` (+ a real `DOMAIN`/feed host) | `update_appcast.sh` (now `--ed-key-file -`) |
| Tag push + GitHub Release | ambient `GITHUB_TOKEN` (auto) — only gated alongside the above so a release isn't cut unsigned | `npx semantic-release`, `softprops/action-gh-release` (the release-tail `.fork-sync-state` advance step was **REMOVED** 2026-06-16 — it clobbered the upstream-sync cursor with the fork release tag; the cursor must be advanced by the sync-merge flow instead — see `ci_cd.yml`) |
| Sync PR fires `guard.yml`/`ci_cd.yml` PR checks | `SYNC_BOT_TOKEN` (GitHub App token or fork PAT — NOT default `GITHUB_TOKEN`) | `upstream_sync.yml` (fail-closed if missing) |
> The release tail is **all-or-nothing**: it requires the full Apple set **and** the Sparkle key
> (`signing-ready` is the AND of all five). This is deliberate — cutting a tag/Release without a signed,
> notarized, Sparkle-signed artifact would publish an un-updatable or Gatekeeper-blocked build and burn a
> version number. If you want to test the build path before the Apple cert exists, push runs build + Guard
> A and stops cleanly.
## (C) OWNER-BLOCKED — exact action required (cannot be done by agents)
| # | Blocker | Exact owner action |
|---|---|---|
| 1 | Apple Developer ID cert | Obtain a **Developer ID Application** cert for the fork; base64 it into secret `APPLE_P12_CERTIFICATE`; set `CODE_SIGN_IDENTITY` in `config/local.xcconfig` (currently commented). Re-sign the vendored `vendor/Sparkle/Helpers/*` under the SAME ID or notarization rejects (PLAN §3.3). |
| 2 | Notarization creds | Set secrets `APPLE_ID`, `APPLE_PASSWORD` (app-specific password), `APPLE_TEAM_ID` in the `production` Environment. |
| 3 | Sparkle private key | Store `SPARKLE_ED_PRIVATE_KEY` (already generated 2026-06-15) in the `production` Environment. Confirm the `Info.plist` `SUPublicEDKey` is the real public half (currently may be a placeholder). |
| 4 | `production` Environment | Create the GitHub Environment named **`production`** (matches `ci_cd.yml: environment: production`) with **no required-reviewer protection** that would stall releases; attach secrets #1–#3. |
| 5 | Real DOMAIN / appcast host | Replace `DOMAIN`/`API_DOMAIN` placeholders (`fork.invalid`) in `config/local.xcconfig` with fork-owned routable hosts; stand up `https://<DOMAIN>/appcast.xml` (gh-pages); `git rm appcast.xml` + gitignore it (PLAN §3.2). Until done, auto-update has no feed even with the key. |
| 6 | `SYNC_BOT_TOKEN` | Provision a GitHub App installation token (preferred) or fork PAT with contents + pull-requests write. Default `GITHUB_TOKEN` does NOT re-trigger PR checks → guards never run on the sync PR (`upstream_sync.yml` fails closed without it). |
| 7 | PR labels | `gh label create sync` / `conflict` / `chokepoint-refresh` (`upstream_sync.yml` fails closed if any is missing). |
| 8 | External scheduler | Hit `repository_dispatch` (type `upstream-sync`) from an external cron (immune to GitHub's 60-day in-repo `schedule:` auto-disable); add the two-trigger liveness alert (PLAN §4.2). |
| 9 | Xcode re-pin discipline | When an upstream sync bumps `ci_cd.yml`'s pinned Xcode, re-pin `guard.yml`'s `Xcode_26.0.1` line to match (EXECUTION-STATUS §3.5). |
| 10 | Bootstrap acceptance tests | (a) sync PR through the bot shows guard checks; (b) a deliberately-relocked branch goes RED on `guard.yml`; (c) fork build N→N+1 auto-updates via Sparkle (PLAN §4.2/§4.4/§6.1). |
---
## Remaining risks (need a real CI run to confirm)
- **macos-15 + Xcode_26.0.1 availability** on GitHub-hosted runners is assumed, not verified here.
- **commitlint `ignores`** is verified to load and match our synthetic subject, but the exact set of
*upstream* non-conforming messages can't be enumerated until a real `chore(sync)` merge — re-verify on
the FIRST sync PR (PLAN §4.3 says confirm on first sync).
- **`semantic-release` v15 / commitlint v8 on node-16**: kept per PLAN §4.3 (engines mismatch only warns);
unverified end-to-end on the runner since the release tail can't run without secrets.
- **`update_appcast.sh` gh-pages publish path** (orphan-branch seed, append-before-`</channel>`) is logic
the agents can't exercise without `GITHUB_TOKEN` + a real repo; verify on the first signed release.
- **`set -x` in `update_appcast.sh`** will print the `printf '%s' "$SPARKLE_ED_PRIVATE_KEY"` command in
the (private-repo) log trace; the key is no longer on the argv/process list, but consider `set +x` around
the sign line if the repo ever goes from private logs to public. (Not changed in this pass — out of scope.)
+295
View File
@@ -0,0 +1,295 @@
# Execution status — depaywall-free integration
**Branch:** `depaywall-free`
**Upstream sync point:** lwouis/alt-tab-macos `v11.3.0` (recorded in `.fork-sync-state`)
**Date:** 2026-06-10
**Authoritative plan:** `docs/PLAN-maintained-fork.md`. Audit: `docs/AUDIT.md`.
This document records what the automated agents DID, the verified build/test/gate
results, and the **single authoritative owner publish checklist** (only the human
owner can do the items at the bottom). Read the checklist top to bottom before publishing —
several items are BLOCKING (the fork will not notarize, auto-update, or gate releases
until they are done).
---
## 1. What was DONE
### 1.1 De-paywall patch (committed BEFORE this integration pass)
Landed in commit `f3d76859` (`depaywall: neutralize license gate, cookie, telemetry, and
activate handler (src/pro left intact)`). `src/pro/` is left physically present but inert.
Four neutralizations, each carrying a `depaywall` marker comment:
| # | File:line | Edit | Effect |
|---|-----------|------|--------|
| 1 | `src/pro/license/LicenseManager.swift:177` | `guard false else { return .pro }` (body below wrapped in `if false { … }`) | The single state producer `computeState()` always returns `.pro`. Opens every Pro gate in the tree at once; no per-merge UI/pbxproj edits. |
| 2 | `src/App.swift:474` | `guard false else { return }` at top of `handleCustomUrl` | The scheme-gated `<bundleid>://activate?license_key=…` handler early-returns, so it can NEVER reach `LicenseManager.shared.activate → RemoteLicenseClient` POST that exfiltrates the machine hardware UUID (`MachineFingerprint`). This is the live-exfiltration surface, killed independent of where `API_DOMAIN` points. |
| 3 | `src/pro/license/LicenseCookie.swift:6` | body wrapped in `if false { … }` | `syncLicenseCookie(state:)` never writes a `license` cookie to the fork/upstream domain. Call site in `App.swift` (hot file) untouched. |
| 4 | `src/vendors/AppCenterCrashes.swift:10` | `init()` body wrapped in `if false { … }` | `AppCenter.start(...)` never runs; no crash telemetry network calls. `App.appCenterDelegate = AppCenterCrash()` still constructs the object, which now does nothing. |
All four use `if false { … }` / `guard false` rather than a bare early `return`, because
`config/base.xcconfig:7` sets `SWIFT_TREAT_WARNINGS_AS_ERRORS=YES` and "code after return"
is a build error.
### 1.2 Anti-relock guard tests (committed BEFORE this integration pass)
Landed in commit `4506c539`. Two methods appended to the EXISTING
`src/pro/license/LicenseManagerTests.swift` (already in the `unit-tests` Sources phase — zero
pbxproj edits), per PLAN §4.4 Guard A:
- `testDepaywallProNeverLocked` — fresh mock-injected `LicenseManager`; asserts `state == .pro`.
- `testDepaywallStillProAfterTrialExpiry` — injects a long-past `trialStartDate` so an
*unpatched* `computeState()` would return `.trialExpired`; asserts `.pro` + `!isProLocked`
+ `isProAvailable`. This is the discriminating test — it goes RED on a re-armed paywall.
**Both pass** (see §2). They use the existing `MockClock`/`MockKeychain`/`MockLicenseAPI`
fixtures and never reference `LicenseManager.shared`, `Endpoints.*`, or `ProFeature.*` (the four
traps documented in PLAN §4.4).
### 1.3 Scaffolding (committed in THIS pass — `3dde8a91`)
`git commit -m "chore: identity overlay + sync/guard/release CI scaffolding (placeholders flagged for owner)"`
— 15 files, +681/-3891. The agents wrote these but had not committed; this pass committed them.
**Identity overlay (fork-owned, last-include-wins; zero edits to `base.xcconfig`/`project.pbxproj`):**
- `config/local.xcconfig` (NEW) — `PRODUCT_NAME=AltTabFree`, `PRODUCT_BUNDLE_IDENTIFIER=io.github.koftwentytwo.alt-tab-free`, `DOMAIN=fork.invalid`, `API_DOMAIN=fork.invalid/api`, `APPCENTER_SECRET=` (empty), `CODE_SIGN_IDENTITY` left commented (TODO). All values are PLACEHOLDERS flagged for the owner.
- `Info.plist` — `Domain`/`ApiDomain` now wired to `$(DOMAIN)`/`$(API_DOMAIN)`; `SUPublicEDKey` = `REPLACE_WITH_FORK_SUPUBLIC_EDKEY` placeholder.
- `src/api/Endpoints.swift` — reads `Domain`/`ApiDomain` from the bundle (build-time, fork-owned), so every license/feedback/appcast URL derives from the fork's own hosts, never upstream `alt-tab.app`.
- `package.json` — `license` set to `GPL-3.0`, author cleared.
**GPL attribution docs:** `README.md` (modified), `NOTICE.md` (NEW) — GPL §5(a) statement of
changes; currently references placeholder identity (`AltTabFree`, the placeholder bundle id, the
placeholder GitHub URL) and upstream `v11.3.0` / `2026-06-10`.
**Upstream-sync + guard CI:** `.github/workflows/upstream_sync.yml` (NEW), `.github/workflows/guard.yml`
(NEW), `.fork-sync-state` (NEW, `v11.3.0`). `guard.yml` runs Guard A (anti-relock test on `macos-15`,
Xcode pinned to `26.0.1`), Guard B (depaywall marker grep), Guard C (conflict-marker grep) on
`pull_request`.
**Release pipeline:** `.github/workflows/ci_cd.yml` (re-architected: `pull_request` trigger added,
release-side steps gated, Guard B/C greps inserted FIRST in the push job),
`scripts/update_appcast.sh`, `scripts/replace_environment_variables_in_app.sh`, `release.config.js`,
`appcast.xml` (trimmed), `.github/FUNDING.yml`, `.gitignore`.
All three workflow YAMLs validate (`yaml.safe_load` OK).
---
## 2. Verified results
### 2.1 Build — full tree compiles (PASS)
`bash ai/build.sh` (Debug) FAILS in this environment with exactly one error:
```
error: No certificate matching 'Local Self-Signed' found … (target 'alt-tab-macos')
```
This is `config/debug.xcconfig:5` (`CODE_SIGN_IDENTITY = Local Self-Signed`) requiring a
self-signed cert that is **not present in this CI/dev keychain** (`security find-identity -v
-p codesigning` → `0 valid identities found`). It is a pre-existing ENVIRONMENT prerequisite,
unrelated to the depaywall patch or scaffolding (the scaffolding touches no Debug signing config).
Re-running with signing disabled isolates compilation:
```
xcodebuild -project alt-tab-macos.xcodeproj -scheme Debug -configuration Debug \
-derivedDataPath DerivedData \
CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO
→ ** BUILD SUCCEEDED ** (exit 0; 0 errors; 218 Swift compile actions)
```
**The full source tree compiles clean after all scaffolding.** No scaffolding file needed a fix,
so the commit was not amended. The default `ai/build.sh` will succeed once the owner provisions a
signing identity (see checklist).
### 2.2 Tests — GREEN (anti-relock guards PASS; 16 legacy paywall tests skipped — §2.3)
`xcodebuild test -scheme Test -configuration Debug` (signing disabled by `config/test-base.xcconfig`):
- **477 tests pass.**
- The two anti-relock guards **PASS**:
- `testDepaywallProNeverLocked` — passed (0.001s)
- `testDepaywallStillProAfterTrialExpiry` — passed (0.001s)
- **16 legacy paywall-behavior tests in `LicenseManagerTests` were RED** (they assert the now-dead
trial/expiry/lock/activate behavior). **RESOLVED in commit `1a914c88`** — each is now `XCTSkip`-marked
with an `alt-tab-free [depaywall]` reason. Zero failures outside `LicenseManagerTests`; zero attributable
to scaffolding.
**Overall Test scheme result: GREEN** (`** TEST SUCCEEDED **`) — 493 executed, **16 skipped, 0 failures**;
both `testDepaywall*` anti-relock guards RUN and PASS.
### 2.3 RESOLVED (commit `1a914c88`) — 16 legacy paywall tests contradicted the patch
> **RESOLVED 2026-06-10:** all 16 are now `XCTSkip`-marked (`alt-tab-free [depaywall]`), so the `Test`
> scheme is GREEN and the two `testDepaywall*` guards remain the active anti-relock signal. The analysis
> below is retained for the record.
The depaywall patch forces `computeState()` to always return `.pro`. Sixteen pre-existing tests in
`src/pro/license/LicenseManagerTests.swift` still assert the now-dead trial/expiry/lock behavior and
therefore fail. They were introduced-as-failing by the depaywall patch commit (`f3d76859`), NOT by
this integration pass's scaffolding. The failing tests:
```
testFirstLaunchStartsTrial testTrialMidway
testSecondLaunchPreservesTrialStart testTrialLastDay
testTrialExpiresOnDay14 testTrialExpiresWellPastDuration
testPreviouslyInvalidatedLicenseIsTrialExpired testLicenseWithoutValidationResultIsTrialExpired
testIsProLockedTrueAfterTrialExpiry testIsProLockedTrueWhenKeychainInvalidated
testOnStateChangedFiresOnInitialize testOnBeforeProUnlockFiresBeforeStateFlipsToPro
testActivateFailurePreservesState testActivateSeatLimitExceededSurfacesInstances
testActivateFailsAndRollsBackIfKeychainWriteFails testActivateRollsBackPartialKeychainWritesOnLaterFailure
```
Root cause (two clusters, both downstream of the forced `.pro`):
1. **initialize-path tests** assert `.trial(...)` / `.trialExpired` after `initialize()`, which now
always yields `.pro`.
2. **activate-failure-path tests** assert state stays `.trial` after a rejected/rolled-back
`activate`, but the rollback re-reads `state = computeState()` → `.pro`.
**Why this is BLOCKING and was NOT silently "fixed" here:** PLAN §4.4 makes `run_tests.sh` (the whole
`Test` scheme) the Guard A release gate, wired into both `ci_cd.yml` (push job) and `guard.yml`
(PR). A permanently-RED Test scheme means **Guard A can never go green → no release can ever ship,
and the genuine anti-relock signal is drowned out by 16 expected failures.** Neutralizing 16 tests is
a substantive source change to a hot test file (re-conflicts on every upstream sync that touches it)
and is outside the "fix the offending *scaffolding* file" / "do NOT deviate from strategy" mandate of
this integration pass, so it is flagged for an explicit owner/patch decision rather than done
unilaterally. **Recommended disposition** (consistent with the depaywall strategy — neutralize, don't
delete): wrap each failing assertion's body in `if false { … }` with an `alt-tab-free [depaywall]`
marker and replace it with an `XCTAssertEqual(manager.state, .pro)` assertion, exactly mirroring how
the production code was neutralized. This keeps the merge surface minimal and the test file's
membership/pbxproj untouched. (Alternatively, delete the 16 methods — simpler diff, but loses the
documentation of the dead behavior.)
### 2.4 Gate proofs — the paywall is dead (verified by grep + reachability)
| Plan requirement | Proof |
|---|---|
| (a) `computeState()` returns `.pro` with `depaywall` marker | `LicenseManager.swift:177` — `guard false else { return .pro } // depaywall: …` |
| (b) no reachable POST to `alt-tab.app/api` | Both POST sites (`RemoteLicenseClient.swift:105`, `FeedbackWindow.swift:446`) target `Endpoints.apiDomain`, which is read from Info.plist `ApiDomain` (fork-owned, build-time — currently `fork.invalid/api`), NEVER upstream `alt-tab.app`. The only two literal `alt-tab.app` strings in the tree are doc comments, not live code. The license-activate POST's auto-reachable entry point (`App.swift:474` `handleCustomUrl`) early-returns via `guard false`. Its only other caller (`UpgradeTab.activateLicense`) requires a human to paste a key into the upsell UI and would hit the fork's own backend, not upstream. |
| (c) `syncLicenseCookie` + `AppCenterCrash.init` wrapped in `if false` | `LicenseCookie.swift:6` — `if false { // depaywall: …`; `AppCenterCrashes.swift:10` — `if false { // depaywall: …` |
---
## 3. Owner publish checklist — only you can do these
These require human judgment, secrets, or external accounts. Items marked **BLOCKING** must be done
or the fork will not notarize, auto-update, gate releases, or stop phoning home. Grouped, with the
per-component owner actions gathered from the scaffolding agents merged in.
### 3.0 ✅ DONE (commit `1a914c88`) — Test scheme is GREEN
- [x] **Resolved the 16 RED legacy paywall tests** in `src/pro/license/LicenseManagerTests.swift` —
each is now `XCTSkip`-marked (`if true { throw XCTSkip("alt-tab-free [depaywall]: …") }`; the bare
`throw` form is rejected by `SWIFT_TREAT_WARNINGS_AS_ERRORS`). The `Test` scheme is now GREEN
(493 executed, 16 skipped, 0 failures); the two `testDepaywall*` anti-relock guards still RUN and
PASS. No owner action remains here.
### 3.1 Brand / identity / trademark (BLOCKING for a clean publish)
- [x] **Fork name + brand sweep + l10n (DONE 2026-06-15)** — name is **CommandTabFree** (trademark-distinct);
brand sweep done; l10n rebranded across base/en + all ~20 language tables, upstream attribution kept.
- [x] **`PRODUCT_NAME = CommandTabFree` (DONE)** in `config/local.xcconfig`. Verify `ci_cd.yml` `APP_NAME`
matches when CI is wired.
- [x] **Fork bundle id FROZEN (DONE)** — `com.koftwentytwo.commandtabfree` (option (a) fresh id) in `config/local.xcconfig`.
- [x] **`README.md` + `NOTICE.md` (DONE)** — final product name, real fork GitHub URL; README now includes the brew install.
- [ ] **At release time, set `NOTICE.md`'s upstream version + modification date** to the actual sync
point (currently `v11.3.0` / `2026-06-10`). Keep `NOTICE.md` current per PLAN §6.2 on every future
sync that changes the fork's modification surface. **Note:** `NOTICE.md` lists
"App.handleCustomUrl (activate disabled)" as a change — the §2 Edit-2 neutralization HAS landed
(`App.swift:474`), so that line is accurate; if you ever opt NOT to neutralize it, remove that line.
- [x] **App icon DONE (owner-approved 2026-06-15)** — the ⌘⇥ glyph (app + menu bar) is the chosen mark, not lwouis's mark. No replacement planned.
- [ ] **Add `config/local.xcconfig` and `package.json` to the PLAN §6.2 "keep ours" recurring-conflict
set** so a future merge can't re-introduce upstream identity or the MIT license string.
### 3.2 Hosts / domain (BLOCKING for update + feedback)
- [ ] **Set `DOMAIN` and `API_DOMAIN` in `config/local.xcconfig`** to fork-owned, routable hosts
(currently `fork.invalid` / `fork.invalid/api` placeholders). `DOMAIN` must serve
`https://<DOMAIN>/appcast.xml` and `/support`; `API_DOMAIN` drives the feedback POST. Decide the
§3.4 feedback strategy. The `activate` fingerprint POST is closed independently at the handler
(§2 Edit 2), so `API_DOMAIN` may be routable for feedback WITHOUT re-arming exfiltration.
- [ ] **Stand up the appcast/feed host:** point `DOMAIN` at the gh-pages site that serves
`/appcast.xml` (or CNAME it). `Endpoints.appcastUrl = https://$DOMAIN/appcast.xml`.
- [ ] **Remove `appcast.xml` from the tree** (`git rm appcast.xml`) and add `/appcast.xml` to
`.gitignore` — the feed is served out-of-tree from gh-pages. (Coordinate: `.gitignore` is owned by
the identity overlay.)
### 3.3 Code signing + Sparkle keys (BLOCKING for notarization + auto-update)
- [ ] **Obtain an Apple Developer ID Application certificate** for the fork and set
`CODE_SIGN_IDENTITY` in `config/local.xcconfig` (currently a commented TODO). Required for
notarization/Gatekeeper. Also re-sign the vendored Sparkle helpers under the SAME Developer ID
(PLAN §3.3 / §4.6) or notarization rejects. (This is also what makes the default `ai/build.sh`
stop failing on the missing `Local Self-Signed` cert.)
- [x] **Sparkle EdDSA keypair generated (2026-06-15).** PUBLIC key wired into `Info.plist`
(`SUPublicEDKey`); PRIVATE key stored in 1Password "CommandTabFree-Sparkle-EdDSA" + GitHub
Actions secret `SPARKLE_ED_PRIVATE_KEY` (env `production`); keychain account `commandtabfree`.
`SUEnableAutomaticChecks` set false until DOMAIN serves a real appcast.
**TODO at CI-wiring time:** `update_appcast.sh` still calls the deprecated `sign_update -s` —
switch it to `--ed-key-file` (or `--account commandtabfree`); the `-s` path rejects this key format.
### 3.4 GitHub Actions secrets + Environment (BLOCKING for release)
- [ ] **Create the GitHub Environment named `production`** (matches `ci_cd.yml` `environment:`) with NO
required-reviewer protection that would stall releases.
- [ ] **Set these secrets (repo + the `production` Environment):** `APPLE_P12_CERTIFICATE` (fork's
Developer ID), `APPLE_ID`, `APPLE_PASSWORD`, `APPLE_TEAM_ID`, `SPARKLE_ED_PRIVATE_KEY` (fork's NEW
EdDSA private key), and `SYNC_BOT_TOKEN`.
- [ ] **Provision `SYNC_BOT_TOKEN` (BLOCKING, PLAN §4.2):** a GitHub App installation token (preferred)
or a fork-owned PAT with contents + pull-requests write. **The default `GITHUB_TOKEN` will NOT
work** — a PR it authors fires no `pull_request` checks, so `guard.yml` / `ci_cd.yml` never run on
the sync PR. Add it to the §4.6 credential-lifecycle bucket (it expires; can push to master if
leaked).
### 3.5 Upstream-sync wiring (BLOCKING for the perpetual-republish promise)
- [ ] **Create the three PR labels at bootstrap (§6.1):** `gh label create sync`,
`gh label create conflict`, `gh label create chokepoint-refresh`. `upstream_sync.yml` fails closed
if any is missing.
- [ ] **Set up the EXTERNAL scheduler (§4.2 recommended primary)** hitting `repository_dispatch` (event
type `upstream-sync`) carrying `SYNC_BOT_TOKEN` — immune to GitHub's 60-day auto-disable of in-repo
cron. The in-repo cron is belt-and-suspenders only.
- [ ] **`.fork-sync-state` writer (contract owned by `ci_cd.yml`):** add the push-job step that advances
`.fork-sync-state` to the merged tag on merge to master — without it the cron re-opens the same tag
forever. (This file is the contract; the writer lives in `ci_cd.yml`.)
- [ ] **Add the two-trigger liveness alert (§4.2):** notify if no `sync/*` PR in ~45 days OR oldest open
`sync/*` PR > ~14 days (the workflow emits a `stalled` output flag for this).
- [ ] **Re-pin `guard.yml`'s Xcode line** (currently `Xcode_26.0.1`) whenever an upstream sync bumps
`ci_cd.yml`'s pinned Xcode (§4.5 / §6.2).
### 3.6 Commit/changelog plumbing (needed for CI to pass on sync PRs)
- [ ] **Add the `commitlint.config.js` `ignores` predicate (§4.3)** to drop the synthetic
`chore(sync): merge upstream` commit and upstream's non-conforming messages — `ci_cd.yml`'s
commitlint steps depend on it.
- [ ] **Inject the GPL §6(d) corresponding-source pointer into the GitHub Release body**
(`scripts/extract_latest_changelog.sh`). `update_appcast.sh` already covers the Sparkle channel;
the GitHub Release channel still needs it (PLAN §5(1)).
- [ ] **Consider a source tarball release asset and/or a takedown-contingency mirror** so GPL §6 source
survives a repo takedown (PLAN §5(1) conveyance durability).
### 3.7 Bootstrap acceptance tests (do before declaring "published")
- [ ] **§4.2 first-sync acceptance:** open a sync PR THROUGH the bot and confirm `guard.yml` +
`ci_cd.yml` `pull_request` checks actually appear and run. A check-less bot PR means
`SYNC_BOT_TOKEN` is mis-set.
- [ ] **§4.4 relock acceptance:** push a branch reverting the `computeState() → .pro` flip and confirm
`guard.yml` goes RED (Guard A test on `macos-15`, and/or the Guard B marker grep) before merge.
- [ ] **§6.1 fork-to-fork auto-update acceptance:** confirm a user on fork build N actually receives
build N+1 via Sparkle — enclosure URL resolves to the fork's release, the EdDSA signature verifies
against the embedded fork public key, `SUVersion` ordering is monotonic, and Gatekeeper is the only
first-run friction (PLAN §3.6.1).
---
## 4. Commit log on `depaywall-free`
```
3dde8a91 chore: identity overlay + sync/guard/release CI scaffolding (placeholders flagged for owner) [this pass]
4506c539 test: anti-relock guards (pro never locked, incl. post-trial-expiry)
f3d76859 depaywall: neutralize license gate, cookie, telemetry, and activate handler (src/pro left intact)
e243fb4b docs: audit + republish/maintained-fork plans
9fadf36b chore(release): 11.3.0 [skip ci] (upstream sync point)
```
+291
View File
@@ -0,0 +1,291 @@
# alt-tab-free — System Graphs
Visual companion to the paywall-removal audit (`docs/audit/01..09`). Five Mermaid diagrams:
overall architecture, license activation/state flow, the Day1→Day35 trial-nag escalation, the
feature-gating downgrade/restore mechanism, and the removal map (delete vs edit vs keep).
All `file:line` references are against branch `master`, commit `9fadf36b`. Diagrams use only simple
ASCII node labels so they render in any Mermaid viewer.
---
## 1. Overall application architecture & subsystem relationships
```mermaid
flowchart TD
main["src/main.swift<br/>CLI fast-path, signal/exception handlers<br/>(PAYWALL-FREE)"]
main -->|App.shared.run| app["src/App.swift<br/>App : AppCenterApplication<br/>NSApplicationDelegate"]
app -->|phase A| phaseA["applicationDidFinishLaunching<br/>App.swift:435-463<br/>logging, Preferences, license wiring,<br/>permission-poll timer"]
phaseA -->|polls until granted| perms["src/macos/SystemPermissions<br/>Accessibility + Screen Recording"]
perms -->|"continueAppLaunchAfterPermissionsAreGranted (SystemPermissions.swift:77)"| phaseB["phase B<br/>App.swift:383-431<br/>threads, panels, menubar,<br/>hooks, Sparkle"]
phaseB --> switcher["Switcher UI<br/>src/switcher/<br/>TilesPanel, PreviewPanel, Windows"]
phaseB --> prefs["Preferences + Settings<br/>src/preferences/"]
phaseB --> events["Event hooks<br/>src/events/, KeyboardEvents,<br/>AccessibilityEvents, RunningApps"]
phaseB --> macos["src/macos/<br/>AXCallScheduler, LoginItem<br/>(PAYWALL-FREE)"]
phaseB --> bg["BackgroundWork<br/>run-loop threads + queues<br/>(PAYWALL-FREE)"]
phaseB --> menubar["src/Menubar.swift<br/>status item + menu"]
app -. license callbacks .-> pro["src/pro/ PAYWALL OVERLAY"]
menubar -. Get Pro / badge dot .-> pro
switcher -. ProFeature.attemptUse .-> pro
prefs -. PreferenceDefinition gating .-> pro
subgraph pro["src/pro/ PAYWALL OVERLAY"]
lic["license/<br/>LicenseManager, RemoteLicenseClient,<br/>Keychain, MachineFingerprint"]
sched["scheduling/<br/>ProTransitionManager + Scheduler,<br/>Day1..Day35 windows"]
feat["ProFeature.swift<br/>capability registry"]
ui["ui/<br/>ProPromptHost, ProBadgeView,<br/>ProGradientButton, UsageStatHeroView"]
feat --> sched
sched --> ui
lic --> sched
end
api["src/api/Endpoints.swift"] -.-> lic
sparkle["Sparkle auto-update<br/>SparkleDelegate"] --> phaseB
appcenter["AppCenter crash reporting<br/>src/vendors/"] -.-> app
```
The app boots from a plain top-level `src/main.swift` (no `@main`), which calls `App.shared.run()`.
`App.swift` is the spine and uses a deliberate two-phase launch: phase A wires logging, preferences,
the license callbacks, and a permission-poll timer; only once Accessibility + Screen-Recording
permissions pass does `SystemPermissions` call back into phase B, which stands up every subsystem and
installs the macOS hooks. The switcher, events, `src/macos/`, and `BackgroundWork` are entirely
paywall-free; the paywall (`src/pro/`) is grafted on through callbacks wired in `App.swift` and
`Menubar.swift`, plus a handful of gate call-sites in the switcher and preferences. The dotted arrows
are the only couplings a removal must sever.
---
## 2. License activation + state flow
```mermaid
sequenceDiagram
actor User
participant App as App.swift
participant LM as LicenseManager.shared
participant API as RemoteLicenseClient
participant Remote as alt-tab.app/api/v1/license
participant KC as Keychain + UserDefaults
participant UI as Menubar / Settings / Gating
Note over App,LM: App launch (phase A)
App->>LM: initialize() (App.swift:460)
LM->>LM: computeState()<br/>seeds trialStartDate on first launch
LM-->>UI: onStateChanged(state) fan-out (App.swift:449-459)
Note right of UI: refreshLicenseMenuItems, syncLicenseCookie,<br/>ProTransitionManager.onLicenseStateChanged,<br/>UpgradeTab.refreshStatus, proLockStateDidChange
Note over User,App: Activation via alt-tab://activate?license_key=...
User->>App: open URL (App.swift:473-485)
App->>LM: activate(licenseKey)
LM->>API: api.activate(key)
API->>Remote: POST /activate<br/>{license_key, fingerprint, trial_started_at}
Remote-->>API: {activated, instance_id, variant_id, customer_email}
API-->>LM: ActivateResult
alt activated == true
LM->>KC: all-or-nothing write<br/>licenseKey, instanceId, variantId<br/>(rollback on any failure)
LM->>KC: lastValidation, lastValidationResult=true, customerEmail
LM->>LM: onBeforeProUnlock() then state = .pro
LM-->>UI: onStateChanged(.pro) (gates open)
else invalid_key / seat_limit_exceeded / rejected
LM-->>UI: LicenseAPIError (state untouched)
end
Note over LM,Remote: Background revalidation throttled to 30 days
LM->>API: revalidateWithServer() (if elapsed >= 30d)
API->>Remote: POST /validate {license_key, instance_id}
Remote-->>LM: {valid} -> .pro or .trialExpired
```
`LicenseManager.shared` is the single source of truth for entitlement and computes a flat 4-case
`LicenseState` (`.trial`, `.pro`, `.proExpired`, `.trialExpired`). At launch `initialize()` computes
state (seeding a 14-day `trialStartDate` on first run) and fans out through `onStateChanged`.
Activation arrives via the `alt-tab://activate` URL scheme (or the Settings Upgrade tab), POSTs to
`alt-tab.app/api/v1/license/activate` with the machine fingerprint, and on success performs an
all-or-nothing Keychain write (with rollback) before flipping state to `.pro`. A throttled 30-day
background revalidation re-checks the license. The whole remote/Keychain layer feeds exactly one
downstream signal the rest of the app consumes: `isProLocked` / `isProAvailable`.
---
## 3. The Day1 -> Day35 trial-nag escalation
```mermaid
stateDiagram-v2
[*] --> Day1
note right of Day1
SOFT NAGS = informational, never block.
Each fires once, gated by a hasSeen* flag.
Prompts only fire 10:00-11:30 or 15:30-17:00.
end note
Day1: Day 1 - [A] Welcome Letter (SOFT)
Day1: Fires immediately on first launch; blocks others until seen
Day4: Day 4 - [H] Tour Popover (SOFT)
Day4: Only if switcher opened on Day 4 exactly
Silent: Days 5-11 silent trial
Day12: Day 12 - [B] Heads-Up Popover (SOFT)
Day12: "Trial ends in 2 days"; skipped on Day 13+
Badge: Days 13-14 - menubar badge dot (SOFT)
Expiry: Day 15 - trial expires -> HARD GATE ARMS
Expiry: onProLockEngaged downgrades degradable prefs to Free,<br/>snapshots Pro values into remembered*
Proactive: Day 15+ - [D] Proactive Window (SOFT)
Proactive: Only if no hard gate fired yet
FreePass: First post-expiry switcher open -> one-shot Free Pass
FullUpgrade: [C] Full Upgrade Window (HARD - lock-in)
FullUpgrade: Sets hasSeenFullUpgrade; once-ever
HardGate: [E] Hard-Gate Popover (HARD)
HardGate: Every blocked feature attempt after [C], forever
Day21: Day 21-34 - [F] Reminder Popover (SOFT)
Day35: Day 35-48 - [G] Final Window (SOFT)
Day35: Has "No thanks - don't ask again" opt-out
Steady: Day 49+ - steady state
Steady: [E] on every hard-gate attempt; degradable prefs fall back
Day1 --> Day4
Day4 --> Silent
Silent --> Day12
Day12 --> Badge
Badge --> Expiry
Expiry --> Proactive
Expiry --> FreePass
FreePass --> FullUpgrade
Proactive --> FullUpgrade
FullUpgrade --> HardGate
Expiry --> Day21
Day21 --> Day35
Day35 --> Steady
HardGate --> Steady
Steady --> [*]
FullUpgrade --> Purchased
Purchased: Purchase -> .pro
Purchased: Scheduler cancelled, all windows dismissed, prefs restored
Purchased --> [*]
```
The trial-nag system (`src/pro/scheduling/`) escalates upsell prompts across a Day1→Day35 timeline,
driven by a pure decision struct (`ProTransitionManagerTestable`) and a persisted scheduler. The
**soft nags** ([A] Welcome, [H] Day4 Tour, [B] Day12 Heads-Up, [D] Day15 Proactive, [F] Day21,
[G] Day35, plus the Days13-14 badge dot) are purely informational and never block functionality. The
**hard gate** arms at Day 15 expiry: degradable preferences are immediately downgraded to their free
equivalents, and the three hard-gated features (extra shortcut slot, search, lock-search) are blocked
at use-time through a free-pass ladder that grants one last full session, then shows [C] Full Upgrade
once, then [E] Hard-Gate popover forever. Only a purchase clears the gate (cancelling the scheduler,
dismissing windows, and restoring remembered Pro prefs).
---
## 4. The feature-gating mechanism (downgrade on lock / restore on unlock)
```mermaid
flowchart TD
state["LicenseManager.state"] --> locked{"isProLocked?<br/>LicenseManager.swift:67-72<br/>(true for proExpired/trialExpired)"}
locked -->|"becomes true (lock)"| engage["ProTransitionState.onProLockEngaged()<br/>ProTransitionState.swift:73-79"]
engage --> snap["For each of 6 ProGatedPreferences:<br/>snapshot Pro index -> remembered* key,<br/>overwrite stored value with freeEquivalent"]
snap --> stored1["UserDefaults stored = Free value<br/>(style=thumbnails, size=medium,<br/>shortcutStyle=doNothingOnRelease)"]
locked -->|"becomes false (unlock/purchase)"| unlock["ProTransitionState.onProUnlocked()<br/>ProTransitionState.swift:85-92"]
unlock --> restore["Restore remembered* Pro index<br/>-> stored value (notify:false),<br/>clear remembered key"]
restore --> stored2["UserDefaults stored = Pro value"]
stored1 --> read["PreferenceDefinition.read()<br/>PreferenceDefinition.swift:32-44"]
stored2 --> read
read --> freepass{"isFreePassSessionActive?"}
freepass -->|yes| pro["return remembered Pro value<br/>(one-session preview)"]
freepass -->|"no + locked + stored still Pro"| free["return freeEquivalent"]
freepass -->|no| asis["return stored value"]
hard["Hard-gated features<br/>extraShortcut, search, lockSearch"] --> attempt["ProFeature.attemptUse()<br/>ProFeature.swift:74-83"]
attempt --> avail{"isProAvailable?"}
avail -->|yes| allow["return true (run)"]
avail -->|"no (expired)"| ladder["ProTransitionManager.attemptHardGatedFeature<br/>free-pass -> [C] -> [E] ladder"]
pro --> getters["Preferences.effective* getters<br/>(appearanceStyle/Size, shortcutStyle)"]
free --> getters
asis --> getters
getters --> switcher["TilesView / ShortcutAction render"]
```
The master gate is `LicenseManager.isProLocked` (true once trial or Pro expires). On the
false→true transition, `onProLockEngaged()` snapshots each of the six gated preferences' Pro index
into a `remembered*` key and overwrites the stored value with its free equivalent; on unlock,
`onProUnlocked()` restores the remembered Pro value (with `notify:false` to avoid bouncing). The
hot-path getter `PreferenceDefinition.read()` returns the remembered Pro value during an active
free-pass session, the free equivalent while locked-and-still-Pro, or the stored value otherwise.
Hard-gated runtime features have no backing preference and are gated at use-time by
`ProFeature.attemptUse()`. Crucially, the registered defaults already contain the Pro values, so
forcing `isProLocked = false` auto-unlocks every degradable feature without any default changes.
---
## 5. The REMOVAL MAP — delete vs edit vs keep
```mermaid
flowchart TB
subgraph DELETE["DELETE WHOLESALE - the paywall tree"]
direction TB
d1["src/pro/license/*<br/>LicenseManager, RemoteLicenseClient,<br/>Keychain, MachineFingerprint, LicenseCookie,<br/>LicenseAPI, Clock"]
d2["src/pro/scheduling/*<br/>ProTransitionManager + Scheduler + State + Testable,<br/>all Day1..Day35 windows/popovers"]
d3["src/pro/ProFeature.swift<br/>ProFeatureCopy.swift, ProConversionCopy.swift"]
d4["src/pro/ui/*<br/>ProPromptHost, ProGradientButton,<br/>UsageStatHeroView (ProBadgeView/ProGradient<br/>only AFTER Settings consumers gone)"]
d5["src/preferences/PreferenceDefinition.swift<br/>(entire gating engine)"]
d6["Tests: LicenseManagerTests, ProTransitionTests,<br/>ProBadgeViewSegmentTests, UsageStatsMessageTests"]
end
subgraph EDIT["EDIT IN PLACE - sever wiring, keep file"]
direction TB
e1["src/App.swift<br/>remove license block 448-460, onAction/onAppLaunchComplete<br/>428-429, switcher hooks 78/328, custom-URL handler 465-490,<br/>Day1Welcome first-launch entanglement 189-233"]
e2["src/Menubar.swift<br/>remove Get Pro/My Account items 46-50,<br/>UpgradeMenuItemView 235-390, refreshLicenseMenuItems 84-118,<br/>badge dot 202-227, refreshState in menuWillOpen 396"]
e3["src/preferences/Preferences.swift<br/>rewrite gated getters 129/130/155 +<br/>override getters 313/319/330 to read raw values"]
e4["src/switcher/ShortcutAction.swift:56<br/>src/switcher/main-window/TilesView.swift:79,92<br/>remove attemptUse gates"]
e5["src/events/PreferencesEvents.swift:62-64<br/>remove isProLocked/isStoredValuePro bounce"]
e6["Settings tabs: AppearanceTab, ControlsTab,<br/>ShortcutEditor, ShortcutsWhenActiveSheet,<br/>LabelAndControl - strip proGatedIndices + ProBadge"]
e7["SettingsWindow.swift - remove UpgradeButton 133-214,<br/>showUpgradeView/hideUpgradeView, refreshUpgradeButton,<br/>windowDidBecomeKey license refresh; SidebarList setProBadge"]
e8["UpgradeTab.swift - DELETE tab; remove navigateToUpgradeTab callers"]
e9["PreferencesMigrations.swift:20<br/>remove markFreshInstallIfUnknown call"]
e10["DebugProfile.swift:17 - drop .debugProfileLabel line<br/>(keep file; feeds feedback)"]
e11["QAMenu.swift:170-241<br/>remove DEBUG Day-X triggers/resets"]
e12["alt-tab-macos-Bridging-Header.h + Info.plist<br/>NSPrincipalClass + alttab:// URL scheme<br/>(coordinate with AppCenter/identity decision)"]
e13["alt-tab-macos.xcodeproj/project.pbxproj<br/>remove ~102 in-Sources entries + fileRef/group<br/>for every deleted src/pro file (app + test UUIDs)"]
end
subgraph KEEP["KEEP UNTOUCHED - paywall-free"]
direction TB
k1["src/main.swift (entry point)"]
k2["src/macos/* (SystemPermissions,<br/>AXCallScheduler, LoginItem)"]
k3["BackgroundWork (threads/queues)"]
k4["src/switcher kernels (SelectionResolver,<br/>WindowFilterResolver, etc.) + Windows/Window"]
k5["src/events hooks (Keyboard, Accessibility,<br/>RunningApplications) minus the few gate lines"]
k6["CachedUserDefaults / index / macroPref plumbing"]
k7["Sparkle wiring (repoint feed/key separately)"]
end
DELETE -. "deleting these breaks compile until EDIT done" .-> EDIT
EDIT -. "must compile against" .-> KEEP
classDef del fill:#ffd6d6,stroke:#c0392b,color:#7b1f1f;
classDef edt fill:#fff3cd,stroke:#d4a017,color:#7a5c00;
classDef kp fill:#d6f5d6,stroke:#27ae60,color:#145a32;
class d1,d2,d3,d4,d5,d6 del;
class e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13 edt;
class k1,k2,k3,k4,k5,k6,k7 kp;
```
This is the money diagram for the removal plan. **Red = delete wholesale**: the entire `src/pro/`
tree (license, scheduling, ProFeature, copy, UI primitives) plus `PreferenceDefinition.swift` and the
paywall test files. **Yellow = edit in place**: files that survive but must have their paywall wiring
severed — most are surgical (a handful of lines in `App.swift`, the switcher gates, the preference
getters), but `Menubar.swift`, `SettingsWindow.swift`, and the Settings tabs need real surgery to
strip the upsell UI, and `project.pbxproj` needs every deleted file's build-file/group/sources
entries removed or the project won't even parse. **Green = keep untouched**: the entry point,
`src/macos/`, `BackgroundWork`, the switcher kernels, the event hooks, and the `CachedUserDefaults`
plumbing are all verified paywall-free. The ordering constraint is critical: the deletes break the
build at compile time, so the edits (severing every consumer of `LicenseManager`, `LicenseState`,
`ProFeature`, `ProGatedPreferences`, `ProBadgeView`, and `ProGradientButton`) must land in the same
change set. The lowest-risk first step before any deletion is to force `isProLocked = false` /
`isProAvailable = true`, which turns every gate into a pass-through and lets defaults auto-unlock.
File diff suppressed because it is too large. Load diff
+300
View File
@@ -0,0 +1,300 @@
# Plan: Republish a Fully-Free, Paywall-Free AltTab Fork
> **Status:** actionable plan derived from the deep-audit sections in `docs/audit/01-*.md … 09-*.md` and the completeness-critic verdict. Read those sections for full per-file detail; this document is the execution plan that sits on top of them.
>
> **Scope reminder (from `AGENTS.md`):** pure Swift 5.8, no SwiftUI, no Interface Builder. Compile-check after every change with `ai/build.sh`.
---
## A. Licensing & Ethics (read this first — it constrains everything below)
### What the license actually is
- AltTab is **GPL-3.0** (`LICENCE.md` — verbatim GNU GPL v3, "Copyright (C) 2007 Free Software Foundation").
- The paywall overlay (everything under `src/pro/`, plus the integration call-sites in `src/App.swift`, `src/Menubar.swift`, `src/preferences/…`) was added **upstream by the original author lwouis in a single commit** `9147a4a8 "feat: introducing alt-tab pro!"` (v11.0.0, 2026-04-05) — see audit section 09. Because it was added on top of GPL-3.0 code and links against it, the paywall code is itself a **derivative work and therefore also GPL-3.0**. There is no separately-licensed proprietary blob here.
- **Consequence:** GPL-3.0 explicitly grants you the right to modify and redistribute, *including removing the gating*. You may delete the paywall and ship the result.
### What you MUST do (GPL-3.0 obligations)
1. **Offer the complete modified source under GPL-3.0.** Keep `LICENCE.md` as-is. Publish your fork's full source (you already are — public GitHub repo).
2. **Preserve upstream copyright and attribution.** Do **not** remove copyright headers, the GPL notice, `LICENCE.md`, or `docs/contributors.md` / `docs/acknowledgments.md`. Keep a clear "based on AltTab by Louis Pontoise (lwouis/alt-tab-macos), GPL-3.0" statement in your README and About box.
3. **State your changes.** GPL §5(a): mark the files you changed and the dates. A `CHANGELOG`/`NOTICE` entry ("forked from v11.x; removed the Pro/trial/license system; all features unlocked") satisfies this.
4. **Pass the same freedoms downstream.** Your fork must remain GPL-3.0 — you cannot re-close it.
### What you MUST NOT do
- **Do not claim original authorship.** This is a fork; credit lwouis prominently.
- **Do not strip the GPL or attribution** (see above) — that would terminate your license under GPL §8.
- **Do not reuse the original's trademarks / app name / icon / branding in a confusing way.** "AltTab", the AltTab icon, and the `alt-tab.app` brand are the upstream project's identity. Copyright license ≠ trademark license. **Rename the app and replace the icon** (see Section D). Shipping a binary still called "AltTab" with the same icon but a different signer invites both trademark confusion and user-trust problems.
- **Do not impersonate the paywalled product's identity.** Do **not** reuse the upstream **Developer ID** (`Developer ID Application: Louis Pontoise (QXD7GW8FHY)`, `config/release.xcconfig:5`) — you cannot sign with it and must not try. Do **not** reuse the bundle id `com.lwouis.alt-tab-macos`, the Sparkle public key, the `alt-tab.app` license/feedback/appcast endpoints, or the AppCenter app slug. These are operationally tied to lwouis's accounts and you do not control them.
- **Do not point your auto-updater at upstream's appcast / GitHub release downloads** — that would cross-feed updates between the two products and is both a technical and an identity problem.
**Net:** removing the gating and republishing is *legal and in the spirit of GPL-3.0*. The hard requirements are (a) keep it open under GPL-3.0 with attribution, and (b) ship under a **new identity** (name, icon, bundle id, Developer ID, update feed, endpoints).
---
## B. Removal Strategies & Recommendation
### Strategy 1 — "Surgical force-unlock" (smallest diff)
Make the gate always open and neutralize the nag scheduler, leaving the paywall code physically present but inert.
- `LicenseManager.isProLocked` → always `false`; `isProAvailable` → always `true` (audit 03/04: gate lives at `src/pro/license/LicenseManager.swift:67-72`). Hardcode `state = .pro`.
- `ProFeature.attemptUse()` becomes a pass-through (`src/pro/ProFeature.swift:74-83`).
- `PreferenceDefinition.read()` returns the stored value unconditionally (`src/preferences/PreferenceDefinition.swift:32-44`); defaults already hold the Pro values (audit 03), so features unlock with no default changes.
- Stub `ProTransitionManager.onSwitcherShown/onSwitcherDismissed/onAppLaunchComplete` to no-ops to kill nags (`src/App.swift:78,328,429`).
**Pros:** ~10–20 line diff, lowest compile risk, fastest, no Xcode-project surgery.
**Cons:** Dead paywall code ships in the binary; **live remote/telemetry references remain** — license API client, `LicenseCookie` writing a tier cookie to `alt-tab.app` on every state change (`src/App.swift:451`), `RemoteLicenseClient` POSTs (`src/pro/license/RemoteLicenseClient.swift`), machine-fingerprint code (`src/pro/license/MachineFingerprint.swift`). For a *genuine free republish* this is unacceptable: it still phones the upstream paywall backend and leaks a per-machine fingerprint. Also still ships under the upstream identity unless you separately do Section D. **Not recommended as the end state.**
### Strategy 2 — "Full excision" (delete `src/pro/` and untangle) **← RECOMMENDED**
Delete the entire `src/pro/` tree, remove every integration call-site, rewrite the gated preference getters to read raw values, remove the upsell UI from `App.swift` / `Menubar.swift` / `SettingsWindow.swift`, drop the license/cookie/fingerprint network code, fix the Xcode project file and the tests.
**Pros:** Truly free; no dead paywall code; no license API, no tier cookie, no machine fingerprint, no Day-X nag windows. The binary is honestly "all features, no strings."
**Cons:** Larger, riskier change touching ~35 source files plus `alt-tab-macos.xcodeproj/project.pbxproj` (~102 in-Sources entries) and several test files. Build-break risks are real and enumerated in Section C/E.
### Strategy 3 — "Rebase onto pre-paywall / current upstream" (cleanest of all, different shape)
Take **upstream `lwouis/alt-tab-macos`** at a point you want (either pre-paywall `v10.12.0` = commit `317a485b`, or current `master` *minus* the `src/pro/` commit) and cherry-pick only the genuinely-free fork features you care about.
**Pros:** You never have to extract the paywall from this snapshot at all — you start from a clean, paywall-free tree (pre-v11) or a tree where you simply never merge the Pro commit. Lowest *long-term* maintenance because you track upstream directly.
**Cons:** audit 09 confirms this repo has **zero fork-owner commits** — every commit is lwouis or `semantic-release-bot`. So there are effectively **no unique fork features to carry over**; the only delta from upstream *is* the paywall. Rebasing on `v10.12.0` loses all post-v11 fixes unless cherry-picked; rebasing on current upstream-minus-Pro is essentially Strategy 2 done via git topology instead of file deletion. It also still requires the full Section D re-identity work.
### Recommendation
**Adopt Strategy 2 (full excision) as the deliverable, but use Strategy 1 as an intermediate checkpoint.** Concretely:
1. First land Strategy 1 (force-unlock) as a *temporary* commit so you have a known-good, fully-unlocked, compiling build to A/B against.
2. Then perform the full excision on top of it, verifying the build stays green at each phase (Section C).
3. Do Section D (re-identity) in the same release.
Strategy 3 is the right call **only** if you would rather track upstream long-term and re-apply removal as a maintained patch set — given there are no unique fork features, that is a reasonable alternative, but it does not save the re-identity work and loses the newer fixes if you go to `v10.12.0`. For a one-shot "free AltTab" republish from *this* snapshot, full excision is the most honest result and keeps the current v11.x fixes.
---
## C. Step-by-Step Execution (Strategy 2, full excision)
> **Golden rule:** after **every** numbered step, run `ai/build.sh` (Debug) and do not proceed until it compiles. Deleting `src/pro/` before its consumers are rewritten is a guaranteed hard break (the completeness critic lists the exact symbols). The ordering below removes *consumers first*, then the *toolkit*, then the *files*, then the *Xcode refs*, then the *tests*.
### Phase 0 — Safety net
- Branch off `master`. Optionally land the Strategy-1 force-unlock commit first (Section B) to get a fully-unlocked baseline you can diff behavior against.
- Confirm the Debug build is green before touching anything: `ai/build.sh`.
### Phase 1 — Open the gates in place (no deletions yet)
Goal: make every feature live and stop all nags while all Pro symbols still exist, so the build stays green.
1. `src/pro/ProFeature.swift:74-83` — `attemptUse()` returns `true` unconditionally (remove the `isFreePassSessionActive` short-circuit at `:76` and the `attemptHardGatedFeature` call at `:79`).
2. `src/preferences/PreferenceDefinition.swift:32-44` — `read()` returns the stored value unconditionally (drop the free-pass and isProLocked branches).
3. `src/preferences/Preferences.swift` — verify the three gated getters (`:129` appearanceStyle, `:130` appearanceSize, `:155` shortcutStyle) and the three index-0 overrides (`:313, :319, :330`) now return Pro values; defaults already hold them (audit 03).
4. `src/preferences/settings-window/tabs/controls/ControlsTab.swift:589-592` — remove the 1-shortcut cap; `:515` remove the `index>=1` Pro badge.
**Verify:** build green; manually confirm extra shortcuts, in-switcher search, App-Icons/Titles styles, and Auto size all work (audit 06 lists these four advertised features).
### Phase 2 — Sever the App.swift wiring
Edit `src/App.swift`, removing only the Pro lines (audit 01/05 enumerate them):
5. Remove the trial-nag hooks: `:78` (`onSwitcherDismissed`), `:328` (`onSwitcherShown`), `:428` (`onAction = ProPromptHost.shared.dispatch`), `:429` (`onAppLaunchComplete`).
6. Remove the license callback block `:448-460` (`onBeforeProUnlock`, the `onStateChanged` fan-out, and `LicenseManager.shared.initialize()`). Keep `resetPreferencesDependentComponents` (`:51-53`) — it is used elsewhere; only drop the Pro caller. Drop the `proLockStateDidChangeNotification` post (`:458`).
7. Remove the custom-URL activation handler wholesale: `application(_:open:)` + `handleCustomUrl` (`:465-490`) — it exists only for `alttab://activate`.
8. Remove the menubar action selectors/methods: `:25-27` selectors, `:111-121` (`upgradeToPro`, `openAccount`; **decide** whether to keep `supportProject` — it is a donation link, not paywall, audit 01/07).
9. Simplify first-launch: `willShowDay1WelcomeOnAppLaunch` (`:205-208`) and the deferral observer (`:210-220`) reference `Day1WelcomeLetterWindow` and `hasSeenWelcome`. Replace with an unconditional `showAndCenterSettingsWindowOnFirstLaunch`. **Risk (audit 01):** if you delete the welcome window but leave the `willClose` observer, Settings never shows on first launch — remove both together.
**Verify:** build green. `App.swift` now references no `ProTransitionManager`/`LicenseManager`/`ProPromptHost` symbols.
### Phase 3 — Strip the Menubar upsell
Edit `src/Menubar.swift` (audit 07):
10. Delete the 3 license item vars (`:8-10`), the Get-Pro / My-Account / (optionally Support) item adds (`:46-49`), the `UpgradeMenuItemView` assignment (`:47`), and the `refreshLicenseMenuItems` call (`:50`).
11. Delete `refreshLicenseMenuItems` (`:84-107`) and `toggleUpgradeMenuItem` (`:109-118`).
12. Delete the `UpgradeMenuItemView` class (`:235-390`) — its only consumer was `:47`. **Note (critic):** `updateContent(_ state: LicenseState)` (`:357`) hard-depends on the `LicenseState` enum; it dies with this class, which is what lets you delete `LicenseState` later.
13. Delete `badgeDotLayer` (`:187`) and `updateBadgeDotOverlay` (`:202-227`), and remove its call inside `loadPreferredIcon` (`:196`). This severs Menubar's dependency on `ProTransitionManager.shouldShowBadgeDot`.
14. In `menuWillOpen` (`:392-399`) drop `LicenseManager.shared.refreshState()` (`:396`) but **keep** `refreshPermissionCallout()` (`:397`) — non-pro.
15. `showPopoverFromMenubar` (`:229-232`) becomes dead once Day-X popovers go; remove it. **Keep** `menubarIconCallback` (`:155-164`) — also used by PreferencesEvents/QAMenu.
**Verify:** build green. The menu now matches the upstream non-pro item set (Show / Settings / Updates / Permissions / About / Feedback / Quit).
### Phase 4 — Strip Settings-window license entanglement (the critic's biggest miss)
Edit `src/preferences/settings-window/SettingsWindow.swift` (completeness critic):
16. Delete the `UpgradeButton` class (`:133-214`, a `ProGradientButton` subclass reading `LicenseManager.state`/`.isLifetimeVariant`/`.customerEmail`).
17. Delete the `upgradeButton` instance (`:303`) and its state (`:308-311` `upgradeContentView`/`isShowingUpgradeView`/`upgradeViewBottomConstraint`).
18. Delete `setupUpgradeButton` + constraints + `upgradeButtonClicked` (`:401, :503, :507-526`).
19. Delete `showUpgradeView`/`hideUpgradeView` (`:1066, :1122-1161`) which embed `UpgradeTab.initTab`.
20. Delete `refreshUpgradeButton` (`:1163-1165`) — was called from `App.swift:454` (removed in Phase 2) and `UpgradeTab:214`.
21. In `windowDidBecomeKey` (`:1243-1254`) remove `LicenseManager.refreshState` + `UpgradeTab.refreshStatus` + `playShineAnimation`; in `windowWillClose` remove `UpgradeTab.cleanup` (`:1266`).
22. Remove `refreshEmailTooltip` / `hasSecondLine` license reads (`:196, :206-207`).
23. Remove the settings-search "Pro" registration (`:679-680`, registers `ProBadgeView` → "Pro" string).
Edit `src/preferences/settings-window/SidebarList.swift` (critic):
24. Remove `private var proBadge: ProBadgeView?` (`:93`) and `setProBadge` (`:244-258`).
Edit the tabs (audit 03):
25. `AppearanceTab.swift` — remove the `proLockStateDidChange` observer (`:414-419`), the `proGatedAppearanceStyleIndices` args (`:462, :700-703`), the `ProBadge.attach` calls (`:463, :481, :575, :688-698`), the `wrapShortcutStyleProLockIntercept` (`:585-598`) and `wrapAppearanceSizeProLockIntercept` (`:662-679`), and `refreshProLockUi` (`:705+`).
26. `ShortcutEditor.swift` — remove `proGatedIndices` args (`:429, :437, :449, :459`) and the locked intercepts (`:599-607, :705-711`).
27. `ControlsTab.swift` — remove the `proLockStateDidChange` observer (`:141`) (cap + badge already removed in Phase 1).
28. `ShortcutsWhenActiveSheet.swift` — remove the ProBadge on search / lock-search rows (`:25, :51, :54, :63-69`).
29. `LabelAndControl.swift` — remove the `proGatedIndices` param and the `isProLocked` intercept from `makeImageRadioButtons` (`:74-116`, esp. `:78, :86-92`).
30. `src/events/PreferencesEvents.swift:62-64` — delete the "bounce a Pro-valued write to the Upgrade tab" block (depends on `ProFeature.isStoredValuePro`).
**Verify:** build green. No file outside `src/pro/` now references `ProBadgeView`, `ProGradientButton`, `ProGradient`, `LicenseManager`, `LicenseState`, `ProTransitionManager`, `ProFeature`, `UpgradeTab`, or `proLockStateDidChangeNotification`. Grep to confirm:
```
grep -rn -e ProBadgeView -e ProGradient -e LicenseManager -e LicenseState \
-e ProTransitionManager -e ProFeature -e UpgradeTab -e proLockStateDidChange \
--include=*.swift src | grep -v '^src/pro/'
```
This grep returning empty (modulo the test files handled in Phase 7) is the gate for Phase 5.
### Phase 5 — Rewrite gated preference getters to be self-contained, then prepare deletion
31. `src/preferences/Preferences.swift` — rewrite the 3 gated getters (`:129, :130, :155`) and the 3 index-0 override branches (`:313, :319, :330`) to read raw values via `CachedUserDefaults.macroPref(...)` instead of `ProGatedPreferences.*.read()`. Remove `overrideRememberedKey` + the `ProTransitionState.setInt` cleanup in `removeOverride` (`:282-298`).
32. `src/preferences/PreferencesMigrations.swift:20` — remove the `ProTransitionState.markFreshInstallIfUnknown` call (the only paywall coupling in migrations).
33. (Optional, in-place-upgrade only) If you ship under the **same** bundle id, add a one-time migration that copies any `proTransition.remembered*` indices back to the base keys before you stop reading them, else users who passed trial expiry on the paywalled build silently lose their prior Pro selections (audit 03 risk). **If you ship a new bundle id (recommended, Section D), this is moot** — clean UserDefaults domain.
**Verify:** build green. `src/pro/` is now referenced only by itself + tests.
### Phase 6 — Delete `src/pro/` and fix telemetry/endpoints
34. Delete the entire `src/pro/` directory (verified contents):
- `src/pro/license/` — `Clock.swift`, `Keychain.swift`, `LicenseAPI.swift`, `LicenseCookie.swift`, `LicenseManager.swift`, `LicenseManagerSpecs.md`, `LicenseManagerTests.swift`, `LicenseState.swift`, `MachineFingerprint.swift`, `RemoteLicenseClient.swift`
- `src/pro/scheduling/` — all `Day*.swift` (Day1/4/12/15×3/21/35), `ProTransitionManager.swift`, `ProTransitionManagerTestable.swift`, `ProTransitionScheduler.swift`, `ProTransitionState.swift`, `ProTransitionTests.swift`, `ProTransitionSpecs.md`
- `src/pro/ui/` — `ProBadgeView.swift`, `ProBadgeViewSegmentTests.swift`, `ProBadgeViewSegmentSpecs.md`, `ProGradientButton.swift`, `ProPromptHeader.swift`, `ProPromptHost.swift`, `ProPromptPopover.swift`, `ProPromptWindow.swift`, `UsageStatHeroView.swift`
- `src/pro/ProFeature.swift`, `src/pro/ProConversionCopy.swift`, `src/pro/ProFeatureCopy.swift`
35. Delete `src/preferences/PreferenceDefinition.swift` entirely (the gate engine; getters were rewritten in Phase 5).
36. Delete the Upgrade tab `src/preferences/settings-window/tabs/UpgradeTab.swift` (it contains `ProHeroButton: ProGradientButton` at `:493`, the `usageHero`/`heroButton` plumbing `:5-6, :37-38, :160-161`, and the full `activateLicense`/`deactivateLicense`/`deactivateInstance` + `LicenseAPIError.seatLimitExceeded` UI `:322-405` — critic). Remove it from the Settings tab list/registration.
37. **Endpoints/cookie/fingerprint** (`src/api/Endpoints.swift`): remove `checkoutUrl` (`:9`), `accountUrl` (`:10`), `licenseApiBaseUrl` (`:11`). Keep `appcastUrl` and `supportUrl`; keep or repoint `feedbackUrl` (`:12`) per Section D. The `LicenseCookie`, `RemoteLicenseClient`, `MachineFingerprint` files are already gone with `src/pro/license/`.
38. **`UsageStats`** (`src/util/UsageStats.swift`, `UsageStatsTestable.swift`, `UsageStatsMessageTests.swift`): local-only, no network (audit 09). Its only *paywall* consumers were `ProConversionCopy`/`UsageStatHeroView`, now deleted. You may keep it (the neutral `App.swift` recording / AboutTab display still compile) or delete it; deleting also requires removing `UsageStatsMessageTests.swift` from the test target.
39. **QA/Debug menu** `src/debug/QAMenu.swift:170-241` (audit 05): directly instantiates every Day-X window and pokes manager flags. Remove those manual triggers/resets or the DEBUG build won't compile.
40. **DebugProfile** `src/secondary-windows/DebugProfile.swift:17` reads `LicenseManager.shared.state.debugProfileLabel` (the extension lived at `src/pro/license/LicenseState.swift:14`). Since DebugProfile feeds the (kept) Feedback report, **hand-edit** — drop the License line, do not delete the file (critic).
41. **AppCenter telemetry** (audit 08/09) — remove it (most privacy-aligned for a free build; AppCenter is also EoL):
- delete `src/vendors/AppCenterCrashes.swift` and references in `src/App.swift` (`import`/`AppCenterApplication` superclass at `App.swift:7`/start call).
- **Principal class break (critic):** `Info.plist:36-37` `NSPrincipalClass = AppCenterApplication`, the `class App: AppCenterApplication` superclass, and `alt-tab-macos-Bridging-Header.h:1` import are coupled. Replace the superclass with `NSApplication` and set `NSPrincipalClass` to `NSApplication` (or your own subclass), and remove the bridging-header import — or the app won't launch *and* won't compile.
- remove `Secrets.appCenterSecret` usage (`src/api/Secrets.swift`), `Info.plist` `AppCenterSecret`/forwarder keys, and the `Package.swift` AppCenter deps.
- keep `DebugProfile.make()` if Feedback stays (it is shared); only the crash-attachment call site goes away.
**Verify:** build green.
### Phase 7 — Xcode project file + tests (the mechanical part — do not skip)
42. **`alt-tab-macos.xcodeproj/project.pbxproj`** (critic): every deleted file has a `PBXBuildFile` + `PBXFileReference` + `PBXGroup` child + `PBXSourcesBuildPhase` membership (~102 in-Sources pro entries; app phase ~line 1830, test phase ~1902; `PreferenceDefinition.swift` at ~1979). Note **`Clock`, `Keychain`, `LicenseAPI`, `MachineFingerprint`, `ProTransitionManagerTestable` have TWO build-file UUIDs (app + test)** — remove **both**. Any file deleted on disk but still referenced makes the project fail to parse/link. The cleanest way to do this safely is to let Xcode reconcile, but since `AGENTS.md` says don't develop in Xcode, edit `project.pbxproj` by hand and verify with `xcodebuild -list` / `ai/build.sh` after.
43. **Tests** (critic): remove/repair test-target members that reference vanished symbols — `LicenseManagerTests`, `ProTransitionTests`, `ProTransitionManagerTestable`, `ProBadgeViewSegmentTests`, and (if you deleted UsageStats) `UsageStatsMessageTests`. In `src/_test-support/Mocks.swift` remove the `ProBadgeView` Symbols stub and the `ShortcutStylePreference` mock, and update the hardcoded bundle id (`Mocks.swift:133`, `com.lwouis.alt-tab-macos`) to the new id. `PreferencesMigrationsTests.swift:356` has a *self-contained local stub* `ProTransitionState` (won't break on deletion), but the real `PreferencesMigrations.swift:20` call you removed in Phase 5 is what mattered.
**Verify:** Test scheme passes:
```
scripts/run_tests.sh # Test scheme, Release config (audit 08)
```
### Phase 8 — Final compile + behavior pass
44. `ai/build.sh` (Debug) green; `scripts/build_app.sh` (Release scheme) green; `scripts/run_tests.sh` green.
45. Manual smoke test (Section E checklist): permissions flow, switcher show/hide, all four previously-Pro features, multiple shortcuts, Settings opens with no Upgrade tab / no Get-Pro item / no badge dot, no `alttab://` handler, no network call to `alt-tab.app/api`.
---
## D. Re-Identity & Publish
> Per `AGENTS.md`, app identity (Developer ID, TeamID, bundle id) and Keychain items are coupled to the code signature. **For the free build this invariant is effectively MOOT (audit 08/09):** once `src/pro/license/Keychain.swift` is deleted there are no stored license items to orphan, so rebranding the bundle id is safe. But the identity change itself is **mandatory** — you cannot sign with upstream's Developer ID.
### Identity
- **Bundle id:** change `com.lwouis.alt-tab-macos` → your reverse-DNS (e.g. `app.koftwentytwo.alt-tab-free`). Locations: `config/base.xcconfig:4`; unit-test bundle id in `project.pbxproj:2477/2542`; hardcoded `Mocks.swift:133`.
- **App name / `PRODUCT_NAME`:** rename away from "AltTab" (trademark — Section A). Update `config/base.xcconfig`, README, and the About box (`App.repository`, `src/App.swift:16`).
- **Icon:** replace the AltTab icon with your own (trademark + brand identity).
- **TeamID / Developer ID:** `DEVELOPMENT_TEAM = "${TEAM_ID}"` currently expands to empty; signing is driven by `CODE_SIGN_IDENTITY` (`config/release.xcconfig:5`) = the upstream `Developer ID Application: Louis Pontoise (QXD7GW8FHY)`. **Replace with your own Developer ID Application cert + TeamID.** The CI cert secret `$APPLE_P12_CERTIFICATE` (`scripts/codesign/setup_ci_master.sh`) must be your P12. Notarization Apple-ID/password/team (`ci_cd.yml:9-11`, `scripts/package_and_notarize_release.sh`) must be your account.
### Auto-update (Sparkle) — must repoint or you can't ship updates
- Feed URL `Endpoints.appcastUrl` = `https://<DOMAIN>/appcast.xml`, `DOMAIN=alt-tab.app` (`config/base.xcconfig:20`). **Repoint `DOMAIN`** to a host you control, or serve the committed `appcast.xml` from your own GitHub Pages / raw URL.
- **Generate a NEW Sparkle EdDSA keypair.** Replace `SUPublicEDKey` (`Info.plist:62`, currently `2e9SQOBoaKElchSa/4QDli/nvYkyuDNfynfzBF6vJK4=`) and the CI signing secret `$SPARKLE_ED_PRIVATE_KEY` (`update_appcast.sh:9`). Public and private **must match** or updates fail verification. You cannot reuse lwouis's key (you don't have the private half anyway).
- **Truncate/regenerate `appcast.xml`** (~3876 lines). Existing items are signed by upstream's private key and point at `github.com/lwouis/alt-tab-macos/releases/...` (`update_appcast.sh:18`). Leaving them risks cross-feeding updates between the two products — start a fresh feed for your fork's own releases.
- Re-vendor/re-sign `vendor/Sparkle/Helpers/Updater.app` + `Autoupdate` with **your** Developer ID (`copy_sparkle_helpers.sh` re-seals with `CODE_SIGN_IDENTITY`); a mismatch trips `codesign --verify --deep --strict`.
### Remove the license API + telemetry endpoints
- License API (`Endpoints.licenseApiBaseUrl`, `RemoteLicenseClient`) and the per-tier `LicenseCookie` are deleted in Phase 6 — confirm no remaining reference to `alt-tab.app/api/v1/license`.
- **AppCenter** removed in Phase 6 (Step 41). Decide explicitly: remove entirely (recommended) vs repoint to a self-owned AppCenter app (note: AppCenter is EoL, so removal is the durable choice).
- **Feedback** (`Endpoints.feedbackUrl` → `alt-tab.app/api/v1/feedback`, used `FeedbackWindow.swift:445`): its server turns the POST into a GitHub issue on **lwouis's** repo and is **not in this repo**. Either stand up your own endpoint and repoint, or remove the in-app feedback submitter. This is a *product decision*, flagged in audit 08/09.
- **Website repository-dispatch** (`update_website.sh:5` → `lwouis/alt-tab-website`, `$WEBSITE_DISPATCH_TOKEN`, `ci_cd.yml:67-69`) and the README-stats step hitting `api.github.com/repos/lwouis/alt-tab-macos` (`update_readme_and_website.sh:10`) must be removed or repointed to your repo. Update `.github/FUNDING.yml`.
### Distribution channel & notarization
- **Recommended:** GitHub Releases of *your* fork + Sparkle feed served from your domain or GitHub Pages. This mirrors the existing pipeline with minimal change once the URLs/keys above are yours.
- **Alternatively / additionally:** a Homebrew cask (`brew install --cask <your-fork>`), which still requires a notarized, stapled `.zip`/`.app`.
- **Notarization is mandatory** for Gatekeeper on modern macOS regardless of channel: sign with your Developer ID → `notarytool` submit (bundled `scripts/notarytool`, `scripts/package_and_notarize_release.sh`) with **your** `$APPLE_ID`/`$APPLE_PASSWORD`/`$APPLE_TEAM_ID` → `xcrun stapler staple` → re-zip.
- **Versioning:** releases are 100% `semantic-release` from Conventional Commits on `master` (`determine_next_version.sh` → CI-only `VERSION.txt` → `Info.plist`). `package.json` `1.0.0` is irrelevant. Your fork can keep this as-is once the secrets/URLs are yours, or reset the version line for a clean v1.
**Gating prerequisite (audit 08 open question):** you need your own Apple Developer account (Developer ID Application cert + notarization credentials) and a domain (or GitHub Pages) for the appcast + your own Sparkle EdDSA keypair **before** the first signed, self-updating release is possible.
---
## E. Risks, Testing, and Phased Checklist
### Top build-break risks (from the completeness critic — fix the consumer before deleting the type)
- **`LicenseState` enum** is referenced by non-pro `Menubar.swift:357` (`updateContent` param) and `DebugProfile.swift:17` (`.debugProfileLabel`). Handle in Phase 3/6 before deleting `src/pro/license/LicenseState.swift`.
- **`LicenseManager` singleton** is read by non-obvious non-pro sites: `SettingsWindow.swift:162,164,167,196,206-207,1246` and `UpgradeTab.swift:220-405`. All removed in Phase 4/6.
- **`ProGradientButton`** is the **superclass** of `UpgradeButton` (`SettingsWindow.swift:133`) and `ProHeroButton` (`UpgradeTab.swift:493`); `Menubar.swift:247` uses `ProGradient.makeLayer()`. Delete all subclasses/usages (Phase 3/4/6) before deleting the toolkit.
- **`ProBadgeView`** referenced by `SidebarList.swift:93,254`, `SettingsWindow.swift:679`, Appearance/Controls/ShortcutsWhenActiveSheet. Remove all (Phase 4) before deleting it.
- **`ProGatedPreferences`/`PreferenceDefinition.swift`** feeds `Preferences.swift:129,130,155` getters and is a **unit-test-target member** (`project.pbxproj:1979`) — a broken getter fails *app and test* compile. Rewrite getters (Phase 5) before deleting.
- **App superclass / principal class** (`App.swift:7`, bridging header, `Info.plist:36-37`) — removing AppCenter without replacing the principal class means the app won't launch *and* won't compile (Phase 6, Step 41).
- **`Day1WelcomeLetterWindow`** referenced in non-pro `App.swift:213`; the first-launch deferral observer (`:194-218`) must be simplified to always show Settings (Phase 2, Step 9) or compile breaks.
- **`project.pbxproj` integrity** — ~102 in-Sources entries + fileRef/group entries per deleted file; dual app+test UUIDs on Clock/Keychain/LicenseAPI/MachineFingerprint/ProTransitionManagerTestable must **both** go (Phase 7).
### Behavioral / product risks
- **In-place upgrade data loss** (audit 03): if you keep the same bundle id, users past trial-expiry have downgraded stored prefs with the Pro index parked in `proTransition.remembered*` (in the `<bundleId>.license` UserDefaults suite). After removal nothing restores them. **Mitigation:** ship a new bundle id (clean domain) — recommended — or add the one-time restore migration in Phase 5, Step 33.
- **Orphaned UserDefaults / Keychain** (audit 04/05): with a new bundle id there is nothing to orphan; with the same id, old `proTransition.*` / `trialStartDate` keys are harmless once no code reads them.
- **Sparkle key mismatch** breaks updates silently for end users — verify the public/private EdDSA pair before first release.
- **Trademark/identity** (Section A): shipping as "AltTab" with the AltTab icon is the highest *non-build* risk — rename + re-icon.
### Testing matrix
- **Unit:** `scripts/run_tests.sh` (Test scheme) green after Phase 7. The pure kernels (`SelectionResolver`, `SearchModeResolver`, `WindowFilterResolver`, `WindowOrderResolver`) never touched pro code (audit 02) and should pass unchanged — a good signal that gate removal didn't perturb core logic.
- **Debug build:** `ai/build.sh` green after **every** phase (the discipline that catches the consumer-before-type breaks).
- **Release build:** `scripts/build_app.sh` green before packaging.
- **Manual smoke (post-Phase 8):**
1. Fresh launch → Accessibility + Screen-Recording permission flow → switcher panels appear (phase-A → phase-B handoff, audit 01).
2. Alt-Tab show/hide/cycle; selection + hover; window focus.
3. All four previously-Pro features work: App-Icons/Titles appearance style, Auto size, in-switcher search, lock-search, and **>1 keyboard shortcut**.
4. Settings: no Upgrade tab, no Get-Pro menu item, no trial subtitle, no orange badge dot, no Pro badges on Appearance/Controls rows.
5. No `alttab://` URL handler registered (and removed from `Info.plist` URL scheme).
6. Network check (e.g. Little Snitch / `nettop`): **no** request to `alt-tab.app/api/v1/license` and **no** tier cookie; appcast points at *your* host.
7. Auto-update: a test appcast item signed with your EdDSA key updates successfully.
### Phased checklist
- [ ] Phase 0 — branch; baseline build green; (optional) land Strategy-1 force-unlock checkpoint.
- [ ] Phase 1 — gates open in place (`ProFeature`, `PreferenceDefinition.read`, shortcut cap); build green.
- [ ] Phase 2 — `App.swift` wiring severed (hooks, license block, custom-URL, selectors, first-launch); build green.
- [ ] Phase 3 — `Menubar.swift` upsell stripped (items, `UpgradeMenuItemView`, badge dot, `refreshState`); build green.
- [ ] Phase 4 — `SettingsWindow`/`SidebarList`/tabs/`PreferencesEvents` license + ProBadge plumbing removed; grep gate empty; build green.
- [ ] Phase 5 — `Preferences.swift` getters read raw values; `PreferencesMigrations:20` removed; (optional) restore migration; build green.
- [ ] Phase 6 — delete `src/pro/` + `PreferenceDefinition.swift` + `UpgradeTab.swift`; fix `Endpoints`, `DebugProfile`, `QAMenu`, AppCenter/principal class; build green.
- [ ] Phase 7 — `project.pbxproj` entries removed (incl. dual app+test UUIDs); tests/Mocks repaired; `scripts/run_tests.sh` green.
- [ ] Phase 8 — Release build green; manual smoke pass.
- [ ] Re-identity (D) — new bundle id, name, icon, Developer ID, Sparkle EdDSA keypair + repointed feed, removed license/AppCenter, repointed/removed feedback + website dispatch + FUNDING.
- [ ] Publish — signed, notarized, stapled `.app`/`.zip` via your GitHub Releases + your appcast (and/or Homebrew cask).
- [ ] Compliance (A) — `LICENCE.md` intact, attribution + "based on lwouis/alt-tab-macos, GPL-3.0" in README/About, changes noted, fork remains GPL-3.0.
---
### Appendix — reference: audit sections
| # | File | Topic |
|---|------|-------|
| 01 | `docs/audit/01-core-architecture.md` | App lifecycle, App.swift/Menubar.swift spine touchpoints |
| 02 | `docs/audit/02-switcher-ui.md` | Switcher gates (`ProFeature.attemptUse` call sites) |
| 03 | `docs/audit/03-preferences-and-gating.md` | `PreferenceDefinition`/`ProGatedPreferences`, `isProLocked` |
| 04 | `docs/audit/04-license-subsystem.md` | `LicenseManager`/`RemoteLicenseClient`/Keychain |
| 05 | `docs/audit/05-trial-nag-scheduling.md` | `ProTransitionManager` Day1→Day35 scheduler |
| 06 | `docs/audit/06-profeature-and-copy.md` | `ProFeature` cases + marketing copy |
| 07 | `docs/audit/07-pro-ui-and-menubar.md` | `src/pro/ui/` toolkit + Menubar integration |
| 08 | `docs/audit/08-build-release-distribution.md` | xcconfig, signing, Sparkle, CI |
| 09 | `docs/audit/09-telemetry-and-upstream.md` | AppCenter, network surfaces, upstream relationship |
+43
View File
@@ -0,0 +1,43 @@
# SESSION-STATE — CommandTabFree (de-paywalled AltTab fork)
_Updated 2026-06-16. `master` carries the fork; the **full CI/CD publishing pipeline is LIVE** — signed + notarized **v100.1.0** released and Gatekeeper-accepted. Homebrew tap live._
## ✅ SIGNED + NOTARIZED RELEASE LIVE
The complete release pipeline ran green end-to-end (run `27643432063`, commit `2f9fac17`): cert import → **signed** `build_app.sh` (Developer ID **`James Maes (2X834TJ5MA)`**) → notarize + staple → appcast→gh-pages → semantic-release → GitHub Release. **[v100.1.0](https://github.com/KofTwentyTwo/CommandTabFree/releases/tag/v100.1.0)** is published; the downloaded asset verifies `spctl` = "accepted, source=Notarized Developer ID" and `stapler validate` passes (offline-clean, no quarantine prompt). Non-release pushes stay green via the ad-hoc `build_app.sh` path (run `27634828800`).
**How signing is wired:** `config/local.xcconfig` sets `CODE_SIGN_IDENTITY` + `CODE_SIGN_STYLE = Manual` + `TEAM_ID 2X834TJ5MA`; the vendored Sparkle helpers (`vendor/Sparkle/Helpers/*`) are committed **re-signed** under the same Developer ID; `setup_ci_master.sh` imports the cert with an optional `APPLE_P12_PASSWORD`. The release secrets (`APPLE_P12_CERTIFICATE`/`APPLE_P12_PASSWORD`/`APPLE_ID`/`APPLE_PASSWORD`/`APPLE_TEAM_ID` + `SPARKLE_ED_PRIVATE_KEY`) are set in the `production` env. Getting here also required two CI fixes earlier this session: `d1e1b296` (regenerate base `Localizable.strings` to clear the genstrings gate) and `6070f0cb` (ad-hoc build until the cert existed).
**Remaining (NOT yet done):**
- **Auto-update** (deferred by choice): `appcast.xml` is published to gh-pages, but the app's feed URL is still `fork.invalid` and `SUEnableAutomaticChecks=false`. To enable N→N+1 updates: set a real `DOMAIN` (kof22.com), serve gh-pages at `https://<DOMAIN>/appcast.xml`, flip checks on.
- **Homebrew cask**: now notarized — drop the quarantine-strip postflight and bump the cask to v100.1.0.
- **Upstream-sync**: `.fork-sync-state` reset to `v11.3.0` (the release tail no longer clobbers it — see ci_cd.yml). Before enabling upstream-sync, advance the cursor from the sync-merge flow (recording the UPSTREAM tag), and provision `SYNC_BOT_TOKEN` + an external cron. The 3 sync labels exist.
**Repo facts:** GitHub = `KofTwentyTwo/CommandTabFree` (local dir `~/Git.Local/kof22/alt-tab-free`, SSH remote). Latest release **v100.1.0** (signed + notarized zip). ⌘⇥ icon FINAL. Owner-gated checklist: `docs/TODO.md`.
## What this is
`KofTwentyTwo/CommandTabFree` is a fork of **AltTab** (`lwouis/alt-tab-macos`, GPL-3.0) that neutralizes the v11 Pro paywall so all features are free, rebranded **CommandTabFree**. Strategy: thin, merge-stable patch tracking upstream forever (`docs/PLAN-maintained-fork.md`).
## ✅ DONE
- De-paywall + anti-relock tests + frozen identity (`com.koftwentytwo.commandtabfree`) + brand sweep + ⌘⇥ icon (final) — all on **`master`** (was `depaywall-free`, fast-forward merged, HEAD `c7d2d968`, pushed to origin; source is public for GPL §6).
- **Sparkle EdDSA keypair generated.** Public key in `Info.plist` (`SUPublicEDKey`); private key in 1Password item **"CommandTabFree-Sparkle-EdDSA"** + GitHub Actions secret `SPARKLE_ED_PRIVATE_KEY` (env `production`); keychain account `commandtabfree`. `SUEnableAutomaticChecks=false` until a real appcast host exists. This fixed the launch-time "updater failed to start" alert.
- **Public release v100.0.3** (pre-release, **unsigned / not notarized**, universal x86_64+arm64) — ⌘⇥ menu-bar icon, redesigned About (KofTwentyTwo identity + AltTab attribution links), and a **full l10n rebrand** (product name → CommandTabFree across base/en + all ~20 translated languages; upstream attribution kept). Earlier v100.0.0/v100.0.1/v100.0.2 superseded.
- **Homebrew tap live:** `brew install --cask koftwentytwo/tap/commandtabfree` (`KofTwentyTwo/homebrew-tap` → `Casks/commandtabfree.rb`). Cask strips the quarantine (postflight `xattr`) — was needed for the unsigned v100.0.x; now that v100.1.0 is notarized, drop that postflight and bump the cask.
- **CI/CD wired** (GitHub Actions), **fully green on push** (run `27634828800`, commit `6070f0cb`). Passing: Guard A/B/C, commitlint, generated-files gate, version compute, `run_tests.sh`, ad-hoc `build_app.sh`. The sign/notarize/appcast/semantic-release/gh-release tail is gated on a `release-gate` step that **auto-activates** when `APPLE_*` secrets are added — secrets were added 2026-06-16 and the **full tail is now proven** (signed+notarized **v100.1.0**, run `27643432063`). Fixed this session (2026-06-16): regenerated base `Localizable.strings` to clear the genstrings gate; build ad-hoc until the owner provisions the Apple cert (was inheriting upstream's Developer ID → exit 65). Earlier this session: Guard B grep now matches the shipped `guard false else { return .pro }` patch (was checking the PLAN's never-shipped `if false`/`alt-tab-free [depaywall]` form); `update_appcast.sh` → `--ed-key-file`; commitlint sync-merge `ignores`; dropped upstream-only scripts (AppCenter/website); commit headers must be ≤72 chars. Full status: `docs/CICD-STATUS.md`.
- **Local daily driver installed:** `/Applications/CommandTabFree.app` = **Release** build (no QA menu) signed with the `Local Self-Signed` cert (stable signature → no TCC re-grant loop). Remaining: user grants Accessibility + Screen Recording on first launch.
### Build recipes (verified this session)
- **Local (stable, no QA menu):** `xcodebuild -project alt-tab-macos.xcodeproj -scheme Release -derivedDataPath DerivedData CURRENT_PROJECT_VERSION=<v> CODE_SIGN_IDENTITY="Local Self-Signed" CODE_SIGN_STYLE=Manual DEVELOPMENT_TEAM="" OTHER_CODE_SIGN_FLAGS="--timestamp=none" CODE_SIGNING_ALLOWED=YES` (needs `scripts/codesign/setup_local.sh` cert first; user runs it — keychain/admin prompt).
- **Public artifact (ad-hoc):** same recipe but `CODE_SIGN_IDENTITY="-" CODE_SIGNING_REQUIRED=NO`. Zip with `ditto -c -k --sequesterRsrc --keepParent`.
- **GOTCHA — do NOT pass `-configuration Release`.** With `-scheme Release` it splits SPM package outputs and breaks clean-build module-map generation (`build/GeneratedModuleMaps/*.modulemap not found`, then "unable to resolve module Cocoa/Sparkle/..."). Use the scheme only (matches `scripts/build_app.sh`). A failed build can corrupt `build/`; recover with `rm -rf build DerivedData` then rebuild.
## ⏳ NEXT (owner-gated — `docs/EXECUTION-STATUS.md` §3)
- **Apple Developer ID** (long pole): set `CODE_SIGN_IDENTITY` in `config/local.xcconfig`, re-sign Sparkle helpers, notarize → re-release signed/notarized, then drop the cask's quarantine postflight.
- **Real DOMAIN/appcast** (kof22.com ready): replace `fork.invalid` in `local.xcconfig`, serve `/appcast.xml`, flip `SUEnableAutomaticChecks` back on.
- **Wire CI:** `update_appcast.sh` uses the deprecated `sign_update -s` — switch to `--ed-key-file` (or `--account commandtabfree`) for the new key; create `sync`/`conflict`/`chokepoint-refresh` labels; external cron for `upstream_sync.yml`.
## Gotchas
- Bundle id FROZEN (`com.koftwentytwo.commandtabfree`); keychain/UserDefaults suites derive from it.
- Don't `git revert 9147a4a8` (mixes paywall with a 1869-file reorg).
- Fork version line starts at **v100.0.0** (avoids collision with upstream tags merged into `master`).
- `aws`: use `AWS_PROFILE=kingsrook_root_admin aws …` (the `--profile` flag fails on the local wrapper).
+34
View File
@@ -0,0 +1,34 @@
# TODO — CommandTabFree
_Updated 2026-06-16. The **signed + notarized publishing pipeline is LIVE** — **v100.1.0** is released (Gatekeeper-accepted). Remaining items are auto-update, the Homebrew cask, and upstream-sync. Full detail: `docs/CICD-STATUS.md`, `docs/EXECUTION-STATUS.md` §3._
## ✅ Signed + notarized releases — DONE (2026-06-16)
- [x] Apple Developer ID `Developer ID Application: James Maes (2X834TJ5MA)` provisioned; cert + app-specific password in `production` secrets (`APPLE_P12_CERTIFICATE`/`APPLE_P12_PASSWORD`/`APPLE_ID`/`APPLE_PASSWORD`/`APPLE_TEAM_ID`).
- [x] `CODE_SIGN_IDENTITY` + Manual style + `TEAM_ID` set in `config/local.xcconfig`.
- [x] Vendored `vendor/Sparkle/Helpers/*` committed re-signed under the fork Developer ID.
- [x] Full release tail proven on CI (run `27643432063`): signed → notarized → stapled → released. **v100.1.0** published.
## Auto-update (deferred by choice — appcast already publishes to gh-pages)
- [ ] **Real `DOMAIN`** — replace `fork.invalid` in `config/local.xcconfig` with the fork host (kof22.com).
- [ ] Serve the gh-pages `appcast.xml` at `https://<DOMAIN>/appcast.xml` (CNAME the gh-pages site).
- [ ] `git rm` the in-tree `appcast.xml` skeleton + gitignore it (feed is published out-of-tree to gh-pages); flip `SUEnableAutomaticChecks` back on (PLAN §3.2).
## Homebrew cask (now that builds are notarized)
- [ ] Drop the quarantine-strip postflight (`xattr`) from `KofTwentyTwo/homebrew-tap` `Casks/commandtabfree.rb` — no longer needed for a notarized app.
- [ ] Bump the cask to v100.1.0.
## Upstream-sync automation
- [x] `.fork-sync-state` reset to `v11.3.0`; release tail no longer clobbers the cursor with the fork tag (`ci_cd.yml`).
- [ ] **Re-wire the cursor advance** into the upstream-sync merge flow so it records the synced **UPSTREAM** tag (not the fork release tag) — `upstream_sync.yml` (PLAN §4.2).
- [ ] **`SYNC_BOT_TOKEN`** — GitHub App installation token (or fork PAT with contents + pull-requests write). Default `GITHUB_TOKEN` does NOT re-trigger PR checks, so guards never run on the sync PR.
- [ ] **External cron** — hit `repository_dispatch` (type `upstream-sync`) from an external scheduler (immune to GitHub's 60-day in-repo `schedule:` auto-disable).
- [x] Sync PR labels `sync` / `conflict` / `chokepoint-refresh` created.
## Bootstrap acceptance tests (after the above)
- [ ] Sync PR through the bot shows guard checks running.
- [ ] A deliberately-relocked branch goes RED on `guard.yml`.
- [ ] Fork build N→N+1 auto-updates via Sparkle (needs DOMAIN/appcast live).
## Done earlier this session (2026-06-16)
- [x] genstrings consistency gate fixed — regenerated base `Localizable.strings` from source (`d1e1b296`).
- [x] `build_app.sh` builds ad-hoc until cert provisioned; was failing on upstream's Developer ID (`6070f0cb`). Push CI green (run `27634828800`).
+12
View File
@@ -0,0 +1,12 @@
## Acknowledgments
These third-party libraries are used:
**ShortcutRecorder**
[Website](https://github.com/Kentzo/ShortcutRecorder) - [CC 4.0 License](https://github.com/Kentzo/ShortcutRecorder/blob/master/LICENSE.txt)
**Sparkle**
[Website](https://github.com/sparkle-project/Sparkle) - [License](https://github.com/sparkle-project/Sparkle/blob/master/LICENSE)
**AppCenter**
[Website](https://github.com/microsoft/appcenter-sdk-apple) - [Custom](https://github.com/microsoft/appcenter-sdk-apple/blob/develop/LICENSE)
+403
View File
@@ -0,0 +1,403 @@
# 01 — Core Application Architecture & Lifecycle
> Audit scope: the app entry point, `App.swift` (`NSApplicationDelegate`), and `src/macos/`
> (permissions, accessibility, login item, AX scheduling). This is the spine the rest of the
> paywall-removal audit hangs on. **Read-only audit — no source was modified.**
All `file:line` references are against the tree as audited (branch `master`, commit `9fadf36b`).
---
## 1. Entry point & process bootstrap
The app has **no `@main` / `@NSApplicationMain`**. It uses a top-level `main.swift`
(`src/main.swift`) as the executable entry, per the AGENTS.md "pure Swift, no Interface Builder"
constraint.
Boot order in `src/main.swift`:
1. `src/main.swift:4-6` — CLI fast-path. If launched with a recognized CLI command
(`CliClient.detectCommand()`), it forwards the command to the already-running instance via a
Mach message port and the process exits early (never becomes the GUI app).
2. `src/main.swift:11-15` — installs POSIX signal handlers for `SIGTERM` / `SIGTRAP` that call
`emergencyExit(...)`.
3. `src/main.swift:19-21` — installs `NSSetUncaughtExceptionHandler` (Obj-C exceptions) → also
`emergencyExit(...)`.
4. `src/main.swift:23` — `App.shared.run()` enters the AppKit run loop.
`emergencyExit` (`src/main.swift:33-39`) re-enables the native ⌘-Tab
(`setNativeCommandTabEnabled(true)`), prints a stack trace, drains in-flight screen captures
(`makeSureAllCapturesAreFinished()`, `src/main.swift:41-51`, which sets `App.isTerminating = true`
and spins up to 5 s waiting on `ActiveWindowCaptures.value()`), then `exit(0)`.
**Paywall touchpoint in entry path:** none. `main.swift` is clean.
---
## 2. The `App` class
`App` (`src/App.swift:7`) subclasses `AppCenterApplication` (a Microsoft AppCenter `NSApplication`
subclass, used for crash reporting) and sets itself as its own delegate
(`src/App.swift:41-44`, `delegate = self`). It conforms to `NSApplicationDelegate` in the extension
at `src/App.swift:434-507`.
It is a hybrid singleton: instance methods satisfy the `NSApplicationDelegate` protocol, but the
bulk of the app's coordination logic lives in `static` methods/properties on `App` (e.g.
`App.showUi`, `App.hideUi`, `App.refreshUi`, `App.continueAppLaunchAfterPermissionsAreGranted`).
`App.shared` (`src/App.swift:24`) downcasts `NSApplication.shared`.
Notable static state:
- `App.isTerminating` (`src/App.swift:28`) — read by the capture-drain loop.
- `App.activity` (`src/App.swift:9-10`) — a `ProcessInfo.beginActivity` token preventing App Nap.
- `App.sparkleDelegate` / `App.updaterController` (`src/App.swift:35-36`) — Sparkle auto-update.
- Selectors `supportProjectAction` / `upgradeToProAction` / `openAccountAction`
(`src/App.swift:25-27`) — wired into the menubar (see §7).
---
## 3. Startup sequence (the two-phase launch)
Launch is **deliberately two-phase**, gated on macOS permissions. This split is structurally
important for the removal plan because the paywall is initialized in **phase A** and the rest of the
app only boots in **phase B** after permissions pass.
### Phase A — `applicationDidFinishLaunching` (`src/App.swift:435-463`)
Runs immediately on launch, before any permission is confirmed:
1. `:436` `AppCenterCrash()` — crash reporting.
2. `:437` `disableRelaunchOnLogin()`.
3. `:438-439` `Logger.initialize()` + version log.
4. `:444` (release only) `MoveToApplicationsFolder.promptIfNeeded()`.
5. `:446` `AXUIElement.setGlobalTimeout()` — sets the global 1 s AX messaging timeout.
6. `:447` `Preferences.initialize()` — loads `UserDefaults`, runs migrations.
7. **`:448-460` License/Pro wiring (PAYWALL).** Wires three `LicenseManager.shared` callbacks and
calls `LicenseManager.shared.initialize()`. Detailed in §6.
8. `:461` `BackgroundWork.preStart()` — creates the *minimal* early queues needed for permission
polling (`permissionsCheckOnTimerQueue`, `permissionsSystemCallsQueue`, `screenshotsQueue`;
`src/util/BackgroundWork.swift:23-30`).
9. `:462` `SystemPermissions.ensurePermissionsAreGranted()` — starts the permission timer (see §5).
Phase A does **not** create the switcher panel, menubar, or any event taps. If permissions are
missing, the app sits in the permission-window loop and never proceeds to phase B.
### Phase B — `App.continueAppLaunchAfterPermissionsAreGranted` (`src/App.swift:383-431`)
Called **once**, from `SystemPermissions.checkPermissionsPreStartup()`
(`src/macos/SystemPermissions.swift:77`), the moment both Accessibility and Screen-Recording
permissions are confirmed. This is the real subsystem-wiring sequence:
| Line | Call | Subsystem |
|------|------|-----------|
| `:385` | `BackgroundWork.start()` | full set of background threads/queues (§4) |
| `:386` | `NSScreen.updatePreferred()` | display state |
| `:387` | `Appearance.update()` | switcher theming |
| `:388-389` | `TilesPanel.updateMaxPossible…Size()` | layout precompute |
| `:390` | `Menubar.initialize()` | menubar status item (**touches license**, §7) |
| `:391` | `MainMenu.create()` | app main menu |
| `:392-393` | `TilesPanel()` / `PreviewPanel()` | switcher windows |
| `:394-395` | `Spaces.refresh()` / `Screens.refresh()` | spaces & displays state |
| `:396-405` | `*.observe()` for Spaces, Screens, SystemAppearance, SystemScrollerStyle, InputSource, Cursor, Trackpad, Cli; plus `Applications.initialDiscovery()`; `KeyboardEvents.addEventHandlers()` | event observers / taps (§8) |
| `:406-413` | `SparkleDelegate()` + `SPUStandardUpdaterController`, updater started 30 s later | auto-update |
| `:414` | `PreferencesEvents.initialize()` | applies side-effects of every preference |
| `:415` | `BenchmarkRunner.startIfNeeded()` | dev benchmark |
| `:416-420` | first-launch Settings window (`showSettingsWindowOnFirstLaunchIfNeeded`) | UI (**license-aware**, §6) |
| `:421-426` | `#if DEBUG` QA menu / debug graph | dev-only |
| `:427` | `UsageStats.prune()` | usage telemetry |
| **`:428-429`** | **`ProTransitionManager.shared.onAction = …` + `onAppLaunchComplete()`** | **PAYWALL** (§6) |
`Applications.initialDiscovery()` (`src/App.swift:401`) is also where the NSWorkspace
running-applications observer gets installed: it calls `RunningApplicationsEvents.observe()`
internally (`src/switcher/state/Applications.swift:20`).
---
## 4. Background threading model (`BackgroundWork`)
`src/util/BackgroundWork.swift`. The app is heavily multithreaded because most macOS hooks
(CGEvent taps, AX observers, Mach ports) require their own run loops, and AX calls can block for the
1 s timeout.
- **Dedicated run-loop threads** (`BackgroundThreadWithRunLoop`, `:106-137`):
`accessibilityEventsThread`, `keyboardAndMouseAndTrackpadEventsThread`, `missionControlThread`,
`cliEventsThread`. Each runs a `CFRunLoopRun()` with a dummy source to stay alive
(`:131-136`). Created in `start()` (`:43-49`).
- **Operation queues** (`LabeledOperationQueue`, `:140-160`): `repeatingKeyQueue`,
`screenshotsQueue`, `accessibilityCommandsQueue`, `focusOrderQueue`, `crashReportsQueue`,
`permissionsCheckOnTimerQueue`, `permissionsSystemCallsQueue`.
- `preStart()` (`:23-30`) creates only the three queues needed before permissions; `start()`
(`:32-50`) creates the rest in phase B.
- Thread budget is policed: `addPotentialThreadCount` asserts the total stays ≤ 45 against the
~64-thread process limit (`:59-63`).
The separate `AXCallScheduler` (`src/macos/AXCallScheduler.swift`) owns three more bounded pools
for *outgoing* AX queries (`axQueryFirstTryQueue` 10, `axQueryScanQueue` 6, `axQueryRetryQueue` 8;
`:43-45`). It is a per-key serializing executor with retry/backoff for unresponsive apps
(`schedule(...)`, `:51-71`; `attemptBlock`, `:113-169`). It does **no** throttling/coalescing —
that is the caller's job. **No paywall coupling.**
**Paywall touchpoint in threading:** none. `BackgroundWork` and `AXCallScheduler` are clean.
---
## 5. How permissions are requested (`src/macos/SystemPermissions.swift`)
`SystemPermissions` drives a `DispatchSourceTimer` on `permissionsCheckOnTimerQueue`.
- `ensurePermissionsAreGranted()` (`:22-27`) creates the timer with handler
`checkPermissionsOnTimer` and fires it immediately.
- **Pre-startup** (`checkPermissionsPreStartup`, `:70-84`): if both
`AccessibilityPermission.status` and `ScreenRecordingPermission.status` are not-`.notGranted`,
it flips `preStartupPermissionsPassed = true`, closes the permission window, switches to the
infrequent timer, starts the distributed-notification revoke listener, and calls
**`App.continueAppLaunchAfterPermissionsAreGranted()`** (`:77`). Otherwise it shows the
permissions window (`:81`).
- **Post-startup** (`checkPermissionsPostStartup`, `:86-91`): if Accessibility is revoked while
running, it restarts the app (`App.restart()`).
- **Revoke detection** (`startListeningForDistributedRevoke`, `:29-43`): observes the undocumented
`com.apple.accessibility.api` distributed notification; on revoke → `App.restart()`. A sparse
60 s backstop timer covers cases where the notification doesn't fire (`setInfrequentTimer`,
`:96-103`).
- **Accessibility detection** (`AccessibilityPermission`, `:116-128`): `AXIsProcessTrustedWithOptions`
with `kAXTrustedCheckOptionPrompt: false`.
- **Screen-recording detection** (`ScreenRecordingPermission`, `:130-217`): via
`SCShareableContent.getExcludingDesktopWindows` (macOS 12.3+) or `CGDisplayStream` probing,
each wrapped in a 6 s timeout (`runWithTimeout`, `:202-217`). Honors
`Preferences.screenRecordingPermissionSkipped` (`:141`).
The permission UI window (`PermissionsWindow`) lives outside this scope
(`src/secondary-windows/permission-window/`).
**Paywall touchpoint in permissions:** none. `SystemPermissions.swift` is clean.
---
## 6. PAYWALL — every place the spine touches License / Pro
This section is the deliverable's core. Below is **every** reference in the spine (`App.swift`,
`Menubar.swift`, `main.swift`, `src/macos/`) to `LicenseManager`, `ProTransitionManager`,
`ProPromptHost`, checkout, and `UpgradeTab`.
### 6.1 `App.swift` — license wiring & callbacks
| `file:line` | Code | Purpose |
|-------------|------|---------|
| `src/App.swift:26` | `static var upgradeToProAction: Selector { #selector(App.upgradeToPro) }` | selector exposed to menubar "Get Pro" |
| `src/App.swift:27` | `static var openAccountAction: Selector { #selector(App.openAccount) }` | selector for menubar "My Account" |
| `src/App.swift:78` | `ProTransitionManager.shared.onSwitcherDismissed()` | inside `hideUi()` — ends free-pass session, queues post-dismiss upsell windows |
| `src/App.swift:115-117` | `@objc static func upgradeToPro() { ProTransitionManager.openCheckout() }` | opens checkout URL |
| `src/App.swift:119-121` | `@objc static func openAccount() { UpgradeTab.openAccountPage() }` | opens account page |
| `src/App.swift:206-207` | `if case .pro = LicenseManager.shared.state { return false }` / `return !ProTransitionManager.shared.hasSeenWelcome` | `willShowDay1WelcomeOnAppLaunch()` — defers first-launch Settings if the Day-1 welcome nag will show |
| `src/App.swift:328` | `ProTransitionManager.shared.onSwitcherShown()` | inside `showUiOrCycleSelection()` — decides Day-4 tour or post-expiration free-pass |
| `src/App.swift:428` | `ProTransitionManager.shared.onAction = { ProPromptHost.shared.dispatch($0) }` | binds the prompt-action emitter to the Day-X UI host |
| `src/App.swift:429` | `ProTransitionManager.shared.onAppLaunchComplete()` | starts the trial-nag scheduler |
| `src/App.swift:448` | `LicenseManager.shared.onBeforeProUnlock = { ProTransitionManager.shared.onProUnlocked() }` | restore Pro prefs on activation |
| `src/App.swift:449-459` | `LicenseManager.shared.onStateChanged = { state in … }` | the big state-change fan-out (see below) |
| `src/App.swift:460` | `LicenseManager.shared.initialize()` | computes initial license/trial state; **first thing that touches Keychain/UserDefaults trial bookkeeping** |
| `src/App.swift:480` | `UpgradeTab.showAutoActivating(licenseKey)` | custom-URL `alttab://activate` handler |
| `src/App.swift:481-489` | `LicenseManager.shared.activate(licenseKey) { … }` (+ `UpgradeTab.showAutoActivation{Success,Failed}`) | license activation via custom URL |
The `onStateChanged` closure (`src/App.swift:449-459`) does six things on every license-state
transition:
1. `Menubar.refreshLicenseMenuItems()` (`:450`)
2. `syncLicenseCookie(state:)` (`:451`) — defined in `src/pro/license/LicenseCookie.swift:5`,
writes a Sparkle HTTP cookie so the appcast can serve license-aware updates.
3. `ProTransitionManager.shared.onLicenseStateChanged()` (`:452`)
4. `UpgradeTab.refreshStatus()` (`:453`)
5. `SettingsWindow.shared?.refreshUpgradeButton()` (`:454`)
6. `App.resetPreferencesDependentComponents()` if `TilesPanel.shared != nil` (`:455`), then posts
`ProTransitionManager.proLockStateDidChangeNotification` (`:458`).
### 6.2 `App.swift` custom-URL scheme — license activation
`application(_:open:)` (`src/App.swift:465-471`) routes `alttab://` URLs to `handleCustomUrl`
(`:473-490`), which handles **only** `host == "activate"` with a `license_key` query item, calling
`LicenseManager.shared.activate(...)`. **The entire custom-URL handler exists solely for license
activation** — there is no other URL scheme use in the spine.
### 6.3 `Menubar.swift` — license-driven menu items & badge
`Menubar` is the other spine file with deep paywall coupling (it's created in phase B at
`src/App.swift:390`):
| `file:line` | Purpose |
|-------------|---------|
| `src/Menubar.swift:46-47` | builds the "Get Pro" item with a custom `UpgradeMenuItemView` |
| `src/Menubar.swift:48` | "My Account" item (`App.openAccountAction`) |
| `src/Menubar.swift:49` | "Support this project" item |
| `src/Menubar.swift:50` | calls `refreshLicenseMenuItems()` during build |
| `src/Menubar.swift:84-107` | `refreshLicenseMenuItems()` — switches visibility of Get-Pro/Account/Support items on `LicenseManager.shared.state` |
| `src/Menubar.swift:109-118` | `toggleUpgradeMenuItem()` — inserts/removes the Get-Pro item |
| `src/Menubar.swift:156-158` | comment referencing `LicenseManager.initialize()` ordering vs `statusItem` nil |
| `src/Menubar.swift:202-227` | `updateBadgeDotOverlay()` — gated on `ProTransitionManager.shared.shouldShowBadgeDot` (orange nag dot on the menubar icon) |
| `src/Menubar.swift:235-390` | `UpgradeMenuItemView` — the entire gradient/shine "Get Pro" menu cell, uses `ProGradient.makeLayer()` and `App.upgradeToPro()`; `updateContent(_ state: LicenseState)` renders trial-days-remaining |
| `src/Menubar.swift:392-399` | `MenubarMenuDelegate.menuWillOpen` → `LicenseManager.shared.refreshState()` |
### 6.4 `src/macos/` — license touchpoints
**None.** `SystemPermissions.swift`, `BackgroundWork.swift`, `AXCallScheduler.swift`,
`LoginItem.swift` contain no License/Pro references (verified by grep). The `src/macos/` layer is
paywall-free.
### 6.5 The contract the spine depends on (for the removal plan)
`App.swift` depends on this public surface of the Pro module:
- `LicenseManager.shared` (singleton, `src/pro/license/LicenseManager.swift:7-15`), with:
`.state: LicenseState` (`:51`), `.initialize()` (`:91`), `.refreshState()` (`:99`),
`.activate(_:completion:)` (`:104`), `.onStateChanged` (`:38`), `.onBeforeProUnlock` (`:49`),
`.isProLocked` (`:67`), `.isProAvailable` (`:62`), `.daysSinceTrialStart` (`:79`),
`.customerEmail` (`:55`).
- `LicenseState` enum (`src/pro/license/LicenseState.swift:1-5`): `.trial(daysRemaining:)`,
`.pro`, `.proExpired`, `.trialExpired`.
- `ProTransitionManager.shared` (`src/pro/scheduling/ProTransitionManager.swift:105`), with the
lifecycle hooks `onSwitcherShown/Dismissed`, `onAppLaunchComplete`, `onLicenseStateChanged`,
`onProUnlocked`, `onAction`, `hasSeenWelcome`, `shouldShowBadgeDot`, the static
`openCheckout()` (`:307`) and `proLockStateDidChangeNotification` (`:110`).
- `ProPromptHost.shared.dispatch(_:)` (`src/pro/ui/ProPromptHost.swift:9-11`).
- `UpgradeTab` static methods (`src/preferences/settings-window/tabs/UpgradeTab.swift`).
- `syncLicenseCookie(state:)` (`src/pro/license/LicenseCookie.swift:5`).
The **runtime feature gate** itself is `ProFeature.attemptUse()`
(`src/pro/ProFeature.swift:74-83`): returns `true` if `isProAvailable`, else if a free-pass
session is active, else routes hard-gated features through
`ProTransitionManager.shared.attemptHardGatedFeature(...)`. Call sites for the gate live outside
this scope (TilesView, ShortcutAction, SearchModeResolver) — see §9.
---
## 7. App-menu / window plumbing (license-adjacent)
`App` exposes several `@objc` window/show helpers wired into the menubar and main menu:
`showSettingsWindow` (`:137`), `showAboutWindow` (`:151`), `showFeedbackPanel` (`:123`),
`showDebugWindow` (`:132`), `showPermissionsWindow` (`:235`), `checkForUpdatesNow` (`:103`),
`checkPermissions` (`:107`), `supportProject` (`:111`). Of these, only `supportProject`,
`upgradeToPro`, `openAccount` are paywall-adjacent.
First-launch Settings logic (`showSettingsWindowOnFirstLaunchIfNeeded`, `:189-233`) is
**entangled with the Day-1 welcome nag**: it checks `willShowDay1WelcomeOnAppLaunch()`
(`:205-208`, reads `LicenseManager.shared.state` and `ProTransitionManager.shared.hasSeenWelcome`)
and, if the welcome window will appear, defers showing Settings until a `Day1WelcomeLetterWindow`
`willCloseNotification` fires (`:210-220`).
---
## 8. How AltTab hooks into macOS (event taps, AX observers, NSWorkspace)
The hooks are installed in phase B and live mostly under `src/events/`. Summary of the kernel of
macOS integration the rest of the audit will reference:
- **CGEvent tap (keyboard)** — `KeyboardEvents.addCgEventTap()`
(`src/events/KeyboardEvents.swift:132-152`): a `.cghidEventTap` / `.headInsertEventTap` /
`.defaultTap` tap for `.flagsChanged` + `.keyDown`, added to
`BackgroundWork.keyboardAndMouseAndTrackpadEventsThread`'s run loop. If `tapCreate` returns nil
(permission lost) → `App.restart()` (`:150`). Also a local `NSEvent` monitor
(`:123-130`). The tap's `.keyDown` branch only absorbs Esc, and only when a shortcut binds it
and the switcher is active (issue #5585 workaround, `:33-44`).
- **Carbon hotkeys** — `RegisterEventHotKey` for the global switcher shortcuts
(`registerHotKeyIfNeeded`, `:104-120`; handlers installed in `addGlobalHandlerIfNeeded`,
`:154-173`). `toggleGlobalShortcuts` (`:64-75`) registers/unregisters them when an app exception
disables AltTab.
- **Accessibility (AX) observers** — `AccessibilityEvents.axObserverCallback`
(`src/events/AccessibilityEvents.swift:6-21`). Subscriptions bake `(pid, wid)` into the
`refcon` (`subscriptionRefcon`, `:25-28`). Focus/activation use an IPC-free fast lane
(`updateFocusOrderFastLane`, `:38-56`) on `BackgroundWork.focusOrderQueue`; everything else is
scheduled through `AXCallScheduler.shared` and dispatched to `handleEventApp` / `handleEventWindow`.
These feed the window inventory (`Windows`, `Applications`) and drive
`App.refreshOpenUiAfterExternalEvent` / `App.checkIfShortcutsShouldBeDisabled`.
- **NSWorkspace** — `RunningApplicationsEvents.observe()`
(`src/events/RunningApplicationsEvents.swift:6-10`): KVO on
`NSWorkspace.shared.runningApplications` (not the launch/terminate notifications, which miss
non-GUI apps), feeding `Applications.addRunningApplications` / `removeRunningApplications`.
- **Other observers** wired at `src/App.swift:396-405`: Spaces, Screens, system appearance,
scroller style, input source, cursor, trackpad, CLI (Mach message port).
- **Login item** — `src/macos/LoginItem.swift` writes/removes a launchd `LaunchAgents` plist
keyed by `App.bundleIdentifier`; reconciled from `Preferences.startAtLogin` via
`PreferencesEvents`.
None of the macOS hook installation is paywall-coupled. The only license interaction at runtime
is via `ProFeature.attemptUse()` invoked from feature call sites (§9), not from the tap/observer
plumbing itself.
---
## 9. Runtime feature gates reachable from the spine (out-of-scope files, noted for the plan)
The spine wires the managers; the actual *gating* happens when features run. For continuity with
later audit sections, the `ProFeature.attemptUse()` (`src/pro/ProFeature.swift:74`) call sites are:
- `src/switcher/main-window/TilesView.swift:79` (`lockSearchInSwitcher`), `:92` (`searchInSwitcher`)
- `src/switcher/ShortcutAction.swift:56` (`extraShortcut(index:)`)
- preference read interception: `src/preferences/PreferenceDefinition.swift:34-35`
(`isProLocked` + `isFreePassSessionActive` swap stored Pro values for Free)
And the broader (non-spine) paywall coupling surface — settings UI badges, upgrade tab, and the
preference setter that bounces to the Upgrade tab — is concentrated in `src/preferences/...`,
`src/Menubar.swift`, `src/events/PreferencesEvents.swift:62-63`, and `src/debug/QAMenu.swift`
(DEBUG-only). These are covered by later audit sections; they are listed here only so the spine's
fan-out is traceable.
---
## 10. Removal-plan notes (spine only)
**Goal:** every `ProFeature.attemptUse()` should behave as if `isProAvailable == true`, and all
trial-nag / upsell windows and license activation should be gone, without breaking the two-phase
launch.
1. **`App.continueAppLaunchAfterPermissionsAreGranted` must keep its non-Pro work.** Only
`src/App.swift:428-429` (the `onAction` binding + `onAppLaunchComplete`) is Pro. Removing those
two lines stops the trial-nag scheduler. Everything else in this method (queues, panels,
observers, Sparkle, first-launch Settings) must stay.
2. **`applicationDidFinishLaunching` license block (`src/App.swift:448-460`)** is the cleanest cut
point. If the Pro module is deleted wholesale, all 13 lines (`:448-459` callback wiring +
`:460` `initialize()`) go. **Risk:** `LicenseManager.shared.initialize()` is currently the
place that seeds `trialStartDate` (`src/pro/license/LicenseManager.swift:193-194`); removing it
is fine for a free build (nothing reads trial state once gating is unconditional), but any
leftover reader of `LicenseManager.shared.state` will crash if the singleton is deleted.
3. **`onStateChanged` fan-out (`src/App.swift:449-459`)** has one non-Pro side effect worth noting:
`App.resetPreferencesDependentComponents()` (`:455`) and the
`proLockStateDidChangeNotification` post (`:458`). Both become dead once Pro is removed, but
`resetPreferencesDependentComponents()` itself (`src/App.swift:51-53`) is a legitimate function
used elsewhere — keep the function, drop this caller.
4. **`hideUi` / `showUiOrCycleSelection`** each have exactly one Pro line
(`src/App.swift:78` and `:328`). Remove the `ProTransitionManager.shared.onSwitcher*` calls;
the surrounding session logic is independent.
5. **`upgradeToPro` / `openAccount` / `supportProject`** (`src/App.swift:111-121`) and their
selectors (`:25-27`) are only referenced by the menubar. Removing the corresponding
`Menubar` items (`src/Menubar.swift:46-50`, the entire `UpgradeMenuItemView`
`:235-390`, `refreshLicenseMenuItems` `:84-118`, badge dot `:202-227`, and the
`MenubarMenuDelegate.menuWillOpen` license refresh `:392-399`) lets these selectors be deleted.
`supportProject` (`Endpoints.supportUrl`) is a donation link, not a paywall — keep or drop per
the owner's call.
6. **Custom-URL handler (`src/App.swift:465-490`).** The entire `application(_:open:)` +
`handleCustomUrl` exists only for license activation. It can be removed entirely (and the
`alttab://` URL scheme dropped from `Info.plist` — out of this scope but flagged).
7. **First-launch welcome entanglement (`src/App.swift:189-233`).** `willShowDay1WelcomeOnAppLaunch`
(`:205-208`) and the deferral observer (`:210-220`) reference Pro. With the welcome nag gone,
simplify `showSettingsWindowOnFirstLaunchIfNeeded` to always call
`showAndCenterSettingsWindowOnFirstLaunch()` directly. **Risk:** if you delete
`Day1WelcomeLetterWindow` but leave the `willCloseNotification` observer, the observer never
fires and Settings never shows on first launch — remove the observer path together with the nag.
8. **Keychain / signing invariant (from AGENTS.md).** A free build that *keeps* `LicenseManager`
alive (e.g. to avoid touching many call sites) must preserve `App.bundleIdentifier`, TeamID, and
Developer ID, because `LicenseManager.keychainService` is `"\(App.bundleIdentifier).license"`
(`src/pro/license/LicenseManager.swift:4`). A clean free build that deletes the Pro module
entirely removes all Keychain usage and sidesteps this — preferred. Either way, do **not**
rotate bundle ID without the migration AGENTS.md describes.
9. **`src/macos/` is safe.** No file under `src/macos/` references the paywall; the permission
loop, AX scheduler, and login item need no changes. The phase-A→phase-B handoff
(`SystemPermissions.swift:77` → `App.continueAppLaunchAfterPermissionsAreGranted`) is the
critical path and is paywall-free.
---
### Appendix — files read for this section
`src/main.swift`, `src/App.swift`, `src/Menubar.swift`, `src/macos/SystemPermissions.swift`,
`src/macos/AXCallScheduler.swift`, `src/macos/LoginItem.swift`, `src/util/BackgroundWork.swift`,
`src/events/KeyboardEvents.swift`, `src/events/AccessibilityEvents.swift`,
`src/events/RunningApplicationsEvents.swift`, `src/switcher/SwitcherSession.swift`,
`src/pro/scheduling/ProTransitionManager.swift`, `src/pro/license/LicenseManager.swift`,
`src/pro/license/LicenseState.swift`, `src/pro/ProFeature.swift`,
`src/pro/ui/ProPromptHost.swift` (surface only), `src/pro/license/LicenseCookie.swift` (ref only).
+523
View File
@@ -0,0 +1,523 @@
# Audit 02 — Switcher UI (the product itself)
Scope: `src/switcher/` and `src/events/`. This section covers how windows are
enumerated and modeled, how the switcher panel is rendered/updated, how
cycling/selection/focus works, the keyboard/shortcut event flow, and how all of
this consults preferences. Pro-gated behavior that surfaces in this subsystem is
called out explicitly with `file:line` references and summarized at the end.
All paths are relative to the repo root `/Users/james.maes/Git.Local/kof22/alt-tab-free`.
---
## 1. Window enumeration and modeling
### 1.1 The data model
The product is built around two model layers:
- **Live AppKit-coupled objects** — `Window` (`src/switcher/state/Window.swift`)
and `Application` (`src/switcher/state/Application.swift`). These hold
`AXUIElement` handles, AX observers, thumbnails, icons, etc.
- **Pure value records** — `WindowState` (`src/switcher/state/WindowState.swift`)
and `ApplicationState`. These are `Equatable` structs containing only the
"facts" (`isMinimized`, `isFullscreen`, `spaceIds`, `title`, `lastFocusOrder`,
…) and are passed into the unit-testable decision "kernels"
(`WindowFilterResolver`, `WindowOrderResolver`, `SelectionResolver`,
`ExceptionMatcher`, `SearchModeResolver`).
`Window` is `@dynamicMemberLookup` over `WindowState`
(`src/switcher/state/Window.swift:3`, subscript at `:43-46`), so `window.title`,
`window.isMinimized`, etc. forward to `window.state`. This is purely a
convenience and has no paywall coupling.
Per-window fields of interest (`Window.swift:19-38`): `state`, `cgWindowId`,
`thumbnail: CALayerContents?`, `icon` (delegates to `application.icon`),
`shouldShowTheUser`, `tabbedSiblingWids`, `position`/`size`, `screenId`,
`axUiElement`, `application`, `axObserver`, `rowIndex`, search-result caches
(`swAppResults`, `swTitleResults`, `swBestSimilarity`, `lastSearchQuery`).
### 1.2 How windows are discovered
Discovery is **event-driven**, not poll-driven, and is rooted in `src/events/`:
1. **Accessibility (AX) notifications** drive everything. Each `Window` subscribes
to a fixed set of AX notifications on creation
(`Window.swift:5-12`: destroyed/title-changed/miniaturized/deminiaturized/
resized/moved) via `observeEvents()` (`Window.swift:134-150`). The callback is
`AccessibilityEvents.axObserverCallback`
(`src/events/AccessibilityEvents.swift:6-21`).
2. The callback decodes the owning `(pid, wid)` from a packed `refcon`
(`AccessibilityEvents.swift:25-33`) and routes through `AxEventRouting`
(`src/events/AxEventRouting.swift`) to either app-level (`handleEventApp`,
`AccessibilityEvents.swift:95-107`) or window-level (`handleEventWindow`,
`:141-175`) handling.
3. `handleEventWindow` reads AX attributes (title, subrole, role, size, position,
fullscreen, minimized, children for tab detection) and calls
`Windows.findOrCreate(...)` (`AccessibilityEvents.swift:151`).
4. `Windows.findOrCreate` (`src/switcher/state/Windows.swift:390-400`) either
updates an existing window (matched by `cgWindowId` via `byWindowId` or by
`isEqualRobust`) or, gated by `WindowDiscriminator.isActualWindow(...)`, creates
a new `Window` and calls `appendWindow`.
`WindowDiscriminator` (`src/switcher/state/WindowDiscriminator.swift`) is the
"is this a real, user-switchable window?" filter: it rejects `wid == 0`, missing
size, and windows smaller than 100x50 (`:8-19`), then accepts based on subrole
(`kAXStandardWindowSubrole`/`kAXDialogSubrole`) plus a large set of
app-specific special cases (Adobe, Steam, Firefox, VLC, JetBrains, Keynote,
Books, Crossover/Wine, scrcpy, AutoCAD, etc., `:20-44` and helpers). No paywall
logic here.
`appendWindow` (`Windows.swift:402-411`) appends to the canonical
`Windows.list`, registers it in `byWindowId`, assigns an initial
`lastFocusOrder`, and grows the recycled `TileView` pool if needed
(`TilesView.recycledViews`).
### 1.3 Spaces / screens / tab groups
- `Window.updateSpacesAndScreen` (`Window.swift:301-307`) populates `spaceIds`,
`spaceIndexes`, `isOnAllSpaces`, and `screenId` from CGS, with a workaround for
inactive tabs (`:309-320`).
- `recomputeIsInvisible()` (`Window.swift:124-126`) flags "ghost" windows
(no Space, not tabbed/minimized/hidden).
- Tab groups are tracked via `TabGroup` (`src/switcher/state/TabGroup.swift`) and
`tabbedSiblingWids`.
### 1.4 Window lifecycle / removal
`Windows.removeWindows` (`Windows.swift:413-483`) is the teardown path. Of note
(all memory-hygiene, no paywall): it releases pooled `TileView` IOSurfaces
(`:419-425`), clears `PreviewPanel` if it was showing a removed window
(`:427-431`), detaches the per-window AX observer runloop source via
`releaseAxObserver()` (`Window.swift:101-108`, `Windows.swift:473`), strips
`AXCallScheduler`/throttler entries, and re-shifts `lastFocusOrder`. It ends with
`App.refreshOpenUiAfterExternalEvent([], windowRemoved: true)`.
### 1.5 Per-show refresh
`Windows.updatesBeforeShowing()` (`Windows.swift:63-82`) runs each time the
switcher is summoned: refreshes Spaces, snapshots per-shortcut filter preferences
once (`WindowFilters.snapshot()`, `Windows.swift:507-519`), recomputes
`shouldShowTheUser` per window via `WindowFilterResolver.shouldShow(...)`
(`Windows.swift:105-125`), applies "only main windows" grouping
(`refreshWhichWindowsToShowTheUser`, `:89-103`, gated on
`Preferences.onlyShowMainWindows()`), and sorts. It returns `false` (and the show
aborts) if Mission Control is showing all/front windows.
---
## 2. The switcher panel: rendering and updating
### 2.1 Panel objects
- **`TilesPanel`** (`src/switcher/main-window/TilesPanel.swift`) — the main
`NSPanel`. `.nonactivatingPanel`, floating, `level = .popUpMenu`, joins all
Spaces, clear background, vibrant dark/light appearance
(`TilesPanel.swift:11-32`, appearance at `:34-37`). Its content view is
`TilesView.contentView`. Singleton `TilesPanel.shared`. Created in
`App.swift:392` (`_ = TilesPanel()`).
- **`PreviewPanel`** (`src/switcher/PreviewPanel.swift`) — a separate `NSPanel`
that shows a full-resolution preview of the *selected* window, ordered just
below `TilesPanel` (`PreviewPanel.swift:46-53`). Created in `App.swift:393`.
**This is the "preview selected window" feature** (see §6).
### 2.2 `TilesView` — the layout/render engine
`TilesView` (`src/switcher/main-window/TilesView.swift`) is a static class that
owns the scroll view, search field, "No Window" label, the recycled tile pool,
and the layout math. Key flow:
- `initialize()` (`:29-38`) sets up the search field, the no-window label, the
background effect view, and pre-allocates **20** `TileView` objects into
`recycledViews`.
- **Cell recycling**: `TileView`s are reused across shows. `recycledViews[i]` is
bound to `Windows.list[i]` during layout. Tiles past the visible/list count get
their image references released and `window_ = nil`
(`:514-519`, `:455`).
- `updateItemsAndLayout(_:)` (`:386-412`) is the entry point called by
`TilesPanel.updateContents` (`TilesPanel.swift:39-49`). It computes max width,
optionally resolves "auto" size, lays out tiles into rows
(`layoutTileViews`, `:471-529`), positions parent views
(`layoutParentViews`, `:549-601`), centers rows, and re-highlights the
selection.
- `TileView` (`src/switcher/main-window/TileView.swift`) renders a single cell:
thumbnail layer, app-icon layer, title label, status icons, dock label badge,
windowless-app indicator. The chosen content depends on the **appearance
style** (`thumbnails` / `appIcons` / `titles`) read via
`Preferences.effectiveAppearanceStyle(...)` (e.g. `TileView.swift:52, 64, 82`).
- Companion views: `TileOverView` (hover/window-controls overlay + hit-testing),
`TileUnderLayer` (highlight rectangle), `StatusIconsView`, `TileTitleView`,
`TileFontIconView`, `TilesPanelBackgroundView` (all under
`src/switcher/main-window/`).
### 2.3 Show / hide / refresh orchestration (in `src/App.swift`)
The switcher's lifecycle methods live in `App.swift`, not in `src/switcher/`, but
they are the orchestration glue:
- `App.showUiOrCycleSelection(shortcutIndex, forceDoNothingOnRelease)`
(`App.swift:307-351`) — creates the `SwitcherSession` if absent, records usage
(`UsageStats.recordTrigger`, see §6), and on the first summon (or a
different shortcut index) rebuilds: updates preferred screen, sorts by level on
the very first summon, hides the panel (`alpha = 0`) to mask the rebuild,
**notifies the trial/upsell scheduler** via
`ProTransitionManager.shared.onSwitcherShown()` (`App.swift:328`, see §6),
starts the search session, runs `updatesBeforeShowing`, picks the initial
selection, then displays after `Preferences.windowDisplayDelay`. If the same
shortcut is held, it cycles instead (`:347-350`).
- `App.buildUiAndShowPanel()` (`App.swift:353-369`) — updates Appearance, swaps
the background effect view, refreshes UI, calls `TilesPanel.shared.show()`,
previews the selected window, kicks off thumbnail capture.
- `App.refreshUi(preserveScrollPosition)` (`App.swift:293-305`) — the in-session
redraw: `Windows.updateSelectedWindow()` → `TilesPanel.updateContents(...)` →
VoiceOver → `WindowThumbnails.previewSelectedIfNeeded()` →
`Applications.refreshBadgesAsync()`. Heavily guarded by
`SwitcherSession.isActive` between each step (race-safety).
- `App.refreshOpenUiAfterExternalEvent(...)` (`App.swift:284-291`) — throttled
redraw triggered by AX events (window created/moved/focused/destroyed).
- `App.hideUi(keepPreview)` (`App.swift:63-79`) — tears down the session:
`SwitcherSession.current = nil`, `UsageStats.resetSession()`, end search,
toggle context-menu/cursor/trackpad event handling off, order the panel out,
and **notify the scheduler** via
`ProTransitionManager.shared.onSwitcherDismissed()` (`App.swift:78`, see §6).
### 2.4 `SwitcherSession` — per-invocation state
`SwitcherSession` (`src/switcher/SwitcherSession.swift`) holds everything scoped
to one show: `shortcutIndex`, `isFirstSummon`, `forceDoNothingOnRelease`,
`selectedIndex`, `hoveredIndex`, `selectedTarget` (window id for stable
re-selection), `searchQuery`. `SwitcherSession.current != nil` is the canonical
"panel is conceptually shown" flag (`isActive`, `:11`).
`SwitcherSession.activeShortcutIndex` (`:14`) is read by essentially every
per-shortcut effective-preference lookup in the UI.
---
## 3. Cycling, selection, hover, and focus
### 3.1 Selection state
Selection is stored on `SwitcherSession` (`selectedIndex`, `hoveredIndex`,
`selectedTarget`). The canonical list `Windows.list` is index-aligned with
`TilesView.recycledViews`.
### 3.2 Selection decisions (pure kernel)
`SelectionResolver` (`src/switcher/state/SelectionResolver.swift`) is a pure,
unit-tested kernel. `Windows` projects `list` into `[SelectionWindow]`
(`Windows.selectionSnapshot`, `Windows.swift:185-193`), builds `SelectionInputs`
(`makeSelectionInputs`, `:195-204`), and:
- On show: `setInitialSelectedAndHoveredWindowIndex()` (`Windows.swift:163-172`)
→ `SelectionResolver.initialPickIndex(...)`.
- On every refresh: `updateSelectedWindow()` (`Windows.swift:174-182`) →
`SelectionResolver.decide(...)` → `applySelectionDecision(...)` (`:206-223`).
`makeSelectionInputs` reads `Preferences.windowOrder[shortcutIndex]` to set
`useLastFocusedRule` (`Windows.swift:200-201`).
### 3.3 Cycling
- `App.cycleSelection(direction, allowWrap)` (`App.swift:248-256`) dispatches:
up/down → `TilesView.navigateUpOrDown(...)`; left/right →
`Windows.cycleSelectedWindowIndex(step, allowWrap)`.
- `Windows.cycleSelectedWindowIndex` (`Windows.swift:272-284`) and
`selectedWindowIndexAfterCycling` (`:286-297`) skip non-displayed windows and
handle wrap-around suppression on key-repeat.
- `TilesView.navigateUpOrDown` (`TilesView.swift:367-384`) and `nextRow`
(`:341-365`) handle row-based vertical navigation, respecting RTL layout.
- `updateSelectedAndHoveredWindowIndex(newIndex, fromMouse)`
(`Windows.swift:238-270`) is the single mutation point. It distinguishes hover
(mouse) from focus (keyboard or mouse-with-`mouseHoverEnabled`), updates the
highlight (`TilesView.highlight`), scrolls the focused tile into view, triggers
the window preview (`WindowThumbnails.previewSelectedIfNeeded()`), and notifies
VoiceOver. Mouse hover honors `Preferences.mouseHoverEnabled` (`:255`).
### 3.4 Highlight rendering
`TilesView.highlight(index)` (`TilesView.swift:324-339`) draws the per-tile
highlight and updates `TileUnderLayer` with the focused and (distinct) hovered
tile frames.
### 3.5 Focus / activation
When the user commits (key-up in focus-on-release, or the focus shortcut):
- `App.focusTarget()` (`App.swift:96-101`) → `App.focusSelectedWindow(...)`
(`:263-275`) → `Window.focus()` (`Window.swift:245-275`).
- `Window.focus()` handles three cases: AltTab's own windows, windowless apps
(launch/activate), and normal windows (private SkyLight
`_SLPSSetFrontProcessWithOptions` + `makeKeyWindow` byte-poking ported from
Hammerspoon, `Window.swift:277-288`, then `axUiElement.focusWindow()`).
- Optional cursor-follows-focus via `App.moveCursorToSelectedWindow`
(`App.swift:277-282`), gated on `Preferences.cursorFollowFocus`.
Window-management actions on the selected window are wired in `ShortcutActions`
(`src/switcher/ShortcutAction.swift:28-32`): `close()`, `minDemin()`,
`toggleFullscreen()`, `application.quit()`, `application.hideOrShow()` (all in
`Window.swift`/`Application.swift`). None of these are paywalled.
---
## 4. Keyboard / shortcut event flow
### 4.1 Registration
`KeyboardEvents` (`src/events/KeyboardEvents.swift`) installs:
- **Carbon global hotkeys** (`RegisterEventHotKey`) for the `nextWindowShortcut*`
and `holdShortcut*` slots (`:104-120`, IDs from
`KeyboardEventsTestable.globalShortcutsIds`,
`src/events/KeyboardEventsTestable.swift:4-9`).
- A **local NSEvent monitor** for keyDown/keyUp (`:123-130`).
- A **CGEvent tap** on `.cghidEventTap` for `.flagsChanged` and `.keyDown`
(`:132-152`). The `.keyDown` path only absorbs **Esc** (and only when a
shortcut binds Esc and the switcher is active) to beat the macOS 26 Game
Overlay hook on `⌘⎋` (`:33-44`, `anyShortcutUsesEscape` at `:20`).
Registration is driven from `ControlsTab`
(`src/preferences/.../ControlsTab.swift:781` calls
`KeyboardEvents.addGlobalShortcut`). `addEventHandlers()` is called once at
startup (`App.swift:402`).
### 4.2 Matching and dispatch
All paths funnel into `handleKeyboardEvent(...)`
(`src/events/KeyboardEventsTestable.swift:13-24`):
1. If the search field is being edited and the panel is key, the keyDown is first
offered to `TilesView.handleSearchEditingKeyDown` (`:14-19`).
2. `triggerMatchingShortcuts(...)` (`:49-66`) iterates `ControlsTab.shortcuts`,
and for each `ATShortcut` calls `matches(...)` then `shouldTrigger()`, and if
both pass, `executeAction(isARepeat)`.
`ATShortcut` (`src/switcher/ATShortcut.swift`) encapsulates one bound shortcut:
`matches(...)` (`:21-41`) does global-id and modifier/keycode matching;
`modifiersMatch(...)` (`:43-61`) handles the hold-modifier semantics and the
"base key without hold modifiers when panel open" case;
`shouldTrigger()` (`:63-80`) gates by scope (global/local), trigger phase
(down/up), session shortcut index, and — for the key-up path —
`Preferences.effectiveShortcutStyle(...) == .focusOnRelease`;
`redundantSafetyMeasures()` (`:90-110`) is a safety net for dropped/out-of-order
key-up events.
### 4.3 Actions
`ShortcutActions.execute(id)` (`src/switcher/ShortcutAction.swift:49-70`) maps an
id to behavior:
- A static table `ShortcutActions.all` (`:9-41`) maps named ids to closures
(`focusWindowShortcut`, `previousWindowShortcut`, arrow/vim cycling,
`cancelShortcut`, `closeWindowShortcut`, `minDeminWindowShortcut`,
`toggleFullscreenWindowShortcut`, `quitAppShortcut`, `hideShowAppShortcut`,
`searchShortcut`, `lockSearchShortcut`).
- Prefix-matched ids: `holdShortcut*` → `App.focusTarget()`;
`nextWindowShortcut*` → `App.showUiOrCycleSelection(index, false)`.
- **A Pro gate is applied at the top** for `holdShortcut`/`nextWindowShortcut`
slots with index ≥ 1 (`ShortcutAction.swift:50-58`, see §6).
### 4.4 Key repeat
`KeyRepeatTimer` (`src/switcher/KeyRepeatTimer.swift`) implements artificial
key-repeat for next/previous-window cycling when the bound shortcut has no
keycode (modifier-only). It reads the system `KeyRepeat`/`InitialKeyRepeat`
defaults (`:41-42`) and polls hardware modifier state to detect release
(`holdModifierIsReleased`, `:62-70`). No paywall coupling.
### 4.5 Other event monitors (`src/events/`)
- `CursorEvents` (`src/events/CursorEvents.swift`) — `.cgSessionEventTap` for
mouse down/up/moved; handles click-to-focus, click-outside-to-dismiss
(`:88`), middle-click-to-close (`:120-129`), and hover with a "deadzone" to
ignore tiny trackpad jitter (`:178-189`). Toggled on/off with the session.
- `ScrollwheelEvents` (`src/events/ScrollwheelEvents.swift`) — blocks continuous
(trackpad) scroll while letting discrete (mouse) scroll through.
- `TrackpadEvents` (`src/events/TrackpadEvents.swift`) — gesture-based cycling.
- `ContextMenuEvents` (`:ContextMenuEvents.swift`) — right-click menu on tiles.
- Plus environment monitors that trigger refreshes: `SpacesEvents`,
`ScreensEvents`, `DockEvents`, `SleepWakeEvents`, `InputSourceEvents`,
`SystemAppearanceEvents`, `SystemScrollerStyleEvents`,
`RunningApplicationsEvents`, `WindowCaptureEvents` (thumbnail capture),
`PreferencesEvents`, `UserDefaultsEvents`, `CliEvents`, `AxEventRouting`.
**`PreferencesEvents`** contains one paywall touchpoint
(`src/events/PreferencesEvents.swift:62`, see §6).
---
## 5. Search
Search is a first-class part of the switcher UI and is **Pro-gated** (see §6).
- `Search` (`src/switcher/Search.swift`) computes per-window match/relevance
using the `SearchTestable` fuzzy matcher, caching results on the `Window`
(`swBestSimilarity`, `lastSearchQuery`).
- `Windows.updateSearchQuery(...)` (`Windows.swift:14-35`) updates the session
query and the "select best match / restore default" flags, then re-sorts.
- `Windows.shouldDisplay(window)` (`Windows.swift:10-12`) is
`shouldShowTheUser && Search.matches(window, query)`. This single predicate is
consulted everywhere (layout, cycling, selection snapshot, viewport).
- `SearchModeResolver` (`src/switcher/state/SearchModeResolver.swift`) is the pure
search-mode state machine (`off`/`editing`/`locked`). Its `enableEditing` and
`lock` decisions take a `canSearch` / `canLockSearch` `Bool`; the caller
(`TilesView`) computes that bool from `ProFeature.*.attemptUse()` (`:68-86`).
- `TilesView` translates those decisions into AppKit side effects
(`enableSearchEditing`, `lockSearchMode`, `disableSearchMode`,
`TilesView.swift:59-128`).
- Sorting respects per-shortcut order/group preferences via `WindowOrderResolver`
(`src/switcher/state/WindowOrderResolver.swift`, `OrderSortType` =
`recentlyFocused`/`recentlyCreated`/`alphabetical`/`space`) and search
relevance (`Windows.sort`, `Windows.swift:322-343`).
---
## 6. Pro / paywall touchpoints surfacing in this subsystem
The switcher subsystem itself is mostly free of paywall logic — the gating lives
in `src/pro/` (`ProFeature`, `ProTransitionManager`, `LicenseManager`,
`ProGatedPreferences`) — but it is *invoked* from a small number of well-defined
sites in scope. The pattern is consistent: pure kernels never gate; the
imperative wrapper calls `ProFeature.<case>.attemptUse()` (or reads an
"effective" preference that silently downgrades when Pro is locked) at the real
use moment.
`ProFeature.attemptUse()` (`src/pro/ProFeature.swift:74-83`) returns `true` when
Pro/trial is available or a "free pass session" is active; otherwise it consults
the Day1→Day35 nag ladder for hard-gated features. For a fully-free build, every
one of these should resolve to "always allowed."
### Hard gates invoked from the switcher
1. **Extra shortcut slots (index ≥ 1)** — `ShortcutAction.swift:50-58`
(`ShortcutActions.execute`): pressing any `holdShortcut`/`nextWindowShortcut`
slot past the first calls `ProFeature.extraShortcut(index:).attemptUse()` and
`return`s (does nothing) if denied. Removing this gate makes all configured
shortcut variants always work.
2. **Search in the switcher** — `TilesView.swift:92`
(`enableSearchEditing`): `ProFeature.searchInSwitcher.attemptUse()` is passed
as `canSearch` to `SearchModeResolver.enableEditing`. If denied, the kernel
returns `.proGateBlocked(.search)` and editing never starts.
3. **Lock search results** — `TilesView.swift:79` (`lockSearchMode`):
`ProFeature.lockSearchInSwitcher.attemptUse()` passed as `canLockSearch` to
`SearchModeResolver.lock`.
### Degradable preferences read via "effective" getters
These do not call `attemptUse()` directly; instead the switcher reads
`Preferences.effective*` getters, and the *stored* value is silently downgraded
when Pro is locked (via `ProGatedPreferences`). The switcher consumes them at:
4. **Appearance style** (`appIcons`/`titles` are Pro;
`ProFeature.appIconsAndTitlesStyle`) — read via
`Preferences.effectiveAppearanceStyle(...)`. Surfaces in the switcher at, e.g.,
`TilesView.swift:388, 563, 614`, `TilesPanel.swift:101, 128`,
`TileView.swift:52, 64, 82`. The Pro-aware read path for index 0 is
`ProGatedPreferences.appearanceStyleOverride0.read()`
(`Preferences.swift:311-315`).
5. **Auto size** (`ProFeature.autoSize`) — read via
`Preferences.effectiveAppearanceSize(...)` at `TilesView.swift:388, 391`
(and `TilesPanel`/`Appearance`). Pro-aware read at
`Preferences.swift:317-321`.
6. **Search-on-release shortcut style** (`ProFeature.searchOnReleaseShortcut`) —
read via `Preferences.effectiveShortcutStyle(...)` at `ATShortcut.swift:70,
96`, `App.swift:329`, `ShortcutAction.swift:22`. Pro-aware read at
`Preferences.swift:328-332`. (`focusOnRelease` itself is free; the
`searchOnRelease` value is the Pro one.)
### Preview selected window
7. **`PreviewPanel`** (`src/switcher/PreviewPanel.swift`) and
`WindowThumbnails.previewSelectedIfNeeded()`
(`src/switcher/state/WindowThumbnails.swift:6-19`) implement the "preview the
selected window full-size" feature, driven by
`Preferences.effectivePreviewSelectedWindow(...)`
(`Preferences.swift:334-337`). **As written, this preference is NOT in
`ProFeature` / `ProGatedPreferences`** — `effectivePreviewSelectedWindow`
reads the stored bool directly with no Pro-aware override. So in the current
code preview-selected-window is effectively a free feature gated only by the
Screen-Recording permission. Worth confirming against `src/pro/` during
removal, but it does not appear to need changes for a free build.
### Trial/upsell scheduler hooks
8. The switcher show/hide lifecycle notifies the trial-nag scheduler:
`ProTransitionManager.shared.onSwitcherShown()` (`App.swift:328`) and
`onSwitcherDismissed()` (`App.swift:78`). These are the hooks the Day1→Day35
nag system uses to decide when to interrupt the user with upsell UI. For a free
build these calls should be removed (or made no-ops).
### Usage analytics
9. `UsageStats.recordTrigger(...)` (`App.swift:315`) and
`UsageStats.recordSearchIfFirst()` (`TilesView.swift:183`), reset via
`UsageStats.resetSession()` (`App.swift:67`). `UsageStats`
(`src/util/UsageStats.swift`) records trigger/search counts (including
`triggersExtraShortcuts`, `triggersAppIcons`, etc.) into a private
`UserDefaults` suite. This feeds the upsell messaging ("you used X N times").
Not strictly a gate, but part of the paywall apparatus; safe to strip or stub
for a free build.
> Note: `ProFeature.searchOnReleaseShortcut` is mapped to the "extra shortcuts"
> marketing copy and grouped under keyboard shortcuts
> (`ProFeature.swift:52`), which is why the trial copy lumps them together.
---
## 7. Preferences interaction summary
The switcher reads preferences in two modes:
- **Per-shortcut "effective" reads**, keyed on
`SwitcherSession.activeShortcutIndex`. These are the ones that can be Pro-gated:
`effectiveAppearanceStyle`, `effectiveAppearanceSize`, `effectiveShortcutStyle`,
`effectivePreviewSelectedWindow`, `effectiveAppearanceTheme`
(`Preferences.swift:311-337`). Window-filter preferences are snapshotted once per
show in `WindowFilters.snapshot()` (`Windows.swift:507-519`) for performance.
- **Plain reads** scattered throughout: `Preferences.onlyShowMainWindows()`,
`windowOrder`, `mouseHoverEnabled`, `cursorFollowFocus`, `windowDisplayDelay`,
`fadeOutAnimation`, `previewFadeInAnimation`, `captureWindowsInBackground`, the
`exceptions` list (consumed by `ExceptionMatcher`), etc.
`Appearance` (`src/switcher/Appearance.swift`) centralizes all derived layout
constants (paddings, font, theme, max-width-on-screen) and is recomputed via
`Appearance.update()` on each show.
---
## 8. Removal notes for a clean free build
To free everything in this subsystem without breaking the build, the cleanest
approach is to make the gates at the call sites always pass rather than ripping
`src/pro/` out from under the switcher first:
- **Make `ProFeature.attemptUse()` always return `true`.** This single change
neutralizes the three hard gates invoked from scope
(`ShortcutAction.swift:56`, `TilesView.swift:79, 92`) with no signature changes.
- **Make the `Preferences.effective*` getters read the raw stored value** (i.e.
bypass `ProGatedPreferences.*Override0.read()` downgrades at
`Preferences.swift:313, 319, 330`) so `appIcons`/`titles`/`auto`/`searchOnRelease`
are honored regardless of license state. Equivalently, make
`ProGatedPreferences.read()` return the stored Pro value unconditionally.
- **Stub `ProTransitionManager.shared.onSwitcherShown()` /
`onSwitcherDismissed()`** (`App.swift:78, 328`) to no-ops, or delete the calls,
to kill the trial-nag interrupts triggered by the switcher lifecycle.
- **`UsageStats` calls** (`App.swift:67, 315`; `TilesView.swift:183`) can be left
(harmless) or stubbed; they only feed upsell copy.
- **`PreviewPanel` / preview-selected-window needs no change** for the free build
per current code (not actually Pro-gated; see §6.7) — but verify against
`src/pro/` in the licensing-focused audit section.
Risks / things to verify in the dedicated `src/pro/` audit:
- `SearchModeResolver` and `SelectionResolver` are pure and have unit tests; do
**not** move gating into them — keep gates at the `TilesView`/`ShortcutAction`
call sites so the kernels' tests stay valid.
- Removing `ProTransitionManager`/`LicenseManager` types outright will break these
call sites at compile time; either keep thin stubs or update all call sites in
the same change. The keyboard/selection/render paths have no other Pro coupling,
so once the four/five sites above are neutralized the switcher is fully free.
- `ProFeatureCopy` / marketing strings are referenced only by `src/pro/` UI, not by
the switcher, so they are out of scope here.
+368
View File
@@ -0,0 +1,368 @@
# 03 — Preferences System & Feature-Gating Mechanism
Audit scope: the preferences system (`src/preferences/`) and the Pro feature-gating mechanism
that sits on top of it. This is the heart of how the paywall degrades and hides features. This
document is the authoritative reference for the removal plan; every gated preference is enumerated
with its exact key, Pro values, and free equivalent.
---
## 1. How the preferences system works (no-paywall baseline)
### 1.1 Storage and defaults
- `Preferences.defaultValues` (`src/preferences/Preferences.swift:6-78`) is the single dictionary of
every default, registered into `UserDefaults.standard` via `registerDefaults()`
(`Preferences.swift:179-181`). All values are stored as **strings** (e.g. `"true"`, `"100"`, or a
stringified enum index like `AppearanceStylePreference.thumbnails.indexAsString`).
- Macro (enum-backed) preferences store the **enum case index** as a string. The index is derived by
the `CaseIterable where Self: Equatable` extension `index` / `indexAsString`
(`src/macos/api-wrappers/HelperExtensions.swift:330-337`).
- Reads go through `CachedUserDefaults` (`Preferences.swift:432-523`), a thread-safe cache keyed by
preference name. `macroPref(key, allCases)` reads the stored int and maps it to `allCases[index]`,
resetting to the default if the value can't be parsed (`getThenConvertOrReset`, lines 503-518).
- Writes go through `Preferences.set` / `setShortcut` / `remove` (`Preferences.swift:191-228`). Each
write invalidates the cache and, unless `notify: false` is passed, fires
`PreferencesEvents.preferenceChanged(key)` (`Preferences.swift:216-218`). **This notify hook is the
single chokepoint the paywall hijacks to bounce setters to the Upgrade tab — see §3.2.**
### 1.2 Per-shortcut model and overrides
- Most behavioral prefs are per-shortcut, indexed by `indexToName(baseName, index)`
(`Preferences.swift:421-423`): index 0 has no suffix (`appearanceSizeOverride`), index 1 gets
suffix `2` (`appearanceSizeOverride2`), etc. (`nameToIndex` is the inverse, lines 425-429.)
- `maxShortcutCount = 9`, `minShortcutCount = 1` (`Preferences.swift:160-161`). `shortcutCount`
clamps the stored count into that range (lines 162-164).
- Appearance **overrides** let any shortcut deviate from the global appearance. The 5 override base
names are `appearanceStyleOverride`, `appearanceSizeOverride`, `appearanceThemeOverride`,
`shortcutStyleOverride`, `previewFocusedWindowOverride` (`Preferences.swift:258-261`), each mapped
back to its global key by `overrideToGlobalKey` (lines 264-270).
- `hasOverride(baseName, index)` (lines 275-277) consults `Preferences.all` (the cached
`persistentDomain` snapshot, lines 238-244), which **excludes registered defaults**. So an
untouched override reports `false` even though its key has a registered default. The override
defaults are deliberately set to the **free-tier value** (`Preferences.swift:67-75`) so that
`snapshotAndDowngrade` is a no-op for unset overrides.
- `effectiveAppearanceStyle/Size/Theme/ShortcutStyle/PreviewSelectedWindow(index)` (lines 311-337)
resolve the value a given shortcut actually uses: the override if set, else the global. **For
index 0, the three Pro-gated overrides route through `ProGatedPreferences.*Override0.read()`**
(lines 313, 319, 330) — meaning index-0 overrides are degraded exactly like the globals.
### 1.3 Migrations
`PreferencesMigrations` (`src/preferences/PreferencesMigrations.swift`) runs once per version bump on
launch via `Preferences.initialize()` (`Preferences.swift:168-172`). It is largely paywall-agnostic
historical data migration. **The only paywall coupling** is one line in `migratePreferences()`:
- `PreferencesMigrations.swift:20` — `ProTransitionState.markFreshInstallIfUnknown(existingVersion == nil)`.
This is the *only* place that can still observe a nil `preferencesVersion`, so it persists the
fresh-install signal the trial scheduler later reads. For a free build this single call must be
removed along with `ProTransitionState`.
No other migration references Pro/license/trial state.
---
## 2. The Pro-gating mechanism (the heart of the paywall)
The gating mechanism has two complementary halves:
1. **Degradable preferences** — stored values that get *silently downgraded* to a free equivalent
when Pro locks, snapshotted for later restore, and *intercepted at write-time* in Settings.
2. **Hard-gated runtime actions** — features with no stored preference, gated at use-time (extra
shortcuts, in-switcher search, lock-search).
### 2.1 `isProLocked` — the master gate
`LicenseManager.shared.isProLocked` (`src/pro/license/LicenseManager.swift:67-72`) is the single
boolean every gate consults:
```swift
var isProLocked: Bool {
switch state {
case .pro, .trial: return false
case .proExpired, .trialExpired: return true
}
}
```
So a user is "locked" once the 14-day trial (`trialDuration = 14`, line 17) expires or a Pro license
becomes invalid. `isProAvailable` is the inverse-ish (`pro` or `trial`).
For a fully-free build, the cleanest semantic equivalent is **`isProLocked == false` always** (and
`isProAvailable == true` always). Every gate below then becomes a no-op pass-through.
### 2.2 The `PreferenceDefinition` / `PreferenceGate` engine
`src/preferences/PreferenceDefinition.swift` is the single source of truth for degradable prefs.
- `PreferenceGate<T>` (lines 7-11) holds three things:
- `freeEquivalent: T` — the value returned/written when locked.
- `rememberedKey: String` — the `ProTransitionState` key under which the original Pro index is
snapshotted for restore + "ghost UI".
- `isProValue: (T) -> Bool` — predicate identifying which stored values count as "Pro".
- `PreferenceDefinition<T>` (lines 18-74) wraps `key`, `default`, and an optional `gate`, and exposes
the read/downgrade/restore operations:
- **`read()`** (lines 32-44): the hot-path getter. If there's no gate or `!isProLocked`, returns
the stored value verbatim. When **locked**, three branches:
1. If a **free-pass session** is active and a remembered Pro index exists → returns the
remembered Pro value (so the switcher renders the user's Pro choice "one last time").
2. Else if the stored value is still a Pro value (transient, before
`onProLockEngaged()` has downgraded it) → returns `freeEquivalent`.
3. Else → returns stored (already downgraded).
- **`snapshotAndDowngrade()`** (lines 51-57): if stored is a Pro value, overwrites it with
`freeEquivalent` via `Preferences.set` (which **fires the notify hook**), and returns the
original index for the caller to remember. No-op if no gate or already free.
- **`restore(from:)`** (lines 62-65): writes the remembered index back with `notify: false`.
- **`isStoredValuePro()`** (lines 69-73): true iff stored is currently a Pro value, regardless of
lock state — used by the notify hook (§3.2).
- `AnyProGatedPreference` (lines 79-85) is the type-erased view (Int/Bool returns only) that the
lock/unlock passes iterate over. `PreferenceDefinition.erased` (lines 87-96) produces it.
### 2.3 `ProGatedPreferences` — the registry of gated prefs
`ProGatedPreferences` (`PreferenceDefinition.swift:102-170`) declares **six** gated
`PreferenceDefinition`s (3 globals + 3 index-0 overrides). `ProGatedPreferences.all` (lines 157-164)
is the list iterated on lock/unlock. `forPreferenceKey(_:)` (lines 167-169) is the lookup the notify
hook uses. **This enum is the precise enumeration source for the table in §4.**
### 2.4 `ProFeature` — capability registry
`src/pro/ProFeature.swift` enumerates every gated capability (degradable + hard-gated):
- Cases (lines 9-16): `.appIconsAndTitlesStyle`, `.autoSize`, `.searchOnReleaseShortcut`
(degradable) and `.extraShortcut(index:)`, `.searchInSwitcher`, `.lockSearchInSwitcher`
(hard-gated).
- `gateKind` (lines 27-33): `.degradable`, `.hardGated`, or `.degradableAndHardGated`.
- `gatedPreference` (lines 37-44): maps the 3 degradable features to their
`ProGatedPreferences.*.erased` definition.
- `attemptUse()` (lines 74-83): the runtime gate. Returns `true` if `isProAvailable` or a free-pass
session is active; otherwise hard-gated features defer to
`ProTransitionManager.attemptHardGatedFeature`, and degradable features always return `true`
(they're gated at write-time, not use-time).
- `isStoredValuePro(preferenceKey:)` (lines 87-89): delegates to the registry; used by the notify hook.
### 2.5 Lock / unlock passes — downgrade & restore
`ProTransitionState` (`src/pro/scheduling/ProTransitionState.swift`) owns the snapshot/restore logic
and the `remembered*` indices (persisted in the `<bundleId>.license` UserDefaults suite under keys
prefixed `proTransition.`):
- **`onProLockEngaged()`** (lines 73-79): iterates `ProGatedPreferences.all`, calls
`snapshotAndDowngrade()` on each, and stores the returned Pro index under the pref's
`rememberedKey`. Triggered when the license locks via `ProTransitionManager.onLicenseStateChanged`
→ `onProLockEngaged` (`ProTransitionManager.swift:179-181, 259-262`), and also from the Day 15
Full-Upgrade / Proactive paths (lines 248-249, 256). Idempotent (re-entry no-ops because stored is
already free).
- **`onProUnlocked()`** (lines 85-92): iterates the registry, restores each remembered index via
`restoreFromIndex` (with `notify: false`), then clears the remembered key. Triggered on activation
via `LicenseManager.onBeforeProUnlock` (wired in `App.swift`) and `ProTransitionManager.onProUnlocked`.
- `rememberedAppearanceStyle/Size/ShortcutStyle` + the three `*Override` variants (lines 36-62) are
typed accessors over those `proTransition.remembered*` keys.
### 2.6 Free-pass session & ghost UI
- `ProTransitionManager.isFreePassSessionActive` (`ProTransitionManager.swift:135-142`) is a
session-only flag, true between a free-pass grant and switcher dismissal. While active,
`PreferenceDefinition.read()` returns the **remembered Pro value** (branch 1 above), so the
switcher shows the user's Pro selection one last time before `[C]` upsell fires. Flipping the flag
triggers `App.resetPreferencesDependentComponents()` so `TilesView` re-renders.
- The remembered indices also drive the "ghost outline" in Settings (the Pro selection is shown
badged/dimmed even though the live value is the free equivalent).
---
## 3. How gating reaches the UI
### 3.1 Settings controls — write-time interception + badges
`LabelAndControl.makeImageRadioButtons` (`src/preferences/settings-window/LabelAndControl.swift:74-116`)
takes a `proGatedIndices: Set<Int>` parameter. On click, **if `isProLocked` and the clicked index is
gated** (lines 86-92): it snaps the radio group back to the stored value and calls
`UpgradeTab.navigateToUpgradeTab()` instead of writing. This is the generic interception primitive.
`AppearanceTab` (`src/preferences/settings-window/tabs/appearance/AppearanceTab.swift`) wires the three
global gated controls:
- **Appearance Style** radios (lines 458-463): `proGatedIndices: proGatedAppearanceStyleIndices()`
which is "everything but `.thumbnails`" (lines 700-703 → indices `{1, 2}` = appIcons, titles).
`addProBadgesToStyleButtons` (lines 688-698) attaches a `ProBadgeView` to every non-thumbnails
card.
- **Appearance Size** segmented (lines 474-490): `wrapAppearanceSizeProLockIntercept` (lines 662-679)
intercepts the `.auto` segment (last index) when locked — snaps back to stored, calls
`navigateToUpgradeTab()`. `addProBadgeToAutoSegment` (lines 681-686) badges the Auto segment.
- **After-keys-released / shortcutStyle** segmented (lines 566-583):
`wrapShortcutStyleProLockIntercept` (lines 585-598) intercepts the `.searchOnRelease` segment.
`addProBadgeToShortcutStyleSegment` (lines 606-611) badges the Search segment.
- `refreshProLockUi()` (lines 705+) re-syncs these three controls when
`ProTransitionManager.proLockStateDidChangeNotification` fires (observer registered lines 414-419),
so the live Settings window updates on lock/unlock without a reopen.
The per-shortcut override panes mirror this exactly in `ShortcutEditor.swift`
(`src/preferences/settings-window/tabs/controls/ShortcutEditor.swift`):
- `ShortcutOverrideSegmented` / `ShortcutOverrideRadios` carry their own `proGatedIndices` (lines
540, 648). The override `AppearancePane` (lines 425-465) gates: style → `{appIcons, titles}` (line
429), size → `{.auto}` (line 437), theme → `[]` (line 449, **not gated**), shortcutStyle →
`{.searchOnRelease}` (line 459). Preview toggle is **not** gated.
- The write-time intercept lives in `handleClick` for both controls (lines 596-621 for segmented,
702-717 for radios): if a gated index is clicked while locked, snap back + `navigateToUpgradeTab()`.
### 3.2 The notify-hook bounce (write-side enforcement)
`PreferencesEvents.preferenceChanged(_:)` (`src/events/PreferencesEvents.swift:53-75`) contains the
critical line **62-64**:
```swift
if LicenseManager.shared.isProLocked && ProFeature.isStoredValuePro(preferenceKey: key) {
UpgradeTab.navigateToUpgradeTab()
}
```
Any write that lands a Pro value into a gated key while locked bounces the user to Upgrade. This is
why `onProUnlocked` restores with `notify: false` (otherwise restoring a Pro value during a
still-locked window would yank the user to Upgrade). For the free build, removing this branch is
mandatory.
### 3.3 Extra-shortcut sidebar gating (`ControlsTab`)
- `ControlsTab` badges every shortcut row at index ≥ 1 as Pro (`row.setProBadge(index >= 1)`,
`src/preferences/settings-window/tabs/controls/ControlsTab.swift:515`).
- `addShortcutSlot()` (lines 586-598): if `currentCount >= 1 && isProLocked`, it refuses to add the
slot and calls `navigateToUpgradeTab()` (lines 589-592). **So free users are hard-capped at exactly
1 shortcut.**
### 3.4 Runtime hard-gates (switcher)
- Extra shortcut trigger: `ShortcutAction.swift:56` — `if !ProFeature.extraShortcut(index: index).attemptUse() { return }`.
- In-switcher search: `TilesView.swift:92` gates editing on `ProFeature.searchInSwitcher.attemptUse()`.
- Lock-search: `TilesView.swift:79` gates on `ProFeature.lockSearchInSwitcher.attemptUse()`.
- `searchInSwitcher` / `lockSearchInSwitcher` map to copy "Search"; `searchOnReleaseShortcut` is the
Settings-side degradable twin of the same capability.
---
## 4. ENUMERATION — every Pro-gated preference (exact)
There are **6 degradable preference definitions** (3 globals + 3 index-0 overrides) plus runtime
hard-gates with no backing preference. Indices below are the `CaseIterable` order (and thus the
stored string value).
### 4.1 Degradable preferences (downgraded on lock, snapshot/restore)
Source: `ProGatedPreferences` (`PreferenceDefinition.swift:103-153`).
| # | Preference key | Type / enum | `isProValue` (Pro values) | Pro index value(s) | Free equivalent (value written on lock) | Free index | rememberedKey | Default |
|---|----------------|-------------|---------------------------|--------------------|------------------------------------------|-----------|---------------|---------|
| 1 | `appearanceStyle` | `AppearanceStylePreference` | `$0 != .thumbnails` | `.appIcons` (1), `.titles` (2) | `.thumbnails` | 0 | `rememberedAppearanceStyle` | `.thumbnails` |
| 2 | `appearanceSize` | `AppearanceSizePreference` | `$0 == .auto` | `.auto` (3) | `.medium` | 1 | `rememberedAppearanceSize` | `.auto` |
| 3 | `shortcutStyle` | `ShortcutStylePreference` | `$0 == .searchOnRelease` | `.searchOnRelease` (2) | `.doNothingOnRelease` | 1 | `rememberedShortcutStyle` | `.focusOnRelease` |
| 4 | `appearanceStyleOverride` (shortcut 0 only) | `AppearanceStylePreference` | `$0 != .thumbnails` | `.appIcons` (1), `.titles` (2) | `.thumbnails` | 0 | `rememberedAppearanceStyleOverride` | `.thumbnails` |
| 5 | `appearanceSizeOverride` (shortcut 0 only) | `AppearanceSizePreference` | `$0 == .auto` | `.auto` (3) | `.medium` | 1 | `rememberedAppearanceSizeOverride` | `.medium` |
| 6 | `shortcutStyleOverride` (shortcut 0 only) | `ShortcutStylePreference` | `$0 == .searchOnRelease` | `.searchOnRelease` (2) | `.doNothingOnRelease` | 1 | `rememberedShortcutStyleOverride` | `.doNothingOnRelease` |
Notes:
- Enum orders: `AppearanceStylePreference = [thumbnails(0), appIcons(1), titles(2)]`
(`MacroPreferences.swift:284-287`); `AppearanceSizePreference = [small(0), medium(1), large(2),
auto(3)]` (lines 308-312); `ShortcutStylePreference = [focusOnRelease(0), doNothingOnRelease(1),
searchOnRelease(2)]` (lines 100-103).
- **Note the asymmetry for `appearanceSize`/`shortcutStyle`**: the *registered default* is the Pro
value (`.auto` / `.focusOnRelease` for the global), but the *free equivalent written on lock* is
`.medium` / `.doNothingOnRelease`. (For `appearanceStyle` the default `.thumbnails` is already
free.) Override-key defaults are intentionally the **free** value so unset overrides never get
snapshotted (`Preferences.swift:67-75`, `PreferenceDefinition.swift:130-153`).
- Index-0 overrides (4-6) are the only override indices snapshotted, because indices ≥ 1 are
unreachable while locked (extra shortcuts are hard-gated). `Preferences.removeOverride` also clears
the matching remembered key for these three (`Preferences.swift:282-298`).
- The corresponding index-1..8 override keys (`appearanceStyleOverride2..9`, etc.) and the two
**non-gated** overrides (`appearanceThemeOverride`, `previewFocusedWindowOverride`) are NOT gated.
### 4.2 Hard-gated runtime features (no backing preference)
Source: `ProFeature` (`ProFeature.swift:13-16`), enforcement sites in §3.3–3.4.
| Feature | Gate kind | Enforcement | Free-tier effect when locked |
|---------|-----------|-------------|------------------------------|
| Extra shortcuts (`shortcutCount` > 1, slots index ≥ 1) | hardGated | `ControlsTab.addShortcutSlot` (ControlsTab.swift:589-592) + `ShortcutAction.swift:56` | Capped at 1 shortcut; extra-shortcut chord no-ops |
| In-switcher search (`searchInSwitcher`) | hardGated | `TilesView.swift:92` via `attemptUse()` | Typing-to-search disabled in switcher |
| Lock-search (`lockSearchInSwitcher`) | hardGated | `TilesView.swift:79` via `attemptUse()` | Lock-search disabled |
`searchOnReleaseShortcut` is `degradableAndHardGated` (`ProFeature.swift:30`): it is the
Settings-side degradable form (#3/#6 above) **and** its first post-expiration switcher summon can
trigger the `[C]` upsell.
---
## 5. What must change for a clean free build
The intent is: **all features unlocked, all paywall/trial/license/upsell removed**, without breaking
the build. The preferences subsystem must keep working; only the gating layered on top is removed.
### 5.1 Minimal, low-risk approach (recommended first pass)
Neuter the master gate so every check becomes a pass-through, leaving the preferences plumbing intact:
- Make `LicenseManager.shared.isProLocked` always return `false` and `isProAvailable` always `true`.
Every Settings intercept, the notify-hook bounce, the sidebar shortcut cap, and `attemptUse()`
immediately become no-ops, and `PreferenceDefinition.read()` returns stored values verbatim.
- This is the smallest change that unlocks everything. Downside: dead paywall code (badges,
`ProTransitionState`, Day-X UI, `UpgradeTab`) remains compiled in.
### 5.2 Full removal (the actual goal — requires care)
Touchpoints that must be removed/rewritten in this scope:
1. **`PreferenceDefinition.swift` (entire file)** — `PreferenceGate`, `PreferenceDefinition`,
`AnyProGatedPreference`, `ProGatedPreferences`. The getters in `Preferences.swift` that call
`ProGatedPreferences.*.read()` (lines 129, 130, 155) and the index-0 override branches in
`effectiveAppearanceStyle/Size/ShortcutStyle` (lines 313, 319, 330) must be rewritten to read
the raw value directly, e.g. `CachedUserDefaults.macroPref("appearanceStyle", AppearanceStylePreference.allCases)`.
2. **`PreferencesEvents.swift:62-64`** — delete the `isProLocked && isStoredValuePro` bounce block
(and the `ProFeature` import dependency it implies).
3. **`Preferences.swift`** — remove `overrideRememberedKey` (lines 291-298) and the
`ProTransitionState.setInt(...)` cleanup inside `removeOverride` (lines 284-286).
4. **`PreferencesMigrations.swift:20`** — remove the
`ProTransitionState.markFreshInstallIfUnknown(...)` call.
5. **`LabelAndControl.swift:74-116`** — drop the `proGatedIndices` parameter and the
`isProLocked && proGatedIndices.contains(index)` intercept (lines 86-92).
6. **`AppearanceTab.swift`** — remove `proGatedAppearanceStyleIndices`, all `ProBadgeView` attach
calls, both `wrap*ProLockIntercept` methods, `refreshProLockUi` and its
`proLockStateDidChangeNotification` observer, and the `autoSegment/shortcutStyleSegment` overlay
refs.
7. **`ShortcutEditor.swift`** — drop `proGatedIndices`/`attachBadge`/`refreshBadge` plumbing and the
locked-intercept branches in both `ShortcutOverrideSegmented.handleClick` (lines 599-607) and
`ShortcutOverrideRadios.handleClick` (lines 705-711).
8. **`ControlsTab.swift`** — remove `row.setProBadge(index >= 1)` (line 515) and the
`isProLocked` cap in `addShortcutSlot` (lines 589-592), plus the
`proLockStateDidChangeNotification` observer (line 141).
9. **Switcher hard-gates** (out of strict scope but coupled) — `ShortcutAction.swift:56`,
`TilesView.swift:79,92` call `ProFeature.*.attemptUse()`; these calls must be removed or replaced
with `true`.
10. The defaults in `Preferences.defaultValues` need no value change to unlock features (defaults
already include the Pro values, e.g. `appearanceSize = .auto`), but the **override defaults**
that were deliberately set to the free value (`appearanceSizeOverride = .medium`,
`shortcutStyleOverride = .doNothingOnRelease`, `Preferences.swift:72,74`) can stay as-is — they
only mattered for the snapshot no-op trick, which is being removed.
### 5.3 Risks / gotchas
- **`index`/`indexAsString`/`macroPref` cache plumbing is paywall-independent** and must be
preserved — it is core preferences infrastructure, not paywall code.
- **Already-locked users have downgraded stored values.** A user who ran the paywalled build past
trial expiry has `appearanceStyle`/`appearanceSize`/`shortcutStyle` already overwritten to free
equivalents in UserDefaults, with the original Pro index sitting in the `proTransition.remembered*`
keys (in the `<bundleId>.license` suite). After removal, `read()` no longer restores those — the
user keeps the free value and silently loses their old Pro selection. A free build with a **new
bundle ID** (per AGENTS.md, identity is coupled to the signature) gets a clean UserDefaults domain,
so this only affects in-place upgrades of the same bundle ID. Consider a one-time migration that
copies any `proTransition.remembered*` index back into its base key before deleting the
`proTransition.*` state — otherwise it's a silent (minor) data loss.
- **`screenRecordingDependentFeatures`** (`Preferences.swift:346-355`) iterates
`effectiveAppearanceStyle`/`effectivePreviewSelectedWindow` across all shortcuts; once those stop
routing through `read()`, behavior is unchanged but verify the permission callout still resolves
correctly when more than 1 shortcut is now reachable.
- Removing `ProGatedPreferences` will break `ProFeature.gatedPreference` and
`ProTransitionState.remembered*` accessors (compile errors) — these live in `src/pro/` and should
be deleted as a unit alongside the rest of the paywall (covered by the pro-subsystem audit).
- Test files reference these symbols: `PreferencesMigrationsTests.swift`,
`LicenseManagerTests.swift`, `ProTransitionTests.swift`, `OnActionExtensionTests.swift`, and the
`_test-support/Mocks.swift` `ShortcutStylePreference` mock — they will need updating/removal.
+282
View File
@@ -0,0 +1,282 @@
# Audit 04 — License / Activation Subsystem
> Scope: `src/pro/license/` — `LicenseManager.swift`, `LicenseState.swift`, `LicenseAPI.swift`, `RemoteLicenseClient.swift`, `LicenseCookie.swift`, `Keychain.swift`, `MachineFingerprint.swift`, `Clock.swift` (plus `LicenseManagerSpecs.md` & `LicenseManagerTests.swift`). Cross-references `src/api/Endpoints.swift`, `Info.plist`, `config/base.xcconfig`, and the app-side consumers.
>
> This is the **single source of truth** for whether the user has Pro. Every Pro gate and upsell prompt in the app reads from `LicenseManager.shared`. Removing the paywall cleanly = making this subsystem report "always Pro/free-unlocked" (or stubbing it out) without breaking the public surface the rest of the app links against.
---
## 1. The `LicenseState` model
Defined in `src/pro/license/LicenseState.swift:1-21`. It is a flat 4-case `enum LicenseState: Equatable` — **there is no separate "lifetime" enum case**:
```swift
enum LicenseState: Equatable {
case trial(daysRemaining: Int) // active trial, day count baked in
case pro // valid paid license (any variant)
case proExpired // version-limited Pro past its version cutoff
case trialExpired // trial over, OR a defensively-invalidated license
}
```
Members:
- `isProAvailable: Bool` (`LicenseState.swift:7-12`) — `true` for `.trial` and `.pro`; `false` for `.proExpired` and `.trialExpired`. This is the "can the user use Pro features right now" gate.
- `debugProfileLabel: String` (`LicenseState.swift:14-20`) — `"Trial"`, `"Pro"`, or `"Free"` (both expired cases map to `"Free"`). Used only by `src/secondary-windows/DebugProfile.swift:17`.
### "Lifetime" vs "Pro" vs "version-limited" — these are *variants*, not states
The free/trial/pro/lifetime distinction the audit brief asks about is split across two mechanisms:
1. **State** (`.trial` / `.pro` / `.proExpired` / `.trialExpired`) — the runtime entitlement.
2. **Variant slug** (a string from the backend, persisted in Keychain account `variantId`) — sub-classifies a `.pro` license:
- **Lifetime**: `LicenseManager.lifetimeVariants: Set<String> = ["pro_lifetime"]` (`LicenseManager.swift:25`). A lifetime variant has *no version cutoff, ever*.
- **Version-limited Pro**: `LicenseManager.versionLimitedVariants: [String: String] = [:]` (`LicenseManager.swift:28`) — maps a variant slug to a max supported version string (e.g. `"variant_slug": "X.Y.Z"`). **Currently empty**, so in this build every `.pro` variant behaves as unlimited and `.proExpired` is unreachable in practice (confirmed by `testVersionLimitedPastCutoffIsProExpired` in the specs, `LicenseManagerSpecs.md:55-56`).
- **Regular Pro**: any variant slug that is neither lifetime nor version-limited.
`isLifetimeVariant` (see §6) reads the persisted `variantId` and tests membership in `lifetimeVariants`. There is **no** `.lifetime` enum case — lifetime is just `.pro` + a particular variant slug.
### State transitions (from `LicenseManagerSpecs.md:18-23`)
```
.trial(daysRemaining) → .pro (user activates a key)
.trial(daysRemaining) → .trialExpired (14 days elapse)
.pro → .trialExpired (revalidation fails / license invalidated)
.pro → .proExpired (version-limited variant past its cutoff — dead code while the dict is empty)
```
---
## 2. The activation flow — `activate(_ licenseKey:)`
`LicenseManager.activate(_:completion:)` — `LicenseManager.swift:104-140`.
1. Calls `api.activate(licenseKey)` (network).
2. On `.success(response: ActivateResult)`, hops to the **main queue** and builds an all-or-nothing batch of Keychain writes:
- `licenseKey` → account `"licenseKey"` (`keychainKeyAccount`).
- `response.instanceId` → account `"instanceId"` (`keychainInstanceAccount`).
- `response.variantId` (if non-nil) → account `"variantId"` (`keychainVariantAccount`).
3. **Rollback invariant** (`LicenseManager.swift:117-126`): each write is attempted in order; if any returns a status other than `errSecSuccess`, *every previously-attempted account is removed* and the call fails with `LicenseAPIError.keychainWriteFailed(account:status:)`. Validation timestamps and email are **not** written in this path, so the user can never end up half-activated. The spec (`LicenseManagerSpecs.md:29`) calls this "the most important invariant in the file."
4. On a fully successful write batch:
- `defaults["lastValidation"] = clock.now.timeIntervalSince1970` (`LicenseManager.swift:127`).
- `defaults["lastValidationResult"] = true` (`:128`).
- If `response.customerEmail` is non-nil/non-empty → `defaults[customerEmailKey] = email` (`:129-131`).
- Calls `onBeforeProUnlock()` (`:132`) **before** flipping state.
- Sets `state = .pro` (`:133`), which triggers `didSet → onStateChanged?(state)`.
- `completion(.success(()))`.
5. On `.failure(error)` from the API, state is untouched and the error is forwarded (`:135-137`).
The completion runs on the main thread in all branches (the whole result handler is wrapped in `DispatchQueue.main.async`).
App-side activation entrypoints:
- **URL scheme** `alt-tab://activate?license_key=...` → `App.handleCustomUrl` → `LicenseManager.shared.activate(...)` (`src/App.swift:473-485`).
- **Settings → Upgrade tab** manual key entry (`src/preferences/settings-window/tabs/UpgradeTab.swift:325`).
### Sibling network operations
- `deactivate(completion:)` — `LicenseManager.swift:142-166`. Requires both `licenseKey` and `instanceId` in Keychain (else `LicenseAPIError.invalidKey`); calls `api.deactivate`, and on success **removes all three Keychain accounts**, clears `lastValidation`, `lastValidationResult`, and `customerEmail` from defaults, then recomputes via `computeTrialState()` (→ `.trial(n)` if still inside the 14-day window, else `.trialExpired`). Consumed by `UpgradeTab.swift:405`.
- `deactivateInstance(licenseKey:instanceId:completion:)` — `LicenseManager.swift:170-174`. Remote-deactivates *another machine's* seat without touching any local state. Used to reclaim a seat after a `seatLimitExceeded` error (`UpgradeTab.swift:389`).
- `revalidateWithServer()` — `LicenseManager.swift:209-232` (see §4).
---
## 3. Remote server validation — the actual API
### Base URL resolution
`Endpoints` (`src/api/Endpoints.swift:3-13`) reads two Info.plist keys, themselves fed from `config/base.xcconfig`:
| Constant | Source | Resolved value (this build) |
|---|---|---|
| `Endpoints.domain` | Info.plist `Domain` ← xcconfig `DOMAIN` | `alt-tab.app` (`config/base.xcconfig:20`) |
| `Endpoints.apiDomain` | Info.plist `ApiDomain` ← xcconfig `API_DOMAIN` | `alt-tab.app/api` (`config/base.xcconfig:21`) |
| `Endpoints.website` | `"https://\(domain)"` | `https://alt-tab.app` |
| `Endpoints.licenseApiBaseUrl` | `"https://\(apiDomain)/v1/license"` | **`https://alt-tab.app/api/v1/license`** |
`Info.plist:75-78` declares `Domain → $(DOMAIN)` and `ApiDomain → $(API_DOMAIN)`. (Note `feedbackUrl` at `Endpoints.swift:12` is `https://alt-tab.app/api/v1/feedback` — a separate, non-license endpoint owned by the feedback window.)
`LicenseManager.shared` injects `RemoteLicenseClient(baseUrl: Endpoints.licenseApiBaseUrl, keychain: keychain)` (`LicenseManager.swift:12`).
### Endpoints, methods, request/response shapes
`RemoteLicenseClient` (`src/pro/license/RemoteLicenseClient.swift`) is a `struct` conforming to the `LicenseAPI` protocol. All three calls are **POST**, `Content-Type: application/json`, `Accept: application/json`, body via `JSONSerialization`, executed on `URLSession.shared` (`RemoteLicenseClient.swift:103-128`). The file header comment (`:1-5`) describes it as "our own licensing backend at `alt-tab.app/v1/license/*`", provider-agnostic; the `LicenseManagerSpecs.md:13` calls the backend "LemonSqueezy-backed."
**POST `{baseUrl}/activate`** (`RemoteLicenseClient.swift:15-60`)
Request body:
```json
{
"license_key": "<key>",
"fingerprint": "<MachineFingerprint.get>",
"trial_started_at": <int epoch seconds> // only if LicenseManager.shared.trialStartDate != nil
}
```
`trial_started_at` (`:23-25`) lets the backend report trial→paid conversion latency (backend takes MIN across machines; omitted after deactivation clears the local trial start).
Response DTO `ActivateResponse` (`:132-139`): `{ activated: Bool, instance_id: String?, variant_id: String?, customer_email: String?, error: String?, instances: [InstanceDTO]? }`.
Mapping (`:28-58`):
- `activated == true` but missing `instance_id` → `invalidResponse(debugInfo: "missing instance_id")`.
- `activated == true` → `ActivateResult(instanceId, variantId, customerEmail)`.
- `activated == false` + `error == "invalid_key"` → `LicenseAPIError.invalidKey`.
- `error == "seat_limit_exceeded"` → `LicenseAPIError.seatLimitExceeded(instances:)` (maps `instances` DTOs).
- any other non-nil `error` → `activationRejected(reason)`; nil error → `activationRejected("unknown")`.
**POST `{baseUrl}/validate`** (`RemoteLicenseClient.swift:62-78`)
Request body: `{ "license_key": "<key>", "instance_id": "<id>" }`.
Response DTO `ValidateResponse` (`:141-144`): `{ valid: Bool, variant_id: String? }` → `ValidateResult(valid, variantId)`.
**POST `{baseUrl}/deactivate`** (`RemoteLicenseClient.swift:80-101`)
Request body: `{ "license_key": "<key>", "instance_id": "<id>" }`.
Response DTO `DeactivateResponse` (`:146-149`): `{ deactivated: Bool, error: String? }`. `deactivated == false` → `LicenseAPIError.deactivationRejected`.
`InstanceDTO` (`:151-159`): `{ id: String, machineName: String?, lastSeenAt: Int }` → maps to the public `ActiveInstance` struct.
### `LicenseAPI` protocol & error model
`src/pro/license/LicenseAPI.swift`:
- `protocol LicenseAPI` (`:4-8`) — the three async methods. This is the seam tests mock (`MockLicenseAPI`, `LicenseManagerTests.swift:504-527`).
- Result structs: `ActivateResult` (`:10-14`), `ValidateResult` (`:16-19`), `ActiveInstance` (`:21-25`).
- `enum LicenseAPIError: LocalizedError` (`:27-58`) — `invalidKey`, `activationRejected(String)`, `seatLimitExceeded(instances:)`, `deactivationRejected`, `noData`, `invalidResponse(debugInfo:)`, `apiError(String)`, `keychainWriteFailed(account:status:)`. Provides localized `errorDescription` and an internal `debugInfo`.
### Decode-failure handling
`post<T>` (`RemoteLicenseClient.swift:103-128`): network error → forwarded; nil data → `noData`; decode failure logs `statusCode`+body and, if the raw JSON has a string `error` field, surfaces `apiError(message)`, else `invalidResponse(debugInfo:)`. **Note:** no HTTP status-code gating — a 4xx/5xx with a decodable body is treated as a normal response.
---
## 4. Async revalidation (background re-check)
- `scheduleAsyncRevalidationIfNeeded()` (`LicenseManager.swift:202-207`): on `initialize()`, computes `elapsed = now - defaults["lastValidation"]`; only calls `revalidateWithServer()` if `elapsed >= revalidationInterval`.
- `revalidationInterval = 30 * 24 * 60 * 60` (30 days) — `LicenseManager.swift:18` (private static).
- `revalidateWithServer()` (`:209-232`): requires `licenseKey` + `instanceId` in Keychain (else returns). On `api.validate` success: refreshes `lastValidation` timestamp, stores `response.valid` into `lastValidationResult`, persists a returned `variantId` to Keychain, and sets `state = computeState()` if valid or `.trialExpired` if invalid. Network failure is swallowed (`:227-228`) — state and timestamp preserved, retried next launch. Also called directly from the QA menu "Revalidate" button (`src/debug/QAMenu.swift:221`).
---
## 5. State computation, machine fingerprint, persistence
### `computeState()` / `computeTrialState()`
- `computeState()` (`LicenseManager.swift:176-190`): if a `licenseKey` exists in Keychain — read `lastValidationResult`; if missing/false → **defensively** `.trialExpired` (`:179`); if a `variantId` exists and is in `versionLimitedVariants` and `currentAppVersion()` numerically exceeds the cutoff → `.proExpired` (`:180-186`); otherwise `.pro`. If no license key → `computeTrialState()`.
- `computeTrialState()` (`:192-200`): persists `trialStartDate` on first ever call (never reset on relaunch); `daysSince = floor((now - start)/86400)`; if `>= trialDuration` → `.trialExpired`, else `.trial(daysRemaining: trialDuration - daysSince)`.
- `trialDuration = 14` (`:17`), 0-indexed: day 0 → `.trial(14)`, day 13 → `.trial(1)`, day 14 → `.trialExpired` (`LicenseManagerSpecs.md:27`).
- `currentAppVersion: () -> String` (`:42-44`) defaults to `CFBundleShortVersionString`; overridable for tests.
### Machine fingerprint
`MachineFingerprint.get(keychain:)` (`src/pro/license/MachineFingerprint.swift:9-20`): primary source is the IOKit `IOPlatformUUID` of `IOPlatformExpertDevice` (`:11-14`). Fallback: a previously-stored value at Keychain account `"machineFingerprint"` (`:5,:16`); if neither exists, generates a random `UUID().uuidString`, persists it to that Keychain account, and returns it. Only consumer is the `activate` request body (`RemoteLicenseClient.swift:18`). `validate`/`deactivate` use the stored `instanceId` instead.
### Persistence map (Keychain + UserDefaults + cookie)
**Keychain** — `SystemKeychain` (`src/pro/license/Keychain.swift:10-89`), generic-password items (`kSecClassGenericPassword`), accessibility `kSecAttrAccessibleWhenUnlocked` on write (`Keychain.swift:45`). `setValue` deletes-then-adds (`:39-48`). All items share one service:
- **Service:** `LicenseManager.keychainService = "\(App.bundleIdentifier).license"` (`LicenseManager.swift:4`) → resolves to **`com.lwouis.alt-tab-macos.license`** (`App.bundleIdentifier` = `Bundle.main.bundleIdentifier!`, `src/App.swift:11`; bundle id `com.lwouis.alt-tab-macos`, `config/base.xcconfig:4`).
- Accounts under that service:
| Account constant | Account string | Written by |
|---|---|---|
| `keychainKeyAccount` | `"licenseKey"` | activate (`LicenseManager.swift:19`) |
| `keychainInstanceAccount` | `"instanceId"` | activate (`:20`) |
| `keychainVariantAccount` | `"variantId"` | activate / revalidate (`:21`) |
| (MachineFingerprint) | `"machineFingerprint"` | fingerprint fallback (`MachineFingerprint.swift:5`) |
- `removeAll()` (`Keychain.swift:74-88`, DEBUG only) wipes everything under the service — used by the QA "Mock fresh install" action.
> **Code-signature coupling (from AGENTS.md):** Keychain access is tied to the app's Developer ID / TeamID / bundle id. If the free build changes the bundle id or signing identity, these items become inaccessible — but for a free build that no longer reads them, that is harmless.
**UserDefaults** — suite `LicenseManager.defaultsSuiteName = "\(App.bundleIdentifier).license"` (`LicenseManager.swift:5`) → `com.lwouis.alt-tab-macos.license`. Non-secret bookkeeping keys:
| Key | Type | Set by | Read by |
|---|---|---|---|
| `"trialStartDate"` | Double (epoch) | `computeTrialState` first launch (`:194`) | `trialStartDate`, `daysSinceTrialStart`, trial math |
| `"lastValidation"` | Double (epoch) | activate / revalidate (`:127`,`:217`) | `scheduleAsyncRevalidationIfNeeded` |
| `"lastValidationResult"` | Bool | activate / revalidate (`:128`,`:218`) | `computeState` defensive check |
| `customerEmailKey` = `"customerEmail"` | String | activate (`:130`) | `customerEmail` getter |
**HTTP cookie** — `syncLicenseCookie(state:)` (`src/pro/license/LicenseCookie.swift:5-22`) sets a `license` cookie on `.alt-tab.app` (host from `Endpoints.website`), value `"pro"` / `"proExpired"` / `""`, `secure`, `distantFuture` expiry, in `HTTPCookieStorage.shared`. Purpose: Sparkle's appcast request can be tailored per tier. Called from the `onStateChanged` hook (`src/App.swift:451`).
---
## 6. PUBLIC SURFACE — what the rest of the app depends on
`LicenseManager.shared` (`LicenseManager.swift:7-15`) is the singleton; the wider app touches **only** the members below. Each entry lists definition site + every external call site, since this is what a free-build rewrite must keep compiling.
### `state: LicenseState` — `private(set)` stored, `didSet → onStateChanged?(state)` (`LicenseManager.swift:51-53`)
The core read. External readers:
- `src/App.swift:206` — `if case .pro = ... { return false }` (gates some behavior).
- `src/Menubar.swift:86` — menubar Pro/trial display.
- `src/preferences/settings-window/SettingsWindow.swift:162,196,206` — account UI.
- `src/preferences/settings-window/tabs/UpgradeTab.swift:220` — upgrade tab rendering.
- `src/pro/scheduling/ProTransitionManager.swift:172,299` — trial-nag scheduling.
- `src/secondary-windows/DebugProfile.swift:17` — `.debugProfileLabel`.
### `isProLocked: Bool` — computed (`LicenseManager.swift:67-72`)
`true` for `.proExpired`/`.trialExpired`, `false` for `.pro`/`.trial`. **The most widely consumed gate.** Drives degradation of Pro prefs and ghosting of Pro UI:
- `src/pro/ProFeature.swift:65` (`var isLocked`).
- `src/events/PreferencesEvents.swift:62`.
- `src/preferences/PreferenceDefinition.swift:34`.
- `src/preferences/settings-window/LabelAndControl.swift:86`.
- `src/preferences/settings-window/tabs/appearance/AppearanceTab.swift:589,667`.
- `src/preferences/settings-window/tabs/controls/ControlsTab.swift:589`.
- `src/preferences/settings-window/tabs/controls/ShortcutEditor.swift:599,705`.
- `src/pro/scheduling/ProTransitionManager.swift:179`.
### `isProAvailable: Bool` — computed, delegates to `state.isProAvailable` (`LicenseManager.swift:62`)
- `src/pro/ProFeature.swift:63,75`.
### `customerEmail: String?` — computed from `defaults[customerEmailKey]` (`LicenseManager.swift:55`)
- `src/preferences/settings-window/SettingsWindow.swift:167,196,207`.
- `src/preferences/settings-window/tabs/UpgradeTab.swift:227`.
### `isLifetimeVariant: Bool` — computed from Keychain `variantId` ∈ `lifetimeVariants` (`LicenseManager.swift:57-60`)
- `src/preferences/settings-window/SettingsWindow.swift:164`.
- `src/preferences/settings-window/tabs/UpgradeTab.swift:228`.
### `onStateChanged: ((LicenseState) -> Void)?` (`LicenseManager.swift:38`)
Fired from `state.didSet` on initialize and on every transition. Wired once in `src/App.swift:449-459` to: refresh menubar license items, sync the Sparkle cookie, notify `ProTransitionManager`, refresh `UpgradeTab`/upgrade button, reset preference-dependent components, and post `proLockStateDidChangeNotification`.
### `onBeforeProUnlock: () -> Void` (`LicenseManager.swift:49`, default no-op)
Fired **before** `state` flips to `.pro` (in `activate` `:132` and `mockProUser` `:276`) so observers can snapshot pre-Pro selections. Wired in `src/App.swift:448` to `ProTransitionManager.shared.onProUnlocked()`.
### `initialize()` (`LicenseManager.swift:91-94`)
Sets `state = computeState()` then schedules async revalidation. Called once at startup: `src/App.swift:460`.
### `refreshState()` (`LicenseManager.swift:99-102`)
Recomputes `state` and reassigns only if changed (so the baked-in trial day count tracks the clock). Called before UI surfaces read the day count:
- `src/Menubar.swift:396`.
- `src/preferences/settings-window/SettingsWindow.swift:1246`.
### `activate(_:completion:)` (`LicenseManager.swift:104-140`) — see §2
- `src/App.swift:481`, `src/preferences/settings-window/tabs/UpgradeTab.swift:325`.
### Other public members consumed externally
- `deactivate(completion:)` — `UpgradeTab.swift:405`.
- `deactivateInstance(licenseKey:instanceId:completion:)` — `UpgradeTab.swift:389`.
- `revalidateWithServer()` — `QAMenu.swift:221` (DEBUG).
- `daysSinceTrialStart: Int` (`:79-82`) — `ProTransitionManager.swift:300`.
- `trialStartDate: Date?` (`:74-77`) — read internally by `RemoteLicenseClient.activate` (`:23`).
- `LicenseManager.trialDuration` (static, `=14`) — referenced for trial messaging.
- DEBUG-only QA helpers `mockTrialUser`/`mockTrialExpired`/`mockTrialDay`/`mockProUser` (`:234-279`) — `src/debug/QAMenu.swift:151,239` etc.
---
## 7. Tests & specs (skim)
- `LicenseManagerSpecs.md` — prose spec; the load-bearing rules are in §"Behavior & edge cases" (`:25-34`): 14-day 0-indexed trial, no grace period, all-or-nothing Keychain writes with rollback, defensive expiry, 30-day throttled revalidation, synchronous compute on initialize, callback ordering.
- `LicenseManagerTests.swift` — 1:1 with the spec's scenario list. Tests inject `MockClock` (`:475`), `MockKeychain` (`:482`), `MockLicenseAPI` (`:504-527`) and an isolated `UserDefaults(suiteName:)` per test (`:13-23`). They never set `onStateChanged`/`onBeforeProUnlock` side effects unless asserting on them. `mockProUser`-related test is `#if DEBUG`-guarded.
---
## 8. Removal notes for a fully-free build
**Goal:** every feature unlocked, no trial nag, no network, no Keychain license reads — without breaking the ~30 external call sites in §6.
Recommended strategy (lowest blast radius): **keep the `LicenseManager.shared` public surface, gut the internals.**
- Make `state` permanently `.pro` (or add an always-`true` short-circuit). Then `isProLocked` is always `false` and `isProAvailable` always `true` automatically — most consumers (§6) need no edits.
- Stub `activate`/`deactivate`/`deactivateInstance`/`revalidateWithServer` to no-op-success (or delete and remove the 2 activate call sites + Upgrade tab management). The `LicenseAPI`/`RemoteLicenseClient`/`MachineFingerprint`/`LicenseCookie`/`Keychain` files can then be deleted entirely, since nothing else references them.
- `customerEmail` → return nil; `isLifetimeVariant` → return false (or true). Their consumers are all in `SettingsWindow`/`UpgradeTab` account UI, which is being removed with the paywall anyway.
- `onStateChanged`/`onBeforeProUnlock`/`initialize()`/`refreshState()` can become no-ops but should remain as symbols until the `App.swift` wiring (`:448-460`), `Menubar`, and `SettingsWindow` callers are also cleaned up — otherwise the build breaks.
**What is safe to delete outright** (no external readers beyond the license subsystem itself + the paywall UI being removed): `Clock.swift`, `MachineFingerprint.swift`, `LicenseCookie.swift` (also drop the `onStateChanged` call to `syncLicenseCookie` in `App.swift:451`), `RemoteLicenseClient.swift`, `Keychain.swift`, `LicenseAPI.swift`, `LicenseManagerTests.swift`, `LicenseManagerSpecs.md`.
**Coupled removals to coordinate (outside this audit's scope but flagged):**
- `src/api/Endpoints.swift:11` `licenseApiBaseUrl` becomes dead; `Info.plist`/`config/base.xcconfig` `ApiDomain` only feeds license + feedback URLs (feedback at `Endpoints.swift:12` is independent — keep `apiDomain` if feedback stays).
- The Sparkle appcast tier cookie (`LicenseCookie.swift`) means the free build's updater no longer differentiates tiers — verify the appcast still serves the free build without the `license` cookie.
- `App.swift:473-485` URL-scheme `activate` handler and the whole `UpgradeTab` should be removed with the paywall UI.
**Risks:**
- The `private(set) var state` `didSet` fires `onStateChanged` — if you hardcode `state = .pro` at init time, ensure the `onStateChanged` hook (and `ProTransitionManager`) tolerate being invoked, or unset the hook in the free build.
- Existing installs have stale Keychain items under `com.lwouis.alt-tab-macos.license` and UserDefaults under the same suite; a free build can ignore them, but leaving them is cosmetically untidy.
- Bundle id is still `com.lwouis.alt-tab-macos` (upstream's). Republishing under a new identity will change the Keychain service name anyway (moot once license reads are gone), but is a signing/identity decision per AGENTS.md.
+244
View File
@@ -0,0 +1,244 @@
# 05 — Trial / "Pro Transition" Nag-Escalation System
Scope: `src/pro/scheduling/` (the timed/escalating upsell machinery). This is the layer that
schedules and fires the Day1→Day35 nag prompts, computes the "hard gate" that blocks Pro features
after trial expiry, and persists which prompts have already been shown. It sits on top of the
license layer (`src/pro/license/`) and the feature-gating layer (`src/pro/ProFeature.swift`).
---
## 1. Architecture at a glance
The system is split into four cooperating pieces plus eight UI classes:
| Piece | File | Role |
|---|---|---|
| Coordinator | `ProTransitionManager.swift` | Singleton. Wires license state + persisted state + scheduler + UI emitter. Holds the public hooks App.swift calls. Owns the session-only free-pass flag. |
| Scheduler | `ProTransitionScheduler.swift` | Owns the persisted `nextScheduledDate`, the in-flight `DispatchWorkItem`, and `computeNextFireDate()`. Fires `onFire` (→ `evaluateAndShow()`). |
| Persisted state | `ProTransitionState.swift` | All `hasSeen*` flags + `remembered*` Pro indices in the `<bundleId>.license` UserDefaults suite, keys prefixed `proTransition.`. Snapshots into the pure decision struct. |
| Pure decision logic | `ProTransitionManagerTestable.swift` | No singletons / no `Date()` / no UI. `State` struct + `evaluate*` functions. The actual state machine. 100% unit-tested by `ProTransitionTests.swift`. |
| UI dispatch | `src/pro/ui/ProPromptHost.swift` | Receives `ProPromptAction` enum cases and maps them to concrete Day-X window/popover classes. |
The coordinator never references AppKit Day-X classes directly. It emits a `ProPromptAction`
(`ProTransitionManager.swift:87-98`) through `onAction`; `ProPromptHost.dispatch(_:)`
(`ProPromptHost.swift:11-38`) owns the concrete `.show()` calls.
### Time / day model
- `daysSinceTrialStart` is **0-indexed**: Day 1 = 0, Day 12 = 11, Day 15 = 14, Day 21 = 20,
Day 35 = 34, Day 49 = 48 (`ProTransitionManagerTestable.swift:11`, computed in
`LicenseManager.daysSinceTrialStart`, `LicenseManager.swift:79-82`:
`Int(clock.now.timeIntervalSince(start) / 86400)`).
- `trialStartDate` is stored in the license UserDefaults suite (`LicenseManager.swift:74-77`).
- Time-of-day windows: prompts only fire between **10:00–11:30** or **15:30–17:00**
(`ProTransitionManagerTestable.isInTimeWindow`, `ProTransitionManagerTestable.swift:148-152`:
600–690 min or 930–1020 min). The window check is snapshotted in
`ProTransitionState.snapshot(...)` (`ProTransitionState.swift:97-118`).
---
## 2. What triggers the system (entry points)
There are exactly **three** kinds of trigger, all routed through `ProTransitionManager`:
### A. App launch / timed scheduler fire
- `App.swift:429` calls `ProTransitionManager.shared.onAppLaunchComplete()` at end of launch
(after `onAction` is wired at `App.swift:428`).
- `ProTransitionManager.onAppLaunchComplete()` (`ProTransitionManager.swift:167-169`) delegates to
`scheduler.onAppLaunchComplete()` (`ProTransitionScheduler.swift:24-30`): if a persisted
`nextScheduledDate` is in the past, fire immediately; then `scheduleNext()`.
- The scheduler arms a single `DispatchWorkItem` (`ProTransitionScheduler.swift:40-55`) that calls
`onFire` → `evaluateAndShow()` (`ProTransitionManager.swift:121, 271-293`) → consults
`evaluateTimedAction(...)` and emits the matching prompt action, then re-arms `scheduleNext()`.
### B. Switcher shown / dismissed
- `App.showUiOrCycleSelection()` calls `ProTransitionManager.shared.onSwitcherShown()` at the start
of a **fresh** summon, not on a cycle (`App.swift:328`, inside the `isFirstSummon` branch).
- `App.hideUi()` calls `ProTransitionManager.shared.onSwitcherDismissed()` (`App.swift:78`).
- `onSwitcherShown()` (`ProTransitionManager.swift:205-223`) consults `evaluateSwitcherOpen(...)`
and queues a `pendingDismissAction` (Day 4 tour, or post-expiration free-pass + [C]).
- `onSwitcherDismissed()` (`ProTransitionManager.swift:187-201`) ends any active free-pass session
and, 1 second later (so the focused window is back in front), runs the queued action.
### C. Hard-gated feature attempt (use-time)
- `ProFeature.attemptUse()` (`ProFeature.swift:74-83`) is the gate. For the hard-gated features
(`.extraShortcut`, `.searchInSwitcher`, `.lockSearchInSwitcher`) it calls
`ProTransitionManager.shared.attemptHardGatedFeature(self)` (`ProFeature.swift:79`).
- `attemptHardGatedFeature(_:)` (`ProTransitionManager.swift:226-242`) consults `evaluateHardGate`
and returns whether the action may proceed; side effects are the free-pass / [C] / [E] ladder.
---
## 3. Public hooks called from App.swift (the integration surface)
These are the exact call sites a clean removal must sever (all in `src/App.swift` unless noted):
| Call site | Hook | Purpose |
|---|---|---|
| `App.swift:78` | `onSwitcherDismissed()` | Ends free-pass session, fires deferred prompt. |
| `App.swift:116` | `ProTransitionManager.openCheckout()` | Opens LemonSqueezy checkout URL. |
| `App.swift:207` | `hasSeenWelcome` (read) | Gates first-launch behavior (`!hasSeenWelcome`). |
| `App.swift:328` | `onSwitcherShown()` | Queues Day 4 tour / post-expiry free-pass. |
| `App.swift:428` | `onAction = { ProPromptHost.shared.dispatch($0) }` | Wires the emitter to the UI host. |
| `App.swift:429` | `onAppLaunchComplete()` | Kicks off the scheduler. |
| `App.swift:448` | `onProUnlocked()` (via `LicenseManager.onBeforeProUnlock`) | Restores remembered Pro prefs on purchase. |
| `App.swift:452` | `onLicenseStateChanged()` | Cancels scheduler + dismisses windows on Pro; engages lock on expiry. |
| `App.swift:458` | `proLockStateDidChangeNotification` (post) | Refreshes Settings ghost UI. |
| `Menubar.swift:205` | `shouldShowBadgeDot` (read) | Days 13–14 menubar badge dot. |
| `PreferenceDefinition.swift:35` | `isFreePassSessionActive` (read) | Swaps stored→remembered Pro value during free-pass. |
| `ProFeature.swift:76,79` | `isFreePassSessionActive`, `attemptHardGatedFeature(_:)` | Hard-gate ladder. |
| `QAMenu.swift:179-234` | many | DEBUG-only manual triggers / resets. |
| `AppearanceTab.swift:416`, `ControlsTab.swift:141` | `proLockStateDidChangeNotification` (observe) | Live Settings ghost-UI refresh. |
---
## 4. The full trial timeline (day-by-day)
All prompt selection lives in `ProTransitionManagerTestable.evaluateTimedAction(_:)`
(`ProTransitionManagerTestable.swift:63-98`), `evaluateSwitcherOpen(_:)` (lines 114-127), and
`evaluateHardGate(_:)` (lines 101-106). Letters [A]–[H] match the spec / `ProPromptAction` enum.
| Day (1-idx) | `daysSinceTrialStart` | Prompt | Trigger | What fires | Gate flag | Soft / Hard | Retry / miss behavior |
|---|---|---|---|---|---|---|---|
| **Day 1** | 0 | **[A] Welcome Letter** `Day1WelcomeLetterWindow` | Timed: launch / scheduler. `computeNextFireDate` returns `Date()` immediately while `!hasSeenWelcome` (`ProTransitionScheduler.swift:64-66`). `evaluateTimedAction` returns `.showWelcome` and blocks all other actions until seen (`Testable:67-69`). | NSWindow 560×520, Free-vs-Pro comparison table, "Start my 14-day trial" button. Copy varies fresh-install vs upgrade via `ProTransitionState.isFreshInstall` (`Day1WelcomeLetterWindow.swift:14-26`). | `hasSeenWelcome` | Soft | Always shows. |
| **Day 4** | 3 | **[H] Day 4 Tour** `Day4TourPopover` | **Switcher open** only. `evaluateSwitcherOpen` returns `.showDay4Tour` iff `isTrialActive && daysSinceTrialStart==3 && !hasSeenDay4Tour` (`Testable:116-119`). Deferred to 1s post-dismiss (`Manager:208-210, 193-199`). | NSPopover under menubar icon, 280×110, lists App Icons/Titles, extra shortcuts, Search; "Try them in Settings". | `hasSeenDay4Tour` | Soft | No retry — only fires if switcher is opened on Day 4 exactly. |
| Days 5–11 | 4–10 | — | — | Silent trial. | — | — | — |
| **Day 12** | 11 | **[B] Heads-Up** `Day12HeadsUpPopover` | Timed, only on the single day `daysSinceTrialStart==11`, inside a time window (`Testable:71-73`). Scheduler drops the candidate once `< day13Start` (`Scheduler:71-76`). | NSPopover under menubar icon, 300×100, "Your Pro trial ends in 2 days", "Not now" + "Get Pro". Also refreshes badge (`ProPromptHost.swift:17-19`). | `hasSeenDay12` | Soft | If missed in 10:00 window, try 15:30 window; **skip entirely** on Day 13+ (no retry). |
| Days 13–14 | 12–13 | Badge dot | `shouldShowBadgeDot` = `!isPro && isTrialActive && 12 <= days <= 13` (`Testable:131-133`). Read by `Menubar.swift:205`. | Orange/red dot on menubar icon. | — | Soft | Removed on Day 15 (days≥14). |
| **Day 15 (expiry)** | 14 | License flips to `.trialExpired`; **HARD GATE arms** | On the license state change, `onLicenseStateChanged()` (`Manager:171-182`) calls `onProLockEngaged()` because `isProLocked` is now true. | Degradable Pro prefs (style, size, shortcut style) immediately downgrade to Free equivalents and the Pro value is snapshotted into `remembered*` (`ProTransitionState.onProLockEngaged`, `ProTransitionState.swift:73-79`). | — | **HARD** | — |
| **Day 15+** | ≥14 | **[D] Proactive** `Day15ProactiveWindow` | Timed, only if **no hard-gate fired yet**: `days>=14 && !hasSeenProactiveDay15 && !hasSeenFullUpgrade && isInTimeWindow` (`Testable:77`). | NSWindow 380×280, "Your 14-day Pro trial just ended", two-stat usage hero, "Get Pro" / "Maybe later". `showProactiveDay15Window()` also calls `onProLockEngaged()` (`Manager:253-257`). | `hasSeenProactiveDay15` | Soft (window) | Retry next active day until shown or [C] fires. Scheduler stops offering it once `hasSeenFullUpgrade` (`Scheduler:79`). |
| **Day 15+** | ≥14 | **[C] Full Upgrade** `Day15FullUpgradeWindow` | (a) First **switcher open** post-expiry → free-pass + [C] (`evaluateSwitcherOpen` → `.triggerFreePass`, `Testable:123-124`); or (b) first **hard-gate attempt** via the free-pass ladder (`evaluateHardGate`, `Testable:101-106`). | NSWindow 440×340, header resolved by `HardGateReason.resolved` priority (`Manager:40-73`), usage hero, "Get Pro" / "Continue with Free". `showFullUpgradeWindow` sets `hasSeenFullUpgrade=true` then `onProLockEngaged()` (`Manager:244-251`). | `hasSeenFullUpgrade`, `freePassUsed`, `hasTriggeredPostExpirationSwitcher` | **HARD** (this is the lock-in moment) | N/A — user-initiated. Once-ever. |
| **after [C]** | ≥14 | **[E] Hard-Gate Popover** `Day15HardGatePopover` | Every hard-gate attempt **after** [C] shown: `evaluateHardGate` returns `.showHardGatePopover` when `freePassUsed && hasSeenFullUpgrade` (`Testable:101-106`). | NSPopover under menubar icon 280×100, header from same `resolved` priority, "Not now" / "Get Pro". | — | **HARD** (feature is blocked, returns `false`) | Fires on **every** post-[C] hard-gate attempt forever (continues after opt-out). |
| **Day 21–34** | 20–33 | **[F] Day 21 Reminder** `Day21ReminderPopover` | Timed: `days>=20 && days<34 && !hasSeenDay21 && isInTimeWindow` (`Testable:88`). Checked **after** Day 35 so a long-inactive user skips straight to [G]. | NSPopover 300×140, "AltTab Pro is still available", `ProConversionCopy.day21Body()`, "Not now" / "Get Pro". | `hasSeenDay21` | Soft | Retry daily; skipped if Day 35 arrives first (`hasSeenDay35` guard, `Scheduler:86`). |
| **Day 35–48** | 34–47 | **[G] Day 35 Final** `Day35FinalWindow` | Timed: `days>=34 && days<48 && !hasSeenDay35 && isInTimeWindow` (`Testable:83`). Checked **before** [F] (`Testable:82`). | NSWindow 380×280, "Still interested in Pro?", usage hero, "Get Pro" / **"No thanks — don't ask again"** (→ `userOptedOut=true`, `Day35FinalWindow.swift:37-41`). | `hasSeenDay35`, `userOptedOut` | Soft | Retry daily; **give up at Day 49** (`days<48` upper bound; scheduler caps at `day49`, `Scheduler:92-99`). ⨉ sets `hasSeenDay35` but does NOT opt out. |
| **Day 49+** | ≥48 | — | Scheduling complete (`isSchedulingComplete`, `Testable:140`). | Steady state: [E] on every hard-gate attempt; degradable features silently fall back; purchase only via Preferences. | — | **HARD** persists | — |
After all proactive prompts: `evaluateTimedAction` falls through to `.refreshBadgeDot` for `days>=14`
(`Testable:93-95`), which just re-paints the (now-removed) badge.
---
## 5. Soft nags vs. the HARD GATE — exactly what gets locked
**Soft nags** = [A], [H], [B], [D], [F], [G] and the badge dot. These are pure informational
windows/popovers. They never block functionality. Each is gated once-ever by a `hasSeen*` flag.
Dismissing them does nothing except set the flag (except [G]'s opt-out link, which sets
`userOptedOut`).
**The HARD GATE** is the feature-blocking mechanism that arms at trial expiry (Day 15). Two layers:
1. **Degradable prefs downgrade immediately** (`onProLockEngaged`, `ProTransitionState.swift:73-79`).
On the `isProLocked` transition, every entry in `ProGatedPreferences.all` is snapshotted and
downgraded: appearance style → `.thumbnails`, size → `.medium`, shortcut style →
`.doNothingOnRelease`. The original Pro index is saved to `remembered*` (drives Settings "ghost"
UI + the one-last-session free-pass read). `PreferenceDefinition.read()` (`PreferenceDefinition.swift:32-44`)
returns the Free equivalent once locked — unless a free-pass session is active, in which case it
returns the remembered Pro value (`PreferenceDefinition.swift:35-39`).
2. **Hard-gated features are blocked at use-time** via the **free-pass ladder**
(`evaluateHardGate`, `Testable:101-106`):
- `isPro || isTrialActive` → `.allow` (run normally).
- `!freePassUsed` → `.freePass`: allow the action **once**, mark `freePassUsed=true`, open a
free-pass session, and queue [C] for after dismissal (`Manager:230-234`).
- `!hasSeenFullUpgrade` → `.showFullUpgrade`: block the feature (return `false`), show [C]
inline (`Manager:235-237`).
- else → `.showHardGatePopover`: block the feature, show [E] (`Manager:238-240`). Fires forever.
Hard-gated features (`ProFeature.attemptUse`, `ProFeature.swift:77-82`): `.extraShortcut`
(shortcut slot ≥ 2), `.searchInSwitcher`, `.lockSearchInSwitcher`. The degradable-only set
(`.appIconsAndTitlesStyle`, `.autoSize`, `.searchOnReleaseShortcut`) always returns `true` here
because it is gated at preference-write time, not use-time.
**The defining difference:** soft nags return control to the user immediately. After [C] has fired,
the hard gate **permanently blocks** the three hard-gated features (returns `false`, action does
not execute) and shows [E] each time — even after opt-out, even past Day 49. Only purchase clears it.
---
## 6. Free-pass sessions
A free-pass session is a **session-only** window (`isFreePassSessionActive`,
`ProTransitionManager.swift:135-142`) during which the user gets their Pro experience back for one
last switcher summon. It is opened in two places:
- `onSwitcherShown()` → `.triggerFreePass` (first post-expiry summon): sets `freePassUsed=true`,
`hasTriggeredPostExpirationSwitcher=true`, `isFreePassSessionActive=true`, builds a
`HardGateReason.proPreferences(...)` from `remembered*`, and queues [C] (`Manager:211-219`).
- `attemptHardGatedFeature()` → `.freePass`: sets `freePassUsed=true`, `isFreePassSessionActive=true`,
queues [C] for the attempted feature (`Manager:230-234`).
While active:
- `PreferenceDefinition.read()` returns the **remembered Pro value** instead of the downgraded
stored value (`PreferenceDefinition.swift:35-39`), so the switcher renders Pro for that one session.
- `ProFeature.attemptUse()` returns `true` for *all* features without re-consuming the pass
(`ProFeature.swift:76`), so search/lock-search/extra-shortcut chords work inside the session.
- Setting the flag triggers `App.resetPreferencesDependentComponents()` (when `TilesPanel` exists)
so `TilesView` re-renders against the new `read()` (`Manager:136-142`).
The session ends in `onSwitcherDismissed()` (`Manager:189`), which sets
`isFreePassSessionActive=false`; the deferred [C] window then appears 1s later (`Manager:193-199`).
---
## 7. How the schedule is computed and persisted
`ProTransitionScheduler.computeNextFireDate()` (`ProTransitionScheduler.swift:58-103`):
- Bails (returns `nil`) if Pro, or `userOptedOut && hasSeenDay35`, or no `trialStartDate`.
- If `!hasSeenWelcome` → returns `Date()` (fire [A] now).
- Otherwise builds a candidate list from the unshown prompts (Day 12, Day 15 proactive, Day 21,
Day 35), each via `nextTimeWindow(onOrAfterDay:trialStart:)` (`Scheduler:106-123`) which finds the
next 10:00 or 15:30 slot on/after the target trial day (scanning up to 60 days). Returns the
**earliest** candidate.
- Day 12 candidate is dropped once past `day13Start` (`Scheduler:71-76`); Day 35 candidate must be
before `day49` (`Scheduler:92-99`).
`scheduleNext()` (`Scheduler:40-55`) cancels the prior `DispatchWorkItem`, persists the chosen date
to UserDefaults key `proTransition.nextScheduledDate` (`Scheduler:14, 46`), and arms a new
`DispatchWorkItem` via `asyncAfter`. On fire it calls `onFire()` then re-schedules.
**Persistence:** all flags + the next-fire date live in the `<bundleId>.license` UserDefaults suite,
keys prefixed `proTransition.` (`ProTransitionState.swift:9, 136-154`; `Scheduler:14`). Note the
schedule and the nag state are co-located in the **license** suite (shared with `trialStartDate`),
not standard defaults. The pure-decision `isSchedulingComplete` (`Testable:136-145`) mirrors the
scheduler's bail conditions for testing.
`cancel()` (`Scheduler:33-37`) removes `nextScheduledDate` and the work item — called on purchase
via `onLicenseStateChanged()` (`Manager:172-176`), which also emits `.dismissAllProWindows` +
`.refreshBadge`.
---
## 8. Removal notes (for the free build)
Removing the nag system cleanly is largely about severing the App.swift hooks in §3 and deleting the
`src/pro/scheduling/` directory. Key dependencies and risks:
- **`src/pro/scheduling/` is self-contained UI/logic** but depends on: `ProFeature` /
`ProGatedPreferences` (feature gating), `LicenseManager` (state, `trialStartDate`,
`daysSinceTrialStart`, `clock`), `UsageStats`, `ProConversionCopy` / `ProFeatureCopy`,
`ProPromptWindow`/`ProPromptPopover`/`ProPromptHeader`/`UsageStatHeroView`/`NotAdvisedButton`
(shared Pro UI in `src/pro/ui/`), and `Endpoints.checkoutUrl`. Those are part of the broader
paywall and are covered by other audit sections; this directory is a *consumer* of them.
- **App.swift hooks to remove/neutralize** (all load-bearing): `App.swift:78, 116, 207, 328, 428,
429, 448, 452, 458`. The `onSwitcherShown`/`onSwitcherDismissed` calls are in the switcher hot
path; the `pendingDismissAction` 1s-deferred dispatch must be dropped with them.
- **`ProFeature.attemptUse()` (`ProFeature.swift:74-83`)** calls into `attemptHardGatedFeature`.
For a fully-unlocked build this must unconditionally return `true` (delete the
`ProTransitionManager` call and the `isFreePassSessionActive` short-circuit at `ProFeature.swift:76`).
- **`PreferenceDefinition.read()` (`PreferenceDefinition.swift:32-44`)** references
`isFreePassSessionActive` and `ProTransitionState.int(...)`. With no lock these branches are dead;
removal must keep `read()` returning the stored value unconditionally.
- **`Menubar.swift:205`** reads `shouldShowBadgeDot`; remove the badge-dot call.
- **Settings observers** (`AppearanceTab.swift:416`, `ControlsTab.swift:141`) subscribe to
`proLockStateDidChangeNotification`; with no lock these never fire but the symbol must still
resolve or be removed alongside the manager.
- **`ProGatedPreferences.all`** is iterated by `onProLockEngaged`/`onProUnlocked`. If those prefs
become permanently unlocked, the snapshot/restore logic is dead code; ensure no stored value is
ever forced to the Free equivalent on launch.
- **Risk — orphaned UserDefaults:** existing installs carry `proTransition.*` keys in the
`<bundleId>.license` suite (and `trialStartDate`). A free build that ignores them is safe, but if
any remaining read of `isProLocked` survives, a previously-expired user could still see a degraded
pref. Confirm `isProLocked` always evaluates to `false` in the free build.
- **DEBUG-only QAMenu** (`QAMenu.swift:170-241`) directly instantiates every Day-X window and pokes
manager flags; it must be removed/updated in lockstep or it won't compile.
- **Tests:** `ProTransitionTests.swift` (729 lines) and `ProTransitionManagerTestable.swift` are
pure-logic and will need to be deleted with the system; nothing outside scheduling imports them.
+215
View File
@@ -0,0 +1,215 @@
# 06 — ProFeature Model & Marketing/Conversion Copy
Scope: `src/pro/ProFeature.swift`, `src/pro/ProFeatureCopy.swift`, `src/pro/ProConversionCopy.swift`, and the Pro-gating machinery in `src/preferences/PreferenceDefinition.swift`. Cross-references to call sites are included so a clean free-build removal can be planned without breaking compilation.
All paths are absolute under `/Users/james.maes/Git.Local/kof22/alt-tab-free`.
---
## 1. The `ProFeature` model
Defined in `src/pro/ProFeature.swift:8`. `ProFeature` is an `enum: Equatable, Hashable` that is described in its own doc comment (`src/pro/ProFeature.swift:3-7`) as the "single source of truth" for: which preferences degrade on lock, which runtime actions are hard-gated, which preference keys the click-interceptor routes to the Upgrade tab, and which copy the Day-X views show.
### 1.1 Cases (`src/pro/ProFeature.swift:9-16`)
```swift
case appIconsAndTitlesStyle // degradable preference
case autoSize // degradable preference
case searchOnReleaseShortcut // degradable preference
case extraShortcut(index: Int) // hard-gated runtime action, no stored pref
case searchInSwitcher // hard-gated runtime action, no stored pref
case lockSearchInSwitcher // hard-gated runtime action, no stored pref
```
### 1.2 `GateKind` and `gateKind` (`src/pro/ProFeature.swift:18-33`)
Three gate kinds:
- `.degradable` — silent fallback only; the stored value is downgraded on lock; never triggers the `[C]` upgrade prompt by itself.
- `.hardGated` — use-time free-pass → `[C]` ladder; no stored preference.
- `.degradableAndHardGated` — both: silent downgrade AND the first post-expiration switcher summon triggers `[C]`.
Mapping in `gateKind` (`src/pro/ProFeature.swift:27-33`):
- `.autoSize` → `.degradable`
- `.appIconsAndTitlesStyle`, `.searchOnReleaseShortcut` → `.degradableAndHardGated`
- `.extraShortcut`, `.searchInSwitcher`, `.lockSearchInSwitcher` → `.hardGated`
### 1.3 `gatedPreference` — link to the backing preference (`src/pro/ProFeature.swift:35-44`)
Returns the type-erased `AnyProGatedPreference` (defined in `PreferenceDefinition.swift`) that backs a degradable feature, or `nil` for hard-gated cases:
- `.appIconsAndTitlesStyle` → `ProGatedPreferences.appearanceStyle.erased`
- `.autoSize` → `ProGatedPreferences.appearanceSize.erased`
- `.searchOnReleaseShortcut` → `ProGatedPreferences.shortcutStyle.erased`
- `.extraShortcut`, `.searchInSwitcher`, `.lockSearchInSwitcher` → `nil`
### 1.4 `copy` — per-case marketing line (`src/pro/ProFeature.swift:46-56`)
Maps each case to a `ProFeatureCopy` string. Note multiple cases share a line:
- `.appIconsAndTitlesStyle` → `ProFeatureCopy.appIconsAndTitles`
- `.autoSize` → `ProFeatureCopy.autoSize`
- `.searchOnReleaseShortcut` → `ProFeatureCopy.extraShortcuts` ("grouped under keyboard shortcuts")
- `.extraShortcut` → `ProFeatureCopy.extraShortcuts`
- `.searchInSwitcher`, `.lockSearchInSwitcher` → `ProFeatureCopy.search`
### 1.5 `degradable` list (`src/pro/ProFeature.swift:59`)
```swift
static let degradable: [ProFeature] = [.appIconsAndTitlesStyle, .autoSize, .searchOnReleaseShortcut]
```
### 1.6 Availability & runtime gating
- `isAvailable` (`src/pro/ProFeature.swift:63`) → `LicenseManager.shared.isProAvailable`
- `isLocked` (`src/pro/ProFeature.swift:65`) → `LicenseManager.shared.isProLocked`
- `attemptUse() -> Bool` (`src/pro/ProFeature.swift:74-83`): returns `true` if Pro is available or a free-pass session is active; otherwise hard-gated cases consult `ProTransitionManager.shared.attemptHardGatedFeature(self)` while degradable cases always return `true` (they are gated at preference-write time, not use time).
- `isStoredValuePro(preferenceKey:)` (`src/pro/ProFeature.swift:87-89`): static helper that delegates to `ProGatedPreferences.forPreferenceKey(...)?.isStoredValuePro()`. **Note:** the `snapshotAndDowngradeStored` / `restoreStored` / `preferenceKey` / `rememberedKey` methods named in the audit prompt no longer live on `ProFeature` — the doc comments in `PreferenceDefinition.swift:16-17` and `:99-101` explicitly state this logic was extracted out of `ProFeature` into `PreferenceDefinition`. They are documented in section 3 below at their current home.
---
## 2. Marketing copy strings (these get deleted)
### 2.1 `ProFeatureCopy` (`src/pro/ProFeatureCopy.swift:3-8`)
The canonical feature-list strings. Every one of these is a `NSLocalizedString`:
| Constant | String |
|---|---|
| `appIconsAndTitles` | `"App Icons & Titles styles"` |
| `search` | `"Search — find a window by typing"` |
| `autoSize` | `"Auto Size — larger previews with few windows, more at once with many"` |
| `extraShortcuts` | `"Up to 9 keyboard shortcuts"` |
Consumers (all upsell UI, to be removed/neutralised):
- `src/pro/scheduling/Day1WelcomeLetterWindow.swift:77-80` — the Free-vs-Pro comparison table rows.
- `src/pro/ProFeature.swift:50-54` — the `copy` accessor.
### 2.2 `ProConversionCopy` (`src/pro/ProConversionCopy.swift`)
View-layer presenter for trial-nag prompts. Reads from `UsageStats` and emits formatted upsell strings. All strings are `NSLocalizedString` and are pure upsell/nag copy.
`day12Subtitle()` (`src/pro/ProConversionCopy.swift:11-24`):
- empty usage: `"On Day 15, Pro features revert to the free version."`
- 1–2 used: `"You've been using %@.\nThese will switch back to defaults on Day 15."`
- 3+ used: `"You've been using %d Pro features.\nThey'll switch back to defaults on Day 15."`
`day21Body()` (`src/pro/ProConversionCopy.swift:26-44`):
- both counts > 0: `"You've used AltTab %@ times — %@ of those used Pro features."`
- triggers only: `"You've used AltTab %@ times."`
- neither: `"Pro is still available whenever you're ready."`
Consumers:
- `src/pro/scheduling/Day12HeadsUpPopover.swift:21` — `ProConversionCopy.day12Subtitle()`
- `src/pro/scheduling/Day21ReminderPopover.swift:18` — `ProConversionCopy.day21Body()`
### 2.3 Adjacent upsell copy that references this scope (out of file, in scope by linkage)
These strings live in sibling files but are wired directly to `ProFeatureCopy`/feature names and are also upsell copy slated for deletion:
- `src/pro/scheduling/Day1WelcomeLetterWindow.swift:20-26` — welcome/"now has a Pro tier" titles and the 14-day-trial body copy; `:36` `"Start my 14-day trial"`; `:75-76,89-92` table headers (`"Feature"`, `"Free"`, gradient "Pro" header) and the two always-true free rows (`"Reliable, fast window switching with high-quality thumbnails"`, `"Dark Mode, live preview, window controls, trackpad gestures, and more"`).
- `src/pro/scheduling/Day15FullUpgradeWindow.swift:22-44` — supporting lines: `"AltTab Pro adds 4 features beyond the free switcher."`, `"Some Pro features have reverted to free defaults."`, plus per-reason lines (`"Extra shortcuts are a Pro feature."`, `"Search is a Pro feature."`, `"The App Icons style is a Pro feature."`, `"The Titles style is a Pro feature."`); `:59` `"Get Pro"`; `:66` `"Continue with Free"`.
- `src/util/UsageStatsTestable.swift:4-9` — feature display names fed into `ProConversionCopy.day12Subtitle()` via `UsageStats.usedProFeatureNames()`: `"Search"`, `"App Icons appearance"`, `"Titles appearance"`, `"Extra shortcuts"`.
---
## 3. Snapshot / downgrade / restore machinery (now in `PreferenceDefinition.swift`)
The methods the prompt calls `snapshotAndDowngradeStored` / `restoreStored` / `isStoredValuePro` / `preferenceKey` / `rememberedKey` have been refactored out of `ProFeature` and now live on `PreferenceDefinition<T>` / `AnyProGatedPreference` in `src/preferences/PreferenceDefinition.swift`.
### 3.1 `PreferenceGate<T>` (`src/preferences/PreferenceDefinition.swift:7-11`)
Per-preference gate policy carrying:
- `freeEquivalent: T` — the value to fall back to when locked.
- `rememberedKey: String` — UserDefaults sub-key under which the Pro value index is snapshotted.
- `isProValue: (T) -> Bool` — predicate identifying which stored values count as "Pro".
### 3.2 `PreferenceDefinition<T>` (`src/preferences/PreferenceDefinition.swift:18-74`)
Single-source-of-truth per macro preference. Carries `key`, `default`, optional `gate`. Methods:
- `read() -> T` (`:32-44`) — reads stored value via `CachedUserDefaults.macroPref`; if locked + gated, three branches: (1) active free-pass + valid remembered index → return remembered Pro selection; (2) stored value is still Pro → return `freeEquivalent`; (3) otherwise return stored (already downgraded).
- `snapshotAndDowngrade() -> Int?` (`:51-57`) — if stored value is a Pro selection, overwrite with `freeEquivalent` via `Preferences.set(...)` and return the original index for the caller to persist under `rememberedKey`. Returns `nil` if no gate or already free.
- `restore(from rememberedIndex:)` (`:62-65`) — writes the remembered index back via `Preferences.set(key, ..., false)` (notify:false so the restore pass doesn't bounce observers to Upgrade).
- `isStoredValuePro() -> Bool` (`:69-73`) — true when the stored value is a Pro selection, regardless of lock state. This is what `ProFeature.isStoredValuePro(preferenceKey:)` and `PreferencesEvents` consult.
### 3.3 `AnyProGatedPreference` (`src/preferences/PreferenceDefinition.swift:79-96`)
Type-erased descriptor exposing concrete-typed ops only: `preferenceKey`, `rememberedKey`, `snapshotAndDowngrade: () -> Int?`, `restoreFromIndex: (Int) -> Void`, `isStoredValuePro: () -> Bool`. Produced by `PreferenceDefinition.erased` (`:88-95`). This is what `ProFeature.gatedPreference` returns.
### 3.4 `ProGatedPreferences` registry (`src/preferences/PreferenceDefinition.swift:102-170`)
Holds all gated `PreferenceDefinition`s, the `all` list, and `forPreferenceKey(_:)` lookup. See section 4 for the value-level mapping.
### 3.5 Where the passes are driven (`src/pro/scheduling/ProTransitionState.swift`)
- `onProLockEngaged()` (`:73-79`) — iterates `ProGatedPreferences.all`, calls `pref.snapshotAndDowngrade()`, and persists the returned index under `pref.rememberedKey`. Idempotent.
- `onProUnlocked()` (`:85-92`) — iterates `ProGatedPreferences.all`, restores from remembered index via `pref.restoreFromIndex(idx)`, then clears the remembered key.
- `resetAll()` (DEBUG, `:125-131`) — clears the remembered keys among other transition flags.
---
## 4. Definitive list of "Pro" features and their preference mappings
### 4.1 Degradable features (have a backing preference)
| ProFeature case | Backing `ProGatedPreferences` def | preferenceKey | rememberedKey | default | freeEquivalent | isProValue (= what counts as Pro) |
|---|---|---|---|---|---|---|
| `.appIconsAndTitlesStyle` | `appearanceStyle` (`PreferenceDefinition.swift:103-109`) | `appearanceStyle` | `rememberedAppearanceStyle` | `.thumbnails` | `.thumbnails` | `$0 != .thumbnails` (i.e. `.appIcons` or `.titles`) |
| `.autoSize` | `appearanceSize` (`:111-117`) | `appearanceSize` | `rememberedAppearanceSize` | `.auto` | `.medium` | `$0 == .auto` |
| `.searchOnReleaseShortcut` | `shortcutStyle` (`:119-125`) | `shortcutStyle` | `rememberedShortcutStyle` | `.focusOnRelease` | `.doNothingOnRelease` | `$0 == .searchOnRelease` |
Underlying enums (`src/preferences/MacroPreferences.swift`):
- `AppearanceStylePreference` (`:284-287`): `.thumbnails`, `.appIcons`, `.titles` → Pro = `.appIcons`/`.titles`.
- `AppearanceSizePreference` (`:308-312`): `.small`, `.medium`, `.large`, `.auto` → Pro = `.auto`.
- `ShortcutStylePreference` (`:100-103`): `.focusOnRelease`, `.doNothingOnRelease`, `.searchOnRelease` → Pro = `.searchOnRelease`.
### 4.2 Per-shortcut override gated preferences (no direct ProFeature case)
`ProGatedPreferences.all` (`PreferenceDefinition.swift:157-164`) also includes three per-shortcut "override 0" definitions that are NOT directly mapped from a `ProFeature` case but ARE snapshotted/restored on lock/unlock. Their registered defaults are the FREE values, so `snapshotAndDowngrade` is a no-op unless the user explicitly set a Pro override:
| Def | preferenceKey | rememberedKey | default | freeEquivalent | isProValue |
|---|---|---|---|---|---|
| `appearanceStyleOverride0` (`:131-137`) | `appearanceStyleOverride` | `rememberedAppearanceStyleOverride` | `.thumbnails` | `.thumbnails` | `$0 != .thumbnails` |
| `appearanceSizeOverride0` (`:139-145`) | `appearanceSizeOverride` | `rememberedAppearanceSizeOverride` | `.medium` | `.medium` | `$0 == .auto` |
| `shortcutStyleOverride0` (`:147-153`) | `shortcutStyleOverride` | `rememberedShortcutStyleOverride` | `.doNothingOnRelease` | `.doNothingOnRelease` | `$0 == .searchOnRelease` |
### 4.3 Hard-gated features (no backing preference)
| ProFeature case | Gate site | Behaviour |
|---|---|---|
| `.extraShortcut(index:)` | `src/switcher/ShortcutAction.swift:56` — gates pressing shortcut slot index ≥ 1 | `attemptUse()` → `ProTransitionManager.attemptHardGatedFeature`. Also recorded by `UsageStats.recordTrigger` under `triggersExtraShortcuts`. |
| `.searchInSwitcher` | `src/switcher/main-window/TilesView.swift:92` (`enableSearchEditing`) | gated via `SearchModeResolver.enableEditing(...canSearch:)` |
| `.lockSearchInSwitcher` | `src/switcher/main-window/TilesView.swift:79` (`lockSearchMode`) | gated via `SearchModeResolver.lock(...canLockSearch:)` |
The four marketing-level "Pro features" advertised to users (per `Day15FullUpgradeWindow.swift:23-25` "adds 4 features" and the `Day1` table `:77-80`) are: **App Icons & Titles styles, Search, Auto Size, and up to 9 keyboard shortcuts.**
---
## 5. Cross-reference: all known consumers of this scope
| Symbol | Consumer site |
|---|---|
| `ProFeature.extraShortcut(index:).attemptUse()` | `src/switcher/ShortcutAction.swift:56` |
| `ProFeature.lockSearchInSwitcher.attemptUse()` | `src/switcher/main-window/TilesView.swift:79` |
| `ProFeature.searchInSwitcher.attemptUse()` | `src/switcher/main-window/TilesView.swift:92` |
| `ProFeature.isStoredValuePro(preferenceKey:)` | `src/events/PreferencesEvents.swift:62` (bounces to `UpgradeTab.navigateToUpgradeTab()` when locked) |
| `ProFeatureCopy.*` (4 strings) | `src/pro/scheduling/Day1WelcomeLetterWindow.swift:77-80`; `src/pro/ProFeature.swift:50-54` |
| `ProConversionCopy.day12Subtitle()` | `src/pro/scheduling/Day12HeadsUpPopover.swift:21` |
| `ProConversionCopy.day21Body()` | `src/pro/scheduling/Day21ReminderPopover.swift:18` |
| `ProGatedPreferences.all` / `forPreferenceKey` | `src/pro/scheduling/ProTransitionState.swift:74,86,129`; `src/preferences/Preferences.swift`; `src/pro/ProFeature.swift:39-41,88` |
| `SearchModeResolver` gating note | `src/switcher/state/SearchModeResolver.swift:9` |
`SearchModeResolver` itself does not depend on `ProFeature` — it is purely a pure-state resolver that receives `canSearch`/`canLockSearch` booleans, so in a free build those callers can simply pass `true` (or be inlined) without touching `SearchModeResolver`.
---
## 6. Removal notes for a clean free build
1. **`attemptUse()` must become an unconditional `true`.** The three runtime gate sites (`ShortcutAction.swift:56`, `TilesView.swift:79,92`) all call `ProFeature.*.attemptUse()`. For a fully-unlocked build, either delete the `if !... { return }` guard at `ShortcutAction.swift:53-58` entirely, and pass `canSearch: true` / `canLockSearch: true` directly at `TilesView.swift:79,92`, or stub `attemptUse()` to always return `true`. Removing `ProFeature` wholesale requires editing all three call sites.
2. **`PreferencesEvents.swift:62` bounce-to-Upgrade must be removed.** This is the only consumer of `ProFeature.isStoredValuePro(preferenceKey:)`. Deleting the `if LicenseManager.shared.isProLocked && ProFeature.isStoredValuePro(...)` block (`:62-64`) prevents settings changes from yanking users to a (deleted) Upgrade tab. Note `UpgradeTab.navigateToUpgradeTab()` is itself paywall UI removed elsewhere.
3. **Preference gating (`PreferenceDefinition.read()`) must stop downgrading.** `read()` (`PreferenceDefinition.swift:32-44`) returns `freeEquivalent` when `LicenseManager.shared.isProLocked`. With a free build `isProLocked` should be hard-wired to `false` (license layer is audited separately), which neutralises `read()`, `snapshotAndDowngrade()`, and `onProLockEngaged()` without code changes here. Cleaner removal: strip the `gate:` arguments from all six `ProGatedPreferences` definitions (`:103-153`) so every preference is ungated, then `ProGatedPreferences.all` becomes empty and the snapshot/restore passes in `ProTransitionState` become no-ops. Confirm `Preferences.swift` getters still resolve through `PreferenceDefinition.read()` (referenced by the doc comment at `:99-100`) before stripping.
4. **`rememberedKey` migration risk.** Existing installs may have `proTransition.rememberedAppearanceStyle` / `...Size` / `...Style` (and the three `*Override` variants) persisted from a prior lock. If gating is removed without an unlock pass, a user's pre-lock Pro selection stays downgraded in `appearanceStyle`/`appearanceSize`/`shortcutStyle`. Consider running `onProUnlocked()` (`ProTransitionState.swift:85-92`) once on upgrade-to-free-build, or document that users may need to re-select their preferred style/size after migrating. The remembered keys are namespaced `proTransition.<key>` in UserDefaults.
5. **Copy deletion is self-contained.** `ProFeatureCopy.swift` and `ProConversionCopy.swift` can be deleted in full once `ProFeature.copy` (`ProFeature.swift:48-56`), `Day1WelcomeLetterWindow.swift:77-80`, `Day12HeadsUpPopover.swift:21`, and `Day21ReminderPopover.swift:18` are removed. The feature-name strings in `UsageStatsTestable.swift:4-9` and the `UsageStats.usedProFeatureNames()`/`usedProFeaturesSessionCount` telemetry feed only the conversion copy — they can be deleted with the nag system. `Day15FullUpgradeWindow.swift` supporting lines (`:22-44`) and `HardGateReason` are tied to the hard-gate ladder and are removed with that subsystem (covered by other audit sections).
6. **`UsageStats` trigger recording** (`src/util/UsageStats.swift:8-15`) exists only to power conversion copy and the Day-X nags. It has no functional effect on switching; safe to remove along with the prompt system, but it is harmless if left (writes to a separate `.usage` UserDefaults suite).
+332
View File
@@ -0,0 +1,332 @@
# 07 — Pro Upsell UI Overlay & Menu-bar Integration
**Scope:** `src/pro/ui/` (the shared upsell UI toolkit) and `src/Menubar.swift` (the
`NSStatusItem` menu and its license/trial/badge integration).
This section documents every upsell-specific UI component, how `ProPromptHost.dispatch`
routes the timed Day-X prompts, every menu-bar item that is license / trial / upsell
related, and what the menu bar should look like once the paywall is removed.
> Cross-references: the Day-X window/popover classes live in `src/pro/scheduling/`
> (audited separately). The coordinator that *emits* prompt actions is
> `ProTransitionManager` (`src/pro/scheduling/ProTransitionManager.swift`). License state
> lives in `src/pro/license/`. This section only covers the *UI receivers* of those
> emissions and the menu-bar surface.
---
## 1. The `src/pro/ui/` toolkit
`src/pro/ui/` is a small library of reusable AppKit building blocks. None of these classes
contain license/trial *logic* themselves — they are pure presentation primitives consumed
by the Day-X scheduling windows (in `src/pro/scheduling/`) and by the Settings "Upgrade"
tab (`src/preferences/settings-window/tabs/UpgradeTab.swift`). They exist *only* to render
the paywall/upsell, so all of them are deletion candidates for a fully-free build, but
several are referenced from non-pro code and must be untangled (see §1.8).
### 1.1 `ProPromptHost.swift` — the dispatch hub
`/Users/james.maes/Git.Local/kof22/alt-tab-free/src/pro/ui/ProPromptHost.swift`
A singleton (`ProPromptHost.shared`, line 9) whose sole job is to translate the abstract
`ProPromptAction` enum into concrete Day-X UI calls. It is wired at launch in
`src/App.swift:428`:
```swift
ProTransitionManager.shared.onAction = { ProPromptHost.shared.dispatch($0) }
```
`dispatch(_:)` (lines 11–38) is a single `switch` over `ProPromptAction`
(defined in `src/pro/scheduling/ProTransitionManager.swift:87-98`). The complete routing
table:
| `ProPromptAction` case | Source line | UI call made | Day label |
|---|---|---|---|
| `.showWelcome` | `ProPromptHost.swift:13-14` | `Day1WelcomeLetterWindow.show()` | [A] Day 1 |
| `.showDay4Tour` | `:15-16` | `Day4TourPopover.show()` | [H] Day 4 |
| `.showDay12HeadsUp` | `:17-19` | `Day12HeadsUpPopover.show()` **then** `Menubar.menubarIconCallback(nil)` | [B] Day 12 |
| `.showDay15Proactive` | `:20-21` | `Day15ProactiveWindow.show()` | [D] Day 15 |
| `.showDay15FullUpgrade(reason)` | `:22-23` | `Day15FullUpgradeWindow.show(for: reason)` | [C] Day 15 |
| `.showDay15HardGatePopover(reason)` | `:24-25` | `Day15HardGatePopover.show(for: reason)` | [E] Day 15 hard gate |
| `.showDay21Reminder` | `:26-27` | `Day21ReminderPopover.show()` | [F] Day 21 |
| `.showDay35Final` | `:28-29` | `Day35FinalWindow.show()` | [G] Day 35 |
| `.dismissAllProWindows` | `:30-34` | closes the four singleton windows (Day1/Day15Full/Day15Proactive/Day35) | on upgrade-to-pro |
| `.refreshBadge` | `:35-36` | `Menubar.menubarIconCallback(nil)` | menu-bar badge dot refresh |
Two cases reach back into the menu bar: `.showDay12HeadsUp` (line 19) and `.refreshBadge`
(line 36) both call `Menubar.menubarIconCallback(nil)` to repaint the orange badge dot
(see §2.5). The window-class APIs the host calls were verified to exist:
`show()` / `show(for:)` static methods and `shared?` optionals on the window subclasses.
### 1.2 `ProPromptPopover.swift` — popover plumbing
`/Users/james.maes/Git.Local/kof22/alt-tab-free/src/pro/ui/ProPromptPopover.swift`
An `enum` namespace (no instances) with two static helpers used by the four menu-bar-anchored
Day-X popovers ([B] Day 12, [E] Day 15 hard gate, [F] Day 21, [H] Day 4):
- `make(contentSize:)` (lines 10–15) builds a `.transient` `NSPopover`.
- `present(_:content:)` (lines 18–25) sets the content VC, activates the app, then anchors
the popover under the menu-bar icon via `Menubar.showPopoverFromMenubar(popover)`
(line 23) — its only coupling to `Menubar`.
### 1.3 `ProPromptWindow.swift` — base window chrome
`/Users/james.maes/Git.Local/kof22/alt-tab-free/src/pro/ui/ProPromptWindow.swift`
`NSWindow` subclass (lines 7–26) providing the shared chrome for the four non-modal Day-X
*windows* ([A] Welcome, [C] Full Upgrade, [D] Proactive, [G] Final): hidden titlebar,
hidden traffic-light buttons, `hidesOnDeactivate = false`, `isReleasedWhenClosed = false`,
and `Esc`→`close()` (line 23-25). Title is hard-coded `"AltTab Pro"` (line 12).
### 1.4 `ProPromptHeader.swift` — branded window header
`/Users/james.maes/Git.Local/kof22/alt-tab-free/src/pro/ui/ProPromptHeader.swift`
`NSStackView` subclass (lines 10–64) drawing an app-icon + title row at the top of every
Day-X window. Notable: it auto-replaces the last `"Pro"` substring in the title with a
gradient text attachment from `ProGradient.makeProTextAttachment` (lines 55–63). Consumed by
Day1/Day15Full/Day15Proactive/Day35 windows (see §1.8).
### 1.5 `ProGradientButton.swift` — the gradient CTA button
`/Users/james.maes/Git.Local/kof22/alt-tab-free/src/pro/ui/ProGradientButton.swift`
`NSButton` subclass (lines 3–100) rendering the pink→blue gradient "buy" button used as the
primary CTA across the upsell. Custom layer-based gradient fill (line 8, using
`ProGradient.makeLayer`), drop shadow, and a hover "shine" sweep animation
(`playShineAnimation`, lines 74–99). Subclassed by Settings: `UpgradeButton`
(`SettingsWindow.swift:133`) and `ProHeroButton` (`UpgradeTab.swift:493`).
### 1.6 `UsageStatHeroView.swift` — "your usage so far" stat block
`/Users/james.maes/Git.Local/kof22/alt-tab-free/src/pro/ui/UsageStatHeroView.swift`
`NSStackView` subclass (lines 22–140) rendering a guilt/value-framing hero block driven by
`UsageStats.triggerCount` and `UsageStats.usedProFeaturesSessionCount` (read at init and on
`refresh()`, lines 64–65). Three render modes (both counts >0 → two columns; only triggers
→ one column; both zero → omitted). The "Pro feature uses" column number is drawn as a
gradient image (lines 84-88, 112-117). Lead-in copy is `"YOUR USAGE SO FAR"` (line 69).
Consumed by Day15Full, Day15Proactive, Day35 windows and the Upgrade tab (see §1.8).
### 1.7 `ProBadgeView.swift` — the "Pro" pill + gradient utilities (largest file)
`/Users/james.maes/Git.Local/kof22/alt-tab-free/src/pro/ui/ProBadgeView.swift`
This 458-line file actually contains **five** distinct types, only the last of which is the
badge view proper:
1. **`enum ProGradient`** (lines 3–119) — the gradient color/geometry definitions
(lines 4–13) plus rendering helpers: `makeLayer`, `makeGradientTextImage`,
`makeProTextAttachment`, `makeGradientTextAttachment` (used for menu rows showing
"Get Pro" per the line 70 comment), `makeFullProBadgeImage` (renders the badge into an
`NSImage` for `NSMenuItem.image` / closed `NSPopUpButton` face, lines 90–101), and
`drawGradientFill`. This enum is the shared dependency of basically every other upsell
surface (the gradient menu pill, the Pro segment overlays in Settings, etc.).
2. **`class ProDropdownItemView`** (lines 124–187) — a custom `NSMenuItem.view` that draws a
title + full Pro pill in a dropdown row, with its own highlight handling. (Used by
Settings dropdowns, **not** the menu bar.)
3. **`class NotAdvisedButton`** (lines 190–200) — the small gray "discouraged action" link
button ("Not now", "Maybe later", "Continue with Free", "No thanks…"). Consumed by all
Day-X dismiss links (see §1.8).
4. **`class DynamicColorImageView`** (lines 205–213) — state-aware tinted image view used by
the Pro-segment overlay in Settings.
5. **`class ProBadgeView`** (lines 215–458) — the actual "Pro" pill. Includes static helpers
`attach(to:segmentIndex:…)` (lines 257–318) and `refreshSelection(…)` (lines 323–327)
that overlay a Pro badge on a `NSSegmentedControl` segment in Settings. Registers `"Pro"`
with the Settings search index at init (line 344: `SettingsSearchIndex.registerString`).
> Note: despite the filename, the menu-bar code does **not** instantiate `ProBadgeView`
> directly. Menubar uses `ProGradient.makeLayer` (indirectly, via `UpgradeMenuItemView`)
> and the orange dot is a hand-rolled `CALayer`, not a `ProBadgeView`.
### 1.8 Consumers of the toolkit (untangle map for removal)
Confirmed via grep across `src/`. These are the call sites that will break if `src/pro/ui/`
is deleted wholesale:
| Toolkit type | Consumed by | File:line |
|---|---|---|
| `ProGradientButton` | `UpgradeButton` (Settings) | `preferences/settings-window/SettingsWindow.swift:133` |
| `ProGradientButton` | `ProHeroButton` (Upgrade tab) | `preferences/settings-window/tabs/UpgradeTab.swift:493` |
| `UsageStatHeroView` | Upgrade tab hero | `preferences/settings-window/tabs/UpgradeTab.swift:5,37` |
| `UsageStatHeroView` | Day15Full / Day15Proactive / Day35 | `pro/scheduling/Day15FullUpgradeWindow.swift:56`, `Day15ProactiveWindow.swift:38`, `Day35FinalWindow.swift:27` |
| `ProPromptHeader` | Day1 / Day15Full / Day15Proactive / Day35 | `pro/scheduling/Day1WelcomeLetterWindow.swift:22`, `Day15FullUpgradeWindow.swift:53`, `Day15ProactiveWindow.swift:34`, `Day35FinalWindow.swift:23` |
| `NotAdvisedButton` | Day12 / Day15Full / Day15HardGate / Day15Proactive / Day21 / Day35 | `pro/scheduling/Day12HeadsUpPopover.swift:28`, `Day15FullUpgradeWindow.swift:66`, `Day15HardGatePopover.swift:28`, `Day15ProactiveWindow.swift:48`, `Day21ReminderPopover.swift:34`, `Day35FinalWindow.swift:37` |
| `ProGradient` / `ProBadgeView.attach` | Settings tabs (Appearance/Controls Pro segments, search index) | `SettingsSearchIndex.swift`, `AppearanceTab.swift`, `ControlsTab.swift`, `LabelAndControl.swift` (per earlier grep on `ProTransitionManager`/badge usage) |
Because every Day-X scheduling class is being removed in the same effort, the
`src/pro/ui/` types whose *only* surviving consumers are the Settings Upgrade tab are
`ProGradientButton`, `UsageStatHeroView`, and the `ProGradient`/`ProBadgeView` segment
helpers. Those will be resolved when the Upgrade tab and Pro-segment overlays are removed.
---
## 2. `src/Menubar.swift` — the `NSStatusItem` menu
`/Users/james.maes/Git.Local/kof22/alt-tab-free/src/Menubar.swift`
`Menubar` is the always-present `NSStatusItem`. Most of it (Show / Settings / Check for
updates / Check permissions / About / Send feedback / Quit, the menu-bar icon preference,
removal-from-menubar observation, the Screen-Recording `PermissionCallout`) is **not**
paywall-related and must survive. The paywall touch-points are isolated to the three
license-driven menu items, the `refreshLicenseMenuItems` state machine, the
`UpgradeMenuItemView`, and the badge-dot overlay.
### 2.1 Stored upsell menu items
Lines 8–10 declare three license-driven items as static vars:
```swift
private static var upgradeToProMenuItem: NSMenuItem! // line 8
private static var supportProjectMenuItem: NSMenuItem! // line 9
private static var myAccountMenuItem: NSMenuItem! // line 10
```
### 2.2 Menu construction (`initialize()`, lines 27–66)
The non-pro items are added at lines 37–45 (Show, Settings, Check for updates, Check
permissions, About, **Debug tools**, Send feedback). The three pro items are added
immediately after:
- **Line 46:** `upgradeToProMenuItem = addMenuItem("Get Pro", App.upgradeToProAction, "", "star.fill", …)`
— the "Get Pro" upsell entry. Its action `App.upgradeToProAction`
(`App.swift:26`) → `@objc App.upgradeToPro()` (`App.swift:115-117`) →
`ProTransitionManager.openCheckout()` → opens `Endpoints.checkoutUrl`
(`ProTransitionManager.swift:307-308`; URL `…/pricing`, `Endpoints.swift:9`).
- **Line 47:** `upgradeToProMenuItem.view = UpgradeMenuItemView()` — replaces the row with the
custom gradient view (§2.4).
- **Line 48:** `myAccountMenuItem = addMenuItem("My Account", App.openAccountAction, …)` —
action `App.openAccountAction` (`App.swift:27`) → `App.openAccount()`
(`App.swift:119-121`) → `UpgradeTab.openAccountPage()` → opens `Endpoints.accountUrl`
(`…/my-account`, `Endpoints.swift:10`).
- **Line 49:** `supportProjectMenuItem = addMenuItem("Support this project", App.supportProjectAction, …, .red, …)`
— heart icon, action `App.supportProjectAction` (`App.swift:25`) →
`App.supportProject()` (`App.swift:111-113`) → opens `Endpoints.supportUrl`
(`…/support`, `Endpoints.swift:8`).
- **Line 50:** `refreshLicenseMenuItems()` — runs the state machine to show/hide these three.
> Upstream AltTab (the GPL parent) historically shipped a "Support this project" /
> donate item; "Get Pro" and "My Account" are the fork's proprietary additions. Whether to
> keep "Support this project" in the free build is a product decision (see §3), but it is
> currently gated by the same `refreshLicenseMenuItems` state machine.
### 2.3 `refreshLicenseMenuItems()` state machine (lines 84–107)
Reads `LicenseManager.shared.state` (`LicenseState`, defined
`pro/license/LicenseState.swift:1-21`) and shows/hides the three items per state:
| `LicenseState` | "Get Pro" (upgrade) | "Support this project" | "My Account" |
|---|---|---|---|
| `.trial(daysRemaining)` | shown | hidden | hidden |
| `.pro` | **removed** (`toggleUpgradeMenuItem(false)`) | hidden | shown |
| `.proExpired` | shown | shown | shown |
| `.trialExpired` | shown | shown | hidden |
- `.pro` early-returns at line 105 *before* calling `updateContent`, so the gradient view's
text is only refreshed for non-pro states (line 106).
- `toggleUpgradeMenuItem(_:)` (lines 109–118) inserts/removes `upgradeToProMenuItem`
relative to `supportProjectMenuItem`'s index — the "Get Pro" row is fully removed from the
menu (not just `isHidden`) for Pro users, because `NSMenuItem.isHidden` is unreliable with
custom views (same pattern as the permission callout, comment at line 135).
`refreshLicenseMenuItems()` is invoked from:
- `Menubar.initialize()` line 50 (initial build).
- `App.swift:450` inside `LicenseManager.shared.onStateChanged` (license state transitions).
### 2.4 `UpgradeMenuItemView` (lines 235–390)
Custom `NSView` set as `upgradeToProMenuItem.view`. Renders the gradient "Get Pro" pill in
the menu with a two-line label and a `star.fill` icon (lines 269–275, tinted white). Uses
`ProGradient.makeLayer()` (line 247) for the backdrop and has its own hover "shine"
animation (`playShineAnimation`, lines 328–355) mirroring `ProGradientButton`.
- `updateContent(_ state:)` (lines 357–382) builds the two-line attributed string. The
**trial day count** appears here: line 370-371,
`String(format: "Trial: %d days remaining", daysRemaining)` for `.trial`; line 372-373
`"License doesn't cover this version"` for `.proExpired`; else `"Trial expired"`
(line 375). Second line is always `"Get Pro"` (line 380).
- `mouseUp` (lines 384–389) cancels menu tracking and calls `App.upgradeToPro()`
(opens checkout).
### 2.5 The orange badge dot overlay (lines 187–227)
A hand-rolled 7pt orange `CALayer` (`systemOrange`, line 221) anchored to the bottom-right
of the menu-bar icon, signalling "the trial is ending / there's an upsell to see."
- `badgeDotLayer` static var (line 187).
- `updateBadgeDotOverlay()` (lines 202–227): removes any existing dot, then
**guards on `ProTransitionManager.shared.shouldShowBadgeDot`** (line 205). If false (or
no button), it stops — so the dot only appears when the transition manager says so
(`shouldShowBadgeDot` defined `ProTransitionManager.swift:161-162`, delegating to
`ProTransitionManagerTestable.shouldShowBadgeDot`). Otherwise it builds the orange dot
layer.
- Invoked only from `loadPreferredIcon()` (line 196), which runs inside
`applyMenubarIconPreferences()` → `menubarIconCallback(_:)` (lines 155–164). That callback
is the entry point `ProPromptHost` calls (lines 19, 36) to repaint the dot, and is also
called from `PreferencesEvents.swift:79` and `QAMenu.swift:240` (non-pro icon-pref
changes also repaint, harmlessly).
### 2.6 `MenubarMenuDelegate` (lines 392–399)
`menuWillOpen` calls `LicenseManager.shared.refreshState()` (line 396) so the trial-day
subtitle in `UpgradeMenuItemView` reflects the current clock at open time, then
`Menubar.refreshPermissionCallout()` (line 397, non-pro). The `refreshState()` call is the
license/trial coupling here; the permission-callout refresh is independent and must stay.
### 2.7 Non-pro menu-bar code (must survive untouched)
For clarity on what is *not* in scope for removal: `addMenuItem` helper (14–25), the
QA-menu middle-click monitor (DEBUG only, 68–82), `refreshPermissionCallout` /
`togglePermissionCallout` / `PermissionCallout` (120–144, 401–445), `statusItemOnClick`
(146–153), the icon-preference + removal-observer machinery (166–197 minus the badge-dot
call at 196), and `showPopoverFromMenubar` (229–232). Note `showPopoverFromMenubar` is used
*only* by the Day-X popovers via `ProPromptPopover.present`, so after the paywall is removed
it becomes dead code and can be deleted too.
---
## 3. What the menu bar should look like with the paywall gone
After removing the trial/license/upsell system, the `NSStatusItem` menu should reduce to
the upstream-style set of items:
```
Show
─────────
Settings…
Check for updates…
Check permissions…
─────────
About AltTab
Debug tools (DEBUG builds only — see note)
Send feedback…
Support this project (product decision — see below)
─────────
Quit AltTab
```
Concrete `Menubar.swift` changes required for a clean free build:
- **Remove the three license-driven items and their wiring:**
- Delete the three static vars at lines 8–10.
- Delete line 46 (`Get Pro`), line 47 (`.view = UpgradeMenuItemView()`), line 48
(`My Account`), and the `refreshLicenseMenuItems()` call at line 50. ("Support this
project" at line 49 is the only one of the four that has upstream precedent — keep or
drop per product decision; if kept, add it unconditionally and stop hiding it.)
- **Delete `refreshLicenseMenuItems()` (84–107) and `toggleUpgradeMenuItem(_:)` (109–118)**
entirely — both reference `LicenseManager`/`LicenseState`.
- **Delete the `UpgradeMenuItemView` class (235–390)** — it is the gradient pill, the trial
day-count renderer, and the checkout `mouseUp`. Its only consumer is line 47.
- **Delete the badge-dot overlay** (`badgeDotLayer` line 187; `updateBadgeDotOverlay()`
202–227) and remove its call at line 196 inside `loadPreferredIcon()`. With it gone,
`loadPreferredIcon` no longer depends on `ProTransitionManager`.
- **Simplify `MenubarMenuDelegate.menuWillOpen` (392–399)** — drop the
`LicenseManager.shared.refreshState()` call at line 396; keep
`refreshPermissionCallout()` (line 397).
- **`menubarIconCallback(_:)` (155–164)** can stay (it is also the icon-preference entry
point), but its callers in `ProPromptHost.swift:19,36` disappear with the host. The
`applyMenubarIconPreferences`/`loadPreferredIcon` path remains valid for the
PreferencesEvents/QAMenu callers.
- **`showPopoverFromMenubar` (229–232)** becomes dead code (only the Day-X popovers used it)
and can be removed.
In `src/App.swift`: remove `supportProjectAction`/`upgradeToProAction`/`openAccountAction`
(25–27) and the `@objc supportProject/upgradeToPro/openAccount` methods (111–121) if their
endpoints (`pricing`, `my-account`, `support`) are also dropped; remove the
`ProTransitionManager.shared.onAction = …` wiring (line 428) and the
`Menubar.refreshLicenseMenuItems()` call inside `onStateChanged` (line 450).
The entire `src/pro/ui/` directory can be deleted **once** its non-pro consumers in
`src/preferences/settings-window/` (the Upgrade tab, the Pro-segment overlays via
`ProBadgeView.attach` / `ProGradient`, and the search-index `"Pro"` registration at
`ProBadgeView.swift:344`) are removed in the Settings audit. Until then,
`ProGradient`, `ProGradientButton`, `UsageStatHeroView`, and the `ProBadgeView` segment
helpers are still referenced and would break the build if deleted prematurely.
> **Note on "Debug tools":** it is added unconditionally at `Menubar.swift:44` in this fork
> (not behind `#if DEBUG`), unlike the QA-menu monitor. Leaving it is orthogonal to the
> paywall; flag it for the product owner but it is not a removal blocker.
+259
View File
@@ -0,0 +1,259 @@
# 08 — Build, Signing, Auto-Update & Publishing Pipeline
How `alt-tab-free` (a fork of `lwouis/alt-tab-macos`) is actually built, versioned, signed,
notarized, shipped, and auto-updated. This section is written for the republish-as-free goal:
every place the pipeline still points at the **original upstream / paywall vendor** (`lwouis`,
`alt-tab.app`, AppCenter, the upstream Developer ID and Sparkle key) is enumerated at the end.
---
## 1. How to build locally
There is no Makefile / wrapper — builds are raw `xcodebuild` invocations over
`alt-tab-macos.xcodeproj`. There are exactly **three schemes** (`alt-tab-macos.xcodeproj/xcshareddata/xcschemes/`):
`Debug.xcscheme`, `Release.xcscheme`, `Test.xcscheme`.
### Debug build (everyday dev loop)
`ai/build.sh:3-7`:
```
xcodebuild -project alt-tab-macos.xcodeproj -scheme Debug -configuration Debug -derivedDataPath DerivedData
```
- Per `AGENTS.md` the sanctioned workflow is "copy commands from `ai/build.sh` and run them" — never drive Xcode interactively.
- Run the built app: `ai/run.sh:3` runs `DerivedData/Build/Products/Debug/AltTab.app/Contents/MacOS/AltTab --logs=debug --benchmark showUi 3`.
- Profile: `ai/profile.sh` records a 20s Time Profiler trace via `xcrun xctrace` and exports it to XML.
### Release build (what CI ships)
`scripts/build_app.sh:5`:
```
xcodebuild -project alt-tab-macos.xcodeproj -scheme Release -derivedDataPath DerivedData | scripts/xcbeautify
```
Release products land in `DerivedData/Build/Products/Release` (`XCODE_BUILD_PATH` env, `ci_cd.yml:17`).
### Build configuration (xcconfig layering)
Build settings live in `config/*.xcconfig`, attached to the project via `baseConfigurationReference`
entries in `alt-tab-macos.xcodeproj/project.pbxproj` (lines ~2429–2562). The layering:
- `config/base.xcconfig` — shared identity & build settings. Key values:
- `PRODUCT_NAME = AltTab` (`base.xcconfig:3`)
- `PRODUCT_BUNDLE_IDENTIFIER = com.lwouis.alt-tab-macos` (`base.xcconfig:4`) **[upstream identity — see §7]**
- `MACOSX_DEPLOYMENT_TARGET = 10.13` (`base.xcconfig:5`); `SWIFT_VERSION = 5.8` (`:6`)
- `INFOPLIST_FILE = Info.plist`, `CODE_SIGN_ENTITLEMENTS = alt_tab_macos.entitlements` (`:8-9`)
- `ENABLE_HARDENED_RUNTIME = YES` (`:12`, required for notarization)
- `DOMAIN = alt-tab.app` and `API_DOMAIN = alt-tab.app/api` (`:20-21`) **[upstream domains — see §7]**
- `config/debug.xcconfig` — `#include "base.xcconfig"`, then `CODE_SIGN_IDENTITY = Local Self-Signed` (`:5`), `SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG` (`:6`), `OTHER_CODE_SIGN_FLAGS = --timestamp=none` (`:8`). Ends with `#include? "local.xcconfig"` (`:13`).
- `config/release.xcconfig` — `#include "base.xcconfig"`, then `CODE_SIGN_IDENTITY = Developer ID Application: Louis Pontoise (QXD7GW8FHY)` (`:5`) **[upstream Developer ID — see §7]**, `OTHER_CODE_SIGN_FLAGS = --timestamp --deep --options runtime` (`:7`, for notarization), wholemodule + `-O` + ThinLTO + full stripping (`:8-18`). Ends with `#include? "local.xcconfig"` (`:21`).
- `config/test-base.xcconfig` / `test-debug.xcconfig` / `test-release.xcconfig` — for the Test scheme; signing disabled (`CODE_SIGNING_REQUIRED = NO`, `CODE_SIGNING_ALLOWED = NO`, `test-base.xcconfig:6-7`), `ONLY_ACTIVE_ARCH = YES`.
`config/local.xcconfig` is **not committed** (referenced via `#include?`, so optional). It is the
per-developer / CI override channel for `CODE_SIGN_IDENTITY`, `APPCENTER_SECRET`, `CURRENT_PROJECT_VERSION`,
`DOMAIN`, `API_DOMAIN`. The pbxproj has a stale `local.xcconfig` file reference (`project.pbxproj:458`)
but it is *not* set as a `baseConfigurationReference` — the `#include?` in debug/release is what loads it.
### `DEVELOPMENT_TEAM` is empty at build time
In `project.pbxproj` the app target sets `DEVELOPMENT_TEAM = "${TEAM_ID}"` (lines 2462, 2520, 2554),
but **`TEAM_ID` is never defined** anywhere (not in any xcconfig, not in CI env). It therefore
expands to empty, so signing is driven purely by `CODE_SIGN_IDENTITY`. The CI's `APPLE_TEAM_ID`
secret is used *only* by `notarytool` (`package_and_notarize_release.sh:17`), not by `xcodebuild`.
The Debug target explicitly sets `DEVELOPMENT_TEAM = ""` (`project.pbxproj:2562`). Net effect:
Release is signed with whatever identity `release.xcconfig` (or a `local.xcconfig` override) names.
### Local Release signing without the upstream cert
`scripts/codesign/setup_local.sh` generates a throwaway self-signed cert and imports it into the
main keychain (calls `generate_selfsigned_certificate.sh` → `import_certificate_into_main_keychain.sh`).
This lets a developer who lacks the `Developer ID Application: Louis Pontoise` cert still produce a
signed-but-not-notarizable Release (typically combined with a `local.xcconfig` overriding
`CODE_SIGN_IDENTITY`).
### Tooling prerequisites
- **Xcode 26.0.1** pinned in CI (`ci_cd.yml:45`: `sudo xcode-select -s /Applications/Xcode_26.0.1.app/...`).
- **Node** (16 in CI, `package.json` `engines` says `>=18`) for `commitlint`, `semantic-release`, `swiftformat.js`, `ts-node`.
- **Python 3.6** (`Pipfile`) only for asset/l10n tooling (`fonttools`, `googletrans`), not the app build.
- Bundled binaries in `scripts/`: `xcbeautify` (6.5 MB), `notarytool` (17 MB), `assets/createicns`; and `vendor/Sparkle/bin/sign_update`.
---
## 2. Versioning & release cutting (semantic-release)
Releases are fully automated from Conventional Commits on `master`; there is **no manual version
bump**. `package.json` `version` (`1.0.0`) is irrelevant — the app version is computed by semantic-release.
### Commit linting → version derivation
- `commitlint.config.js` extends `@commitlint/config-conventional`. CI enforces it across the pushed range: `npx commitlint --from "$GITHUB_EVENT_BEFORE" --to "$GITHUB_EVENT_AFTER"` (`ci_cd.yml:48`).
- `release.config.js` configures `@semantic-release/commit-analyzer` (angular preset) with extra `releaseRules` so `perf/docs/style/refactor/test/chore/ci` all force at least a **patch** bump (`release.config.js:6-14`). `feat` → minor, breaking → major (defaults).
- `scripts/determine_next_version.sh:5-8` runs `npx semantic-release --dry-run`, greps "The next release version is …", and writes the bare version (e.g. `11.3.0`) to `VERSION.txt` (the `$VERSION_FILE`, `ci_cd.yml:18`). `VERSION.txt` is **not committed** — it is a CI-only scratch file consumed by later steps.
### Version injection into the app
`scripts/replace_environment_variables_in_app.sh:7-11` writes a fresh `config/local.xcconfig`:
```
CURRENT_PROJECT_VERSION = <contents of VERSION.txt>
APPCENTER_SECRET = $APPCENTER_SECRET
```
`Info.plist` consumes `$(CURRENT_PROJECT_VERSION)` for both `CFBundleShortVersionString` and
`CFBundleVersion` (`Info.plist:26-29`), and `$(APPCENTER_SECRET)` for `AppCenterSecret` (`Info.plist:73-74`).
### Changelog, tag & GitHub Release
- `npx semantic-release` (`ci_cd.yml:59`) runs the full plugin chain in `release.config.js`: generates release notes → updates `changelog.md` (`@semantic-release/changelog`) → commits `changelog.md`, `appcast.xml`, `README.md` back to the repo (`@semantic-release/git`), and creates the git tag.
- `scripts/extract_latest_changelog.sh` writes `tag_name=v<version>` and the top changelog block to `$GITHUB_OUTPUT` (`:6-9`).
- `softprops/action-gh-release@v3` (`ci_cd.yml:62-66`) publishes the GitHub Release with that tag/body and attaches `DerivedData/Build/Products/Release/*.zip`.
- `changelog.md` is already populated with upstream history; entries link to `github.com/lwouis/alt-tab-macos/...` (e.g. `changelog.md:1`). The most recent committed release is **11.3.0** (matches `git log`).
---
## 3. Code signing & notarization
### Signing
- Release is signed by Xcode using `CODE_SIGN_IDENTITY = Developer ID Application: Louis Pontoise (QXD7GW8FHY)` (`release.xcconfig:5`) with hardened runtime + secure timestamp (`base.xcconfig:12`, `release.xcconfig:7`).
- The signing cert reaches CI via a base64 P12 secret: `scripts/codesign/setup_ci_master.sh:8` decodes `$APPLE_P12_CERTIFICATE` to `codesign.p12`, then `import_certificate_into_new_keychain.sh` creates/unlocks a dedicated `alt-tab-macos.keychain`, imports the P12 for `/usr/bin/codesign`, and runs `security set-key-partition-list` (`import_certificate_into_new_keychain.sh:12-19`).
- `setup_ci_pr.sh` (used on PRs, not wired into the current `master`-only workflow) generates a self-signed cert instead — PRs build but cannot notarize.
### Entitlements
`alt_tab_macos.entitlements`: `app-sandbox = false` (it needs Accessibility/Screen Recording) and
`com.apple.security.cs.disable-library-validation = true` (to load the embedded Sparkle/AppCenter
frameworks under hardened runtime).
### Sparkle framework re-sealing (build phase)
`scripts/copy_sparkle_helpers.sh` is a "Copy Sparkle Helpers" build phase that runs after Embed
Frameworks and before Xcode's final code sign. It copies the prebuilt `Updater.app` + `Autoupdate`
into `Sparkle.framework/Versions/A/`, mirrors SPM-generated resources, rewrites the framework
`CFBundleIdentifier` to `org.sparkle-project.Sparkle`, then **re-signs** the framework with
`EXPANDED_CODE_SIGN_IDENTITY`/`CODE_SIGN_IDENTITY` (final lines of the script). The `Updater.app`/
`Autoupdate` helpers are pre-signed with the maintainer's Developer ID at vendor time
(`vendor/scripts/update_sparkle.sh`).
### Notarization (`scripts/package_and_notarize_release.sh`)
1. `ditto -c -k --keepParent AltTab.app AltTab-<version>.zip` (`:11`).
2. Submit to Apple: `scripts/notarytool submit --apple-id "$APPLE_ID" --password "$APPLE_PASSWORD" --team-id "$APPLE_TEAM_ID" <zip> --wait --timeout 15m` (`:14-19`). Exits non-zero unless status is `Accepted` (`:22`).
3. `xcrun stapler staple AltTab.app` (`:25`) then re-zips the stapled app over the same name (`:26`). That stapled zip is the GitHub Release asset and the Sparkle download.
### Keychain / identity invariant (from `AGENTS.md`)
The app's Developer ID, TeamID, and bundle ID must stay stable across builds: Keychain items
(license keys) are tied to the code signature. Changing any one orphans every user's stored
license. **For the free fork this is the reason §7 matters** — but since the fork is *removing*
the license/Keychain layer entirely, the invariant's coupling concern goes away once the `src/pro`
license code is gone (no Keychain license to orphan). The identity still must change because the
upstream Developer ID cannot be used.
---
## 4. Auto-update (Sparkle)
The app embeds **Sparkle 2.9.1** (`vendor/Sparkle/UPSTREAM`), vendored as source via SPM plus
prebuilt helper apps.
### Wiring in code
- `src/App.swift:407-413` builds an `SPUStandardUpdaterController(startingUpdater: false, updaterDelegate: App.sparkleDelegate!, ...)` and calls `startUpdater()` 30s after launch.
- `src/vendors/SparkleDelegate.swift:26-28` supplies the feed URL: `feedURLString → Endpoints.appcastUrl`.
- `src/api/Endpoints.swift`: `website = "https://\(domain)"` where `domain` is read from the `Domain` Info.plist key (`Endpoints.swift:4,6`); `appcastUrl = "\(website)/appcast.xml"` (`:7`). With `DOMAIN = alt-tab.app` that resolves to **`https://alt-tab.app/appcast.xml`** **[upstream feed — see §7]**.
- `feedParameters` (`SparkleDelegate.swift:30-38`) appends `version`, `macos`, `arch`, `lang` query params to the feed request.
- **Tier-aware appcast:** `src/pro/license/LicenseCookie.swift` writes a `license` cookie (`pro`/`proExpired`/empty) on the `alt-tab.app` domain so the appcast server can tailor responses per license tier (`LicenseCookie.swift:3,9-21`). This is paywall-coupled and goes away with `src/pro` removal.
- Update preferences are toggled in `src/events/UserDefaultsEvents.swift`, `src/events/PreferencesEvents.swift:85-86`, and `src/preferences/settings-window/tabs/GeneralTab.swift:100-101`. `Info.plist:63-66` sets `SUEnableAutomaticChecks = true`, `SUScheduledCheckInterval = 604800` (weekly).
### EdDSA signing
- The **public** EdDSA key is baked into `Info.plist:61-62`: `SUPublicEDKey = 2e9SQOBoaKElchSa/4QDli/nvYkyuDNfynfzBF6vJK4=` **[upstream key — see §7]**.
- The **private** key lives only in CI as `$SPARKLE_ED_PRIVATE_KEY`. `scripts/update_appcast.sh:9` signs each zip with `vendor/Sparkle/bin/sign_update -s $SPARKLE_ED_PRIVATE_KEY <zip>` and embeds the `sparkle:edSignature` + `length` into a new `<item>`.
### Appcast file (`appcast.xml`)
- RSS 2.0 with Sparkle namespace; `<title>alt-tab-macos</title>`. 3876 lines, newest item first (currently 11.3.0).
- `scripts/update_appcast.sh:11-26` builds an `ITEM.txt` block and `sed`-inserts it right after the `</language>` tag. Each `<enclosure url=...>` points at **`https://github.com/lwouis/alt-tab-macos/releases/download/v<version>/AltTab-<version>.zip`** (`update_appcast.sh:18`) **[upstream download host — see §7]**, and the release-notes link is **`https://alt-tab.app/changelog-bare`** (`:16`) **[upstream — see §7]**.
- `appcast.xml` is committed back to the repo by semantic-release (`release.config.js:21-26`). The *file* is what Sparkle fetches from `alt-tab.app/appcast.xml`, so the hosting website serves this committed file.
### Distribution surface summary
The download artifacts live on **GitHub Releases of `lwouis/alt-tab-macos`** (per the appcast
enclosure URLs and the `update_readme_and_website.sh` API calls), and the appcast/release-notes are
served from the **`alt-tab.app`** website. The website itself is a *separate* repo
(`lwouis/alt-tab-website`, see §6).
---
## 5. Crash reporting & symbols (Microsoft AppCenter)
- The app subclasses `AppCenterApplication` (`Info.plist:36-37` `NSPrincipalClass`; `src/App.swift:7`). `src/vendors/AppCenterCrashes.swift:20` calls `AppCenter.start(withAppSecret: Secrets.appCenterSecret, services: [Crashes.self])`. The secret is read from the `AppCenterSecret` Info.plist key (`src/api/Secrets.swift:6`), injected from `$APPCENTER_SECRET` (`replace_environment_variables_in_app.sh:9`).
- Network is gated off unless a crash is actually sent (`AppCenterCrashes.swift:13-14, 49`).
- AppCenter is vendored (4.3.0 + PLCrashReporter 1.11.1, `vendor/scripts/update_appcenter.sh`).
- **dSYM upload:** `scripts/upload_symbols_to_appcenter.sh` zips and uploads `AltTab.app.dSYM` and `Sparkle.framework.dSYM` to `https://api.appcenter.ms/v0.1/apps/alt-tab-macos/alt-tab-macos` (`:4-7`) using `$APPCENTER_TOKEN`. **[upstream AppCenter account — see §7]**
> NOTE: Microsoft App Center is being retired (Microsoft announced March 31 2025 EoL). Even
> independent of the fork, this crash-reporting path is dead-ending and is a candidate for removal,
> not just re-pointing.
---
## 6. CI/CD workflow (`.github/workflows/ci_cd.yml`)
Single workflow, single `build` job, triggered only on **push to `master`** (`ci_cd.yml:1-4`),
runs on `macos-15`, environment `production` (`:22-23`). Step order (`:38-69`):
1. `actions/checkout@v6` with computed `fetch-depth` (commits + 30, `:28-40`) — needs history for commitlint/semantic-release.
2. `actions/setup-node@v6` (node 16) + `npm ci` (`:41-47`).
3. `npx commitlint --from <before> --to <after>` (`:48`).
4. `scripts/ensure_generated_files_are_up_to_date.sh` (`:49`) — runs l10n extraction and fails if it produced a diff (`git diff-files --exit-code`).
5. `scripts/determine_next_version.sh` (`:50`) → `VERSION.txt`.
6. `scripts/replace_environment_variables_in_app.sh` (`:51`) → `config/local.xcconfig`.
7. `scripts/codesign/setup_ci_master.sh` (`:52`) — import Developer ID P12.
8. `scripts/run_tests.sh` (`:53`) — `xcodebuild test -scheme Test -configuration Release`.
9. `scripts/build_app.sh` (`:54`) — Release build.
10. `scripts/package_and_notarize_release.sh` (`:55`) — zip + notarize + staple.
11. `scripts/upload_symbols_to_appcenter.sh` (`:56`) — dSYMs → AppCenter.
12. `scripts/update_appcast.sh` (`:57`) — sign zip + prepend appcast item.
13. `scripts/update_readme_and_website.sh` (`:58`) — refresh README stats SVG + contributors.
14. `npx semantic-release` (`:59`) — changelog/tag/commit-back.
15. `extract_latest_changelog.sh` (`:60-61`) → release notes.
16. `softprops/action-gh-release@v3` (`:62-66`) — publish GitHub Release + attach `*.zip`.
17. `scripts/update_website.sh` (`:67-69`) — `gh api repos/lwouis/alt-tab-website/dispatches -f event_type=update-website`, authed with `$WEBSITE_DISPATCH_TOKEN` (`update_website.sh:5`). **[upstream website repo — see §7]**
### CI secrets / env (`ci_cd.yml:5-19`)
`GITHUB_TOKEN`, `APPCENTER_SECRET`, `APPCENTER_TOKEN`, `APPLE_ID`, `APPLE_PASSWORD`,
`APPLE_TEAM_ID`, `APPLE_P12_CERTIFICATE` (base64 Developer ID P12), `SPARKLE_ED_PRIVATE_KEY`,
`WEBSITE_DISPATCH_TOKEN`. Plus computed `BUILD_DIR`, `XCODE_BUILD_PATH=DerivedData/Build/Products/Release`,
`VERSION_FILE=VERSION.txt`, `APP_NAME=AltTab`.
`scripts/update_readme_and_website.sh` hits `https://api.github.com/repos/lwouis/alt-tab-macos/...`
for contributors / star / download counts (`:10`) — another hardcoded upstream slug.
`.github/FUNDING.yml` points at upstream donation channels (`github: lwouis`, `patreon: alt_tab_macos`,
`ko_fi: alt_tab`, a PayPal button id). Cosmetic, but fork-specific.
---
## 7. CRITICAL — identities / URLs / secrets a fork MUST change or remove
Everything below still targets the **original upstream / paywall vendor**. A republished free fork
must change (C) or remove (R) each item. Build will not *break* if these are left as-is (it will
build and sign with whatever cert is present), but the app would phone home to upstream, fail to
update from the fork's own releases, and attempt to notarize/sign under the upstream account.
| # | What | Where (file:line) | Current value | Action |
|---|------|-------------------|---------------|--------|
| 1 | **Bundle ID** | `config/base.xcconfig:4` (+ unit-tests id `project.pbxproj:2477,2542`; mocks `src/_test-support/Mocks.swift:133`) | `com.lwouis.alt-tab-macos` | **C** — set fork's reverse-DNS id (e.g. `com.koftwentytwo.alt-tab-free`). |
| 2 | **Developer ID signing cert** | `config/release.xcconfig:5` | `Developer ID Application: Louis Pontoise (QXD7GW8FHY)` | **C** — fork's own Developer ID Application cert + TeamID. |
| 3 | **Signing P12 secret** | `ci_cd.yml:12` / `setup_ci_master.sh` | `$APPLE_P12_CERTIFICATE` | **C** — replace with fork's exported Developer ID P12. |
| 4 | **Notarization Apple account** | `ci_cd.yml:9-11`; `package_and_notarize_release.sh:15-18` | `$APPLE_ID` / `$APPLE_PASSWORD` / `$APPLE_TEAM_ID` | **C** — fork's Apple ID + app-specific password + TeamID. |
| 5 | **Sparkle public EdDSA key** | `Info.plist:62` | `2e9SQOBoaKElchSa/4QDli/nvYkyuDNfynfzBF6vJK4=` | **C** — generate a NEW EdDSA keypair (`generate_keys`); put public half here. |
| 6 | **Sparkle private EdDSA key** | `ci_cd.yml:13`; `update_appcast.sh:9` | `$SPARKLE_ED_PRIVATE_KEY` | **C** — fork's new private key. Must match #5 or updates won't verify. |
| 7 | **Appcast feed domain** | `config/base.xcconfig:20` (`DOMAIN`) → `Endpoints.swift:6-7` | `alt-tab.app` → `https://alt-tab.app/appcast.xml` | **C** — fork's domain, OR repoint feed at fork's GitHub-hosted appcast. |
| 8 | **API domain (license + feedback)** | `config/base.xcconfig:21` (`API_DOMAIN`) → `Endpoints.swift:5,11-12` | `alt-tab.app/api` → `https://alt-tab.app/api/v1/license`, `.../v1/feedback` | **R** — license API is paywall; remove with `src/pro`. Feedback endpoint must be repointed or removed. |
| 9 | **Appcast download URL** | `update_appcast.sh:18` | `https://github.com/lwouis/alt-tab-macos/releases/download/v<v>/...` | **C** — fork's GitHub releases URL (`KofTwentyTwo/CommandTabFree`). |
| 10 | **Appcast release-notes link** | `update_appcast.sh:16`; existing items in `appcast.xml` | `https://alt-tab.app/changelog-bare` | **C/R** — fork URL or drop the link. |
| 11 | **License tier cookie** | `src/pro/license/LicenseCookie.swift` | cookie on `alt-tab.app` | **R** — remove with paywall. |
| 12 | **Website dispatch repo + token** | `update_website.sh:5`; `ci_cd.yml:69` | `lwouis/alt-tab-website` + `$WEBSITE_DISPATCH_TOKEN` | **R/C** — fork has no upstream website; remove this CI step or repoint. |
| 13 | **README stats / contributors API** | `update_readme_and_website.sh:10` | `api.github.com/repos/lwouis/alt-tab-macos` | **C/R** — fork slug, or drop the step. |
| 14 | **AppCenter app + secret** | `update_symbols`→`upload_symbols_to_appcenter.sh:4-7`; `ci_cd.yml:7-8`; `Info.plist:73`; `Secrets.swift:6` | `apps/alt-tab-macos/alt-tab-macos`, `$APPCENTER_SECRET`, `$APPCENTER_TOKEN` | **R** — AppCenter is EoL; remove crash-reporting + the upload step (or repoint to a fork-owned analytics-free build). |
| 15 | **`App.repository`** | `src/App.swift:16` | `https://github.com/lwouis/alt-tab-macos` | **C** — fork repo URL (used in About/links). |
| 16 | **GitHub Release target** | implicit via `GITHUB_TOKEN` repo + appcast URLs | upstream releases | **C** — fork publishes to its own repo; ensure appcast URLs (#9) match. |
| 17 | **FUNDING.yml** | `.github/FUNDING.yml` | upstream Patreon/Ko-fi/PayPal/github sponsor | **C/R** — fork's funding or remove. |
| 18 | **Vendored Developer-ID-signed Sparkle helpers** | `vendor/Sparkle/Helpers/Updater.app`, `Autoupdate` (re-signed by `copy_sparkle_helpers.sh`) | signed with maintainer Developer ID at vendor time | **C** — re-vendor/re-sign with fork's Developer ID, else `--deep --strict` verify may flag mismatched seals once the app id changes. |
### Notes for the removal plan
- Items **8, 11, 14** (license API, license cookie, AppCenter) are *removals* that should fall out
naturally when `src/pro/` and the AppCenter vendor wiring are stripped — they are not just
re-pointing.
- Items **1, 2, 3, 4, 5, 6** are the hard prerequisites to ship a notarized, self-updating fork:
without a new Developer ID + a new Sparkle EdDSA keypair the fork can neither notarize nor sign
its own updates. The `AGENTS.md` Keychain-orphaning concern is **moot** for the free fork because
the license/Keychain code is being removed — there is no stored license to orphan.
- The `appcast.xml` already in the repo contains ~3876 lines of upstream EdDSA-signed enclosures
pointing at upstream releases. A clean fork should **truncate/regenerate** it (old entries are
signed by the upstream private key #6 and reference upstream downloads #9), otherwise existing
AltTab users' Sparkle could see fork updates or vice-versa.
- `DEVELOPMENT_TEAM = "${TEAM_ID}"` (undefined) is harmless today but should be set to the fork's
TeamID (or left empty with explicit `CODE_SIGN_IDENTITY`) for clarity.
+390
View File
@@ -0,0 +1,390 @@
# 09 — Telemetry / Analytics & Relationship to Upstream
Audit scope: every network/telemetry surface in the app, the fork's divergence from
upstream AltTab (`lwouis/alt-tab-macos`), and every branding/identity string that ties
this binary to the paywalled "AltTab Pro" product. Read-only analysis; no source was
modified. All paths are relative to the repo root unless noted.
---
## 1. Executive summary
- There is **no third-party analytics or product-tracking SDK** in this app. A broad
sweep for Mixpanel / Amplitude / Sentry / Firebase / Crashlytics / Segment / PostHog /
Datadog / Heap / Matomo / Plausible / Google Analytics found **nothing** in shipped
source, `Info.plist`, or xcconfig.
- The only vendored telemetry SDK is **Microsoft AppCenter**, and only its **Crashes**
module is used — there is no `import AppCenterAnalytics` anywhere. Crash reporting is
**opt-in / ask-by-default** and is deliberately wired so AppCenter makes **no network
request at all** unless the user agrees to send a specific crash report.
- The app makes network calls from exactly **four** places, all to first-party
`alt-tab.app` infrastructure or to AppCenter:
1. AppCenter crash uploads (opt-in).
2. The license backend (`alt-tab.app/api/v1/license/*`) — part of the paywall.
3. The feedback form (`alt-tab.app/api/v1/feedback`) — posts to a server that opens a
public GitHub issue.
4. Sparkle auto-update (`alt-tab.app/appcast.xml`), which sends a small system profile
and a per-license-tier cookie.
- **This repo is a near-verbatim copy of upstream `lwouis/alt-tab-macos`, not a
diverged fork.** Every one of the last 40 commits is authored by `lwouis` or
`semantic-release-bot`; there are **no fork-specific commits**. The entire paywall was
introduced **upstream** by lwouis in a single commit, `9147a4a8 "feat: introducing
alt-tab pro!"` (v11.0.0, 2026-04-05). The "alt-tab-free" repo has only re-hosted the
code under `KofTwentyTwo/CommandTabFree` — **no code-level rebrand has happened yet**:
bundle id, app name, domain, GitHub URL, and SUPublicEDKey are all still the upstream
`com.lwouis.alt-tab-macos` / `alt-tab.app` / `lwouis/alt-tab-macos` values.
This has a major strategic implication discussed in §6: because upstream is alive,
GPL-3.0, and is the source of both the features *and* the paywall, the cleanest path may
be to **rebase a free build on a pre-11.0.0 upstream tag** rather than surgically
extracting the paywall from this snapshot.
---
## 2. Telemetry / crash reporting (AppCenter)
### 2.1 What is vendored
- `vendor/AppCenter/` — Microsoft AppCenter SDK, version pinned in
`vendor/AppCenter/UPSTREAM`:
- `VERSION=appcenter-4.3.0 + PLCrashReporter-1.11.1`
- `SOURCE=https://github.com/microsoft/appcenter-sdk-apple.git`
- `DATE=2026-05-12`
- `vendor/AppCenter/Package.swift` declares **only two** products/targets:
`AppCenter` and `AppCenterCrashes` (plus the `PLCrashReporter` binary target). The
**Analytics** module is not vendored at all (`Package.swift:8-9`). So even if someone
wanted product analytics, the SDK pieces are not present.
### 2.2 The wrapper — `src/vendors/AppCenterCrashes.swift`
This is the single integration point. Key behaviors:
- `src/vendors/AppCenterCrashes.swift:6` — `static let secret = Secrets.appCenterSecret`
reads the AppCenter app secret from `Info.plist` (see §5).
- `src/vendors/AppCenterCrashes.swift:14` —
`AppCenter.networkRequestsAllowed = false` is set **before** `AppCenter.start`,
specifically (per the inline comment) so that "appcenter makes network call just from
AppCenter.start; we only want networking when sending reports."
- `src/vendors/AppCenterCrashes.swift:18-20` — wires `Crashes.delegate = self`, a
`userConfirmationHandler`, then `AppCenter.start(withAppSecret:services:[Crashes.self])`.
Only the `Crashes` service is registered.
- `src/vendors/AppCenterCrashes.swift:31-54` — `confirmationHandler` defers a modal
`NSAlert` and only allows the network channel to flush
(`AppCenter.networkRequestsAllowed = shouldSend`,
`Crashes.notify(with: shouldSend ? .send : .dontSend)`) if the user agrees.
- `src/vendors/AppCenterCrashes.swift:56-77` — `checkIfShouldSend()` reads
`Preferences.crashPolicy` (`.ask` shows the dialog; `.always` auto-sends; otherwise
don't send). The user-facing copy is "AltTab crashed last time you used it…"
(`:61-62`) and a "Remember my choice" checkbox.
- `src/vendors/AppCenterCrashes.swift:94-96` — on a crash upload, the SDK attaches a
**debug profile** (`DebugProfile.make()`) as `debug-profile.md`. See §2.4 for what's
in it.
- `src/vendors/AppCenterCrashes.swift:99` & `:103` — after each send succeeds/fails,
`AppCenter.networkRequestsAllowed` is forced back to `false`, so the channel goes
silent again between reports.
### 2.3 Instantiation and plist hooks
- `src/App.swift:4` `import AppCenterCrashes`; `src/App.swift:33`
`private static var appCenterDelegate: AppCenterCrash?`;
`src/App.swift:436` `App.appCenterDelegate = AppCenterCrash()` — created at the very
top of `applicationDidFinishLaunching`.
- `Info.plist:36-37` — `NSPrincipalClass = AppCenterApplication` (the AppCenter
exception-catching `NSApplication` subclass).
- `Info.plist:69-70` — `AppCenterApplicationForwarderEnabled = 0`.
- `Info.plist:73-74` — `AppCenterSecret = $(APPCENTER_SECRET)` (substituted from
xcconfig at build time).
### 2.4 What leaves the device on a crash — `DebugProfile`
`src/secondary-windows/DebugProfile.swift` builds the attachment. Notable fields
(`DebugProfile.swift:15-34`): app name+version, macOS version, **License state label**
(`LicenseManager.shared.state.debugProfileLabel`), OS architecture
(`Sysctl.run("hw.machine")`), **hardware model** (`Sysctl.run("hw.model")`), and
hardware-utilization data. This same profile is also attached to feedback submissions
(§4). It does **not** appear to include the user's name/email or the machine fingerprint,
but it does include the license tier and hardware model — worth a privacy note.
### 2.5 Recommendation for a privacy-respecting free build
Two viable options, in order of how clean they are:
1. **Remove AppCenter entirely.** Delete `vendor/AppCenter/`, `src/vendors/AppCenterCrashes.swift`,
the `App.swift` instantiation (`:4`, `:33`, `:436`), the `Info.plist` keys
(`NSPrincipalClass` -> revert to plain `NSApplication`; drop
`AppCenterApplicationForwarderEnabled`, `AppCenterSecret`), and the
`Secrets.appCenterSecret` accessor. Remove the crash-policy UI/preference if nothing
else uses it. This is the most defensible "free + private" posture and removes a
~Microsoft-hosted network dependency and the `com.lwouis` AppCenter app secret. Note
`DebugProfile.make()` is also used by the feedback path, so keep `DebugProfile.swift`
if feedback is retained; only the crash-attachment call site goes away.
2. **Keep AppCenter but neuter the default.** The current design is already opt-in
(`networkRequestsAllowed=false` until consent), so a minimal change is to ship with
`crashPolicy` defaulting to ask/never and point the secret at a self-owned AppCenter
app. This keeps crash diagnostics but still ships a Microsoft SDK; less aligned with a
"fully free, no strings" rebrand.
The grafted **upsell** uses of usage data (see §3) are independent of AppCenter and must
be removed regardless.
---
## 3. `UsageStats` — local-only behavioral counters (NOT telemetry, but paywall fuel)
`src/util/UsageStats.swift` records how often the switcher is triggered and which
"pro" features were used. **This is local-only**: it writes to a private `UserDefaults`
suite `"\(App.bundleIdentifier).usage"` (`UsageStats.swift:2`) and **is never sent over
the network** (no URLSession reference anywhere in the file; data is pruned after 365
days at `:59-69`). So it is not a telemetry concern per se.
However, it exists **to drive the paywall**: the recorded counts feed the Day1->Day35
trial-nag prompts and the upgrade UI:
- `src/pro/ProConversionCopy.swift:12,27,28` — reads `usedProFeatureNames()`,
`triggerCount`, `usedProFeaturesSessionCount` to compose upsell copy.
- `src/pro/ui/UsageStatHeroView.swift:64-86` — renders trigger/pro-use counts in the
upgrade hero.
- `src/pro/scheduling/Day15FullUpgradeWindow.swift:22`,
`Day15ProactiveWindow.swift:21` — branch on `usedProFeaturesSessionCount`.
- `src/App.swift:315` `UsageStats.recordTrigger`, `:427` `UsageStats.prune`,
`:67` `resetSession`.
- `src/preferences/settings-window/tabs/AboutTab.swift:148-152` — also shows week/month/
year trigger counts in the About tab (a benign stat display).
Removal note: when the `src/pro/` tree is removed, `UsageStats` callers in `src/pro/*`
disappear. The neutral callers (`App.swift` recording, `AboutTab` display) can stay or be
removed; nothing about `UsageStats` requires the paywall. It does **not** make network
calls, so it is not a privacy blocker on its own.
---
## 4. Other network surfaces (outside AppCenter)
### 4.1 License backend — `src/pro/license/RemoteLicenseClient.swift` (PAYWALL)
- POSTs to `Endpoints.licenseApiBaseUrl` = `https://alt-tab.app/api/v1/license`
(`src/api/Endpoints.swift:11`), endpoints `activate` / `validate` / `deactivate`
(`RemoteLicenseClient.swift:104`, network at `:109` `URLSession.shared.dataTask`,
`:127` `.resume()`).
- The activation body sends a **machine fingerprint** and the local trial-start timestamp
(`RemoteLicenseClient.swift:16-25`). The fingerprint is the IOKit
`IOPlatformUUID` with a keychain fallback (`src/pro/license/MachineFingerprint.swift:9-20`).
This is a stable per-machine identifier transmitted to the backend — a privacy-relevant
data flow that exists **only** to support the paywall.
- Removal note: this entire client and all of `src/pro/license/` goes away in a free
build. It is the most clearly paywall-coupled network call.
### 4.2 License-tier cookie for Sparkle — `src/pro/license/LicenseCookie.swift` (PAYWALL)
- `syncLicenseCookie(state:)` writes a `license` cookie (value `pro` / `proExpired` /
empty) on the `alt-tab.app` domain so "Sparkle's appcast request can be tailored per
tier" (`LicenseCookie.swift:3-21`). Called from `src/App.swift:451` on every license
state change.
- This means the **auto-update check itself transmits the user's license tier** to the
server via cookie. In a free build with no tiers, this should be deleted; the appcast
becomes a single feed for everyone.
### 4.3 Feedback form — `src/secondary-windows/FeedbackWindow.swift`
- POSTs to `Endpoints.feedbackUrl` = `https://alt-tab.app/api/v1/feedback`
(`Endpoints.swift:12`; request built `FeedbackWindow.swift:444-456`, sent `:390`/`:412`).
- Body includes the user's title/body, a `kind`, and **the `DebugProfile`**
(`FeedbackWindow.swift:449-454`). The UI explicitly warns "Your feedback will be
submitted as a public GitHub issue" with "A debug profile (versions, settings,
hardware) is attached" (`:380-381`).
- This is **first-party and consent-gated**, not analytics. It is not paywall code, but
it is tied to the `alt-tab.app` backend and the upstream GitHub repo. A free rebrand
must repoint or remove this (the backend that turns the POST into a GitHub issue is not
in this repo and presumably belongs to lwouis). Note: a prior upstream commit
(`da9a46bf "feat: remove the need to add email in feedback form"`) already minimized PII
here.
### 4.4 Sparkle auto-update — `src/vendors/SparkleDelegate.swift`
- Feed URL = `Endpoints.appcastUrl` = `https://alt-tab.app/appcast.xml`
(`SparkleDelegate.swift:26-28`, `Endpoints.swift:7`).
- `feedParameters` sends a small system profile on each check: app version, macOS
version, CPU arch (`Sysctl.run("hw.machine")`), and preferred language
(`SparkleDelegate.swift:30-38`). Combined with the license cookie (§4.2), update checks
currently carry version + OS + arch + lang + license tier.
- `Info.plist:61-66` — `SUPublicEDKey` (the upstream lwouis signing key),
`SUEnableAutomaticChecks=true`, weekly interval (604800s).
- Removal note: a fork **cannot** ship updates against `SUPublicEDKey` /
`alt-tab.app/appcast.xml` unless it controls that domain and private signing key. A free
republish must either point the appcast at its own host with its own EdDSA key, or strip
auto-update. The license-tier cookie should be removed regardless.
---
## 5. Build-time identity/secrets wiring
- `src/api/Secrets.swift:6` — `appCenterSecret` from `Info.plist` key `AppCenterSecret`.
- `src/api/Endpoints.swift` — all URLs derive from `Domain` (`alt-tab.app`) and
`ApiDomain` (`alt-tab.app/api`) plist keys (`Endpoints.swift:4-5`), themselves from
`config/base.xcconfig:20-21` (`DOMAIN`, `API_DOMAIN`).
- `config/base.xcconfig:3-4` — `PRODUCT_NAME = AltTab`,
`PRODUCT_BUNDLE_IDENTIFIER = com.lwouis.alt-tab-macos`.
- `Info.plist:73-78` — `AppCenterSecret`, `Domain`, `ApiDomain` substituted from xcconfig.
- `alt_tab_macos.entitlements` — app-sandbox **off**, library validation disabled. No
app-group / keychain-access-group is declared here (per AGENTS.md the keychain items are
tied to the code signature / bundle id, so the bundle id is load-bearing for stored
license keys — relevant only if you keep licensing, which a free build would not).
---
## 6. Fork vs upstream — git characterization
### 6.1 Commands run and what they showed
```
git log --oneline -40 # last 40 commits: ALL authored by lwouis / semantic-release-bot
git log --oneline -- src/pro # only 3 commits ever touch src/pro
git log --oneline --diff-filter=A -- src/pro | tail -5 # src/pro first appears in 9147a4a8
git log -40 --format='%an' | sort | uniq -c # 34 lwouis, 6 semantic-release-bot
git rev-list --count HEAD # 1850 commits total
git remote -v # origin = github.com:KofTwentyTwo/CommandTabFree.git
```
Findings:
- **The paywall was born in one commit, upstream.** `src/pro/` has only ever been touched
by three commits, and it was **added** in `9147a4a8 "feat: introducing alt-tab pro!"`,
authored by `lwouis <lwouis@gmail.com>` on **2026-04-05**, shipped as **v11.0.0**
(`1f2b5a51 "chore(release): 11.0.0 [skip ci]"`). The commit immediately before the pro
era (`317a485b`) is v10.12.0. Confirmed `src/pro/` did not exist before 9147a4a8
(`git log 9147a4a8~1 -- src/pro` is empty).
- **This is not a diverged fork.** The author of every recent commit — including bug
fixes after the pro launch (`f3fe535a`, `cddc89dd`, `e0b1778d`, etc.) — is `lwouis`.
There are **zero commits by KofTwentyTwo / the current owner**. The "alt-tab-free" repo
is a mirror of upstream `lwouis/alt-tab-macos` re-hosted under a new origin
(`git@github.com:KofTwentyTwo/CommandTabFree.git`), with the codebase otherwise unchanged.
The README still markets it as "AltTab Pro" and links `https://alt-tab.app/`
(`README.md:1`).
### 6.2 What `9147a4a8` actually changed
It was a **1,869-file** commit — far more than just adding `src/pro/`. It simultaneously
introduced the paywall *and* performed a large repo-wide reorganization (many files were
moved into new folder structures: `macos/api-wrappers/`, `switcher/main-window/`,
`switcher/state/`, `kit/`, `preferences/settings-window/tabs/...`, etc.). So the v11.0.0
boundary is both "Pro launches" and "big refactor," which makes a literal
`git revert 9147a4a8` impractical.
**Files added under `src/pro/` in that commit (the paywall proper):**
- `src/pro/license/` — `Clock.swift`, `Keychain.swift`, `LicenseAPI.swift`,
`LicenseCookie.swift`, `LicenseManager.swift`, `LicenseState.swift`,
`MachineFingerprint.swift`, `RemoteLicenseClient.swift`.
- `src/pro/scheduling/` — `ProTransitionManager.swift`, `ProTransitionScheduler.swift`,
`ProTransitionState.swift`, and the trial-nag windows/popovers
`Day1WelcomeLetterWindow`, `Day4TourPopover`, `Day12HeadsUpPopover`,
`Day15FullUpgradeWindow`, `Day15HardGatePopover`, `Day15ProactiveWindow`,
`Day21ReminderPopover`, `Day35FinalWindow`.
- `src/pro/ui/` — `ProBadgeView`, `ProGradientButton`, `ProPromptHeader`,
`ProPromptHost`, `ProPromptPopover`, `ProPromptWindow`, `UsageStatHeroView`.
- `src/pro/` root — `ProConversionCopy.swift`, `ProFeature.swift`, `ProFeatureCopy.swift`.
(Subsequent commit `60cca89b` added co-located `*Specs.md` / `*Tests.swift` under
`src/pro`, the only other src/pro churn.)
### 6.3 Upstream vs fork-added top-level areas
Because this repo *is* upstream-as-of-v11.x, the right framing is **upstream AltTab core
vs the v11.0.0 paywall graft**, not "fork-added" (there is no fork-added code):
- **Upstream AltTab core (keep):** `src/switcher/`, `src/events/`, `src/macos/`,
`src/preferences/` (minus pro-gating hooks), `src/kit/`, `src/util/`,
`src/experimentations/`, `src/secondary-windows/` (feedback/debug), `App.swift`,
`main.swift`, `MainMenu.swift`, `Menubar.swift`, and the `vendor/Sparkle` +
`vendor/ShortcutRecorder` deps. These predate and are independent of the paywall.
- **Paywall graft (remove):** the entire `src/pro/` tree, plus the call sites that hook it
into the core — e.g. `App.swift:428-429` (`ProTransitionManager` wiring), `:448-459`
(`LicenseManager` callbacks, `syncLicenseCookie`), `Menubar.swift:46/48/49` ("Get Pro",
"My Account", "Support this project"), `App.swift:111-120`
(`supportProject`/`upgradeToPro`/`openAccount` selectors), `UpgradeTab`, and the
`src/pro/license/` network/keychain/fingerprint machinery (`src/api/Endpoints.swift`
license/account/checkout URLs, `LicenseCookie`). These are detailed in the
paywall-specific audit sections; this section flags them only as the fork/upstream
boundary.
- **Telemetry/diagnostics (decide):** `vendor/AppCenter` + `src/vendors/AppCenterCrashes.swift`
(crash reporting), feedback POST, Sparkle appcast — first-party, not paywall, but tied to
`alt-tab.app` and the lwouis signing identity.
---
## 7. Branding / identity strings that tie the binary to the paywalled product
Everything below is still the **upstream lwouis identity** — none of it has been rebranded
for "alt-tab-free" yet. Each is a string a clean free build must change or remove.
| What | Value | Location |
|---|---|---|
| App name | `AltTab` | `config/base.xcconfig:3` (`PRODUCT_NAME`), surfaced via `App.name` `src/App.swift:13` |
| Bundle id | `com.lwouis.alt-tab-macos` | `config/base.xcconfig:4`; also hardcoded in `src/_test-support/Mocks.swift:133`; consumed by `UsageStats.swift:2` and the URL scheme `Info.plist:46-58` |
| Source-code / repo URL | `https://github.com/lwouis/alt-tab-macos` | `src/App.swift:16` (`App.repository`); shown as "Source code" link in `AboutTab.swift:19` |
| Website domain | `alt-tab.app` | `config/base.xcconfig:20` (`DOMAIN`), `Info.plist:75-76` |
| API domain | `alt-tab.app/api` | `config/base.xcconfig:21` (`API_DOMAIN`), `Info.plist:77-78` |
| Website link | `https://alt-tab.app` | `Endpoints.website` `src/api/Endpoints.swift:6`; "Website" link `AboutTab.swift:18` |
| Support/donate URL | `alt-tab.app/support` | `Endpoints.supportUrl` `Endpoints.swift:8`; opened by `App.supportProject()` `App.swift:111-112`; menubar "Support this project" `Menubar.swift:49` |
| Checkout/pricing URL | `alt-tab.app/pricing` | `Endpoints.checkoutUrl` `Endpoints.swift:9` (paywall) |
| Account URL | `alt-tab.app/my-account` | `Endpoints.accountUrl` `Endpoints.swift:10`; opened by `App.openAccount()`/`UpgradeTab.swift:273`; menubar "My Account" `Menubar.swift:48` |
| License API base | `https://alt-tab.app/api/v1/license` | `Endpoints.licenseApiBaseUrl` `Endpoints.swift:11` (paywall) |
| Feedback URL | `https://alt-tab.app/api/v1/feedback` | `Endpoints.feedbackUrl` `Endpoints.swift:12` |
| Appcast URL | `https://alt-tab.app/appcast.xml` | `Endpoints.appcastUrl` `Endpoints.swift:7`; `SparkleDelegate.swift:27` |
| Sparkle signing key | `SUPublicEDKey = 2e9SQOBoaKElchSa/4QDli/nvYkyuDNfynfzBF6vJK4=` | `Info.plist:62` (the upstream EdDSA key; cannot sign updates without lwouis's private key) |
| AppCenter app secret | `$(APPCENTER_SECRET)` -> lwouis's AppCenter app | `Info.plist:73-74`, `config/*.xcconfig`, `Secrets.swift:6` |
| Menubar upsell text | "Get Pro" | `Menubar.swift:46`, `:380` |
| Crash dialog copy | "AltTab crashed last time you used it…" | `AppCenterCrashes.swift:61-62` |
| Copyright | "GPL-3.0 licence" | `Info.plist:20-21` (license — keep, it's correct) |
| README marketing | "AltTab Pro — … — Get AltTab", links `https://alt-tab.app/` | `README.md:1` |
Code identifiers named `AltTab*` (e.g. `AltTabKey`, image asset names) and references to
`lwouis/alt-tab-macos` GitHub **issue numbers** inside code comments
(`src/macos/api-wrappers/MissionControl.swift:32`, `src/switcher/state/Applications.swift:109-110`,
`src/switcher/state/WindowThumbnails.swift:35`, etc.) are benign provenance/attribution and
can stay; they don't gate behavior. The `changelog.md` is entirely upstream-linked but is a
doc artifact, not shipped behavior.
**Keychain/identity caveat (from AGENTS.md):** the bundle id `com.lwouis.alt-tab-macos`
is coupled to Developer ID / TeamID and to keychain items used by the license code.
For a free build that *removes* licensing, the keychain coupling stops mattering (no
stored license keys to orphan), so rebranding the bundle id to a KofTwentyTwo identifier
is safe and recommended. If any licensing were retained, a keychain migration would be
required first.
---
## 8. Rebase-on-upstream vs clean-this-fork
Because the audit shows this repo is **upstream code re-hosted, with the paywall authored
upstream**, the owner has a real choice:
**Option A — Rebase the free build on a pre-Pro upstream tag.**
Upstream `lwouis/alt-tab-macos` is alive and GPL-3.0. v10.12.0 (`317a485b`) is the last
release **before** the Pro paywall (`9147a4a8` / v11.0.0). A free build could branch from
the pre-11.0.0 state and then cherry-pick only the *non-paywall* bug fixes that landed in
the 11.x line. Pros: no paywall code to extract, no `src/pro/` entanglement, no license
cookie/fingerprint surfaces, no need to reverse the 1,869-file Pro reorg. Cons: loses any
genuinely useful non-paywall improvements made *after* v11.0.0 unless individually
cherry-picked; the v11 refactor is intermixed with the paywall, so picking later fixes
that depend on the new folder layout is harder.
**Option B — Clean this snapshot (remove `src/pro/` + hooks in place).**
Keep the current v11.x codebase (with its newer fixes/refactor) and surgically remove the
paywall: delete `src/pro/`, the App.swift/Menubar/UpgradeTab hooks, the license/account/
checkout endpoints, the license cookie, and decide on AppCenter. Pros: keeps the latest
window-switching improvements. Cons: more invasive, must verify the build still links and
that nothing in the core silently depends on `LicenseManager`/`ProTransitionManager`
(the App.swift wiring at `:428-459` is the main coupling to untangle).
GPL-3.0 permits either path (the fork must stay GPL-3.0 and preserve `LICENCE.md` and the
`NSHumanReadableCopyright` notice). Given that the goal is "all features unlocked," and the
paywall gates **existing** AltTab features rather than adding new ones, **both options yield
the same feature set**; the decision is really "do we want the post-v11 fixes badly enough
to do the harder in-place removal (B), or do we prefer the clean slate of pre-paywall
upstream (A)?" A pragmatic hybrid is to start from this snapshot (B) for the newer fixes
but use upstream's v10.12.0 as a reference for what the core looked like before the graft.
Either way, the telemetry/branding cleanup in §2, §4, §5, and §7 is identical and must be
done on top of whichever base is chosen — most importantly: drop the license-tier cookie,
repoint or remove the appcast + Sparkle signing key, decide AppCenter's fate, and rebrand
the bundle id / name / URLs off the `lwouis` / `alt-tab.app` identity.
+151
View File
@@ -0,0 +1,151 @@
You can [suggest an enhancement or discuss an issue on github](https://github.com/lwouis/alt-tab-macos/issues), or use the feedback form in the app.
## Technical overview
This document gives a technical overview of the project, for newcomers who want to contribute.
## Building the project
This project has minimal dependency on Xcode-only features (e.g. InterfaceBuilder, Playgrounds). You can build it by doing:
* `scripts/codesign/setup_local.sh` to generate a local self-signed certificate, to avoid having to re-check the `System Preferences > Security & Privacy` permissions on every build
* Either open `alt-tab-macos.xcodeproj` with Xcode, or use the CLI: `xcodebuild -project alt-tab-macos.xcodeproj -scheme Debug` to build the .app with the `Debug` build configuration
## Mac development
Mac development ecosystem is pretty terrible in general. They keep piling on the tech stacks on top of each other, so you have C APIs, ObjC APIs, Swift APIs, Interface builder, Playgrounds, Swift UI, Mac Catalyst. All these are bridging with each other with a bunch of macros, SDKs glue, compiler flags, compatibility mode, XCode legacy build system, etc. For alt-tab, we are on Swift 5.0. Note that swift just recently started being stable, but overall any change of version breaks a lot of stuff. Swift itself is the mainstream language with the worst governance I’ve seen in modern times.
Regarding SDKs, it’s very different from other (better) ecosystems like Java. Here the SDK is bundled with XCode, and XCode is bundled with the OS. This means that from a machine running let’s say macOS 10.10, you have access to only a specific range of XCode versions (you can’t run the latest for instance), and these give you access to a specific range of SDKs (i.e. Swift + objc + c + bridges + compiler + toolchain + etc)
Documentation is abysmal. Very simple things are not documented at all, and good information is hard to find. Compared to other ecosystem I’ve worked on in the past like Android, nodejs, Java, rust, this is really a bad spot. You can truly tell Apple doesn’t care about supporting third-parties. They are in such a good position that people will struggle and just push through to deliver on their ecosystem because it is so valuable, and because they don’t have to care, they don’t. They could pay an intern to update the docs over the summer for instance, just to give you context of the lack of care we are talking about here.
Dependencies in this project are vendored under `vendor/` and consumed as local Swift Package Manager packages. Each dependency has an `update_*.sh` script under `vendor/scripts/` that re-fetches it from upstream, strips unused files, and regenerates its `Package.swift`. There is no remote dependency resolution at build time — `git clone && xcodebuild` is the full bootstrap.
OS APIs are quite limited for the kind of low-level, system-wide app AltTab is. This means often we just don’t have an API to do something. For instance, there is no API to ask the OS “how many Spaces does the user have?” or “Can you focus the window on Space 2?”. There are however, retro-engineered private APIs which you can call. These are not documented at all, not guaranteed to be there in future macOS releases, and prevent us from releasing AltTab on the Mac AppStore. We have tried our best to [document the ones we are using](https://github.com/lwouis/alt-tab-macos/blob/master/src/api-wrappers/private-apis/README.md), as well as [the ones we investigated](https://github.com/lwouis/alt-tab-macos/blob/master/src/experimentations/PrivateApis.swift) in the past.
## Project architecture
To mitigate the issues listed above, we took some measures.
We minimize reliance on XCode, InterfaceBuilder, Playground, and other GUI tools. You can’t cut the dependency completely though as only XCode can build macOS apps. Currently, the project has these files:
* 1 xib (InterfaceBuilder UI file, describing the menubar items like “Edit” or “Format”)
* `alt-tab-macos.xcodeproj` file describing AltTab itself. It contains some settings for the app
* `Alt-tab-macos.entitlements` and Info.plist which are static files describing some app config for XCode
* `vendor/` holds vendored open-source libraries (Sparkle, ShortcutRecorder, AppCenter) as local SPM packages. `vendor/scripts/update_*.sh` refresh them from upstream.
* Some `.xcconfig` files in `config/` which contain XCode settings that people typically change using XCode UI, but that I want to be version controlled
The project directory is organized in the following way:
| Path | Role |
|------|-------|
| `config/` | XCode build settings |
| `docs/` | supporting material to document the project |
| `resources/` | files that are shipped inside the final `.app` (e.g. icons) |
| `scripts/` | bash scripts useful for CI and local workflows |
| `src/` | Swift source code |
| `src/api-wrappers` | Wrapping some unfriendly APIs (usually C-APIs) |
| `src/logic` | Business logic (i.e. "models") |
| `src/ui` | UI code (e.g. sublasses of NSView or NSCollectionView) |
Other folders/files are either tooling or auto-generated (e.g. `DerivedData/` is generated by Xcode builds).
## QA
**alt-tab-macos** is deeply integrated with the OS and other apps. Thus doing end-to-end automated QA would be a nightmare. For the time being QA is done manually.
In an attempt to not have too many regressions, this documents will list OS interactions. This should be useful as some of them are very exotic and not many people know about them.
## List of use-cases
### Which windows to list, and be able to focus
* Minimized windows
* Windows from hidden apps
* Windows of fullscreen apps
* Windows of fullscreen apps with split-screen
* Windows merged into 1 as tabs (e.g. Finder "Merge All Windows", drag-and-drop a window onto an existing window, etc)
* Windows on multiple monitors
* Windows on multiple Spaces
* Should not show: dialogs, pop-overs, context menus (e.g. Outlook meeting reminder, iStats Pro menus)
### App is summoned during an OS animation
* The UI should only appear after the animation completes for:
* Space transition
* an app going fullscreen
* The UI should not show at all (i.e. ignore the shortcut) if Mission Control is open
* The UI should show instantly during:
* Window minimizing/de-minimizing
* Window maximizing (i.e. double-click the titlebar)
* An app is launching/quitting
### Thumbnail layout corner-cases
* Very small windows (i.e. smaller than the thumbnail min size)
* Very wide/tall windows
* Should show the app name for windows without a title
* Long titles should be truncated
* Many windows are opened
* There is no open window
* AltTab should appear on top of all windows, dialogs, pop-overs, the Dock, etc
### OS events to handle while AltTab’s UI is shown
* An app is launching/quitting
* A new window opens
* An existing window is closed
### Drag-and-drop on top of the thumbnails
* Drag-and-dropping a URL onto a window thumbnail should open it with that window’s app
* Drag-and-dropping a file onto a window thumbnail should open it with that window’s app
### System Preferences
* General > Appearance > "Dark": switches to Dark Mode
* General > Accent color > "Graphite": traffic lights on thumbnails should be gray
* Accessibility > Display > Reduce transparency: AltTab background should be a solid color
* General > Show scroll bars > "Always": regenerates all scrollbars
* Display > Resolution > Scaled: changes DPI and rescale AltTab
* Mission Control > "Displays have separate Spaces": changes Spaces behavior on multi-displays setups
### Spaces
* Spaces get created/destroyed
* A window is moved to another space by drag-and-dropping on the Spaces thumbnails at the top of the Mission Control UI
* A window is moved to another space by dragging it on the side of the current Space, and waiting for a Space transition, then dropping it
* A window is moved to another space by destroying the Space it is in
* An app is assigned to a specific space or all spaces by clicking its Dock icon > Options > Assign to
### Shortcuts
* The hold "key" can be multiple modifiers (e.g. `⌥⇧`)
* Shortcuts should have priority over system shortcuts such as `cmd+tab`, so the user can replace these
* The "select next window" shortcut can be modifiers, modifiers+key, or just key; it can also contain the same modifiers as the hold "key"
* All shortcuts, except the hold key, can be disabled by the user
* Shortcuts can include the `escape` and `delete` key; these should not stop recording shortcuts
* [Secure Input](https://github.com/lwouis/alt-tab-macos/issues/157#issuecomment-659170293) can prevent AltTab from listening to the keyboard
* Some shortcuts should only work when AltTab is open
* These shortcuts should active whether the hold shortcut is held or not
* Shortcuts should work with capslock active or inactive
* Shortcuts should repeat if kept pressed
* Repeat rate and initial delay should match the values set in `System Preference` > `Keyboard`
* when navigating left/right/up/down, the repeating behavior should stop when hitting the last window in the list. The user can then manually do the shortcut once more to cycle to the other side; it then repeats again
* The shortcut sets 1 and 2 should not interact with each other (e.g. opening AltTab with one, then using the other to navigate)
* Shortcuts can focus the window on release, or be pressing a key or using the mouse
* Keyboards from other countries have different layout which impact shortcuts
* e.g. the default ``` ⌥` ``` shortcut should become `⌥<` on a Spanish ISO keyboard
### Localization
* Right-to-left languages (e.g. arabic) have the whole layout reversed
* For the main window, even navigation is reversed
* For preferences and feedback windows, all layout is reversed
* Text length can vary per languages which can create layout issues
### Misc
* AltTab is launched after some apps/windows are already opened
* Displays/mouses/trackpads/keyboards get connected/disconnected while AltTab is used
* Sudden Termination
+7
View File
@@ -0,0 +1,7 @@
## [Developed the app](https://github.com/lwouis/alt-tab-macos/graphs/contributors)
[adamnemecek](https://github.com/adamnemecek), [AfzalivE](https://github.com/AfzalivE), [akx](https://github.com/akx), [Allsochen](https://github.com/Allsochen), [ayroblu](https://github.com/ayroblu), [britalmeida](https://github.com/britalmeida), [Calinou](https://github.com/Calinou), [damonpam](https://github.com/damonpam), [decodism](https://github.com/decodism), [delaneyb](https://github.com/delaneyb), [gingerr](https://github.com/gingerr), [GrzegorzKazana](https://github.com/GrzegorzKazana), [hughlilly](https://github.com/hughlilly), [karbassi](https://github.com/karbassi), [L1cardo](https://github.com/L1cardo), [lwouis](https://github.com/lwouis), [metacodes](https://github.com/metacodes), [mnin](https://github.com/mnin), [MrPaschenko](https://github.com/MrPaschenko), [nella17](https://github.com/nella17), [notlmn](https://github.com/notlmn), [phungtuanhoang1996](https://github.com/phungtuanhoang1996), [rbnis](https://github.com/rbnis), [Rjevski](https://github.com/Rjevski), [ShlomoCode](https://github.com/ShlomoCode), [skolj](https://github.com/skolj), [stopdesign](https://github.com/stopdesign), [xanathar](https://github.com/xanathar), [zacharee](https://github.com/zacharee)
## Localized the app
73, A, a774 nn, Aamirsuleman, Aarni Koskela, Abdulelah, Abdur-Rahman Bilal, Aden Aziz, Admin, Aindriú Mac Giolla Eoin, Ajaykumarmkaju, Aku, Albert Abdilim, Aleksander Bang-Larsen, Alex, Alexander Kilian, Alexey Eremeev, Ali, Ali Gokmen, Ali. tas103, Allen Guan, Alonso Chen, Ameng, Anders, Andreas Wagner, Andrej Koman, Andrew Vader, antoon334, Anurag Roy, anushree b, Arman, Artem Stankov, Arthur, Ash, blanorama, bluefirex, BO the Man, bovirus, Bufo, BV Joshi, caduellery, Caner İlhan, catcore, changanmoon, Christian Keilmann, Chun Fei Lung, codecantata, codingalone, Cong Tri, Dan, Dan84, Darius Rosendahl, Darko, David R, Denis, Dékány Martin, dibas-np, Didier Deschrijver, Dzhuneyt, edu_sombra, EDUARDO, Eimantas, Eliezer Shpigelman, Emir H. KAYNAK, EP45, Eric WANTZ, Ersagun Kuruca, EUKA, Eukarya, Eyelly wu, fil, Filipe, Frangarciasalomon, Frank, Friendship1, Fukuda, Ganesh Sawant, Gezimos, Giacomo Volpi, Giang, Github, Gkostov, Grzegorz Kazana, Guillaume, Gumpanath Puttarassu, hann-solo, Haoshuai Xu, Hao豪, Heramb Lonkar, Hjörtur Hjartarson, Hokuto Kato, Huandngoc, Huynh Sang, Ialiendeg, Ida Bomholt Dyrholm Jacobsen, Igor Aradski, igorpocta, Indexerrowaty, Inês Almeida, isametry, Ismatulla, Isthereanybody, Jaeyong Sung, Jakob, Jakob Licina, Jakub Bartušek, Jesus Angel Villafuerte, jiho4, Jisan, Joao Vitor Casarin, Jord Nijhuis, Jui Yuan Liu, Jules Beckers, Julian Nowaczyk, Julio, justcontributor, Kagurazaka Tsuki, kal, kant, Kawarimidoll+git, kazuki sakamoto, Kevinsevinche, KillianG, Kinyagulovrr, Klara, Kostiantyn Ko, Kristófer Fannar Björnsson, Kushnee5, Kuuchi, Lakshman Kolappan, Lars, Lasse Mattila, Lcwhhh, Leo, Lester, Logan Boissy, Loic. peron, Loïc, LostInCompilation, Lumaxis, lwouis, M, Malo, Maplevantablack, Marc Pla, Marcus Billman, Marekscholle, Marko McLion, Martin Mitka, Martin. mitka, Masayoshi Motojima, Masih, Matheus, Max, Maximilian Falk, MaximilianFreitag, Mehmet Ali Ertorer, Meriç Bağlayan, Michael, Milos M, Mohammad Al Zouabi, mohma, Mohsin Rahman, Mr. axel. bock, mrtbts, MuDraconis, Muzhenstudent, Mwolfinspace, Nathancodes, NIKHIL S, Nikola Rajić, Nils Fahldieck, Nilton Souza, Nmolham, Nuriddin Islamov, Ori, Paul Pichaureau, Paul Przybyszewski, Paul. pichaureau, Pehovorka, Pendolino, Petar Shomov, Peterkim0620, Petr Kolář, Petter Johan Olsen, Piotr Budny, Quentin. douarre, Rajesh Kaswala, rajuneon, Rami Elsawy, Raphaël, Rasmus, Raymonf, raz, Razvan, rbnis, rei fujise, Roccobot, Roccobot, Rodrigo Schneider, Ron Nuss, rPaasch, Ryan Nardi, sa-ha, Sai Khant Zay Lynn Yaung, Sami Suleiman, Samimkel00, Saransh, sawtooth, Sebastian, Selcuk Dursun, Sergey, Serhii Alekseev, Seyedparsa Mirtaheri, Shameem Reza, SheNeVmerla, Shivam Bansal, shlomo, Sippawit Thammawiset, Sjur Moshagen, Sjur.n. moshagen, Stan Smits, star-affinity, Stefan, Stefan Lange, Svetoslav Stefanov, Tamilselvan0x0, Thebennue, Thomas Wölk, Thorsten, Thorsten, Tomoa Nozawa, Trevor, Tsilimpotis Dimitrios, Umutakkaya1996, Vadym, Vijayant Saini, Vincent Orback, Vlad, Webmaster, Wesley Matos, Whatsmine-HaoshuaiXu, White Vogel, Wilhelm Wolfgang Gärtner, Yongsung Yoon, Yorben, Yossi Zahn, ysaito, Yukai, yumechan, Yusuf Caliskan, Zamaialexander, Zuhaib Syed, Τσιλιμπότης Δημ., Андрій Кирбаба, Ивайло, Пустой, 林清, 橙梓
Binary file not shown.

After

Width:  |  Height:  |  Size: 507 KiB

+13
View File
@@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" width="298" height="64" fill="none" viewBox="0 0 298 64">
<defs>
<linearGradient id="a" x1=".850001" x2="62.62" y1="62.72" y2="1.81" gradientUnits="userSpaceOnUse">
<stop stop-color="#FF9419"/>
<stop offset=".43" stop-color="#FF021D"/>
<stop offset=".99" stop-color="#E600FF"/>
</linearGradient>
</defs>
<path fill="#000" d="M86.4844 40.5858c0 .8464-.1792 1.5933-.5377 2.2505-.3585.6573-.8564 1.1651-1.5137 1.5236-.6572.3585-1.3941.5378-2.2406.5378H78v6.1044h5.0787c1.912 0 3.6248-.4282 5.1484-1.2846 1.5236-.8564 2.7186-2.0415 3.585-3.5452.8663-1.5037 1.3045-3.1966 1.3045-5.0886V21.0178h-6.6322v19.568Zm17.8556-1.8224h13.891v-5.6065H104.34v-6.3633h15.355v-5.7758H97.8766v29.9743h22.2464v-5.7757H104.34v-6.453Zm17.865-11.8005h8.882v24.0193h6.633V26.9629h8.842v-5.9451h-24.367v5.9551l.01-.01Zm47.022 9.0022c-.517-.2788-1.085-.4879-1.673-.6472.449-.1295.877-.2888 1.275-.488 1.096-.5676 1.962-1.3643 2.579-2.39.618-1.0257.936-2.2007.936-3.5351 0-1.5237-.418-2.8879-1.244-4.0929-.827-1.195-1.992-2.131-3.486-2.8082-1.494-.6672-3.206-1.0058-5.118-1.0058h-13.315v29.9743h13.574c2.011 0 3.804-.3485 5.387-1.0556 1.573-.707 2.798-1.6829 3.675-2.9476.866-1.2547 1.304-2.6887 1.304-4.302 0-1.4837-.338-2.8082-1.026-3.9833-.687-1.175-1.633-2.0812-2.858-2.7285l-.01.0099Zm-13.603-9.9184h5.886c.816 0 1.533.1494 2.161.4382.627.2888 1.115.707 1.464 1.2547.348.5378.527 1.1751.527 1.9021 0 .7269-.179 1.414-.527 1.9817-.349.5676-.837.9958-1.464 1.3045-.628.3087-1.345.4581-2.161.4581h-5.886v-7.3492.0099Zm10.138 18.134c-.378.5676-.916 1.0058-1.603 1.3145-.697.3087-1.484.4581-2.39.4581h-6.145v-7.6878h6.145c.886 0 1.673.1693 2.37.4979.687.3286 1.235.7867 1.613 1.3842.378.5975.578 1.2747.578 2.0414 0 .7668-.19 1.4241-.568 1.9917Zm29.596-5.3077c1.663-.7967 2.947-1.922 3.864-3.3659.916-1.444 1.374-3.117 1.374-5.0289 0-1.912-.448-3.5253-1.344-4.9592-.897-1.434-2.171-2.5394-3.814-3.3261-1.644-.7867-3.546-1.1751-5.717-1.1751h-13.124v29.9743h6.642V40.0779h4.322l6.084 10.9142h7.578l-6.851-11.7208c.339-.1195.677-.249.996-.3983h-.01Zm-2.151-6.1244c-.369.6274-.896 1.1154-1.583 1.444-.688.3386-1.494.5079-2.42.5079h-5.975v-8.2953h5.975c.926 0 1.732.1693 2.42.4979.687.3287 1.214.8166 1.583 1.434.368.6174.558 1.3544.558 2.1908 0 .8365-.19 1.5734-.558 2.2008v.0199Zm20.594-11.7308-10.706 29.9743h6.742l2.121-6.6122h11.114l2.27 6.6122h6.612L220.99 21.0178h-7.189Zm-.339 18.3431 3.445-10.5756.409-1.922.408 1.922 3.685 10.5756h-7.947Zm20.693 11.6312h6.851V21.0178h-6.851v29.9743Zm31.02-9.6993-12.896-20.275h-6.463v29.9743h6.055V30.7172l12.826 20.2749h6.533V21.0178h-6.055v20.275Zm31.528-3.3559c-.647-1.2448-1.564-2.2904-2.729-3.1369-1.165-.8464-2.509-1.4041-4.023-1.6929l-5.098-1.0456c-.797-.1892-1.434-.5178-1.902-.9958-.469-.478-.708-1.0755-.708-1.7825 0-.6473.17-1.205.518-1.683.339-.478.827-.8464 1.444-1.1153.618-.2689 1.335-.3983 2.151-.3983.817 0 1.554.1394 2.181.4182.627.2788 1.115.6672 1.464 1.1751s.528 1.0755.528 1.7228h6.642c-.04-1.7427-.528-3.2863-1.444-4.6207-.916-1.3443-2.201-2.3899-3.834-3.1468-1.633-.7568-3.505-1.1352-5.597-1.1352-2.091 0-3.943.3884-5.566 1.1751-1.623.7867-2.898 1.8721-3.804 3.2663-.906 1.3941-1.364 2.9775-1.364 4.76 0 1.444.288 2.7485.876 3.9036.587 1.1652 1.414 2.1311 2.479 2.8979 1.076.7668 2.311 1.3045 3.725 1.6033l5.397 1.1153c.886.2091 1.584.5975 2.101 1.1551.518.5577.767 1.2448.767 2.0813 0 .6672-.189 1.2747-.567 1.8025-.379.5277-.907.936-1.584 1.2248-.677.2888-1.474.4282-2.39.4282-.916 0-1.782-.1593-2.529-.478-.747-.3186-1.325-.7767-1.733-1.3742-.418-.5875-.617-1.2747-.617-2.0414h-6.642c.029 1.8721.527 3.5152 1.513 4.9492.976 1.424 2.32 2.5394 4.033 3.336 1.713.7967 3.675 1.195 5.886 1.195 2.21 0 4.202-.4083 5.915-1.2249 1.723-.8165 3.057-1.9418 4.023-3.3758.966-1.434 1.444-3.0572 1.444-4.8696 0-1.4838-.329-2.848-.976-4.1028l.02.01Z"/>
<path fill="url(#a)" d="M20.34 3.66 3.66 20.34C1.32 22.68 0 25.86 0 29.18V59c0 2.76 2.24 5 5 5h29.82c3.32 0 6.49-1.32 8.84-3.66l16.68-16.68c2.34-2.34 3.66-5.52 3.66-8.84V5c0-2.76-2.24-5-5-5H29.18c-3.32 0-6.49 1.32-8.84 3.66Z"/>
<path fill="#000" d="M48 16H8v40h40V16Z"/>
<path fill="#fff" d="M30 47H13v4h17v-4Z"/>
</svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

+178
View File
@@ -0,0 +1,178 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
AUTOGENERATED by scripts/build_readme_svg.py — do not edit by hand.
Stat values are refreshed by scripts/update_readme_and_website.sh.
-->
<svg xmlns="http://www.w3.org/2000/svg" width="900" height="1040" viewBox="0 0 900 1040">
<defs>
<linearGradient id="bg" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stop-color="#13132a"/>
<stop offset="40%" stop-color="#0f0f24"/>
<stop offset="100%" stop-color="#0a0a1a"/>
</linearGradient>
<radialGradient id="glow1" cx="50%" cy="6%" r="40%">
<stop offset="0%" stop-color="#4488ff" stop-opacity="0.10"/>
<stop offset="100%" stop-color="#0a0a1a" stop-opacity="0"/>
</radialGradient>
<radialGradient id="glow2" cx="50%" cy="40%" r="30%">
<stop offset="0%" stop-color="#8F47EB" stop-opacity="0.08"/>
<stop offset="100%" stop-color="#0a0a1a" stop-opacity="0"/>
</radialGradient>
<linearGradient id="proGrad"
x1="0" y1="48.541" x2="35.267" y2="0"
gradientUnits="userSpaceOnUse"
spreadMethod="repeat">
<stop offset="0" stop-color="#FF4488"/>
<stop offset="0.333" stop-color="#4488ff"/>
<stop offset="0.667" stop-color="#66CCFF"/>
<stop offset="1" stop-color="#FF4488"/>
<animateTransform attributeName="gradientTransform" type="translate"
values="0,0; -102.107,0" dur="8s" repeatCount="indefinite"/>
</linearGradient>
<linearGradient id="ctaGrad"
x1="0" y1="121.353" x2="88.167" y2="0"
gradientUnits="userSpaceOnUse"
spreadMethod="repeat">
<stop offset="0" stop-color="#FF4488"/>
<stop offset="0.333" stop-color="#4488ff"/>
<stop offset="0.667" stop-color="#66CCFF"/>
<stop offset="1" stop-color="#FF4488"/>
<animateTransform attributeName="gradientTransform" type="translate"
values="0,0; -255.267,0" dur="14s" repeatCount="indefinite"/>
</linearGradient>
<filter id="ctaShadow" x="-10%" y="-30%" width="120%" height="160%">
<feDropShadow dx="0" dy="1" stdDeviation="1" flood-color="#000000" flood-opacity="0.25"/>
</filter>
<linearGradient id="iconCardA" x1="50%" x2="50%" y1="0%" y2="100%">
<stop stop-color="#d619ac"/>
<stop offset="1" stop-color="#d0224c"/>
</linearGradient>
<linearGradient id="iconCardB" x1="50%" x2="50%" y1="0%" y2="100%">
<stop stop-color="#1ddfdf"/>
<stop offset="1" stop-color="#1d8cdc"/>
</linearGradient>
<linearGradient id="iconCardC" x1="50%" x2="50%" y1="0%" y2="100%">
<stop stop-color="#161386"/>
<stop offset="1" stop-color="#0a093d"/>
</linearGradient>
<clipPath id="screenshotClip">
<rect x="40" y="455" width="820" height="461" rx="14"/>
</clipPath>
</defs>
<rect width="900" height="1040" fill="url(#bg)"/>
<rect width="900" height="1040" fill="url(#glow1)"/>
<rect width="900" height="1040" fill="url(#glow2)"/>
<g fill="#ffffff">
<circle cx="60" cy="40" r="0.9" opacity="0.55"/>
<circle cx="135" cy="80" r="0.6" opacity="0.35"/>
<circle cx="200" cy="30" r="1.1" opacity="0.45"/>
<circle cx="42" cy="160" r="0.5" opacity="0.3"/>
<circle cx="170" cy="180" r="1" opacity="0.5"/>
<circle cx="50" cy="280" r="0.6" opacity="0.4"/>
<circle cx="120" cy="340" r="0.7" opacity="0.45"/>
<circle cx="40" cy="430" r="0.8" opacity="0.4"/>
<circle cx="160" cy="380" r="0.5" opacity="0.3"/>
<circle cx="80" cy="430" r="0.9" opacity="0.5"/>
<circle cx="700" cy="35" r="0.6" opacity="0.4"/>
<circle cx="780" cy="80" r="1" opacity="0.5"/>
<circle cx="840" cy="40" r="0.7" opacity="0.45"/>
<circle cx="860" cy="170" r="0.6" opacity="0.35"/>
<circle cx="730" cy="220" r="0.9" opacity="0.5"/>
<circle cx="820" cy="320" r="0.5" opacity="0.3"/>
<circle cx="870" cy="430" r="0.7" opacity="0.45"/>
<circle cx="730" cy="380" r="0.5" opacity="0.3"/>
<circle cx="820" cy="430" r="0.6" opacity="0.35"/>
<circle cx="450" cy="22" r="0.5" opacity="0.3"/>
<circle cx="60" cy="940" r="0.8" opacity="0.45"/>
<circle cx="120" cy="1000" r="0.5" opacity="0.3"/>
<circle cx="180" cy="980" r="0.7" opacity="0.4"/>
<circle cx="780" cy="930" r="0.6" opacity="0.4"/>
<circle cx="840" cy="1000" r="0.7" opacity="0.45"/>
<circle cx="730" cy="980" r="0.5" opacity="0.3"/>
<circle cx="40" cy="1010" r="0.6" opacity="0.35"/>
<circle cx="860" cy="940" r="0.5" opacity="0.3"/>
</g>
<g transform="translate(166 50)">
<svg width="144" height="144" viewBox="0 0 55 55">
<g><rect width="43.171" height="36.695" x="1.843" y="15.476" fill="url(#iconCardA)" rx="1.125" transform="rotate(-9 1.843 15.476)"/><rect width="43.171" height="36.695" x="5.771" y="9.315" fill="url(#iconCardB)" rx="1.125" transform="rotate(-9 5.771 9.315)"/><path fill="url(#iconCardC)" d="M6.481 13.787 43.49 7.926a1.125 1.125 0 0 1 1.287.935l4.856 30.658-37.009 5.862a1.125 1.125 0 0 1-1.287-.935z"/><path fill="#fff" fill-rule="evenodd" d="m43.728 21.934-9.955 8.01-.639-4.033-6.662 1.055-.714-4.51L32.42 21.4l-.635-4.009z" clip-rule="evenodd"/><path fill="#fff" fill-rule="evenodd" d="m12.892 34.939 11.943 4.542-.639-4.033 6.663-1.055-.714-4.51-6.663 1.055-.635-4.01z" clip-rule="evenodd"/><circle cx="12.121" cy="18.181" r="1.923" fill="#fff" transform="rotate(-9 12.121 18.18)"/><circle cx="17.55" cy="17.322" r="1.923" fill="#fff" transform="rotate(-9 17.55 17.322)"/><circle cx="23.036" cy="16.452" r="1.923" fill="#fff" transform="rotate(-9 23.036 16.452)"/></g>
</svg>
</g>
<text x="330" y="120" font-family="-apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Helvetica Neue', Helvetica, Arial, sans-serif" font-weight="700" font-size="56" fill="#ffffff" letter-spacing="-1.5">AltTab <tspan fill="url(#proGrad)">Pro</tspan></text>
<text x="330" y="158" font-family="-apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Helvetica Neue', Helvetica, Arial, sans-serif" font-weight="400" font-size="22" fill="#8888a8">See every window. Switch in an instant.</text>
<g transform="translate(170 220)">
<g transform="translate(80 0)" opacity="0.85">
<svg width="140" height="140" viewBox="0 0 120 120">
<g fill="none" stroke="#7EB6FF" stroke-linecap="round" stroke-linejoin="round">
<path d="M22 16v10 M18 22l4 4 4-4" stroke-width="2" opacity=".6"/>
<path d="M45 8v8 M42 13l3 3 3-3" stroke-width="1.5" opacity=".35"/>
<path d="M78 10v8 M75 15l3 3 3-3" stroke-width="1.5" opacity=".4"/>
<path d="M100 18v10 M96 24l4 4 4-4" stroke-width="2" opacity=".55"/>
<path d="M12 52v8 M9 57l3 3 3-3" stroke-width="1.5" opacity=".3"/>
<path d="M60 30v14 M54 39l6 5 6-5" stroke-width="2.5" opacity=".7"/>
<path d="M108 50v8 M105 55l3 3 3-3" stroke-width="1.5" opacity=".3"/>
<path d="M30 86v10 M26 92l4 4 4-4" stroke-width="2" opacity=".55"/>
<path d="M58 96v8 M55 101l3 3 3-3" stroke-width="1.5" opacity=".45"/>
<path d="M90 88v10 M86 94l4 4 4-4" stroke-width="2" opacity=".5"/>
</g>
<g fill="#7EB6FF">
<circle cx="38" cy="52" r="1" opacity=".3"/>
<circle cx="82" cy="48" r="1" opacity=".3"/>
<circle cx="50" cy="72" r=".8" opacity=".25"/>
<circle cx="72" cy="78" r=".8" opacity=".25"/>
</g>
</svg>
</g>
<text x="150" y="78" text-anchor="middle" font-family="-apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Helvetica Neue', Helvetica, Arial, sans-serif" font-weight="700" font-size="42" fill="#ffffff" letter-spacing="-0.5"><!--downloads-->7.4M</text>
<text x="150" y="115" text-anchor="middle" font-family="-apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Helvetica Neue', Helvetica, Arial, sans-serif" font-weight="500" font-size="14" fill="#8888a8" letter-spacing="2.4">DOWNLOADS</text>
</g>
<g transform="translate(450 220)">
<g transform="translate(80 0)" opacity="0.85">
<svg width="140" height="140" viewBox="0 0 120 120">
<g fill="#F5D97E">
<path d="m22 28 2-6 2 6 6 2-6 2-2 6-2-6-6-2Z" opacity=".7"/>
<path d="m90 20 1.5-5 1.5 5 5 1.5-5 1.5-1.5 5-1.5-5-5-1.5Z" opacity=".5"/>
<path d="m15 70 1.5-5 1.5 5 5 1.5-5 1.5-1.5 5-1.5-5-5-1.5Z" opacity=".45"/>
<path d="m98 72 2-6 2 6 6 2-6 2-2 6-2-6-6-2Z" opacity=".6"/>
<path d="m50 10 1-3 1 3 3 1-3 1-1 3-1-3-3-1Z" opacity=".35"/>
<path d="m70 8 1-3 1 3 3 1-3 1-1 3-1-3-3-1Zm-40 92 1.5-5 1.5 5 5 1.5-5 1.5-1.5 5-1.5-5-5-1.5Z" opacity=".45"/>
<path d="m85 98 1.5-5 1.5 5 5 1.5-5 1.5-1.5 5-1.5-5-5-1.5Z" opacity=".5"/>
<circle cx="40" cy="18" r="1" opacity=".3"/>
<circle cx="80" cy="15" r=".8" opacity=".25"/>
<circle cx="12" cy="50" r=".8" opacity=".25"/>
<circle cx="108" cy="50" r="1" opacity=".3"/>
<circle cx="60" cy="105" r=".8" opacity=".25"/>
</g>
</svg>
</g>
<text x="150" y="78" text-anchor="middle" font-family="-apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Helvetica Neue', Helvetica, Arial, sans-serif" font-weight="700" font-size="42" fill="#ffffff" letter-spacing="-0.5"><!--stars-->15K</text>
<g transform="translate(150 110)">
<g transform="translate(-79 -7) scale(0.143)" opacity="0.7">
<path fill="#8888a8" fill-rule="evenodd" d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a47 47 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0" clip-rule="evenodd"/>
</g>
<text x="-58" y="5" font-family="-apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Helvetica Neue', Helvetica, Arial, sans-serif" font-weight="500" font-size="14" fill="#8888a8" letter-spacing="2.4">GITHUB STARS</text>
</g>
</g>
<g transform="translate(372 365)">
<rect width="156" height="56" rx="28" fill="url(#ctaGrad)"/>
<text x="78" y="36" text-anchor="middle" font-family="-apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Helvetica Neue', Helvetica, Arial, sans-serif" font-weight="700" font-size="22" fill="#ffffff" filter="url(#ctaShadow)">Get AltTab</text>
</g>
<image href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAQDAwQDAwQEBAQFBQQFBwsHBwYGBw4KCggLEA4RERAOEA8SFBoWEhMYEw8QFh8XGBsbHR0dERYgIh8cIhocHRz/2wBDAQUFBQcGBw0HBw0cEhASHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBz/wAARCAP1BwgDASIAAhEBAxEB/8QAHQAAAQQDAQEAAAAAAAAAAAAAAAIDBAUBBgcICf/EAGkQAAEDAwICBQYGCgoNCQcCBwECAwQABRESIQYxBxNBUWEUIjJxgZEVQlKhsdEIFiMzU2JykpPBFyQ2Q1RzgpSy0hg0RFVWV2N0g6Kz4fAlJjU3RWR1lfEnRoSjtMLTCRnD4kdlhaQo/8QAGwEAAwEBAQEBAAAAAAAAAAAAAAECAwQFBgf/xABEEQACAgEEAAMEBQkGBQQDAQAAAQIRAwQSITETQVEFFCIyFWFxgdEjM3KRoaKxwfA0QlJT0uE1Q1RjwgYkRGIWJfGC/9oADAMBAAIRAxEAPwD2RRRRXzHZ6oVV8NcSWni62quVlmtzbeHnGBIazoWttWlek/GAUCMjY4rxh9l5048c8E9JjFisV4k2q3xYTLqUR9P3dS9eVK1JOR5oAHLY1tP2DnG1y4ni8QxrtxU6+m3IYbh2VSG20MNY3cQkJGBkacJ2GMkbjHU9M44/EbMfG+PbR6+orHjWO/5vXXMbWKzWM15U6NpXDtzjWnibiLjS7wekZ7iJ2FLiR7k48sPeULQIZh6lJ6rqwkE6AQnzsjGz/AHFXFXCDln6qZbZnD944o4giKtfkig+FoXKeSsPa9yVNYxp5Kxud63eFeRn4h6lzRXlbg7pz47vPDVyuL8jh3rZHDyrxGXNkRo7cV/WEpSUIkKX1B1FOp3QoKbwdjtaq6XOLX+Fl+ST467zGviLfKYkxorMtDRj9boZzIMZ53dKshYwgkadQoWml6oPFT4PSVZ5ZrT+i3iz7eeAbJf/ACsTPLWSTITEVFDikqKSQ2pSindPyiDzBIIrb6wkqbRSdCs1jnXPOleSpDPC0OVIVE4euF6Zj3eSl9TGhnq3FNoLiSClK30soO+4Vp+NWmx+LW+G5/ENosQkwHl3GHHaaLyLlG61xLqlNsanEJZcLLIWpLiwhOtCsEqIVUMVq7Dcd1zQDtXn6P0rcV3jhGTdocu0Q3LbabvOeL0UOpkOwpSmUnKXMJQtKCVaVKxnzVdpsr10j8T8PvXC2LlQJksu2gtSWoqWhHRMU6FIKFuhBOWSlClLTu4kEKI85vDIe47dRWqdHHEFx4h4YEq6tsJmtSpEYqZW2oLS26pKVHq1rQlWB5yQo6VAg45VtoOSazap0NciaK0npjKkdGnEC21JS51KEpKpCmEnLqAQXE7oBBwVDcDfsrUo9wncOC0W6G1w3w87fbuYzsuNcnLm2htEdbox1iW8OqLZSEnbAKsk7VcMe5WS5Uzse3fRXk2TxLcWOju5SIc2H8KfA/GMtu9REHrUlm4ox1KislCF6s7E4wjBGkZ9R2hS12uIpctEtamkqU+hISlwkbqABIwfWac8e1ApbifRQk5NaR0mOOWm32riZt9xpvh2c3MlJDhQ2uIctSCsfGCG3FOgd7Y5VnFW6KZu/OiuHMcSS7db08apiJuD13+FrxEZypxfkzUbEZtrnpC2mkKICTutXM80WvpW4igW6Zc76uCu125i33GTIbDGoxny4l7DTT7pS2nCHErUclOpO5STWnhMndZ3SiuXdHfHHEPEt9XZrubezcbXGdfukeOg5SXnEqhBOTkZY1atjlQ2Ixg9QB51Eo7XTHdmaPbRXnGxcVXaNG4o4ZTdnV3Hiy9XJuwvOLHWRtMtxiUEauaWEN9cAexeNgKcIbhN0ejqK832TpJvlo6Ore9Bu0IosPCdsuiIk5suyryt1K8p1agQVBoISUhR6xe420q2y79Jt+sy79DZiMzLjw3HuF0mshggvxkt64TacKJStZWAVAKB8ndwBkY0eB+oRmdkoxXDYPSDxwq03Bt0W6RLQYDjDyVw233kva+tbaZElTerDepsrWnVrI84oJV03gPiBfE3CkG5uSRJdWXGnHREMbK23FIUOrKlYIUkjZRBxkEgis5Q2q7GpWbLRQDzrTulB12Bwk5eGpPk/wABSWLo6vfdhlwKfSccwWetGO8ioXLG5UbjiivPNin3K48QwbTInzltcc3BjiaKorWOoiMuFTjII9BGluGCnPnF9fjiU1xnxKxYr0qxSrJBjWW03C6hnyErS68ibJSkE9YNKCGjqIBJJyCOVavH9ZDmd8rI2zXAOM+MLney4DerZFhQ+K7HARaw3+2XUrfiulZc1ggnrSQkAp0JOc582e90hcWy3I7lruFndl3eddraxbPJipdvVGQ+WXXVasqGphKVpISMvpwRpBWlhbVpgpUdvorjPDPS1ceJ77AYhqhKtd/fbk2l5DepSoLSCJZUc4JDidII5BxPPG/ZQazcHHsceTNFFcpm3Ti1rjDjlqxWq03GIhuKVmfdXIxaUY5JCUpZcBGMHORueXaXCO60Ozq1Fec+HukjiWFbOGYVrUw5EhWWyvOLlLYJliQAFqW66+lYyElKVJSvK851ejUqwcWXqNMg2CHfbZa48+ZxPLclz2Q+rVHuZS2hOpaRsHVEjfZBxjG2i07I3HoKitc4Gv8AI4n4LsN6ktNNv3GE1IWloko1KTklJO5SeYzvgithB51jJU6LCiiikMTRRRQAUUUUAFFFFABRRRQAUUUUAFFFFNIAooooAKKKKYBRRRQAUUUUEt0FFFFBIUUUUDCiiigAooooAKKKKACiiigTYUUUUCCiiigAooopoAooopgFFFFLsTYUUUUCCiiimAUUUUAFFFFABRRRQDYUUUUIQUUUVSAKKKKXQBRRRQAUUUUCboKKKKBBRRRQAUUUUAFFFFAm6CiiigQUUUUDCiiigAooooAKKKKACiiiglsKKKKCRNFFFUURrhcI1rhuy5bnVsNDKlYJ7cAADckkgADck1V/bdbvwV0Hrtcn/wDHWeLtrLq7pcT/AOparR7zxpwpBusu2cLG2Xziq3PMA2sXbqFAqccxhayUladbh0AE7gHspxTYje4vFNulTGIiVSW35BKWhIiPMhxQBUUgrQATgE4znAPcausVyTgXini7iy2cPyuMeGBYJwuxS0kP6/KW/J3sOdWd2/USc8663mlkW10AYoIwKzXBvspuIuMrZ0fyY3DFrli3vNKXd7wy62hUKKD56UalA61DbIBIB23Ioxw3y22I7hFmMTozMmK62/GeQFtvNqCkOJPakjmPGngc1onRHxBJ4n4EtU9zh02CEWUNwYSntavJkpAbURpTpyNwO7B2zgb2ntqWtraGZoorhfTvx/IsD1tsspcWBZZ9wiRpzlyKQ3NhuOhL+gqBQpAQVpcQrCkpPWDYbuEXKVIDs9ru8K9Q/LLfKakxusW1rbVnStCilaFDsUlQIIO4IqbXKlcQ2Ru6xFdH0q03ObKfaTc40F/rxJbDRCC66gqDLgQ2dDrgIX1fVqUNSVJ6ontqpxoDChVTeb7b+H2EO3CSGg4rS2gJUtbhxnCUJBUdhk4G1Wyq510o8PSrjHRdo5Q41BYUh6OSAtSNQVlOdlZICSg41ZTvtgxCNujPLKSg3DsvXePuG2tB+FmVIUNZWlKlJaTkjLhA+5jII87GMHOMVsiQlaErQoKQoZBB2IrzzC4Y4gXItS1W9tpU15fV6nUpVGktpQFsylEkqdw0rz2wQpIWnlgq73Yrf8D2aDbus63yRlDPWadOvSMZxk4rfPhWJ15mWDNknfiRolgDB32rV+MekThXo+ZjO8UX6DaUyyoR0yXMKe04zpSNyBkZPIZGedbZXhP7Ndjhe5cYtLVxg3E4ig29DDtpeivuJKCVqQUOISUpUoKyQrnhJqMGNZJ7ZG57PVxVYkXuPZF3q3Iu8lvrmYSpKQ+42eSkozkj/gVc6a+abXD1s6RelwmV0mQ4V9lvxFRJibU6G3HA0gN6F6tKVDSjTqOCVAA719KUjIqtRi8Kqd2A1NmMW2HIlynUtRo7anXXFnCUJSMkn2VCY4igSLbIuHWOsRIySp5cphbBbSE6iSFgHGnfNR+OHFtcG38ohpmq8he/a6kFQd8xXmkJ3OeWx7a1O8RLhE6HeLk3Rt7y1dvmqV5Q8XFlHVLCCRqUEnQE5SCQDnckmsIq2Bpp+zE6MM5TJvS0H0VptbuFeIrH9mJ0Yfh73/5W5Xz6h63m2m221LdUEBKE81EgAAeNOOhTLzjK0KS60ooWlXNKgcEHxBBHsr2fo/HV8k7j6BJ+zD6MFOJR197Ge34Ldrtlqu8O922JcrdIbkwJrKX2HmzlLjahlKh6xvXyRYX+2Wvyq+nfQUn/ANi3R/8A+CRP9mK49Vpo4opxGnZv+dq1+18Y2K9SocaBcmn35sZcxhCQQVtIWG1q3G2FqAwd857qvztXMuiXh+A1EF6MARbkoFspGsaElKMp0qUrtQD2blRxlRJ4YQUrbGUkj7KXo0jcQLsy7pNLrclURySILnk6XArQfumMadWRq5dvKuyV8nr7apyp95nJjOqiJmylF3HmgB9YJz3ZFfV9pJDLecegnl+SK7dbovddvDW71Jx5FO6fQ1OmxrXAlT5jyWYkVtTrriuSEpBJJ9QBqHH4gt8m0O3UPluAyhbjjr7am+rSjJUVBQBAwM0cShz7Xbr1SUrc8mc0pUVgKVpOASgFQ9aQT3VzhxKWugri5SWVICrfcVFTiCnrSUL88DJGD3pwk9gHKuOMbNKKJX2X/RkhR/bN5Un4q02t3Ch3jIpP9mD0Y/wi9f8AlbteKolo4YejMl7iB9tfVoylS42x0jI9Kpn2ucKsBp1+9yeqUcgLXHSHADhQBLine truncated
<g transform="translate(372 950)">
<rect width="156" height="56" rx="28" fill="url(#ctaGrad)"/>
<text x="78" y="36" text-anchor="middle" font-family="-apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Helvetica Neue', Helvetica, Arial, sans-serif" font-weight="700" font-size="22" fill="#ffffff" filter="url(#ctaShadow)">Get AltTab</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 407 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

+35
View File
@@ -0,0 +1,35 @@
<svg xmlns="http://www.w3.org/2000/svg" width="900" height="160" viewBox="0 0 900 160">
<defs>
<linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#0f0f24"/>
<stop offset="100%" stop-color="#0a0a1a"/>
</linearGradient>
<linearGradient id="jbA" x1=".850001" x2="62.62" y1="62.72" y2="1.81" gradientUnits="userSpaceOnUse">
<stop stop-color="#FF9419"/>
<stop offset=".43" stop-color="#FF021D"/>
<stop offset=".99" stop-color="#E600FF"/>
</linearGradient>
</defs>
<rect width="900" height="160" fill="url(#bg)"/>
<g fill="#ffffff">
<circle cx="80" cy="40" r="0.6" opacity="0.4"/>
<circle cx="160" cy="120" r="0.7" opacity="0.45"/>
<circle cx="50" cy="90" r="0.5" opacity="0.3"/>
<circle cx="820" cy="40" r="0.6" opacity="0.4"/>
<circle cx="750" cy="120" r="0.7" opacity="0.45"/>
<circle cx="860" cy="100" r="0.5" opacity="0.3"/>
</g>
<text x="450" y="48" text-anchor="middle" font-family="-apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Helvetica Neue', Helvetica, Arial, sans-serif" font-weight="500" font-size="13" fill="#8888a8" letter-spacing="2.4">SPONSORED BY</text>
<g transform="translate(351 70)">
<svg width="198" height="42" viewBox="0 0 298 64">
<path fill="#ffffff" d="M86.4844 40.5858c0 .8464-.1792 1.5933-.5377 2.2505-.3585.6573-.8564 1.1651-1.5137 1.5236-.6572.3585-1.3941.5378-2.2406.5378H78v6.1044h5.0787c1.912 0 3.6248-.4282 5.1484-1.2846 1.5236-.8564 2.7186-2.0415 3.585-3.5452.8663-1.5037 1.3045-3.1966 1.3045-5.0886V21.0178h-6.6322v19.568Zm17.8556-1.8224h13.891v-5.6065H104.34v-6.3633h15.355v-5.7758H97.8766v29.9743h22.2464v-5.7757H104.34v-6.453Zm17.865-11.8005h8.882v24.0193h6.633V26.9629h8.842v-5.9451h-24.367v5.9551l.01-.01Zm47.022 9.0022c-.517-.2788-1.085-.4879-1.673-.6472.449-.1295.877-.2888 1.275-.488 1.096-.5676 1.962-1.3643 2.579-2.39.618-1.0257.936-2.2007.936-3.5351 0-1.5237-.418-2.8879-1.244-4.0929-.827-1.195-1.992-2.131-3.486-2.8082-1.494-.6672-3.206-1.0058-5.118-1.0058h-13.315v29.9743h13.574c2.011 0 3.804-.3485 5.387-1.0556 1.573-.707 2.798-1.6829 3.675-2.9476.866-1.2547 1.304-2.6887 1.304-4.302 0-1.4837-.338-2.8082-1.026-3.9833-.687-1.175-1.633-2.0812-2.858-2.7285l-.01.0099Zm-13.603-9.9184h5.886c.816 0 1.533.1494 2.161.4382.627.2888 1.115.707 1.464 1.2547.348.5378.527 1.1751.527 1.9021 0 .7269-.179 1.414-.527 1.9817-.349.5676-.837.9958-1.464 1.3045-.628.3087-1.345.4581-2.161.4581h-5.886v-7.3492.0099Zm10.138 18.134c-.378.5676-.916 1.0058-1.603 1.3145-.697.3087-1.484.4581-2.39.4581h-6.145v-7.6878h6.145c.886 0 1.673.1693 2.37.4979.687.3286 1.235.7867 1.613 1.3842.378.5975.578 1.2747.578 2.0414 0 .7668-.19 1.4241-.568 1.9917Zm29.596-5.3077c1.663-.7967 2.947-1.922 3.864-3.3659.916-1.444 1.374-3.117 1.374-5.0289 0-1.912-.448-3.5253-1.344-4.9592-.897-1.434-2.171-2.5394-3.814-3.3261-1.644-.7867-3.546-1.1751-5.717-1.1751h-13.124v29.9743h6.642V40.0779h4.322l6.084 10.9142h7.578l-6.851-11.7208c.339-.1195.677-.249.996-.3983h-.01Zm-2.151-6.1244c-.369.6274-.896 1.1154-1.583 1.444-.688.3386-1.494.5079-2.42.5079h-5.975v-8.2953h5.975c.926 0 1.732.1693 2.42.4979.687.3287 1.214.8166 1.583 1.434.368.6174.558 1.3544.558 2.1908 0 .8365-.19 1.5734-.558 2.2008v.0199Zm20.594-11.7308-10.706 29.9743h6.742l2.121-6.6122h11.114l2.27 6.6122h6.612L220.99 21.0178h-7.189Zm-.339 18.3431 3.445-10.5756.409-1.922.408 1.922 3.685 10.5756h-7.947Zm20.693 11.6312h6.851V21.0178h-6.851v29.9743Zm31.02-9.6993-12.896-20.275h-6.463v29.9743h6.055V30.7172l12.826 20.2749h6.533V21.0178h-6.055v20.275Zm31.528-3.3559c-.647-1.2448-1.564-2.2904-2.729-3.1369-1.165-.8464-2.509-1.4041-4.023-1.6929l-5.098-1.0456c-.797-.1892-1.434-.5178-1.902-.9958-.469-.478-.708-1.0755-.708-1.7825 0-.6473.17-1.205.518-1.683.339-.478.827-.8464 1.444-1.1153.618-.2689 1.335-.3983 2.151-.3983.817 0 1.554.1394 2.181.4182.627.2788 1.115.6672 1.464 1.1751s.528 1.0755.528 1.7228h6.642c-.04-1.7427-.528-3.2863-1.444-4.6207-.916-1.3443-2.201-2.3899-3.834-3.1468-1.633-.7568-3.505-1.1352-5.597-1.1352-2.091 0-3.943.3884-5.566 1.1751-1.623.7867-2.898 1.8721-3.804 3.2663-.906 1.3941-1.364 2.9775-1.364 4.76 0 1.444.288 2.7485.876 3.9036.587 1.1652 1.414 2.1311 2.479 2.8979 1.076.7668 2.311 1.3045 3.725 1.6033l5.397 1.1153c.886.2091 1.584.5975 2.101 1.1551.518.5577.767 1.2448.767 2.0813 0 .6672-.189 1.2747-.567 1.8025-.379.5277-.907.936-1.584 1.2248-.677.2888-1.474.4282-2.39.4282-.916 0-1.782-.1593-2.529-.478-.747-.3186-1.325-.7767-1.733-1.3742-.418-.5875-.617-1.2747-.617-2.0414h-6.642c.029 1.8721.527 3.5152 1.513 4.9492.976 1.424 2.32 2.5394 4.033 3.336 1.713.7967 3.675 1.195 5.886 1.195 2.21 0 4.202-.4083 5.915-1.2249 1.723-.8165 3.057-1.9418 4.023-3.3758.966-1.434 1.444-3.0572 1.444-4.8696 0-1.4838-.329-2.848-.976-4.1028l.02.01Z"/>
<path fill="url(#jbA)" d="M20.34 3.66 3.66 20.34C1.32 22.68 0 25.86 0 29.18V59c0 2.76 2.24 5 5 5h29.82c3.32 0 6.49-1.32 8.84-3.66l16.68-16.68c2.34-2.34 3.66-5.52 3.66-8.84V5c0-2.76-2.24-5-5-5H29.18c-3.32 0-6.49 1.32-8.84 3.66Z"/>
<path fill="#0a0a1a" d="M48 16H8v40h40V16Z"/>
<path fill="#fff" d="M30 47H13v4h17v-4Z"/>
</svg>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.0 KiB

+11568
View File
File diff suppressed because it is too large. Load diff
+42
View File
@@ -0,0 +1,42 @@
{
"private": true,
"name": "alt-tab-macos",
"version": "1.0.0",
"author": "",
"license": "GPL-3.0",
"husky": {
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.swift": [
"node scripts/swiftformat.js --lint"
]
},
"scripts": {
"format": "node scripts/swiftformat.js",
"format:check": "node scripts/swiftformat.js --lint"
},
"devDependencies": {
"@commitlint/cli": "^8.1.0",
"@commitlint/config-conventional": "^8.1.0",
"@semantic-release/changelog": "^3.0.4",
"@semantic-release/git": "^7.0.16",
"fontkit": "^1.8.0",
"glob": "^10.0.0",
"husky": "^3.0.4",
"lint-staged": "^13.0.0",
"marked": "^0.8.0",
"semantic-release": "^15.13.24"
},
"engines": {
"node": ">=18.0.0"
},
"dependencies": {
"@types/node": "^22.10.2",
"ts-node": "^10.9.2",
"typescript": "^5.7.2"
}
}
+31
View File
@@ -0,0 +1,31 @@
module.exports = {
plugins: [
['@semantic-release/commit-analyzer', {
'preset': 'angular',
// having version increments and builds for these commit types is valuable
'releaseRules': [
{'type': 'perf', 'release': 'patch'},
{'type': 'docs', 'release': 'patch'},
{'type': 'style', 'release': 'patch'},
{'type': 'refactor', 'release': 'patch'},
{'type': 'test', 'release': 'patch'},
{'type': 'chore', 'release': 'patch'},
{'type': 'ci', 'release': 'patch'},
],
}],
'@semantic-release/release-notes-generator',
['@semantic-release/changelog', {
'changelogFile': 'changelog.md',
}],
['@semantic-release/git', {
// alt-tab-free [depaywall]: 'appcast.xml' REMOVED from assets (PLAN §3.3/§4.3). The fork
// publishes the Sparkle feed OUT OF TREE (gh-pages) via scripts/update_appcast.sh, and
// appcast.xml is removed from the tree. If it stayed here, semantic-release would try to
// commit the now-untracked file back every release.
'assets': [
'changelog.md',
'README.md',
],
}],
],
}
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loaded 100 of 1248 files, more files were not shown because too many files have changed in this diff. Show more