diff --git a/.agents/skills/ropy-gpui/SKILL.md b/.agents/skills/ropy-gpui/SKILL.md index f0592a4..92e81a6 100644 --- a/.agents/skills/ropy-gpui/SKILL.md +++ b/.agents/skills/ropy-gpui/SKILL.md @@ -9,13 +9,13 @@ Read the official [GPUI Kit skill](../gpui-kit/SKILL.md), and the official [Desi ## Official snapshots -Both official skill directories are unmodified copies of [GPUI Kit v0.8.0](https://github.com/longbridge/gpui-kit/tree/v0.8.0/skills), commit `1676826d9d49b90f4d7b6808b69924f58796f6f1`. Keep all local additions and corrections in this adapter, including changes to links and examples. Do not edit or add files inside either official directory. When upgrading, replace each complete directory from one upstream revision and record the new revision here. +Both official skill directories are unmodified copies of [GPUI Kit v0.8.1](https://github.com/longbridge/gpui-kit/tree/v0.8.1/skills), commit `99576db58ec8103417c41a092e891b4022d24e7e`. Keep all local additions and corrections in this adapter, including changes to links and examples. Do not edit or add files inside either official directory. When upgrading, replace each complete directory from one upstream revision and record the new revision here. To verify against an extracted upstream checkout, run `diff -qr /skills/gpui-kit .agents/skills/gpui-kit` and the equivalent command for `gpui-kit-design-guides`. Both must report no differences. ## Ropy contracts -- Normal and development dependencies use `gpui-kit` 0.8.0, with the default `gpui-pre` 0.3.9 engine. Keep the existing feature set unless the task requires a change. Optional backend entries in Cargo.lock do not imply an active renderer switch. +- Normal and development dependencies use `gpui-kit` 0.8.1, with the default `gpui-pre` 0.3.10 engine. Keep the existing feature set unless the task requires a change. Optional backend entries in Cargo.lock do not imply an active renderer switch. - Localize visible strings and accessible names with existing translation keys where appropriate. The official design guide's English-only accessibility-label exception does not override Ropy's localization convention. - The Coding Guides allow deliberately record-like configuration, theme tokens, geometry and serialized schemas to expose fields with `#[non_exhaustive]` and construction APIs. Follow that detailed rule instead of treating the official entrypoint's abbreviated “No pub fields” statement as an instruction to migrate unrelated types. - `gpui_kit::open_window` installs the window Root and returns the window handle and view entity. Do not mount duplicate dialog, sheet or notification layers. Existing setup is in [window.rs](../../../src/gui/window.rs). @@ -25,7 +25,7 @@ To verify against an extracted upstream checkout, run `diff -qr /skill ## Task-specific references - Before copying low-level examples, read [locked API notes](references/locked-api.md) for callback arity, entity return types, focus and Element lifecycle differences. -- For 0.8.0 adoption and prioritized project opportunities, read [integration notes](references/integration.md). +- For 0.8.1 adoption and prioritized project opportunities, read [integration notes](references/integration.md). - Production-view UI integration tests live in [ui_tests.rs](../../../src/gui/board/ui_tests.rs). Use the official testing reference for the new `TestQueryExt`, `TestEventExt` and `TestInput` APIs, checking signatures in the installed crate. Official site-relative links and diagrams remain unchanged in the upstream copies. Resolve them against `https://gpui-kit.com`; a missing file in Ropy does not authorize inventing a local counterpart. diff --git a/.agents/skills/ropy-gpui/references/integration.md b/.agents/skills/ropy-gpui/references/integration.md index 3f13f9a..a70daec 100644 --- a/.agents/skills/ropy-gpui/references/integration.md +++ b/.agents/skills/ropy-gpui/references/integration.md @@ -1,13 +1,19 @@ -# Ropy integration with GPUI Kit 0.8.0 +# Ropy integration with GPUI Kit 0.8.1 ## Source and refresh policy -Checked against [GPUI Kit v0.8.0](https://github.com/longbridge/gpui-kit/releases/tag/v0.8.0), commit `1676826d9d49b90f4d7b6808b69924f58796f6f1`. The upstream default branch matched this release when checked on 2026-10-19. Normal and development dependencies use 0.8.0; the default engine remains `gpui-pre` 0.3.9. Optional GPUI Fast entries in Cargo.lock do not mean Ropy switched rendering engines. +Checked against [GPUI Kit v0.8.1](https://github.com/longbridge/gpui-kit/releases/tag/v0.8.1), commit `99576db58ec8103417c41a092e891b4022d24e7e`. Normal and development dependencies use 0.8.1; the default engine remains `gpui-pre` 0.3.10. Optional GPUI Fast entries in Cargo.lock do not mean Ropy switched rendering engines. Use the official `gpui-kit` and `gpui-kit-design-guides` skills alongside the `ropy-gpui` adapter for visible UI work. First read the relevant guide sections, then the component family convention, then verify the exact signature in the installed source. Keep Ropy-specific guidance in `ropy-gpui`; replace the two official skill directories only with an unmodified upstream snapshot. Upstream `script/check-ai` commands do not run in this repository. This reference adapts [GPUI Kit documentation](https://gpui-kit.com) under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), adding Ropy-specific scope, verification and recommendations. Code examples retain their upstream Apache-2.0 terms. +## 0.8.1 migration + +Dynamic shortcut loading uses `KeyBinding::load` with the application context. Parsing and formatting use `cx.platform_info().os`; this keeps shortcut validation, recording and display consistent with the runtime host. Static default bindings use string literals. The input-blocking promotion overlay uses the renamed `on_scroll` handler. + +The official skill directories in v0.8.1 are byte-for-byte identical to v0.8.0. Their recorded source revision still advances with the dependency. Existing UI integration tests cover shortcut editing, persistence and focus; host-parameterized binding tests cover `secondary` normalization and conflicts on macOS, Windows and Linux. + ## Adopted integration - `Slider::accessibility_label` names the opacity slider and each RGB channel using existing localized labels. The settings UI integration test queries the opacity label through `TestQueryExt` and checks that it identifies a slider. diff --git a/.agents/skills/ropy-gpui/references/locked-api.md b/.agents/skills/ropy-gpui/references/locked-api.md index 98ab947..960a91a 100644 --- a/.agents/skills/ropy-gpui/references/locked-api.md +++ b/.agents/skills/ropy-gpui/references/locked-api.md @@ -1,10 +1,14 @@ # Locked API notes -These notes preserve Ropy's verified corrections for `gpui-kit` 0.8.0 and its default `gpui-pre` 0.3.9 engine. Read the installed source before using an upstream example with a conflicting signature. This is a compatibility note, not another framework manual. +These notes preserve Ropy's verified corrections for `gpui-kit` 0.8.1 and its default `gpui-pre` 0.3.10 engine. Read the installed source before using an upstream example with a conflicting signature. This is a compatibility note, not another framework manual. + +## Keyboard and scroll APIs + +`KeyBinding::new` and `Keystroke::parse` require static strings with explicit modifiers. Use `KeyBinding::load(..., cx)` for configuration strings and `Keystroke::parse_with_os(source, cx.platform_info().os)` for dynamic parsing. `Keystroke::unparse` takes the host operating system; do not infer it from the compilation target. The `secondary` modifier resolves from that runtime host. `InteractiveElement::on_scroll` replaces the deprecated `on_scroll_wheel`. ## Contexts and async work -The [Context source](https://docs.rs/crate/gpui-pre/0.3.9/source/src/app/context.rs) defines these callbacks: +The [Context source](https://docs.rs/crate/gpui-pre/0.3.10/source/src/app/context.rs) defines these callbacks: | Receiver and operation | Callback arguments | | --- | --- | @@ -20,18 +24,18 @@ The [Context source](https://docs.rs/crate/gpui-pre/0.3.9/source/src/app/context `Entity::update` returns the closure result directly. `WeakEntity::update` and `update_in` return a synchronous Result; do not await them. `WeakEntity::upgrade` returns Option. Await I/O or background Tasks, then update the owner. There is no `Task::then` continuation API in this engine. Retain cancellable Tasks and Subscriptions on their owner; detach only for an intentional independent lifetime. -`Context::defer_in` already borrows the owner mutably. Use the supplied `&mut T`; accessing the same entity through another handle re-enters its borrow. See the [entity source](https://docs.rs/crate/gpui-pre/0.3.9/source/src/app/entity_map.rs). +`Context::defer_in` already borrows the owner mutably. Use the supplied `&mut T`; accessing the same entity through another handle re-enters its borrow. See the [entity source](https://docs.rs/crate/gpui-pre/0.3.10/source/src/app/entity_map.rs). ## Global state and focus `set_global`, `global_mut` and completion of `update_global` queue observer notifications; manually broadcasting a second notification is unnecessary. Mutating data behind a shared lock does not invoke those hooks. `Global` does not require Clone. Use `Theme::update` to synchronize theme colors, renderable tokens and the Base projection. -Focus queries take a Window: `handle.is_focused(window)`. Native activation is `window.is_window_active()`. Create retained handles with `cx.focus_handle().tab_stop(true)` when they belong in Tab order; `track_focus` does not add a tab stop by itself. Focus subscriptions (`on_focus`, `on_blur`, `on_focus_in`, `on_focus_out`) are Context methods, not div builders. Bind keys before setting native menus. See the [Window source](https://docs.rs/crate/gpui-pre/0.3.9/source/src/window.rs). +Focus queries take a Window: `handle.is_focused(window)`. Native activation is `window.is_window_active()`. Create retained handles with `cx.focus_handle().tab_stop(true)` when they belong in Tab order; `track_focus` does not add a tab stop by itself. Focus subscriptions (`on_focus`, `on_blur`, `on_focus_in`, `on_focus_out`) are Context methods, not div builders. Bind keys before setting native menus. See the [Window source](https://docs.rs/crate/gpui-pre/0.3.10/source/src/window.rs). ## Elements and component constructors -`Element` has two associated states, `RequestLayoutState` and `PrepaintState`; its trait methods differ from type-erased `AnyElement` helpers. `AnyElement::request_layout(window, cx)` returns a LayoutId, `prepaint(window, cx)` returns an optional FocusHandle, and `paint(window, cx)` returns unit. Do not pass Element trait IDs, bounds or state arguments to those wrapper helpers. See the [Element source](https://docs.rs/crate/gpui-pre/0.3.9/source/src/element.rs). +`Element` has two associated states, `RequestLayoutState` and `PrepaintState`; its trait methods differ from type-erased `AnyElement` helpers. `AnyElement::request_layout(window, cx)` returns a LayoutId, `prepaint(window, cx)` returns an optional FocusHandle, and `paint(window, cx)` returns unit. Do not pass Element trait IDs, bounds or state arguments to those wrapper helpers. See the [Element source](https://docs.rs/crate/gpui-pre/0.3.10/source/src/element.rs). `Window::with_element_state` receives a GlobalElementId and a closure mapping `Option` to `(result, S)`. Element fields do not establish persistent application state. Register hitboxes in prepaint and input handlers in paint; the latter capture owned data or handles, not a temporary `&mut self`. -`Input::new` and `Select::new` receive retained state entities, not string IDs. `Tab::new()` takes no ID argument. `h_flex()` centers on the cross axis; `v_flex()` retains stretch behavior. Full-height columns inside rows may need explicit height or stretch. Verify constructors in the [0.8.0 component source](https://github.com/longbridge/gpui-kit/tree/1676826d9d49b90f4d7b6808b69924f58796f6f1/crates/component/src). +`Input::new` and `Select::new` receive retained state entities, not string IDs. `Tab::new()` takes no ID argument. `h_flex()` centers on the cross axis; `v_flex()` retains stretch behavior. Full-height columns inside rows may need explicit height or stretch. Verify constructors in the [0.8.1 component source](https://github.com/longbridge/gpui-kit/tree/99576db58ec8103417c41a092e891b4022d24e7e/crates/component/src). diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 06592f7..7cf1722 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -56,7 +56,7 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: persist-credentials: false submodules: recursive @@ -116,7 +116,7 @@ jobs: - name: enable windows longpaths run: | git config --global core.longpaths true - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: persist-credentials: false submodules: recursive @@ -195,7 +195,7 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: persist-credentials: false submodules: recursive @@ -258,7 +258,7 @@ jobs: outputs: val: ${{ steps.host.outputs.manifest }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: persist-credentials: false submodules: recursive @@ -323,7 +323,7 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: persist-credentials: false submodules: recursive diff --git a/Cargo.lock b/Cargo.lock index 01e4b33..90eb447 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -586,15 +586,6 @@ version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" -[[package]] -name = "bit-set" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ddef2995421ab6a5c779542c81ee77c115206f4ad9d5a8e05f4ff49716a3dd" -dependencies = [ - "bit-vec 0.9.1", -] - [[package]] name = "bit-set" version = "0.10.0" @@ -1018,7 +1009,7 @@ checksum = "f6140449f97a6e97f9511815c5632d84c8aacf8ac271ad77c559218161a1373c" dependencies = [ "bitflags 1.3.2", "block", - "cocoa-foundation 0.1.2", + "cocoa-foundation", "core-foundation 0.9.4", "core-graphics 0.23.2", "foreign-types", @@ -1026,22 +1017,6 @@ dependencies = [ "objc", ] -[[package]] -name = "cocoa" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f79398230a6e2c08f5c9760610eb6924b52aa9e7950a619602baba59dcbbdbb2" -dependencies = [ - "bitflags 2.13.2", - "block", - "cocoa-foundation 0.2.1", - "core-foundation 0.10.1", - "core-graphics 0.24.0", - "foreign-types", - "libc", - "objc", -] - [[package]] name = "cocoa-foundation" version = "0.1.2" @@ -1056,19 +1031,6 @@ dependencies = [ "objc", ] -[[package]] -name = "cocoa-foundation" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81411967c50ee9a1fc11365f8c585f863a22a9697c89239c452292c40ba79b0d" -dependencies = [ - "bitflags 2.13.2", - "block", - "core-foundation 0.10.1", - "core-graphics-types 0.2.0", - "objc", -] - [[package]] name = "codespan-reporting" version = "0.13.1" @@ -2391,31 +2353,11 @@ dependencies = [ "windows 0.62.2", ] -[[package]] -name = "gpu-descriptor" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" -dependencies = [ - "bitflags 2.13.2", - "gpu-descriptor-types", - "hashbrown 0.15.5", -] - -[[package]] -name = "gpu-descriptor-types" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" -dependencies = [ - "bitflags 2.13.2", -] - [[package]] name = "gpui-base" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5cd7de73d5b2d3d18b94a928abf343922091fa77bc472f77b7d2e7e8b1823a7" +checksum = "d862bc8f2e27710039013d075ac4995892e9687ff207fa530f880cbcd513936f" dependencies = [ "aho-corasick", "anyhow", @@ -2455,9 +2397,9 @@ dependencies = [ [[package]] name = "gpui-component" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4097e161cc81e86323b439664be0cdd4f7c56148e867ed6f67fd72b966b6c2d1" +checksum = "46ce53430332e30f303364eaabfa10ed2aa23dfaf2a147e04370e0e9c423578b" dependencies = [ "anyhow", "chrono", @@ -2503,9 +2445,9 @@ dependencies = [ [[package]] name = "gpui-component-macros" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b98496748463b60ad69eab80cd91fc9b3807fed9a0e01ab4d5c159c949fd814" +checksum = "a512c830553e7dddc43c3f8faffc2d2d7bd24db21fe3dc1326dde9c470013768" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -2515,9 +2457,9 @@ dependencies = [ [[package]] name = "gpui-fast" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f539554aee0e994d84014d99e85f3923db613a62a94f248a6559e628bbb0b0be" +checksum = "87b6d2f355531132e8f1ec357cb23901aba1d1b3e522260822ae199f02ec32da" dependencies = [ "accesskit", "anyhow", @@ -2570,7 +2512,7 @@ dependencies = [ "smallvec", "spin 0.10.1", "strum", - "taffy 0.14.0", + "taffy", "thiserror 2.0.21", "ttf-parser", "url", @@ -2584,9 +2526,9 @@ dependencies = [ [[package]] name = "gpui-fast-apple" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd2f932eea173f357ace60f2267cd0c8031123fc788160b61f8566efe51f6bd0" +checksum = "c5f0aff0a75a63953782a609bf023c68cdb71c3dbd74478223db9bbd1b744795" dependencies = [ "anyhow", "async-task", @@ -2626,9 +2568,9 @@ dependencies = [ [[package]] name = "gpui-fast-linux" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f41024ac6447667ddb55d23dd897acc714f1d4ed74214b34144f320458de879f" +checksum = "8d5a4351392d339049584e06a58460a4907a060e3f46e49b7c130d80ffe36871" dependencies = [ "accesskit", "accesskit_unix", @@ -2671,15 +2613,14 @@ dependencies = [ [[package]] name = "gpui-fast-macos" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c9656cc924a624ebbc44bb9f8149f5206fe6e94b262349f662efe692e03d900" +checksum = "d8e8b377d6dcbc0007e68098cb3f40bc2591a1d29526301e9572a70bb674f171" dependencies = [ "accesskit", "accesskit_macos", "anyhow", "block2 0.6.2", - "cocoa 0.26.0", "core-foundation 0.10.1", "core-foundation-sys", "core-graphics 0.24.0", @@ -2695,9 +2636,9 @@ dependencies = [ "image", "itertools 0.14.0", "log", - "objc", "objc2 0.6.5", "objc2-app-kit 0.3.2", + "objc2-core-graphics", "objc2-core-video", "objc2-foundation 0.3.2", "objc2-user-notifications", @@ -2711,9 +2652,9 @@ dependencies = [ [[package]] name = "gpui-fast-macros" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce9b7a528e074c62bf71f05d886d6c8db88d567de2ccd8ab3d228ea2a6f6711" +checksum = "e07e9e22196a84bb8cb06c19fc6e5d2218fa11d6b573f914f423970a1b38c97e" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -2723,9 +2664,9 @@ dependencies = [ [[package]] name = "gpui-fast-platform" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a7f82c182e1c0f1b0cc0d28493e2f7dc1c00bc7b57e581b33502b1154bc5a0" +checksum = "7c4b2959631b713899ae6d58236a0ac7c7e404a6cd8c16f30822177eb90a5b59" dependencies = [ "anyhow", "console_error_panic_hook", @@ -2740,9 +2681,9 @@ dependencies = [ [[package]] name = "gpui-fast-web" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44dac167a7e6c1d43a836df0f7e4cf1db6b3a843ec95653d26b1df2a88d52a74" +checksum = "ad903fddb78ae4c8f1c24b7fa07c79a0697da7614183d8c7dad67bd296802901" dependencies = [ "anyhow", "async-channel", @@ -2770,9 +2711,9 @@ dependencies = [ [[package]] name = "gpui-fast-wgpu" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cac7d34083b2611b49b2f415a16aa9e33620b127a25e981f835db8fe72f07423" +checksum = "ebf72d3c1fee16dde347707ef306940d39656f80e35d3aaace01075996f12199" dependencies = [ "anyhow", "bytemuck", @@ -2792,15 +2733,15 @@ dependencies = [ "unicode-bidi", "unicode-segmentation", "web-sys", - "wgpu 30.0.1", + "wgpu", "zed-font-kit", ] [[package]] name = "gpui-fast-windows" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f034e131f83ff84b67f009cde41e0cbecb3be09d7ebba7c548ea78fe0fdee5b0" +checksum = "6a1a193343ef7faaa18eb9ccc0aadf8ec9571f2791c4419c2ca23aa17198f970" dependencies = [ "accesskit", "accesskit_windows", @@ -2828,9 +2769,9 @@ dependencies = [ [[package]] name = "gpui-kit" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cdcb78553bef8785669e572e79759b0eab47fdd9d318fe0cce1def798189432" +checksum = "25210f6e59ea9ffac3a033dbce9edafe5ff0dd2900f894fd1316f54da2fe2b89" dependencies = [ "gpui-base", "gpui-component", @@ -2845,9 +2786,9 @@ dependencies = [ [[package]] name = "gpui-kit-assets" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b037e2fa43d53a567a8aa5be6b1a8931f416cbd010ceee8d4a3727a71e9b1d05" +checksum = "c214017b45e5654665f18faa551f58a2c2c8d25efe6632b1a443ba8edf365e96" dependencies = [ "anyhow", "gpui-pre", @@ -2860,9 +2801,9 @@ dependencies = [ [[package]] name = "gpui-pre" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34f61c1cfd36fc9c436af09308c963822ae27a45a84feb21a77ba5c9e051f1c0" +checksum = "df4b5f8d0c278308df2f11e0bfe0212dd77d7848ce1bdc4b9d513334414396f6" dependencies = [ "accesskit", "anyhow", @@ -2915,7 +2856,7 @@ dependencies = [ "smallvec", "spin 0.10.1", "strum", - "taffy 0.13.0", + "taffy", "thiserror 2.0.21", "ttf-parser", "url", @@ -2929,9 +2870,9 @@ dependencies = [ [[package]] name = "gpui-pre-apple" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b52f58893fe1a0836464428dfad2b5eaf42c9c303a9638f4c2aced5a69072a15" +checksum = "e97cd068d8134b4e073321b946491760aa1e4511e486084a92e73b9174bff78a" dependencies = [ "anyhow", "async-task", @@ -2971,9 +2912,9 @@ dependencies = [ [[package]] name = "gpui-pre-collections" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "920c2f5b2f1a7813114d89f4841f26f6060d9c35d7c8a852a4205d1a767a7ce0" +checksum = "8f89bf8941a7437dd761161c552543fb8268b9633fe74e29eafbe0014cd2164b" dependencies = [ "gpui-pre-util", "indexmap", @@ -2982,9 +2923,9 @@ dependencies = [ [[package]] name = "gpui-pre-derive-refineable" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "947395f26228296c0c79fb889d3687b205e552c25bbcdece216fb2394ea9bcd1" +checksum = "2998b1cebbaa0fa004fe4939a513bbf4103c7fb69ae2e84ee73634554e3f7edc" dependencies = [ "proc-macro2", "quote", @@ -2993,9 +2934,9 @@ dependencies = [ [[package]] name = "gpui-pre-http-client" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56cdaa3f1a271162b7fede1d4557879eedb056e293cedbb82743600650b755e" +checksum = "e516820ee56ac357a87ff97b1a2c5f22c8d5dcd2a50cdd15c16949f24464d98e" dependencies = [ "anyhow", "bytes", @@ -3012,9 +2953,9 @@ dependencies = [ [[package]] name = "gpui-pre-ios" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e735b73ae85ed188764287df4d24837045d71a122c51c2264aed8c38ffd51b" +checksum = "5773a1e3a399df64f3ecc5538727fd0575279bd190959cf97a9e2b698c0310b8" dependencies = [ "anyhow", "block2 0.6.2", @@ -3034,9 +2975,9 @@ dependencies = [ [[package]] name = "gpui-pre-linux" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28213c3fde6f13e91ba0b74b90cbaadec9373e36a031eda98561d31059870f3" +checksum = "7c6ffd2dce7b75cce0bb3382994912f84c2a05389a4a236bb8bd72cb098fc083" dependencies = [ "accesskit", "accesskit_unix", @@ -3079,15 +3020,14 @@ dependencies = [ [[package]] name = "gpui-pre-macos" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c988b7e49775cc8542dbe48d5a10e073d8e898a023ef3ff3d24f33363e9863" +checksum = "7e07a5e5c84f0b2160c194a1c852cc89d1942db66867938ceabcd7f763cb4386" dependencies = [ "accesskit", "accesskit_macos", "anyhow", "block2 0.6.2", - "cocoa 0.26.0", "core-foundation 0.10.1", "core-foundation-sys", "core-graphics 0.24.0", @@ -3103,9 +3043,9 @@ dependencies = [ "image", "itertools 0.14.0", "log", - "objc", "objc2 0.6.5", "objc2-app-kit 0.3.2", + "objc2-core-graphics", "objc2-core-video", "objc2-foundation 0.3.2", "objc2-user-notifications", @@ -3119,9 +3059,9 @@ dependencies = [ [[package]] name = "gpui-pre-macros" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb80dac5e1f6b8cde1d2740389e77dfc0071bfcc81fba5526d5dc90f68171cc" +checksum = "9c95d70a9fe10701533606c6135f9a1d4cd96e87e4e6062b3d426eb57b415daf" dependencies = [ "heck 0.5.0", "proc-macro-crate", @@ -3132,13 +3072,14 @@ dependencies = [ [[package]] name = "gpui-pre-platform" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbdbdac421178313fed8929fe95b42634a266a735079fcf03ff231bc2ccb2c5e" +checksum = "e8a7f07a15187e82ec76491492c7e3245db1b59633d3bedb00b828ffaf67c4b8" dependencies = [ "anyhow", "console_error_panic_hook", "gpui-pre", + "gpui-pre-ios", "gpui-pre-linux", "gpui-pre-macos", "gpui-pre-web", @@ -3148,9 +3089,9 @@ dependencies = [ [[package]] name = "gpui-pre-refineable" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "237703b3b219d11adb50dd33bb0fcca3d34fc001623b3143e72cb051d0fb3777" +checksum = "4ce7e83592bc6c1ead2affd91b333f11b60c3eb7d06cae1605dd56f149fe8674" dependencies = [ "gpui-pre-derive-refineable", ] @@ -3207,9 +3148,9 @@ dependencies = [ [[package]] name = "gpui-pre-scheduler" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83f342555282a59ed8dd58dd7e0a920524fa8ef6aa8c8f30e2edb7019a8f72cb" +checksum = "87c2c6b0fabcd20e6773a0be30afa1f25637c53a06201bb80ab24a21fe198865" dependencies = [ "async-task", "backtrace", @@ -3224,9 +3165,9 @@ dependencies = [ [[package]] name = "gpui-pre-shared-string" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71f488bf4780735f6b2dad24f8db1e3d9e2593de0ec298e3574c788f571b81c4" +checksum = "8068f94355f173558a51998a32985a434af54cc6c7262a060fffc369a505998f" dependencies = [ "schemars", "serde", @@ -3235,9 +3176,9 @@ dependencies = [ [[package]] name = "gpui-pre-sum-tree" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aadb3bd3da22617e2158b1842f5a9c29c1626c926ad0686163ced1a009963ff3" +checksum = "c1ce66c57e9b5fd6c7a90fa9f9de2f9bb342127d670ca3c8fe5885270079eefa" dependencies = [ "gpui-pre-ztracing", "heapless", @@ -3247,9 +3188,9 @@ dependencies = [ [[package]] name = "gpui-pre-util" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a04ec9abd7a87ac05a221f4629403831c44c17123bc33cb5d271a6303259b340" +checksum = "162dc29b2d2c0223ee4bb4e9f5e913eab4f62cad0943eb0c1122a74ac82b0768" dependencies = [ "anyhow", "log", @@ -3258,9 +3199,9 @@ dependencies = [ [[package]] name = "gpui-pre-web" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aedd55b99dc77e28df8202b0ea868aa5c90fda4aefff539ea21087d7c2ff4bfb" +checksum = "1acd86af2347f0dd8b63c441a5dbd43b3fcd7dac69b340827c3497da5a13d6fb" dependencies = [ "anyhow", "async-channel", @@ -3288,9 +3229,9 @@ dependencies = [ [[package]] name = "gpui-pre-wgpu" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b1cdb26c1503bf9662ee8fbc5ab0b44b2deeee4b5c12dc67491ba6fb5fc544b" +checksum = "ce693915768aae38bf788f245af75aae78e3e1179245860fc80ce831d0a8f74e" dependencies = [ "anyhow", "bytemuck", @@ -3310,15 +3251,15 @@ dependencies = [ "unicode-bidi", "unicode-segmentation", "web-sys", - "wgpu 29.0.4", + "wgpu", "zed-font-kit", ] [[package]] name = "gpui-pre-windows" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "513d4f0fc7d596d3bdef2a73a524ffb83dabc95bf484f2855a698e7f431290a9" +checksum = "80670f987b920fba019917b2e222ecf2b377f2a6d77872010c7d284c235837b3" dependencies = [ "accesskit", "accesskit_windows", @@ -3346,9 +3287,9 @@ dependencies = [ [[package]] name = "gpui-pre-ztracing" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17bfd6bd1f77ba5c58181fa6f82fc7a63015a1c58bef94a76e5acb9f8e42572" +checksum = "814cc08c526961c88703806a68ba4cf216a1d988ffbbdc673304f4dd25858952" dependencies = [ "gpui-pre-ztracing-macro", "tracing", @@ -3356,9 +3297,9 @@ dependencies = [ [[package]] name = "gpui-pre-ztracing-macro" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b0d73e1bc02eef886a5947f41b8512708792e9e5d3053d181843311a487f96f" +checksum = "e0f9dae92b9bc15baa6e530c90bdd4c689d3710bd4d18c3566deb1d6ae182daf" [[package]] name = "granit-parser" @@ -3492,12 +3433,6 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[package]] -name = "hexf-parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" - [[package]] name = "hkdf" version = "0.12.4" @@ -4519,32 +4454,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "743fb55ba31b18fb1ecef6bdc9aa2743314978ac084044301a7eee33fb99a20d" -[[package]] -name = "naga" -version = "29.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2bf919621e7975acb27d881bae2fb993e0d45c8e0446e85e6272971e00dc8df" -dependencies = [ - "arrayvec", - "bit-set 0.9.1", - "bitflags 2.13.2", - "cfg-if", - "cfg_aliases", - "codespan-reporting", - "half", - "hashbrown 0.16.1", - "hexf-parse", - "indexmap", - "libm", - "log", - "num-traits", - "once_cell", - "rustc-hash 1.1.0", - "spirv", - "thiserror 2.0.21", - "unicode-ident", -] - [[package]] name = "naga" version = "30.0.1" @@ -7301,23 +7210,10 @@ dependencies = [ [[package]] name = "taffy" -version = "0.13.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c034e05f6ee85a12daa63863c2245797715075c70649947aa0da54f3f2ab1d0f" +checksum = "3c8480887e8803986d96a7173729565520d4bbb721ad6b7ad6941a22897207aa" dependencies = [ - "arrayvec", - "serde", - "slotmap", - "smallvec", -] - -[[package]] -name = "taffy" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "639627c87f43b9181c811f40a6296409e093a17bc761214cba3c15df74f86b99" -dependencies = [ - "arrayvec", "serde", "slotmap", "smallvec", @@ -8383,36 +8279,6 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" -[[package]] -name = "wgpu" -version = "29.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76e8840e1ba2881d4cbb18d2147627a56af426ff064c0401eb0c8410c6325d07" -dependencies = [ - "arrayvec", - "bitflags 2.13.2", - "bytemuck", - "cfg-if", - "cfg_aliases", - "document-features", - "hashbrown 0.16.1", - "js-sys", - "log", - "naga 29.0.4", - "parking_lot", - "portable-atomic", - "profiling", - "raw-window-handle", - "smallvec", - "static_assertions", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "wgpu-core 29.0.4", - "wgpu-hal 29.0.4", - "wgpu-types 29.0.4", -] - [[package]] name = "wgpu" version = "30.0.1" @@ -8428,7 +8294,7 @@ dependencies = [ "hashbrown 0.17.1", "js-sys", "log", - "naga 30.0.1", + "naga", "parking_lot", "portable-atomic", "profiling", @@ -8438,43 +8304,9 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "wgpu-core 30.0.1", - "wgpu-hal 30.0.1", - "wgpu-types 30.0.1", -] - -[[package]] -name = "wgpu-core" -version = "29.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f519832254e56965a9940c4af57dcb75f702b6f6fa4a0b172f685395843a4d7" -dependencies = [ - "arrayvec", - "bit-set 0.9.1", - "bit-vec 0.9.1", - "bitflags 2.13.2", - "bytemuck", - "cfg_aliases", - "document-features", - "hashbrown 0.16.1", - "indexmap", - "log", - "naga 29.0.4", - "once_cell", - "parking_lot", - "portable-atomic", - "profiling", - "raw-window-handle", - "rustc-hash 1.1.0", - "smallvec", - "thiserror 2.0.21", - "wgpu-core-deps-apple 29.0.4", - "wgpu-core-deps-emscripten 29.0.4", - "wgpu-core-deps-wasm 29.0.4", - "wgpu-core-deps-windows-linux-android 29.0.4", - "wgpu-hal 29.0.4", - "wgpu-naga-bridge 29.0.4", - "wgpu-types 29.0.4", + "wgpu-core", + "wgpu-hal", + "wgpu-types", ] [[package]] @@ -8493,7 +8325,7 @@ dependencies = [ "hashbrown 0.17.1", "indexmap", "log", - "naga 30.0.1", + "naga", "naga-types", "once_cell", "parking_lot", @@ -8503,22 +8335,13 @@ dependencies = [ "rustc-hash 1.1.0", "smallvec", "thiserror 2.0.21", - "wgpu-core-deps-apple 30.0.1", - "wgpu-core-deps-emscripten 30.0.1", - "wgpu-core-deps-wasm 30.0.1", - "wgpu-core-deps-windows-linux-android 30.0.1", - "wgpu-hal 30.0.1", - "wgpu-naga-bridge 30.0.1", - "wgpu-types 30.0.1", -] - -[[package]] -name = "wgpu-core-deps-apple" -version = "29.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5e39e26c4c0e07589e67d18546cf79ff45383659fc72fca4dd293358a0347f3" -dependencies = [ - "wgpu-hal 29.0.4", + "wgpu-core-deps-apple", + "wgpu-core-deps-emscripten", + "wgpu-core-deps-wasm", + "wgpu-core-deps-windows-linux-android", + "wgpu-hal", + "wgpu-naga-bridge", + "wgpu-types", ] [[package]] @@ -8527,16 +8350,7 @@ version = "30.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "061f3d319a40d39d00b1ecc2c33b89fe21d4e6fe01859df3500a3a8ecccd6b68" dependencies = [ - "wgpu-hal 30.0.1", -] - -[[package]] -name = "wgpu-core-deps-emscripten" -version = "29.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01e09be551dc939498bdd5f6b2c66e55ab275dad25825267a08605a80fc9f0af" -dependencies = [ - "wgpu-hal 29.0.4", + "wgpu-hal", ] [[package]] @@ -8545,16 +8359,7 @@ version = "30.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d98b86cf4abf524a902dd35f18ca6a3f08fc2ae9847c8f10b48e30491b1f0b86" dependencies = [ - "wgpu-hal 30.0.1", -] - -[[package]] -name = "wgpu-core-deps-wasm" -version = "29.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1fb1798be2a912497d4c224f72d39bb0cb34af50e8bcc29865bc339c943059" -dependencies = [ - "wgpu-hal 29.0.4", + "wgpu-hal", ] [[package]] @@ -8563,16 +8368,7 @@ version = "30.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d260ca2ca8adc654f513a869bf3cac0b47f5b8d3f87803d6942015f8de597aae" dependencies = [ - "wgpu-hal 30.0.1", -] - -[[package]] -name = "wgpu-core-deps-windows-linux-android" -version = "29.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e592c1bbef6ad047647ae6e666ebd8cee7a32bb4544d9700ec96cbf73230257" -dependencies = [ - "wgpu-hal 29.0.4", + "wgpu-hal", ] [[package]] @@ -8581,61 +8377,7 @@ version = "30.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7586165fd5f6d881cb9ce4bb71f40d6caab2c0f1837e3fc1d9788a197fb6004f" dependencies = [ - "wgpu-hal 30.0.1", -] - -[[package]] -name = "wgpu-hal" -version = "29.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97ace1c17727311c22a46e4e3faf56ea6de81af99dcc839bdfb54857b94d448d" -dependencies = [ - "android_system_properties", - "arrayvec", - "ash", - "bit-set 0.9.1", - "bitflags 2.13.2", - "block2 0.6.2", - "bytemuck", - "cfg-if", - "cfg_aliases", - "glow", - "glutin_wgl_sys", - "gpu-allocator", - "gpu-descriptor", - "hashbrown 0.16.1", - "js-sys", - "khronos-egl", - "libc", - "libloading", - "log", - "naga 29.0.4", - "ndk-sys", - "objc2 0.6.5", - "objc2-core-foundation", - "objc2-foundation 0.3.2", - "objc2-metal 0.3.2", - "objc2-quartz-core 0.3.2", - "once_cell", - "ordered-float", - "parking_lot", - "portable-atomic", - "portable-atomic-util", - "profiling", - "range-alloc", - "raw-window-handle", - "raw-window-metal", - "renderdoc-sys", - "smallvec", - "thiserror 2.0.21", - "wasm-bindgen", - "wayland-sys", - "web-sys", - "wgpu-naga-bridge 29.0.4", - "wgpu-types 29.0.4", - "windows 0.62.2", - "windows-core 0.62.2", - "windows-result 0.4.1", + "wgpu-hal", ] [[package]] @@ -8662,7 +8404,7 @@ dependencies = [ "libc", "libloading", "log", - "naga 30.0.1", + "naga", "naga-types", "ndk-sys", "objc2 0.6.5", @@ -8687,45 +8429,21 @@ dependencies = [ "wasm-bindgen", "wayland-sys", "web-sys", - "wgpu-naga-bridge 30.0.1", - "wgpu-types 30.0.1", + "wgpu-naga-bridge", + "wgpu-types", "windows 0.62.2", "windows-core 0.62.2", "windows-result 0.4.1", ] -[[package]] -name = "wgpu-naga-bridge" -version = "29.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95226013f547544b223281cd16a4fb549aa9dcb562adbda0faae4c73ffbbc161" -dependencies = [ - "naga 29.0.4", - "wgpu-types 29.0.4", -] - [[package]] name = "wgpu-naga-bridge" version = "30.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2f62e73117bb7a62bfd9c5a5841438a823f6566c6442a808ee269d2d055c081" dependencies = [ - "naga 30.0.1", - "wgpu-types 30.0.1", -] - -[[package]] -name = "wgpu-types" -version = "29.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84bf84cd9ca8ca45e2b223a3868f1adf9bfc0c66aeac212e76ee7e40fdadf8f5" -dependencies = [ - "bitflags 2.13.2", - "bytemuck", - "js-sys", - "log", - "raw-window-handle", - "web-sys", + "naga", + "wgpu-types", ] [[package]] @@ -9841,7 +9559,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6b338d705ae33a43ca00287c11129303a7a0aa57b101b72a1c08c863f698ac8" dependencies = [ "anyhow", - "cocoa 0.25.0", + "cocoa", "core-graphics-helmer-fork", "log", "objc", diff --git a/Cargo.toml b/Cargo.toml index f09972c..17e839b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ publish = false [dependencies] ropy-core = { path = "crates/ropy-core" } clipboard-rs = "0.3.5" -gpui-kit = { version = "0.8.0", default-features = false, features = ["component", "assets"] } +gpui-kit = { version = "0.8.1", default-features = false, features = ["component", "assets"] } global-hotkey = "0.9.0" serde.workspace = true serde_json.workspace = true @@ -92,7 +92,7 @@ image = { version = "0.25.10", default-features = false, features = [ [dev-dependencies] ropy-core = { path = "crates/ropy-core", features = ["test"] } -gpui-kit = { version = "0.8.0", default-features = false, features = ["component", "test-support"] } +gpui-kit = { version = "0.8.1", default-features = false, features = ["component", "test-support"] } rstest.workspace = true [lints] diff --git a/dist-workspace.toml b/dist-workspace.toml index f3bdbde..d465e3e 100644 --- a/dist-workspace.toml +++ b/dist-workspace.toml @@ -21,6 +21,10 @@ github-build-setup = "../dist-build-setup.yml" github-custom-job-permissions = { "release-update-manifest" = { contents = "read", actions = "read" } } global-artifacts-jobs = ["./release-update-manifest"] +# Keep generated release checkout aligned with the other workflows. +[dist.github-action-commits] +"actions/checkout" = "v7" + [dist.dependencies.apt] pkg-config = "*" libxdo-dev = "*" diff --git a/src/gui/board/actions/shortcuts.rs b/src/gui/board/actions/shortcuts.rs index bf15828..3701b53 100644 --- a/src/gui/board/actions/shortcuts.rs +++ b/src/gui/board/actions/shortcuts.rs @@ -1,5 +1,5 @@ use gpui_kit::{ - Action, App, AsKeystroke, DummyKeyboardMapper, Global, KeyBinding, KeyContext, SharedString, + Action, App, AsKeystroke, Global, KeyBinding, KeyContext, OperatingSystem, SharedString, }; use rust_i18n::t; use thiserror::Error; @@ -41,8 +41,8 @@ impl HistoryShortcut { label: impl Into, group: ShortcutGroup, action: impl Action + Clone, - primary: &str, - aliases: &[&str], + primary: &'static str, + aliases: &[&'static str], ) -> Self { let aliases = aliases .iter() @@ -57,10 +57,10 @@ impl HistoryShortcut { } } - pub(crate) fn default_keys(&self) -> Vec { + pub(crate) fn default_keys(&self, os: OperatingSystem) -> Vec { std::iter::once(&self.primary) .chain(&self.aliases) - .map(|binding| binding.keystrokes()[0].as_keystroke().unparse()) + .map(|binding| binding.keystrokes()[0].as_keystroke().unparse(os)) .collect() } } @@ -187,13 +187,14 @@ pub(crate) fn history_shortcuts() -> Vec { &[], ), ]; - shortcuts.extend((0..QUICK_SELECT_COUNT).map(|index| { + let quick_keys: [&str; QUICK_SELECT_COUNT] = ["1", "2", "3", "4", "5"]; + shortcuts.extend(quick_keys.into_iter().enumerate().map(|(index, key)| { HistoryShortcut::new( format!("confirm_record_{}", index + 1), t!("shortcuts_quick_select", index = index + 1), QuickSelection, ConfirmRecord { index }, - &(index + 1).to_string(), + key, &[], ) })); @@ -317,6 +318,7 @@ fn supported_key(key: &str) -> bool { pub(crate) fn compile_history_bindings( settings: &KeybindingSettings, + cx: &App, ) -> Result, KeybindingError> { let shortcuts = history_shortcuts(); for action in settings.history.keys() { @@ -331,7 +333,7 @@ pub(crate) fn compile_history_bindings( for shortcut in shortcuts { let bindings = if let Some(keys) = settings.history.get(&shortcut.id) { keys.iter() - .map(|key| parse_history_binding(&shortcut, key, &reserved)) + .map(|key| parse_history_binding(&shortcut, key, &reserved, cx)) .collect::, _>>()? } else { std::iter::once(shortcut.primary) @@ -350,7 +352,7 @@ pub(crate) fn compile_history_bindings( key: binding .keystrokes() .iter() - .map(|key| key.as_keystroke().unparse()) + .map(|key| key.as_keystroke().unparse(cx.platform_info().os)) .collect::>() .join(" "), first: other.clone(), @@ -367,6 +369,7 @@ fn parse_history_binding( shortcut: &HistoryShortcut, key: &str, reserved: &[KeyBinding], + cx: &App, ) -> Result { let invalid = || KeybindingError::InvalidKey { action: shortcut.id.clone(), @@ -378,7 +381,7 @@ fn parse_history_binding( shortcut.primary.predicate(), false, None, - &DummyKeyboardMapper, + cx, ) .map_err(|_| invalid())?; let [stroke] = binding.keystrokes() else { @@ -419,7 +422,7 @@ pub(crate) fn bind_application_keys(cx: &mut App) { return; } match GlobalSettings::read(cx, |settings| { - compile_history_bindings(&settings.keybindings) + compile_history_bindings(&settings.keybindings, cx) }) { Ok(bindings) => cx.bind_keys(bindings), Err(error) => { @@ -484,6 +487,42 @@ mod tests { use super::*; + fn compile(settings: &KeybindingSettings) -> Result, KeybindingError> { + gpui_kit::TestAppContext::single().read(|cx| compile_history_bindings(settings, cx)) + } + + #[rstest] + #[case(OperatingSystem::Mac, "cmd-d")] + #[case(OperatingSystem::Windows, "ctrl-d")] + #[case(OperatingSystem::Linux, "ctrl-d")] + fn test_history_secondary_modifier_uses_runtime_host( + #[case] os: OperatingSystem, + #[case] expected: &str, + ) { + let mut cx = gpui_kit::TestAppContext::single(); + cx.set_platform_info(gpui_kit::PlatformInfo { + os, + target: gpui_kit::PlatformTarget::Native, + }); + cx.read(|cx| { + let settings = overrides("delete_record", &["secondary-d"]); + let bindings = compile_history_bindings(&settings, cx).unwrap(); + let binding = bindings + .iter() + .find(|binding| binding.action().as_any().is::()) + .unwrap(); + assert_eq!(binding.keystrokes()[0].as_keystroke().unparse(os), expected); + let mut settings = settings; + settings + .history + .insert("toggle_favorite".into(), vec![expected.into()]); + assert!(matches!( + compile_history_bindings(&settings, cx), + Err(KeybindingError::Conflict { .. }) + )); + }); + } + fn overrides(action: &str, keys: &[&str]) -> KeybindingSettings { let mut settings = KeybindingSettings::default(); settings.history.insert( @@ -505,7 +544,7 @@ mod tests { fn test_history_invalid_key_returns_error(#[case] key: &str) { assert!( matches!( - compile_history_bindings(&overrides("delete_record", &[key])), + compile(&overrides("delete_record", &[key])), Err(KeybindingError::InvalidKey { .. }) ), "{key}" @@ -518,7 +557,7 @@ mod tests { #[case("shift-tab")] fn test_history_reserved_key_returns_error(#[case] key: &str) { assert!(matches!( - compile_history_bindings(&overrides("delete_record", &[key])), + compile(&overrides("delete_record", &[key])), Err(KeybindingError::ReservedKey { .. }) )); } @@ -531,7 +570,7 @@ mod tests { "alt-f4" }; assert!(matches!( - compile_history_bindings(&overrides("delete_record", &[key])), + compile(&overrides("delete_record", &[key])), Err(KeybindingError::ReservedKey { .. }) )); } @@ -539,7 +578,7 @@ mod tests { #[test] fn test_history_unknown_action_returns_error_even_when_disabled() { assert!(matches!( - compile_history_bindings(&overrides("delete_reocrd", &[])), + compile(&overrides("delete_reocrd", &[])), Err(KeybindingError::UnknownAction { .. }) )); } @@ -553,7 +592,7 @@ mod tests { .history .insert("toggle_favorite".into(), vec![second.into()]); assert!(matches!( - compile_history_bindings(&settings), + compile(&settings), Err(KeybindingError::Conflict { .. }) )); } @@ -562,17 +601,22 @@ mod tests { fn test_history_disabling_action_releases_keys_and_removing_override_restores_defaults() { let mut settings = overrides("delete_record", &["f", "f"]); assert!(matches!( - compile_history_bindings(&settings), + compile(&settings), Err(KeybindingError::Conflict { .. }) )); settings.history.insert("toggle_favorite".into(), vec![]); - let bindings = compile_history_bindings(&settings).unwrap(); + let bindings = compile(&settings).unwrap(); let delete = bindings .iter() .filter(|binding| binding.action().as_any().is::()) .collect::>(); assert_eq!(delete.len(), 1); - assert_eq!(delete[0].keystrokes()[0].as_keystroke().unparse(), "f"); + assert_eq!( + delete[0].keystrokes()[0] + .as_keystroke() + .unparse(OperatingSystem::Linux), + "f" + ); assert!( !bindings .iter() @@ -580,11 +624,15 @@ mod tests { ); settings.history.clear(); - let bindings = compile_history_bindings(&settings).unwrap(); + let bindings = compile(&settings).unwrap(); let delete = bindings .iter() .filter(|binding| binding.action().as_any().is::()) - .map(|binding| binding.keystrokes()[0].as_keystroke().unparse()) + .map(|binding| { + binding.keystrokes()[0] + .as_keystroke() + .unparse(OperatingSystem::Linux) + }) .collect::>(); assert_eq!(delete, ["delete", "d"]); assert!( diff --git a/src/gui/board/shortcut_editor.rs b/src/gui/board/shortcut_editor.rs index 67c7a14..1e29031 100644 --- a/src/gui/board/shortcut_editor.rs +++ b/src/gui/board/shortcut_editor.rs @@ -30,7 +30,7 @@ pub(crate) struct ShortcutEditor { impl ShortcutEditor { fn new(settings: KeybindingSettings, return_panel: ActivePanel, cx: &App) -> Self { - let error = compile_history_bindings(&settings).err(); + let error = compile_history_bindings(&settings, cx).err(); let scroll = ScrollHandle::new(); let row_focus = super::actions::shortcuts::history_shortcuts() .into_iter() @@ -52,38 +52,41 @@ impl ShortcutEditor { self.draft != self.baseline } - pub(crate) fn keys(&self, shortcut: &HistoryShortcut) -> Vec { + pub(crate) fn keys(&self, shortcut: &HistoryShortcut, cx: &App) -> Vec { let mut keys = self .draft .history .get(&shortcut.id) .cloned() - .unwrap_or_else(|| shortcut.default_keys()); + .unwrap_or_else(|| shortcut.default_keys(cx.platform_info().os)); // A manually edited file may repeat a key; show one removable control. let mut seen = std::collections::HashSet::new(); keys.retain(|key| seen.insert(key.clone())); keys } - pub(crate) fn is_modified(&self, shortcut: &HistoryShortcut) -> bool { + pub(crate) fn is_modified(&self, shortcut: &HistoryShortcut, cx: &App) -> bool { + let os = cx.platform_info().os; let normalize = |keys: Vec| -> std::collections::HashSet { keys.into_iter() - .map(|key| gpui_kit::Keystroke::parse(&key).map_or(key, |key| key.unparse())) + .map(|key| { + gpui_kit::Keystroke::parse_with_os(&key, os).map_or(key, |key| key.unparse(os)) + }) .collect() }; - normalize(self.keys(shortcut)) != normalize(shortcut.default_keys()) + normalize(self.keys(shortcut, cx)) != normalize(shortcut.default_keys(os)) } - pub(crate) fn edit(&mut self, edit: impl FnOnce(&mut KeybindingSettings)) { + pub(crate) fn edit(&mut self, edit: impl FnOnce(&mut KeybindingSettings), cx: &App) { self.recording = None; self.save_error = None; edit(&mut self.draft); - self.error = compile_history_bindings(&self.draft).err(); + self.error = compile_history_bindings(&self.draft, cx).err(); } - pub(crate) fn revert(&mut self) { + pub(crate) fn revert(&mut self, cx: &App) { let baseline = self.baseline.clone(); - self.edit(|draft| *draft = baseline); + self.edit(|draft| *draft = baseline, cx); } } @@ -106,11 +109,11 @@ impl RopyBoard { pub(crate) fn edit_shortcuts( &mut self, - edit: impl FnOnce(&mut ShortcutEditor), + edit: impl FnOnce(&mut ShortcutEditor, &App), cx: &mut Context<'_, Self>, ) { if let Some(editor) = &mut self.shortcut_editor { - edit(editor); + edit(editor, cx); cx.notify(); } } @@ -161,8 +164,8 @@ impl RopyBoard { .into_iter() .find(|s| s.id == recording.action); if let Some(shortcut) = shortcut { - let mut keys = editor.keys(&shortcut); - let key = event.keystroke.unparse(); + let mut keys = editor.keys(&shortcut, cx); + let key = event.keystroke.unparse(cx.platform_info().os); if let Some(index) = recording .previous .as_ref() @@ -172,9 +175,12 @@ impl RopyBoard { } else { keys.push(key); } - editor.edit(|draft| { - draft.history.insert(recording.action, keys); - }); + editor.edit( + |draft| { + draft.history.insert(recording.action, keys); + }, + cx, + ); } } cx.notify(); @@ -189,7 +195,7 @@ impl RopyBoard { if editor.recording.is_some() || !editor.is_dirty() { return; } - let bindings = match compile_history_bindings(&editor.draft) { + let bindings = match compile_history_bindings(&editor.draft, cx) { Ok(bindings) => bindings, Err(error) => { editor.error = Some(error); diff --git a/src/gui/board/ui_tests/shortcut_editor.rs b/src/gui/board/ui_tests/shortcut_editor.rs index 613c879..d3200d0 100644 --- a/src/gui/board/ui_tests/shortcut_editor.rs +++ b/src/gui/board/ui_tests/shortcut_editor.rs @@ -83,12 +83,12 @@ fn test_shortcuts_apply_persists_alias_removal_and_refreshes_help(cx: &mut TestA cx.key_bindings().borrow().bindings().len(), original_count - 1 ); - assert!( - cx.key_bindings() - .borrow() - .bindings() - .any(|binding| binding.keystrokes()[0].as_keystroke().unparse() == "f12") - ); + assert!(cx.key_bindings().borrow().bindings().any(|binding| { + binding.keystrokes()[0] + .as_keystroke() + .unparse(cx.platform_info().os) + == "f12" + })); window.click("shortcuts-back", cx); let label = window .find("board::DeleteRecord") diff --git a/src/gui/panel/shortcuts.rs b/src/gui/panel/shortcuts.rs index bf469bc..224755d 100644 --- a/src/gui/panel/shortcuts.rs +++ b/src/gui/panel/shortcuts.rs @@ -127,10 +127,13 @@ fn unknown_shortcut_row(id: &str, disabled: bool, cx: &Context<'_, RopyBoard>) - .disabled(disabled) .on_click(cx.listener(move |board, _, _, cx| { board.edit_shortcuts( - |editor| { - editor.edit(|draft| { - draft.history.remove(&action); - }); + |editor, cx| { + editor.edit( + |draft| { + draft.history.remove(&action); + }, + cx, + ); }, cx, ); @@ -150,7 +153,7 @@ fn shortcut_row( let id = &shortcut.id; let recording = editor.recording.as_ref().is_some_and(|r| r.action == *id); let menu = shortcut_menu(shortcut, disabled || editor.recording.is_some(), cx); - let keys = editor.keys(shortcut); + let keys = editor.keys(shortcut, cx); let controls = shortcut_controls(shortcut, &keys, disabled || editor.recording.is_some(), cx); v_flex() .id(SharedString::from(format!("shortcuts-row-{id}"))) @@ -175,7 +178,7 @@ fn shortcut_row( .text_sm() .child(shortcut.label.clone()), ) - .when(editor.is_modified(shortcut), |header| { + .when(editor.is_modified(shortcut, cx), |header| { header.child( div() .id(SharedString::from(format!("shortcuts-modified-{id}"))) @@ -310,7 +313,7 @@ fn shortcut_footer( .disabled(disabled || recording) .on_click(cx.listener(|board, _, _, cx| { board.edit_shortcuts( - |editor| editor.edit(|draft| draft.history.clear()), + |editor, cx| editor.edit(|draft| draft.history.clear(), cx), cx, ); })), @@ -363,10 +366,13 @@ fn shortcut_menu( PopupMenuItem::new(t!("shortcuts_restore")).on_click(move |_, _, cx| { let _ = restore_owner.update(cx, |board, cx| { board.edit_shortcuts( - |editor| { - editor.edit(|draft| { - draft.history.remove(&restore_id); - }); + |editor, cx| { + editor.edit( + |draft| { + draft.history.remove(&restore_id); + }, + cx, + ); }, cx, ); @@ -377,10 +383,13 @@ fn shortcut_menu( PopupMenuItem::new(t!("shortcuts_clear")).on_click(move |_, _, cx| { let _ = clear_owner.update(cx, |board, cx| { board.edit_shortcuts( - |editor| { - editor.edit(|draft| { - draft.history.insert(clear_id.clone(), Vec::new()); - }); + |editor, cx| { + editor.edit( + |draft| { + draft.history.insert(clear_id.clone(), Vec::new()); + }, + cx, + ); }, cx, ); @@ -404,8 +413,8 @@ fn shortcut_controls( let remove_action = id.clone(); let mut remaining = keys.to_vec(); remaining.retain(|other| other != key); - let label = - gpui_kit::Keystroke::parse(key).map_or_else(|_| key.clone(), |key| Kbd::format(&key)); + let label = gpui_kit::Keystroke::parse_with_os(key, cx.platform_info().os) + .map_or_else(|_| key.clone(), |key| Kbd::format(&key)); let remove_label = t!("shortcuts_remove_key", key = label, action = shortcut.label); controls = controls.child( h_flex() @@ -445,12 +454,15 @@ fn shortcut_controls( .disabled(disabled) .on_click(cx.listener(move |board, _, _, cx| { board.edit_shortcuts( - |editor| { - editor.edit(|draft| { - draft - .history - .insert(remove_action.clone(), remaining.clone()); - }); + |editor, cx| { + editor.edit( + |draft| { + draft + .history + .insert(remove_action.clone(), remaining.clone()); + }, + cx, + ); }, cx, ); diff --git a/src/promo.rs b/src/promo.rs index f47f2c8..f3149bc 100644 --- a/src/promo.rs +++ b/src/promo.rs @@ -182,7 +182,7 @@ impl Render for PromoView { .occlude() .on_any_mouse_down(|_, _, cx| cx.stop_propagation()) .capture_any_mouse_up(|_, _, cx| cx.stop_propagation()) - .on_scroll_wheel(|_, _, cx| cx.stop_propagation()), + .on_scroll(|_, _, cx| cx.stop_propagation()), ) } }