[feat] Windows: a way to get the native window handle on creation
type: feature request
### Describe the problem
On Windows there is no supported point at which an application can act on its own window between `CreateWindowExW` and the moment the window first appears on screen. `WebviewWindowBuilder::build()` creates the HWND, applies the requested state, shows the window, and only then hands back a `WebviewWindow`. Every hook Tauri does expose - `RunEvent::WindowEvent`, `on_window_event`, the returned handle - is reached after the window has already been shown at least once.
Some launch-time details I needed to apply have to land before the first frame, and none of them can be expressed on the builder. Currently I must resort to using `SetWindowsHookExW`.
<details><summary>The things I need</summary>
<p>
Just mentioning for completeness what I encountered:
1. **Exact placement in physical pixels.** The builder only takes logical coordinates. tao resolves those to a monitor with a search of its own - the first monitor on which the position, scaled by *that* monitor's factor, lands. On a mixed-DPI setup that can be a different monitor than the position was derived from, and for a window remembered half off an edge it can be no monitor at all, which falls back to the default cascade position. A window restoring its saved geometry therefore opens in the wrong place. A rectangle in physical pixels has no such ambiguity, but there is no way to pass one.
2. **The caption/taskbar icon.** tao gives the window a single icon - the largest image decoded out of `icon.ico` - which Windows then squeezes into the ~16px caption slot, so the small icon is a badly downscaled 256x256. Applying proper `WM_SETICON` `ICON_SMALL`/`ICON_BIG` images after `build()` returns means the frame and the taskbar button have already been drawn with tao's.
3. **Activation.** We must build with `.focused(false)`: wry calls `MoveFocus` as the last step of a focused webview build and propagates the result. But Tauri passes that same flag to the window, so tao shows it with `SW_SHOWNOACTIVATE` and the launch never comes to the foreground. There is no way to say "show the window activated, but do not move focus into the webview": one flag controls both.
4. **`maximized: true`.** As observed with tao 0.35, a window asked to open maximized is maximized while hidden, then shown with `SW_SHOWNOACTIVATE` - which carries `SW_SHOWNORMAL`'s "most recent size and position" meaning and therefore *restores* it - and only then maximized again. What the user sees is the window arriving at its restored size and being animated up to fill the screen on every single launch.
</p>
</details>
### Describe the solution you'd like
A creation-time escape hatch on the window builder, plus (ideally) fixes that remove the need to reach for it.
A callback that runs while the window exists but is not yet visible:
```rust
WebviewWindowBuilder::new(app, "main", url)
// Called on the window's own thread after CreateWindowExW has produced the
// HWND (WM_CREATE would be ideal) and before the window is first shown.
.on_window_created(|window: &Window| { /* raw HWND available here */ })
```
### Alternatives considered
- **Build hidden, fix up, then show** (`.visible(false)` + `set_position` + icons + `show()`). This is the obvious answer and the one we would prefer, but `build()` also creates the WebView2 environment and controller, which takes the better part of a second. Deferring the first appearance until after `build()` returns means half a second of nothing on screen after the user launched the app. The window has to be visible *during* the build, which means its geometry, icon and activation have to be right *before* the build.
- **`SetWindowSubclass` after `build()` returns.** Too late for everything above; the window has been shown.
- **`RunEvent::WindowEvent` / `on_window_event` / the returned `WebviewWindow`.** All post-show. Correcting position or maximized state from there is visible as a jump or an animation, which is what we are trying to eliminate.
### Additional context
Versions: `tauri 2.11.5`, `tauri-runtime-wry 2.11.4`, `tao 0.35.3`, `wry 0.55.1`, Windows 11.
0 条评论