Progress notes from the MapXr development sessions.
2026-03-24
Getting arbitrary key injection working on Android without root required three attempts: AccessibilityService (too limited for modifier keys and non-text apps), a custom IME (same ceiling), and a hand-rolled ADB wireless debugging client (pairing worked, but Samsung Android 16 rejected the keys for an undiagnosable reason). Shizuku solved it cleanly — shell-uid Binder IPC via the same wireless debugging infrastructure. The full action vocabulary is dispatched through a JNI bridge that bypasses the WebView entirely, so injection keeps working when the app is backgrounded. APK coming soon.
2026-03-20
Shipped v0.1.2 — the first release where the full pipeline works end-to-end: build, sign, publish, auto-update. Getting there required hunting down three separate bugs: a missing config key that silently suppressed the auto-updater manifest, a Windows API breaking change in the focus monitor, and a tray icon crash that took down the app before the first window opened.
2026-03-19
Shipped OS desktop notifications for device and layer events (Epic 16). Audited the key dispatch path and found six categories of silent failure — arrow keys, all F-keys, punctuation, media, and system keys were all declared valid but never fired. Rewrote name_to_key, added media_stop/pause/brightness/eject/mic_mute, and upgraded the key picker to a grouped select.
2026-03-18
Replaced alphabetical startup profile selection with a preferences.json that remembers the last activated profile. Fixed a bug where explicit deactivation was indistinguishable from first-launch state, causing a profile to always be selected on restart. Added device-aware suggestion banners.
2026-03-18
Improved scan UX with seen/paired/cached device states and stale-RSSI fixes. Added connected device name persistence. Seeded a starter profile on first launch. Renamed reference docs. Implemented live device role reassignment without disconnecting.
2026-03-18
Scaffolded the mapxr project site with Svelte 5, Tailwind CSS v4, and DaisyUI v5. Implemented landing page, docs scaffold, and devlog view with full hash-based routing.
2026-03-16
Fixed double-tap inversion bug caused by TAP Strap hardware bounce. Added 50ms debounce window to ComboEngine. Also added GitHub Actions workflow for Windows builds and a user-facing README.
2026-03-15
Implemented the hold_modifier action with Toggle, Count, and Timeout modes. Added HoldModifierMode enum, full validation, and 15+ tests. Spec-approved before implementation.
2026-03-14
Updated the BLE scanner to filter advertisements by TAP service UUID so only genuine TAP Strap devices appear in the device list.
2026-03-10
Implemented the full ComboEngine with single-tap, double-tap, and cross-device combo detection. Timing is controlled via tokio::time for deterministic tests.
2026-03-05
Added profile validation rules (duplicate triggers, missing actions, hold_modifier constraints). Implemented LayerStack with push/pop/activate semantics.
2026-02-28
Defined TapCode, Trigger, Action, Profile, and Layer types. Full serde round-trip tests. Profile deserialization from .json fixture files.