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
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
- Branch:
feat/stage-8-uia.
- Open draft PR early so CI runs on each push.
- Manual test matrix: Notepad (old + Win11), WordPad, VS Code, Chrome address
bar + web textarea, Word, Telegram (Electron), Outlook.
- Merge to main when manual tests pass and CI is green.
- Tag v0.3.0 after merge.
Goal
Replace the clipboard+
SendInputapproach for reading the user's selectedtext 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:
UIA's
TextPattern.GetSelection()returns the actual selection state, so westop confusing "no selection" with "user copied a line."
Acceptance criteria
perform_conversion(selection-based) uses UIAGetSelectionas the primarypath; if the focused element doesn't implement
TextPattern, falls back tothe existing clipboard+
Ctrl+Cflow.perform_word_conversionuses UIATextRange::ExpandToEnclosingUnit(Word)around the caret as the primary path; falls back to
Ctrl+Shift+Left+Ctrl+Cif UIA isn't available.settings window) toggles the UIA path on/off. Default: enabled. The
caption mentions something like "Uncheck if switching behaves oddly in some app."
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.
DocumentRange) — that's a separate futureimprovement, tracked independently.
Out of scope for this issue
ValuePattern.SetValuefor single-line fields — may be added later as anoptimization for input fields that don't need clipboard.
DocumentRange.for that).
Implementation notes
Win32_UI_Accessibilityinwindows.uia.rswrappingIUIAutomation,IUIAutomationElement,IUIAutomationTextPattern,IUIAutomationTextRange.CoInitializeEx(COINIT_APARTMENTTHREADED)on the threadthat calls UIA (probably the main message loop thread). Must call
CoUninitializeon shutdown.windowscrate's built-inInterfacetypes rather than raw*mut.expose TextPattern and which don't.
Rollout plan
feat/stage-8-uia.bar + web textarea, Word, Telegram (Electron), Outlook.