Problém, který FocusForge řeší
Vývojáři, designéři a kdokoli, kdo žongluje s několika projekty najednou, se ztrácí
v desítkách otevřených oken a Spaces. macOS Spaces sice umí oddělit virtualní plochy,
ale nezná koncept projektu — neví, že okna VS Code, Figmy, terminálu a
prohlížeče dohromady patří k jednomu klientovi. Při přepnutí mezi projekty si
uživatel musí pamatovat, kde vlastně je, a pravidelně otevírá špatný kontext.
FocusForge tento problém řeší ambientně — bez aktivní interakce
s uživatelem. Sledováním předního okna, jeho pracovního adresáře a nakonfigurovaných
mappings sám rozhodne, na jakém projektu uživatel právě je, a tu informaci diskrétně
zobrazí jako overlay na každém monitoru.
Klíčové funkce
Automatická detekce projektu
FocusForge sleduje aktivní okno přes Accessibility API a získává jeho pracovní
adresář (terminál, IDE, Finder). Adresář pak matchuje proti nakonfigurovaným
projektovým cestám. Uživatel přepne do VS Code v
~/projects/sportsman — overlay se aktualizuje na „Sportsman".
Overlay na každém monitoru
Každý displej dostane vlastní vždy viditelný overlay s názvem projektu, ikonou
a barvou. Při nečinnosti je nenápadný, při najetí myší interaktivní. Lze ho
přetáhnout na libovolnou pozici a plně přizpůsobit (velikost, barva,
průhlednost).
Rychlý přepínač
Klikem na overlay se otevře přepínač projektů (NSPopover) — jedním kliknutím
přepnete kontext nebo přiřadíte aktuální okno k jinému projektu. Klávesnice
navigace (šipky, Enter, Esc) standardní.
Soukromí na prvním místě
FocusForge nedělá žádné síťové požadavky. Žádná analytika, žádná
telemetrie, žádný účet. Pracovní adresáře neopouštějí Mac. Jediná síťová operace
je kontrola updatů přes Sparkle — kterou lze vypnout.
Architektura a technologické rozhodnutí
FocusForge je 100% nativní SwiftUI aplikace s přídavkem AppKit
tam, kde SwiftUI naráží na limity. Klíčové architektonické rozhodnutí:
LSUIElement = true — aplikace neukazuje ikonu v Docku
ani standardní menu bar, žije pouze jako overlay na monitorech. To dramaticky snižuje
distrakci uživatele a posiluje ambient povahu produktu.
Vrstvy
- App layer — entry point, NSApplication delegate, životní cyklus
- Core —
SpaceDetector (CGS private API pro Spaces), WindowListProvider (CGWindowList), WorkingDirectoryDetector (Accessibility API), FocusMonitor (NSWorkspace observer), DisplayManager (NSScreen events), LicenseManager
- Models — Project, Workspace, Display config (Codable, persistovaná do Application Support)
- UI — pět hlavních modulů:
Overlay, Switcher, Settings, MenuBar, Onboarding
- Persistence — JSON soubor v Application Support, atomický zápis, migrace verzí schematu
- Permissions — žádost o Accessibility a Screen Recording permissions s onboardingem
Proč SwiftUI a kde AppKit
SwiftUI dostalo na 95 % UI — Settings okno, Switcher, Onboarding, MenuBar. AppKit
jsme sáhli pro:
- Always-on-top borderless okna — overlay vyžaduje
NSWindow s vlastním level = .floating + 1 a collectionBehavior = [.canJoinAllSpaces, .stationary], což SwiftUI nepokrývá
- Detekce Spaces — CGS private API jsou jen v Objective-C/C, SwiftUI je nedosáhne
- Window list a working directory — Accessibility API je tradiční Cocoa
- Dragging overlay — vlastní mouse tracking přes NSEvent monitor
Hlavní technické výzvy
1. „Vždy nahoře" overlay napříč Spaces
Standardní macOS okno se přepne se Spaces. Overlay potřebuje být všude. Klíč
byla kombinace NSWindow.collectionBehavior = [.canJoinAllSpaces, .stationary,
.ignoresCycle], vyloučení z Mission Control přes
.transient hint a vlastní NSWindow.Level nad statusbar.
2. Detekce pracovního adresáře
Získat aktuální cwd z aktivního okna není jednoduché. Pro Terminal/iTerm2
čteme přes Accessibility hodnotu „working directory" atributu. Pro VS Code
parsujeme název okna (obsahuje cestu k projektu). Pro Xcode sledujeme
recently opened projects přes file system watcher. Heuristiky pro 8 nejčastějších IDE
jsou v WorkingDirectoryDetector.
3. Lokalizace do 20 jazyků
FocusForge je k dispozici v 20 jazycích — angličtina, němčina, francouzština,
španělština, italština, japonština, korejština, čínština (zjednodušená i tradiční),
nizozemština, polština, brazilská portugalština, ruština, švédština, dánština,
norština, ukrajinština, turečtina, slovenština a čeština. Přístup: anglické zdrojové
stringy + .strings soubory pro každý jazyk + automatizovaná validace pokrytí klíčů
v CI před release.
4. Distribuce: web + Mac App Store paralelně
FocusForge distribuujeme dvěma cestami současně. Web verze používá
Developer ID, notarizaci a Sparkle pro auto-update s vlastním
appcast.xml hostovaným na getfocusforge.com. App Store verze
má App Sandbox + omezené entitlements, neobsahuje Sparkle (App Store si update řídí
sám) a má strippnutou bezplatnou verzi licenčního managementu. Codebase je jediná,
varianty řízené přes Build Configurations a feature flags.
Vývojové nástroje
- XcodeGen — projekt generujeme z
project.yml, žádné konflikty v .xcodeproj
- Fastlane — automatizace App Store screenshotů, beta builds, release notes
- Sparkle — auto-update s podpisovaným appcastem
- SwiftLint — linting v pre-commit hook
- Custom CI pro release: build, sign, notarize, upload do GitHub Releases + Sparkle příjem
Co si z projektu odnášíme
FocusForge byl pro nás projektem, kde jsme vyzkoušeli kompletní distribuční
stack pro macOS — od Sandboxu přes notarizaci po Sparkle, paralelně Mac
App Store i přímý prodej. Vyzrál náš pattern pro lokalizaci do mnoha jazyků a
CI pipeline pro nativní macOS aplikace, které dnes používáme i na zakázkové projekty.
Nedoporučujeme nikomu, kdo cílí jen na rychlé MVP — App Store review pro nativní
apps je často 3–10 dní a každý sandbox issue znamená iteraci. Pro produktové aplikace
určené k dlouhodobému provozu je ale tato cesta jediná správná.