Files
Artemis-Plugins/plugins/open-computer-use/window-snapshot.ps1
T

45 lines
2.3 KiB
PowerShell

# Refresh the target's compositor before reading its accessibility tree and pixels.
# Chromium can suspend page painting while fully covered. PrintWindow alone can
# then return an old but otherwise valid bitmap. Do not activate or resize windows.
function Build-Snapshot([string]$query, $TextLimit = $script:DefaultTextLimit, [int]$MaxTreeNodes = $script:AccessibilityTreeMaxNodeCount, [int]$MaxTreeDepth = $script:AccessibilityTreeMaxDepth) {
$process = Resolve-App $query
$hwnd = [IntPtr]$process.MainWindowHandle
$wasTopmost = ([OCUWin32]::GetWindowLong($hwnd, -20) -band 8) -ne 0
$previous = [OCUWin32]::GetWindow($hwnd, 3)
$raised = $false
try {
if ($null -ne (Get-CapturableWindowFrame $hwnd)) {
# NOMOVE | NOSIZE | NOACTIVATE | NOOWNERZORDER. This may briefly expose
# the authorized target, but never focuses or captures another window.
$raised = [OCUWin32]::SetWindowPos($hwnd, [IntPtr](-1), 0, 0, 0, 0, 0x213)
if ($raised) {
Start-Sleep -Milliseconds 300
[void][OCUWin32]::DwmFlush()
}
}
$element = Get-MainElement $process
$bounds = Get-WindowBounds $process $element
$rendered = Render-Tree $element $bounds $TextLimit $MaxTreeNodes $MaxTreeDepth
$image = if ($raised) { Capture-WindowPngBase64 $bounds $hwnd } else { $null }
[pscustomobject]@{
app = [pscustomobject]@{ name=$process.ProcessName; bundleIdentifier=$process.ProcessName; pid=[int]$process.Id }
windowTitle = Limit-Text $process.MainWindowTitle $TextLimit
windowBounds = $bounds
screenshotPngBase64 = $image
treeLines = @($rendered.lines)
focusedSummary = Get-FocusedSummary $process.Id $TextLimit
selectedText = Get-SelectedText $process.Id $TextLimit
elements = @($rendered.records)
}
} finally {
if ($raised) {
if (-not $wasTopmost) {
[void][OCUWin32]::SetWindowPos($hwnd, [IntPtr](-2), 0, 0, 0, 0, 0x213)
}
if ($previous -ne [IntPtr]::Zero -and [OCUWin32]::IsWindow($previous)) {
[void][OCUWin32]::SetWindowPos($hwnd, $previous, 0, 0, 0, 0, 0x213)
}
}
}
}