| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
text: Add SelectionFormat::SourceAcrossStyles (#3517) ## Description `SelectionFormat::Source` (#2628) wraps every partial selection in the markup of where it sits. That is consistent, but when the selection stays inside one style the markup is rarely what you want to paste: | Selection | `Source` copies | |---|---| | a word out of `**bold**` | `**word**` | | part of a link | `[part](https://…)` | | two lines of a code block | ```` ```rust … ``` ```` | | a word out of a heading | `## word` | This adds `SelectionFormat::SourceAcrossStyles`. It copies the rendered text while the selection stays within one style, also when it reaches exactly up to the boundaries of a run. It copies the source, like `Source`, as soon as the selection takes in several styles: - text on both sides of a mark boundary (`a **b** c`) - more than one block, list item or table cell (two blocks count as two styles even when their marks match) - an inline object or image The decision reuses the pieces `Source` already collects when it rebuilds the Markdown, so the two always agree on what was selected. `Source` itself is unchanged. Select-all still copies the source verbatim. ## Public API **gpui-base** - `SelectionFormat::SourceAcrossStyles`: new variant. Copies plain text within one style and Markdown source across styles. ## Breaking Changes `SelectionFormat` is not `#[non_exhaustive]`, so code that matches it exhaustively needs an arm for the new variant. ## How to Test - New unit tests in `text/node.rs` (`source_across_styles_*`) cover: - within a mark, up to its boundaries, and across them - a link with and without its surroundings - a single heading, code block and list item - two list items and two paragraphs - an inline object - `cargo test -p gpui-base` passes, and `cargo clippy -p gpui-base -p gpui-component --all-targets -- -D warnings` is clean. - Used in a downstream app (chat transcript with Markdown answers) on top of v0.7.3. ## Checklist - [x] I have read the [CONTRIBUTING](../CONTRIBUTING.md) document and followed the guidelines. - [x] Reviewed the changes in this PR and confirmed AI generated code (If any) is accurate. - [ ] Passed `cargo run` for story tests related to the changes. - [ ] Tested macOS, Windows and Linux platforms performance (if the change is platform-specific) --------- Co-authored-by: Floyd Wang <codelife721@gmail.com> | 11 小时前 | |
setting: Name dropdown, number and text fields after their setting's title (#3582) | 1 天前 | |
webview: Support gpui-pre and make `gpui-fast` optional again (#3591) ## Description Since #3398, `gpui-webview` depends on `gpui-kit` with `features = ["gpui-fast"]`. Through feature unification, every application that depends on `gpui-webview` is moved onto GPUI Fast, so an application that chooses the default gpui-pre backend cannot use a WebView at all. The crate's own `gpui-fast` feature has been a no-op since then. This makes the backend a choice again, and leaves that choice to `gpui-kit`: - `gpui-webview` depends on `gpui-kit` with `default-features = false` and no backend feature. Its `gpui-fast` feature no longer touches `gpui-kit`; it only enables the composition path and the AppKit crates that path uses (`objc2`, `objc2-foundation`). - The two features must agree. `gpui-kit` exports a hidden `GPUI_FAST` constant, and `gpui-webview` asserts `gpui_kit::GPUI_FAST == cfg!(feature = "gpui-fast")` at compile time, with one message per direction: - `gpui-kit/gpui-fast` without `gpui-webview/gpui-fast`: "gpui-kit is built with `gpui-fast`, but gpui-webview is not: enable the `gpui-webview/gpui-fast` feature so the WebView uses GPUI Fast's window composition". - `gpui-webview/gpui-fast` without `gpui-kit/gpui-fast`: "gpui-webview is built with `gpui-fast`, but gpui-kit is not: enable the `gpui-kit/gpui-fast` feature, which selects the GPUI backend". The composition code also reports the GPUI Fast APIs it cannot find in this case; the assertion is listed with those errors. - Window composition on macOS (`composition.rs`) and the Linux composition surface (`NativeWebViewSurface`), including the clipping added in #3499, are behind `#[cfg(feature = "gpui-fast")]`. The macOS `set_theme` helper, which both backends need, moved to `macos.rs`. - Without composition, which means on gpui-pre, or on GPUI Fast when the composition surface cannot be created, the Wry view is a direct child of the GPUI window (AppKit `NSView` on macOS, an X11 child window on Linux, WebView2 on Windows), as it was before #3398. `set_geometry` then gives it the full document bounds even when the clip covers only part of it, so it extends past its container; it is hidden only when it leaves the clip entirely or the application hides it. The previous exact-equality check that hid any partly clipped view is removed. - A failed geometry update (for example a composition surface error) is logged once per WebView when it enters that state, and again only after it has recovered, instead of on every prepaint. - The public API (`WebView::new`, `WebView::build`, `set_bounds`, `set_geometry`, `set_visible`, …) is identical on both backends. - Crates in this repository that use GPUI Fast enable both features: `examples/webview` enables `gpui-kit/gpui-fast` and `gpui-webview/gpui-fast`. `gpui-shell`'s `gpui-fast` feature (which its `webview` feature already selects) now forwards `gpui-kit/gpui-fast` and `gpui-webview?/gpui-fast`; it lists `gpui-kit` as a non-optional dependency because GPUI's macros route their paths through `gpui_kit` whenever a manifest names it, enabled or not. - CI: the workspace lint now includes `gpui-webview` (gpui-pre) and only excludes the example; the GPUI Fast lint and test steps pass `gpui-kit/gpui-fast` and `gpui-webview/gpui-fast`; a new `webview-gpui-pre` job runs `cargo clippy -p gpui-webview --all-targets` on macOS, Linux and Windows. `script/bump-gpui.ts` stops excluding `gpui-webview` from its workspace check. - README, WebView docs (en / zh-CN) and the Shell design note describe both backends. ### Known limitations without composition | Platform | Behavior | | --- | --- | | macOS | WKWebView is attached to the window's view and covers GPUI content in its bounds, including `PopupMenu`, dialogs and tooltips. A partly clipped view, for example in a scrolled region, keeps its full bounds and extends past its container over the neighboring UI. | | Linux (X11 / XWayland) | Same as macOS: the WebKitGTK view lives in a plain X11 child window, covers overlays, and extends past a container that clips it. The X11 requirement, GTK main-loop integration, click forwarding and scale handling are unchanged. Wayland remains unsupported. | | Windows | Unchanged; Windows never used composition. | ## Breaking Changes Applications that relied on `gpui-webview` switching them to GPUI Fast must now select GPUI Fast on `gpui-kit` and enable the WebView feature with it, to keep overlays above the page on macOS and Linux: ```diff [dependencies] -gpui-kit = "0.7" -gpui-webview = "0.7" +gpui-kit = { version = "0.7", features = ["gpui-fast"] } +gpui-webview = { version = "0.7", features = ["gpui-fast"] } ``` Without both they build on gpui-pre; with only one of them, `gpui-webview` fails to compile and names the missing feature. ## Public API ### `gpui-webview` - `gpui-fast` feature: enables native window composition for the WebView on macOS and Linux. It requires `gpui-kit/gpui-fast` and no longer enables it. No longer a no-op; no longer implied by depending on the crate. No `gpui-webview` Rust items were added, removed or changed. ### `gpui-kit` - `#[doc(hidden)] pub const GPUI_FAST: bool` — whether this build selected GPUI Fast. For crates layered on the Kit that keep a backend feature of their own, so they can check at compile time that it matches. ## How to test ```sh # gpui-pre (default) cargo clippy -p gpui-webview --all-targets -- -D warnings cargo test -p gpui-webview cargo tree -p gpui-webview -i gpui-fast # error: did not match any packages # GPUI Fast cargo clippy -p gpui-webview --all-targets --features gpui-fast,gpui-kit/gpui-fast -- -D warnings cargo test -p gpui-webview --features gpui-fast,gpui-kit/gpui-fast cargo tree -p gpui-webview --features gpui-fast -i gpui-fast -e normal # still no match: the feature does not select the backend # Mismatched backends are rejected cargo check -p gpui-webview --features gpui-kit/gpui-fast # E0080, asks for gpui-webview/gpui-fast cargo check -p gpui-webview --features gpui-fast # E0080, asks for gpui-kit/gpui-fast # Consumers cargo clippy -p gpui-webview -p webview -- -D warnings cargo clippy -p gpui-shell --all-targets -- -D warnings cargo check -p gpui-shell --no-default-features --features quickjs,components cargo run -p webview # the "…" menu still renders above the page (GPUI Fast) ``` Every command above except `cargo run` behaves as noted locally on macOS (aarch64). The CI commands that build `gpui-webview` (workspace lint, the GPUI Fast lint and test steps, the new gpui-pre job, `gpui-shell` with and without its default features and with `quickjs,components,gpui-fast`, the Story with and without `gpui-fast`) do not trip the assertion, and `cargo machete`, `cargo fmt --check` and `actionlint` pass. `script/bump-gpui.ts`'s `cargo check --workspace --exclude webview --all-targets` reaches `gpui-webview` without errors; that command already fails on `main` in `gpui-base-examples`, `gpui-base-examples-wasm` and the `gpui-kit-assets` examples, because the default `gpui-shell` features mix the backends across the workspace, and this PR leaves those failures unchanged. The Linux and Windows gpui-pre builds were not compiled locally; the `webview-gpui-pre` CI job covers them. The example was not run in a window for this change, and the overflow of a partly clipped view on gpui-pre was not checked in a real window. --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> | 16 小时前 | |
shell: Add `with_follow_mode` to make a list follow its tail (#3548) Stacked on #3547; only the last commit is new here. ## Description A transcript that is still being written is read at its end: it should open there, stay there as messages are added and as the last one grows, stop following when the reader scrolls up, and follow again when they scroll back down. GPUI's `ListState` does this in `FollowMode::Tail`, but a script's `list` had no way to turn it on, so a chat view had to scroll to the bottom itself after every change. `list(...).with_follow_mode("tail")` sets it on the list's retained state, and `"normal"`, or leaving the call out, sets it back. The mode is set only when it changes, because setting `Tail` scrolls to the end. Stopping and resuming as the reader scrolls is GPUI's behavior. A list that is following is not moved back to the remembered item when its count changes (the anchoring added in #3547): scrolling it to an item would stop it following. A list that is not following, including one whose reader scrolled up, keeps the anchoring. Any other mode throws a `TypeError` at the call site. `uniform_list` and the virtual lists have no follow mode; they log that the call is ignored, and for the virtual lists the log points to `scroll_to_bottom` on their scroll handle. ## Public API ### Script (`gpui-kit.d.ts`, `Element`) ```ts with_follow_mode<Self extends Element>(this: Self, mode: "normal" | "tail"): Self; ``` Honored on `list(...)`. Any other value throws `with_follow_mode(mode) expects "normal" or "tail"`. ## How to Test ```sh cargo test -p gpui-shell --lib -- a_list_following_its_tail a_follow_mode_other ``` - `a_list_following_its_tail_stays_at_the_end_until_the_reader_scrolls_up` draws 100 rows of 20px in a 200px list that follows its tail. It checks that the list opens at the end (`m99` at the bottom), that an appended row is shown at the bottom, and that growing the last row to 60px keeps its end in view. Then it scrolls up 60px and appends: the row being read stays where it was. Then it scrolls back past the end and appends: the new row is at the bottom again. - `a_follow_mode_other_than_normal_or_tail_is_refused` renders `with_follow_mode("bottom")` and checks the error. The first test fails when the `set_follow_mode` call is removed (the list opens at the top, `m9` at the bottom), and when a following list is anchored like any other (the appended row is not shown, `m99` instead of `m1100`). The second fails when the mode check is removed. AI-assisted: written with Claude Code and reviewed by me before submission. ## Checklist - [x] I have read the [CONTRIBUTING](../CONTRIBUTING.md) document and followed the guidelines. - [x] Reviewed the changes in this PR and confirmed AI generated code (If any) is accurate. - [ ] Passed `cargo run` for story tests related to the changes. (No story changes.) - [x] Tested macOS, Windows and Linux platforms performance (if the change is platform-specific). (Not platform-specific.) --------- Co-authored-by: Jason Lee <huacnlee@gmail.com> | 1 天前 |