diff --git a/AGENTS.md b/AGENTS.md index 9686c56..916441e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -5,7 +5,7 @@ Ely GPUI Component. A component library for GPUI, in light and dark. ## Stack - Rust 1.95, edition 2024. One crate: `ely-gpui-component`. -- gpui 0.2.2 from crates.io. Feature `runtime_shaders` is on by default: machines without Xcode lack the Metal compiler. +- gpui and gpui_platform from Zed's repo by git at 1a28cff, the code gpui-pre 0.3.7 republishes. gpui takes `stacker`, which keeps deep layouts off the stack's end; gpui_platform takes `font-kit`, without which macOS draws no text. Feature `runtime_shaders`, on by default, turns on gpui_platform's: machines without Xcode lack the Metal compiler. - Assets, embedded with `rust-embed`: Lucide 1.48.0 icons (ISC), Inter 4.1 (regular, medium, semibold, italic) and JetBrains Mono 2.304 (OFL). - Catalog data: `emojis` (Unicode emoji), `isolang` (ISO 639, native names), `isocountry` (ISO 3166), `iso_currency` (ISO 4217, also minor units for money). - Codes: `qrcode` (QR) and `barcoders` (Code 128, EAN-13), both MIT OR Apache-2.0, default features off. `rqrr` 0.11 ((MIT OR Apache-2.0) AND ISC, default features off) reads QR codes from the host's frames. @@ -53,6 +53,7 @@ Ely GPUI Component. A component library for GPUI, in light and dark. - `hover()` needs an element id. - gpui applies hover and group-hover styles once an element has a hitbox, in prepaint and paint, but text takes its color at layout, so a hover cannot recolor text. What shows on hover rests `invisible()` and turns `visible()` through `group_hover` (`chat::ConversationItem`, `messaging::ChatMessage`). - gpui 0.2.2 panics on a deferred draw inside another. Whatever draws over the page goes through `primitives::raise`: at the top it defers; inside something raised it lays out on its own and draws last there, so a list opened in a dialog lies over the dialog. A raise takes its owner's id and draws under it, so its keyed state and focus hold while other raises come and go. `scripts/check.sh` refuses gpui's `deferred` anywhere else. +- gpui hides hover after a key press until the mouse moves. A hover that holds or shows something (the toast stack, a carousel, tooltips, hover cards, charts, scroll activity) sets `HoverListenerMode::InputModalityIndependent`, so typing under a resting pointer keeps it. A hover preview the keyboard also moves keeps the default, and its leave ignores a key press through `last_input_was_keyboard` (`forms::Calendar`). - `occlude()` blocks the pointer for everything painted before it, its own ancestors too. Put it on the outermost box that should stop the pointer, as the toast stack does, or the ancestors' hover never fires. - A drag that pans, turns or slides goes through gpui's drag, whose moves reach the owner in or out of its box; `on_mouse_move` stops at the box's edge. gpui sends a drag's moves to every listener of its type, so each payload carries its owner's `EntityId` and handlers check it. - gpui 0.2.2 paints pictures without a transform, so a picture turns by its pixels: `media::turn` turns decoded frames by quarter turns off the main thread, an asset keyed by the picture and the turn. An svg turns to any angle through its `Transformation`, so a control that turns shows one (`interaction::Rotatable`). @@ -80,7 +81,7 @@ Ely GPUI Component. A component library for GPUI, in light and dark. - gpui focuses the nearest focusable ancestor on mouse down, and apps wrap everything in a `FocusScope`. A press that must leave focus alone calls `prevent_default`, as buttons and context regions do. - gpui runs the click of every pressed element under the pointer, a row's with its button's. A pressable row that holds buttons stops their press at their box on mouse down (`files::transfer`), as `overlays::media_button` stops its own. - gpui draws a window's first frame inside `open_window`. State the first frame reads, such as `cx.set_menus`, is set before it opens. -- gpui clicks a focused element when Enter or Space is released. An overlay that hands focus back picks on release too; a pick on press returns focus first, and the release clicks the opener again. An edit in place that hands focus back keeps its text on Enter's release (`forms::InlineEdit`). The press itself bubbles, so a container that takes Space leaves a focused button its own: `overlays::media_button` stops it, and a button in a `SelectableList` row stops Space and Enter at its box (`mail::MailItem`'s star, `messaging::PinnedMessages`' Unpin). +- gpui clicks a focused element when Enter or Space is released, and only if the press reached it and focus stayed there. An overlay that hands focus back picks on release too. An edit in place that hands focus back keeps its text on Enter's release (`forms::InlineEdit`). The press itself bubbles, so a container that takes Space leaves a focused button its own: `overlays::media_button` stops it, and a button in a `SelectableList` row stops Space and Enter at its box (`mail::MailItem`'s star, `messaging::PinnedMessages`' Unpin). A key context that binds a key its children use acts only while its own handle is focused and propagates otherwise, or a focused child never arms (`editor::CodeEditor`'s Newline). - A focus handle a component hands back lives across all its modes: take it with `tab_stop` before any early return, or keyed state drops it while the other mode draws and the handed-back focus lands nowhere. A thread's message keeps one handle folded and open, a Tab stop only while folded (`mail::MailThreadView`). - A button whose words and action change with a mode keeps one handle through `Button::focus_handle`, and the component moves focus to it or back to its field as the mode turns (`project::TimeTracker`). - A button that waits on the owner shows it with `loading`, which takes no press and stays a Tab stop, so focus holds through the wait; `disabled` is for what is not ready, and a disabled button is no stop (`onboarding::ContactSupport`). @@ -136,6 +137,7 @@ Ely GPUI Component. A component library for GPUI, in light and dark. - A picture drawn in code reaches gpui as a `RenderImage`. A host that replaces one frees the old through `App::drop_image`, or every frame stays in the sprite atlas (the gallery's model). - `img()` keeps loading state, and moves an animated picture's frames, only with an id. Content masks are rectangles, so rounded corners survive only when the image fills its box without cropping. - gpui reads a `&str` picture source as a web address. A file goes through `Path` (`documents::source` in the crate, `Path::new` in the gallery). +- Taffy 0.13 sizes a flex column by a ratio box's width before its cap, so chat's `shaped` pictures sit in a block inside such a column (`chat::ImageMessage`, `VideoMessage`, `ImageGrid`). - Taffy 0.9's grid rows overgrow tiles that keep a ratio. Tiles in a picture's shape sit in flex rows of `flex_1` cells (`generative::GenerationGrid`). A cell's padding counts in its flex base, so a row of fewer cells gives each more width; cells that match across rows keep their inset on a box inside (`messaging::VideoCallGrid`). - Rise reads green and fall red unless a component's `red_up` swaps them, as markets in East Asia read. `finance::quotes::moves` picks the pair. - Charts lay out in `f32` pixels of their own box, tested without gpui, and paint through `charts::paint::at`: a canvas's paint gets window coordinates, and `with_element_offset` works only in prepaint. Their sizes come from `theme.chart()`. @@ -164,7 +166,7 @@ Ely GPUI Component. A component library for GPUI, in light and dark. - A component built on `lists::Tree` fills its box; the host gives it a height. A fixed-width column beside a `flex_1` one takes `flex_none`, or it shrinks. - Editor rows read their text through `CodeEditor::row_text`: a multi-line ghost cuts its line, and the rest follows the ghost's last line. - gpui styles a drag-over only on an element with its own hitbox. A veil that shows while files hover takes the drop itself (`chat::DragDropOverlay`). -- gpui 0.2.2 never clears `debug_bounds`: a test sees an element appear, not leave. +- gpui clears `debug_bounds` each frame: a test sees an element leave as well as appear. - The system time zone comes from `typography::format::system_zone`, which fails loud; jiff's `TimeZone::system()` falls back to UTC in silence. - A Select with nothing to pick stays shut: disabled, it shows its placeholder; open, it fails (`media::DeviceSelector` says no device was found). - A list opens with its cursor on the current choice: Select on the chosen row, Combobox on its value, MultiSelect on the first one ticked, SelectableList on its first selected row. A selection the owner makes, not the echo of the list's own pick, moves SelectableList's cursor there. @@ -207,7 +209,7 @@ Ely GPUI Component. A component library for GPUI, in light and dark. - gpui's inspector (debug builds) runs no mouse listener while picking and holds a pick on a press without a redraw, so Ely's panel requests a frame each render while picking (`tooling::install_inspector`). Its panel scrolls, so the box model it draws over the page goes through `primitives::raise`, which paints unclipped. The panel is a second root, out of the app's scope, so it owns Tab through a `FocusScope` of its own. - A tool that measures redraws cannot move: any animation redraws the view it counts (`tooling::RenderCounter`). `AnyView::cached` renders again only on its own notify or a window refresh. A meter that counts frames keeps its view drawing while shown (`tooling::FpsMeter`). -- A logger of input lays its canvas before what it holds, so its capture listeners run first and see what a child stops. Key downs come through `App::intercept_keystrokes`, which runs before bindings, and a key context on its box tells it focus is inside (`tooling::EventLogger`). +- A logger of input lays its canvas before what it holds, so its capture listeners run first and see what a child stops. Key downs come through `App::intercept_keystrokes`, which runs before bindings, and a key context on its box tells it focus is inside (`tooling::EventLogger`). It also hears a lone modifier's release as a keystroke, which the logger skips. ## Decisions diff --git a/Cargo.lock b/Cargo.lock index ef39124..5626b31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,86 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "accesskit" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3b7f7f85a7e5f68090000ed7622545829afd484d210358702ae4cb97dd0c320" +dependencies = [ + "enumn", + "uuid", +] + +[[package]] +name = "accesskit_atspi_common" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "023da0e5097f46df7092d5280b02efb9bbf8d93298daeced42652463e357d636" +dependencies = [ + "accesskit", + "accesskit_consumer", + "atspi-common", + "phf 0.13.1", + "serde", + "zvariant", +] + +[[package]] +name = "accesskit_consumer" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d10a236f96f87d70732e44520046785431ef01d5bcd6b041317bfadd2f88245" +dependencies = [ + "accesskit", + "hashbrown 0.16.1", +] + +[[package]] +name = "accesskit_macos" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce02dc63b43f0c9296af9ac946312a2dc8814427d7a64d2d600971dac55b6076" +dependencies = [ + "accesskit", + "accesskit_consumer", + "hashbrown 0.16.1", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "accesskit_unix" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03e156ed3802e35eefe894ef2671bc6c889303d8a7e110b5e1b48f504b91362f" +dependencies = [ + "accesskit", + "accesskit_atspi_common", + "async-channel", + "async-executor", + "async-task", + "atspi", + "futures-lite", + "futures-util", + "serde", + "zbus", +] + +[[package]] +name = "accesskit_windows" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "106c2b961215864d1c2e703ee63269c25c4e80a577ffb2c1017b9c17dcdf83a1" +dependencies = [ + "accesskit", + "accesskit_consumer", + "hashbrown 0.16.1", + "static_assertions", + "windows 0.62.2", + "windows-core 0.62.2", +] + [[package]] name = "addr2line" version = "0.25.1" @@ -29,19 +109,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "ahash" -version = "0.8.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" -dependencies = [ - "cfg-if", - "const-random", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "aho-corasick" version = "1.1.5" @@ -67,7 +134,7 @@ dependencies = [ "piper", "polling", "regex-automata", - "rustix 1.1.5", + "rustix", "rustix-openpty", "signal-hook", "unicode-width", @@ -93,6 +160,21 @@ dependencies = [ "equator", ] +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "android_system_properties" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc" +dependencies = [ + "libc", +] + [[package]] name = "anstream" version = "1.0.0" @@ -187,12 +269,6 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" -[[package]] -name = "as-raw-xcb-connection" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" - [[package]] name = "as-slice" version = "0.2.1" @@ -211,53 +287,16 @@ dependencies = [ "libloading", ] -[[package]] -name = "ash-window" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52bca67b61cb81e5553babde81b8211f713cb6db79766f80168f3e5f40ea6c82" -dependencies = [ - "ash", - "raw-window-handle", - "raw-window-metal", -] - [[package]] name = "ashpd" -version = "0.11.1" +version = "0.13.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f3f79755c74fd155000314eb349864caa787c6592eace6c6882dad873d9c39" +checksum = "fb8421aaa9644a5faf26735f258b669b15f063313ef8f8e2bdb28912a1a6f111" dependencies = [ - "async-fs", - "async-net", "enumflags2", - "futures-channel", "futures-util", - "rand 0.9.5", + "getrandom 0.4.3", "serde", - "serde_repr", - "url", - "wayland-backend", - "wayland-client", - "wayland-protocols 0.32.13", - "zbus", -] - -[[package]] -name = "ashpd" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33a3c86f3fd70c0ffa500ed189abfa90b5a52398a45d5dc372fcc38ebeb7a645" -dependencies = [ - "async-fs", - "async-net", - "enumflags2", - "futures-channel", - "futures-util", - "rand 0.9.5", - "serde", - "serde_repr", - "url", "zbus", ] @@ -267,23 +306,12 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" dependencies = [ - "event-listener 5.4.2", + "event-listener", "event-listener-strategy", "futures-core", "pin-project-lite", ] -[[package]] -name = "async-channel" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" -dependencies = [ - "concurrent-queue", - "event-listener 2.5.3", - "futures-core", -] - [[package]] name = "async-channel" version = "2.5.0" @@ -316,8 +344,8 @@ checksum = "c96bf972d85afc50bf5ab8fe2d54d1586b4e0b46c97c50a0c9e71e2f7bcd812a" dependencies = [ "async-task", "concurrent-queue", - "fastrand 2.5.0", - "futures-lite 2.6.1", + "fastrand", + "futures-lite", "pin-project-lite", "slab", ] @@ -330,22 +358,7 @@ checksum = "8034a681df4aed8b8edbd7fbe472401ecf009251c8b40556b304567052e294c5" dependencies = [ "async-lock", "blocking", - "futures-lite 2.6.1", -] - -[[package]] -name = "async-global-executor" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" -dependencies = [ - "async-channel 2.5.0", - "async-executor", - "async-io", - "async-lock", - "blocking", - "futures-lite 2.6.1", - "once_cell", + "futures-lite", ] [[package]] @@ -358,10 +371,10 @@ dependencies = [ "cfg-if", "concurrent-queue", "futures-io", - "futures-lite 2.6.1", + "futures-lite", "parking", "polling", - "rustix 1.1.5", + "rustix", "slab", "windows-sys 0.61.2", ] @@ -372,7 +385,7 @@ version = "3.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" dependencies = [ - "event-listener 5.4.2", + "event-listener", "event-listener-strategy", "pin-project-lite", ] @@ -385,7 +398,7 @@ checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" dependencies = [ "async-io", "blocking", - "futures-lite 2.6.1", + "futures-lite", ] [[package]] @@ -394,16 +407,16 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75" dependencies = [ - "async-channel 2.5.0", + "async-channel", "async-io", "async-lock", "async-signal", "async-task", "blocking", "cfg-if", - "event-listener 5.4.2", - "futures-lite 2.6.1", - "rustix 1.1.5", + "event-listener", + "futures-lite", + "rustix", ] [[package]] @@ -429,39 +442,12 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix 1.1.5", + "rustix", "signal-hook-registry", "slab", "windows-sys 0.61.2", ] -[[package]] -name = "async-std" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c8e079a4ab67ae52b7403632e4618815d6db36d2a010cfe41b02c1b1578f93b" -dependencies = [ - "async-channel 1.9.0", - "async-global-executor", - "async-io", - "async-lock", - "async-process", - "crossbeam-utils", - "futures-channel", - "futures-core", - "futures-io", - "futures-lite 2.6.1", - "gloo-timers", - "kv-log-macro", - "log", - "memchr", - "once_cell", - "pin-project-lite", - "pin-utils", - "slab", - "wasm-bindgen-futures", -] - [[package]] name = "async-task" version = "4.7.1" @@ -479,19 +465,6 @@ dependencies = [ "syn 3.0.6", ] -[[package]] -name = "async_zip" -version = "0.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b9f7252833d5ed4b00aa9604b563529dd5e11de9c23615de2dcdf91eb87b52" -dependencies = [ - "async-compression", - "crc32fast", - "futures-lite 2.6.1", - "pin-project", - "thiserror 1.0.69", -] - [[package]] name = "atomic" version = "0.5.3" @@ -504,6 +477,43 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +[[package]] +name = "atspi" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c77886257be21c9cd89a4ae7e64860c6f0eefca799bb79127913052bd0eefb3d" +dependencies = [ + "atspi-common", + "atspi-proxies", +] + +[[package]] +name = "atspi-common" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20c5617155740c98003016429ad13fe43ce7a77b007479350a9f8bf95a29f63d" +dependencies = [ + "enumflags2", + "serde", + "static_assertions", + "zbus", + "zbus-lockstep", + "zbus-lockstep-macros", + "zbus_names", + "zvariant", +] + +[[package]] +name = "atspi-proxies" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2230e48787ed3eb4088996eab66a32ca20c0b67bbd4fd6cdfe79f04f1f04c9fc" +dependencies = [ + "atspi-common", + "serde", + "zbus", +] + [[package]] name = "autocfg" version = "1.5.1" @@ -582,9 +592,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bindgen" -version = "0.71.1" +version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" +checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ "bitflags 2.13.2", "cexpr", @@ -606,7 +616,16 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" dependencies = [ - "bit-vec", + "bit-vec 0.8.0", +] + +[[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]] @@ -615,6 +634,12 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" +[[package]] +name = "bit-vec" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71798fca2c1fe1086445a7258a4bc81e6e49dcd24c8d0dd9a1e57395b603f51" + [[package]] name = "bit_field" version = "0.10.3" @@ -642,64 +667,6 @@ dependencies = [ "no_std_io2", ] -[[package]] -name = "blade-graphics" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e71cfb73b98eb9f58ee84048aa1bdf4e7497fd20c141b57523499fa066b48fed" -dependencies = [ - "ash", - "ash-window", - "bitflags 2.13.2", - "bytemuck", - "codespan-reporting", - "glow", - "gpu-alloc", - "gpu-alloc-ash", - "hidden-trait", - "js-sys", - "khronos-egl", - "libloading", - "log", - "mint", - "naga", - "objc2", - "objc2-app-kit", - "objc2-core-foundation", - "objc2-foundation", - "objc2-metal", - "objc2-quartz-core", - "objc2-ui-kit", - "once_cell", - "raw-window-handle", - "slab", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "blade-macros" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27142319e2f4c264581067eaccb9f80acccdde60d8b4bf57cc50cd3152f109ca" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.119", -] - -[[package]] -name = "blade-util" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a6be3a82c001ba7a17b6f8e413ede5d1004e6047213f8efaf0ffc15b5c4904c" -dependencies = [ - "blade-graphics", - "bytemuck", - "log", - "profiling", -] - [[package]] name = "block" version = "0.1.6" @@ -733,13 +700,22 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" +dependencies = [ + "objc2 0.5.2", +] + [[package]] name = "block2" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" dependencies = [ - "objc2", + "objc2 0.6.4", ] [[package]] @@ -748,13 +724,23 @@ version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a70e4329df6cb94385eed412ec92375c3cdd8a6e502493d1229b6414e4036dfa" dependencies = [ - "async-channel 2.5.0", + "async-channel", "async-task", "futures-io", - "futures-lite 2.6.1", + "futures-lite", "piper", ] +[[package]] +name = "borsh" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "553c5d846a6ba5150c65e3b1b8ec073bcf1abc20f9b7220de384a4443ea4e20a" +dependencies = [ + "bytes", + "cfg_aliases", +] + [[package]] name = "bstr" version = "1.13.1" @@ -817,29 +803,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" [[package]] -name = "calloop" -version = "0.13.0" +name = "bzip2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" +checksum = "f3a53fac24f34a81bc9954b5d6cfce0c21e18ec6959f44f56e8e90e4bb7c346c" dependencies = [ - "bitflags 2.13.2", - "log", - "polling", - "rustix 0.38.44", - "slab", - "thiserror 1.0.69", + "libbz2-rs-sys", ] [[package]] -name = "calloop-wayland-source" -version = "0.3.0" +name = "calloop" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" +checksum = "4dbf9978365bac10f54d1d4b04f7ce4427e51f71d61f2fe15e3fed5166474df7" dependencies = [ - "calloop", - "rustix 0.38.44", - "wayland-backend", - "wayland-client", + "bitflags 2.13.2", + "polling", + "rustix", + "slab", + "tracing", ] [[package]] @@ -918,14 +900,17 @@ dependencies = [ ] [[package]] -name = "chacha20" -version = "0.10.2" +name = "chrono" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ - "cfg-if", - "cpufeatures 0.3.1", - "rand_core 0.10.1", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-link 0.2.1", ] [[package]] @@ -1012,15 +997,25 @@ dependencies = [ [[package]] name = "codespan-reporting" -version = "0.12.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" +checksum = "af491d569909a7e4dee0ad7db7f5341fef5c614d5b8ec8cf765732aba3cff681" dependencies = [ "serde", "termcolor", "unicode-width", ] +[[package]] +name = "collections" +version = "0.1.0" +source = "git+https://github.com/zed-industries/zed?rev=1a28cff4b409169bac058bca40dfbfeb7621d19b#1a28cff4b409169bac058bca40dfbfeb7621d19b" +dependencies = [ + "gpui_util", + "indexmap", + "rustc-hash 2.1.3", +] + [[package]] name = "color_quant" version = "1.1.0" @@ -1043,24 +1038,14 @@ dependencies = [ "memchr", ] -[[package]] -name = "command-fds" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b60b5124979fccd9addd89d8b97a1d6eebb4950694520c75ddd722535ea443f" -dependencies = [ - "nix 0.31.3", - "thiserror 2.0.21", -] - [[package]] name = "compression-codecs" version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef16c47ba2797aa6a909cc37d39911f3a6743811fe7408ac0b0cc0276b656e9" dependencies = [ + "bzip2", "compression-core", - "deflate64", "flate2", "memchr", ] @@ -1080,6 +1065,16 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + [[package]] name = "const-oid" version = "0.10.2" @@ -1087,30 +1082,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" [[package]] -name = "const-random" -version = "0.1.18" +name = "convert_case" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" dependencies = [ - "const-random-macro", -] - -[[package]] -name = "const-random-macro" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" -dependencies = [ - "getrandom 0.2.17", - "once_cell", - "tiny-keccak", + "unicode-segmentation", ] [[package]] name = "convert_case" -version = "0.4.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +checksum = "affbf0190ed2caf063e3def54ff444b449371d55c58e513a95ab98eca50adb49" +dependencies = [ + "unicode-segmentation", +] [[package]] name = "cookie" @@ -1211,9 +1198,9 @@ dependencies = [ [[package]] name = "core-graphics2" -version = "0.4.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e4583956b9806b69f73fcb23aee05eb3620efc282972f08f6a6db7504f8334d" +checksum = "4416167a69126e617f8d0a214af0e3c1dbdeffcb100ddf72dcd1a1ac9893c146" dependencies = [ "bitflags 2.13.2", "block", @@ -1236,9 +1223,9 @@ dependencies = [ [[package]] name = "core-video" -version = "0.4.3" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d45e71d5be22206bed53c3c3cb99315fc4c3d31b8963808c6bc4538168c4f8ef" +checksum = "139679cc63eb9504bdbe37e37874b0247136177655f0008588781e90863afa62" dependencies = [ "block", "core-foundation 0.10.0", @@ -1248,12 +1235,6 @@ dependencies = [ "metal", ] -[[package]] -name = "core_detect" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f8f80099a98041a3d1622845c271458a2d73e688351bf3cb999266764b81d48" - [[package]] name = "core_maths" version = "0.1.1" @@ -1265,21 +1246,22 @@ dependencies = [ [[package]] name = "cosmic-text" -version = "0.14.2" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da46a9d5a8905cc538a4a5bceb6a4510de7a51049c5588c0114efce102bcbbe8" +checksum = "be17b688510d934ce13f48a2beba700e11583e281e0fda99c22bb256a14eda73" dependencies = [ "bitflags 2.13.2", - "fontdb 0.16.2", + "fontdb", + "harfrust", + "linebender_resource_handle", "log", "rangemap", - "rustc-hash 1.1.0", - "rustybuzz 0.14.1", + "rustc-hash 2.1.3", "self_cell", + "skrifa 0.40.0", "smol_str", "swash", "sys-locale", - "ttf-parser 0.21.1", "unicode-bidi", "unicode-linebreak", "unicode-script", @@ -1369,7 +1351,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", - "rand_core 0.6.4", "typenum", ] @@ -1407,20 +1388,14 @@ dependencies = [ [[package]] name = "ctor" -version = "0.4.3" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec09e802f5081de6157da9a75701d6c713d8dc3ba52571fd4bd25f412644e8a6" +checksum = "914a755b7c2d4af2bdcff7ce1739e2db9a1b81a9b07123d8015786ae03c0980d" dependencies = [ - "ctor-proc-macro", - "dtor", + "link-section", + "linktime-proc-macro", ] -[[package]] -name = "ctor-proc-macro" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2931af7e13dc045d8e9d26afccc6fa115d64e115c9c84b1166288b46f6782c2" - [[package]] name = "cursor-icon" version = "1.2.0" @@ -1433,12 +1408,6 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376" -[[package]] -name = "deflate64" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac6b926516df9c60bfa16e107b21086399f8285a44ca9711344b9e553c5146e2" - [[package]] name = "defmt" version = "1.1.1" @@ -1476,19 +1445,6 @@ version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" -[[package]] -name = "derive_more" -version = "0.99.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn 2.0.119", -] - [[package]] name = "derive_more" version = "2.1.1" @@ -1504,10 +1460,22 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" dependencies = [ + "convert_case 0.10.0", "proc-macro2", "quote", "rustc_version", "syn 2.0.119", + "unicode-xid", +] + +[[package]] +name = "derive_refineable" +version = "0.1.0" +source = "git+https://github.com/zed-industries/zed?rev=1a28cff4b409169bac058bca40dfbfeb7621d19b#1a28cff4b409169bac058bca40dfbfeb7621d19b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", ] [[package]] @@ -1534,20 +1502,11 @@ dependencies = [ [[package]] name = "dirs" -version = "4.0.0" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" dependencies = [ - "dirs-sys 0.3.7", -] - -[[package]] -name = "dirs" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" -dependencies = [ - "dirs-sys 0.4.1", + "dirs-sys", ] [[package]] @@ -1556,30 +1515,7 @@ version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d57d423b3c82e89b9a24ca3091fee61f456a26edbd28d26c65906f4bc1dcd8f" dependencies = [ - "dirs-sys 0.5.0", -] - -[[package]] -name = "dirs-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" -dependencies = [ - "libc", - "redox_users 0.4.6", - "winapi", -] - -[[package]] -name = "dirs-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" -dependencies = [ - "libc", - "option-ext", - "redox_users 0.4.6", - "windows-sys 0.48.0", + "dirs-sys", ] [[package]] @@ -1590,7 +1526,7 @@ checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" dependencies = [ "libc", "option-ext", - "redox_users 0.5.3", + "redox_users", "windows-sys 0.61.2", ] @@ -1607,7 +1543,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" dependencies = [ "bitflags 2.13.2", - "objc2", + "block2 0.6.2", + "libc", + "objc2 0.6.4", ] [[package]] @@ -1630,27 +1568,30 @@ dependencies = [ "libloading", ] +[[package]] +name = "document-features" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +dependencies = [ + "litrs", +] + [[package]] name = "dom_query" version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fac5fca71e65e94cc718a6e2af65d6e0f9c6027751c2aa562fbb5087fda639bc" dependencies = [ - "bit-set", + "bit-set 0.8.0", "cssparser", "foldhash 0.2.0", "html5ever", "precomputed-hash", "selectors", - "tendril 0.5.1", + "tendril", ] -[[package]] -name = "downcast-rs" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" - [[package]] name = "dpi" version = "0.1.2" @@ -1672,21 +1613,6 @@ dependencies = [ "dtoa", ] -[[package]] -name = "dtor" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97cbdf2ad6846025e8e25df05171abfb30e3ababa12ee0a0e44b9bbe570633a8" -dependencies = [ - "dtor-proc-macro", -] - -[[package]] -name = "dtor-proc-macro" -version = "0.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7454e41ff9012c00d53cf7f475c5e3afa3b91b7c90568495495e8d9bf47a1055" - [[package]] name = "dunce" version = "1.0.5" @@ -1732,6 +1658,7 @@ dependencies = [ "env_logger", "futures", "gpui", + "gpui_platform", "image", "iso_currency", "isocountry", @@ -1745,7 +1672,7 @@ dependencies = [ "regex", "rqrr", "rust-embed", - "rustix 1.1.5", + "rustix", "serde", "serde_json", "similar", @@ -1777,20 +1704,6 @@ dependencies = [ "phf 0.13.1", ] -[[package]] -name = "encoding_rs" -version = "0.8.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e985e0451871ad22fb8d2b6b076e2028a502a0d3950998c2c5c0a4f9b5d9679" -dependencies = [ - "cfg-if", - "core_detect", - "multiversion_no_op", - "rustversion", - "scopeguard", - "simdutf8", -] - [[package]] name = "endi" version = "1.1.1" @@ -1818,6 +1731,17 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "enumn" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "env_filter" version = "2.0.0" @@ -1907,12 +1831,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "event-listener" -version = "2.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" - [[package]] name = "event-listener" version = "5.4.2" @@ -1929,7 +1847,7 @@ version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" dependencies = [ - "event-listener 5.4.2", + "event-listener", "pin-project-lite", ] @@ -1950,20 +1868,14 @@ dependencies = [ "zune-inflate", ] -[[package]] -name = "fastrand" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] - [[package]] name = "fastrand" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" +dependencies = [ + "getrandom 0.4.3", +] [[package]] name = "fax" @@ -1980,33 +1892,18 @@ dependencies = [ "simd-adler32", ] -[[package]] -name = "filedescriptor" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e40758ed24c9b2eeb76c35fb0aebc66c626084edd827e07e1552279814c6682d" -dependencies = [ - "libc", - "thiserror 1.0.69", - "winapi", -] - -[[package]] -name = "filetime" -version = "0.2.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759" -dependencies = [ - "cfg-if", - "libc", -] - [[package]] name = "find-msvc-tools" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef25905e51abafe4dcea6c15fec58c57b601cdbd0ee53d22ea1d3016c587d39b" +[[package]] +name = "fixedbitset" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" + [[package]] name = "flate2" version = "1.1.10" @@ -2038,14 +1935,14 @@ checksum = "8bf7cc16383c4b8d58b9905a8509f02926ce3058053c056376248d958c9df1e8" [[package]] name = "flume" -version = "0.11.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +checksum = "5e139bc46ca777eb5efaf62df0ab8cc5fd400866427e56c68b22e414e53bd3be" dependencies = [ + "fastrand", "futures-core", "futures-sink", - "nanorand", - "spin", + "spin 0.9.9", ] [[package]] @@ -2066,6 +1963,15 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" +[[package]] +name = "font-types" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b38ad915f6dadd993ced50848a8291a543bd41ca62bc10740d5e64e2ab4cfd7" +dependencies = [ + "bytemuck", +] + [[package]] name = "font-types" version = "0.12.5" @@ -2081,21 +1987,7 @@ version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbc773e24e02d4ddd8395fd30dc147524273a83e54e0f312d986ea30de5f5646" dependencies = [ - "roxmltree", -] - -[[package]] -name = "fontdb" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0299020c3ef3f60f526a4f64ab4a3d4ce116b1acbf24cdd22da0068e5d81dc3" -dependencies = [ - "fontconfig-parser", - "log", - "memmap2", - "slotmap", - "tinyvec", - "ttf-parser 0.20.0", + "roxmltree 0.20.0", ] [[package]] @@ -2109,7 +2001,7 @@ dependencies = [ "memmap2", "slotmap", "tinyvec", - "ttf-parser 0.25.1", + "ttf-parser", ] [[package]] @@ -2159,16 +2051,6 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "futf" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" -dependencies = [ - "mac", - "new_debug_unreachable", -] - [[package]] name = "futures" version = "0.3.34" @@ -2194,6 +2076,19 @@ dependencies = [ "futures-sink", ] +[[package]] +name = "futures-concurrency" +version = "7.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175cd8cca9e1d45b87f18ffa75088f2099e3c4fe5e2f83e42de112560bea8ea6" +dependencies = [ + "fixedbitset", + "futures-core", + "futures-lite", + "pin-project", + "smallvec", +] + [[package]] name = "futures-core" version = "0.3.34" @@ -2217,28 +2112,13 @@ version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" -[[package]] -name = "futures-lite" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" -dependencies = [ - "fastrand 1.9.0", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] - [[package]] name = "futures-lite" version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" dependencies = [ - "fastrand 2.5.0", + "fastrand", "futures-core", "futures-io", "parking", @@ -2323,16 +2203,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "gethostname" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" -dependencies = [ - "rustix 1.1.5", - "windows-link 0.2.1", -] - [[package]] name = "getrandom" version = "0.2.17" @@ -2340,10 +2210,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi", - "wasm-bindgen", ] [[package]] @@ -2353,9 +2221,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi 5.3.0", "wasip2", + "wasm-bindgen", ] [[package]] @@ -2368,7 +2238,6 @@ dependencies = [ "js-sys", "libc", "r-efi 6.0.0", - "rand_core 0.10.1", "wasm-bindgen", ] @@ -2389,16 +2258,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" [[package]] -name = "git2" -version = "0.20.4" +name = "gl_generator" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b88256088d75a56f8ecfa070513a775dd9107f6530ef14919dac831af9cfe2b" +checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" dependencies = [ - "bitflags 2.13.2", - "libc", - "libgit2-sys", + "khronos_api", "log", - "url", + "xml-rs", ] [[package]] @@ -2407,36 +2274,11 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" -[[package]] -name = "globset" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07c34a9410465b45bd9787443bc7370f37735bad04b0f0cd57ff1a3186c98988" -dependencies = [ - "aho-corasick", - "bstr", - "log", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "gloo-timers" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - [[package]] name = "glow" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e5ea60d70410161c8bf5da3fdfeaa1c72ed2c15f8bbb9d19fe3a4fad085f08" +checksum = "29038e1c483364cc6bb3cf78feee1816002e127c331a1eec55a4d202b9e1adb5" dependencies = [ "js-sys", "slotmap", @@ -2445,31 +2287,44 @@ dependencies = [ ] [[package]] -name = "gpu-alloc" -version = "0.6.2" +name = "glutin_wgl_sys" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45cf04b2726f02df5508c6de726acdc90cdf97ac771a9a0ffd8ba10a6e696bf9" +checksum = "2c4ee00b289aba7a9e5306d57c2d05499b2e5dc427f84ac708bd2c090212cf3e" dependencies = [ - "bitflags 2.13.2", - "gpu-alloc-types", + "gl_generator", ] [[package]] -name = "gpu-alloc-ash" -version = "0.7.1" +name = "gpu-allocator" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643756f08ef6def813c776199e4766596395a4c6530373c9a4374a64de2f53a1" +checksum = "51255ea7cfaadb6c5f1528d43e92a82acb2b96c43365989a28b2d44ee38f8795" dependencies = [ "ash", - "gpu-alloc-types", - "tinyvec", + "hashbrown 0.16.1", + "log", + "presser", + "thiserror 2.0.21", + "windows 0.57.0", ] [[package]] -name = "gpu-alloc-types" -version = "0.3.1" +name = "gpu-descriptor" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2bbed164dd10ed526c2e4fe3e721ca4a71c61730e5aafac6844b417b3227058" +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", ] @@ -2477,105 +2332,175 @@ dependencies = [ [[package]] name = "gpui" version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "979b45cfa6ec723b6f42330915a1b3769b930d02b2d505f9697f8ca602bee707" +source = "git+https://github.com/zed-industries/zed?rev=1a28cff4b409169bac058bca40dfbfeb7621d19b#1a28cff4b409169bac058bca40dfbfeb7621d19b" dependencies = [ + "accesskit", "anyhow", - "as-raw-xcb-connection", - "ashpd 0.11.1", + "async-channel", "async-task", "backtrace", "bindgen", - "blade-graphics", - "blade-macros", - "blade-util", - "block", - "bytemuck", - "calloop", - "calloop-wayland-source", - "cbindgen", - "cocoa 0.26.0", - "cocoa-foundation 0.2.0", - "core-foundation 0.10.0", - "core-foundation-sys", - "core-graphics 0.24.0", - "core-text", + "bitflags 2.13.2", + "chrono", + "collections", "core-video", - "cosmic-text", "ctor", - "derive_more 0.99.20", + "derive_more", "embed-resource", "etagere", - "filedescriptor", - "flume", - "foreign-types", "futures", - "gpui-macros", - "gpui_collections", - "gpui_http_client", - "gpui_media", - "gpui_refineable", - "gpui_semantic_version", - "gpui_sum_tree", + "futures-concurrency", + "getrandom 0.3.4", + "gpui_macros", + "gpui_shared_string", "gpui_util", - "gpui_util_macros", + "heapless", + "http_client", "image", "inventory", "itertools 0.14.0", - "libc", "log", "lyon", - "metal", - "naga", "num_cpus", - "objc", - "oo7", - "open", + "objc2-core-foundation", + "objc2-core-video", "parking", "parking_lot", - "pathfinder_geometry", "pin-project", + "pollster 0.4.0", "postage", "profiling", + "proptest", "rand 0.9.5", "raw-window-handle", + "refineable", + "regex", "resvg", + "scheduler", "schemars", "seahash", "serde", "serde_json", "slotmap", "smallvec", - "smol", + "spin 0.10.1", "stacksafe", - "strum 0.27.2", + "strum 0.28.0", + "sum_tree", "taffy", "thiserror 2.0.21", + "ttf-parser", + "url", "usvg", + "util_macros", "uuid", "waker-fn", - "wayland-backend", - "wayland-client", - "wayland-cursor", - "wayland-protocols 0.31.2", - "wayland-protocols-plasma", - "windows 0.61.3", - "windows-core 0.61.2", - "windows-numerics 0.2.0", - "windows-registry 0.5.3", - "x11-clipboard", - "x11rb", - "xkbcommon", - "zed-font-kit", + "web-time", + "windows 0.62.2", "zed-scap", - "zed-xim", ] [[package]] -name = "gpui-macros" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcb02dd63a2859714ac7b6b476937617c3c744157af1b49f7c904023a79039be" +name = "gpui_apple" +version = "0.1.0" +source = "git+https://github.com/zed-industries/zed?rev=1a28cff4b409169bac058bca40dfbfeb7621d19b#1a28cff4b409169bac058bca40dfbfeb7621d19b" +dependencies = [ + "anyhow", + "block2 0.6.2", + "cbindgen", + "cocoa 0.26.0", + "core-foundation 0.10.0", + "core-video", + "derive_more", + "etagere", + "foreign-types", + "gpui", + "image", + "log", + "metal", + "objc", + "objc2 0.6.4", + "parking_lot", +] + +[[package]] +name = "gpui_linux" +version = "0.1.0" +source = "git+https://github.com/zed-industries/zed?rev=1a28cff4b409169bac058bca40dfbfeb7621d19b#1a28cff4b409169bac058bca40dfbfeb7621d19b" +dependencies = [ + "accesskit", + "accesskit_unix", + "anyhow", + "bytemuck", + "calloop", + "collections", + "futures", + "gpui", + "gpui_util", + "http_client", + "libc", + "log", + "notify-rust", + "oo7", + "parking_lot", + "raw-window-handle", + "smallvec", + "smol", + "strum 0.28.0", + "url", + "uuid", +] + +[[package]] +name = "gpui_macos" +version = "0.1.0" +source = "git+https://github.com/zed-industries/zed?rev=1a28cff4b409169bac058bca40dfbfeb7621d19b#1a28cff4b409169bac058bca40dfbfeb7621d19b" +dependencies = [ + "accesskit", + "accesskit_macos", + "anyhow", + "async-task", + "block2 0.6.2", + "cocoa 0.26.0", + "collections", + "core-foundation 0.10.0", + "core-foundation-sys", + "core-graphics 0.24.0", + "core-text", + "ctor", + "dispatch2", + "foreign-types", + "futures", + "gpui", + "gpui_apple", + "gpui_util", + "image", + "itertools 0.14.0", + "libc", + "log", + "mach2", + "objc", + "objc2 0.6.4", + "objc2-app-kit 0.3.2", + "objc2-core-graphics", + "objc2-core-media", + "objc2-foundation 0.3.2", + "objc2-screen-capture-kit", + "objc2-user-notifications", + "parking_lot", + "pathfinder_geometry", + "raw-window-handle", + "semver", + "smallvec", + "strum 0.28.0", + "uuid", + "zed-font-kit", +] + +[[package]] +name = "gpui_macros" +version = "0.1.0" +source = "git+https://github.com/zed-industries/zed?rev=1a28cff4b409169bac058bca40dfbfeb7621d19b#1a28cff4b409169bac058bca40dfbfeb7621d19b" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -2584,182 +2509,118 @@ dependencies = [ ] [[package]] -name = "gpui_collections" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae39dc6d3d201be97e4bc08d96dbef2bc5b5c3d5734e05786e8cc3043342351c" -dependencies = [ - "indexmap", - "rustc-hash 2.1.3", -] - -[[package]] -name = "gpui_derive_refineable" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "644de174341a87b3478bd65b66bca38af868bcf2b2e865700523734f83cfc664" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.119", -] - -[[package]] -name = "gpui_http_client" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23822b0a6d2c5e6a42507980a0ab3848610ea908942c8ef98187f646f690335e" +name = "gpui_platform" +version = "0.1.0" +source = "git+https://github.com/zed-industries/zed?rev=1a28cff4b409169bac058bca40dfbfeb7621d19b#1a28cff4b409169bac058bca40dfbfeb7621d19b" dependencies = [ "anyhow", - "async-compression", - "async-fs", - "bytes", - "derive_more 0.99.20", - "futures", - "gpui_util", - "http", - "http-body", - "log", - "parking_lot", + "console_error_panic_hook", + "gpui", + "gpui_linux", + "gpui_macos", + "gpui_web", + "gpui_windows", +] + +[[package]] +name = "gpui_shared_string" +version = "0.1.0" +source = "git+https://github.com/zed-industries/zed?rev=1a28cff4b409169bac058bca40dfbfeb7621d19b#1a28cff4b409169bac058bca40dfbfeb7621d19b" +dependencies = [ + "schemars", "serde", - "serde_json", - "sha2 0.10.9", - "tempfile", - "url", - "zed-async-tar", - "zed-reqwest", -] - -[[package]] -name = "gpui_media" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05cb8912ae17371725132d2b7eec6797a255accc95d58ee5c1134b529810f14b" -dependencies = [ - "anyhow", - "bindgen", - "core-foundation 0.10.0", - "core-video", - "ctor", - "foreign-types", - "metal", - "objc", -] - -[[package]] -name = "gpui_perf" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40a0961dcf598955130e867f4b731150a20546427b41b1a63767c1037a86d77" -dependencies = [ - "gpui_collections", - "serde", - "serde_json", -] - -[[package]] -name = "gpui_refineable" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258cb099254e9468181aee5614410fba61db4ae115fc1d51b4a0b985f60d6641" -dependencies = [ - "gpui_derive_refineable", -] - -[[package]] -name = "gpui_semantic_version" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201e45eff7b695528fb3af6560a534943fbc2db5323d755b9d198bd743948e35" -dependencies = [ - "anyhow", - "serde", -] - -[[package]] -name = "gpui_sum_tree" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4f3bedd573fafafa13d1200b356c588cf094fb2786e3684bb3f5ea59b549fa9" -dependencies = [ - "arrayvec", - "log", - "rayon", + "smol_str", ] [[package]] name = "gpui_util" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68faea25903ae524de9af83990b9aa51bcbc8dd085929ac0aea7fd41905e05c3" +version = "0.1.0" +source = "git+https://github.com/zed-industries/zed?rev=1a28cff4b409169bac058bca40dfbfeb7621d19b#1a28cff4b409169bac058bca40dfbfeb7621d19b" dependencies = [ "anyhow", - "async-fs", - "async_zip", - "command-fds", - "dirs 4.0.0", - "dunce", - "futures", - "futures-lite 1.13.0", - "git2", - "globset", - "gpui_collections", - "gpui_util_macros", - "itertools 0.14.0", - "libc", "log", - "nix 0.29.0", - "rand 0.9.5", - "regex", - "rust-embed", - "schemars", - "serde", - "serde_json", - "serde_json_lenient", - "shlex 1.3.0", - "smol", - "take-until", - "tempfile", - "tendril 0.4.3", - "unicase", - "walkdir", "which", ] [[package]] -name = "gpui_util_macros" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c28f65ef47fb97e21e82fd4dd75ccc2506eda010c846dc8054015ea234f1a22" +name = "gpui_web" +version = "0.1.0" +source = "git+https://github.com/zed-industries/zed?rev=1a28cff4b409169bac058bca40dfbfeb7621d19b#1a28cff4b409169bac058bca40dfbfeb7621d19b" dependencies = [ - "gpui_perf", - "quote", - "syn 2.0.119", + "anyhow", + "console_error_panic_hook", + "futures", + "gpui", + "gpui_wgpu", + "http_client", + "js-sys", + "log", + "parking_lot", + "raw-window-handle", + "scheduler", + "smallvec", + "unicode-properties", + "unicode-script", + "unicode-segmentation", + "uuid", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm_thread", + "web-sys", + "web-time", ] [[package]] -name = "grid" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12101ecc8225ea6d675bc70263074eab6169079621c2186fe0c66590b2df9681" +name = "gpui_wgpu" +version = "0.1.0" +source = "git+https://github.com/zed-industries/zed?rev=1a28cff4b409169bac058bca40dfbfeb7621d19b#1a28cff4b409169bac058bca40dfbfeb7621d19b" +dependencies = [ + "anyhow", + "bytemuck", + "collections", + "cosmic-text", + "etagere", + "gpui", + "gpui_util", + "itertools 0.14.0", + "log", + "parking_lot", + "profiling", + "raw-window-handle", + "smallvec", + "swash", + "unicode-bidi", + "unicode-segmentation", + "web-sys", + "wgpu", +] [[package]] -name = "h2" -version = "0.4.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef8e5e5a340588f4452631496976cf8636d4a7ecf600239fdc27615d2530bc16" +name = "gpui_windows" +version = "0.1.0" +source = "git+https://github.com/zed-industries/zed?rev=1a28cff4b409169bac058bca40dfbfeb7621d19b#1a28cff4b409169bac058bca40dfbfeb7621d19b" dependencies = [ - "atomic-waker", - "bytes", - "fnv", - "futures-core", - "futures-sink", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", + "accesskit", + "accesskit_windows", + "anyhow", + "collections", + "dunce", + "etagere", + "futures", + "gpui", + "gpui_util", + "image", + "itertools 0.14.0", + "log", + "parking_lot", + "rand 0.9.5", + "raw-window-handle", + "smallvec", + "uuid", + "windows 0.62.2", + "windows-core 0.62.2", + "windows-numerics 0.3.1", + "windows-registry", ] [[package]] @@ -2775,10 +2636,26 @@ dependencies = [ ] [[package]] -name = "hashbrown" -version = "0.14.5" +name = "harfrust" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "9da2e5ae821f6e96664977bf974d6d6a2d6682f9ccee23e62ec1d134246845f9" +dependencies = [ + "bitflags 2.13.2", + "bytemuck", + "core_maths", + "read-fonts 0.37.0", + "smallvec", +] + +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] [[package]] name = "hashbrown" @@ -2789,6 +2666,17 @@ dependencies = [ "foldhash 0.1.5", ] +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.2.0", +] + [[package]] name = "hashbrown" version = "0.17.1" @@ -2798,6 +2686,16 @@ dependencies = [ "foldhash 0.2.0", ] +[[package]] +name = "heapless" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ba4bd83f9415b58b4ed8dc5714c76e626a105be4646c02630ad730ad3b5aa4" +dependencies = [ + "hash32", + "stable_deref_trait", +] + [[package]] name = "heck" version = "0.4.1" @@ -2828,17 +2726,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" -[[package]] -name = "hidden-trait" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ed9e850438ac849bec07e7d09fbe9309cbd396a5988c30b010580ce08860df" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "hkdf" version = "0.12.4" @@ -2897,24 +2784,25 @@ dependencies = [ ] [[package]] -name = "http-body-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23169fe34a5fbcdd3f3862e78fb9b6fccd5f02a6dc6f732547005d45631ce71c" +name = "http_client" +version = "0.1.0" +source = "git+https://github.com/zed-industries/zed?rev=1a28cff4b409169bac058bca40dfbfeb7621d19b#1a28cff4b409169bac058bca40dfbfeb7621d19b" dependencies = [ + "anyhow", + "async-compression", "bytes", - "futures-core", + "derive_more", + "futures", "http", "http-body", - "pin-project-lite", + "log", + "parking_lot", + "serde", + "serde_json", + "serde_urlencoded", + "url", ] -[[package]] -name = "httparse" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" - [[package]] name = "hybrid-array" version = "0.4.15" @@ -2925,61 +2813,27 @@ dependencies = [ ] [[package]] -name = "hyper" -version = "1.11.1" +name = "iana-time-zone" +version = "0.1.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b501faa50e7a26c3d3560ca625132f4078a17771f4810baf70475ae48cbe43" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" dependencies = [ - "atomic-waker", - "bytes", - "futures-channel", - "futures-core", - "h2", - "http", - "http-body", - "httparse", - "itoa", - "pin-project-lite", - "smallvec", - "tokio", - "want", + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core 0.57.0", ] [[package]] -name = "hyper-rustls" -version = "0.27.10" +name = "iana-time-zone-haiku" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfa8e654703247911e29c23fbeaa261834bd9bb74efba2f9acddc37bfb127f53" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "http", - "hyper", - "hyper-util", - "rustls", - "rustls-native-certs", - "tokio", - "tokio-rustls", - "tower-service", -] - -[[package]] -name = "hyper-util" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc03d96684f9226b8a787cdb71488417b53ab5ea8fdb1dac946cb9431cc8bff" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "http", - "http-body", - "httparse", - "hyper", - "libc", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", + "cc", ] [[package]] @@ -3104,7 +2958,6 @@ dependencies = [ "qoi", "ravif", "rayon", - "rgb", "tiff", "zune-core", "zune-jpeg", @@ -3117,14 +2970,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "525e9ff3e1a4be2fbea1fdf0e98686a6d98b4d8f937e1bf7402245af1909e8c3" dependencies = [ "byteorder-lite", - "quick-error", + "quick-error 2.0.1", ] [[package]] name = "imagesize" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edcd27d72f2f071c64249075f42e205ff93c9a4c5f6c6da53e79ed9f9832c285" +checksum = "09e54e57b4c48b40f7aec75635392b12b3421fa26fe8b4332e63138ed278459c" [[package]] name = "imgref" @@ -3154,15 +3007,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", -] - [[package]] name = "interpolate_name" version = "0.2.4" @@ -3195,31 +3039,6 @@ dependencies = [ "leaky-cow", ] -[[package]] -name = "ipnet" -version = "2.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791930b43c0d5973160d90a8f3894509f2b273430f5c5c73b668636d0287c5c0" - -[[package]] -name = "is-docker" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3" -dependencies = [ - "once_cell", -] - -[[package]] -name = "is-wsl" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" -dependencies = [ - "is-docker", - "once_cell", -] - [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -3417,36 +3236,32 @@ checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" dependencies = [ "libc", "libloading", + "pkg-config", ] +[[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + [[package]] name = "kurbo" -version = "0.11.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62026ae44756f8a599ba21140f350303d4f08dcdcc71b5ad9c9bb8128c13c62" +checksum = "4b60dfc32f652b926df6192e55525b16d186c69d47876c3ead4da5cc9f8450e2" dependencies = [ "arrayvec", "euclid", + "polycool", "smallvec", ] -[[package]] -name = "kv-log-macro" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" -dependencies = [ - "log", -] - [[package]] name = "lazy_static" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -dependencies = [ - "spin", -] [[package]] name = "leak" @@ -3469,6 +3284,12 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8" +[[package]] +name = "libbz2-rs-sys" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34b357333733e8260735ba5894eb928c02ecc69c78715f01a8019e7fa7f2db4c" + [[package]] name = "libc" version = "0.2.189" @@ -3485,18 +3306,6 @@ dependencies = [ "cc", ] -[[package]] -name = "libgit2-sys" -version = "0.18.5+1.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "005d6ae6eac1912906073e069f7db60b1fa98e052a68227824afe3e3a1c59ca2" -dependencies = [ - "cc", - "libc", - "libz-sys", - "pkg-config", -] - [[package]] name = "libloading" version = "0.8.9" @@ -3523,22 +3332,22 @@ dependencies = [ ] [[package]] -name = "libz-sys" -version = "1.1.29" +name = "linebender_resource_handle" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85bc9657773828b90eeb625adff10eeac83cc21bbfd8e23a03eaa8a33c9e28d9" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] +checksum = "d4a5ff6bcca6c4867b1c4fd4ef63e4db7436ef363e0ad7531d1558856bae64f4" [[package]] -name = "linux-raw-sys" -version = "0.4.15" +name = "link-section" +version = "0.19.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" +checksum = "39c29a617ce3df32c08497bdc1ab6e2376e0b17948ac166a2fbe5977c5954cd9" + +[[package]] +name = "linktime-proc-macro" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e57c38c1e860fd37c604281cdfb1dd2216977fd76a50f85ba2f388ef3219616" [[package]] name = "linux-raw-sys" @@ -3552,6 +3361,12 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" +[[package]] +name = "litrs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" + [[package]] name = "lock_api" version = "0.4.14" @@ -3589,12 +3404,6 @@ dependencies = [ "hashbrown 0.17.1", ] -[[package]] -name = "lru-slab" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4050469837a6ff301cd14c1f8f24f88549e6d548f24f64e2148eb0f72cebc51f" - [[package]] name = "lyon" version = "1.0.19" @@ -3648,10 +3457,27 @@ dependencies = [ ] [[package]] -name = "mac" -version = "0.1.1" +name = "mac-notification-sys" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" +checksum = "fd604973958ddcc11b561193c0fb96ba146506ef2f231ef2e7c35fd2cbc9beca" +dependencies = [ + "cc", + "log", + "objc2 0.6.4", + "objc2-foundation 0.3.2", + "time", + "uuid", +] + +[[package]] +name = "mach2" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a1b95cd5421ec55b445b5ae102f5ea0e768de1f82bd3001e11f426c269c3aea" +dependencies = [ + "libc", +] [[package]] name = "malloc_buf" @@ -3669,7 +3495,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7122d987ec5f704ee56f6e5b41a7d93722e9aae27ae07cafa4036c4d3f9757de" dependencies = [ "log", - "tendril 0.5.1", + "tendril", "web_atoms", ] @@ -3719,13 +3545,13 @@ dependencies = [ [[package]] name = "metal" -version = "0.29.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ecfd3296f8c56b7c1f6fbac3c71cefa9d78ce009850c45000015f206dc7fa21" +checksum = "c7047791b5bc903b8cd963014b355f71dc9864a9a0b727057676c1dcae5cbc15" dependencies = [ "bitflags 2.13.2", "block", - "core-graphics-types 0.1.3", + "core-graphics-types 0.2.0", "foreign-types", "log", "objc", @@ -3774,23 +3600,6 @@ dependencies = [ "simd-adler32", ] -[[package]] -name = "mint" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e53debba6bda7a793e5f99b8dacf19e626084f525f7829104ba9898f367d85ff" - -[[package]] -name = "mio" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b18443e9c262bfe8fa82f51666e2642c53393f7e5c27b3e1aeab922cff5b9d8" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.61.2", -] - [[package]] name = "miow" version = "0.6.1" @@ -3810,46 +3619,32 @@ dependencies = [ "pxfm", ] -[[package]] -name = "multiversion_no_op" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743fb55ba31b18fb1ecef6bdc9aa2743314978ac084044301a7eee33fb99a20d" - [[package]] name = "naga" -version = "25.0.1" +version = "29.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b977c445f26e49757f9aca3631c3b8b836942cb278d69a92e7b80d3b24da632" +checksum = "b2bf919621e7975acb27d881bae2fb993e0d45c8e0446e85e6272971e00dc8df" dependencies = [ "arrayvec", - "bit-set", + "bit-set 0.9.1", "bitflags 2.13.2", + "cfg-if", "cfg_aliases", "codespan-reporting", "half", - "hashbrown 0.15.5", + "hashbrown 0.16.1", "hexf-parse", "indexmap", + "libm", "log", "num-traits", "once_cell", "rustc-hash 1.1.0", "spirv", - "strum 0.26.3", "thiserror 2.0.21", "unicode-ident", ] -[[package]] -name = "nanorand" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" -dependencies = [ - "getrandom 0.2.17", -] - [[package]] name = "ndk" version = "0.9.0" @@ -3880,30 +3675,6 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" -[[package]] -name = "nix" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" -dependencies = [ - "bitflags 2.13.2", - "cfg-if", - "cfg_aliases", - "libc", -] - -[[package]] -name = "nix" -version = "0.31.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" -dependencies = [ - "bitflags 2.13.2", - "cfg-if", - "cfg_aliases", - "libc", -] - [[package]] name = "no_std_io2" version = "0.9.4" @@ -3938,6 +3709,20 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" +[[package]] +name = "notify-rust" +version = "4.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe430c879247371c47fdedd328ad4e301e6b30b533c5fd5db1c06d75253d0e46" +dependencies = [ + "futures-lite", + "log", + "mac-notification-sys", + "serde", + "tauri-winrt-notification", + "zbus", +] + [[package]] name = "ntapi" version = "0.4.3" @@ -3947,6 +3732,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.59.0", +] + [[package]] name = "num" version = "0.4.3" @@ -3973,16 +3767,16 @@ dependencies = [ [[package]] name = "num-bigint-dig" -version = "0.8.6" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" +checksum = "a7f9a86e097b0d187ad0e65667c2f58b9254671e86e7dbb78036b16692eae099" dependencies = [ - "lazy_static", "libm", "num-integer", "num-iter", "num-traits", - "rand 0.8.8", + "once_cell", + "rand 0.9.5", "serde", "smallvec", "zeroize", @@ -4108,6 +3902,22 @@ dependencies = [ "objc_id", ] +[[package]] +name = "objc-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" + +[[package]] +name = "objc2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" +dependencies = [ + "objc-sys", + "objc2-encode", +] + [[package]] name = "objc2" version = "0.6.4" @@ -4118,6 +3928,22 @@ dependencies = [ "objc2-exception-helper", ] +[[package]] +name = "objc2-app-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" +dependencies = [ + "bitflags 2.13.2", + "block2 0.5.1", + "libc", + "objc2 0.5.2", + "objc2-core-data", + "objc2-core-image", + "objc2-foundation 0.2.2", + "objc2-quartz-core 0.2.2", +] + [[package]] name = "objc2-app-kit" version = "0.3.2" @@ -4125,10 +3951,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" dependencies = [ "bitflags 2.13.2", - "objc2", + "block2 0.6.2", + "objc2 0.6.4", "objc2-core-foundation", - "objc2-foundation", - "objc2-quartz-core", + "objc2-foundation 0.3.2", +] + +[[package]] +name = "objc2-core-audio" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1eebcea8b0dbff5f7c8504f3107c68fc061a3eb44932051c8cf8a68d969c3b2" +dependencies = [ + "dispatch2", + "objc2 0.6.4", + "objc2-core-audio-types", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-core-audio-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a89f2ec274a0cf4a32642b2991e8b351a404d290da87bb6a9a9d8632490bd1c" +dependencies = [ + "bitflags 2.13.2", + "objc2 0.6.4", +] + +[[package]] +name = "objc2-core-data" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" +dependencies = [ + "bitflags 2.13.2", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -4139,7 +3999,70 @@ checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ "bitflags 2.13.2", "dispatch2", - "objc2", + "objc2 0.6.4", +] + +[[package]] +name = "objc2-core-graphics" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" +dependencies = [ + "bitflags 2.13.2", + "dispatch2", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-io-surface", +] + +[[package]] +name = "objc2-core-image" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", + "objc2-metal 0.2.2", +] + +[[package]] +name = "objc2-core-location" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca347214e24bc973fc025fd0d36ebb179ff30536ed1f80252706db19ee452009" +dependencies = [ + "objc2 0.6.4", + "objc2-foundation 0.3.2", +] + +[[package]] +name = "objc2-core-media" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05ec576860167a15dd9fce7fbee7512beb4e31f532159d3482d1f9c6caedf31d" +dependencies = [ + "bitflags 2.13.2", + "dispatch2", + "objc2 0.6.4", + "objc2-core-audio", + "objc2-core-audio-types", + "objc2-core-foundation", + "objc2-core-video", +] + +[[package]] +name = "objc2-core-video" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d425caf1df73233f29fd8a5c3e5edbc30d2d4307870f802d18f00d83dc5141a6" +dependencies = [ + "bitflags 2.13.2", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-io-surface", ] [[package]] @@ -4157,6 +4080,18 @@ dependencies = [ "cc", ] +[[package]] +name = "objc2-foundation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +dependencies = [ + "bitflags 2.13.2", + "block2 0.5.1", + "libc", + "objc2 0.5.2", +] + [[package]] name = "objc2-foundation" version = "0.3.2" @@ -4164,11 +4099,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ "bitflags 2.13.2", - "block2", - "objc2", + "block2 0.6.2", + "libc", + "objc2 0.6.4", "objc2-core-foundation", ] +[[package]] +name = "objc2-io-surface" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" +dependencies = [ + "bitflags 2.13.2", + "objc2 0.6.4", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-metal" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" +dependencies = [ + "bitflags 2.13.2", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + [[package]] name = "objc2-metal" version = "0.3.2" @@ -4176,9 +4135,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0125f776a10d00af4152d74616409f0d4a2053a6f57fa5b7d6aa2854ac04794" dependencies = [ "bitflags 2.13.2", - "block2", - "objc2", - "objc2-foundation", + "block2 0.6.2", + "objc2 0.6.4", + "objc2-foundation 0.3.2", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" +dependencies = [ + "bitflags 2.13.2", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", + "objc2-metal 0.2.2", ] [[package]] @@ -4188,10 +4160,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" dependencies = [ "bitflags 2.13.2", - "objc2", + "objc2 0.6.4", "objc2-core-foundation", - "objc2-foundation", - "objc2-metal", + "objc2-foundation 0.3.2", + "objc2-metal 0.3.2", +] + +[[package]] +name = "objc2-screen-capture-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74b7c5390f477482f001bc354d6571a70db7e4f8d5288e860c45521fbce11394" +dependencies = [ + "block2 0.6.2", + "dispatch2", + "objc2 0.6.4", + "objc2-core-graphics", + "objc2-core-media", + "objc2-foundation 0.3.2", ] [[package]] @@ -4201,10 +4187,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" dependencies = [ "bitflags 2.13.2", - "objc2", + "objc2 0.6.4", "objc2-core-foundation", - "objc2-foundation", - "objc2-quartz-core", + "objc2-foundation 0.3.2", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9df9128cbbfef73cda168416ccf7f837b62737d748333bfe9ab71c245d76613e" +dependencies = [ + "bitflags 2.13.2", + "block2 0.6.2", + "objc2 0.6.4", + "objc2-core-location", + "objc2-foundation 0.3.2", ] [[package]] @@ -4214,11 +4212,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2e5aaab980c433cf470df9d7af96a7b46a9d892d521a2cbbb2f8a4c16751e7f" dependencies = [ "bitflags 2.13.2", - "block2", - "objc2", - "objc2-app-kit", + "block2 0.6.2", + "objc2 0.6.4", + "objc2-app-kit 0.3.2", "objc2-core-foundation", - "objc2-foundation", + "objc2-foundation 0.3.2", ] [[package]] @@ -4271,12 +4269,12 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "oo7" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3299dd401feaf1d45afd8fd1c0586f10fcfb22f244bb9afa942cec73503b89d" +checksum = "78f2bfed90f1618b4b48dcad9307f25e14ae894e2949642c87c351601d62cebd" dependencies = [ "aes", - "ashpd 0.12.3", + "ashpd", "async-fs", "async-io", "async-lock", @@ -4285,17 +4283,17 @@ dependencies = [ "cipher", "digest 0.10.7", "endi", - "futures-lite 2.6.1", + "futures-lite", "futures-util", - "getrandom 0.3.4", + "getrandom 0.4.3", "hkdf", "hmac", "md-5", "num", "num-bigint-dig", "pbkdf2", - "rand 0.9.5", "serde", + "serde_bytes", "sha2 0.10.9", "subtle", "zbus", @@ -4304,28 +4302,21 @@ dependencies = [ "zvariant", ] -[[package]] -name = "open" -version = "5.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa576c76302b7b808eecc68061e67336c47833ef9d22caa74dda10fa9675eebc" -dependencies = [ - "is-wsl", - "libc", -] - -[[package]] -name = "openssl-probe" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" - [[package]] name = "option-ext" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "ordered-float" +version = "5.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c7c9e0d9b23589f26070720bac724174bfec1083e82f7854cdd0267518343c0" +dependencies = [ + "num-traits", +] + [[package]] name = "ordered-stream" version = "0.2.0" @@ -4360,7 +4351,7 @@ checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.18", + "redox_syscall", "smallvec", "windows-link 0.2.1", ] @@ -4412,6 +4403,16 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +[[package]] +name = "perf" +version = "0.1.0" +source = "git+https://github.com/zed-industries/zed?rev=1a28cff4b409169bac058bca40dfbfeb7621d19b#1a28cff4b409169bac058bca40dfbfeb7621d19b" +dependencies = [ + "collections", + "serde", + "serde_json", +] + [[package]] name = "phf" version = "0.11.3" @@ -4448,7 +4449,7 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" dependencies = [ - "fastrand 2.5.0", + "fastrand", "phf_shared 0.13.1", ] @@ -4515,12 +4516,6 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - [[package]] name = "piper" version = "0.2.5" @@ -4528,7 +4523,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c835479a4443ded371d6c535cbfd8d31ad92c5d23ae9770a61bc155e4992a3c1" dependencies = [ "atomic-waker", - "fastrand 2.5.0", + "fastrand", "futures-io", ] @@ -4574,7 +4569,7 @@ dependencies = [ "concurrent-queue", "hermit-abi", "pin-project-lite", - "rustix 1.1.5", + "rustix", "windows-sys 0.61.2", ] @@ -4584,6 +4579,21 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5da3b0203fd7ee5720aa0b5e790b591aa5d3f41c3ed2c34a3a393382198af2f7" +[[package]] +name = "pollster" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3" + +[[package]] +name = "polycool" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50596ddc09eb5ad5f75cacd40209568e66df71baf86e1499a0e99c4cff12a5a6" +dependencies = [ + "arrayvec", +] + [[package]] name = "portable-atomic" version = "1.15.0" @@ -4611,7 +4621,7 @@ dependencies = [ "log", "parking_lot", "pin-project", - "pollster", + "pollster 0.2.5", "static_assertions", "thiserror 1.0.69", ] @@ -4646,6 +4656,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +[[package]] +name = "presser" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" + [[package]] name = "prettyplease" version = "0.2.37" @@ -4665,28 +4681,6 @@ dependencies = [ "toml_edit 0.25.15+spec-1.1.0", ] -[[package]] -name = "proc-macro-error-attr2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" -dependencies = [ - "proc-macro2", - "quote", -] - -[[package]] -name = "proc-macro-error2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" -dependencies = [ - "proc-macro-error-attr2", - "proc-macro2", - "quote", - "syn 2.0.119", -] - [[package]] name = "proc-macro2" version = "1.0.107" @@ -4715,6 +4709,36 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "proptest" +version = "1.10.0" +source = "git+https://github.com/proptest-rs/proptest?rev=3dca198a8fef1b32e3a66f1e1897c955b4dc5b5b#3dca198a8fef1b32e3a66f1e1897c955b4dc5b5b" +dependencies = [ + "bit-set 0.8.0", + "bit-vec 0.8.0", + "bitflags 2.13.2", + "num-traits", + "proptest-macro", + "rand 0.9.5", + "rand_chacha 0.9.0", + "rand_xorshift", + "regex-syntax", + "rusty-fork", + "tempfile", + "unarray", +] + +[[package]] +name = "proptest-macro" +version = "0.5.0" +source = "git+https://github.com/proptest-rs/proptest?rev=3dca198a8fef1b32e3a66f1e1897c955b4dc5b5b#3dca198a8fef1b32e3a66f1e1897c955b4dc5b5b" +dependencies = [ + "convert_case 0.11.0", + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "psm" version = "0.1.32" @@ -4780,6 +4804,12 @@ version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d68782463e408eb1e668cf6152704bd856c78c5b6417adaee3203d8f4c1fc9ec" +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quick-error" version = "2.0.1" @@ -4795,62 +4825,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "quinn" -version = "0.11.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4051e23e9185c255a7e33ef59cdbca87a22d359052eecd22fc6b901fb37d9d11" -dependencies = [ - "bytes", - "cfg_aliases", - "pin-project-lite", - "quinn-proto", - "quinn-udp", - "rustc-hash 2.1.3", - "rustls", - "socket2", - "thiserror 2.0.21", - "tokio", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-proto" -version = "0.11.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9746dbde176634f4f2f1faf2404e30a31b2bc1e9cafb5329c95d8177a18c9fc" -dependencies = [ - "bytes", - "getrandom 0.4.3", - "lru-slab", - "rand 0.10.3", - "rand_pcg", - "ring", - "rustc-hash 2.1.3", - "rustls", - "rustls-pki-types", - "slab", - "thiserror 2.0.21", - "tinyvec", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-udp" -version = "0.5.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35a133f956daabe89a61a685c2649f13d82d5aa4bd5d12d1277e1072a21c0694" -dependencies = [ - "cfg_aliases", - "libc", - "once_cell", - "socket2", - "tracing", - "windows-sys 0.61.2", -] - [[package]] name = "quote" version = "1.0.47" @@ -4893,17 +4867,6 @@ dependencies = [ "rand_core 0.9.5", ] -[[package]] -name = "rand" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65c9fb96cbc91e3478eaae79a69fcd3f1ae4ad052e471fe6732fff548984b4af" -dependencies = [ - "chacha20", - "getrandom 0.4.3", - "rand_core 0.10.1", -] - [[package]] name = "rand_chacha" version = "0.3.1" @@ -4943,19 +4906,19 @@ dependencies = [ ] [[package]] -name = "rand_core" -version = "0.10.1" +name = "rand_xorshift" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" +dependencies = [ + "rand_core 0.9.5", +] [[package]] -name = "rand_pcg" -version = "0.10.2" +name = "range-alloc" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a" -dependencies = [ - "rand_core 0.10.1", -] +checksum = "ca45419789ae5a7899559e9512e58ca889e41f04f1f2445e9f4b290ceccd1d08" [[package]] name = "rangemap" @@ -5007,7 +4970,7 @@ dependencies = [ "avif-serialize", "imgref", "loop9", - "quick-error", + "quick-error 2.0.1", "rav1e", "rayon", "rgb", @@ -5030,14 +4993,14 @@ checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" [[package]] name = "raw-window-metal" -version = "0.4.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76e8caa82e31bb98fee12fa8f051c94a6aa36b07cddb03f0d4fc558988360ff1" +checksum = "40d213455a5f1dc59214213c7330e074ddf8114c9a42411eb890c767357ce135" dependencies = [ - "cocoa 0.25.0", - "core-graphics 0.23.2", - "objc", - "raw-window-handle", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "objc2-quartz-core 0.3.2", ] [[package]] @@ -5060,6 +5023,17 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "read-fonts" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b634fabf032fab15307ffd272149b622260f55974d9fad689292a5d33df02e5" +dependencies = [ + "bytemuck", + "core_maths", + "font-types 0.11.3", +] + [[package]] name = "read-fonts" version = "0.41.0" @@ -5067,7 +5041,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046a7d674daf459825b32f5062056d6882db0d2f5a479fbd76ccfc870ac18709" dependencies = [ "bytemuck", - "font-types", + "font-types 0.12.5", "once_cell", ] @@ -5077,15 +5051,6 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03251193000f4bd3b042892be858ee50e8b3719f2b08e5833ac4353724632430" -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.5.18" @@ -5095,17 +5060,6 @@ dependencies = [ "bitflags 2.13.2", ] -[[package]] -name = "redox_users" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" -dependencies = [ - "getrandom 0.2.17", - "libredox", - "thiserror 1.0.69", -] - [[package]] name = "redox_users" version = "0.5.3" @@ -5136,6 +5090,14 @@ dependencies = [ "syn 3.0.6", ] +[[package]] +name = "refineable" +version = "0.1.0" +source = "git+https://github.com/zed-industries/zed?rev=1a28cff4b409169bac058bca40dfbfeb7621d19b#1a28cff4b409169bac058bca40dfbfeb7621d19b" +dependencies = [ + "derive_refineable", +] + [[package]] name = "regex" version = "1.13.1" @@ -5166,17 +5128,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] -name = "resvg" -version = "0.45.1" +name = "renderdoc-sys" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8928798c0a55e03c9ca6c4c6846f76377427d2c1e1f7e6de3c06ae57942df43" +checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" + +[[package]] +name = "resvg" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b563218631706d614e23059436526d005b50ab5f2d506b55a17eb65c5eb83419" dependencies = [ + "gif", + "image-webp", "log", "pico-args", "rgb", "svgtypes", "tiny-skia", "usvg", + "zune-jpeg", ] [[package]] @@ -5188,26 +5159,21 @@ dependencies = [ "bytemuck", ] -[[package]] -name = "ring" -version = "0.17.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" -dependencies = [ - "cc", - "cfg-if", - "getrandom 0.2.17", - "libc", - "untrusted", - "windows-sys 0.52.0", -] - [[package]] name = "roxmltree" version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" +[[package]] +name = "roxmltree" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1964b10c76125c36f8afe190065a4bf9a87bf324842c05701330bba9f1cacbb" +dependencies = [ + "memchr", +] + [[package]] name = "rqrr" version = "0.11.0" @@ -5249,7 +5215,6 @@ version = "8.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ffa149f6aa81b58a5b3011d01a857c4ed12c7a732d2c51947a4c7c692185f0" dependencies = [ - "globset", "sha2 0.11.0", "walkdir", ] @@ -5281,19 +5246,6 @@ dependencies = [ "semver", ] -[[package]] -name = "rustix" -version = "0.38.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" -dependencies = [ - "bitflags 2.13.2", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", -] - [[package]] name = "rustix" version = "1.1.5" @@ -5303,7 +5255,7 @@ dependencies = [ "bitflags 2.13.2", "errno", "libc", - "linux-raw-sys 0.12.1", + "linux-raw-sys", "windows-sys 0.61.2", ] @@ -5315,63 +5267,7 @@ checksum = "1de16c7c59892b870a6336f185dc10943517f1327447096bbb7bb32cd85e2393" dependencies = [ "errno", "libc", - "rustix 1.1.5", -] - -[[package]] -name = "rustls" -version = "0.23.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d41d731c7d2f962d1ccc364cec258de3c0e93b38c2fb3ba97ac74513048d634" -dependencies = [ - "once_cell", - "ring", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls-native-certs" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d" -dependencies = [ - "openssl-probe", - "rustls-pki-types", - "schannel", - "security-framework", -] - -[[package]] -name = "rustls-pemfile" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" -dependencies = [ - "rustls-pki-types", -] - -[[package]] -name = "rustls-pki-types" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96" -dependencies = [ - "web-time", - "zeroize", -] - -[[package]] -name = "rustls-webpki" -version = "0.103.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2" -dependencies = [ - "ring", - "rustls-pki-types", - "untrusted", + "rustix", ] [[package]] @@ -5381,20 +5277,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" [[package]] -name = "rustybuzz" -version = "0.14.1" +name = "rusty-fork" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfb9cf8877777222e4a3bc7eb247e398b56baba500c38c1c46842431adc8b55c" +checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2" dependencies = [ - "bitflags 2.13.2", - "bytemuck", - "libm", - "smallvec", - "ttf-parser 0.21.1", - "unicode-bidi-mirroring 0.2.0", - "unicode-ccc 0.2.0", - "unicode-properties", - "unicode-script", + "fnv", + "quick-error 1.2.3", + "tempfile", + "wait-timeout", ] [[package]] @@ -5408,9 +5299,9 @@ dependencies = [ "core_maths", "log", "smallvec", - "ttf-parser 0.25.1", - "unicode-bidi-mirroring 0.4.0", - "unicode-ccc 0.4.0", + "ttf-parser", + "unicode-bidi-mirroring", + "unicode-ccc", "unicode-properties", "unicode-script", ] @@ -5431,12 +5322,19 @@ dependencies = [ ] [[package]] -name = "schannel" -version = "0.1.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" +name = "scheduler" +version = "0.1.0" +source = "git+https://github.com/zed-industries/zed?rev=1a28cff4b409169bac058bca40dfbfeb7621d19b#1a28cff4b409169bac058bca40dfbfeb7621d19b" dependencies = [ - "windows-sys 0.61.2", + "async-task", + "backtrace", + "chrono", + "flume", + "futures", + "parking_lot", + "rand 0.9.5", + "wasm_thread", + "web-time", ] [[package]] @@ -5465,12 +5363,6 @@ dependencies = [ "syn 3.0.6", ] -[[package]] -name = "scoped-tls" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" - [[package]] name = "scopeguard" version = "1.2.0" @@ -5506,29 +5398,6 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" -[[package]] -name = "security-framework" -version = "3.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" -dependencies = [ - "bitflags 2.13.2", - "core-foundation 0.10.0", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "selectors" version = "0.38.0" @@ -5537,7 +5406,7 @@ checksum = "8adfa1c298912827b8a28b223b3b874357397ae706e6190acd9bf28cee99114d" dependencies = [ "bitflags 2.13.2", "cssparser", - "derive_more 2.1.1", + "derive_more", "log", "new_debug_unreachable", "phf 0.13.1", @@ -5559,6 +5428,10 @@ name = "semver" version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" +dependencies = [ + "serde", + "serde_core", +] [[package]] name = "serde" @@ -5570,6 +5443,16 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde_bytes" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" +dependencies = [ + "serde", + "serde_core", +] + [[package]] name = "serde_core" version = "1.0.229" @@ -5624,19 +5507,6 @@ dependencies = [ "zmij", ] -[[package]] -name = "serde_json_lenient" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e033097bf0d2b59a62b42c18ebbb797503839b26afdda2c4e1415cb6c813540" -dependencies = [ - "indexmap", - "itoa", - "memchr", - "ryu", - "serde", -] - [[package]] name = "serde_repr" version = "0.1.21" @@ -5715,6 +5585,15 @@ dependencies = [ "digest 0.11.3", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shlex" version = "1.3.0" @@ -5762,12 +5641,6 @@ dependencies = [ "quote", ] -[[package]] -name = "simdutf8" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" - [[package]] name = "similar" version = "3.2.0" @@ -5793,6 +5666,16 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" +[[package]] +name = "skrifa" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fbdfe3d2475fbd7ddd1f3e5cf8288a30eb3e5f95832829570cd88115a7434ac" +dependencies = [ + "bytemuck", + "read-fonts 0.37.0", +] + [[package]] name = "skrifa" version = "0.44.0" @@ -5800,7 +5683,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "819ab7d62b1d3e72d9d9dea5650bac30424f9111364bb94928dbf5ecad1baa68" dependencies = [ "bytemuck", - "read-fonts", + "read-fonts 0.41.0", ] [[package]] @@ -5830,7 +5713,7 @@ version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a33bd3e260892199c3ccfc487c88b2da2265080acb316cd920da72fdfd7c599f" dependencies = [ - "async-channel 2.5.0", + "async-channel", "async-executor", "async-fs", "async-io", @@ -5838,23 +5721,17 @@ dependencies = [ "async-net", "async-process", "blocking", - "futures-lite 2.6.1", + "futures-lite", ] [[package]] name = "smol_str" -version = "0.2.2" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" - -[[package]] -name = "socket2" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" +checksum = "4aaa7368fcf4852a4c2dd92df0cace6a71f2091ca0a23391ce7f3a31833f1523" dependencies = [ - "libc", - "windows-sys 0.61.2", + "borsh", + "serde_core", ] [[package]] @@ -5867,10 +5744,19 @@ dependencies = [ ] [[package]] -name = "spirv" -version = "0.3.0+sdk-1.3.268.0" +name = "spin" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" +checksum = "023a211cb3138dbc438680b32560ad89f699977624c9f8dbb95a47d5b4c07dd3" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spirv" +version = "0.4.0+sdk-1.4.341.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9571ea910ebd84c86af4b3ed27f9dbdc6ad06f17c5f96146b2b671e2976744f" dependencies = [ "bitflags 2.13.2", ] @@ -5896,9 +5782,9 @@ dependencies = [ [[package]] name = "stacksafe" -version = "0.1.4" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d9c1172965d317e87ddb6d364a040d958b40a1db82b6ef97da26253a8b3d090" +checksum = "95f9c34983ac74195c710c473db6fdf1085f64a47dbaa0090d1bea03be70da66" dependencies = [ "stacker", "stacksafe-macro", @@ -5906,13 +5792,13 @@ dependencies = [ [[package]] name = "stacksafe-macro" -version = "0.1.4" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "172175341049678163e979d9107ca3508046d4d2a7c6682bee46ac541b17db69" +checksum = "6feeae42a2d6b0dcb8aeb2f08d9e48cdac600239cf8a20fc59f9e252e86bdfe1" dependencies = [ - "proc-macro-error2", + "proc-macro2", "quote", - "syn 2.0.119", + "syn 3.0.6", ] [[package]] @@ -5954,15 +5840,6 @@ dependencies = [ "quote", ] -[[package]] -name = "strum" -version = "0.26.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" -dependencies = [ - "strum_macros 0.26.4", -] - [[package]] name = "strum" version = "0.27.2" @@ -5973,16 +5850,12 @@ dependencies = [ ] [[package]] -name = "strum_macros" -version = "0.26.4" +name = "strum" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd" dependencies = [ - "heck 0.5.0", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.119", + "strum_macros 0.28.0", ] [[package]] @@ -5997,12 +5870,36 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "strum_macros" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "subtle" version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "sum_tree" +version = "0.1.0" +source = "git+https://github.com/zed-industries/zed?rev=1a28cff4b409169bac058bca40dfbfeb7621d19b#1a28cff4b409169bac058bca40dfbfeb7621d19b" +dependencies = [ + "heapless", + "log", + "rayon", + "tracing", + "ztracing", +] + [[package]] name = "sval" version = "2.22.0" @@ -6090,9 +5987,9 @@ checksum = "0193cc4331cfd2f3d2011ef287590868599a2f33c3e69bc22c1a3d3acf9e02fb" [[package]] name = "svgtypes" -version = "0.15.3" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68c7541fff44b35860c1a7a47a7cadf3e4a304c457b58f9870d9706ece028afc" +checksum = "695b5790b3131dafa99b3bbfd25a216edb3d216dad9ca208d4657bfb8f2abc3d" dependencies = [ "kurbo", "siphasher", @@ -6104,22 +6001,11 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c2499c2d826531388872b2268718aed907a39bd785ab0dcfe57fab26283f92e" dependencies = [ - "skrifa", + "skrifa 0.44.0", "yazi", "zeno", ] -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.119" @@ -6142,15 +6028,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "sync_wrapper" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" -dependencies = [ - "futures-core", -] - [[package]] name = "synstructure" version = "0.14.0" @@ -6185,45 +6062,18 @@ dependencies = [ "windows 0.57.0", ] -[[package]] -name = "system-configuration" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" -dependencies = [ - "bitflags 2.13.2", - "core-foundation 0.9.4", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "taffy" -version = "0.9.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13e5d13f79d558b5d353a98072ca8ca0e99da429467804de959aa8c83c9a004" +checksum = "c034e05f6ee85a12daa63863c2245797715075c70649947aa0da54f3f2ab1d0f" dependencies = [ "arrayvec", - "grid", "serde", "slotmap", + "smallvec", ] -[[package]] -name = "take-until" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bdb6fa0dfa67b38c1e66b7041ba9dcf23b99d8121907cd31c807a332f7a0bbb" - [[package]] name = "tao-core-video-sys" version = "0.2.0" @@ -6247,30 +6097,30 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "tauri-winrt-notification" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f37a6c354fd28fc9e322ed9bd47e3959576dad28c9d58ea1cf888cce1c7ccb36" +dependencies = [ + "thiserror 2.0.21", + "windows 0.62.2", + "windows-version", +] + [[package]] name = "tempfile" version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ - "fastrand 2.5.0", + "fastrand", "getrandom 0.4.3", "once_cell", - "rustix 1.1.5", + "rustix", "windows-sys 0.61.2", ] -[[package]] -name = "tendril" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" -dependencies = [ - "futf", - "mac", - "utf-8", -] - [[package]] name = "tendril" version = "0.5.1" @@ -6329,6 +6179,15 @@ dependencies = [ "syn 3.0.6", ] +[[package]] +name = "thread_local" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" +dependencies = [ + "cfg-if", +] + [[package]] name = "tiff" version = "0.11.3" @@ -6338,7 +6197,7 @@ dependencies = [ "fax", "flate2", "half", - "quick-error", + "quick-error 2.0.1", "weezl", "zune-jpeg", ] @@ -6373,15 +6232,6 @@ dependencies = [ "time-core", ] -[[package]] -name = "tiny-keccak" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" -dependencies = [ - "crunchy", -] - [[package]] name = "tiny-skia" version = "0.11.4" @@ -6424,56 +6274,6 @@ version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd3ca314f692efd6c868f8408f53fe444634a845f96c028b97d35f6a1f79f0ee" -[[package]] -name = "tokio" -version = "1.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" -dependencies = [ - "bytes", - "libc", - "mio", - "pin-project-lite", - "socket2", - "windows-sys 0.61.2", -] - -[[package]] -name = "tokio-rustls" -version = "0.26.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c85f2c3ef0b1cd58b36682f4b17aaa995f0e5db534d85692b4903abce21f67" -dependencies = [ - "rustls", - "tokio", -] - -[[package]] -name = "tokio-socks" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7e2948f60dbe26b35f2c7fb74ac2854c1fddded0fe9d7548fcc674a246f7615" -dependencies = [ - "either", - "futures-util", - "thiserror 1.0.69", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "libc", - "pin-project-lite", - "tokio", -] - [[package]] name = "toml" version = "0.8.23" @@ -6566,39 +6366,13 @@ version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2" -[[package]] -name = "tower" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" -dependencies = [ - "futures-core", - "futures-util", - "pin-project-lite", - "sync_wrapper", - "tokio", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - [[package]] name = "tracing" version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -6622,25 +6396,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", + "valuable", ] [[package]] -name = "try-lock" -version = "0.2.5" +name = "tracing-log" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] [[package]] -name = "ttf-parser" -version = "0.20.0" +name = "tracing-subscriber" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4" - -[[package]] -name = "ttf-parser" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" +dependencies = [ + "nu-ansi-term", + "sharded-slab", + "smallvec", + "thread_local", + "tracing-core", + "tracing-log", +] [[package]] name = "ttf-parser" @@ -6674,6 +6456,12 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + [[package]] name = "unicase" version = "2.9.0" @@ -6686,24 +6474,12 @@ version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" -[[package]] -name = "unicode-bidi-mirroring" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23cb788ffebc92c5948d0e997106233eeb1d8b9512f93f41651f52b6c5f5af86" - [[package]] name = "unicode-bidi-mirroring" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dfa6e8c60bb66d49db113e0125ee8711b7647b5579dc7f5f19c42357ed039fe" -[[package]] -name = "unicode-ccc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df77b101bcc4ea3d78dafc5ad7e4f58ceffe0b2b16bf446aeb50b6cb4157656" - [[package]] name = "unicode-ccc" version = "0.4.0" @@ -6724,9 +6500,9 @@ checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" [[package]] name = "unicode-properties" -version = "0.1.4" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" +checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" [[package]] name = "unicode-script" @@ -6753,10 +6529,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] -name = "untrusted" -version = "0.9.0" +name = "unicode-xid" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "url" @@ -6768,25 +6544,24 @@ dependencies = [ "idna", "percent-encoding", "serde", - "serde_derive", ] [[package]] name = "usvg" -version = "0.45.1" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80be9b06fbae3b8b303400ab20778c80bbaf338f563afe567cf3c9eea17b47ef" +checksum = "e419dff010bb12512b0ae9e3d2f318dfbdf0167fde7eb05465134d4e8756076f" dependencies = [ "base64", "data-url", "flate2", - "fontdb 0.23.0", + "fontdb", "imagesize", "kurbo", "log", "pico-args", - "roxmltree", - "rustybuzz 0.20.1", + "roxmltree 0.21.1", + "rustybuzz", "simplecss", "siphasher", "strict-num", @@ -6798,12 +6573,6 @@ dependencies = [ "xmlwriter", ] -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - [[package]] name = "utf8_iter" version = "1.0.4" @@ -6816,6 +6585,16 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "util_macros" +version = "0.1.0" +source = "git+https://github.com/zed-industries/zed?rev=1a28cff4b409169bac058bca40dfbfeb7621d19b#1a28cff4b409169bac058bca40dfbfeb7621d19b" +dependencies = [ + "perf", + "quote", + "syn 2.0.119", +] + [[package]] name = "uuid" version = "1.26.1" @@ -6840,6 +6619,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + [[package]] name = "value-bag" version = "1.14.1" @@ -6876,12 +6661,6 @@ dependencies = [ "sval_serde", ] -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "version_check" version = "0.9.5" @@ -6921,6 +6700,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "wait-timeout" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" +dependencies = [ + "libc", +] + [[package]] name = "waker-fn" version = "1.2.0" @@ -6937,15 +6725,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" @@ -7017,103 +6796,16 @@ dependencies = [ ] [[package]] -name = "wasm-streams" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +name = "wasm_thread" +version = "0.3.3" +source = "git+https://github.com/zed-industries/wasm_thread?rev=0cf96c7708dfb97ccf3da50347e25edcf75d6937#0cf96c7708dfb97ccf3da50347e25edcf75d6937" dependencies = [ - "futures-util", + "futures", "js-sys", "wasm-bindgen", - "wasm-bindgen-futures", "web-sys", ] -[[package]] -name = "wayland-backend" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38a91b4eaddff87b1cd1074985e3713da4af2c49742d1b356b2c01670a67a078" -dependencies = [ - "cc", - "downcast-rs", - "rustix 1.1.5", - "scoped-tls", - "smallvec", - "wayland-sys", -] - -[[package]] -name = "wayland-client" -version = "0.31.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c36a0f861ad76d0901f2800b46321410d9f73f2ea88aac0650d86c32688073" -dependencies = [ - "bitflags 2.13.2", - "rustix 1.1.5", - "wayland-backend", - "wayland-scanner", -] - -[[package]] -name = "wayland-cursor" -version = "0.31.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a52d18780be9b1314328a3de5f930b73d2200112e3849ca6cb11822793fb34d" -dependencies = [ - "rustix 1.1.5", - "wayland-client", - "xcursor", -] - -[[package]] -name = "wayland-protocols" -version = "0.31.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" -dependencies = [ - "bitflags 2.13.2", - "wayland-backend", - "wayland-client", - "wayland-scanner", -] - -[[package]] -name = "wayland-protocols" -version = "0.32.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d0c813de3daa2ed6520af85a3bd49b0e722a3078506899aa9686fea58dc4b6" -dependencies = [ - "bitflags 2.13.2", - "wayland-backend", - "wayland-client", - "wayland-scanner", -] - -[[package]] -name = "wayland-protocols-plasma" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479" -dependencies = [ - "bitflags 2.13.2", - "wayland-backend", - "wayland-client", - "wayland-protocols 0.31.2", - "wayland-scanner", -] - -[[package]] -name = "wayland-scanner" -version = "0.31.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "338e30461b3a2b67d70eb30a6d89f8e0c93a833e07d2ae89085cd070c4a00ac0" -dependencies = [ - "proc-macro2", - "quick-xml", - "quote", -] - [[package]] name = "wayland-sys" version = "0.31.11" @@ -7199,15 +6891,190 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" [[package]] -name = "which" -version = "6.0.3" +name = "wgpu" +version = "29.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ee928febd44d98f2f459a4a79bd4d928591333a494a10a868418ac1b39cf1f" +checksum = "76e8840e1ba2881d4cbb18d2147627a56af426ff064c0401eb0c8410c6325d07" dependencies = [ - "either", - "home", - "rustix 0.38.44", - "winsafe", + "arrayvec", + "bitflags 2.13.2", + "bytemuck", + "cfg-if", + "cfg_aliases", + "document-features", + "hashbrown 0.16.1", + "js-sys", + "log", + "naga", + "parking_lot", + "portable-atomic", + "profiling", + "raw-window-handle", + "smallvec", + "static_assertions", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "wgpu-core", + "wgpu-hal", + "wgpu-types", +] + +[[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", + "once_cell", + "parking_lot", + "portable-atomic", + "profiling", + "raw-window-handle", + "rustc-hash 1.1.0", + "smallvec", + "thiserror 2.0.21", + "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]] +name = "wgpu-core-deps-apple" +version = "29.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5e39e26c4c0e07589e67d18546cf79ff45383659fc72fca4dd293358a0347f3" +dependencies = [ + "wgpu-hal", +] + +[[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", +] + +[[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", +] + +[[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", +] + +[[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", + "ndk-sys", + "objc2 0.6.4", + "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", + "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", + "wgpu-types", +] + +[[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", +] + +[[package]] +name = "which" +version = "8.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bae2f2b2b816647a1cab1acc91f5bd20812d53cb344382635ec2181940c8034f" +dependencies = [ + "libc", ] [[package]] @@ -7445,24 +7312,13 @@ dependencies = [ [[package]] name = "windows-registry" -version = "0.4.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" dependencies = [ - "windows-result 0.3.4", - "windows-strings 0.3.1", - "windows-targets 0.53.5", -] - -[[package]] -name = "windows-registry" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" -dependencies = [ - "windows-link 0.1.3", - "windows-result 0.3.4", - "windows-strings 0.4.2", + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", ] [[package]] @@ -7492,15 +7348,6 @@ dependencies = [ "windows-link 0.2.1", ] -[[package]] -name = "windows-strings" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" -dependencies = [ - "windows-link 0.1.3", -] - [[package]] name = "windows-strings" version = "0.4.2" @@ -7528,24 +7375,6 @@ dependencies = [ "windows-targets 0.42.2", ] -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-sys" version = "0.59.0" @@ -7579,21 +7408,6 @@ dependencies = [ "windows_x86_64_msvc 0.42.2", ] -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - [[package]] name = "windows-targets" version = "0.52.6" @@ -7603,30 +7417,13 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", + "windows_i686_gnullvm", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link 0.2.1", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", -] - [[package]] name = "windows-threading" version = "0.1.0" @@ -7660,180 +7457,90 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - [[package]] name = "windows_aarch64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - [[package]] name = "windows_i686_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - [[package]] name = "windows_i686_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - [[package]] name = "windows_x86_64_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - [[package]] name = "windows_x86_64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - [[package]] name = "winnow" version = "0.7.15" @@ -7862,12 +7569,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "winsafe" -version = "0.0.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" - [[package]] name = "wio" version = "0.2.2" @@ -7896,7 +7597,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a819957a01b3119af85e638a38d242af76dbc87d130dca67bfd0441072e21ff0" dependencies = [ "base64", - "block2", + "block2 0.6.2", "cookie", "crossbeam-channel", "dirs 7.0.0", @@ -7907,10 +7608,10 @@ dependencies = [ "jni", "libc", "ndk", - "objc2", - "objc2-app-kit", + "objc2 0.6.4", + "objc2-app-kit 0.3.2", "objc2-core-foundation", - "objc2-foundation", + "objc2-foundation 0.3.2", "objc2-ui-kit", "objc2-web-kit", "once_cell", @@ -7936,45 +7637,6 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "x11-clipboard" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "662d74b3d77e396b8e5beb00b9cad6a9eccf40b2ef68cc858784b14c41d535a3" -dependencies = [ - "libc", - "x11rb", -] - -[[package]] -name = "x11rb" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414" -dependencies = [ - "as-raw-xcb-connection", - "gethostname", - "libc", - "rustix 1.1.5", - "x11rb-protocol", - "xcursor", -] - -[[package]] -name = "x11rb-protocol" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" - -[[package]] -name = "xattr" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc" -dependencies = [ - "libc", -] - [[package]] name = "xcb" version = "1.7.1" @@ -7988,46 +7650,10 @@ dependencies = [ ] [[package]] -name = "xcursor" -version = "0.3.11" +name = "xml-rs" +version = "0.8.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "163b33ed8786455e2fa5d72f554057ce3f3182425434f756cd39c99839d88e23" - -[[package]] -name = "xim-ctext" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ac61a7062c40f3c37b6e82eeeef835d5cc7824b632a72784a89b3963c33284c" -dependencies = [ - "encoding_rs", -] - -[[package]] -name = "xim-parser" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dcee45f89572d5a65180af3a84e7ddb24f5ea690a6d3aa9de231281544dd7b7" -dependencies = [ - "bitflags 2.13.2", -] - -[[package]] -name = "xkbcommon" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d66ca9352cbd4eecbbc40871d8a11b4ac8107cfc528a6e14d7c19c69d0e1ac9" -dependencies = [ - "as-raw-xcb-connection", - "libc", - "memmap2", - "xkeysym", -] - -[[package]] -name = "xkeysym" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" +checksum = "e450f9b2ed1dff33c94c12589a87338689467b9c4f5d8a5710bd09a847d2c8a7" [[package]] name = "xmlwriter" @@ -8097,13 +7723,13 @@ dependencies = [ "async-trait", "blocking", "enumflags2", - "event-listener 5.4.2", + "event-listener", "futures-core", - "futures-lite 2.6.1", + "futures-lite", "hex", "libc", "ordered-stream", - "rustix 1.1.5", + "rustix", "serde", "serde_repr", "tracing", @@ -8116,6 +7742,30 @@ dependencies = [ "zvariant", ] +[[package]] +name = "zbus-lockstep" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6998de05217a084b7578728a9443d04ea4cd80f2a0839b8d78770b76ccd45863" +dependencies = [ + "zbus_xml", + "zvariant", +] + +[[package]] +name = "zbus-lockstep-macros" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10da05367f3a7b7553c8cdf8fa91aee6b64afebe32b51c95177957efc47ca3a0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", + "zbus-lockstep", + "zbus_xml", + "zvariant", +] + [[package]] name = "zbus_macros" version = "5.19.0" @@ -8142,6 +7792,18 @@ dependencies = [ "zvariant", ] +[[package]] +name = "zbus_xml" +version = "5.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1586c021a01ca0a9216dcd874e546382e156a5cbab5fab6cb5f10087e22682a" +dependencies = [ + "serde", + "winnow 1.0.4", + "zbus_names", + "zvariant", +] + [[package]] name = "zcheapstr" version = "1.1.0" @@ -8151,32 +7813,17 @@ dependencies = [ "serde", ] -[[package]] -name = "zed-async-tar" -version = "0.5.0-zed" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cf4b5f655e29700e473cb1acd914ab112b37b62f96f7e642d5fc6a0c02eb881" -dependencies = [ - "async-std", - "filetime", - "libc", - "pin-project", - "redox_syscall 0.2.16", - "xattr", -] - [[package]] name = "zed-font-kit" version = "0.14.1-zed" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3898e450f36f852edda72e3f985c34426042c4951790b23b107f93394f9bff5" +source = "git+https://github.com/zed-industries/font-kit?rev=94b0f28166665e8fd2f53ff6d268a14955c82269#94b0f28166665e8fd2f53ff6d268a14955c82269" dependencies = [ "bitflags 2.13.2", "byteorder", "core-foundation 0.10.0", "core-graphics 0.24.0", "core-text", - "dirs 5.0.1", + "dirs 6.0.0", "dwrote", "float-ord", "freetype-sys", @@ -8190,61 +7837,10 @@ dependencies = [ "yeslogic-fontconfig-sys", ] -[[package]] -name = "zed-reqwest" -version = "0.12.15-zed" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac2d05756ff48539950c3282ad7acf3817ad3f08797c205ad1c34a2ce03b9970" -dependencies = [ - "base64", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-rustls", - "hyper-util", - "ipnet", - "js-sys", - "log", - "mime", - "mime_guess", - "once_cell", - "percent-encoding", - "pin-project-lite", - "quinn", - "rustls", - "rustls-native-certs", - "rustls-pemfile", - "rustls-pki-types", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "system-configuration", - "tokio", - "tokio-rustls", - "tokio-socks", - "tokio-util", - "tower", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-streams", - "web-sys", - "windows-registry 0.4.0", -] - [[package]] name = "zed-scap" version = "0.0.8-zed" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6b338d705ae33a43ca00287c11129303a7a0aa57b101b72a1c08c863f698ac8" +source = "git+https://github.com/zed-industries/scap?rev=4afea48c3b002197176fb19cd0f9b180dd36eaac#4afea48c3b002197176fb19cd0f9b180dd36eaac" dependencies = [ "anyhow", "cocoa 0.25.0", @@ -8262,20 +7858,6 @@ dependencies = [ "xcb", ] -[[package]] -name = "zed-xim" -version = "0.4.0-zed" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0b46ed118eba34d9ba53d94ddc0b665e0e06a2cf874cfa2dd5dec278148642" -dependencies = [ - "ahash", - "hashbrown 0.14.5", - "log", - "x11rb", - "xim-ctext", - "xim-parser", -] - [[package]] name = "zeno" version = "0.3.3" @@ -8382,12 +7964,39 @@ version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b268e58e7c693d7c271f93ffc4ba3b380412554231c85bf61ca7af91042a4112" +[[package]] +name = "zlog" +version = "0.1.0" +source = "git+https://github.com/zed-industries/zed?rev=1a28cff4b409169bac058bca40dfbfeb7621d19b#1a28cff4b409169bac058bca40dfbfeb7621d19b" +dependencies = [ + "anyhow", + "chrono", + "collections", + "log", +] + [[package]] name = "zmij" version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" +[[package]] +name = "ztracing" +version = "0.1.0" +source = "git+https://github.com/zed-industries/zed?rev=1a28cff4b409169bac058bca40dfbfeb7621d19b#1a28cff4b409169bac058bca40dfbfeb7621d19b" +dependencies = [ + "tracing", + "tracing-subscriber", + "zlog", + "ztracing_macro", +] + +[[package]] +name = "ztracing_macro" +version = "0.1.0" +source = "git+https://github.com/zed-industries/zed?rev=1a28cff4b409169bac058bca40dfbfeb7621d19b#1a28cff4b409169bac058bca40dfbfeb7621d19b" + [[package]] name = "zune-core" version = "0.5.3" @@ -8421,7 +8030,7 @@ dependencies = [ "endi", "enumflags2", "serde", - "url", + "serde_bytes", "winnow 1.0.4", "zcheapstr", "zvariant_derive", diff --git a/Cargo.toml b/Cargo.toml index 70c07fc..a370d69 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ publish = false [features] default = ["runtime_shaders"] -runtime_shaders = ["gpui/runtime_shaders"] +runtime_shaders = ["gpui_platform/runtime_shaders"] test-support = ["gpui/test-support"] [dependencies] @@ -19,7 +19,8 @@ anyhow = "1" barcoders = { version = "2", default-features = false, features = ["std"] } emojis = "0.9" futures = "0.3" -gpui = "0.2.2" +gpui = { git = "https://github.com/zed-industries/zed", rev = "1a28cff4b409169bac058bca40dfbfeb7621d19b", default-features = false, features = ["stacker"] } +gpui_platform = { git = "https://github.com/zed-industries/zed", rev = "1a28cff4b409169bac058bca40dfbfeb7621d19b", features = ["font-kit"] } image = { version = "0.25", default-features = false } iso_currency = { version = "0.7", features = ["iterator"] } isocountry = "0.3" diff --git a/examples/gallery/capture.rs b/examples/gallery/capture.rs index 97fcab8..1b44076 100644 --- a/examples/gallery/capture.rs +++ b/examples/gallery/capture.rs @@ -26,7 +26,7 @@ pub fn run( Theme::update(cx, |theme| theme.reduced_motion = true); cx.spawn(async move |cx| { let outcome = shoot_all(window, &dir, only, scripted, cx).await; - if let Err(error) = outcome.and_then(|()| cx.update(|cx| cx.quit())) { + if let Err(error) = outcome.map(|()| cx.update(|cx| cx.quit())) { log::error!("capture failed: {error:#}"); std::process::exit(1); } diff --git a/examples/gallery/main.rs b/examples/gallery/main.rs index afaa3da..4bd1dde 100644 --- a/examples/gallery/main.rs +++ b/examples/gallery/main.rs @@ -22,8 +22,8 @@ use std::path::PathBuf; use anyhow::{Context as _, Result, bail}; use ely_gpui_component::Assets; use gpui::{ - App, AppContext, Application, Bounds, KeyBinding, Menu, MenuItem, TitlebarOptions, - WindowBounds, WindowHandle, WindowOptions, actions, point, px, size, + App, AppContext, Bounds, KeyBinding, Menu, MenuItem, TitlebarOptions, WindowBounds, + WindowHandle, WindowOptions, actions, point, px, size, }; actions!(gallery, [Quit, About, LightMode, DarkMode, NewWindow]); @@ -38,6 +38,7 @@ fn menus(cx: &mut App) { MenuItem::separator(), MenuItem::action("Quit Ely", Quit), ], + disabled: false, }, Menu { name: "View".into(), @@ -45,6 +46,7 @@ fn menus(cx: &mut App) { MenuItem::action("Light", LightMode), MenuItem::action("Dark", DarkMode), ], + disabled: false, }, ]); cx.set_dock_menu(vec![MenuItem::action("New Window", NewWindow)]); @@ -103,7 +105,7 @@ fn parse_args() -> Result { fn main() -> Result<()> { env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init(); let args = parse_args()?; - Application::new() + gpui_platform::application() .with_assets(Assets) .run(move |cx: &mut App| { ely_gpui_component::init(cx); @@ -123,6 +125,8 @@ fn main() -> Result<()> { traffic_light_position: Some(point(px(16.0), px(18.0))), }), window_min_size: Some(size(px(880.0), px(560.0))), + // Draws every frame while a demo window is key, as gpui 0.2.2 did. + inactive_frame_interval: None, ..Default::default() }; let window = cx diff --git a/examples/gallery/pages/canvas/looks.rs b/examples/gallery/pages/canvas/looks.rs index e82841d..d06f84d 100644 --- a/examples/gallery/pages/canvas/looks.rs +++ b/examples/gallery/pages/canvas/looks.rs @@ -105,6 +105,7 @@ pub fn styles(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> { offset: point(px(shadow.x), px(shadow.y)), blur_radius: px(shadow.blur), spread_radius: px(shadow.spread), + inset: false, }) .collect(), ); diff --git a/examples/gallery/pages/charts/cartesian.rs b/examples/gallery/pages/charts/cartesian.rs index d77089b..44d013f 100644 --- a/examples/gallery/pages/charts/cartesian.rs +++ b/examples/gallery/pages/charts/cartesian.rs @@ -185,7 +185,7 @@ pub fn realtime(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> { cx.background_executor() .timer(Duration::from_millis(900)) .await; - let pushed = cx.update(|cx| { + cx.update(|cx| { stream.update(cx, |(values, pushed), cx| { let last = values.last().copied().unwrap_or(60.0); values.push((last + (rng() - 0.5) * 10.0).clamp(20.0, 100.0)); @@ -194,9 +194,6 @@ pub fn realtime(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> { cx.notify(); }) }); - if pushed.is_err() { - return; - } } }) .detach(); diff --git a/examples/gallery/pages/chat/talk.rs b/examples/gallery/pages/chat/talk.rs index 0d93e11..05566a2 100644 --- a/examples/gallery/pages/chat/talk.rs +++ b/examples/gallery/pages/chat/talk.rs @@ -199,7 +199,7 @@ pub fn streaming(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> cx.background_executor().timer(Duration::from_millis(600)).await; loop { cx.background_executor().timer(Duration::from_millis(45)).await; - let more = feeder.update(cx, |stream, cx| { + let more = cx.update(|_, cx| feeder.update(cx, |stream, cx| { let next = (stream.arrived + 7).min(ANSWER.len()); stream.arrived = (next..=ANSWER.len()) .find(|at| ANSWER.is_char_boundary(*at)) @@ -207,8 +207,8 @@ pub fn streaming(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> stream.live = stream.arrived < ANSWER.len(); cx.notify(); stream.live - }); - if !matches!(more, Ok(true)) { + })); + if !matches!(more.and_then(|inner| inner), Ok(true)) { break; } } diff --git a/examples/gallery/pages/generative/data.rs b/examples/gallery/pages/generative/data.rs index 6bf33a4..770ffb7 100644 --- a/examples/gallery/pages/generative/data.rs +++ b/examples/gallery/pages/generative/data.rs @@ -221,8 +221,7 @@ pub fn playground(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> }, cx, ) - }) - .ok(); + }); }) .detach(); }); diff --git a/examples/gallery/pages/generative/panel.rs b/examples/gallery/pages/generative/panel.rs index fe1702e..7e55e15 100644 --- a/examples/gallery/pages/generative/panel.rs +++ b/examples/gallery/pages/generative/panel.rs @@ -117,8 +117,7 @@ pub fn panel(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> { settings.enhancing = false; settings.suggestion = Some(text.into()); }) - }) - .ok(); + }); }) .detach(); }) diff --git a/examples/gallery/pages/interaction/keys.rs b/examples/gallery/pages/interaction/keys.rs index 9c74b98..93fa729 100644 --- a/examples/gallery/pages/interaction/keys.rs +++ b/examples/gallery/pages/interaction/keys.rs @@ -298,7 +298,7 @@ pub fn focus(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> { .on_click(move |_, window, cx| { change(&show, cx, |focusing| focusing.field = !focusing.field); let focus = focus.clone(); - window.defer(cx, move |window, _| window.focus(&focus)); + window.defer(cx, move |window, cx| window.focus(&focus, cx)); }), ) .when(shown, |column| column.child(Input::new(&field))), diff --git a/examples/gallery/pages/lists/long.rs b/examples/gallery/pages/lists/long.rs index 486f0dc..1dce2d5 100644 --- a/examples/gallery/pages/lists/long.rs +++ b/examples/gallery/pages/lists/long.rs @@ -67,7 +67,7 @@ pub fn infinite(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> { let more = more.clone(); cx.spawn(async move |cx| { cx.background_executor().timer(Duration::from_millis(700)).await; - cx.update(|cx| set(&more, (rows + PAGE, false), cx)).ok(); + cx.update(|cx| set(&more, (rows + PAGE, false), cx)); }) .detach(); }), diff --git a/examples/gallery/pages/lists/trees.rs b/examples/gallery/pages/lists/trees.rs index ccb2b44..22ee479 100644 --- a/examples/gallery/pages/lists/trees.rs +++ b/examples/gallery/pages/lists/trees.rs @@ -144,8 +144,7 @@ pub fn tree(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> { items.push(item("logo", "logo.svg", Some(&key), false)); items.push(item("inter", "Inter.ttf", Some(&key), false)); }) - }) - .ok(); + }); }) .detach(); }) diff --git a/examples/gallery/pages/media/audio.rs b/examples/gallery/pages/media/audio.rs index 8041add..fea9f22 100644 --- a/examples/gallery/pages/media/audio.rs +++ b/examples/gallery/pages/media/audio.rs @@ -4,7 +4,9 @@ use ely_gpui_component::media::{ AudioPlayer, AudioSpectrum, AudioWaveform, MediaControls, PlaybackSpeedControl, Playlist, Repeat, Track, VolumeControl, }; -use gpui::{App, Entity, IntoElement, ParentElement, SharedString, Styled, Window, div, px}; +use gpui::{ + App, Entity, IntoElement, ParentElement, SharedString, Styled, TaskExt as _, Window, div, px, +}; use crate::{ probe::probe, @@ -98,19 +100,21 @@ fn tick(state: &Entity, window: &mut Window, cx: &mut App) { .spawn(cx, async move |cx| { loop { cx.background_executor().timer(TICK).await; - let going = state.update(cx, |now, cx| { - now.at = (now.at + TICK.mul_f32(now.speed)).min(now.length()); - if now.at == now.length() { - match now.repeat { - Repeat::One => now.at = Duration::ZERO, - Repeat::All => now.skip(1), - Repeat::Off if now.song + 1 < SONGS.len() => now.skip(1), - Repeat::Off => now.playing = false, + let going = cx.update(|_, cx| { + state.update(cx, |now, cx| { + now.at = (now.at + TICK.mul_f32(now.speed)).min(now.length()); + if now.at == now.length() { + match now.repeat { + Repeat::One => now.at = Duration::ZERO, + Repeat::All => now.skip(1), + Repeat::Off if now.song + 1 < SONGS.len() => now.skip(1), + Repeat::Off => now.playing = false, + } } - } - now.ticking = now.playing; - cx.notify(); - now.playing + now.ticking = now.playing; + cx.notify(); + now.playing + }) })?; if !going { return anyhow::Ok(()); diff --git a/examples/gallery/pages/media/video.rs b/examples/gallery/pages/media/video.rs index 53ee632..b15e277 100644 --- a/examples/gallery/pages/media/video.rs +++ b/examples/gallery/pages/media/video.rs @@ -1,7 +1,9 @@ use std::{path::Path, time::Duration}; use ely_gpui_component::media::{Cue, Scrubber, SubtitleEditor, VideoPlayer, VideoThumbnailStrip}; -use gpui::{App, Entity, IntoElement, ParentElement, SharedString, Styled, Window, div, px}; +use gpui::{ + App, Entity, IntoElement, ParentElement, SharedString, Styled, TaskExt as _, Window, div, px, +}; use crate::{ probe::probe, @@ -61,13 +63,15 @@ fn tick(state: &Entity, window: &mut Window, cx: &mut App) { .spawn(cx, async move |cx| { loop { cx.background_executor().timer(TICK).await; - let going = state.update(cx, |now, cx| { - let step = TICK.mul_f32(now.speed); - now.at = (now.at + step).min(LENGTH); - now.playing &= now.at < LENGTH; - now.ticking = now.playing; - cx.notify(); - now.playing + let going = cx.update(|_, cx| { + state.update(cx, |now, cx| { + let step = TICK.mul_f32(now.speed); + now.at = (now.at + step).min(LENGTH); + now.playing &= now.at < LENGTH; + now.ticking = now.playing; + cx.notify(); + now.playing + }) })?; if !going { return anyhow::Ok(()); diff --git a/examples/gallery/pages/motion/loading.rs b/examples/gallery/pages/motion/loading.rs index 86f908f..79cce21 100644 --- a/examples/gallery/pages/motion/loading.rs +++ b/examples/gallery/pages/motion/loading.rs @@ -24,9 +24,7 @@ pub fn later(state: &Entity, value: T, wait: Duration, cx: &mut A let state = state.clone(); cx.spawn(async move |cx| { cx.background_executor().timer(wait).await; - if let Err(error) = cx.update(|cx| set(&state, value, cx)) { - log::error!("gallery: the demo closed before its answer: {error:#}"); - } + cx.update(|cx| set(&state, value, cx)); }) .detach(); } diff --git a/examples/gallery/pages/typography/motion.rs b/examples/gallery/pages/typography/motion.rs index c9c79f7..ee38bab 100644 --- a/examples/gallery/pages/typography/motion.rs +++ b/examples/gallery/pages/typography/motion.rs @@ -23,11 +23,13 @@ pub fn animated_number(window: &mut Window, cx: &mut App) -> impl IntoElement + _task: cx.spawn_in(window, async move |ticker, cx| { loop { cx.background_executor().timer(STEP).await; - let advanced = ticker.update(cx, |ticker: &mut Ticker, cx| { - ticker.index = (ticker.index + 1) % VALUES.len(); - cx.notify(); + let advanced = cx.update(|_, cx| { + ticker.update(cx, |ticker: &mut Ticker, cx| { + ticker.index = (ticker.index + 1) % VALUES.len(); + cx.notify(); + }) }); - if advanced.is_err() { + if advanced.and_then(|inner| inner).is_err() { return; } } diff --git a/examples/gallery/script.rs b/examples/gallery/script.rs index 1c1a774..2792bd8 100644 --- a/examples/gallery/script.rs +++ b/examples/gallery/script.rs @@ -73,7 +73,7 @@ pub fn park(window: WindowHandle, cx: &mut AsyncApp) -> Result<()> { } fn opened(key: &str, cx: &mut AsyncApp) -> Result { - cx.update(|cx| Opened::get(key, cx))? + cx.update(|cx| Opened::get(key, cx)) .with_context(|| format!("no window opened as {key}")) } @@ -231,15 +231,15 @@ pub async fn play( } Step::ExpectClosed(key) => { let handle = opened(key, cx)?; - let open = cx.update(|cx| cx.windows().contains(&handle))?; + let open = cx.update(|cx| cx.windows().contains(&handle)); anyhow::ensure!(!open, "window {key} is still open"); - cx.update(|cx| Opened::take(key, cx))?; + cx.update(|cx| Opened::take(key, cx)); log::info!("script: {key} closed"); } Step::CloseWindow(key) => { let handle = opened(key, cx)?; handle.update(cx, |_, window, _| window.remove_window())?; - cx.update(|cx| Opened::take(key, cx))?; + cx.update(|cx| Opened::take(key, cx)); } } cx.background_executor().timer(FRAME).await; @@ -439,13 +439,13 @@ async fn target_bounds( cx: &mut AsyncApp, ) -> Result> { let bounds = cx - .update(|cx| Probes::get(key, cx))? + .update(|cx| Probes::get(key, cx)) .with_context(|| format!("probe {key} never rendered"))?; if window.update(cx, |gallery, _, cx| gallery.reveal(bounds, cx))? { cx.background_executor().timer(FRAME).await; } let bounds = cx - .update(|cx| Probes::get(key, cx))? + .update(|cx| Probes::get(key, cx)) .with_context(|| format!("probe {key} vanished after scrolling"))?; log::info!("script: probe {key} at {bounds:?}"); Ok(bounds) diff --git a/examples/gallery/shell.rs b/examples/gallery/shell.rs index 77e8184..809db72 100644 --- a/examples/gallery/shell.rs +++ b/examples/gallery/shell.rs @@ -44,7 +44,7 @@ impl Gallery { } }); let focus = cx.focus_handle(); - window.focus(&focus); + window.focus(&focus, cx); Self { page, pass: 0, @@ -71,10 +71,7 @@ impl Gallery { /// Viewport height and furthest scroll, in pixels. pub fn scroll_extent(&self) -> (Pixels, Pixels) { - ( - self.scroll.bounds().size.height, - self.scroll.max_offset().height, - ) + (self.scroll.bounds().size.height, self.scroll.max_offset().y) } /// Scrolls until `target` sits inside the page. True if it moved. @@ -87,7 +84,7 @@ impl Gallery { } else { return false; }; - let y = (-self.scroll.offset().y + shift).clamp(px(0.0), self.scroll.max_offset().height); + let y = (-self.scroll.offset().y + shift).clamp(px(0.0), self.scroll.max_offset().y); self.scroll_to(y, cx); true } diff --git a/src/account/tests/mod.rs b/src/account/tests/mod.rs index 7be832d..9444868 100644 --- a/src/account/tests/mod.rs +++ b/src/account/tests/mod.rs @@ -62,9 +62,9 @@ pub(super) fn said(host: &Entity, cx: &mut VisualTestContext) -> Vec) -> impl IntoElement { let (view, height) = (cx.entity(), self.height.clone()); - div() - .relative() - .w(px(640.0)) - .child( - FileChangeCard::new("card", change("src/theme/lift.rs")).on_decide( - move |accepted, _, cx| view.update(cx, |card, _| card.verdicts.push(accepted)), - ), - ) - .child( - canvas( - move |bounds, _, _| height.set(bounds.size.height), - |_, _, _, _| {}, + // gpui fills the window with an auto-sized root, so the measured box sits inside one. + div().child( + div() + .relative() + .w(px(640.0)) + .child( + FileChangeCard::new("card", change("src/theme/lift.rs")).on_decide( + move |accepted, _, cx| { + view.update(cx, |card, _| card.verdicts.push(accepted)) + }, + ), ) - .absolute() - .top_0() - .left_0() - .size_full(), - ) + .child( + canvas( + move |bounds, _, _| height.set(bounds.size.height), + |_, _, _, _| {}, + ) + .absolute() + .top_0() + .left_0() + .size_full(), + ), + ) } } @@ -114,8 +119,8 @@ fn review(cx: &mut TestAppContext) -> (Entity, &mut VisualTestContext) { #[gpui::test] fn accept_all_decides_every_file(cx: &mut TestAppContext) { let (view, cx) = review(cx); - cx.update(|window, _| window.focus_next()); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); + cx.update(|window, cx| window.focus_next(cx)); press("enter", cx); assert_eq!( view.read_with(cx, |review, _| review.decisions.clone()), @@ -127,7 +132,7 @@ fn accept_all_decides_every_file(cx: &mut TestAppContext) { fn a_cards_verdict_names_its_file(cx: &mut TestAppContext) { let (view, cx) = review(cx); for _ in 0..8 { - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); } press("enter", cx); assert_eq!( @@ -145,26 +150,28 @@ struct Narrow { impl Render for Narrow { fn render(&mut self, _: &mut Window, _: &mut Context) -> impl IntoElement { let height = self.height.clone(); - div() - .relative() - .w(self.width) - .child( - MultiFileDiffReview::new( - "narrow", - ["src/theme/lift.rs", "src/theme/tokens.rs"].map(change), + div().child( + div() + .relative() + .w(self.width) + .child( + MultiFileDiffReview::new( + "narrow", + ["src/theme/lift.rs", "src/theme/tokens.rs"].map(change), + ) + .on_decide(|_, _, _| {}), ) - .on_decide(|_, _, _| {}), - ) - .child( - canvas( - move |bounds, _, _| height.set(bounds.size.height), - |_, _, _, _| {}, - ) - .absolute() - .top_0() - .left_0() - .size_full(), - ) + .child( + canvas( + move |bounds, _, _| height.set(bounds.size.height), + |_, _, _, _| {}, + ) + .absolute() + .top_0() + .left_0() + .size_full(), + ), + ) } } diff --git a/src/agent/tests/control.rs b/src/agent/tests/control.rs index 27b0f8d..0588d18 100644 --- a/src/agent/tests/control.rs +++ b/src/agent/tests/control.rs @@ -58,10 +58,10 @@ fn asked(cx: &mut TestAppContext) -> (Entity, &mut VisualTestContext) { #[gpui::test] fn a_pick_answers_the_question_and_the_answer_stands_alone(cx: &mut TestAppContext) { let (view, cx) = asked(cx); - cx.update(|window, _| window.focus_next()); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); + cx.update(|window, cx| window.focus_next(cx)); press("enter", cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); press("enter", cx); assert_eq!( view.read_with(cx, |asked, _| asked.answers.clone()), @@ -74,7 +74,7 @@ fn a_pick_answers_the_question_and_the_answer_stands_alone(cx: &mut TestAppConte fn enter_sends_a_written_answer_and_skips_a_blank_one(cx: &mut TestAppContext) { let (view, cx) = asked(cx); for _ in 0..3 { - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); } cx.simulate_input(" "); press("enter", cx); diff --git a/src/agent/tests/environment.rs b/src/agent/tests/environment.rs index 4404289..cce5e42 100644 --- a/src/agent/tests/environment.rs +++ b/src/agent/tests/environment.rs @@ -62,7 +62,7 @@ fn memories(cx: &mut TestAppContext) -> (Entity, &mut VisualTestContex #[gpui::test] fn enter_keeps_a_memory_and_empties_the_field(cx: &mut TestAppContext) { let (view, cx) = memories(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_input(" "); press("enter", cx); cx.simulate_input("Lifts stay under 20%"); @@ -113,9 +113,9 @@ fn a_servers_switch_turns_it_off_and_on(cx: &mut TestAppContext) { let (view, cx) = cx.add_window_view(|_, _| Servers { thrown: Vec::new() }); cx.update(|window, _| window.activate_window()); settle(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); press("space", cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); press("space", cx); let thrown = view.read_with(cx, |servers, _| servers.thrown.clone()); assert_eq!(thrown, [("files".into(), false), ("web".into(), true)]); @@ -152,9 +152,9 @@ fn every_checkpoint_but_the_current_rewinds(cx: &mut TestAppContext) { let (view, cx) = cx.add_window_view(|_, _| Points { asked: Vec::new() }); cx.update(|window, _| window.activate_window()); settle(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); press("enter", cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); press("enter", cx); assert_eq!( view.read_with(cx, |points, _| points.asked.clone()), diff --git a/src/agent/tests/mod.rs b/src/agent/tests/mod.rs index 8090765..4fb859d 100644 --- a/src/agent/tests/mod.rs +++ b/src/agent/tests/mod.rs @@ -120,7 +120,7 @@ fn the_prompt_walks_deny_always_then_once(cx: &mut TestAppContext) { cx.update(|window, _| window.activate_window()); settle(cx); for _ in 0..3 { - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); } press("enter", cx); assert_eq!( diff --git a/src/agent/tests/previews.rs b/src/agent/tests/previews.rs index 50b823d..f7c0c1a 100644 --- a/src/agent/tests/previews.rs +++ b/src/agent/tests/previews.rs @@ -43,8 +43,8 @@ fn a_frame_shows_from_the_keyboard(cx: &mut TestAppContext) { let (view, cx) = cx.add_window_view(|_, _| Browsing { asked: Vec::new() }); cx.update(|window, _| window.activate_window()); settle(cx); - cx.update(|window, _| window.focus_next()); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); + cx.update(|window, cx| window.focus_next(cx)); press("enter", cx); assert_eq!( view.read_with(cx, |browsing, _| browsing.asked.clone()), @@ -97,8 +97,8 @@ fn the_source_shows_when_asked(cx: &mut TestAppContext) { cx.update(|window, _| window.activate_window()); settle(cx); assert!(!drew.get(), "the preview shows first"); - cx.update(|window, _| window.focus_next()); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); + cx.update(|window, cx| window.focus_next(cx)); press("enter", cx); assert!(drew.get(), "the source shows once asked"); } @@ -113,23 +113,26 @@ impl Render for Strip { fn render(&mut self, _: &mut Window, cx: &mut Context) -> impl IntoElement { let (view, height) = (cx.entity(), self.height.clone()); let frames = (0..8).map(|ix| format!("{ix}.png")); - div() - .relative() - .w(px(280.0)) - .child( - BrowserPreview::new("strip", "localhost", frames, 0) - .on_show(move |ix, _, cx| view.update(cx, |strip, _| strip.asked.push(ix))), - ) - .child( - canvas( - move |bounds, _, _| height.set(bounds.size.height), - |_, _, _, _| {}, + // gpui fills the window with an auto-sized root, so the measured box sits inside one. + div().child( + div() + .relative() + .w(px(280.0)) + .child( + BrowserPreview::new("strip", "localhost", frames, 0) + .on_show(move |ix, _, cx| view.update(cx, |strip, _| strip.asked.push(ix))), ) - .absolute() - .top_0() - .left_0() - .size_full(), - ) + .child( + canvas( + move |bounds, _, _| height.set(bounds.size.height), + |_, _, _, _| {}, + ) + .absolute() + .top_0() + .left_0() + .size_full(), + ), + ) } } @@ -226,7 +229,7 @@ fn tab_brings_a_hidden_frame_into_view(cx: &mut TestAppContext) { cx.update(|window, _| window.activate_window()); settle(cx); for _ in 0..8 { - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); settle(cx); } settle(cx); @@ -254,24 +257,26 @@ struct Screen { impl Render for Screen { fn render(&mut self, _: &mut Window, _: &mut Context) -> impl IntoElement { let height = self.height.clone(); - div() - .relative() - .w(px(480.0)) - .child( - ComputerUseViewer::new("screen", "a.png") - .ratio(4.0 / 3.0) - .pointer(point(0.5, 0.95)), - ) - .child( - canvas( - move |bounds, _, _| height.set(bounds.size.height), - |_, _, _, _| {}, + div().child( + div() + .relative() + .w(px(480.0)) + .child( + ComputerUseViewer::new("screen", "a.png") + .ratio(4.0 / 3.0) + .pointer(point(0.5, 0.95)), ) - .absolute() - .top_0() - .left_0() - .size_full(), - ) + .child( + canvas( + move |bounds, _, _| height.set(bounds.size.height), + |_, _, _, _| {}, + ) + .absolute() + .top_0() + .left_0() + .size_full(), + ), + ) } } diff --git a/src/buttons/confirm.rs b/src/buttons/confirm.rs index 8bfaee3..7d125d8 100644 --- a/src/buttons/confirm.rs +++ b/src/buttons/confirm.rs @@ -97,13 +97,15 @@ fn expire( let (weak, generation) = (state.downgrade(), state.read(cx).generation); window.spawn(cx, async move |cx| { cx.background_executor().timer(after).await; - let cleared = weak.update(cx, |confirm, cx| { - if confirm.generation == generation { - clear(confirm); - cx.notify(); - } + let cleared = cx.update(|_, cx| { + weak.update(cx, |confirm, cx| { + if confirm.generation == generation { + clear(confirm); + cx.notify(); + } + }) }); - if let Err(error) = cleared { + if let Err(error) = cleared.and_then(|inner| inner) { log::error!("confirm button: state gone before it expired: {error:#}"); } }) diff --git a/src/buttons/copy.rs b/src/buttons/copy.rs index 48da63a..44b8432 100644 --- a/src/buttons/copy.rs +++ b/src/buttons/copy.rs @@ -53,10 +53,13 @@ impl RenderOnce for CopyButton { let weak = state.downgrade(); let reset = window.spawn(cx, async move |cx| { cx.background_executor().timer(CONFIRM).await; - if let Err(error) = weak.update(cx, |copied, cx| { - copied._reset = None; - cx.notify(); - }) { + let cleared = cx.update(|_, cx| { + weak.update(cx, |copied, cx| { + copied._reset = None; + cx.notify(); + }) + }); + if let Err(error) = cleared.and_then(|inner| inner) { log::error!("copy button: reset lost its state: {error:#}"); } }); diff --git a/src/buttons/segmented.rs b/src/buttons/segmented.rs index 7ee2d4d..90ccba7 100644 --- a/src/buttons/segmented.rs +++ b/src/buttons/segmented.rs @@ -197,8 +197,8 @@ impl RenderOnce for SegmentedControl { .id(self.id.clone()) .relative() .flex() - .flex_grow() - .flex_shrink() + .flex_grow_1() + .flex_shrink_1() .min_w(least * count as f32) .items_center() .child(measure_origin(state.clone(), Axis::Horizontal)) diff --git a/src/buttons/tests.rs b/src/buttons/tests.rs index ca02679..f27eeec 100644 --- a/src/buttons/tests.rs +++ b/src/buttons/tests.rs @@ -47,7 +47,7 @@ fn a_loading_button_ignores_presses_and_keeps_its_tab_stop(cx: &mut TestAppConte presses: 0, }); let root = view.read_with(cx, |bench, _| bench.root.clone()); - cx.update(|window, _| window.focus(&root)); + cx.update(|window, cx| window.focus(&root, cx)); press("tab", cx); press("enter", cx); assert_eq!(view.read_with(cx, |bench, _| bench.presses), 0); diff --git a/src/calendar/tests/mod.rs b/src/calendar/tests/mod.rs index c0993ff..13339b0 100644 --- a/src/calendar/tests/mod.rs +++ b/src/calendar/tests/mod.rs @@ -74,10 +74,10 @@ fn press(key: &str, cx: &mut VisualTestContext) { /// Moves focus to the `nth` Tab stop from none. fn tab_to(nth: usize, cx: &mut VisualTestContext) { - cx.update(|window, _| { - window.blur(); + cx.update(|window, cx| { + window.blur(cx); for _ in 0..nth { - window.focus_next(); + window.focus_next(cx); } }); settle(cx); diff --git a/src/calendar/tests/people.rs b/src/calendar/tests/people.rs index b5b9dda..450770c 100644 --- a/src/calendar/tests/people.rs +++ b/src/calendar/tests/people.rs @@ -96,9 +96,9 @@ fn a_chip_opens_its_details_and_edit_names_it(cx: &mut TestAppContext) { cx.debug_bounds("event-popover review").is_some(), "the details open" ); - cx.update(|window, _| { - window.focus_next(); - window.focus_next(); + cx.update(|window, cx| { + window.focus_next(cx); + window.focus_next(cx); }); press("space", cx); assert_eq!( diff --git a/src/canvas/mindmap_view.rs b/src/canvas/mindmap_view.rs index 0be9411..b519ef3 100644 --- a/src/canvas/mindmap_view.rs +++ b/src/canvas/mindmap_view.rs @@ -198,7 +198,7 @@ impl RenderOnce for MindMap { .cursor_pointer() .on_mouse_down(MouseButton::Left, move |event, window, cx| { cx.stop_propagation(); - window.focus(&hold); + window.focus(&hold, cx); if let Some(pick) = &pick { pick(Some(&key), window, cx); } @@ -273,7 +273,7 @@ impl RenderOnce for MindMap { if writing_tab.read(cx).field().is_some() { cx.stop_propagation(); writing_tab.update(cx, |editing, cx| editing.finish(false, window, cx)); - window.focus(&back); + window.focus(&back, cx); return; } cx.stop_propagation(); diff --git a/src/canvas/tests/mod.rs b/src/canvas/tests/mod.rs index 1a76c95..3447931 100644 --- a/src/canvas/tests/mod.rs +++ b/src/canvas/tests/mod.rs @@ -137,9 +137,9 @@ fn zoom(_: &Stage, owner: Entity) -> AnyElement { fn the_zoom_buttons_step_and_the_percent_resets(cx: &mut TestAppContext) { let (host, cx) = stage(zoom, cx); for nth in [1, 2, 3] { - cx.update(|window, _| { - window.blur(); - (0..nth).for_each(|_| window.focus_next()); + cx.update(|window, cx| { + window.blur(cx); + (0..nth).for_each(|_| window.focus_next(cx)); }); cx.simulate_keystrokes("space"); cx.simulate_event(gpui::KeyUpEvent { diff --git a/src/canvas/tests/panels.rs b/src/canvas/tests/panels.rs index 69c106c..e3639a2 100644 --- a/src/canvas/tests/panels.rs +++ b/src/canvas/tests/panels.rs @@ -7,9 +7,9 @@ use crate::canvas::{ }; fn tab(stops: usize, cx: &mut VisualTestContext) { - cx.update(|window, _| { - window.blur(); - (0..stops).for_each(|_| window.focus_next()); + cx.update(|window, cx| { + window.blur(cx); + (0..stops).for_each(|_| window.focus_next(cx)); }); settle(cx); } diff --git a/src/canvas/tools.rs b/src/canvas/tools.rs index 82ae9fb..f7e8745 100644 --- a/src/canvas/tools.rs +++ b/src/canvas/tools.rs @@ -343,7 +343,7 @@ impl RenderOnce for ToolLayer { ) .on_mouse_down(MouseButton::Left, move |event, window, cx| { cx.stop_propagation(); - window.focus(&held_focus); + window.focus(&held_focus, cx); let bounds = pressed.read(cx).bounds; let at = point_of(event.position, bounds); let local = event.position - bounds.origin; diff --git a/src/canvas/writing.rs b/src/canvas/writing.rs index d0814ee..57f8d4b 100644 --- a/src/canvas/writing.rs +++ b/src/canvas/writing.rs @@ -49,7 +49,7 @@ pub(super) fn field(editing: &Entity, frame: Frame, cx: &App) -> Option cx.stop_propagation(); closing.update(cx, |editing, cx| { editing.finish(true, window, cx); - editing.give_back(window); + editing.give_back(window, cx); }); } }) @@ -58,7 +58,7 @@ pub(super) fn field(editing: &Entity, frame: Frame, cx: &App) -> Option cx.stop_propagation(); keeping.update(cx, |editing, cx| { editing.finish(false, window, cx); - editing.give_back(window); + editing.give_back(window, cx); }); } }) diff --git a/src/charts/flow.rs b/src/charts/flow.rs index 818e14c..32b9880 100644 --- a/src/charts/flow.rs +++ b/src/charts/flow.rs @@ -1,8 +1,8 @@ use std::rc::Rc; use gpui::{ - App, Bounds, Div, ElementId, Entity, InteractiveElement, IntoElement, MouseMoveEvent, - ParentElement, PathBuilder, Pixels, Refineable, RenderOnce, SharedString, + App, Bounds, Div, ElementId, Entity, HoverListenerMode, InteractiveElement, IntoElement, + MouseMoveEvent, ParentElement, PathBuilder, Pixels, Refineable, RenderOnce, SharedString, StatefulInteractiveElement, StyleRefinement, Styled, Window, canvas, div, fill, prelude::*, }; @@ -368,6 +368,7 @@ impl RenderOnce for SankeyChart { } }) }) + .hover_listener_mode(HoverListenerMode::InputModalityIndependent) .on_hover(move |inside, _, cx| { if !*inside { left.update(cx, |flows, cx| { diff --git a/src/charts/funnel.rs b/src/charts/funnel.rs index f8ac018..8d0978e 100644 --- a/src/charts/funnel.rs +++ b/src/charts/funnel.rs @@ -1,9 +1,9 @@ use std::rc::Rc; use gpui::{ - App, Div, ElementId, Entity, InteractiveElement, IntoElement, MouseMoveEvent, ParentElement, - PathBuilder, Pixels, Refineable, RenderOnce, SharedString, StatefulInteractiveElement, - StyleRefinement, Styled, Window, canvas, div, fill, + App, Div, ElementId, Entity, HoverListenerMode, InteractiveElement, IntoElement, + MouseMoveEvent, ParentElement, PathBuilder, Pixels, Refineable, RenderOnce, SharedString, + StatefulInteractiveElement, StyleRefinement, Styled, Window, canvas, div, fill, }; use super::{ @@ -201,6 +201,7 @@ impl RenderOnce for FunnelChart { } }) }) + .hover_listener_mode(HoverListenerMode::InputModalityIndependent) .on_hover(move |inside, _, cx| { if !*inside { left.update(cx, |flows, cx| { diff --git a/src/charts/network.rs b/src/charts/network.rs index c51e6cf..203dcbf 100644 --- a/src/charts/network.rs +++ b/src/charts/network.rs @@ -1,10 +1,10 @@ use std::{collections::HashSet, f32::consts::TAU}; use gpui::{ - App, Bounds, Div, ElementId, Entity, InteractiveElement, IntoElement, MouseButton, - MouseDownEvent, MouseMoveEvent, MouseUpEvent, ParentElement, PathBuilder, Pixels, Refineable, - RenderOnce, SharedString, StatefulInteractiveElement, StyleRefinement, Styled, Window, canvas, - div, prelude::*, + App, Bounds, Div, ElementId, Entity, HoverListenerMode, InteractiveElement, IntoElement, + MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, ParentElement, PathBuilder, Pixels, + Refineable, RenderOnce, SharedString, StatefulInteractiveElement, StyleRefinement, Styled, + Window, canvas, div, prelude::*, }; use super::{ @@ -331,6 +331,7 @@ impl RenderOnce for NetworkGraph { } }) }) + .hover_listener_mode(HoverListenerMode::InputModalityIndependent) .on_hover(move |inside, _, cx| { if !*inside { left.update(cx, |graph, cx| { diff --git a/src/charts/pie.rs b/src/charts/pie.rs index 6d16c7b..84748a4 100644 --- a/src/charts/pie.rs +++ b/src/charts/pie.rs @@ -4,9 +4,9 @@ use std::{ }; use gpui::{ - App, Bounds, Div, ElementId, Entity, Hsla, InteractiveElement, IntoElement, MouseMoveEvent, - ParentElement, PathBuilder, Pixels, Point, Refineable, RenderOnce, SharedString, - StatefulInteractiveElement, StyleRefinement, Styled, Window, canvas, div, point, + App, Bounds, Div, ElementId, Entity, HoverListenerMode, Hsla, InteractiveElement, IntoElement, + MouseMoveEvent, ParentElement, PathBuilder, Pixels, Point, Refineable, RenderOnce, + SharedString, StatefulInteractiveElement, StyleRefinement, Styled, Window, canvas, div, point, }; use super::{ @@ -326,6 +326,7 @@ impl RenderOnce for PieChart { } }) }) + .hover_listener_mode(HoverListenerMode::InputModalityIndependent) .on_hover(move |inside, _, cx| { if !*inside { left.update(cx, |ring, cx| { diff --git a/src/charts/pointer.rs b/src/charts/pointer.rs index 4e6539a..94914d6 100644 --- a/src/charts/pointer.rs +++ b/src/charts/pointer.rs @@ -1,9 +1,9 @@ use std::rc::Rc; use gpui::{ - App, Bounds, Div, Entity, InteractiveElement, IntoElement, MouseButton, MouseDownEvent, - MouseMoveEvent, MouseUpEvent, PathBuilder, Pixels, Point, Stateful, StatefulInteractiveElement, - Styled, Window, canvas, fill, prelude::*, size, + App, Bounds, Div, Entity, HoverListenerMode, InteractiveElement, IntoElement, MouseButton, + MouseDownEvent, MouseMoveEvent, MouseUpEvent, PathBuilder, Pixels, Point, Stateful, + StatefulInteractiveElement, Styled, Window, canvas, fill, prelude::*, size, }; use super::{ @@ -247,6 +247,7 @@ pub(crate) fn answer( } }) }) + .hover_listener_mode(HoverListenerMode::InputModalityIndependent) .on_hover(move |inside, _, cx| { if !*inside { left.update(cx, |state, cx| { diff --git a/src/charts/radar.rs b/src/charts/radar.rs index 1be6c12..481b214 100644 --- a/src/charts/radar.rs +++ b/src/charts/radar.rs @@ -5,9 +5,10 @@ use std::{ }; use gpui::{ - App, Bounds, Div, ElementId, Entity, InteractiveElement, IntoElement, MouseMoveEvent, - ParentElement, PathBuilder, Pixels, Point, Refineable, RenderOnce, SharedString, - StatefulInteractiveElement, StyleRefinement, Styled, Window, canvas, div, point, prelude::*, + App, Bounds, Div, ElementId, Entity, HoverListenerMode, InteractiveElement, IntoElement, + MouseMoveEvent, ParentElement, PathBuilder, Pixels, Point, Refineable, RenderOnce, + SharedString, StatefulInteractiveElement, StyleRefinement, Styled, Window, canvas, div, point, + prelude::*, }; use super::{ @@ -268,6 +269,7 @@ impl RenderOnce for RadarChart { } }) }) + .hover_listener_mode(HoverListenerMode::InputModalityIndependent) .on_hover(move |inside, _, cx| { if !*inside { left.update(cx, |radar, cx| { diff --git a/src/charts/sunburst.rs b/src/charts/sunburst.rs index 0e38f27..e9a9003 100644 --- a/src/charts/sunburst.rs +++ b/src/charts/sunburst.rs @@ -1,9 +1,9 @@ use std::f32::consts::{FRAC_PI_2, TAU}; use gpui::{ - App, Div, ElementId, Entity, Hsla, InteractiveElement, IntoElement, MouseMoveEvent, - ParentElement, Pixels, Refineable, RenderOnce, SharedString, StatefulInteractiveElement, - StyleRefinement, Styled, Window, canvas, div, + App, Div, ElementId, Entity, HoverListenerMode, Hsla, InteractiveElement, IntoElement, + MouseMoveEvent, ParentElement, Pixels, Refineable, RenderOnce, SharedString, + StatefulInteractiveElement, StyleRefinement, Styled, Window, canvas, div, }; use super::{ @@ -214,6 +214,7 @@ impl RenderOnce for Sunburst { } }) }) + .hover_listener_mode(HoverListenerMode::InputModalityIndependent) .on_hover(move |inside, _, cx| { if !*inside { left.update(cx, |ring, cx| { diff --git a/src/charts/tests.rs b/src/charts/tests.rs index 6bd47ed..601a195 100644 --- a/src/charts/tests.rs +++ b/src/charts/tests.rs @@ -197,9 +197,9 @@ fn tab_reaches_a_legend_entry_and_enter_toggles_it(cx: &mut TestAppContext) { let (_, cx) = cx.add_window_view(|_, _| Keyed(seen)); cx.update(|window, _| window.activate_window()); settle(cx); - cx.update(|window, _| { - window.focus_next(); - window.focus_next(); + cx.update(|window, cx| { + window.focus_next(cx); + window.focus_next(cx); }); settle(cx); cx.simulate_keystrokes("enter"); diff --git a/src/charts/tiles.rs b/src/charts/tiles.rs index 16caf1a..5ece70e 100644 --- a/src/charts/tiles.rs +++ b/src/charts/tiles.rs @@ -1,9 +1,9 @@ use std::rc::Rc; use gpui::{ - App, Bounds, Div, ElementId, Entity, Hsla, InteractiveElement, IntoElement, MouseMoveEvent, - ParentElement, Pixels, Refineable, RenderOnce, SharedString, StatefulInteractiveElement, - StyleRefinement, Styled, Window, canvas, div, fill, + App, Bounds, Div, ElementId, Entity, HoverListenerMode, Hsla, InteractiveElement, IntoElement, + MouseMoveEvent, ParentElement, Pixels, Refineable, RenderOnce, SharedString, + StatefulInteractiveElement, StyleRefinement, Styled, Window, canvas, div, fill, }; use super::{ @@ -53,6 +53,7 @@ pub(crate) fn tracked( } }) }) + .hover_listener_mode(HoverListenerMode::InputModalityIndependent) .on_hover(move |inside, _, cx| { if !*inside { left.update(cx, |tiles, cx| { diff --git a/src/chat/actions.rs b/src/chat/actions.rs index b2be2f8..c9a25f5 100644 --- a/src/chat/actions.rs +++ b/src/chat/actions.rs @@ -248,7 +248,7 @@ impl RenderOnce for MessageEditor { let opened = window.use_keyed_state((self.id.clone(), "opened"), cx, |_, _| false); if !*opened.read(cx) { log::info!("message editor: takes focus"); - window.focus(&self.field.focus_handle(cx)); + window.focus(&self.field.focus_handle(cx), cx); opened.update(cx, |opened, _| *opened = true); } let text = self.field.read(cx).text().trim().to_string(); diff --git a/src/chat/media.rs b/src/chat/media.rs index 90f24db..2c30b61 100644 --- a/src/chat/media.rs +++ b/src/chat/media.rs @@ -15,7 +15,7 @@ use crate::{ typography::{Ellipsis, format::file_size}, }; -/// A box in a picture's own shape: as wide as the picture, but no wider than `widest` or its container. +/// A box in a picture's own shape: as wide as the picture, but no wider than `widest` or its container. Hand it to a flex column inside a block: taffy 0.13 sizes the column by its width before its cap. pub(crate) fn shaped(width: f32, height: f32, widest: Pixels) -> Div { assert!( width > 0.0 && height > 0.0, @@ -76,19 +76,21 @@ impl RenderOnce for ImageMessage { .flex_col() .gap_1() .child( - shaped(self.size.0, self.size.1, widest) - .id(self.id.clone()) - .relative() - .when_some(open, |picture, open| { - picture - .cursor_pointer() - .on_click(move |_, window, cx| open(window, cx)) - }) - .child( - Image::new((self.id.clone(), "picture"), source(&self.source)) - .fit(ObjectFit::Contain) - .size_full(), - ), + div().child( + shaped(self.size.0, self.size.1, widest) + .id(self.id.clone()) + .relative() + .when_some(open, |picture, open| { + picture + .cursor_pointer() + .on_click(move |_, window, cx| open(window, cx)) + }) + .child( + Image::new((self.id.clone(), "picture"), source(&self.source)) + .fit(ObjectFit::Contain) + .size_full(), + ), + ), ) .children(self.caption.map(|caption| { div() @@ -183,7 +185,7 @@ impl RenderOnce for ImageGrid { .flex() .flex_col() .gap_0p5(); - match count { + let grid = match count { 1 => grid.child(row().child(tile(0))), 2 => grid.child(row().child(tile(0)).child(tile(1))), 3 => grid.child( @@ -200,7 +202,8 @@ impl RenderOnce for ImageGrid { _ => grid .child(row().child(tile(0)).child(tile(1))) .child(row().child(tile(2)).child(tile(3))), - } + }; + div().child(grid) } } diff --git a/src/chat/play.rs b/src/chat/play.rs index 1f55ff5..6c81276 100644 --- a/src/chat/play.rs +++ b/src/chat/play.rs @@ -249,7 +249,7 @@ impl RenderOnce for VideoMessage { }; let playing = self.playing; let toggle = self.on_toggle.clone(); - shaped(self.size.0, self.size.1, widest) + let video = shaped(self.size.0, self.size.1, widest) .id(self.id.clone()) .relative() .bg(colors.media_backdrop) @@ -316,6 +316,7 @@ impl RenderOnce for VideoMessage { .bg(colors.on_media.opacity(0.25)) .child(div().h_full().w(relative(share)).bg(colors.on_media)), ), - ) + ); + div().child(video) } } diff --git a/src/chat/tests/cite.rs b/src/chat/tests/cite.rs index 89e5a7f..a684a3f 100644 --- a/src/chat/tests/cite.rs +++ b/src/chat/tests/cite.rs @@ -78,7 +78,7 @@ fn citations_and_sources_open_from_the_keyboard(cx: &mut TestAppContext) { }); cx.update(|window, _| window.activate_window()); settle(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); release("enter", cx); assert_eq!( cited.read_with(cx, |cited, _| cited.opened), @@ -86,7 +86,7 @@ fn citations_and_sources_open_from_the_keyboard(cx: &mut TestAppContext) { "the badge opens its source" ); let folded = frame.borrow().expect("the list is laid out").size.height; - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); release("space", cx); let open = frame.borrow().expect("the list is laid out").size.height; assert!( @@ -126,9 +126,9 @@ fn cards_open_from_the_keyboard(cx: &mut TestAppContext) { let (cards, cx) = cx.add_window_view(|_, _| Cards { opened: Vec::new() }); cx.update(|window, _| window.activate_window()); settle(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); release("enter", cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); release("enter", cx); assert_eq!( cards.read_with(cx, |cards, _| cards.opened.clone()), diff --git a/src/chat/tests/compose.rs b/src/chat/tests/compose.rs index 03662e9..04dc84f 100644 --- a/src/chat/tests/compose.rs +++ b/src/chat/tests/compose.rs @@ -67,7 +67,7 @@ fn open( cx.update(|window, cx| { window.activate_window(); let field = compose.read(cx).field.focus_handle(cx); - window.focus(&field); + window.focus(&field, cx); }); settle(cx); (compose, cx) diff --git a/src/chat/tests/history.rs b/src/chat/tests/history.rs index e9bdfe6..46fb7e0 100644 --- a/src/chat/tests/history.rs +++ b/src/chat/tests/history.rs @@ -67,9 +67,9 @@ fn a_rows_actions_open_from_the_keyboard(cx: &mut TestAppContext) { let (row, cx) = row(cx); cx.simulate_mouse_move(point(px(10.0), px(200.0)), None, Modifiers::none()); settle(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); settle(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); settle(cx); press("enter", cx); press("enter", cx); diff --git a/src/chat/tests/mod.rs b/src/chat/tests/mod.rs index c98c2a7..d90ed5a 100644 --- a/src/chat/tests/mod.rs +++ b/src/chat/tests/mod.rs @@ -1,10 +1,10 @@ -use std::{cell::RefCell, rc::Rc}; +use std::{cell::RefCell, rc::Rc, time::Duration}; use gpui::{ - AppContext as _, Bounds, Context, Entity, Focusable, InteractiveElement, IntoElement, - KeyUpEvent, Keystroke, Modifiers, MouseButton, ParentElement, Pixels, Render, ScrollDelta, - ScrollWheelEvent, Styled, TestAppContext, TouchPhase, VisualTestContext, Window, canvas, div, - point, px, + AnyElement, AppContext as _, Bounds, Context, Entity, Focusable, InteractiveElement, + IntoElement, KeyUpEvent, Keystroke, Modifiers, MouseButton, ParentElement, Pixels, Render, + ScrollDelta, ScrollWheelEvent, Styled, TestAppContext, TouchPhase, VisualTestContext, Window, + canvas, div, point, px, }; mod cite; @@ -13,8 +13,8 @@ mod history; mod welcome; use super::{ - DateSeparator, ImageMessage, MessageAvatar, MessageBubble, MessageEditor, MessageList, Role, - ThinkingBlock, + DateSeparator, ImageGrid, ImageMessage, MessageAvatar, MessageBubble, MessageEditor, + MessageList, Role, ThinkingBlock, VideoMessage, }; use crate::{forms, forms::TextInput, theme::Theme}; @@ -139,7 +139,7 @@ fn an_edit_saves_only_a_change_and_escape_cancels(cx: &mut TestAppContext) { cx.update(|window, cx| { window.activate_window(); let field = edit.read(cx).field.focus_handle(cx); - window.focus(&field); + window.focus(&field, cx); }); settle(cx); cx.simulate_keystrokes("cmd-enter"); @@ -306,6 +306,63 @@ fn a_picture_fits_a_narrow_column_in_its_own_shape(cx: &mut TestAppContext) { assert_eq!(bounds.size.height, px(160.0), "240 wide at 3:2 is 160 tall"); } +/// A message in a narrow flex column, the column measured. +struct Column { + frame: Measured, + message: fn() -> AnyElement, +} + +impl Render for Column { + fn render(&mut self, _: &mut Window, _: &mut Context) -> impl IntoElement { + let frame = self.frame.clone(); + div().size_full().child( + div() + .w(px(240.0)) + .relative() + .flex() + .flex_col() + .child((self.message)()) + .child( + canvas( + move |bounds, _, _| *frame.borrow_mut() = Some(bounds), + |_, _, _, _| {}, + ) + .absolute() + .top_0() + .left_0() + .size_full(), + ), + ) + } +} + +fn column_height(message: fn() -> AnyElement, cx: &mut TestAppContext) -> Pixels { + let frame = Measured::default(); + let seen = frame.clone(); + let (_, cx) = cx.add_window_view(move |_, _| Column { + frame: seen, + message, + }); + settle(cx); + frame.borrow().expect("the column is laid out").size.height +} + +#[gpui::test] +fn a_video_and_a_grid_fit_a_narrow_flex_column_in_their_shape(cx: &mut TestAppContext) { + cx.update(Theme::init); + let video = || { + VideoMessage::new("video", "dunes.jpg", 960.0, 640.0, Duration::from_secs(84)) + .into_any_element() + }; + assert_eq!(column_height(video, cx), px(160.0), "240 wide at 3:2"); + let grid = || ImageGrid::new("grid", ["a.jpg", "b.jpg"]).into_any_element(); + assert_eq!( + column_height(grid, cx), + px(120.0), + "two side by side at 2:1" + ); +} + /// Reasoning folded under its time, the block's box measured. struct Reasoning { frame: Measured, @@ -350,7 +407,7 @@ fn the_reasoning_opens_from_the_keyboard(cx: &mut TestAppContext) { cx.update(|window, _| window.activate_window()); settle(cx); let closed = frame.borrow().expect("the block is laid out").size.height; - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_keystrokes("space"); cx.simulate_event(KeyUpEvent { keystroke: Keystroke::parse("space").expect("space parses"), diff --git a/src/collab/remote.rs b/src/collab/remote.rs index 0f643c7..6cb29dc 100644 --- a/src/collab/remote.rs +++ b/src/collab/remote.rs @@ -2,7 +2,7 @@ use std::ops::Range; use gpui::{ App, Bounds, ContentMask, Entity, FontWeight, IntoElement, Pixels, RenderOnce, SharedString, - Styled, TextRun, Window, canvas, fill, point, size, + Styled, TextAlign, TextRun, Window, canvas, fill, point, size, }; use super::peers::Peer; @@ -92,9 +92,14 @@ impl RenderOnce for RemoteCursor { bottom_right: radius, bottom_left: gpui::Pixels::ZERO, })); - if let Err(error) = - line.paint(point(flag.left() + pad, flag.top()), height, window, cx) - { + if let Err(error) = line.paint( + point(flag.left() + pad, flag.top()), + height, + TextAlign::Left, + None, + window, + cx, + ) { log::error!("remote cursor: name did not paint: {error:#}"); } }, diff --git a/src/collab/tests.rs b/src/collab/tests.rs index 8915350..2a16dca 100644 --- a/src/collab/tests.rs +++ b/src/collab/tests.rs @@ -49,7 +49,7 @@ fn open(following: bool, cx: &mut TestAppContext) -> (Entity, &mut VisualT cx.update(|window, cx| { window.activate_window(); let field = desk.read(cx).field.clone(); - window.focus(&field.focus_handle(cx)); + window.focus(&field.focus_handle(cx), cx); }); cx.run_until_parked(); (desk, cx) @@ -84,7 +84,7 @@ fn following_begun_from_outside_still_stops_on_escape(cx: &mut TestAppContext) { let (desk, cx) = open(false, cx); cx.update(|window, cx| { let outside = desk.read(cx).outside.focus_handle(cx); - window.focus(&outside); + window.focus(&outside, cx); }); desk.update(cx, |desk, cx| { desk.following = true; diff --git a/src/dashboard/tests.rs b/src/dashboard/tests.rs index 35898f5..719a5cc 100644 --- a/src/dashboard/tests.rs +++ b/src/dashboard/tests.rs @@ -95,7 +95,7 @@ fn press(key: &str, cx: &mut VisualTestContext) { #[gpui::test] fn arrows_step_a_focused_tile_past_its_neighbours_and_shift_grows_it(cx: &mut TestAppContext) { let (host, cx) = wall(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); settle(cx); press("down", cx); assert_eq!(place(&host, "a", cx), (0, 4, 6, 2), "a went below c"); @@ -115,7 +115,7 @@ fn arrows_step_a_focused_tile_past_its_neighbours_and_shift_grows_it(cx: &mut Te fn arrows_in_a_control_inside_a_card_leave_the_tiles_where_they_are(cx: &mut TestAppContext) { let (host, cx) = wall(cx); let inside = host.read_with(cx, |wall, _| wall.inside.clone()); - cx.update(|window, _| window.focus(&inside)); + cx.update(|window, cx| window.focus(&inside, cx)); settle(cx); press("right", cx); press("down", cx); @@ -168,9 +168,9 @@ fn said(host: &Entity, cx: &mut VisualTestContext) -> Vec { } fn tab(stops: usize, cx: &mut VisualTestContext) { - cx.update(|window, _| { - window.blur(); - (0..stops).for_each(|_| window.focus_next()); + cx.update(|window, cx| { + window.blur(cx); + (0..stops).for_each(|_| window.focus_next(cx)); }); settle(cx); } diff --git a/src/data_display/carousel.rs b/src/data_display/carousel.rs index 9bf049a..57cbec2 100644 --- a/src/data_display/carousel.rs +++ b/src/data_display/carousel.rs @@ -4,9 +4,9 @@ use std::{ }; use gpui::{ - AnyElement, App, Div, ElementId, InteractiveElement, IntoElement, MouseButton, ParentElement, - RenderOnce, StatefulInteractiveElement, StyleRefinement, Styled, Task, Window, div, prelude::*, - relative, + AnyElement, App, Div, ElementId, HoverListenerMode, InteractiveElement, IntoElement, + MouseButton, ParentElement, RenderOnce, StatefulInteractiveElement, StyleRefinement, Styled, + Task, Window, div, prelude::*, relative, }; use crate::{ @@ -268,6 +268,7 @@ impl RenderOnce for Carousel { .flex() .flex_col() .gap_2() + .hover_listener_mode(HoverListenerMode::InputModalityIndependent) .on_hover(move |hovered, _, cx| { hover.update(cx, |deck, cx| { deck.hovered = *hovered; diff --git a/src/data_display/tests.rs b/src/data_display/tests.rs index 8726ed1..077d515 100644 --- a/src/data_display/tests.rs +++ b/src/data_display/tests.rs @@ -161,6 +161,9 @@ fn wait(time: Duration, cx: &mut VisualTestContext) { #[gpui::test] fn autoplay_turns_the_carousel_and_holds_while_pointed_at(cx: &mut TestAppContext) { let (places, cx) = deck(cx); + // The pointer starts at the corner, over the deck, which gpui now counts as a hover. + cx.simulate_mouse_move(point(px(600.0), px(400.0)), None, Modifiers::none()); + settle(cx); assert_eq!(front(&places), Some(0)); wait(Duration::from_secs(5), cx); assert_eq!(front(&places), Some(1), "five seconds turn it once"); @@ -174,6 +177,17 @@ fn autoplay_turns_the_carousel_and_holds_while_pointed_at(cx: &mut TestAppContex assert_eq!(front(&places), Some(2)); } +#[gpui::test] +fn a_key_under_a_resting_pointer_keeps_the_carousel_held(cx: &mut TestAppContext) { + let (places, cx) = deck(cx); + cx.simulate_mouse_move(point(px(100.0), px(50.0)), None, Modifiers::none()); + settle(cx); + cx.simulate_keystrokes("a"); + settle(cx); + wait(Duration::from_secs(12), cx); + assert_eq!(front(&places), Some(0), "still held"); +} + #[gpui::test] fn left_from_the_first_slide_wraps_to_the_last(cx: &mut TestAppContext) { let (places, cx) = deck(cx); diff --git a/src/debug/flame.rs b/src/debug/flame.rs index d9656c4..317a343 100644 --- a/src/debug/flame.rs +++ b/src/debug/flame.rs @@ -2,8 +2,8 @@ use std::rc::Rc; use gpui::{ App, Bounds, ElementId, Hsla, InteractiveElement, IntoElement, MouseButton, MouseDownEvent, - MouseMoveEvent, ParentElement, Pixels, RenderOnce, SharedString, Styled, Window, canvas, div, - fill, point, size, + MouseMoveEvent, ParentElement, Pixels, RenderOnce, SharedString, Styled, TextAlign, Window, + canvas, div, fill, point, size, }; use crate::{ @@ -297,6 +297,8 @@ impl RenderOnce for Flamegraph { (row - pixels * 1.2) / 2.0, ), pixels * 1.2, + TextAlign::Left, + None, window, cx, ) diff --git a/src/debug/hex.rs b/src/debug/hex.rs index a94a4f6..a9e68c7 100644 --- a/src/debug/hex.rs +++ b/src/debug/hex.rs @@ -1,8 +1,8 @@ use std::{ops::Range, rc::Rc}; use gpui::{ - App, ElementId, InteractiveElement, IntoElement, MouseButton, ParentElement, RenderOnce, - StatefulInteractiveElement, Styled, Window, div, prelude::*, uniform_list, + App, ElementId, HoverListenerMode, InteractiveElement, IntoElement, MouseButton, ParentElement, + RenderOnce, StatefulInteractiveElement, Styled, Window, div, prelude::*, uniform_list, }; use super::OnIndex; @@ -126,6 +126,7 @@ impl RenderOnce for HexViewer { .id((id.clone(), format!("{key}-{at}"))) .px_0p5() .when_some(wash(at), |cell, wash| cell.bg(wash)) + .hover_listener_mode(HoverListenerMode::InputModalityIndependent) .on_hover(move |on, _, cx| { hover.update(cx, |hovered, cx| { let next = if *on { Some(at) } else { None }; diff --git a/src/debug/tests.rs b/src/debug/tests.rs index bc5fb57..a02d04e 100644 --- a/src/debug/tests.rs +++ b/src/debug/tests.rs @@ -124,8 +124,8 @@ fn tab_reaches_each_span_and_enter_picks_it(cx: &mut TestAppContext) { let (_, cx) = cx.add_window_view(|_, _| Spans(store)); cx.update(|window, _| window.activate_window()); settle(cx); - cx.update(|window, _| window.focus_next()); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_keystrokes("enter"); settle(cx); cx.simulate_event(KeyUpEvent { diff --git a/src/devtools/tests/mod.rs b/src/devtools/tests/mod.rs index e438a70..f7695f0 100644 --- a/src/devtools/tests/mod.rs +++ b/src/devtools/tests/mod.rs @@ -65,9 +65,9 @@ fn said(host: &Entity, cx: &mut VisualTestContext) -> Vec { } fn tab(stops: usize, cx: &mut VisualTestContext) { - cx.update(|window, _| { - window.blur(); - (0..stops).for_each(|_| window.focus_next()); + cx.update(|window, cx| { + window.blur(cx); + (0..stops).for_each(|_| window.focus_next(cx)); }); settle(cx); } @@ -163,9 +163,9 @@ fn form(bench: &Bench, _: &mut Window, _: &mut App, owner: Entity) -> Any /// Save is the form's last stop, so a step back from nothing reaches it. fn last(cx: &mut VisualTestContext) { - cx.update(|window, _| { - window.blur(); - window.focus_prev(); + cx.update(|window, cx| { + window.blur(cx); + window.focus_prev(cx); }); settle(cx); } diff --git a/src/documents/blocks/edit.rs b/src/documents/blocks/edit.rs index 92e48f6..5ba9ab7 100644 --- a/src/documents/blocks/edit.rs +++ b/src/documents/blocks/edit.rs @@ -123,7 +123,7 @@ impl BlockEditor { && let Some(field) = block.fields.get(field) { field.update(cx, |field, cx| field.select(selection, cx)); - window.focus(&field.focus_handle(cx)); + window.focus(&field.focus_handle(cx), cx); } self.current = snapshot; cx.emit(BlockEvent::Changed); diff --git a/src/documents/blocks/mod.rs b/src/documents/blocks/mod.rs index 3ba9837..64a8744 100644 --- a/src/documents/blocks/mod.rs +++ b/src/documents/blocks/mod.rs @@ -349,7 +349,7 @@ impl BlockEditor { if let Some(at) = at { field.update(cx, |field, cx| field.select(at..at, cx)); } - window.focus(&field.focus_handle(cx)); + window.focus(&field.focus_handle(cx), cx); } /// Adds a block after `after`, or first, and puts the caret in it. diff --git a/src/documents/blocks/table.rs b/src/documents/blocks/table.rs index 6898dfe..1bb5695 100644 --- a/src/documents/blocks/table.rs +++ b/src/documents/blocks/table.rs @@ -248,7 +248,7 @@ pub(super) fn table( let wide = span(&merged, columns, row, column); line = line.child( div() - .flex_grow() + .flex_grow_1() .flex_basis(gpui::relative(wide as f32 / columns as f32)) .min_w_0() .px_2() diff --git a/src/documents/blocks/tests.rs b/src/documents/blocks/tests.rs index 31a3d70..156f6a5 100644 --- a/src/documents/blocks/tests.rs +++ b/src/documents/blocks/tests.rs @@ -59,7 +59,7 @@ fn caret(editor: &Entity, ix: usize, at: usize, cx: &mut VisualTest cx.update(|window, cx| { let field = editor.read(cx).blocks[ix].fields[0].clone(); field.update(cx, |field, cx| field.select(at..at, cx)); - window.focus(&field.focus_handle(cx)); + window.focus(&field.focus_handle(cx), cx); }); settle(cx); } @@ -211,7 +211,7 @@ fn select( cx.update(|window, cx| { let field = editor.read(cx).blocks[ix].fields[field].clone(); field.update(cx, |field, cx| field.select(range, cx)); - window.focus(&field.focus_handle(cx)); + window.focus(&field.focus_handle(cx), cx); }); settle(cx); } @@ -280,7 +280,7 @@ fn keys_into_a_merged_cell_land_on_the_cell_that_shows(cx: &mut TestAppContext) select(&editor, 0, 0, 1..1, cx); cx.update(|window, cx| { let field = editor.read(cx).blocks[0].fields[1].clone(); - window.focus(&field.focus_handle(cx)); + window.focus(&field.focus_handle(cx), cx); }); settle(cx); cx.simulate_keystrokes("down"); diff --git a/src/documents/link.rs b/src/documents/link.rs index e203ecb..3a98ec5 100644 --- a/src/documents/link.rs +++ b/src/documents/link.rs @@ -105,7 +105,7 @@ impl RenderOnce for LinkEditor { log::info!("link editor: open over {:?}", linking.range); let written = linking.address.clone().unwrap_or_default(); address.update(cx, |field, cx| field.set_text(written, cx)); - window.focus(&address.focus_handle(cx)); + window.focus(&address.focus_handle(cx), cx); editing.update(cx, |editing, _| editing.seeded = true); } let focus = takeover.read(cx).focus.clone(); diff --git a/src/documents/modes.rs b/src/documents/modes.rs index 47f1b22..579d72f 100644 --- a/src/documents/modes.rs +++ b/src/documents/modes.rs @@ -135,7 +135,7 @@ fn open( input.select(0..0, cx); } }); - window.focus(&input.focus_handle(cx)); + window.focus(&input.focus_handle(cx), cx); let blur = { let (state, field) = (state.clone(), field.clone()); cx.subscribe(&input, move |_, event: &InputEvent, cx| { diff --git a/src/documents/reading.rs b/src/documents/reading.rs index 8363ab9..aab754a 100644 --- a/src/documents/reading.rs +++ b/src/documents/reading.rs @@ -214,7 +214,7 @@ impl RenderOnce for ReadingProgress { move |bounds, _, window, _| { let share = read_share( f32::from(scroll.offset().y), - f32::from(scroll.max_offset().height), + f32::from(scroll.max_offset().y), ); let filled = Bounds::new( bounds.origin, diff --git a/src/documents/tests.rs b/src/documents/tests.rs index 4db53b2..db9260a 100644 --- a/src/documents/tests.rs +++ b/src/documents/tests.rs @@ -239,7 +239,7 @@ fn escape_leaves_zen_turned_on_from_outside_and_hands_focus_back(cx: &mut TestAp cx.update(|window, cx| { window.activate_window(); let outside = zen.read(cx).outside.focus_handle(cx); - window.focus(&outside); + window.focus(&outside, cx); }); settle(cx); zen.update(cx, |zen, cx| { diff --git a/src/editor/keys.rs b/src/editor/keys.rs index 8330727..d6c15a4 100644 --- a/src/editor/keys.rs +++ b/src/editor/keys.rs @@ -247,7 +247,13 @@ pub(crate) fn listen(root: E, cx: &mut Context, ) { - window.focus(&self.focus); + window.focus(&self.focus, cx); let at = self.offset_in(line, event.position.x, cx); let chosen = match event.click_count { 2 => { diff --git a/src/editor/state.rs b/src/editor/state.rs index 62fce8a..db6a0bc 100644 --- a/src/editor/state.rs +++ b/src/editor/state.rs @@ -397,9 +397,9 @@ impl CodeEditor { self.marks.chat = line; if line.is_some() { let focus = self.chat_field.read(cx).focus().clone(); - window.focus(&focus); + window.focus(&focus, cx); } else { - window.focus(&self.focus); + window.focus(&self.focus, cx); cx.emit(EditorEvent::ChatClosed); } cx.notify(); diff --git a/src/editor/tests.rs b/src/editor/tests.rs index 81d28aa..091c627 100644 --- a/src/editor/tests.rs +++ b/src/editor/tests.rs @@ -1,6 +1,6 @@ use std::time::Duration; -use gpui::{Entity, EntityInputHandler, TestAppContext, VisualTestContext}; +use gpui::{Entity, EntityInputHandler, KeyUpEvent, Keystroke, TestAppContext, VisualTestContext}; use super::{CodeEditor, GhostText, InlayHint, LineNumbers, layout::Row}; use crate::theme::Theme; @@ -140,6 +140,29 @@ fn a_read_only_editor_ignores_typing_and_undo(cx: &mut TestAppContext) { }); } +#[gpui::test] +fn enter_presses_the_banner_button_inside_the_editor(cx: &mut TestAppContext) { + let (editor, cx) = editor("x", cx); + cx.update(|window, cx| { + super::keys::bind_keys(cx); + editor.update(cx, |editor, cx| editor.set_read_only(true, cx)); + window.refresh(); + }); + cx.run_until_parked(); + let focus = editor.read_with(cx, |editor, _| editor.focus.clone()); + cx.update(|window, cx| { + window.focus(&focus, cx); + window.focus_next(cx); + }); + cx.run_until_parked(); + cx.simulate_keystrokes("enter"); + cx.simulate_event(KeyUpEvent { + keystroke: Keystroke::parse("enter").expect("a key"), + }); + cx.run_until_parked(); + assert!(!editor.read_with(cx, |editor, _| editor.is_read_only())); +} + #[gpui::test] fn a_hint_past_a_multi_line_ghost_stays_in_its_row(cx: &mut TestAppContext) { let (editor, cx) = editor("call(x)\nnext", cx); diff --git a/src/editor/view.rs b/src/editor/view.rs index 3171388..26409c2 100644 --- a/src/editor/view.rs +++ b/src/editor/view.rs @@ -268,7 +268,7 @@ impl Render for CodeEditor { range.map(|ix| editor.row(ix, window, cx)).collect() }), ) - .track_scroll(self.scroll.clone()) + .track_scroll(&self.scroll) .size_full(); let (top, focus, input) = (cx.entity(), self.focus.clone(), cx.entity()); let unlock = cx.entity(); diff --git a/src/feedback/tests/loading.rs b/src/feedback/tests/loading.rs index 9bbb8ca..b7f4878 100644 --- a/src/feedback/tests/loading.rs +++ b/src/feedback/tests/loading.rs @@ -79,7 +79,7 @@ fn an_async_view_shows_its_value_once_loaded(cx: &mut TestAppContext) { fn a_failed_load_tries_again_from_its_button(cx: &mut TestAppContext) { let (loads, shows, cx) = report(true, cx); assert_eq!((loads.load(Ordering::SeqCst), shows.get()), (1, 0)); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); press("enter", cx); settle(cx); assert_eq!(loads.load(Ordering::SeqCst), 2); diff --git a/src/feedback/tests/mod.rs b/src/feedback/tests/mod.rs index 7e6f45b..2135683 100644 --- a/src/feedback/tests/mod.rs +++ b/src/feedback/tests/mod.rs @@ -75,7 +75,7 @@ fn desk(cx: &mut TestAppContext) -> (Entity, &mut VisualTestContext) { }); settle(cx); let root = view.read_with(cx, |desk, _| desk.root.clone()); - cx.update(|window, _| window.focus(&root)); + cx.update(|window, cx| window.focus(&root, cx)); (view, cx) } @@ -161,6 +161,19 @@ fn the_pointer_on_the_stack_holds_the_clock(cx: &mut TestAppContext) { assert!(toasts(&view, cx).is_empty()); } +#[gpui::test] +fn typing_under_a_resting_pointer_keeps_the_hold(cx: &mut TestAppContext) { + let (view, cx) = desk(cx); + let id = push(&view, Toast::new("Saved"), cx); + let screen = cx.update(|window, _| window.viewport_size()); + let on_toast = point(screen.width - px(120.0), screen.height - px(48.0)); + cx.simulate_mouse_move(on_toast, None, Modifiers::none()); + settle(cx); + press("a", cx); + wait(Duration::from_secs(20), cx); + assert_eq!(toasts(&view, cx), [(id, false)], "a key leaves the pointer"); +} + #[gpui::test] fn a_fifth_toast_sends_the_oldest_away(cx: &mut TestAppContext) { let (view, cx) = desk(cx); diff --git a/src/feedback/tests/states.rs b/src/feedback/tests/states.rs index 08e720c..10c214f 100644 --- a/src/feedback/tests/states.rs +++ b/src/feedback/tests/states.rs @@ -73,7 +73,7 @@ fn shelf( }); settle(cx); let root = view.read_with(cx, |shelf, _| shelf.root.clone()); - cx.update(|window, _| window.focus(&root)); + cx.update(|window, cx| window.focus(&root, cx)); (view, cx) } @@ -113,7 +113,7 @@ fn retry_shows_only_once_saving_failed(cx: &mut TestAppContext) { }); settle(cx); let root = view.read_with(cx, |shelf, _| shelf.root.clone()); - cx.update(|window, _| window.focus(&root)); + cx.update(|window, cx| window.focus(&root, cx)); for _ in 0..3 { press("tab", cx); } diff --git a/src/feedback/toast.rs b/src/feedback/toast.rs index 03de386..3f92f42 100644 --- a/src/feedback/toast.rs +++ b/src/feedback/toast.rs @@ -4,10 +4,10 @@ use std::{ }; use gpui::{ - Animation, AnimationExt, AnyElement, App, ClickEvent, Context, Corner, ElementId, Entity, - FontWeight, InteractiveElement, IntoElement, ParentElement, Pixels, RenderOnce, SharedString, - StatefulInteractiveElement, Styled, Task, Window, anchored, canvas, div, point, prelude::*, - relative, + Anchor, Animation, AnimationExt, AnyElement, App, ClickEvent, Context, ElementId, Entity, + FontWeight, HoverListenerMode, InteractiveElement, IntoElement, ParentElement, Pixels, + RenderOnce, SharedString, StatefulInteractiveElement, Styled, Task, Window, anchored, canvas, + div, point, prelude::*, relative, }; use crate::{ @@ -230,6 +230,7 @@ impl RenderOnce for ToastViewport { .flex() .flex_col() .w(width) + .hover_listener_mode(HoverListenerMode::InputModalityIndependent) .on_hover(move |hovered, _, cx| { hold.update(cx, |toaster, cx| toaster.hold(*hovered, cx)) }) @@ -238,7 +239,7 @@ impl RenderOnce for ToastViewport { (self.id, "raised"), anchored() .position(point(viewport.width - margin, viewport.height - margin)) - .anchor(Corner::BottomRight) + .anchor(Anchor::BottomRight) .child(stack), ) .with_priority(1) diff --git a/src/files/tests/explorer.rs b/src/files/tests/explorer.rs index 2ef6b4b..21cdcdb 100644 --- a/src/files/tests/explorer.rs +++ b/src/files/tests/explorer.rs @@ -70,10 +70,10 @@ fn exploring<'a>( /// Moves focus to the `nth` Tab stop from none: the three views, the path's first level, then the view's own. fn tab_to(nth: usize, cx: &mut VisualTestContext) { - cx.update(|window, _| { - window.blur(); + cx.update(|window, cx| { + window.blur(cx); for _ in 0..nth { - window.focus_next(); + window.focus_next(cx); } }); settle(cx); diff --git a/src/files/tests/find.rs b/src/files/tests/find.rs index 02f6eb5..1401e17 100644 --- a/src/files/tests/find.rs +++ b/src/files/tests/find.rs @@ -17,10 +17,10 @@ use crate::{ /// Moves focus to the `nth` Tab stop from none. fn tab_to(nth: usize, cx: &mut VisualTestContext) { - cx.update(|window, _| { - window.blur(); + cx.update(|window, cx| { + window.blur(cx); for _ in 0..nth { - window.focus_next(); + window.focus_next(cx); } }); settle(cx); diff --git a/src/files/tests/mod.rs b/src/files/tests/mod.rs index 96c39bf..0cea779 100644 --- a/src/files/tests/mod.rs +++ b/src/files/tests/mod.rs @@ -103,7 +103,7 @@ fn heard( #[gpui::test] fn the_arrows_move_by_tile_and_by_row_and_enter_opens(cx: &mut TestAppContext) { let (view, cx) = tiled(None, cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); for key in ["right", "right", "down", "down", "cmd-left"] { press(key, cx); } @@ -116,7 +116,7 @@ fn the_arrows_move_by_tile_and_by_row_and_enter_opens(cx: &mut TestAppContext) { #[gpui::test] fn the_keys_start_from_the_tile_picked(cx: &mut TestAppContext) { let (view, cx) = tiled(Some("c"), cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); press("down", cx); assert_eq!(heard(&view, cx).0, ["f"]); } diff --git a/src/files/tests/transfers.rs b/src/files/tests/transfers.rs index 9c5951c..90143c1 100644 --- a/src/files/tests/transfers.rs +++ b/src/files/tests/transfers.rs @@ -11,10 +11,10 @@ use crate::files::{ /// Moves focus to the `nth` Tab stop from none. fn tab_to(nth: usize, cx: &mut VisualTestContext) { - cx.update(|window, _| { - window.blur(); + cx.update(|window, cx| { + window.blur(cx); for _ in 0..nth { - window.focus_next(); + window.focus_next(cx); } }); settle(cx); diff --git a/src/finance/steer.rs b/src/finance/steer.rs index 8bef4b3..c2c5707 100644 --- a/src/finance/steer.rs +++ b/src/finance/steer.rs @@ -1,9 +1,9 @@ use std::rc::Rc; use gpui::{ - App, Bounds, Div, Entity, InteractiveElement, MouseButton, MouseDownEvent, MouseMoveEvent, - MouseUpEvent, Pixels, Point, ScrollWheelEvent, Stateful, StatefulInteractiveElement, Styled, - Subscription, Window, + App, Bounds, Div, Entity, HoverListenerMode, InteractiveElement, MouseButton, MouseDownEvent, + MouseMoveEvent, MouseUpEvent, Pixels, Point, ScrollWheelEvent, Stateful, + StatefulInteractiveElement, Styled, Subscription, Window, }; use super::{ @@ -167,6 +167,7 @@ impl Steering { cx.stop_propagation(); hold(&wheeled, &sync_wheel, cx, Some(next), None); }) + .hover_listener_mode(HoverListenerMode::InputModalityIndependent) .on_hover(move |inside, _, cx| { if !*inside { left.update(cx, |stage, _| { diff --git a/src/forms/date/calendar.rs b/src/forms/date/calendar.rs index 110dc86..7e4f4b9 100644 --- a/src/forms/date/calendar.rs +++ b/src/forms/date/calendar.rs @@ -329,7 +329,7 @@ impl RenderOnce for Calendar { .grid_cols(7) .gap_0p5() .on_hover(move |over, window, cx| { - if !*over { + if !*over && !window.last_input_was_keyboard() { leave.update(cx, |hover, cx| { *hover = None; cx.notify(); diff --git a/src/forms/date/picker.rs b/src/forms/date/picker.rs index 7d10e1f..9a9150b 100644 --- a/src/forms/date/picker.rs +++ b/src/forms/date/picker.rs @@ -60,7 +60,7 @@ pub(crate) fn toggle( state.preview = None; cx.notify(); }); - window.focus(if open { &inner } else { trigger }); + window.focus(if open { &inner } else { trigger }, cx); } /// What a picker field shows while closed, and how it sits. diff --git a/src/forms/group.rs b/src/forms/group.rs index a1c21f6..79e2364 100644 --- a/src/forms/group.rs +++ b/src/forms/group.rs @@ -110,7 +110,9 @@ impl RenderOnce for InputGroup { .bg(colors.surface) .text_size(theme.text_size(text_size(self.size))) .text_color(colors.fg) - .on_mouse_down(MouseButton::Left, move |_, window, _| window.focus(&focus)) + .on_mouse_down(MouseButton::Left, move |_, window, cx| { + window.focus(&focus, cx) + }) .children(self.before.into_iter().map(|block| addon(block, true))) .child(div().flex_1().min_w_0().px(pad).child(self.state)) .children(self.after.into_iter().map(|block| addon(block, false))) diff --git a/src/forms/hotkey.rs b/src/forms/hotkey.rs index 0ebb4c1..54d93c8 100644 --- a/src/forms/hotkey.rs +++ b/src/forms/hotkey.rs @@ -73,7 +73,7 @@ impl RenderOnce for HotkeyInput { let bare = !stroke.modifiers.modified(); let next = match stroke.key.as_str() { "escape" if bare => { - window.blur(); + window.blur(cx); return; } "backspace" | "delete" if bare => None, @@ -87,7 +87,7 @@ impl RenderOnce for HotkeyInput { next.as_ref() .map_or("cleared".into(), |stroke| stroke.unparse()) ); - window.blur(); + window.blur(cx); if let Some(on_change) = &on_change { on_change(next, window, cx); } diff --git a/src/forms/inline.rs b/src/forms/inline.rs index c91eafa..33c46eb 100644 --- a/src/forms/inline.rs +++ b/src/forms/inline.rs @@ -33,7 +33,7 @@ impl Editing { }); let all = field.read(cx).text().len(); field.update(cx, |input, cx| input.select(0..all, cx)); - window.focus(&field.read(cx).focus().clone()); + window.focus(&field.read(cx).focus().clone(), cx); let owner = state.clone(); let events = window.subscribe(&field, cx, move |_, event, window, cx| match event { InputEvent::Submit => owner.update(cx, |editing, cx| { @@ -58,10 +58,10 @@ impl Editing { self.back = Some(back); } - pub(crate) fn give_back(&mut self, window: &mut Window) { + pub(crate) fn give_back(&mut self, window: &mut Window, cx: &mut App) { if let Some(back) = self.back.take() { log::info!("inline edit: focus handed back"); - window.focus(&back); + window.focus(&back, cx); } } @@ -134,7 +134,7 @@ impl RenderOnce for InlineEdit { cx.stop_propagation(); escape.update(cx, |editing, cx| { editing.finish(true, window, cx); - editing.give_back(window); + editing.give_back(window, cx); }); } }) @@ -143,7 +143,7 @@ impl RenderOnce for InlineEdit { cx.stop_propagation(); enter.update(cx, |editing, cx| { editing.finish(false, window, cx); - editing.give_back(window); + editing.give_back(window, cx); }); } }) diff --git a/src/forms/input.rs b/src/forms/input.rs index 23f86ec..2211057 100644 --- a/src/forms/input.rs +++ b/src/forms/input.rs @@ -115,7 +115,9 @@ impl RenderOnce for Input { } else { colors.fg }) - .on_mouse_down(MouseButton::Left, move |_, window, _| window.focus(&focus)) + .on_mouse_down(MouseButton::Left, move |_, window, cx| { + window.focus(&focus, cx) + }) .children(self.prefix) .child(div().flex_1().min_w_0().child(self.state)) .when(self.clearable && !empty && !disabled, |frame| { @@ -125,7 +127,7 @@ impl RenderOnce for Input { .tooltip("Clear") .on_click(move |_, window, cx| { state.update(cx, |input, cx| input.set_text("", cx)); - window.focus(&state.read(cx).focus().clone()); + window.focus(&state.read(cx).focus().clone(), cx); }), ) }) diff --git a/src/forms/options.rs b/src/forms/options.rs index cb33f6a..562aa65 100644 --- a/src/forms/options.rs +++ b/src/forms/options.rs @@ -1,7 +1,7 @@ use std::rc::Rc; use gpui::{ - Animation, AnimationExt, AnyElement, App, Bounds, Corner, Div, ElementId, Entity, + Anchor, Animation, AnimationExt, AnyElement, App, Bounds, Div, ElementId, Entity, InteractiveElement, IntoElement, MouseButton, ParentElement, Pixels, ScrollHandle, SharedString, Stateful, StatefulInteractiveElement, Styled, Window, anchored, canvas, div, prelude::*, @@ -216,7 +216,7 @@ pub(crate) fn float_height( let placed = if up { anchored() .position(anchor.origin) - .anchor(Corner::BottomLeft) + .anchor(Anchor::BottomLeft) .child( div() .child(content) diff --git a/src/forms/pairs.rs b/src/forms/pairs.rs index 9b73be9..fc2c892 100644 --- a/src/forms/pairs.rs +++ b/src/forms/pairs.rs @@ -184,7 +184,7 @@ fn render_rows(id: &ElementId, state: Entity, add: &'static str, cx: &App) grow.update(cx, |rows, cx| { rows.push(&[], window, cx); let last = rows.rows.last().expect("just pushed"); - window.focus(&last[0].0.read(cx).focus().clone()); + window.focus(&last[0].0.read(cx).focus().clone(), cx); rows.report(window, cx); cx.notify(); }) diff --git a/src/forms/picks.rs b/src/forms/picks.rs index 50b016b..2f3dc72 100644 --- a/src/forms/picks.rs +++ b/src/forms/picks.rs @@ -150,7 +150,7 @@ pub(crate) fn grid( .capture_action(move |_: &Down, window, cx| { if count > 0 { cx.stop_propagation(); - window.focus(&into); + window.focus(&into, cx); } }) .capture_action(move |_: &Enter, window, cx| { @@ -231,7 +231,7 @@ pub(crate) fn grid( }) .collect() }) - .track_scroll(scroll) + .track_scroll(&scroll) .h(theme.list_max_height()); div() .track_focus(&focus) diff --git a/src/forms/radio.rs b/src/forms/radio.rs index a3c2f43..c1535d6 100644 --- a/src/forms/radio.rs +++ b/src/forms/radio.rs @@ -256,7 +256,7 @@ impl RenderOnce for RadioGroup { }; cx.stop_propagation(); let next = step(&choices, at, by); - window.focus(&handles[next]); + window.focus(&handles[next], cx); pick(&choices[next].value, window, cx); }) .children(radios) diff --git a/src/forms/slider.rs b/src/forms/slider.rs index 7dc5770..796c0e1 100644 --- a/src/forms/slider.rs +++ b/src/forms/slider.rs @@ -238,7 +238,7 @@ impl Track { _ => 0, }; grab.update(cx, |grab, _| *grab = index); - window.focus(&focus[index]); + window.focus(&focus[index], cx); jump(index, next, window, cx); }) }); diff --git a/src/forms/tags.rs b/src/forms/tags.rs index d5800cf..8cc92bf 100644 --- a/src/forms/tags.rs +++ b/src/forms/tags.rs @@ -229,7 +229,9 @@ impl RenderOnce for TagInput { .bg(colors.surface) .text_size(theme.text_size(TextSize::Base)) .text_color(colors.fg) - .on_mouse_down(MouseButton::Left, move |_, window, _| window.focus(&focus)) + .on_mouse_down(MouseButton::Left, move |_, window, cx| { + window.focus(&focus, cx) + }) .capture_action(move |_: &Up, _, cx| { if open { cx.stop_propagation(); diff --git a/src/forms/tests/choices.rs b/src/forms/tests/choices.rs index c93e506..0c2a040 100644 --- a/src/forms/tests/choices.rs +++ b/src/forms/tests/choices.rs @@ -53,7 +53,7 @@ impl Render for Radios { fn radio_arrows_skip_disabled_choices_and_wrap(cx: &mut TestAppContext) { setup(cx); let (view, cx) = cx.add_window_view(|_, _| Radios { chosen: "a".into() }); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_keystrokes("down"); assert_eq!(view.read_with(cx, |view, _| view.chosen.clone()), "c"); cx.simulate_keystrokes("down"); @@ -84,7 +84,7 @@ impl Render for Picker { fn select_opens_moves_and_picks_from_the_keyboard(cx: &mut TestAppContext) { setup(cx); let (view, cx) = cx.add_window_view(|_, _| Picker { chosen: "a".into() }); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_keystrokes("down down enter"); assert_eq!(view.read_with(cx, |view, _| view.chosen.clone()), "b"); } @@ -213,7 +213,7 @@ impl Render for Level { fn slider_keys_step_jump_and_reach_the_end(cx: &mut TestAppContext) { setup(cx); let (view, cx) = cx.add_window_view(|_, _| Level { value: 10.0 }); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_keystrokes("right pageup"); assert_eq!(view.read_with(cx, |view, _| view.value), 21.0); cx.simulate_keystrokes("end"); @@ -242,7 +242,7 @@ impl Render for Agree { fn space_toggles_a_focused_checkbox(cx: &mut TestAppContext) { setup(cx); let (view, cx) = cx.add_window_view(|_, _| Agree { on: false }); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_keystrokes("space"); cx.simulate_event(KeyUpEvent { keystroke: Keystroke::parse("space").unwrap(), @@ -254,7 +254,7 @@ fn space_toggles_a_focused_checkbox(cx: &mut TestAppContext) { fn a_disabled_choice_still_leaves_the_group_reachable(cx: &mut TestAppContext) { setup(cx); let (view, cx) = cx.add_window_view(|_, _| Radios { chosen: "b".into() }); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_keystrokes("down"); assert_eq!(view.read_with(cx, |view, _| view.chosen.clone()), "c"); } @@ -281,7 +281,7 @@ impl Render for Several { fn a_full_enter_press_opens_a_multi_select_and_keeps_it_open(cx: &mut TestAppContext) { setup(cx); let (view, cx) = cx.add_window_view(|_, _| Several { chosen: Vec::new() }); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_keystrokes("enter"); release("enter", cx); cx.simulate_keystrokes("enter"); @@ -333,7 +333,7 @@ fn typed<'a>( #[gpui::test] fn enter_in_a_combobox_skips_a_disabled_first_row(cx: &mut TestAppContext) { let (view, cx) = typed(None, cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_keystrokes("enter"); assert_eq!( view.read_with(cx, |view, _| view.chosen.clone()), @@ -386,7 +386,7 @@ fn a_disabled_rating_ignores_the_arrows(cx: &mut TestAppContext) { value: 2, disabled: false, }); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); view.update(cx, |view, cx| { view.disabled = true; cx.notify(); @@ -440,7 +440,7 @@ fn a_shut_select_may_be_empty(cx: &mut TestAppContext) { setup(cx); let (_, cx) = cx.add_window_view(|_, _| Empty(true)); cx.run_until_parked(); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); assert!(cx.update(|window, cx| window.focused(cx).is_none())); } @@ -469,7 +469,7 @@ fn a_long_choice_keeps_its_list_inside_the_window(cx: &mut TestAppContext) { let (_, cx) = cx.add_window_view(|_, _| Named); cx.simulate_resize(gpui::size(px(280.0), px(600.0))); cx.run_until_parked(); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_keystrokes("enter"); release("enter", cx); cx.run_until_parked(); diff --git a/src/forms/tests/dates.rs b/src/forms/tests/dates.rs index 4cd01f6..c69d715 100644 --- a/src/forms/tests/dates.rs +++ b/src/forms/tests/dates.rs @@ -1,6 +1,8 @@ +use std::rc::Rc; + use gpui::{ - Context, IntoElement, KeyUpEvent, Keystroke, ParentElement, Render, Styled, TestAppContext, - Window, div, + Context, IntoElement, KeyUpEvent, Keystroke, Modifiers, ParentElement, Render, Styled, + TestAppContext, Window, div, point, px, }; use jiff::civil::{Date, Time, date, time}; @@ -38,7 +40,7 @@ fn a_date_picker_opens_and_picks_from_the_keyboard(cx: &mut TestAppContext) { value: Some(date(2026, 9, 10)), disabled: false, }); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_keystrokes("enter right enter"); assert_eq!( view.read_with(cx, |view, _| view.value), @@ -70,7 +72,7 @@ impl Render for Span { fn a_range_picker_takes_two_picks_in_either_order(cx: &mut TestAppContext) { setup(cx); let (view, cx) = cx.add_window_view(|_, _| Span { value: None }); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_keystrokes("enter enter left left enter"); assert_eq!( view.read_with(cx, |view, _| view.value), @@ -106,7 +108,7 @@ fn a_time_picker_steps_with_the_arrows(cx: &mut TestAppContext) { let (view, cx) = cx.add_window_view(|_, _| Clock { value: Some(time(9, 30, 0, 0)), }); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_keystrokes("enter down down"); assert_eq!( view.read_with(cx, |view, _| view.value), @@ -143,7 +145,7 @@ fn a_calendar_refuses_days_past_its_max(cx: &mut TestAppContext) { picked: None, max: Some(TODAY), }); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_keystrokes("right enter"); assert_eq!(view.read_with(cx, |view, _| view.picked), None); cx.simulate_keystrokes("left enter"); @@ -157,7 +159,7 @@ fn a_picker_disabled_while_open_stops_picking(cx: &mut TestAppContext) { value: Some(date(2026, 9, 10)), disabled: false, }); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_keystrokes("enter"); view.update(cx, |view, cx| { view.disabled = true; @@ -177,18 +179,18 @@ fn the_month_buttons_carry_the_cursor(cx: &mut TestAppContext) { picked: None, max: None, }); - cx.update(|window, _| { - window.focus_next(); - window.focus_next(); - window.focus_next(); + cx.update(|window, cx| { + window.focus_next(cx); + window.focus_next(cx); + window.focus_next(cx); }); cx.simulate_keystrokes("enter"); cx.simulate_event(KeyUpEvent { keystroke: Keystroke::parse("enter").unwrap(), }); - cx.update(|window, _| { - window.focus_prev(); - window.focus_prev(); + cx.update(|window, cx| { + window.focus_prev(cx); + window.focus_prev(cx); }); cx.simulate_keystrokes("enter"); assert_eq!( @@ -196,3 +198,41 @@ fn the_month_buttons_carry_the_cursor(cx: &mut TestAppContext) { Some(date(2026, 10, 25)) ); } + +/// A calendar that records every preview it reports. +struct Watched { + seen: Vec>, +} + +impl Render for Watched { + fn render(&mut self, _: &mut Window, cx: &mut Context) -> impl IntoElement { + let view = cx.entity(); + Calendar::new("watched") + .selected(TODAY) + .today(TODAY) + .on_hover(Rc::new(move |date, _, cx| { + view.update(cx, |view, cx| { + view.seen.push(date); + cx.notify(); + }) + })) + } +} + +#[gpui::test] +fn keys_keep_the_preview_under_a_resting_pointer(cx: &mut TestAppContext) { + setup(cx); + let (view, cx) = cx.add_window_view(|_, _| Watched { seen: Vec::new() }); + cx.update(|window, cx| window.focus_next(cx)); + cx.simulate_mouse_move(point(px(120.0), px(200.0)), None, Modifiers::none()); + let pointed = view.read_with(cx, |view, _| view.seen.last().copied().flatten()); + assert!(pointed.is_some(), "the pointer rests on a day"); + cx.simulate_keystrokes("pagedown"); + cx.update(|window, _| window.refresh()); + cx.run_until_parked(); + assert_eq!( + view.read_with(cx, |view, _| view.seen.last().copied().flatten()), + Some(date(2026, 10, 25)), + "the keyboard's day stays the preview" + ); +} diff --git a/src/forms/tests/mod.rs b/src/forms/tests/mod.rs index d91ccef..279c09b 100644 --- a/src/forms/tests/mod.rs +++ b/src/forms/tests/mod.rs @@ -69,7 +69,7 @@ fn text(field: &Entity, cx: &mut VisualTestContext) -> String { } fn focus(field: &Entity, cx: &mut VisualTestContext) { - cx.update(|window, cx| window.focus(&field.read(cx).focus().clone())); + cx.update(|window, cx| window.focus(&field.read(cx).focus().clone(), cx)); } #[gpui::test] @@ -80,7 +80,7 @@ fn tab_reaches_fields_and_skips_disabled_ones(cx: &mut TestAppContext) { let mut order = Vec::new(); for _ in 0..2 { order.push(cx.update(|window, cx| { - window.focus_next(); + window.focus_next(cx); fields .iter() .position(|field| field.read(cx).focus().is_focused(window)) @@ -96,9 +96,9 @@ fn enter_on_a_clear_button_clears_its_own_field(cx: &mut TestAppContext) { field.update(cx, |input, cx| input.set_text("kept", cx)); } cx.run_until_parked(); - cx.update(|window, _| { - window.focus_next(); - window.focus_next(); + cx.update(|window, cx| { + window.focus_next(cx); + window.focus_next(cx); }); cx.run_until_parked(); cx.simulate_keystrokes("enter"); @@ -177,7 +177,7 @@ impl Render for Stepped { fn stepping_starts_from_the_typed_number(cx: &mut TestAppContext) { setup(cx); let (view, cx) = cx.add_window_view(|_, _| Stepped { value: 4.0 }); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_keystrokes("cmd-a"); cx.simulate_input("20"); cx.simulate_keystrokes("up"); @@ -188,7 +188,7 @@ fn stepping_starts_from_the_typed_number(cx: &mut TestAppContext) { fn a_typed_number_reaches_the_owner_before_any_blur(cx: &mut TestAppContext) { setup(cx); let (view, cx) = cx.add_window_view(|_, _| Stepped { value: 100.0 }); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_keystrokes("cmd-a"); cx.simulate_input("250"); assert_eq!( @@ -224,7 +224,7 @@ fn select_all_then_typing_replaces_the_pin(cx: &mut TestAppContext) { let (view, cx) = cx.add_window_view(|_, _| Pin { code: String::new(), }); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_input("4821"); cx.simulate_keystrokes("cmd-a"); cx.simulate_input("1234"); diff --git a/src/forms/tests/other.rs b/src/forms/tests/other.rs index 88987ee..9cb668a 100644 --- a/src/forms/tests/other.rs +++ b/src/forms/tests/other.rs @@ -29,7 +29,7 @@ impl Render for Icons { fn an_icon_is_searched_walked_and_picked_from_the_keyboard(cx: &mut TestAppContext) { setup(cx); let (view, cx) = cx.add_window_view(|_, _| Icons { picked: None }); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_input("arrow down"); cx.simulate_keystrokes("down right enter"); let wanted: Vec = IconName::ALL @@ -135,7 +135,7 @@ fn an_inline_edit_takes_tab_opens_on_enter_and_takes_focus_back(cx: &mut TestApp cx.update(|cx| cx.bind_keys([KeyBinding::new("tab", FocusNext, None)])); let (view, cx) = cx.add_window_view(|_, _| Titled(Vec::new())); cx.update(|window, _| window.activate_window()); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); release("enter", cx); cx.simulate_input("Stairs"); release("enter", cx); diff --git a/src/forms/tests/structure.rs b/src/forms/tests/structure.rs index 18722ba..82ef81e 100644 --- a/src/forms/tests/structure.rs +++ b/src/forms/tests/structure.rs @@ -59,7 +59,7 @@ fn signup(cx: &mut TestAppContext) -> (Entity, &mut VisualTestContext) { #[gpui::test] fn cmd_enter_in_a_field_submits_the_form_once(cx: &mut TestAppContext) { let (view, cx) = signup(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_input("Ada"); cx.simulate_keystrokes("cmd-enter"); let counts = view.read_with(cx, |view, _| (view.sent, view.field_submits)); @@ -69,9 +69,9 @@ fn cmd_enter_in_a_field_submits_the_form_once(cx: &mut TestAppContext) { #[gpui::test] fn cmd_enter_on_any_control_in_a_form_submits_it(cx: &mut TestAppContext) { let (view, cx) = signup(cx); - cx.update(|window, _| { - window.focus_next(); - window.focus_next(); + cx.update(|window, cx| { + window.focus_next(cx); + window.focus_next(cx); }); cx.simulate_keystrokes("cmd-enter"); assert_eq!( @@ -120,16 +120,16 @@ fn field_array_buttons_remove_their_own_row_and_add_one(cx: &mut TestAppContext) let (view, cx) = cx.add_window_view(|_, _| Rows { rows: vec!["a", "b", "c"], }); - cx.update(|window, _| { - window.focus_next(); - window.focus_next(); + cx.update(|window, cx| { + window.focus_next(cx); + window.focus_next(cx); }); press("space", cx); assert_eq!(view.read_with(cx, |view, _| view.rows.clone()), ["a", "c"]); - cx.update(|window, _| { - window.blur(); + cx.update(|window, cx| { + window.blur(cx); for _ in 0..3 { - window.focus_next(); + window.focus_next(cx); } }); press("space", cx); diff --git a/src/forms/tests/tags.rs b/src/forms/tests/tags.rs index 128d135..4b30caa 100644 --- a/src/forms/tests/tags.rs +++ b/src/forms/tests/tags.rs @@ -56,9 +56,9 @@ fn typing<'a>( tags: Vec::new(), asked: Vec::new(), }); - cx.update(|window, _| { + cx.update(|window, cx| { window.activate_window(); - window.focus_next(); + window.focus_next(cx); }); settle(cx); cx.simulate_input(words); diff --git a/src/forms/tests/upload.rs b/src/forms/tests/upload.rs index 1859a8f..8ffb80d 100644 --- a/src/forms/tests/upload.rs +++ b/src/forms/tests/upload.rs @@ -54,11 +54,11 @@ fn each_row_offers_what_its_state_allows(cx: &mut TestAppContext) { setup(cx); cx.update(|cx| cx.bind_keys([KeyBinding::new("tab", FocusNext, None)])); let (view, cx) = cx.add_window_view(|_, _| Shelf { log: Vec::new() }); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); press("enter", cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); press("enter", cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); press("enter", cx); let log = view.read_with(cx, |shelf, _| shelf.log.clone()); assert_eq!(log, ["cancel 0", "retry 1", "remove 2"]); diff --git a/src/forms/text/actions.rs b/src/forms/text/actions.rs index 3ed9dc4..b183369 100644 --- a/src/forms/text/actions.rs +++ b/src/forms/text/actions.rs @@ -318,7 +318,7 @@ impl TextInput { if self.disabled { return; } - window.focus(&self.focus); + window.focus(&self.focus, cx); let at = self.offset_for_point(event.position); match event.click_count { 2 => { diff --git a/src/forms/text/element.rs b/src/forms/text/element.rs index c438119..32287e7 100644 --- a/src/forms/text/element.rs +++ b/src/forms/text/element.rs @@ -1,3 +1,5 @@ +use std::rc::Rc; + use gpui::{ App, AvailableSpace, Bounds, ContentMask, DispatchPhase, Element, ElementId, ElementInputHandler, Entity, FontStyle, GlobalElementId, Hsla, InspectorElementId, IntoElement, @@ -27,7 +29,7 @@ impl IntoElement for TextElement { } pub(crate) struct Prepaint { - lines: Vec<(usize, WrappedLine)>, + lines: Rc<[(usize, WrappedLine)]>, selections: Vec>, caret: Option>, selection_color: Hsla, @@ -219,7 +221,8 @@ impl Element for TextElement { .text_system() .shape_text(text.clone().into(), font_size, &runs, wrap, None) .expect("text input shaping failed"); - let lines: Vec<(usize, WrappedLine)> = line_starts(&text).into_iter().zip(shaped).collect(); + let lines: Rc<[(usize, WrappedLine)]> = + line_starts(&text).into_iter().zip(shaped).collect(); let focused = input.focus().is_focused(window); let caret_on = input.caret_on(); self.input.update(cx, |input, _| { @@ -285,7 +288,7 @@ impl Element for TextElement { window.with_content_mask(Some(ContentMask { bounds }), |window| { let mut origins = Vec::with_capacity(prepaint.lines.len()); let mut top = Pixels::ZERO; - for (_, line) in &prepaint.lines { + for (_, line) in prepaint.lines.iter() { origins.push(bounds.origin - scroll + point(Pixels::ZERO, top)); top += line.size(line_height).height; } diff --git a/src/forms/text/geometry.rs b/src/forms/text/geometry.rs index da3e24e..afaf244 100644 --- a/src/forms/text/geometry.rs +++ b/src/forms/text/geometry.rs @@ -59,7 +59,7 @@ impl TextInput { return Some(Point::default()); } let mut top = Pixels::ZERO; - for (start, line) in &layout.lines { + for (start, line) in layout.lines.iter() { if display <= start + line.len() { let at = line.position_for_index(display - start, layout.line_height)?; return Some(gpui::point(at.x, at.y + top)); @@ -82,7 +82,7 @@ impl TextInput { return 0; } let mut top = Pixels::ZERO; - for (start, line) in &layout.lines { + for (start, line) in layout.lines.iter() { let height = line.size(layout.line_height).height; if local.y < top + height { let inside = gpui::point(local.x.max(Pixels::ZERO), local.y - top); diff --git a/src/forms/text/mod.rs b/src/forms/text/mod.rs index 69004d1..163c0e2 100644 --- a/src/forms/text/mod.rs +++ b/src/forms/text/mod.rs @@ -36,7 +36,7 @@ pub(crate) type Fit = Rc, &str) -> (String, usize)>; /// The last shaped text: one entry per hard line, with its display offset. pub(crate) struct Layout { - pub lines: Vec<(usize, WrappedLine)>, + pub lines: Rc<[(usize, WrappedLine)]>, pub bounds: Bounds, pub line_height: Pixels, /// The lines show the placeholder, not content. diff --git a/src/generative/embed.rs b/src/generative/embed.rs index 7fe921b..585752e 100644 --- a/src/generative/embed.rs +++ b/src/generative/embed.rs @@ -1,10 +1,10 @@ use std::{collections::HashSet, rc::Rc}; use gpui::{ - App, Bounds, DragMoveEvent, ElementId, EmptyView, EntityId, InteractiveElement, IntoElement, - MouseButton, ParentElement, Pixels, Point, RenderOnce, SharedString, - StatefulInteractiveElement, Styled, Window, canvas, div, fill, point, prelude::*, size, - transparent_black, + App, Bounds, DragMoveEvent, ElementId, EmptyView, EntityId, HoverListenerMode, + InteractiveElement, IntoElement, MouseButton, ParentElement, Pixels, Point, RenderOnce, + SharedString, StatefulInteractiveElement, Styled, Window, canvas, div, fill, point, prelude::*, + size, transparent_black, }; use super::lens::{DRAG, Lens, START, STEP, radius, turned}; @@ -285,6 +285,7 @@ impl RenderOnce for EmbeddingVisualizer { }) }) }) + .hover_listener_mode(HoverListenerMode::InputModalityIndependent) .on_hover(move |inside, _, cx| { if !inside { left.update(cx, |view, cx| { diff --git a/src/generative/mask.rs b/src/generative/mask.rs index 081d128..59408f9 100644 --- a/src/generative/mask.rs +++ b/src/generative/mask.rs @@ -1,9 +1,9 @@ use std::rc::Rc; use gpui::{ - App, Bounds, ElementId, Entity, InteractiveElement, IntoElement, ParentElement, Pixels, Point, - RenderOnce, SharedString, StatefulInteractiveElement, Styled, Window, canvas, div, fill, point, - prelude::*, size, transparent_black, + App, Bounds, ElementId, Entity, HoverListenerMode, InteractiveElement, IntoElement, + ParentElement, Pixels, Point, RenderOnce, SharedString, StatefulInteractiveElement, Styled, + Window, canvas, div, fill, point, prelude::*, size, transparent_black, }; use crate::{ @@ -336,6 +336,7 @@ impl RenderOnce for InpaintCanvas { cx.notify(); }) }) + .hover_listener_mode(HoverListenerMode::InputModalityIndependent) .on_hover(move |hovered, _, cx| { if !hovered { leave.update(cx, |pointer, cx| { diff --git a/src/generative/prompt.rs b/src/generative/prompt.rs index f652ec1..acdbee4 100644 --- a/src/generative/prompt.rs +++ b/src/generative/prompt.rs @@ -134,7 +134,7 @@ impl RenderOnce for PromptEnhancer { "prompt enhancer: suggestion {}", if taken { "taken" } else { "kept out" } ); - window.focus(&field.focus_handle(cx)); + window.focus(&field.focus_handle(cx), cx); if let Some(resolve) = &resolve { resolve(taken, window, cx); } diff --git a/src/generative/tests/canvas.rs b/src/generative/tests/canvas.rs index e86028c..0d1b849 100644 --- a/src/generative/tests/canvas.rs +++ b/src/generative/tests/canvas.rs @@ -125,7 +125,7 @@ fn undo_waits_for_a_stroke(cx: &mut TestAppContext) { cx.notify(); }); settle(cx); - cx.update(|window, _| window.blur()); + cx.update(|window, cx| window.blur(cx)); tab(4, cx); press("enter", cx); assert_eq!( diff --git a/src/generative/tests/data.rs b/src/generative/tests/data.rs index e707fda..7610eb4 100644 --- a/src/generative/tests/data.rs +++ b/src/generative/tests/data.rs @@ -192,7 +192,7 @@ fn run_waits_for_every_value_then_sends_the_filled_prompt(cx: &mut TestAppContex press("enter", cx); let ran = |cx: &mut VisualTestContext| view.read_with(cx, |view, _| view.ran.clone()); assert!(ran(cx).is_empty(), "with tone blank, Run is out of reach"); - cx.update(|window, _| window.blur()); + cx.update(|window, cx| window.blur(cx)); tab(3, cx); cx.simulate_input("calm"); settle(cx); @@ -259,7 +259,7 @@ fn a_version_is_chosen_by_keys_and_only_an_older_one_restores(cx: &mut TestAppCo tab(4, cx); press("enter", cx); assert_eq!(heard(cx), (vec![], vec![]), "the newest offers no Restore"); - cx.update(|window, _| window.blur()); + cx.update(|window, cx| window.blur(cx)); tab(2, cx); press("enter", cx); tab(2, cx); diff --git a/src/generative/tests/mod.rs b/src/generative/tests/mod.rs index 8bba9c6..df7319d 100644 --- a/src/generative/tests/mod.rs +++ b/src/generative/tests/mod.rs @@ -27,7 +27,7 @@ fn press(key: &str, cx: &mut VisualTestContext) { fn tab(times: usize, cx: &mut VisualTestContext) { for _ in 0..times { - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); } } diff --git a/src/git/tests.rs b/src/git/tests.rs index 0305259..5484c8d 100644 --- a/src/git/tests.rs +++ b/src/git/tests.rs @@ -40,7 +40,7 @@ fn a_fold_opens_from_the_keyboard(cx: &mut TestAppContext) { let (view, cx) = cx.add_window_view(|_, _| Folded { opened: Vec::new() }); cx.update(|window, _| window.activate_window()); settle(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); settle(cx); cx.simulate_keystrokes("enter"); settle(cx); diff --git a/src/i18n/skip.rs b/src/i18n/skip.rs index d68a0c3..4fd386c 100644 --- a/src/i18n/skip.rs +++ b/src/i18n/skip.rs @@ -36,9 +36,9 @@ impl RenderOnce for SkipLink { let shown = handle.is_focused(window); let theme = cx.theme(); let (target, label) = (self.target, self.label.clone()); - let skip = move |window: &mut Window| { + let skip = move |window: &mut Window, cx: &mut App| { log::info!("skip link {label:?}: focus to its target"); - window.focus(&target); + window.focus(&target, cx); }; let press = skip.clone(); let pill = div() @@ -55,11 +55,11 @@ impl RenderOnce for SkipLink { .text_color(theme.colors.fg) .cursor_pointer() .child(self.label) - .on_click(move |_, window, _| press(window)); + .on_click(move |_, window, cx| press(window, cx)); div() .id(self.id.clone()) .track_focus(&handle) - .on_click(move |_, window, _| skip(window)) + .on_click(move |_, window, cx| skip(window, cx)) .when(shown, |link| { link.child(raise( self.id.clone(), diff --git a/src/i18n/tests/a11y.rs b/src/i18n/tests/a11y.rs index f3735ee..66f8e10 100644 --- a/src/i18n/tests/a11y.rs +++ b/src/i18n/tests/a11y.rs @@ -209,7 +209,7 @@ fn focused( fn a_skip_link_leads_past_the_nav(cx: &mut TestAppContext) { let (view, cx) = page(cx); let root = view.read_with(cx, |page, _| page.root.clone()); - cx.update(|window, _| window.focus(&root)); + cx.update(|window, cx| window.focus(&root, cx)); press("tab", cx); assert!( !focused(&view, |page| &page.nav[0], cx), @@ -237,7 +237,7 @@ fn a_skip_link_shows_only_while_focused(cx: &mut TestAppContext) { "at rest the nav takes it" ); let root = view.read_with(cx, |page, _| page.root.clone()); - cx.update(|window, _| window.focus(&root)); + cx.update(|window, cx| window.focus(&root, cx)); press("tab", cx); cx.simulate_click(spot, Modifiers::none()); cx.run_until_parked(); diff --git a/src/i18n/tests/mod.rs b/src/i18n/tests/mod.rs index 34cb5b1..7cbf938 100644 --- a/src/i18n/tests/mod.rs +++ b/src/i18n/tests/mod.rs @@ -206,14 +206,7 @@ mod shown { #[test] fn text_sits_against_the_reading_side() { - let side = |direction: Direction| { - direction - .align(div()) - .style() - .text - .as_ref() - .and_then(|text| text.text_align) - }; + let side = |direction: Direction| direction.align(div()).style().text.text_align; assert_eq!(side(Direction::Ltr), Some(gpui::TextAlign::Left)); assert_eq!(side(Direction::Rtl), Some(gpui::TextAlign::Right)); } diff --git a/src/interaction/roving.rs b/src/interaction/roving.rs index e87a377..dd610db 100644 --- a/src/interaction/roving.rs +++ b/src/interaction/roving.rs @@ -137,7 +137,7 @@ impl RenderOnce for RovingFocus { *stop = to; cx.notify(); }); - window.focus(&handles[to]); + window.focus(&handles[to], cx); }) .children(items) } diff --git a/src/interaction/selection.rs b/src/interaction/selection.rs index 705911f..59d5f8e 100644 --- a/src/interaction/selection.rs +++ b/src/interaction/selection.rs @@ -172,7 +172,7 @@ impl RenderOnce for SelectionArea { }) .on_mouse_down(MouseButton::Left, move |event, window, cx| { cx.stop_propagation(); - window.focus(&keys_to); + window.focus(&keys_to, cx); at.update(cx, |area, _| area.cursor = ix); let adding = event.modifiers.platform || event.modifiers.shift; press(&pressed(&now, &held, adding), window, cx) diff --git a/src/interaction/tests.rs b/src/interaction/tests.rs index f8a038f..06cc50e 100644 --- a/src/interaction/tests.rs +++ b/src/interaction/tests.rs @@ -49,9 +49,9 @@ fn settle(cx: &mut VisualTestContext) { } fn tab(stops: usize, cx: &mut VisualTestContext) { - cx.update(|window, _| { - window.blur(); - (0..stops).for_each(|_| window.focus_next()); + cx.update(|window, cx| { + window.blur(cx); + (0..stops).for_each(|_| window.focus_next(cx)); }); settle(cx); } @@ -234,14 +234,17 @@ fn picked(host: &Entity, cx: &mut VisualTestContext) -> Vec { #[gpui::test] fn a_band_selects_what_it_crosses(cx: &mut TestAppContext) { let (host, cx) = bench(area, cx); - drag( - at(100.0, 100.0), - &[at(110.0, 95.0), at(150.0, 70.0), at(160.0, 60.0)], - Modifiers::none(), - cx, - ); - assert_eq!(picked(&host, cx), ["b", "c"]); + let none = Modifiers::none(); + cx.simulate_mouse_down(at(100.0, 100.0), MouseButton::Left, none); + for step in [at(110.0, 95.0), at(150.0, 70.0), at(160.0, 60.0)] { + cx.simulate_mouse_move(step, Some(MouseButton::Left), none); + settle(cx); + } + // gpui now clears debug bounds each frame, and the band leaves on release. assert!(cx.debug_bounds("selection-band").is_some()); + cx.simulate_mouse_up(at(160.0, 60.0), MouseButton::Left, none); + settle(cx); + assert_eq!(picked(&host, cx), ["b", "c"]); } /// A press selects a tile alone, Command adds another, a press on empty space clears, and with focus Command-A takes all and Escape clears. diff --git a/src/layout/scroll.rs b/src/layout/scroll.rs index c49d1dc..66f830c 100644 --- a/src/layout/scroll.rs +++ b/src/layout/scroll.rs @@ -6,9 +6,9 @@ use std::{ use gpui::{ AnyElement, App, Axis, Bounds, Canvas, Div, ElementId, EmptyView, Entity, EntityId, - FocusHandle, InteractiveElement, IntoElement, ParentElement, Pixels, Point, RenderOnce, - ScrollHandle, StatefulInteractiveElement, StyleRefinement, Styled, Window, canvas, div, point, - prelude::*, + FocusHandle, HoverListenerMode, InteractiveElement, IntoElement, ParentElement, Pixels, Point, + RenderOnce, ScrollHandle, StatefulInteractiveElement, StyleRefinement, Styled, Window, canvas, + div, point, prelude::*, }; use smallvec::SmallVec; @@ -145,8 +145,8 @@ impl RenderOnce for Scrollbar { self.handle.offset(), ); let (span, reach, scrolled) = match self.axis { - Axis::Vertical => (view.height, max.height, -offset.y), - Axis::Horizontal => (view.width, max.width, -offset.x), + Axis::Vertical => (view.height, max.y, -offset.y), + Axis::Horizontal => (view.width, max.x, -offset.x), }; let length = (span * (span / (span + reach))).max(min_thumb).min(span); let travel = span - length; @@ -292,6 +292,7 @@ impl RenderOnce for ScrollArea { .id(self.id) .relative() .overflow_hidden() + .hover_listener_mode(HoverListenerMode::InputModalityIndependent) .on_hover(move |hovered, _, cx| { state.update(cx, |activity, cx| { activity.hovered = *hovered; diff --git a/src/layout/scroll_aids.rs b/src/layout/scroll_aids.rs index e1c782d..be65f0a 100644 --- a/src/layout/scroll_aids.rs +++ b/src/layout/scroll_aids.rs @@ -34,7 +34,7 @@ impl ScrollShadow { impl RenderOnce for ScrollShadow { fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement { let scrolled = -self.handle.offset().y; - let reach = self.handle.max_offset().height; + let reach = self.handle.max_offset().y; let shade = cx.theme().elevation(Elevation::Floating); let edge = || { div() diff --git a/src/lists/select.rs b/src/lists/select.rs index 6e4e373..3257d05 100644 --- a/src/lists/select.rs +++ b/src/lists/select.rs @@ -259,7 +259,7 @@ impl RenderOnce for SelectableList { (false, true) => Pick::Toggle, _ => Pick::One, }; - window.focus(&focus); + window.focus(&focus, cx); pick(ix, how, window, cx); if event.click_count() == 2 { activate(&key, window, cx); diff --git a/src/lists/tests/keys.rs b/src/lists/tests/keys.rs index 0ea63ac..73cf935 100644 --- a/src/lists/tests/keys.rs +++ b/src/lists/tests/keys.rs @@ -26,7 +26,7 @@ impl Render for Handoff { SelectableList::new("handoff") .row("a", ListItem::new("handoff-a", "A")) .on_activate(move |_, window, cx| { - window.focus(&to); + window.focus(&to, cx); opened.update(cx, |view, _| view.heard.push("open")); }), ) @@ -49,7 +49,7 @@ fn an_open_that_moves_focus_leaves_the_release_alone(cx: &mut TestAppContext) { heard: Vec::new(), }); settle(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); settle(cx); enter(cx); settle(cx); @@ -66,7 +66,7 @@ impl Render for Relay { fn render(&mut self, _: &mut Window, cx: &mut Context) -> impl IntoElement { let opened = cx.entity(); div() - .capture_action(|_: &Enter, window, _| window.focus_next()) + .capture_action(|_: &Enter, window, cx| window.focus_next(cx)) .child(Input::new(&self.field)) .child( SelectableList::new("relay") @@ -88,7 +88,7 @@ fn a_release_that_began_elsewhere_opens_nothing(cx: &mut TestAppContext) { heard: Vec::new(), }); settle(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); settle(cx); enter(cx); settle(cx); @@ -131,6 +131,7 @@ fn a_letter_with_command_stays_a_shortcut(cx: &mut TestAppContext) { key_char: Some("a".into()), }, is_held: false, + prefer_character_input: false, }); settle(cx); assert_eq!(picks(&view, cx), ["a", "b", "c", "d"]); diff --git a/src/lists/tests/mod.rs b/src/lists/tests/mod.rs index 8e0f299..7022331 100644 --- a/src/lists/tests/mod.rs +++ b/src/lists/tests/mod.rs @@ -124,7 +124,7 @@ fn the_cursor_starts_on_the_first_selected_row(cx: &mut TestAppContext) { setup(cx); let (view, cx) = cx.add_window_view(|_, _| Picks(vec!["c".into()], Vec::new(), None, false)); settle(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_keystrokes("down"); settle(cx); assert_eq!(picks(&view, cx), ["d"]); @@ -137,7 +137,7 @@ fn a_selection_from_the_owner_moves_the_cursor_and_an_echo_does_not(cx: &mut Tes settle(cx); view.update(cx, |picks, _| picks.0 = vec!["b".into()]); settle(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_keystrokes("shift-down shift-down"); settle(cx); assert_eq!( diff --git a/src/lists/tree/mod.rs b/src/lists/tree/mod.rs index 6519a3a..2bb7bfd 100644 --- a/src/lists/tree/mod.rs +++ b/src/lists/tree/mod.rs @@ -180,7 +180,7 @@ impl RenderOnce for Tree { } if nav.read(cx).renaming.is_some() && editing.read(cx).field().is_none() { nav.update(cx, |nav, _| nav.renaming = None); - window.focus(&focus); + window.focus(&focus, cx); } let open: HashSet = opened.read(cx).value.iter().cloned().collect(); let nodes = Rc::new(self.nodes); @@ -320,7 +320,7 @@ impl RenderOnce for Tree { let list = uniform_list((id.clone(), "rows"), count, move |range, window, cx| { draw(&data, range, window, cx) }) - .track_scroll(scroll) + .track_scroll(&scroll) .size_full(); self.base .id(self.id) diff --git a/src/lists/tree/row.rs b/src/lists/tree/row.rs index 59f5ba8..9e4f1ac 100644 --- a/src/lists/tree/row.rs +++ b/src/lists/tree/row.rs @@ -219,7 +219,7 @@ fn row(rows: &Rows, ix: usize, window: &mut Window, cx: &mut App) -> AnyElement })) .children(landing.filter(|at| *at != DropAt::Inside).map(line)) .on_click(move |event, window, cx| { - window.focus(&focus); + window.focus(&focus, cx); if event.click_count() == 2 { activate(ix, window, cx); return; diff --git a/src/mail/tests/mod.rs b/src/mail/tests/mod.rs index 2ce030b..674ef17 100644 --- a/src/mail/tests/mod.rs +++ b/src/mail/tests/mod.rs @@ -41,10 +41,10 @@ fn press(key: &str, cx: &mut VisualTestContext) { /// Moves focus to the `nth` Tab stop from none. fn tab_to(nth: usize, cx: &mut VisualTestContext) { - cx.update(|window, _| { - window.blur(); + cx.update(|window, cx| { + window.blur(cx); for _ in 0..nth { - window.focus_next(); + window.focus_next(cx); } }); settle(cx); diff --git a/src/mail/tests/read.rs b/src/mail/tests/read.rs index ce17d55..f74cf4e 100644 --- a/src/mail/tests/read.rs +++ b/src/mail/tests/read.rs @@ -160,7 +160,7 @@ fn space_on_a_fold_keeps_focus_on_the_message(cx: &mut TestAppContext) { let (host, cx) = mailing(answered, cx); tab_to(2, cx); press("space", cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); settle(cx); press("space", cx); assert_eq!( diff --git a/src/mail/tests/write.rs b/src/mail/tests/write.rs index 9c432b4..49963a9 100644 --- a/src/mail/tests/write.rs +++ b/src/mail/tests/write.rs @@ -46,7 +46,7 @@ fn writing( } fn next(cx: &mut VisualTestContext) { - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); settle(cx); } diff --git a/src/maps/tests/mod.rs b/src/maps/tests/mod.rs index 1f5e1ec..ef2aa9a 100644 --- a/src/maps/tests/mod.rs +++ b/src/maps/tests/mod.rs @@ -31,6 +31,7 @@ struct Stage { others: Vec, said: Vec, tiles: Rc>>, + picture: ImageSource, open: bool, } @@ -69,6 +70,7 @@ fn stage( others: Vec::new(), said: Vec::new(), tiles: Rc::default(), + picture: picture(), open: false, }); settle(cx); @@ -100,6 +102,7 @@ fn said(host: &Entity, cx: &mut VisualTestContext) -> Vec { host.read_with(cx, |stage, _| stage.said.clone()) } +/// One picture per stage: a new one each render would load and redraw without end. fn picture() -> ImageSource { let frame = image::Frame::new(image::RgbaImage::new(1, 1)); ImageSource::Render(Arc::new(RenderImage::new(vec![frame]))) @@ -107,11 +110,12 @@ fn picture() -> ImageSource { fn map(stage: &Stage, owner: Entity) -> AnyElement { let tiles = stage.tiles.clone(); + let picture = stage.picture.clone(); let heard = owner.clone(); MapView::new("map", start()) .tiles(move |tile| { tiles.borrow_mut().insert(tile); - picture() + picture.clone() }) .markers([MapMarker::new("middle", LatLon::new(0.0, 0.0)).label("Null Island")]) .on_marker(move |key, _, cx| say(&heard, key, cx)) @@ -268,10 +272,11 @@ fn pins_without_a_handler_take_no_tab(cx: &mut TestAppContext) { fn tiled(stage: &Stage, _: Entity) -> AnyElement { let tiles = stage.tiles.clone(); + let picture = stage.picture.clone(); MapView::new("map", MapViewport::new(LatLon::new(0.0, 0.0), 1.0)) .tiles(move |tile| { tiles.borrow_mut().insert(tile); - picture() + picture.clone() }) .into_any_element() } @@ -291,11 +296,12 @@ fn the_host_supplies_each_tile_the_view_covers(cx: &mut TestAppContext) { fn capped(stage: &Stage, _: Entity) -> AnyElement { let tiles = stage.tiles.clone(); + let picture = stage.picture.clone(); MapView::new("map", MapViewport::new(LatLon::new(0.0, 0.0), 1.0)) .tile_zooms(0, 0) .tiles(move |tile| { tiles.borrow_mut().insert(tile); - picture() + picture.clone() }) .into_any_element() } diff --git a/src/maps/view.rs b/src/maps/view.rs index f179b8f..47147fb 100644 --- a/src/maps/view.rs +++ b/src/maps/view.rs @@ -183,7 +183,7 @@ impl RenderOnce for MapView { .any(|pin| pin.is_focused(window)); if zoomed && held { log::info!("map: a zoom regroups the pins; focus goes to the map"); - window.focus(&map); + window.focus(&map, cx); } local.update(cx, |local, cx| { local.value = next; diff --git a/src/media/audio.rs b/src/media/audio.rs index 6359638..fabfef1 100644 --- a/src/media/audio.rs +++ b/src/media/audio.rs @@ -1,9 +1,10 @@ use std::{rc::Rc, time::Duration}; use gpui::{ - App, Bounds, Corners, DragMoveEvent, ElementId, EmptyView, EntityId, InteractiveElement, - IntoElement, MouseButton, ParentElement, Pixels, Point, RenderOnce, StatefulInteractiveElement, - Styled, Window, canvas, div, fill, point, prelude::*, relative, size, transparent_black, + App, Bounds, Corners, DragMoveEvent, ElementId, EmptyView, EntityId, HoverListenerMode, + InteractiveElement, IntoElement, MouseButton, ParentElement, Pixels, Point, RenderOnce, + StatefulInteractiveElement, Styled, Window, canvas, div, fill, point, prelude::*, relative, + size, transparent_black, }; use super::scrubber::{OnTime, clock, time_at, time_tip}; @@ -157,6 +158,7 @@ impl RenderOnce for AudioWaveform { cx.notify(); }) }) + .hover_listener_mode(HoverListenerMode::InputModalityIndependent) .on_hover(move |inside, _, cx| { if !inside { left.update(cx, |wave, cx| { diff --git a/src/media/player.rs b/src/media/player.rs index 1d05440..6b7cf71 100644 --- a/src/media/player.rs +++ b/src/media/player.rs @@ -154,15 +154,17 @@ fn wake(watch: &Entity, window: &mut Window, cx: &mut App) { loop { let wait = watch.read_with(cx, |watch, cx| { IDLE.saturating_sub(cx.background_executor().now().duration_since(watch.moved)) - })?; + }); if wait.is_zero() { break; } cx.background_executor().timer(wait).await; } - watch.update(cx, |watch, cx| { - watch.waking = false; - cx.notify(); + cx.update(|_, cx| { + watch.update(cx, |watch, cx| { + watch.waking = false; + cx.notify(); + }) }) }) .detach_and_log_err(cx); diff --git a/src/media/scrubber.rs b/src/media/scrubber.rs index a6a0b1d..080cb77 100644 --- a/src/media/scrubber.rs +++ b/src/media/scrubber.rs @@ -1,9 +1,9 @@ use std::{rc::Rc, time::Duration}; use gpui::{ - App, Bounds, Div, DragMoveEvent, ElementId, EmptyView, EntityId, InteractiveElement, - IntoElement, MouseButton, ParentElement, Pixels, Point, Rems, RenderOnce, SharedString, - StatefulInteractiveElement, Styled, Window, canvas, div, prelude::*, relative, + App, Bounds, Div, DragMoveEvent, ElementId, EmptyView, EntityId, HoverListenerMode, + InteractiveElement, IntoElement, MouseButton, ParentElement, Pixels, Point, Rems, RenderOnce, + SharedString, StatefulInteractiveElement, Styled, Window, canvas, div, prelude::*, relative, transparent_black, }; @@ -183,7 +183,7 @@ impl RenderOnce for Scrubber { .relative() .h(line) .flex_basis(relative(share(end - start))) - .flex_grow() + .flex_grow_1() .rounded_full() .bg(lane) .child( @@ -275,6 +275,7 @@ impl RenderOnce for Scrubber { cx.notify(); }) }) + .hover_listener_mode(HoverListenerMode::InputModalityIndependent) .on_hover(move |inside, _, cx| { if !inside { left.update(cx, |track, cx| { diff --git a/src/media/tests/edit.rs b/src/media/tests/edit.rs index cc93fb5..9dcdc44 100644 --- a/src/media/tests/edit.rs +++ b/src/media/tests/edit.rs @@ -157,7 +157,7 @@ fn a_shaped_crop_keeps_its_shape_as_a_corner_moves(cx: &mut TestAppContext) { #[gpui::test] fn a_cropper_with_no_handler_takes_no_tab(cx: &mut TestAppContext) { let (_, cx) = cropping(HALF, None, false, cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); assert!(cx.update(|window, cx| window.focused(cx)).is_none()); } @@ -226,9 +226,9 @@ fn a_picked_picture_crops_from_a_fitted_box_and_remove_empties_it(cx: &mut TestA }; let fitted = crop.is_some_and(|crop| near(crop, square)); assert!(fitted && heard == 1, "{crop:?} after {heard}"); - cx.update(|window, _| { + cx.update(|window, cx| { for _ in 0..2 { - window.focus_next(); + window.focus_next(cx); } }); press("enter", cx); diff --git a/src/media/tests/images.rs b/src/media/tests/images.rs index c00d01a..8f86397 100644 --- a/src/media/tests/images.rs +++ b/src/media/tests/images.rs @@ -247,7 +247,7 @@ fn a_picture_that_cannot_open_says_so(cx: &mut TestAppContext) { let cx = viewing(std::env::temp_dir().join("ely-media-missing.png"), cx); assert!(cx.debug_bounds("image-viewer-failed").is_some()); assert!(cx.debug_bounds("image-viewer-picture").is_none()); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); let focused = cx.update(|window, cx| window.focused(cx)); assert!(focused.is_none(), "with nothing to show, nothing takes Tab"); } @@ -284,9 +284,9 @@ fn only_a_thumbnail_with_a_handler_takes_tab_and_opens_on_enter(cx: &mut TestApp let (_, cx) = cx.add_window_view(|_, _| Strip(seen, path)); cx.update(|window, _| window.activate_window()); settle(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); let first = cx.update(|window, cx| window.focused(cx)); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); let wrapped = cx.update(|window, cx| window.focused(cx)); assert!( first.is_some() && first == wrapped, diff --git a/src/media/tests/mod.rs b/src/media/tests/mod.rs index 2453dec..e3299da 100644 --- a/src/media/tests/mod.rs +++ b/src/media/tests/mod.rs @@ -59,10 +59,10 @@ pub(super) fn across( /// Moves focus to the `nth` Tab stop from none. pub(super) fn tab_to(nth: usize, cx: &mut VisualTestContext) { - cx.update(|window, _| { - window.blur(); + cx.update(|window, cx| { + window.blur(cx); for _ in 0..nth { - window.focus_next(); + window.focus_next(cx); } }); settle(cx); diff --git a/src/media/tests/player.rs b/src/media/tests/player.rs index 13131d4..506fcc6 100644 --- a/src/media/tests/player.rs +++ b/src/media/tests/player.rs @@ -97,10 +97,10 @@ fn watching(cx: &mut TestAppContext) -> (Entity, &mut VisualTestContex #[gpui::test] fn space_on_a_focused_bar_button_presses_it_once(cx: &mut TestAppContext) { let (view, cx) = watching(cx); - cx.update(|window, _| { - window.blur(); + cx.update(|window, cx| { + window.blur(cx); for _ in 0..3 { - window.focus_next(); + window.focus_next(cx); } }); press("space", cx); @@ -145,7 +145,7 @@ fn a_long_caption_wraps_inside_a_narrow_player(cx: &mut TestAppContext) { #[gpui::test] fn a_caption_stays_while_the_controls_rest(cx: &mut TestAppContext) { let (view, cx) = watching_at(480.0, "Light falls on the stair", true, cx); - cx.update(|window, _| window.blur()); + cx.update(|window, cx| window.blur(cx)); view.update(cx, |view, cx| { view.playing = true; cx.notify(); @@ -181,7 +181,7 @@ fn space_plays_l_and_j_jump_ten_seconds_and_c_turns_captions(cx: &mut TestAppCon #[gpui::test] fn controls_rest_once_the_pointer_is_still_while_it_plays(cx: &mut TestAppContext) { let (view, cx) = watching(cx); - cx.update(|window, _| window.blur()); + cx.update(|window, cx| window.blur(cx)); view.update(cx, |view, cx| { view.playing = true; cx.notify(); @@ -203,7 +203,7 @@ fn controls_rest_once_the_pointer_is_still_while_it_plays(cx: &mut TestAppContex /// Rests a playing player's bar, focus outside it and the pointer still at `spot`. fn rest(spot: Point, view: &Entity, cx: &mut VisualTestContext) { - cx.update(|window, _| window.blur()); + cx.update(|window, cx| window.blur(cx)); view.update(cx, |view, cx| { view.playing = true; cx.notify(); @@ -244,7 +244,7 @@ fn shift_tab_into_a_resting_bar_keeps_focus_on_its_last_button(cx: &mut TestAppC let (view, cx) = watching(cx); let frame = cx.debug_bounds("video-player").expect("the player draws"); rest(frame.center(), &view, cx); - cx.update(|window, _| window.focus_prev()); + cx.update(|window, cx| window.focus_prev(cx)); settle(cx); press("enter", cx); assert_eq!(view.read_with(cx, |view, _| view.fullscreens), 1); @@ -288,7 +288,7 @@ fn the_bar_stays_up_while_a_button_in_it_has_focus(cx: &mut TestAppContext) { let (_, cx) = cx.add_window_view(|_, _| Paced { path }); cx.update(|window, _| window.activate_window()); settle(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); settle(cx); cx.executor().advance_clock(Duration::from_millis(2600)); settle(cx); diff --git a/src/media/tests/video.rs b/src/media/tests/video.rs index d059b5b..2bb0822 100644 --- a/src/media/tests/video.rs +++ b/src/media/tests/video.rs @@ -250,10 +250,10 @@ fn captioning_at<'a>( /// Tabs to the `nth` stop and types over it. fn retype(nth: usize, text: &str, cx: &mut VisualTestContext) { - cx.update(|window, _| { - window.blur(); + cx.update(|window, cx| { + window.blur(cx); for _ in 0..nth { - window.focus_next(); + window.focus_next(cx); } }); press("enter", cx); diff --git a/src/menus/menu.rs b/src/menus/menu.rs index 900f802..7667013 100644 --- a/src/menus/menu.rs +++ b/src/menus/menu.rs @@ -296,7 +296,7 @@ pub(crate) fn hang( if let Some(typing) = &typing && focus.is_focused(window) { - window.focus(typing); + window.focus(typing, cx); } let mut levels = state.read(cx).levels.clone(); settle(menu, &mut levels); diff --git a/src/menus/tests/mod.rs b/src/menus/tests/mod.rs index e2dc763..608b61d 100644 --- a/src/menus/tests/mod.rs +++ b/src/menus/tests/mod.rs @@ -136,7 +136,7 @@ fn click(x: f32, y: f32, cx: &mut VisualTestContext) { #[gpui::test] fn the_keyboard_opens_walks_past_disabled_rows_and_runs(cx: &mut TestAppContext) { let (view, cx) = desk(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); press("enter", cx); press("down", cx); press("enter", cx); @@ -149,7 +149,7 @@ fn the_keyboard_opens_walks_past_disabled_rows_and_runs(cx: &mut TestAppContext) #[gpui::test] fn submenus_open_right_and_close_left(cx: &mut TestAppContext) { let (view, cx) = desk(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); press("enter", cx); press("up", cx); press("right", cx); @@ -164,7 +164,7 @@ fn submenus_open_right_and_close_left(cx: &mut TestAppContext) { #[gpui::test] fn a_check_row_reports_to_its_owner(cx: &mut TestAppContext) { let (view, cx) = desk(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); press("enter", cx); press("up", cx); press("up", cx); @@ -175,7 +175,7 @@ fn a_check_row_reports_to_its_owner(cx: &mut TestAppContext) { #[gpui::test] fn escape_backs_out_one_level_then_closes(cx: &mut TestAppContext) { let (view, cx) = desk(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); press("enter", cx); press("up", cx); press("right", cx); @@ -230,7 +230,7 @@ fn the_trigger_toggles_and_a_press_outside_closes(cx: &mut TestAppContext) { #[gpui::test] fn rows_the_owner_removes_leave_the_menu_usable(cx: &mut TestAppContext) { let (view, cx) = desk(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); press("enter", cx); press("up", cx); view.update(cx, |desk, cx| { @@ -248,7 +248,7 @@ fn rows_the_owner_removes_leave_the_menu_usable(cx: &mut TestAppContext) { #[gpui::test] fn closing_from_the_trigger_hands_focus_back(cx: &mut TestAppContext) { let (view, cx) = desk(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); press("enter", cx); click(12.0, 12.0, cx); press("enter", cx); @@ -269,7 +269,7 @@ fn confirm_keys_stay_inside_the_menu(cx: &mut TestAppContext) { #[gpui::test] fn modified_confirm_keys_do_not_pick(cx: &mut TestAppContext) { let (view, cx) = desk(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); press("enter", cx); press("ctrl-enter", cx); press("shift-space", cx); @@ -281,7 +281,7 @@ fn modified_confirm_keys_do_not_pick(cx: &mut TestAppContext) { #[gpui::test] fn a_second_right_click_moves_the_context_menu(cx: &mut TestAppContext) { let (view, cx) = desk(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); for at in [point(px(150.0), px(120.0)), point(px(20.0), px(40.0))] { cx.simulate_mouse_move(at, None, Modifiers::none()); cx.simulate_mouse_down(at, MouseButton::Right, Modifiers::none()); @@ -312,9 +312,9 @@ fn a_left_press_in_the_region_closes_the_context_menu(cx: &mut TestAppContext) { } fn open_find(cx: &mut VisualTestContext) { - cx.update(|window, _| { - window.focus_next(); - window.focus_next(); + cx.update(|window, cx| { + window.focus_next(cx); + window.focus_next(cx); }); press("enter", cx); } diff --git a/src/menus/tests/more.rs b/src/menus/tests/more.rs index a898bad..b01b8e4 100644 --- a/src/menus/tests/more.rs +++ b/src/menus/tests/more.rs @@ -24,6 +24,8 @@ fn action(name: &str, action: impl gpui::Action) -> OwnedMenuItem { name: name.into(), action: Box::new(action), os_action: None, + checked: false, + disabled: false, } } @@ -33,6 +35,7 @@ impl Render for Bar { OwnedMenu { name: "File".into(), items: vec![action("Open", OpenFile), action("Save", Save)], + disabled: false, }, OwnedMenu { name: "Edit".into(), @@ -42,8 +45,10 @@ impl Render for Bar { OwnedMenuItem::Submenu(OwnedMenu { name: "More".into(), items: vec![action("Deep", Deep)], + disabled: false, }), ], + disabled: false, }, ]; div() @@ -70,7 +75,7 @@ fn bar(cx: &mut TestAppContext) -> (gpui::Entity, &mut VisualTestContext) { ran: Vec::new(), }); settle(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); (view, cx) } @@ -150,7 +155,7 @@ fn wheel(cx: &mut TestAppContext) -> (gpui::Entity, &mut VisualTestContex enters_above: 0, }); settle(cx); - cx.update(|window, cx| window.focus(&view.read(cx).before.clone())); + cx.update(|window, cx| window.focus(&view.read(cx).before.clone(), cx)); let at = point(px(300.0), px(300.0)); cx.simulate_mouse_move(at, None, Modifiers::none()); cx.simulate_mouse_down(at, MouseButton::Right, Modifiers::none()); diff --git a/src/messaging/tests/mod.rs b/src/messaging/tests/mod.rs index 88cb1aa..2a9a2a3 100644 --- a/src/messaging/tests/mod.rs +++ b/src/messaging/tests/mod.rs @@ -41,10 +41,10 @@ fn press(key: &str, cx: &mut VisualTestContext) { /// Moves focus to the `nth` Tab stop from none. fn tab_to(nth: usize, cx: &mut VisualTestContext) { - cx.update(|window, _| { - window.blur(); + cx.update(|window, cx| { + window.blur(cx); for _ in 0..nth { - window.focus_next(); + window.focus_next(cx); } }); settle(cx); diff --git a/src/messaging/tests/people.rs b/src/messaging/tests/people.rs index 1fb9b7d..98ee061 100644 --- a/src/messaging/tests/people.rs +++ b/src/messaging/tests/people.rs @@ -203,12 +203,12 @@ fn an_emoji_is_searched_and_picked_and_focus_comes_back(cx: &mut TestAppContext) let (host, cx) = setting(None, cx); tab_to(1, cx); press("enter", cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); settle(cx); cx.simulate_input("palm tree"); settle(cx); press("enter", cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); settle(cx); cx.simulate_input("Away"); settle(cx); diff --git a/src/misc/calculator.rs b/src/misc/calculator.rs index d1ee998..238c3f4 100644 --- a/src/misc/calculator.rs +++ b/src/misc/calculator.rs @@ -266,7 +266,7 @@ impl RenderOnce for Calculator { .focus_ring(cx) .on_mouse_down(MouseButton::Left, { let focus = focus.clone(); - move |_, window, _| window.focus(&focus) + move |_, window, cx| window.focus(&focus, cx) }) .on_key_down({ let tape = tape.clone(); diff --git a/src/misc/captcha.rs b/src/misc/captcha.rs index ba1d7e7..c1b17a5 100644 --- a/src/misc/captcha.rs +++ b/src/misc/captcha.rs @@ -90,7 +90,7 @@ impl RenderOnce for Captcha { let verify = tab_stop((id.clone(), "verify").into(), !passed, window, cx); if passed && field.read(cx).focus().is_focused(window) { log::info!("captcha: passed; focus goes to the mark"); - window.focus(&verify); + window.focus(&verify, cx); } let checking = self.state == CaptchaState::Checking; let answer = { @@ -101,13 +101,13 @@ impl RenderOnce for Captcha { } let text = SharedString::from(field.read(cx).text().trim().to_string()); if text.is_empty() { - window.focus(field.read(cx).focus()); + window.focus(&field.read(cx).focus().clone(), cx); return; } log::info!("captcha: answered"); on_answer(&text, window, cx); field.update(cx, |field, cx| field.set_text("", cx)); - window.focus(field.read(cx).focus()); + window.focus(&field.read(cx).focus().clone(), cx); }) }; let theme = cx.theme(); diff --git a/src/misc/clock.rs b/src/misc/clock.rs index 0e97e90..d64ff24 100644 --- a/src/misc/clock.rs +++ b/src/misc/clock.rs @@ -54,7 +54,8 @@ fn each_second(id: impl Into, window: &mut Window, cx: &mut App) { cx.background_executor() .timer(Duration::from_nanos(1_000_000_000 - past)) .await; - if ticker.update(cx, |_, cx| cx.notify()).is_err() { + let ticked = cx.update(|_, cx| ticker.update(cx, |_, cx| cx.notify())); + if ticked.and_then(|inner| inner).is_err() { return; } } diff --git a/src/misc/poll.rs b/src/misc/poll.rs index 3b9e7ba..7af2d58 100644 --- a/src/misc/poll.rs +++ b/src/misc/poll.rs @@ -190,7 +190,7 @@ impl RenderOnce for Poll { let ix = picked.expect("Vote waits for a pick"); log::info!("poll: voted for option {ix}"); on_vote(Some(ix), window, cx); - window.focus(&focus); + window.focus(&focus, cx); }) } Some(_) => Button::new((id.clone(), "change"), "Change vote") diff --git a/src/misc/quiz.rs b/src/misc/quiz.rs index cf41c89..0a749fc 100644 --- a/src/misc/quiz.rs +++ b/src/misc/quiz.rs @@ -276,7 +276,7 @@ impl RenderOnce for Quiz { if let (true, Some(on_score)) = (finishing, &on_score) { on_score(score, count, window, cx); } - window.focus(&focus); + window.focus(&focus, cx); }), ), ) diff --git a/src/misc/stopwatch.rs b/src/misc/stopwatch.rs index 760569a..0e943e6 100644 --- a/src/misc/stopwatch.rs +++ b/src/misc/stopwatch.rs @@ -123,7 +123,7 @@ impl RenderOnce for Stopwatch { cx.notify(); }); if let Some(then) = &then { - window.focus(then); + window.focus(then, cx); } } }; diff --git a/src/misc/survey.rs b/src/misc/survey.rs index 98127f7..02fc42a 100644 --- a/src/misc/survey.rs +++ b/src/misc/survey.rs @@ -271,7 +271,7 @@ impl RenderOnce for Survey { sheet.sent = true; cx.notify(); }); - window.focus(&focus); + window.focus(&focus, cx); }), ), ) diff --git a/src/misc/tests/mod.rs b/src/misc/tests/mod.rs index 28ee25c..086d695 100644 --- a/src/misc/tests/mod.rs +++ b/src/misc/tests/mod.rs @@ -63,7 +63,7 @@ pub(super) fn stage( let wakes = Rc::new(Cell::new(0)); let count = wakes.clone(); cx.update(|window, cx| { - window.focus(&root); + window.focus(&root, cx); cx.observe(&view, move |_, _| count.set(count.get() + 1)) .detach(); }); diff --git a/src/misc/tests/notices.rs b/src/misc/tests/notices.rs index dc8fc6b..76cbae8 100644 --- a/src/misc/tests/notices.rs +++ b/src/misc/tests/notices.rs @@ -148,7 +148,7 @@ fn consent_hands_focus_back_to_its_opener(cx: &mut TestAppContext) { button: cx.focus_handle(), }); let button = view.read_with(cx, |opener, _| opener.button.clone()); - cx.update(|window, _| window.focus(&button)); + cx.update(|window, cx| window.focus(&button, cx)); settle(cx); press("enter", cx); press("tab", cx); diff --git a/src/misc/tests/transfer.rs b/src/misc/tests/transfer.rs index 0d91af1..513baff 100644 --- a/src/misc/tests/transfer.rs +++ b/src/misc/tests/transfer.rs @@ -268,7 +268,7 @@ fn answered_from_button(part: fn() -> AnyElement, tabs: usize, cx: &mut TestAppC part, }); let button = view.read_with(cx, |opener, _| opener.button.clone()); - cx.update(|window, _| window.focus(&button)); + cx.update(|window, cx| window.focus(&button, cx)); settle(cx); press("enter", cx); for _ in 0..tabs { diff --git a/src/motion/effects.rs b/src/motion/effects.rs index e513b76..0937e02 100644 --- a/src/motion/effects.rs +++ b/src/motion/effects.rs @@ -216,6 +216,7 @@ fn glow(color: Hsla, reach: Pixels, strength: f32) -> Vec { offset: point(Pixels::ZERO, Pixels::ZERO), blur_radius: reach * (0.4 + 0.6 * strength), spread_radius: Pixels::ZERO, + inset: false, }] } diff --git a/src/navigation/menu.rs b/src/navigation/menu.rs index 0432b88..3fae0ea 100644 --- a/src/navigation/menu.rs +++ b/src/navigation/menu.rs @@ -148,7 +148,7 @@ impl RenderOnce for NavigationMenu { .hover(|style| style.text_color(colors.fg)) .on_mouse_down(MouseButton::Left, move |_, window, cx| { window.prevent_default(); - window.focus(&into); + window.focus(&into, cx); show(&press, if on { None } else { Some(ix) }, cx); }) .on_hover(move |hovered, _, cx| { diff --git a/src/navigation/palette/launcher.rs b/src/navigation/palette/launcher.rs index 99714a5..8bb279d 100644 --- a/src/navigation/palette/launcher.rs +++ b/src/navigation/palette/launcher.rs @@ -81,7 +81,7 @@ impl Render for QuickLauncher { .palette(window, cx); if !self.focused { self.focused = true; - window.focus(&palette.input.read(cx).focus().clone()); + window.focus(&palette.input.read(cx).focus().clone(), cx); } div() .size_full() diff --git a/src/navigation/palette/mod.rs b/src/navigation/palette/mod.rs index 67b8296..07c1661 100644 --- a/src/navigation/palette/mod.rs +++ b/src/navigation/palette/mod.rs @@ -153,7 +153,7 @@ impl Palette { let takeover = take_focus((self.id.clone(), "takeover"), window, cx); let scope = takeover.read(cx).focus.clone(); if scope.is_focused(window) { - window.focus(&self.input.read(cx).focus().clone()); + window.focus(&self.input.read(cx).focus().clone(), cx); } let close = self.on_close.clone(); let close: Run = Rc::new(move |window, cx| { diff --git a/src/navigation/palette/tests.rs b/src/navigation/palette/tests.rs index 2f4ecd7..7fceb15 100644 --- a/src/navigation/palette/tests.rs +++ b/src/navigation/palette/tests.rs @@ -261,7 +261,7 @@ fn search_refuses_disabled_results(cx: &mut TestAppContext) { fn enter_picks_on_release_so_the_opener_stays_shut(cx: &mut TestAppContext) { let (view, cx) = host(Kind::Commands, cx); press("escape", cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); press("enter", cx); assert_eq!(got(&view, cx), (true, None)); cx.simulate_input("zi"); diff --git a/src/navigation/steps.rs b/src/navigation/steps.rs index da5a6f1..f5ae101 100644 --- a/src/navigation/steps.rs +++ b/src/navigation/steps.rs @@ -193,7 +193,7 @@ impl RenderOnce for Steps { .flex_1() .items_center() .gap_3() - .when(ix + 1 == count, |step| step.flex_none()) + .when(ix + 1 == count, |step| step.flex_grow_0().flex_shrink_0()) .child(head.child(circle).child(words)) .children(after) .into_any_element() @@ -337,7 +337,7 @@ impl RenderOnce for Wizard { wizard.child( Steps::new((id.clone(), "steps"), self.steps, current).on_select( move |to, window, cx| { - window.focus(&jumped); + window.focus(&jumped, cx); jump(to, window, cx) }, ), @@ -355,7 +355,7 @@ impl RenderOnce for Wizard { .disabled(current == 0) .on_click(move |_, window, cx| { if current == 1 { - window.focus(&to_advance); + window.focus(&to_advance, cx); } back(current - 1, window, cx) }), diff --git a/src/navigation/tests.rs b/src/navigation/tests.rs index 88a678b..ec9615d 100644 --- a/src/navigation/tests.rs +++ b/src/navigation/tests.rs @@ -53,7 +53,7 @@ impl Render for Strip { fn tab_arrows_skip_disabled_tabs_and_wrap(cx: &mut TestAppContext) { setup(cx); let (view, cx) = cx.add_window_view(|_, _| Strip { chosen: "a".into() }); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_keystrokes("right"); assert_eq!(view.read_with(cx, |view, _| view.chosen.clone()), "c"); cx.simulate_keystrokes("right"); @@ -90,9 +90,9 @@ impl Render for Path { fn a_level_lists_its_siblings_and_picks_one(cx: &mut TestAppContext) { setup(cx); let (view, cx) = cx.add_window_view(|_, _| Path { picked: None }); - cx.update(|window, _| { - window.focus_next(); - window.focus_next(); + cx.update(|window, cx| { + window.focus_next(cx); + window.focus_next(cx); }); press("down", cx); press("down", cx); @@ -132,13 +132,13 @@ fn the_wizard_walks_forward_back_and_finishes(cx: &mut TestAppContext) { step: 0, done: false, }); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); press("enter", cx); assert_eq!(view.read_with(cx, |view, _| view.step), 1); - cx.update(|window, _| { - window.blur(); - window.focus_next(); - window.focus_next(); + cx.update(|window, cx| { + window.blur(cx); + window.focus_next(cx); + window.focus_next(cx); }); press("enter", cx); assert_eq!(view.read_with(cx, |view, _| view.step), 0); @@ -146,10 +146,10 @@ fn the_wizard_walks_forward_back_and_finishes(cx: &mut TestAppContext) { view.step = 2; cx.notify(); }); - cx.update(|window, _| { - window.blur(); + cx.update(|window, cx| { + window.blur(cx); for _ in 0..4 { - window.focus_next(); + window.focus_next(cx); } }); press("enter", cx); @@ -164,9 +164,9 @@ fn a_picked_step_hands_focus_to_next(cx: &mut TestAppContext) { step: 2, done: false, }); - cx.update(|window, _| { - window.blur(); - window.focus_next(); + cx.update(|window, cx| { + window.blur(cx); + window.focus_next(cx); }); press("enter", cx); assert_eq!(view.read_with(cx, |view, _| view.step), 0); @@ -305,7 +305,7 @@ impl Render for Site { fn the_menu_opens_switches_and_picks_from_the_keyboard(cx: &mut TestAppContext) { setup(cx); let (view, cx) = cx.add_window_view(|_, _| Site::new()); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_keystrokes("down right down enter"); let went = view.read_with(cx, |view, _| view.went.clone()); assert_eq!(went, Some(SharedString::from("api"))); @@ -315,7 +315,7 @@ fn the_menu_opens_switches_and_picks_from_the_keyboard(cx: &mut TestAppContext) fn menu_keys_pass_over_disabled_links(cx: &mut TestAppContext) { setup(cx); let (view, cx) = cx.add_window_view(|_, _| Site::new()); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_keystrokes("down enter"); let went = view.read_with(cx, |view, _| view.went.clone()); assert_eq!(went, Some(SharedString::from("price"))); @@ -328,7 +328,7 @@ fn menu_keys_pass_over_disabled_links(cx: &mut TestAppContext) { fn an_open_menu_follows_lists_that_shrink(cx: &mut TestAppContext) { setup(cx); let (view, cx) = cx.add_window_view(|_, _| Site::new()); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_keystrokes("down right down"); view.update(cx, |view, cx| { view.entries[1].1.pop(); @@ -369,13 +369,13 @@ impl Render for Trail { fn back_steps_once_and_the_list_jumps_anywhere(cx: &mut TestAppContext) { setup(cx); let (view, cx) = cx.add_window_view(|_, _| Trail { at: 2 }); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); press("enter", cx); assert_eq!(view.read_with(cx, |view, _| view.at), 1); - cx.update(|window, _| { - window.blur(); + cx.update(|window, cx| { + window.blur(cx); for _ in 0..3 { - window.focus_next(); + window.focus_next(cx); } }); press("down", cx); @@ -405,7 +405,7 @@ fn enter_jumps_to_a_line_and_column(cx: &mut TestAppContext) { field: cx.new(|cx| TextInput::new(window, cx)), to: None, }); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_input("12:4"); cx.simulate_keystrokes("enter"); assert_eq!(view.read_with(cx, |view, _| view.to), Some((12, Some(4)))); @@ -435,7 +435,7 @@ fn load_more_asks_once_per_press_and_goes_once_all_show(cx: &mut TestAppContext) shown: 10, asks: 0, }); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); press("enter", cx); assert_eq!(view.read_with(cx, |more, _| more.asks), 1); view.update(cx, |more, cx| { @@ -449,7 +449,7 @@ fn load_more_asks_once_per_press_and_goes_once_all_show(cx: &mut TestAppContext) more.shown = 30; cx.notify(); }); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); press("enter", cx); assert_eq!( view.read_with(cx, |more, _| more.asks), diff --git a/src/navigation/toc.rs b/src/navigation/toc.rs index 4e9c2cd..69771c8 100644 --- a/src/navigation/toc.rs +++ b/src/navigation/toc.rs @@ -131,7 +131,7 @@ impl RenderOnce for TableOfContents { let (viewport, at_end, tops) = { let sections = self.sections.read(cx); let (scroll, viewport) = (§ions.scroll, sections.scroll.bounds()); - let room = scroll.max_offset().height; + let room = scroll.max_offset().y; let at_end = room > Pixels::ZERO && -scroll.offset().y >= room; let tops: Vec> = self .entries diff --git a/src/onboarding/help.rs b/src/onboarding/help.rs index 5e17894..0f0d710 100644 --- a/src/onboarding/help.rs +++ b/src/onboarding/help.rs @@ -150,8 +150,8 @@ impl RenderOnce for HelpPanel { let search_focus = self.search.read(cx).focus().clone(); let on_open: OnOpen = Rc::new(move |key, window, cx| { match key { - Some(_) => window.focus(&back_focus), - None => window.focus(&search_focus), + Some(_) => window.focus(&back_focus, cx), + None => window.focus(&search_focus, cx), } on_open(key, window, cx) }); diff --git a/src/onboarding/support.rs b/src/onboarding/support.rs index 542c3e0..0894b57 100644 --- a/src/onboarding/support.rs +++ b/src/onboarding/support.rs @@ -94,7 +94,7 @@ impl RenderOnce for ContactSupport { log::info!("contact support: send about {key}"); on_send(&key, &words, window, cx); emptied.update(cx, |field, cx| field.set_text("", cx)); - window.focus(&field); + window.focus(&field, cx); }; div() .flex() diff --git a/src/onboarding/tests/mod.rs b/src/onboarding/tests/mod.rs index a91467b..5a3b2ef 100644 --- a/src/onboarding/tests/mod.rs +++ b/src/onboarding/tests/mod.rs @@ -92,9 +92,9 @@ fn edit(host: &Entity, cx: &mut VisualTestContext, change: impl FnOnce(&m /// Focus on the `stops`th Tab stop from the top. fn tab(stops: usize, cx: &mut VisualTestContext) { - cx.update(|window, _| { - window.blur(); - (0..stops).for_each(|_| window.focus_next()); + cx.update(|window, cx| { + window.blur(cx); + (0..stops).for_each(|_| window.focus_next(cx)); }); settle(cx); } diff --git a/src/overlays/dialog.rs b/src/overlays/dialog.rs index 8989b50..cd94cbf 100644 --- a/src/overlays/dialog.rs +++ b/src/overlays/dialog.rs @@ -107,7 +107,7 @@ impl RenderOnce for Dialog { if let Some(first) = &self.first && focus.is_focused(window) { - window.focus(first); + window.focus(first, cx); } let close: Run = { let (id, on_close) = (self.id.clone(), self.on_close); diff --git a/src/overlays/floats.rs b/src/overlays/floats.rs index 7b6ef74..af875fc 100644 --- a/src/overlays/floats.rs +++ b/src/overlays/floats.rs @@ -1,7 +1,7 @@ use std::rc::Rc; use gpui::{ - AnimationExt, AnyElement, App, Corner, ElementId, Entity, FontWeight, InteractiveElement, + Anchor, AnimationExt, AnyElement, App, ElementId, Entity, FontWeight, InteractiveElement, IntoElement, ParentElement, RenderOnce, SharedString, Styled, Window, anchored, canvas, div, point, prelude::*, }; @@ -72,7 +72,7 @@ impl RenderOnce for FloatingToolbar { (self.id.clone(), "raised"), anchored() .position(anchor.origin - point(gpui::Pixels::ZERO, lift)) - .anchor(Corner::BottomLeft) + .anchor(Anchor::BottomLeft) .snap_to_window() .child( surface((self.id.clone(), "bar"), cx) diff --git a/src/overlays/hover.rs b/src/overlays/hover.rs index 14ce835..209e0e8 100644 --- a/src/overlays/hover.rs +++ b/src/overlays/hover.rs @@ -1,8 +1,9 @@ use std::{rc::Rc, time::Duration}; use gpui::{ - AnyElement, App, Bounds, ElementId, Entity, InteractiveElement, IntoElement, ParentElement, - Pixels, RenderOnce, StatefulInteractiveElement, Styled, Task, Window, canvas, div, + AnyElement, App, Bounds, ElementId, Entity, HoverListenerMode, InteractiveElement, IntoElement, + ParentElement, Pixels, RenderOnce, StatefulInteractiveElement, Styled, Task, Window, canvas, + div, }; use crate::forms::{float_height, surface}; @@ -78,6 +79,7 @@ impl RenderOnce for HoverCard { .id(self.id.clone()) .relative() .child(self.trigger) + .hover_listener_mode(HoverListenerMode::InputModalityIndependent) .on_hover(move |hovered, window, cx| { enter.update(cx, |hover, _| hover.on_trigger = *hovered); settle_after(&enter, if *hovered { OPEN } else { LINGER }, window, cx); @@ -108,6 +110,7 @@ impl RenderOnce for HoverCard { .relative() .occlude() .p_4() + .hover_listener_mode(HoverListenerMode::InputModalityIndependent) .on_hover(move |hovered, window, cx| { over.update(cx, |hover, _| hover.on_card = *hovered); settle_after(&over, LINGER, window, cx); diff --git a/src/overlays/tests/guides.rs b/src/overlays/tests/guides.rs index 4a9b2b1..31ac193 100644 --- a/src/overlays/tests/guides.rs +++ b/src/overlays/tests/guides.rs @@ -141,7 +141,7 @@ fn guides(cx: &mut TestAppContext) -> (Entity, &mut VisualTestContext) { fn open(view: &Entity, which: Open, cx: &mut VisualTestContext) { let before = view.read_with(cx, |guides, _| guides.before.clone()); - cx.update(|window, _| window.focus(&before)); + cx.update(|window, cx| window.focus(&before, cx)); view.update(cx, |guides, cx| { guides.open = Some(which); guides.at = 0; @@ -242,7 +242,7 @@ fn the_toolbar_floats_over_a_selection_only(cx: &mut TestAppContext) { let (view, cx) = guides(cx); let field = view.read_with(cx, |guides, _| guides.field.clone()); let focus = field.read_with(cx, |input, _| input.focus().clone()); - cx.update(|window, _| window.focus(&focus)); + cx.update(|window, cx| window.focus(&focus, cx)); settle(cx); let start = field .read_with(cx, |input, _| input.bounds_for(0)) @@ -253,7 +253,7 @@ fn the_toolbar_floats_over_a_selection_only(cx: &mut TestAppContext) { ); click(bold.0, bold.1, cx); assert!(state(&view, cx).2.is_empty(), "no selection, no toolbar"); - cx.update(|window, _| window.focus(&focus)); + cx.update(|window, cx| window.focus(&focus, cx)); press("secondary-a", cx); click(bold.0, bold.1, cx); assert_eq!(state(&view, cx).2, ["bold"]); @@ -263,10 +263,10 @@ fn the_toolbar_floats_over_a_selection_only(cx: &mut TestAppContext) { fn the_peek_closes_from_its_button(cx: &mut TestAppContext) { let (view, cx) = guides(cx); open(&view, Open::Peek, cx); - cx.update(|window, _| { - window.blur(); + cx.update(|window, cx| { + window.blur(cx); for _ in 0..3 { - window.focus_next(); + window.focus_next(cx); } }); press("enter", cx); @@ -309,7 +309,7 @@ fn the_toolbar_follows_its_field(cx: &mut TestAppContext) { let (view, cx) = guides(cx); let field = view.read_with(cx, |guides, _| guides.field.clone()); let focus = field.read_with(cx, |input, _| input.focus().clone()); - cx.update(|window, _| window.focus(&focus)); + cx.update(|window, cx| window.focus(&focus, cx)); press("secondary-a", cx); view.update(cx, |guides, cx| { guides.lower = true; diff --git a/src/overlays/tests/mod.rs b/src/overlays/tests/mod.rs index 70d1732..fa1c11e 100644 --- a/src/overlays/tests/mod.rs +++ b/src/overlays/tests/mod.rs @@ -198,7 +198,7 @@ fn log(view: &Entity, cx: &mut VisualTestContext) -> Vec { fn show(view: &Entity, open: Open, cx: &mut VisualTestContext) { let before = view.read_with(cx, |stage, _| stage.before.clone()); - cx.update(|window, _| window.focus(&before)); + cx.update(|window, cx| window.focus(&before, cx)); view.update(cx, |stage, cx| { stage.open = Some(open); cx.notify(); @@ -209,7 +209,7 @@ fn show(view: &Entity, open: Open, cx: &mut VisualTestContext) { #[gpui::test] fn tab_walks_inside_an_open_popover(cx: &mut TestAppContext) { let (view, cx) = stage(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); press("enter", cx); for _ in 0..3 { press("tab", cx); @@ -221,7 +221,7 @@ fn tab_walks_inside_an_open_popover(cx: &mut TestAppContext) { #[gpui::test] fn escape_closes_the_popover_and_hands_focus_back(cx: &mut TestAppContext) { let (view, cx) = stage(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); press("enter", cx); press("escape", cx); press("enter", cx); diff --git a/src/primitives/focus.rs b/src/primitives/focus.rs index e934266..e4afd0e 100644 --- a/src/primitives/focus.rs +++ b/src/primitives/focus.rs @@ -70,9 +70,9 @@ impl RenderOnce for FocusScope { if self.root { let handle = self.handle.clone(); window.use_keyed_state("focus-root", cx, |window, cx| Root { - _lost: cx.on_focus_lost(window, move |_: &mut Root, window, _| { + _lost: cx.on_focus_lost(window, move |_: &mut Root, window, cx| { log::info!("focus: its element left the tree; the root takes it"); - window.focus(&handle); + window.focus(&handle, cx); }), }); } @@ -85,21 +85,21 @@ impl RenderOnce for FocusScope { } fn step(scope: &FocusHandle, trap: bool, forward: bool, window: &mut Window, cx: &mut App) { - let advance = |window: &mut Window| { + let advance = |window: &mut Window, cx: &mut App| { if forward { - window.focus_next() + window.focus_next(cx) } else { - window.focus_prev() + window.focus_prev(cx) } }; if !trap { - advance(window); + advance(window, cx); return; } let origin = window.focused(cx); let mut first = None; loop { - advance(window); + advance(window, cx); let focused = window.focused(cx); if scope.contains_focused(window, cx) && focused.as_ref() != Some(scope) { return; @@ -113,7 +113,7 @@ fn step(scope: &FocusHandle, trap: bool, forward: bool, window: &mut Window, cx: } log::warn!("focus scope: trap holds no tab stop; focus stays"); if let Some(origin) = origin { - window.focus(&origin); + window.focus(&origin, cx); } } @@ -137,16 +137,16 @@ pub(crate) fn take_focus( previous: None, taken: false, returned: false, - _lost: cx.on_focus_lost(window, |takeover: &mut Takeover, window, _| { + _lost: cx.on_focus_lost(window, |takeover: &mut Takeover, window, cx| { if !takeover.returned { log::info!("focus: its element left the tree; the overlay takes it back"); - window.focus(&takeover.focus); + window.focus(&takeover.focus, cx); } }), }); if !state.read(cx).taken { let previous = window.focused(cx); - window.focus(&state.read(cx).focus.clone()); + window.focus(&state.read(cx).focus.clone(), cx); state.update(cx, |takeover, _| { takeover.previous = previous; takeover.taken = true; @@ -163,7 +163,7 @@ pub(crate) fn give_back(state: &Entity, window: &mut Window, cx: &mut }); match previous { Some(previous) => { - window.focus(&previous); + window.focus(&previous, cx); log::info!("focus: handed back after an overlay"); } None => log::info!("focus: overlay closed, nothing was focused before"), @@ -193,7 +193,7 @@ pub(crate) fn hold_focus( if on && !was_on && !focus.contains_focused(window, cx) { log::info!("focus: a mode takes it, so Escape reaches it"); let previous = window.focused(cx); - window.focus(&focus); + window.focus(&focus, cx); held.update(cx, |held, _| held.previous = previous); } if on != was_on { @@ -206,7 +206,7 @@ pub(crate) fn hold_focus( pub(crate) fn hand_back(held: &Entity, window: &mut Window, cx: &mut App) { if let Some(previous) = held.update(cx, |held, _| held.previous.take()) { log::info!("focus: handed back after a mode"); - window.focus(&previous); + window.focus(&previous, cx); } } diff --git a/src/primitives/layer.rs b/src/primitives/layer.rs index ff81b14..fbd750a 100644 --- a/src/primitives/layer.rs +++ b/src/primitives/layer.rs @@ -95,7 +95,7 @@ impl Element for Raised { ) { let child = self.child.take().expect("a raised element prepaints once"); if !self.nested { - window.defer_draw(child, window.element_offset(), self.priority); + window.defer_draw(child, window.element_offset(), self.priority, None); return; } LAYERS.with_borrow_mut(|layers| { diff --git a/src/primitives/tests.rs b/src/primitives/tests.rs index fe7c2ef..d50b0b5 100644 --- a/src/primitives/tests.rs +++ b/src/primitives/tests.rs @@ -113,7 +113,7 @@ fn a_raise_keeps_its_state_while_another_comes_before_it(cx: &mut TestAppContext cx.run_until_parked(); let first = seen.borrow().last().cloned().expect("the box drew"); let handle = first.read_with(cx, |handle, _| handle.clone()); - cx.update(|window, _| window.focus(&handle)); + cx.update(|window, cx| window.focus(&handle, cx)); view.update(cx, |nest, cx| { nest.tip = true; cx.notify(); diff --git a/src/primitives/tooltip.rs b/src/primitives/tooltip.rs index a004677..af01e42 100644 --- a/src/primitives/tooltip.rs +++ b/src/primitives/tooltip.rs @@ -2,9 +2,9 @@ use std::{rc::Rc, time::Duration}; use gpui::{ Animation, AnimationExt, AnyElement, AnyView, App, AppContext, Context, Div, ElementId, - InteractiveElement, IntoElement, ParentElement, Pixels, Point, Render, RenderOnce, - SharedString, StatefulInteractiveElement, Styled, Task, Window, anchored, div, point, - prelude::*, + HoverListenerMode, InteractiveElement, IntoElement, ParentElement, Pixels, Point, Render, + RenderOnce, SharedString, StatefulInteractiveElement, Styled, Task, Window, anchored, div, + point, prelude::*, }; use super::{Icon, IconName, raise}; @@ -143,6 +143,7 @@ impl RenderOnce for TooltipTrigger { div() .id(self.id) .child(self.child) + .hover_listener_mode(HoverListenerMode::InputModalityIndependent) .on_hover(move |hovered, window, cx| { if !*hovered { hover.update(cx, hide); diff --git a/src/project/pomodoro.rs b/src/project/pomodoro.rs index 49af305..7c906a1 100644 --- a/src/project/pomodoro.rs +++ b/src/project/pomodoro.rs @@ -181,7 +181,8 @@ impl RenderOnce for PomodoroTimer { cx.spawn_in(window, async move |ticker, cx| { loop { cx.background_executor().timer(Duration::from_secs(1)).await; - if ticker.update(cx, |_, cx| cx.notify()).is_err() { + let ticked = cx.update(|_, cx| ticker.update(cx, |_, cx| cx.notify())); + if ticked.and_then(|inner| inner).is_err() { return; } } diff --git a/src/project/tests/mod.rs b/src/project/tests/mod.rs index e3377a0..dffcdce 100644 --- a/src/project/tests/mod.rs +++ b/src/project/tests/mod.rs @@ -67,10 +67,10 @@ fn heard(host: &Entity, cx: &mut VisualTestContext) -> Vec { /// Moves focus to the `nth` Tab stop from none. fn tab_to(nth: usize, cx: &mut VisualTestContext) { - cx.update(|window, _| { - window.blur(); + cx.update(|window, cx| { + window.blur(cx); for _ in 0..nth { - window.focus_next(); + window.focus_next(cx); } }); settle(cx); diff --git a/src/project/tracker.rs b/src/project/tracker.rs index 7aeefb2..b5c1d12 100644 --- a/src/project/tracker.rs +++ b/src/project/tracker.rs @@ -104,7 +104,8 @@ impl RenderOnce for TimeTracker { cx.spawn_in(window, async move |ticker, cx| { loop { cx.background_executor().timer(Duration::from_secs(1)).await; - if ticker.update(cx, |_, cx| cx.notify()).is_err() { + let ticked = cx.update(|_, cx| ticker.update(cx, |_, cx| cx.notify())); + if ticked.and_then(|inner| inner).is_err() { return; } } @@ -129,7 +130,7 @@ impl RenderOnce for TimeTracker { let now = cx.background_executor().now(); log::info!("time tracker {id:?}: start {task}"); field.update(cx, |input, cx| input.set_text(String::new(), cx)); - window.focus(&action); + window.focus(&action, cx); if let Some(on_start) = &on_start { on_start(&task, now, window, cx); } @@ -144,7 +145,7 @@ impl RenderOnce for TimeTracker { Rc::new(move |window, cx| { let now = cx.background_executor().now(); log::info!("time tracker {id:?}: stop"); - window.focus(&typing); + window.focus(&typing, cx); if let Some(on_stop) = &on_stop { on_stop(now, window, cx); } diff --git a/src/settings/tests/mod.rs b/src/settings/tests/mod.rs index 86550a2..954ed04 100644 --- a/src/settings/tests/mod.rs +++ b/src/settings/tests/mod.rs @@ -66,9 +66,9 @@ fn said(host: &Entity, cx: &mut VisualTestContext) -> Vec { } fn tab(stops: usize, cx: &mut VisualTestContext) { - cx.update(|window, _| { - window.blur(); - (0..stops).for_each(|_| window.focus_next()); + cx.update(|window, cx| { + window.blur(cx); + (0..stops).for_each(|_| window.focus_next(cx)); }); settle(cx); } @@ -271,9 +271,9 @@ fn proxy(_: &mut Window, _: &mut App, owner: Entity) -> AnyElement { #[gpui::test] fn apply_hands_on_the_manual_proxy(cx: &mut TestAppContext) { let (host, cx) = desk(proxy, cx); - cx.update(|window, _| { - window.blur(); - window.focus_prev(); + cx.update(|window, cx| { + window.blur(cx); + window.focus_prev(cx); }); settle(cx); tap("space", cx); @@ -430,9 +430,9 @@ fn bad_port(_: &mut Window, _: &mut App, owner: Entity) -> AnyElement { #[gpui::test] fn apply_rests_while_the_port_is_bad(cx: &mut TestAppContext) { let (host, cx) = desk(bad_port, cx); - cx.update(|window, _| { - window.blur(); - window.focus_prev(); + cx.update(|window, cx| { + window.blur(cx); + window.focus_prev(cx); }); settle(cx); tap("space", cx); diff --git a/src/shell/dialogs.rs b/src/shell/dialogs.rs index 503b473..91b2af9 100644 --- a/src/shell/dialogs.rs +++ b/src/shell/dialogs.rs @@ -185,7 +185,7 @@ impl SplashScreen { }; let handle = cx.open_window(options, |window, cx| { let focus = cx.focus_handle(); - window.focus(&focus); + window.focus(&focus, cx); cx.new(|_| Hosted::new(self, focus)) })?; log::info!("splash: shown"); diff --git a/src/shell/native.rs b/src/shell/native.rs index c787e96..adeb803 100644 --- a/src/shell/native.rs +++ b/src/shell/native.rs @@ -103,12 +103,9 @@ mod mac { fn pick(&self, index: usize) { log::info!("tray: picked item {index}"); let on_pick = self.on_pick.clone(); + // The app outlives its run loop, the only place this task is polled. self.app - .spawn(async move |cx| { - if let Err(error) = cx.update(|cx| on_pick(index, cx)) { - log::error!("tray: app gone before item {index} ran: {error:#}"); - } - }) + .spawn(async move |cx| cx.update(|cx| on_pick(index, cx))) .detach(); } } diff --git a/src/shell/tests.rs b/src/shell/tests.rs index 2868c4e..1346f2a 100644 --- a/src/shell/tests.rs +++ b/src/shell/tests.rs @@ -80,7 +80,7 @@ fn the_switcher_switches_on_release_so_its_opener_stays_shut(cx: &mut TestAppCon .expect("a managed window"); }); settle(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); press("enter", cx); assert!(desk.read_with(cx, |desk, _| desk.open)); let above = desk.read_with(cx, |desk, _| desk.enters_above); diff --git a/src/shell/windows.rs b/src/shell/windows.rs index ac48c0f..b69ae4f 100644 --- a/src/shell/windows.rs +++ b/src/shell/windows.rs @@ -77,7 +77,7 @@ pub fn open_hosted( }; let handle = cx.open_window(options, |window, cx| { let focus = cx.focus_handle(); - window.focus(&focus); + window.focus(&focus, cx); cx.new(|_| Hosted::new(content, focus)) })?; log::info!("window: opened {title}"); diff --git a/src/tables/grid.rs b/src/tables/grid.rs index b3f14a6..0687d21 100644 --- a/src/tables/grid.rs +++ b/src/tables/grid.rs @@ -79,7 +79,7 @@ pub(crate) fn grid(face: Face, base: Div, window: &mut Window, cx: &mut App) -> } if sheet.read(cx).editing && editor.read(cx).field().is_none() { sheet.update(cx, |sheet, _| sheet.editing = false); - window.focus(&focus); + window.focus(&focus, cx); } let theme = cx.theme(); let colors = theme.colors.clone(); @@ -356,7 +356,7 @@ pub(crate) fn grid(face: Face, base: Div, window: &mut Window, cx: &mut App) -> return; }; let cell = land(&merges, cell); - window.focus(&focus_on_press); + window.focus(&focus_on_press, cx); pressed.update(cx, |sheet, cx| { sheet.cursor = cell; if !event.modifiers.shift { diff --git a/src/tables/table.rs b/src/tables/table.rs index 97f4f5d..36dc5c0 100644 --- a/src/tables/table.rs +++ b/src/tables/table.rs @@ -408,7 +408,7 @@ impl RenderOnce for DataTable { .map(|at| drawn.line(at, &cols, true, window, cx)) .collect() }) - .track_scroll(scroll) + .track_scroll(&scroll) .flex_1() .min_h_0(), )) diff --git a/src/tables/tests/columns.rs b/src/tables/tests/columns.rs index 1d70256..a35f56d 100644 --- a/src/tables/tests/columns.rs +++ b/src/tables/tests/columns.rs @@ -103,7 +103,7 @@ fn tab_reaches_a_header_and_enter_sorts_by_it(cx: &mut TestAppContext) { let (_, cx) = cx.add_window_view(|_, _| Sorting(seen)); cx.update(|window, _| window.activate_window()); settle(cx); - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); cx.simulate_keystrokes("enter"); settle(cx); cx.simulate_event(KeyUpEvent { @@ -141,7 +141,7 @@ fn a_focused_header_past_the_edge_scrolls_into_view(cx: &mut TestAppContext) { cx.update(|window, _| window.activate_window()); settle(cx); for _ in 0..5 { - cx.update(|window, _| window.focus_next()); + cx.update(|window, cx| window.focus_next(cx)); } settle(cx); edit_at(point(px(270.0), px(54.0)), "x", cx); diff --git a/src/tables/tests/mod.rs b/src/tables/tests/mod.rs index 36d6b82..84f0d4b 100644 --- a/src/tables/tests/mod.rs +++ b/src/tables/tests/mod.rs @@ -117,7 +117,11 @@ impl Render for Grouped { ) }) .collect(); - crate::primitives::Measure::new("measure", move |bounds, _, _| tall.set(bounds.size.height)) + // gpui fills the window with an auto-sized root, so the measured box sits inside one. + div().child( + crate::primitives::Measure::new("measure", move |bounds, _, _| { + tall.set(bounds.size.height) + }) .w(px(400.0)) .child( DataTable::new( @@ -126,7 +130,8 @@ impl Render for Grouped { ) .rows(rows) .group_by("region"), - ) + ), + ) } } diff --git a/src/terminal/logs.rs b/src/terminal/logs.rs index f7093a7..41aab75 100644 --- a/src/terminal/logs.rs +++ b/src/terminal/logs.rs @@ -228,7 +228,7 @@ impl RenderOnce for LogViewer { .collect() }, ) - .track_scroll(scroll) + .track_scroll(&scroll) .size_full(); div() .size_full() diff --git a/src/terminal/paint.rs b/src/terminal/paint.rs index 5db8749..865d455 100644 --- a/src/terminal/paint.rs +++ b/src/terminal/paint.rs @@ -3,8 +3,8 @@ use std::{ops::Range, rc::Rc}; use alacritty_terminal::vte::ansi::CursorShape; use gpui::{ BorderStyle, Bounds, ElementInputHandler, Entity, Font, FontStyle, FontWeight, Hsla, - IntoElement, Pixels, Size, StrikethroughStyle, Styled, TextRun, UnderlineStyle, canvas, fill, - outline, point, size, + IntoElement, Pixels, Size, StrikethroughStyle, Styled, TextAlign, TextRun, UnderlineStyle, + canvas, fill, outline, point, size, }; use super::{ @@ -101,7 +101,7 @@ pub(crate) fn grid( Some(cell.width), ); shaped - .paint_background(at(ix, 0), cell.height, window, cx) + .paint_background(at(ix, 0), cell.height, TextAlign::Left, None, window, cx) .expect("a terminal row's ground paints"); for (_, columns, why) in frame.lit.iter().filter(|(row, ..)| *row == ix) { let wash = match why { @@ -113,7 +113,7 @@ pub(crate) fn grid( window.paint_quad(fill(Bounds::new(at(ix, columns.start), extent), wash)); } shaped - .paint(at(ix, 0), cell.height, window, cx) + .paint(at(ix, 0), cell.height, TextAlign::Left, None, window, cx) .expect("a terminal row paints"); for (column, cluster, style) in &row.clusters { let run = TextRun { @@ -127,7 +127,14 @@ pub(crate) fn grid( window .text_system() .shape_line(cluster.clone().into(), look.size, &[run], None) - .paint(at(ix, *column), cell.height, window, cx) + .paint( + at(ix, *column), + cell.height, + TextAlign::Left, + None, + window, + cx, + ) .expect("a terminal cluster paints"); } } diff --git a/src/terminal/tests.rs b/src/terminal/tests.rs index 41cc45e..c3e3dac 100644 --- a/src/terminal/tests.rs +++ b/src/terminal/tests.rs @@ -54,7 +54,7 @@ fn find_counts_matches_and_steps_round(cx: &mut TestAppContext) { fn tab_reaches_the_terminal(cx: &mut TestAppContext) { let (terminal, cx) = replayed(b"ok", cx); let focused = cx.update(|window, cx| { - window.focus_next(); + window.focus_next(cx); terminal.read(cx).focus.is_focused(window) }); assert!(focused); diff --git a/src/theme/mod.rs b/src/theme/mod.rs index 3e750e3..cd05b26 100644 --- a/src/theme/mod.rs +++ b/src/theme/mod.rs @@ -205,12 +205,12 @@ impl Theme { theme.colors = from.mix(&to, motion::ease_in_out_cubic(t)); cx.refresh_windows(); t < 1.0 - })?; + }); if !running { - return anyhow::Ok(()); + return; } } }) - .detach_and_log_err(cx); + .detach(); } } diff --git a/src/theme/tokens.rs b/src/theme/tokens.rs index cb2cede..b4b700b 100644 --- a/src/theme/tokens.rs +++ b/src/theme/tokens.rs @@ -491,10 +491,5 @@ impl Theme { } fn shadow(color: Hsla, y: f32, blur: f32) -> BoxShadow { - BoxShadow { - color, - offset: point(px(0.0), px(y)), - blur_radius: px(blur), - spread_radius: px(0.0), - } + BoxShadow::new(px(0.0), px(y), color).blur_radius(px(blur)) } diff --git a/src/tooling/events.rs b/src/tooling/events.rs index f15332f..2121bef 100644 --- a/src/tooling/events.rs +++ b/src/tooling/events.rs @@ -7,9 +7,9 @@ use std::{ use gpui::{ AnyElement, App, DispatchPhase, ElementId, InteractiveElement, IntoElement, KeyContext, - Modifiers, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, - Point, RenderOnce, ScrollDelta, ScrollWheelEvent, StatefulInteractiveElement, Styled, Window, - canvas, div, prelude::FluentBuilder, + Keystroke, Modifiers, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, ParentElement, + Pixels, Point, RenderOnce, ScrollDelta, ScrollWheelEvent, StatefulInteractiveElement, Styled, + Window, canvas, div, prelude::FluentBuilder, }; use smallvec::SmallVec; @@ -43,6 +43,12 @@ fn button(button: MouseButton) -> String { format!("{button:?}").to_lowercase() } +/// The key gpui makes of a modifier pressed and released alone; the log shows it as modifiers. +fn lone_modifier(keystroke: &Keystroke) -> bool { + let names = ["shift", "control", "alt", "platform", "function"]; + !keystroke.modifiers.modified() && names.contains(&keystroke.key.as_str()) +} + impl fmt::Display for Seen { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { @@ -158,7 +164,7 @@ impl RenderOnce for EventLogger { .context_stack .iter() .any(|context| context.get("logger").is_some_and(|logger| *logger == mark)); - if inside { + if inside && !lone_modifier(&event.keystroke) { down(Seen::KeyDown(event.keystroke.unparse()), cx) } }) diff --git a/src/tooling/inspector.rs b/src/tooling/inspector.rs index 13cb27c..35e7a66 100644 --- a/src/tooling/inspector.rs +++ b/src/tooling/inspector.rs @@ -3,8 +3,8 @@ use std::fmt; use gpui::{ AbsoluteLength, AnyElement, App, BorderStyle, Bounds, Context, Corners, DefiniteLength, DivInspectorState, Edges, FontWeight, Inspector, InteractiveElement, IntoElement, Length, - ParentElement, Pixels, StatefulInteractiveElement, StyleRefinement, Styled, TextRun, Window, - canvas, div, fill, point, quad, size, transparent_black, + ParentElement, Pixels, StatefulInteractiveElement, StyleRefinement, Styled, TextAlign, TextRun, + Window, canvas, div, fill, point, quad, size, transparent_black, }; use crate::{ @@ -156,7 +156,14 @@ fn paint_layers(bounds: Bounds, layers: Layers, window: &mut Window, cx: ); let radius = theme.radius(Radius::Sm).to_pixels(window.rem_size()); window.paint_quad(fill(tag, colors.fg).corner_radii(radius)); - if let Err(error) = line.paint(point(tag.left() + pad, tag.top()), height, window, cx) { + if let Err(error) = line.paint( + point(tag.left() + pad, tag.top()), + height, + TextAlign::Left, + None, + window, + cx, + ) { log::error!("inspector: size tag did not paint: {error:#}"); } } @@ -380,8 +387,10 @@ fn panel( /// Draws gpui's inspector, which debug builds have, in Ely's look. `window.toggle_inspector` opens it at the window's right, and the page gives up its width. Hovering picks the box under the pointer, the wheel steps out to the boxes around it, and a press holds it; the picked box shows its margin, border, padding and size over the page, and its model in the panel. pub fn install_inspector(cx: &mut App) { cx.set_inspector_renderer(Box::new(panel)); - cx.register_inspector_element(|_, state: &DivInspectorState, window, cx| { - box_model(state, window, cx) + cx.register_inspector_element(|_, _| { + |_, state: &DivInspectorState, window: &mut Window, cx: &mut App| { + box_model(state, window, cx) + } }); log::info!("inspector: installed"); } diff --git a/src/tooling/tests/inspection.rs b/src/tooling/tests/inspection.rs index 82d3d19..0813fb6 100644 --- a/src/tooling/tests/inspection.rs +++ b/src/tooling/tests/inspection.rs @@ -120,7 +120,7 @@ fn tab_passes_through_the_panel(cx: &mut TestAppContext) { ) }); cx.update(|window, cx| { - window.focus(&root); + window.focus(&root, cx); window.toggle_inspector(cx); }); cx.run_until_parked(); @@ -227,7 +227,7 @@ fn the_logger_lists_events(cx: &mut TestAppContext) { field: cx.new(|cx| TextInput::new(window, cx)), }); let target = view.read_with(cx, |logged, _| logged.target.clone()); - cx.update(|window, _| window.focus(&target)); + cx.update(|window, cx| window.focus(&target, cx)); cx.run_until_parked(); assert!(shown("event-logger-empty", cx)); cx.simulate_mouse_move(point(px(20.0), px(20.0)), None, Modifiers::none()); @@ -257,10 +257,16 @@ fn the_logger_lists_events(cx: &mut TestAppContext) { assert!(shown("event-key up a", cx)); cx.simulate_modifiers_change(Modifiers::shift()); assert!(shown("event-modifiers shift", cx)); + cx.simulate_modifiers_change(Modifiers::none()); + assert!(shown("event-modifiers none", cx)); + assert!( + !shown("event-key down shift", cx), + "a lone modifier is no key" + ); let (field, root) = view.read_with(cx, |logged, cx| { (logged.field.focus_handle(cx), logged.root.clone()) }); - cx.update(|window, _| window.focus(&field)); + cx.update(|window, cx| window.focus(&field, cx)); for key in ["b", "c", "backspace", "left", "enter"] { press(key, cx); } @@ -273,7 +279,7 @@ fn the_logger_lists_events(cx: &mut TestAppContext) { ] { assert!(shown(row, cx), "{row}: a key the field's bindings take"); } - cx.update(|window, _| window.focus(&root)); + cx.update(|window, cx| window.focus(&root, cx)); press("z", cx); assert!( !shown("event-key down z", cx), diff --git a/src/tooling/tests/mod.rs b/src/tooling/tests/mod.rs index 6881ed9..3f5038d 100644 --- a/src/tooling/tests/mod.rs +++ b/src/tooling/tests/mod.rs @@ -93,7 +93,7 @@ fn knobs_redraw_the_preview(cx: &mut TestAppContext) { root: cx.focus_handle(), }); let root = view.read_with(cx, |stage, _| stage.root.clone()); - cx.update(|window, _| window.focus(&root)); + cx.update(|window, cx| window.focus(&root, cx)); settle(cx); let shown = |selector: &'static str, cx: &mut VisualTestContext| cx.debug_bounds(selector).is_some(); diff --git a/src/typography/fit.rs b/src/typography/fit.rs index 2c37a69..0dc48df 100644 --- a/src/typography/fit.rs +++ b/src/typography/fit.rs @@ -128,7 +128,14 @@ fn cut_line(text: SharedString, fit: fn(&str, Pixels, &mut Window) -> String) -> let line = style.line_height_in_pixels(window.rem_size()); let x = offset(style.text_align, bounds.size.width - shaped.width); shaped - .paint(bounds.origin + point(x, Pixels::ZERO), line, window, cx) + .paint( + bounds.origin + point(x, Pixels::ZERO), + line, + TextAlign::Left, + None, + window, + cx, + ) .expect("a cut line paints"); }, ) diff --git a/src/typography/formatted.rs b/src/typography/formatted.rs index a75738f..0f03ef3 100644 --- a/src/typography/formatted.rs +++ b/src/typography/formatted.rs @@ -187,7 +187,8 @@ pub(crate) fn fresh(id: impl Into, window: &mut Window, cx: &mut App) cx.spawn_in(window, async move |ticker, cx| { loop { cx.background_executor().timer(TICK).await; - if ticker.update(cx, |_, cx| cx.notify()).is_err() { + let ticked = cx.update(|_, cx| ticker.update(cx, |_, cx| cx.notify())); + if ticked.and_then(|inner| inner).is_err() { return; } } diff --git a/src/typography/select.rs b/src/typography/select.rs index 8f6897b..8d06537 100644 --- a/src/typography/select.rs +++ b/src/typography/select.rs @@ -82,7 +82,7 @@ impl RenderOnce for SelectableText { .on_mouse_down(MouseButton::Left, move |event, window, cx| { let ix = index_at(&down_layout, event.position); down.update(cx, |selection, cx| { - window.focus(&selection.focus); + window.focus(&selection.focus, cx); if !event.modifiers.shift { selection.anchor = ix; } diff --git a/src/typography/text.rs b/src/typography/text.rs index 7aaa6d7..04b2037 100644 --- a/src/typography/text.rs +++ b/src/typography/text.rs @@ -10,20 +10,14 @@ use crate::theme::{ActiveTheme, Palette, TextSize}; /// Tabular numerals, so digits line up in columns. pub fn tabular(mut element: E) -> E { let features = FontFeatures(Arc::new(vec![("tnum".into(), 1)])); - element - .text_style() - .get_or_insert_with(Default::default) - .font_features = Some(features); + element.text_style().font_features = Some(features); element } /// Each character drawn as itself, without ligatures: `==` stays two signs in encoded text and keys. pub fn literal(mut element: E) -> E { let features = FontFeatures(Arc::new(vec![("calt".into(), 0), ("liga".into(), 0)])); - element - .text_style() - .get_or_insert_with(Default::default) - .font_features = Some(features); + element.text_style().font_features = Some(features); element }