ITADN

[feat] Windows: a way to get the native window handle on creation

#15841Openjustanotheranonymoususer 创建于 14 天前
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 条评论