microsoft / microsoft/winappCli
[Bug]: ui focus should activate the target window and verify focus before reporting success
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 1.3k
- Forks
- 80
- Avg merge
- 3d 6h
- Merged PRs (30d)
- 51
Description
### Describe the bug
`winapp ui focus ` can report success after focusing a control inside an inactive application, without bringing the application window to the foreground. The next guarded click or keyboard action can still fail because the app is not active.
The agreed user-facing behavior is: **activate the target window, focus the requested control, and verify the result before reporting success**. Activation should be attempted by default when needed, not require taking a screenshot or discovering a separate workaround.
This is an intentional correction to the current low-level UIA SetFocus-only contract, not a claim that the original implementation promised foreground activation. Windows restrictions, user interruption, target isolation, and existing input safety checks must remain in effect.
### To Reproduce
Observed with CLI `0.6.3-prerelease.52` in Windows Sandbox using the Daylight WinUI demo (https://github.com/nmetulev/daylight):
1. Start Daylight and discover its current app PID and main HWND. Establish that its main window is inactive.
2. Run `winapp ui click SearchTasksBox -a --on sandbox --json`.
3. Run `winapp ui focus SearchTasksBox -a --on sandbox --json`.
4. Read `HasKeyboardFocus` for the control and inspect which window is foreground. Do not use `get-focused` as the sole oracle because of #876.
Observed:
- The guarded click exited 1 with `foreground_not_target`.
- `focus SearchTasksBox` exited 0 and the control reported `HasKeyboardFocus=True`, but the main window remained inactive.
- `screenshot -w --focus --on sandbox` subsequently succeeded; an owned Daylight popup became foreground, and the following guarded click succeeded and activated the main window.
**Reproduction limitation:** Daylight was confirmed inactive, but this trial did not establish a stable unrelated foreground window. Add a controlled two-window regression case rather than treating the screenshot workaround as proof of the underlying activation failure.
Relevant current behavior:
- [UiFocusCommand](https://github.com/microsoft/winappCli/blob/2e307c7e8e648a1906205241148de20bcf12f7ab/src/winapp-CLI/WinApp.Cli/Commands/UiFocusCommand.cs) invokes UIA focus without an explicit foreground activation step.
- `UiClickCommand` already requests foreground activation and refuses if it is not obtained or retained. Do not remove that guard; simply adding another identical activation attempt is not sufficient evidence of a fix.
- Separately, installed help shows `focus []`, while `winapp ui focus -w 0 --on local --json` exits 1 with `missing_selector`. This help/validation mismatch is independently reproduced and should be corrected on the affected command.
### Expected behavior
For `winapp ui focus -a ` or `-w `:
1. Resolve and revalidate the intended app/window/control within the existing coordinated desktop operation.
2. If necessary, request activation of the correct target window using existing foreground helpers and safety rules.
3. Focus the requested control and verify both target foreground ownership and control keyboard focus before reporting success.
4. If Windows refuses activation, the user interrupts, focus moves elsewhere, or the target disappears, return an actionable nonzero failure rather than a success-shaped result.
"Activate by default" means **attempt activation when needed**, not forcibly bypass Windows focus restrictions or user-interruption safeguards.
Acceptance criteria:
- Cover an already active app, an eligible inactive app, refused activation, loss of foreground during focus, a stale/reused target, and relevant owned-popup cases.
- Never focus/type/click into an unrelated app or blindly treat every owned popup as the requested control's active window.
- Keep app/window targeting and local/sandbox isolation intact; do not add a local fallback.
- Preserve existing coordination and reuse existing helpers rather than creating a parallel activation subsystem.
- Add regression tests and a controlled live reproduction. Verify the observable outcome, not just that SetFocus or SetForegroundWindow was called.
- Update focus help, affected user documentation/skill guidance, and recovery messages to match the implemented behavior. Show the selector as required if it remains required; a new selector-less window-activation mode is not required for this issue.
Coordinate with #876 if focus verification needs shared ownership handling, but do not duplicate its focused-element discovery fix. #875 is a separate empty-value issue.
### Screenshots
N/A. Evidence consists of command exit codes and structured control-focus/foreground-window results.
### OS Version and details
CLI `0.6.3-prerelease.52`; native ARM64 Windows host and managed Windows Sandbox. Sandbox viewer connected and interactive during the reproduction. Source inspected at revision `2e307c7e8e648a1906205241148de20bcf12f7ab`.
No application code changes, saved edits, data resets, or input-guard bypasses were made during investigation.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with src/winapp-CLI/WinApp.Cli/Commands/UiFocusCommand.cs and compare its flow with UiClickCommand's existing foreground activation and safety checks. Add a controlled two-window regression covering activation, focus verification, refusal, stale targets, and owned popups, then update focus help, documentation or skill guidance, and recovery messages. Done means observable foreground ownership and control focus are verified before success without weakening isolation or input guards.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- cli, operating-systems, testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100