Skip to content

Stage 8: UI Automation integration (fix smart-copy bug in Notepad / VS Code / Electron) #1

@zergius-eggstream

Description

@zergius-eggstream

Goal

Replace the clipboard+SendInput approach for reading the user's selected
text with a UI Automation (UIA) path. Keep the old approach as a fallback for
apps that don't expose TextPattern.

Fixes the main user-visible limitation from 0.2.0:

In editors with "smart copy" (Notepad on Windows 11, VS Code, many Electron apps),
Ctrl+C without an explicit selection copies the current line. LightSwitch can't
tell this apart from a real one-line selection, so triggering the conversion hotkey
without an explicit selection in such an editor incorrectly appends a converted
copy of the current line.

UIA's TextPattern.GetSelection() returns the actual selection state, so we
stop confusing "no selection" with "user copied a line."

Acceptance criteria

  • perform_conversion (selection-based) uses UIA GetSelection as the primary
    path; if the focused element doesn't implement TextPattern, falls back to
    the existing clipboard+Ctrl+C flow.
  • perform_word_conversion uses UIA TextRange::ExpandToEnclosingUnit(Word)
    around the caret as the primary path; falls back to Ctrl+Shift+Left +
    Ctrl+C if UIA isn't available.
  • A setting Use UIA when available (checkbox under autostart in the
    settings window) toggles the UIA path on/off. Default: enabled. The
    caption mentions something like "Uncheck if switching behaves oddly in some app."
  • Writing text back still uses clipboard+Ctrl+V (consistent, widely supported).
    That's fine because by then we know the real selection from UIA, so the paste
    lands in the right place.
  • Clipboard restore still works.
  • No "convert all" feature (DocumentRange) — that's a separate future
    improvement, tracked independently.

Out of scope for this issue

  • ValuePattern.SetValue for single-line fields — may be added later as an
    optimization for input fields that don't need clipboard.
  • "Convert all" via UIA DocumentRange.
  • UIA-based language-switch detection (not needed — existing HKL polling works
    for that).

Implementation notes

  • New crate feature: Win32_UI_Accessibility in windows.
  • New module uia.rs wrapping IUIAutomation, IUIAutomationElement,
    IUIAutomationTextPattern, IUIAutomationTextRange.
  • COM initialization: CoInitializeEx(COINIT_APARTMENTTHREADED) on the thread
    that calls UIA (probably the main message loop thread). Must call
    CoUninitialize on shutdown.
  • Safe Rust wrappers over COM interfaces — use the windows crate's built-in
    Interface types rather than raw *mut.
  • Detailed logging under the "[uia]" prefix so we can diagnose which programs
    expose TextPattern and which don't.

Rollout plan

  1. Branch: feat/stage-8-uia.
  2. Open draft PR early so CI runs on each push.
  3. Manual test matrix: Notepad (old + Win11), WordPad, VS Code, Chrome address
    bar + web textarea, Word, Telegram (Electron), Outlook.
  4. Merge to main when manual tests pass and CI is green.
  5. Tag v0.3.0 after merge.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions