Skip to content

Latest commit

 

History

History
126 lines (85 loc) · 6.4 KB

File metadata and controls

126 lines (85 loc) · 6.4 KB

Architecture

Scope

Figma Micro is a native macOS configurator for the Work Louder Figma Creator Micro. It replaces the browser-only VIA workflow for the supported use case without flashing or replacing controller firmware.

The project is a Swift Package executable targeting macOS 14 or newer and uses SwiftUI, Observation, IOKit HID, Carbon, and ServiceManagement.

Runtime structure

SwiftUI views
    │ user selection, drag/drop, Apply
    ▼
AppStore
    ├── local draft assignments + keycap state
    ├── FigmaActivityMonitor
    └── LightingStateMachine
             │
             ▼
ControllerLightingService
             │
             ▼
HIDDeviceService ── Raw HID / VIA ── Creator Micro

Application and views

  • MicroMapApp owns the main AppStore, creates the window and Settings scene, and starts runtime services.
  • ContentView provides the three-column NavigationSplitView, global search, connection badge, and refresh action.
  • SidebarView selects a shortcut category and reports the current firmware layer.
  • ShortcutLibraryView lists assignable Figma actions and supplies drag payloads.
  • ControllerWorkspaceView owns the visual hardware layout, layer selector, draft editing, the perimeter lighting configurator card, and the global Apply action.
  • SettingsView contains launch-at-login, global shortcut, keyboard layout, and night-dimming preferences.

State and orchestration

AppStore is the single UI-facing source of truth. It owns:

  • the decoded action catalog;
  • current category, search query, selected action, selected slot, and selected layer;
  • draft assignments for all four layers;
  • the physical keycap color and printed-glyph representation;
  • the HID connection service and lighting services;
  • persistence and migration of special buttons.

Assigning or dragging an action immediately updates the local draft. It does not write to the controller. applyAllLayersToController() is the only normal path that writes key mappings, and it iterates all four firmware layers.

Data model

Shortcut catalog

Resources/figma-shortcuts.json is decoded into FigmaAction values. Each action declares:

  • a stable ID and title;
  • category and fallback SF Symbol;
  • an optional keyboard chord;
  • assignability: direct, macro, mouse-required, or system-required;
  • an optional explanatory note.

Only direct actions with an encodable chord can be assigned to hardware. FigmaAction.figmaAssetName maps actions with supplied physical artwork to a bundled icon.

Controller mapping

ControllerSlot represents keys, encoder presses, and encoder directions. LayerAssignments stores a dictionary keyed by firmware layer and slot ID.

Special slots are enforced whenever state is restored or applied:

  • key-11 is the global Figma button;
  • key-14 is the firmware layer switch;
  • layers are firmware indexes 0..<4.

QMK encoding

QMKKeycodeEncoder converts supported macOS chords into QMK/VIA keycodes. Printable keys resolve through the selected keyboard layout, except actions marked keyResolution: physical, which always encode the US key position because Figma matches these commands by position rather than by typed character. Multi-key macros remain visible in the catalog but are not written as direct assignments.

Persistence

Draft state is stored in UserDefaults:

Key Contents
figmaMicro.assignments.v1 All layer assignments
figmaMicro.currentLayer.v1 Selected firmware layer
figmaMicro.keycapGlyphs.v1 Printed action/icon per black keycap
figmaMicro.keycapColors.v1 Colored keycap allocation

These values describe the application draft and visual representation. They do not prove that the same state is currently present on the controller.

Lighting flow

FigmaActivityMonitor observes activation of com.figma.Desktop and feeds LightingStateMachine, which applies this priority:

  1. Figma active: user-configured perimeter preset (default: bright rainbow swirl);
  2. outside Figma: user-configured perimeter preset (default: dim white breathing).

Layer 0 behaves like every other layer. (An earlier optional "Layer 0 is Off Mode" toggle was removed; its stale figmaMicro.layerZeroOffMode.v1 default is cleaned up on launch.)

Three lighting zones are user-configurable in the main controller workspace through LightingZoneConfig (preset, brightness, speed, color): the perimeter while in Figma, the perimeter outside Figma, and the key matrix while in Figma. The configuration is persisted as LightingConfiguration in UserDefaults under figmaMicro.perimeterLighting.v1; decoding tolerates older payloads without the key zone. Keys stay off outside Figma. Configurator edits preview on the hardware immediately and settle back to the state machine's scene after three seconds.

Perimeter presets map to RGB Light modes (speed selects same-direction effect variants); key presets map to RGB Matrix modes, where the raw speed value is honored directly and the press-reactive typing heatmap and digital rain framebuffer effects are available. Per-key colors are not possible over stock VIA, which only exposes zone-wide values.

ControllerLightingService resolves states to zone configurations, serializes scene changes, and delegates Raw HID writes to HIDDeviceService, which translates a LightingZoneConfig into VIA channel commands (effect, color, brightness, speed).

Testing

Run unit tests:

swift test

Run the build and application-launch smoke test:

./script/build_and_run.sh --verify

The current tests cover lighting priority, VIA layer naming/index behavior, special-button invariants, application launching behavior, the physical matrix coordinates, the device-snapshot import/merge rules, persistence round-trips and launch migration, the night-dimming window, and the apply flow (through the ControllerKeymapWriting seam with a recording writer). Actual VIA report traffic still requires a connected physical controller for end-to-end verification.

Extension points

  • Add new actions in figma-shortcuts.json and, when available, map their artwork in FigmaVisualAssets.swift.
  • Add new directly writable chord shapes in QMKKeycodeEncoder together with focused unit tests.
  • Keep all controller I/O inside HIDDeviceService; views should never construct VIA reports.
  • Keep firmware indexes canonical in the model even if the UI later presents user-facing names L1–L4.