JJason LeeBump v0.7.0
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
root: Add Base window hosting and a single Kit startup entry point (#3152) ## Summary Window startup now always mounts a `gpui_base::Root`, regardless of Cargo feature unification. Base owns application content, overlay hosting, keyboard traversal, and text-selection copying. Component initialization registers its per-window presentation state as a Root plugin, so dialogs, sheets, notifications, menus, tooltips, touch selection, and window chrome remain automatic without making Base depend on Component. - Add `gpui_kit::open_window` as the standard Kit application entry point. It always mounts Base Root and returns both the window handle and content entity. - Move Root ownership and unconditional overlay hosting into `gpui-base`; `gpui_component::Root` is now a re-export. Root now renders sheet, dialog, and notification layers automatically. - Add the typed `RootPlugin` interface. Plugins are registered before window creation, instantiated independently per window, rendered in registration order, and can prepare, style, and decorate the root surface. - Keep Component presentation in a `WindowState` Root plugin while application-facing operations remain on `WindowExt`. - Make `window_border()` solely responsible for client-side window chrome. Server-decorated windows pass content through unchanged; client-decorated windows receive borders, shadow inset, rounded corners, and resize hit zones. - Remove `Root::bordered` and `Root::window_shadow_size`, plus the obsolete `root_borderless` example. - Migrate Kit examples, stories, tests, documentation, and pending 0.7.0 release notes to the new startup and Root APIs. ## Public API ### gpui-base ```rust pub trait RootPlugin: Render + Sized { fn prepare(&mut self, window: &mut Window, cx: &mut Context<Self>) {} fn style(&self, surface: &mut Stateful<Div>, window: &mut Window, cx: &mut App) {} fn decorate( &self, surface: AnyElement, root: &Root, window: &mut Window, cx: &mut App, ) -> impl IntoElement { surface } } impl Root { pub fn new( view: impl Into<AnyView>, window: &mut Window, cx: &mut Context<Self>, ) -> Self; pub fn register_plugin<V: RootPlugin>( cx: &mut App, build: fn(&mut Window, &mut Context<V>) -> V, ); pub fn plugin<V: RootPlugin>(&self) -> Option<Entity<V>>; pub fn view(&self) -> &AnyView; pub fn read<'a>(window: &'a Window, cx: &'a App) -> &'a Self; pub fn update<R>( window: &mut Window, cx: &mut App, f: impl FnOnce(&mut Self, &mut Window, &mut Context<Self>) -> R, ) -> R; } ``` `Root` also implements `Styled`. Instance style refinements are applied after plugin defaults and therefore take precedence: ```rust impl Styled for Root { fn style(&mut self) -> &mut StyleRefinement; } ``` Register plugins during explicit application initialization, before creating windows. Re-registering a plugin type replaces its factory for future windows rather than mounting it twice. Registration does not retrofit existing roots. ### gpui-kit ```rust pub fn open_window<V: Render>( options: WindowOptions, cx: &mut App, build: impl FnOnce(&mut Window, &mut App) -> Entity<V>, ) -> Result<(AnyWindowHandle, Entity<V>)>; ``` The builder returns application content, not a Root. Kit mounts Base Root around it. ### gpui-component `pub use gpui_base::Root;` replaces the former Component-owned Root. `gpui_component::init(cx)` registers Component `WindowState` as a Root plugin. Manual layer-rendering and Root-owned dialog, sheet, and notification operations are removed. In particular, `Root::render_sheet_layer`, `Root::render_dialog_layer`, and `Root::render_notification_layer` no longer exist because Root hosts those layers automatically. Use the existing `WindowExt` operations to open and update them. ## Breaking Changes Targeted for 0.7.0; package versions remain unchanged. Use the Kit window entry point and return application content instead of constructing `Root` manually. Retain the returned content entity when direct content access is needed, because the window root is now `gpui_base::Root`: ```diff - cx.open_window(options, |window, cx| { - let content = build_content(window, cx); - cx.new(|cx| Root::new(content, window, cx)) - }) + let (window_handle, content) = + gpui_kit::open_window(options, cx, |window, cx| { + build_content(window, cx) + })?; ``` Delete manual overlay placement. `Root::render_sheet_layer`, `Root::render_dialog_layer`, and `Root::render_notification_layer` are removed because `Root` now hosts these layers automatically: ```diff - let sheet_layer = Root::render_sheet_layer(window, cx); - let dialog_layer = Root::render_dialog_layer(window, cx); - let notification_layer = Root::render_notification_layer(window, cx); - div() .child(content) - .children(sheet_layer) - .children(dialog_layer.map(|layer| deferred(layer).with_priority(1))) - .children(notification_layer) ``` Root window-chrome configuration is removed. Decoration policy comes from GPUI `WindowOptions`; `window_border()` applies client chrome only for `Decorations::Client`: ```diff - Root::bordered - Root::window_shadow_size + window_border() ``` The Root- and WindowExt-owned text-selection methods are removed in favor of `gpui_base::TextSelection`: ```diff - window.selected_text(cx) + TextSelection::selected_text(window, cx) - window.has_text_selection(cx) + TextSelection::has_selection(window, cx) - root.clear_text_selection(window, cx) - window.clear_text_selection(cx) + TextSelection::clear(window, cx) - window.end_text_selection(cx) + TextSelection::end(window, cx) ``` The remaining Component-owned Root operations are removed in favor of the corresponding `WindowExt` methods: ```diff - root.open_dialog(build, window, cx) + window.open_dialog(cx, build) - root.close_dialog(window, cx) + window.close_dialog(cx) - root.close_all_dialogs(window, cx) + window.close_all_dialogs(cx) - root.open_sheet_at(placement, build, window, cx) + window.open_sheet_at(placement, cx, build) - root.close_sheet(window, cx) + window.close_sheet(cx) - root.push_notification(notification, window, cx) + window.push_notification(notification, cx) - root.remove_notification::<T>(window, cx) + window.remove_notification::<T>(cx) - root.remove_notification1::<T>(key, window, cx) + window.remove_notification1::<T>(key, cx) - root.clear_notifications(window, cx) + window.clear_notifications(cx) ``` ## Test Plan - `cargo test -p gpui-base --lib` — 993 passed. - `cargo test -p gpui-component --lib` — 559 passed. - `cargo test -p gpui-kit --features test-support,component,assets --test root` — 6 passed. - `cargo test -p gpui-kit --features test-support,component,assets --tests` — 114 passed during the window-startup migration. - `cargo test -p gpui-kit --features test-support,component,assets --test rendering` — 2 Metal pixel checks passed. - `cargo clippy -p gpui-base -p gpui-component -p gpui-kit --all-targets --features gpui-kit/test-support -- --deny warnings` — passed. - `cargo check -p gpui-kit --no-default-features` — passed. - `cargo fmt --all --check` — passed. - `git diff --check` — passed. - `script/check-ai-recipes` — 9 published recipe fragments passed. AI-assisted changes prepared with Codex. --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> Co-authored-by: Codex <codex@openai.com> | 6 天前 | |
Bump v0.7.0 | 23 小时前 |