Skip to content

enhancement: adopt Swift 6 language mode and make the global hot-path state concurrency-safe #95

Description

Problem

Package.swift is swift-tools-version: 5.10 with no Swift 6 language mode. The CGEvent-tap hot path reads module-level var globals — shortcutList, exclusionAppsDict, isRecordingShortcut, keyMappingList, activeAppsList, exclusionAppsList.

Today there is no live data race: the tap's run-loop source is added to the main run loop (CFRunLoopGetMain()), and AppSettings (the writer) is @MainActor — so every reader and writer is on the main thread. But that contract is invisible to the compiler. Under Swift 6 strict concurrency these globals are hard errors (non-Sendable mutable global state), and the safety relies entirely on a convention that is easy to break (e.g. moving the tap to a background run loop).

Suggested approach

  1. Wrap the shared caches in a @MainActor holder type (or a small lock-guarded struct).
  2. Enable Swift 6 language mode (swiftLanguageModes: [.v6] / per-target setting).
  3. Let the compiler enforce the main-thread contract that is currently only documented in CLAUDE.md.

Forward-looking; related to closed #73 ("crash risk under Swift 6").

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions