stablyai/orca · error · RuntimeError
window_not_focused: keyboard input requires the target windo
Error message
window_not_focused: keyboard input requires the target window to be focused; restoreWindow was requested but the target window is still not focused; bring it forward manually or check desktop permissions
What it means
Raised by require_keyboard_focus (runtime.py:180-191) when operation.get('restoreWindow') was truthy, the window did not have the AT-SPI ACTIVE state, and a 500ms polling loop (10× 50ms checks) failed to observe the window become ACTIVE. restore_window was attempted (in run_operation line 1049-1051 before require_keyboard_focus) via grab_focus or xdotool windowactivate, but the compositor still did not grant active focus — synthetic keyboard input would go to the wrong window, so the bridge refuses rather than type into the wrong app.
Source
Thrown at native/computer-use-linux/runtime.py:191
["xdotool", "search", "--pid", str(pid), "windowactivate", "--sync"],
check=False,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
def require_keyboard_focus(window, operation):
if has_state(window, Atspi.StateType.ACTIVE):
return
if operation.get("restoreWindow"):
deadline = time.monotonic() + 0.5
while time.monotonic() < deadline:
if has_state(window, Atspi.StateType.ACTIVE):
return
time.sleep(0.05)
if has_state(window, Atspi.StateType.ACTIVE):
return
raise RuntimeError("window_not_focused: keyboard input requires the target window to be focused; restoreWindow was requested but the target window is still not focused; bring it forward manually or check desktop permissions")
raise RuntimeError("window_not_focused: keyboard input requires the target window to be focused; retry with --restore-window")
def app_matches(app, query):
needle = str(query or "").strip().lower()
if not needle:
return False
if needle.startswith("pid:"):
requested_pid = parse_positive_pid(needle[4:])
return requested_pid is not None and pid_of(app) == requested_pid
if needle.isdigit() and int(needle) > 0 and pid_of(app) == int(needle):
return True
haystacks = [name_of(app).lower()] + [name_of(window).lower() for _, window in windows_for(app)]
return any(value == needle or needle in value for value in haystacks)
def parse_positive_pid(value):
return int(value) if value.isdigit() and int(value) > 0 else NoneView on GitHub (pinned to 1136503c6a)
Solutions
- Manually bring the target window to the foreground (click it, Alt-Tab to it) and retry without restoreWindow.
- On Wayland, ensure the AT-SPI bridge and Orca have permission to grab focus (focus-stealing-prevention disabled or the right xdg-desktop-portal).
- Increase robustness by retrying the operation after a longer settle, or chain multiple restore attempts with xdotool.
- If the window is on another workspace, switch to that workspace first (wmctrl -s or xdotool set_desktop_for_window).
Defensive patterns
Strategy: fallback
Validate before calling
# Pre-check focus state before requiring keyboard focus
if not has_state(window, Atspi.StateType.ACTIVE) and not operation.get('restoreWindow'):
operation['restoreWindow'] = True # let the bridge attempt activation
# also pre-check the window is restorable (not on another workspace, etc.) Type guard
def window_has_focus(window) -> bool:
return has_state(window, Atspi.StateType.ACTIVE) Try / catch
try:
require_keyboard_focus(window, operation)
except RuntimeError as exc:
if 'still not focused' in str(exc):
# manual fallback: prompt user to bring window forward, or switch workspace
raise SystemExit(f'Could not activate {name_of(window)}. Bring it forward manually and retry.')
raise Prevention
- On Wayland, ensure AT-SPI/Orca has focus-grab permission via xdg-desktop-portal.
- Disable GNOME focus-stealing-prevention for the bridge, or use xdotool windowactivate --sync before keyboard ops.
- Switch to the target window's workspace (wmctrl/xdotool) before restore attempts.
When it happens
Trigger: type_text/press_key/hotkey/paste_text called with restoreWindow:true on a window that another app's focus-stealing, a fullscreen/always-on-top window, minimized state, or lacking focus permissions prevents from becoming ACTIVE within 500ms. restore_window's grab_focus returned false or xdotool's windowactivate didn't take effect.
Common situations: GNOME/Mutter focus-stealing-prevention blocking grab_focus; a fullscreen game or always-on-top dialog keeping focus; the target window on a different virtual desktop; the user's session lacks permission to programmatically activate windows (Wayland without the right portal).
Related errors
- window_not_focused: keyboard input requires the target windo
- No top-level AT-SPI window is available for {app}
- windowId is not supported by the Linux AT-SPI provider; use
- windowNotFound("{window_index}")
- Linux computer use requires an active desktop session; missi
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/9f28b4f2c785d61b.
Report an issue: GitHub.