Skip to content

Shortcut flow broken on Windows — no single/double distinction, focus, and routing issues #30

@0xMMA

Description

@0xMMA

Context

The global hotkey (Ctrl+G) should work as: single press → silent fix, double press (quick succession) → open Pyramidize UI. The v1 Rust/Tauri implementation had proper double-click detection with a 200ms threshold (archive/v1-tauri-rust/src/frontend/src/app/shortcut-manager.ts). This was never ported to the Go/Wails rewrite.

Currently, every hotkey press emits the same shortcut:triggered event with no timing-based differentiation. Both FixComponent and TextEnhancementComponent independently subscribe to this event.

Problems

1. Pyramidize captures clipboard on single press

If the Pyramidize page (/enhance) is the active route, a single Ctrl+G press copies clipboard content into the Pyramidize editor (text-enhancement.component.ts:1096) instead of performing a silent fix. The FixComponent subscription (fix.component.ts:107) also fires but its behavior depends on route state.

Expected: Single press should always trigger silent fix regardless of which page is active.

2. Window doesn't focus on double shortcut press

main.go has a comment about showing the window but never calls window.Show().Focus() in the shortcut handler. The tray service handles focus on click, but the shortcut path does not.

Expected: Double press should bring the KeyLint window to front with the Pyramidize page ready.

3. Silent fix leaks into Pyramidize when UI was previously open

If the user previously had the app open on the Pyramidize page, then hid it, a single Ctrl+G press copies text into the Pyramidize editor in the background (since the route is still /enhance) but doesn't show the window — so the silent fix either doesn't happen or produces unexpected state.

Expected: Single press should always run the silent fix pipeline regardless of the app's current route/visibility state.

Root Cause

No single vs double press detection exists in the current implementation. The shortcut service (internal/features/shortcut/service_windows.go) emits one event per WM_HOTKEY message with no timing logic. Both page components subscribe to the same event with no routing guard.

Relevant Code

  • internal/features/shortcut/service_windows.go — Win32 hotkey registration, message loop
  • main.go:136-147 — shortcut handler goroutine (captures source app, copies clipboard, emits event)
  • frontend/src/app/core/wails.service.tsshortcutTriggered$ RxJS subject
  • frontend/src/app/features/fix/fix.component.ts:107 — silent fix subscription
  • frontend/src/app/features/text-enhancement/text-enhancement.component.ts:1096 — pyramidize subscription
  • archive/v1-tauri-rust/src/frontend/src/app/shortcut-manager.ts — v1 double-click detection (reference)

Acceptance Criteria

  • Single Ctrl+G press always triggers silent fix, regardless of active route or window visibility
  • Double Ctrl+G press (within ~200ms) opens Pyramidize UI, brings window to front, and loads clipboard into editor
  • Pyramidize page does not capture clipboard on single press
  • Window correctly receives focus on double press

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions