fix(computer-use): send the plain chord for uppercase hotkey letters on Windows (#27642)

SendKeys presses Shift for an uppercase letter (VkKeyScan reports the
shift state), so `orca computer hotkey --key CmdOrCtrl+A` (the documented
example) sent Ctrl+Shift+A on Windows. Lower-case a single-character key
when the hotkey has modifiers; Shift is still sent when written explicitly.

Extract ConvertTo-OrcaSendKeysHotkey so runtime-render.test.ps1 can assert
the SendKeys strings case-sensitively.

Fixes #27589

Co-authored-by: jespo2021 <joeespo@gmail.com>
Co-authored-by: Neil <neil@stably.ai>
This commit is contained in:
Joe Esposito
2026-10-26 05:59:08 -07:00
committed by GitHub
co-authored by jespo2021 Neil
parent 99631994bc
commit ae8e3e1c37
2 changed files with 14 additions and 2 deletions
@@ -218,6 +218,11 @@ try {
$MaxDepth = $originalMaxDepth
}
foreach ($case in @(@("CmdOrCtrl+A", "^a"), @("Ctrl+Shift+T", "^+t"), @("Ctrl+Enter", "^{ENTER}"))) {
$keys = ConvertTo-OrcaSendKeysHotkey $case[0]
if ($keys -cne $case[1]) { throw "hotkey $($case[0]) expected '$($case[1])', received '$keys'" }
}
Write-Output "windows-snapshot-render-tests-ok"
} finally {
Remove-Item -LiteralPath $operationPath -Force -ErrorAction SilentlyContinue
+9 -2
View File
@@ -1102,18 +1102,25 @@ function Get-OrcaClickModifierVirtualKeys([string]$Modifiers) {
@($parts | ForEach-Object { Get-OrcaModifierVirtualKey $_ })
}
function Send-OrcaHotkey([IntPtr]$WindowHandle, [string]$KeySpec) {
function ConvertTo-OrcaSendKeysHotkey([string]$KeySpec) {
$parts = @($KeySpec.Split("+") | ForEach-Object { $_.Trim() } | Where-Object { -not [string]::IsNullOrWhiteSpace($_) })
if ($parts.Count -eq 0) { throw "Unsupported key: $KeySpec" }
$key = $parts[$parts.Count - 1]
$prefix = ""
if ($parts.Count -gt 1) {
# SendKeys adds Shift for an uppercase letter, turning Ctrl+A into Ctrl+Shift+A.
if ($key.Length -eq 1) { $key = $key.ToLowerInvariant() }
foreach ($modifier in $parts[0..($parts.Count - 2)]) {
$prefix += ConvertTo-OrcaSendKeysModifier $modifier
}
}
$prefix + (ConvertTo-OrcaSendKeysKey $key)
}
function Send-OrcaHotkey([IntPtr]$WindowHandle, [string]$KeySpec) {
$keys = ConvertTo-OrcaSendKeysHotkey $KeySpec
[void][OrcaDesktopWin32]::SetForegroundWindow($WindowHandle)
[System.Windows.Forms.SendKeys]::SendWait($prefix + (ConvertTo-OrcaSendKeysKey $key))
[System.Windows.Forms.SendKeys]::SendWait($keys)
}
function ConvertTo-OrcaSendKeysText([string]$Text) {