gpui: Fix `TestWindow` panicking on `window_handle` (#62775)

> **AI disclosure:** I used Claude (Anthropic) to diagnose this, write
the fix and its test, and draft this PR description, after every
headless test in my own app started panicking during a gpui upgrade. I
reviewed the diff and the reasoning below, ran the tests myself, and
understand and take responsibility for the change, per Zed's [AI
Policy](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#ai-policy).

# Objective

- `TestWindow` panics instead of returning an error when asked for its
raw window handle. `HasWindowHandle` and `HasDisplayHandle` both return
`Result<_, HandleError>`, so a window with no C-typed handle can report
that — but `TestWindow` calls `unimplemented!()`. Callers who correctly
write `window_handle().ok()?` still crash, and any headless test whose
window reaches code that asks for the platform handle dies on boot.
- This has two halves, and only the second made it reachable:
- `a54eaaece` ("Add raw window handle implementations to GPUI", #7101,
2024-01-30) added both impls for `TestWindow` as `unimplemented!()`
placeholders while the real platforms got real ones. `TestWindow` was
`pub(crate)` then, so nothing outside gpui could hit it.
- `4270f8995` ("gpui: Implement `HasWindowHandle` on `Window`", #24327,
2025-02-06) made `Window` implement both traits by forwarding to
`platform_window`. From then on, any consumer asking a `Window` for its
raw handle reaches `TestWindow` under `TestAppContext`.
- I hit this through
[gpui-component](https://github.com/longbridge/gpui-component), whose
macOS accessibility code calls
`HasWindowHandle::window_handle(window).ok()?` on every window it roots
— correct defensive code that still panics, taking every one of my
headless `#[gpui::test]` tests down at boot.


## Solution

- `TestWindow::window_handle` and `TestWindow::display_handle` now
return `Err(HandleError::NotSupported)` instead of calling
`unimplemented!()`. That variant's documentation describes exactly this
case — "the underlying handle cannot be represented using the types in
this crate".
- Real platform windows are untouched: this only changes what the test
platform reports, so `Ok(...)` on macOS, Linux and Windows is
unaffected. Callers that already handle the error path now get the error
they were written for.

## Testing

- Added `test_window_reports_no_raw_handle_instead_of_panicking` in
`crates/gpui/src/window.rs`, asserting both calls return
`Err(HandleError::NotSupported)`.
- Reverting the fix while keeping the test reproduces the original
panic, so the test pins the behaviour rather than passing vacuously.
- `cargo test -p gpui --lib` from a clean target directory — 220 passed,
0 failed:

```
   Compiling gpui v0.2.2 (/…/zed/crates/gpui)
    Finished `test` profile [unoptimized + debuginfo] target(s) in 5m 25s
     Running unittests src/gpui.rs (target/debug/deps/gpui-463768d254ca0c08)

running 220 tests
...
test window::tests::test_window_reports_no_raw_handle_instead_of_panicking ... ok
...
test result: ok. 220 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.49s
```
- Tested on macOS. The change is confined to
`crates/gpui/src/platform/test/`, which is platform independent, but I
have not built the Linux or Windows platform crates.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

Before — the new test against the current `unimplemented!()`:

```
thread 'window::tests::test_window_reports_no_raw_handle_instead_of_panicking' panicked at
crates/gpui/src/platform/test/window.rs:57:9:
not implemented: Test Windows are not backed by a real platform window

test result: FAILED. 0 passed; 1 failed
```

After — see the full run above.

Release Notes:

- N/A
7bddd16a09goring committed on 8/17/2026, 9:50:09 PM· committed by GitHubparent8b1497d
2 files changedLine totals unavailable