{"record":{"id":"9f28b4f2c785d61b","repo":"stablyai/orca","slug":"window-not-focused-keyboard-input-requires-the-ta","errorCode":null,"errorMessage":"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","messagePattern":"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","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"native/computer-use-linux/runtime.py","lineNumber":191,"sourceCode":"        [\"xdotool\", \"search\", \"--pid\", str(pid), \"windowactivate\", \"--sync\"],\n        check=False,\n        stdout=subprocess.DEVNULL,\n        stderr=subprocess.DEVNULL,\n    )\n\n\ndef require_keyboard_focus(window, operation):\n    if has_state(window, Atspi.StateType.ACTIVE):\n        return\n    if operation.get(\"restoreWindow\"):\n        deadline = time.monotonic() + 0.5\n        while time.monotonic() < deadline:\n            if has_state(window, Atspi.StateType.ACTIVE):\n                return\n            time.sleep(0.05)\n        if has_state(window, Atspi.StateType.ACTIVE):\n            return\n        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\")\n    raise RuntimeError(\"window_not_focused: keyboard input requires the target window to be focused; retry with --restore-window\")\n\n\ndef app_matches(app, query):\n    needle = str(query or \"\").strip().lower()\n    if not needle:\n        return False\n    if needle.startswith(\"pid:\"):\n        requested_pid = parse_positive_pid(needle[4:])\n        return requested_pid is not None and pid_of(app) == requested_pid\n    if needle.isdigit() and int(needle) > 0 and pid_of(app) == int(needle):\n        return True\n    haystacks = [name_of(app).lower()] + [name_of(window).lower() for _, window in windows_for(app)]\n    return any(value == needle or needle in value for value in haystacks)\n\n\ndef parse_positive_pid(value):\n    return int(value) if value.isdigit() and int(value) > 0 else None","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/native/computer-use-linux/runtime.py#L173-L209","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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)."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"# Pre-check focus state before requiring keyboard focus\nif not has_state(window, Atspi.StateType.ACTIVE) and not operation.get('restoreWindow'):\n    operation['restoreWindow'] = True  # let the bridge attempt activation\n# also pre-check the window is restorable (not on another workspace, etc.)","typeGuard":"def window_has_focus(window) -> bool:\n    return has_state(window, Atspi.StateType.ACTIVE)","tryCatchPattern":"try:\n    require_keyboard_focus(window, operation)\nexcept RuntimeError as exc:\n    if 'still not focused' in str(exc):\n        # manual fallback: prompt user to bring window forward, or switch workspace\n        raise SystemExit(f'Could not activate {name_of(window)}. Bring it forward manually and retry.')\n    raise","preventionTips":["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."],"tags":["linux","at-spi","focus","keyboard","window","permissions"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}