# Windows RDP install/uninstall UX validation — 2026-09-07

RC6's normal install, native registration, registered uninstall, cancellation,
and reinstall work in an actual Windows desktop. Four UX findings remain open;
this report records observations, not implementation fixes.

## Environment and method

- Windows 11 amd64 development VM, native Edge 152.0.4191.66, RDP at 1440×960.
- Published `1.3.0-rc.6`, application commit `59ab4c2`, build
  `2026-09-06T17:37:55Z`; executable SHA256
  `028adca411768d1b14a944e373e3b033d1d201323739d85ff7891a23f6131901`.
- Temporary standard account `MPVRocksQA-RDP`, actual profile/default install
  path and HKCU/Known Folders; no HOME or APPDATA redirection. RDP certificate
  SHA256 was checked against the VM certificate over authenticated SSH.
- Visible Edge was controlled through browser locators over an SSH-forwarded
  local debugging connection. Windows Settings, Run and player windows were
  controlled through the RDP desktop. Screenshots were visually inspected.
  Product mutations used the UI; jobs, files and registry checks corroborated
  outcomes. The test video was a locally generated blue frame, with no private
  media. No factory mocks or headless browser substituted for the desktop.
- Atlas QA task: `5ac0f8b2-30a6-4acf-9959-42bfbaa45661`.

## Verified outcomes

| Scenario | Observed result | Evidence |
| --- | --- | --- |
| Fresh account | No installed mpv discovered; published RC6 loaded | [Desktop](rdp-apps-initial.png) |
| Install confirmation | ModernZ selected by default; Cancel starts no job and restores enabled Install button | [Dialog](02-install-dialog.png) |
| Install | mpv, FFmpeg and ModernZ installed in about 26 seconds; installed card appeared without a manual reload; native executable launched | [Installed card](05-installed.png), [jobs](jobs.json) |
| Set default app | Native registrar opened the specific mpv Settings page; selecting mpv for AAC and MKV changed the visible Windows defaults in the disposable account | [AAC](rdp-aac-default.png), [MKV](rdp-mkv-default.png) |
| Shell file opening | Opening the MKV through Windows Run launched native mpv and displayed the generated video with ModernZ | [Playback](rdp-shell-playback.png) |
| Cancel uninstall | Confirmation initially focused Cancel; cancelling started no uninstall job and restored focus to the Uninstall button | [Confirmation](06-uninstall-dialog.png) |
| Registered uninstall | Completed; executable, ownership manifest, shortcuts and native chooser/handler entries removed. Config hash and sentinel file preserved | [UI](08-uninstall-settled.png), [state checks](uninstall-verification.json) |
| File opening after removal | Windows offered an app chooser without mpv; no attempt to launch a missing executable | [Actual chooser](rdp-after-uninstall-open.png) |
| Cancel during download | Terminal Cancelled in less than one second; exact staging directory removed and config hash preserved | [Dialog](09-cancel-running.png), [state checks](cancel-verification.json) |
| Retry installation/navigation | Reinstalled in about 21 seconds. Closed progress dialog, navigated to Dashboard and Tasks while running, then returned to the installed card; task continued | [Active task](11-navigation-active-task.png), [installed](12-reinstalled-after-navigation.png) |
| Uninstall with player open | Failure was correctly reported, but supporting files had already been removed; see WUX-01 | [Details](14-uninstall-running-error-details.png), [partial state](busy-uninstall-verification.json) |
| Close player and retry | Clicking the native player's close button and retrying uninstall completed successfully; config/sentinel preserved and no staging remained | [UI](15-retry-uninstall-success.png), [final state](final-verification.json) |
| Shutdown | UI confirmation shut down the test manager; no test-manager process remained before account cleanup | [Cleanup](cleanup.json) |

The [seven recorded jobs](jobs.json) comprise two successful installs, two
successful uninstalls, one cancelled install and two failed uninstalls while
mpv remained open. The second failed attempt occurred because an SSH-side
CloseMainWindow call could not close a window in the RDP session; actual RDP
window closure then allowed retry. [Detailed jobs](job-details.json) retain
worker outcomes. No JavaScript page errors were observed during the attached
browser sessions.

## Open findings

### WUX-01 — P1: running mpv causes a partially removed installation

With the reinstalled player paused on the test video, Uninstall removes desktop
and Start Menu shortcuts and nine owned files (including FFmpeg) before failing
on locked `mpv.exe`. The installed card remains, and the toast says only
“Failed to uninstall MPV.” Details contain “Access is denied,” with no instruction
to close mpv and retry. The config and ownership inventory survive, and retry
succeeds after closing the player.

The removal loop in `pkg/installer/windows_ownership.go` continues deleting
other files after a removal error; `WindowsInstaller.UninstallWithOutput` in
`pkg/installer/windows.go` removes shortcuts before payload removal. A repair
should detect/reserve the required file removals before destructive cleanup,
retain recovery guarantees, and provide actionable close-and-retry guidance.
The busy-player case used an unregistered reinstall; the successful registered
uninstall was tested separately.

Atlas: `97239155-c4e0-41d8-8831-165967494f4d`.

### WUX-02 — P2: cancelled install leaves an active-looking toast

After the worker reaches Cancelled and the task count returns to zero, the
“Installing MPV…” toast persists. Retrying produces two “View Progress” toasts,
one pointing to the cancelled job. [Screenshot](10-duplicate-progress-after-cancel.png).

`jobs.js` excludes cancelled terminal status from `showCompletionToast`, while
`toast.js` removes the started toast inside `showJobToast`. Cancellation needs
the same started-toast cleanup even if no extra completion toast is desired.

Atlas: `e913827b-f0f5-4761-877a-8330f9dcfaa4`.

### WUX-03 — P2: overall progress reaches 100% before installation completes

The dialog shows Running (100%) while extracting FFmpeg, with configuration and
ModernZ still pending. [Screenshot](04-progress-dialog.png). The Tasks page
repeats the same overall percentage. `pkg/web/jobs.go` promotes percentages
parsed from download output into monotonically increasing overall job progress.
Separate download/phase progress from total completion, or reserve 100% for the
terminal completed state.

Atlas: `df40af03-c9a9-44b8-a73d-3650a2e07bd7`.

### WUX-04 — P2: cancelling overlay selection loses keyboard focus

Cancel restores the Install button text and enabled state, but the active element
remains BODY even after the close animation. In `ui-select.js`, `close()` closes
the dialog and attempts focus restoration before re-enabling the invoker.
Re-enable the invoker before restoring focus, and exercise Cancel/Escape with a
real browser. Uninstall confirmation correctly returns focus to its invoker.

Atlas: `2322718b-5a38-42e1-8eee-1aa66345061c`.

A secondary accessibility observation: job-dialog footer button names include
icon-font glyphs (for example, a private-use glyph before “Close”). Exact
accessible-name locators failed; the labelled close icon worked. Decorative
footer icons should be hidden from the accessibility tree when that dialog is
next revised.

## Scope and cleanup

This pass validates standard-user Windows amd64 behavior for the published RC6.
It does not establish elevated/HKLM uninstall, other native architectures,
MPC-QT installer behavior, browser-download SmartScreen/quarantine, or final
release acceptance. The executable was downloaded and hash-checked through the
QA setup, so this is not a browser-download permission test.

The temporary account was logged off; its profile, QA directory and launch task
were removed, local temporary credentials deleted, and the existing owner
console session restored. Before cleanup, the owner's mpv executable and native
registered path were still present. No owner installation was used for the
mutation tests. See [cleanup](cleanup.json) and [final state](final-verification.json).
