Features:
- Add auto-enable on startup based on config
- Add enabled state persistence in config.json
- Add limitations notice in GUI menu
- Simplify logging to single file (uskey.log)
- Change "Open Logs Folder" to "Open Config Folder"
Bug Fixes:
- Fix GUI status display mismatch on startup
- Fix first toggle click not working issue
- Revert password field changes that caused key blocking
UI Changes:
- Add ⚠️ emoji to "About Limitations" menu item
- Remove button action to fix menu refresh
🤖 Generated with [Qoder][https://qoder.com]
Changed event handling to create and post new keyboard events instead of
modifying existing events, which resolves issues with password fields in
web browsers and other secure input contexts that ignore modified events.
🤖 Generated with [Qoder][https://qoder.com]
Features:
- Build DMG for both arm64 (Apple Silicon) and x86_64 (Intel)
- Automatic release creation when tags are pushed
- Multi-architecture support using matrix strategy
- Upload artifacts to GitHub releases
Workflow:
1. Triggered only on tag push (e.g., v1.0.0)
2. Build job: Compiles for arm64 and x86_64 in parallel
3. Release job: Creates GitHub release with both DMGs
Build Scripts Updates:
- Support VERSION environment variable
- Dynamic version in Info.plist
- Dynamic version in DMG filename
Release Artifacts:
- uskey-v{version}-arm64.dmg (Apple Silicon)
- uskey-v{version}-x86_64.dmg (Intel)
Files:
- .github/workflows/release.yml: CI/CD workflow
- build-app.sh: Support VERSION env var
- build-dmg.sh: Support VERSION env var
Usage:
🤖 Generated with [Qoder](https://qoder.com)
Problem:
- When user first launches the app without accessibility permissions,
the system shows a permission dialog
- After granting permissions, the app was already running but not
fully initialized
- User couldn't reopen the app (already running) and functionality
wasn't available
Solution:
- Implemented permission monitoring with Timer (checks every 1 second)
- Deferred app initialization until permissions are granted
- Split initialization into initializeApp() method
- Automatically initialize once permissions are detected
User Experience:
- User grants permission in System Preferences
- App automatically detects permission change
- App initializes and starts working without restart
- Updated alert message to inform user about auto-start
Technical Changes:
- Added permissionCheckTimer for monitoring
- Added initializeApp() for deferred initialization
- Store config and keyMapper as instance variables
- Use Task { @MainActor } for timer callback
- Changed alert style from warning to informational
🤖 Generated with [Qoder](https://qoder.com)
Features:
- Menu bar GUI with enable/disable toggle
- JSON-based configuration system
- File-based logging with debug support
- CGEventTap-based key remapping
- Custom app icon support
- DMG installer packaging
Core Components:
- AppDelegate: Application lifecycle and initialization
- EventTapManager: Event tap creation and management with proper pointer lifetime
- KeyMapper: Key mapping logic and configuration loading
- StatusBarController: Menu bar UI and user interactions
- Logger: File and console logging with configurable levels
- Config: JSON configuration parser with default creation
Build System:
- build-app.sh: Creates macOS .app bundle with icon
- build-dmg.sh: Generates distributable DMG installer
- create-icon.sh: Converts PNG to .icns format
Documentation:
- README.md: User guide and troubleshooting
- BUILD.md: Build instructions and packaging
- DEBUG.md: Debugging guide with log access
🤖 Generated with [Qoder](https://qoder.com)