Follow-up to #24797
This PR ensures some cursor styles do not change for draggable elements
during dragging. The linked PR covered this on the higher level for
draggable divs. However, e.g. the pane divider inbetween two editors is
not a draggable div and thus still has the issue that the cursor style
changes during dragging. This PR fixes this issue by setting the hitbox
to `None` in cases where the element is currently being dragged, which
ensures the cursor style is applied to the cursor no matter what during
dragging.
Namely, this change fixes this for
- non-div pane dividers
- minimap slider and the
- editor scrollbars
and implements it for the UI scrollbars (Notably, UI scrollbars do
already have `cursor_default` on their parent container but would not
keep this during dragging. I opted out on removing this from the parent
containers until #30194 or a similar PR is merged).
https://github.com/user-attachments/assets/f97859dd-5f1d-4449-ab92-c27f2d933c4a
Release Notes:
- N/A
Allows setting element as window control elements which consist of
`Drag`, `Close`, `Max`, or `Min`. This allows you to implement
dynamically sized elements that control the platform window, this is
used for areas such as the title bar. Currently only implemented for
Windows.
Release Notes:
- N/A
Release Notes:
- N/A
---
This change is used to solve the problem of not being able to respond
correctly in two-layer scrolling (in different directions). This is a
common practical requirement.
As in the example, in actual use, there may be a scene with a horizontal
scroll in a vertical scroll. Before the modification, if we scroll up
and down in the area that can scroll horizontally, it will not respond
(because it is blocked by the horizontal scroll layer).
## Before
https://github.com/user-attachments/assets/e8ea0118-52a5-44d8-b419-639d4b6c0793
## After
https://github.com/user-attachments/assets/aa14ddd7-5596-4dc5-9c6e-278aabdfef8e
----
This change may cause many side effects, causing some scrolling details
to be different from before, and more testing and analysis are needed.
I have tested some existing scenarios of Zed (such as opening the Branch
panel on the Editor and scrolling) and it seems to be correct (but it is
possible that I don’t know some interaction details). Here, the person
who added this line of code before needs to evaluate the original
purpose.
This method was added in #20649 to be an alternative of `occlude` which
allows scroll events. It seems a bit arbitrary to only stop left mouse
downs, so this seems like it's probably an improvement.
Release Notes:
- N/A
tl;dr: This adds `.block_mouse_except_scroll()` which should typically
be used instead of `.occlude()` for cases when the mouse shouldn't
interact with elements drawn below an element. The rationale for
treating scroll events differently:
* Mouse move / click / styles / tooltips are for elements the user is
interacting with directly.
* Mouse scroll events are about finding the current outer scroll
container.
Most use of `occlude` should probably be switched to this, but I figured
I'd derisk this change by minimizing behavior changes to just the 3 uses
of `block_mouse_except_scroll`.
GPUI changes:
* Added `InteractiveElement::block_mouse_except_scroll()`, and removes
`stop_mouse_events_except_scroll()`
* Added `Hitbox::should_handle_scroll()` to be used when handling scroll
wheel events.
* `Window::insert_hitbox` now takes `HitboxBehavior` instead of
`occlude: bool`.
- `false` for that bool is now `HitboxBehavior::Normal`.
- `true` for that bool is now `HitboxBehavior::BlockMouse`.
- The new mode is `HitboxBehavior::BlockMouseExceptScroll`.
* Removes `Default` impl for `HitboxId` since applications should not
manually create `HitboxId(0)`.
Release Notes:
- N/A
Open inspector with `dev: toggle inspector` from command palette or
`cmd-alt-i` on mac or `ctrl-alt-i` on linux.
https://github.com/user-attachments/assets/54c43034-d40b-414e-ba9b-190bed2e6d2f
* Picking of elements via the mouse, with scroll wheel to inspect
occluded elements.
* Temporary manipulation of the selected element.
* Layout info and JSON-based style manipulation for `Div`.
* Navigation to code that constructed the element.
Big thanks to @as-cii and @maxdeviant for sorting out how to implement
the core of an inspector.
Release Notes:
- N/A
---------
Co-authored-by: Antonio Scandurra <me@as-cii.com>
Co-authored-by: Marshall Bowers <git@maxdeviant.com>
Co-authored-by: Federico Dionisi <code@fdionisi.me>
https://github.com/zed-industries/zed/issues/30972 brought up another
case where our context is not enough to track the actual source of the
issue: we get a general top-level error without inner error.
The reason for this was `.ok_or_else(|| anyhow!("failed to read HEAD
SHA"))?; ` on the top level.
The PR finally reworks the way we use anyhow to reduce such issues (or
at least make it simpler to bubble them up later in a fix).
On top of that, uses a few more anyhow methods for better readability.
* `.ok_or_else(|| anyhow!("..."))`, `map_err` and other similar error
conversion/option reporting cases are replaced with `context` and
`with_context` calls
* in addition to that, various `anyhow!("failed to do ...")` are
stripped with `.context("Doing ...")` messages instead to remove the
parasitic `failed to` text
* `anyhow::ensure!` is used instead of `if ... { return Err(...); }`
calls
* `anyhow::bail!` is used instead of `return Err(anyhow!(...));`
Release Notes:
- N/A
This is a dumb first pass at a standard text example. We'll use this to
start digging in to some text/scale rendering issues.
There will be a ton of follow-up features to this, but starting simple.
Release Notes:
- N/A
Closes https://github.com/zed-industries/zed/issues/23386
This PR updates the scrollbar-component to account for padding present
in the parent container.
Since the linked issue was opened,
https://github.com/zed-industries/zed/pull/25288 improved the behaviour
so that the scrollbar does allow scrolling the entire container, however
the scrollbar thumb still does not go the entire way to the bottom. This
can be seen here:
https://github.com/user-attachments/assets/89204355-e6b8-428b-9fa9-bb614051b6fa
This happens because during layouting of the scrollbar, padding of the
parent container is not taken into account. The scrollbar thumb size is
calculated as if no padding was present.
With this change, padding is now included in the calculation, which
resolves the issue:
https://github.com/user-attachments/assets/1d4c62e0-4555-4332-a9ab-4e114684b4b3
The change here is to store the calculated content size during prepaint
_including_ padding and use this for layouting the scrollbar. This
ensures that the actual scroll max and the content size are always in
sync. Furthermore, the existing `TODO`-comment is also resolved, as we
now no longer look at the size of the last child but the actual parent
size instead.
This also removes an existing panic of the scrollbar-component in cases
where the content size was 0, which was previously not accounted for
(this never happened in practice so far, for example because of the
padding added here:
https://github.com/zed-industries/zed/blob/43712285bfa8aa75bac1ca8a7eb5146dd36239be/crates/editor/src/hover_popover.rs#L802-L809
which prevented the container size from ever being 0).
---
Lastly, as I was wiring through the changes of the `content_size` I
noticed that some code was duplicated during the initial layouting as
well as in the click handlers. I refactored this in the second commit to
use `along` where possible as well as computing the new click offset in
one closure which can be passed to both event listeners. As always,
should any of these changes not be wanted, feel free to let me know and
I will revert these.
Looking forward to your feedback 😄
Release Notes:
- Fixed scrollbars sometimes not scrolling all the way to the bottom.
This is similar to the `block_mouse_down` method added in #20649 (which
has a very similar motivation), but is more comprehensive in stopping
mouse events. Since I want to cherry-pick this to the releases, keeping
this change just to the agent panel. In a follow-up will replace
existing use of `block_mouse_down` to instead use this.
Release Notes:
- N/A
This PR fixes several possible memory leaks due to loading images in
markdown files and the image viewer, using the new image cache APIs
TODO:
- [x] Ensure this didn't break rendering in any of the affected
components.
Release Notes:
- Fixed several image related memory leaks
cc: @sunli829 @huacnlee @probably-neb
I really liked the earlier PR, but had an idea for how to utilize the
element state so that you don't need to construct the cache externally.
I've updated the APIs to introduce an `ImageCacheProvider` trait, and
added an example implementation of it to the image gallery :)
Release Notes:
- N/A
Closes#27414
`ImageCache` is independent of the original image loader and can
actively release its cached images to solve the problem of images loaded
from the network or files not being released.
It has two constructors:
- `ImageCache::new`: Manually manage the cache.
- `ImageCache::max_items`: Remove the least recently used items when the
cache reaches the specified number.
When creating an `img` element, you can specify the cache object with
`Img::cache`, and the image cache will be managed by `ImageCache`.
In the example `crates\gpui\examples\image-gallery.rs`, the
`ImageCache::clear` method is actively called when switching a set of
images, and the memory will no longer continuously increase.
Release Notes:
- N/A
---------
Co-authored-by: Ben Kunkle <ben@zed.dev>
Earlier, I merged #24723
Before merging it, I made a change that was incorrect and fast followed
with a fix: #28548
Following that fix, @bennetbo discovered that the modals where no longer
highlighting correctly, particularly the outline modal.
So I'm going to revert it all.
Release Notes:
- N/A
Release Notes:
- N/A
---
Fix this long-standing issue so that we can support Link hover colors.
And renamed `text_layout` example to `text_style`.
---
I spent some time studying the process of this text style change and
found it a bit complicated.
At first, I thought there was a problem with refine and it was not
passed properly. After changing it, I found that it was not the problem.
Then I found that it was because `TextRun` had already stored the
`color`, `background`, `underline`, `strikethrough` in TextRun in the
`request_layout` stage. They area calculate at the `request_layout`
stage, but request_layout stage there was no `hitbox`, so the hover
state was not obtained.
```bash
cargo run -p gpui --example text_style
```
https://github.com/user-attachments/assets/24f88f73-775e-41d3-a502-75a7a39ac82b
---------
Co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com>
Swift bindings BEGONE
Release Notes:
- Switched from using the Swift LiveKit bindings, to the Rust bindings,
fixing https://github.com/zed-industries/zed/issues/9396, a crash when
leaving a collaboration session, and making Zed easier to build.
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Co-authored-by: Michael Sloan <michael@zed.dev>
This required adding scrollbar support to `list`. Since `list` is
virtualized, the scrollbar height will change as more items are
measured. When the user manually drags the scrollbar, we'll persist the
initial height and offset calculations accordingly to prevent the
scrollbar from moving away from the cursor as new items are measured.
We're not doing this yet, but in the future, it'd be nice to budget some
time each frame to layout unmeasured items so that the scrollbar height
is as accurate as possible.
Release Notes:
- N/A
Closes#4461
Take 2 on https://github.com/zed-industries/zed/pull/25040.
Fixes panic caused due to using `setHiddenUntilMouseMoves` return type
to `set` cursor on macOS.
Release Notes:
- Now cursor hides when the user is typing in editor. It will stay
hidden until it is moved again. This behavior is `true` by default, and
can be configured with `hide_mouse_while_typing` in settings.
---------
Co-authored-by: Peter Tripp <peter@zed.dev>
Co-authored-by: Thomas Mickley-Doyle <thomas@zed.dev>
Co-authored-by: Agus <agus@zed.dev>
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
Co-authored-by: Agus Zubiaga <hi@aguz.me>
Co-authored-by: Angelk90 <angelo.k90@hotmail.it>
This seems more correct as corners are not necessarily only for rounding
radii.
Also applies clamping after scaling in `paint_quad`, deduplicating that
logic. This also provides a more precise result by doing the clamping
after scaling, avoiding floating point rounding issues (probably a
non-issue).
Release Notes:
- N/A
Since `TextLayout` is not shared by multiple threads, changing it to
`Rc<RefCell<T>>` should improve performance.
I also found several codes with the same problem. If you think this
change is beneficial, I will continue to improve it in the subsequent
PR. 🙂
Release Notes:
- N/A
Closes#25671
Release Notes:
- Added support for `claude-3-7-sonnet-thinking` in the assistant panel
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Co-authored-by: Antonio Scandurra <me@as-cii.com>
Co-authored-by: Agus Zubiaga <hi@aguz.me>
This is the core change:
https://github.com/zed-industries/zed/pull/26758/files#diff-044302c0d57147af17e68a0009fee3e8dcdfb4f32c27a915e70cfa80e987f765R1052
TODO:
- [x] Use AsyncFn instead of Fn() -> Future in GPUI spawn methods
- [x] Implement it in the whole app
- [x] Implement it in the debugger
- [x] Glance at the RPC crate, and see if those box future methods can
be switched over. Answer: It can't directly, as you can't make an
AsyncFn* into a trait object. There's ways around that, but they're all
more complex than just keeping the code as is.
- [ ] Fix platform specific code
Release Notes:
- N/A
Release Notes:
- Improved performance when using the scroll wheel and some other mouse
interactions.
Based on some cache details about GPUI `AnyView::cached` that I found in
the discussion of
https://github.com/zed-industries/zed/discussions/24260#discussioncomment-12135749,
and combined with the optimization points found in actual applications.
This change may have some scenarios that I have not considered, so I
just make a draft to put forward my ideas first for discussion.
From my analysis, `AnyView::cached` will always invalid by Div's mouse
events, because of it called `window.refresh`. I understand that (mouse
move event) this is because the interface changes related to hover and
mouse_move will be affected style, so `window.refresh` is required.
Since Div does not have the `entity_id` of View, it is impossible to
know which View should be refreshed, so the entire window can only be
refreshed.
With this change, we can reduce a lot of `render` method calls on
ScrollWheel or Mouse Event.
Previously, if a user clicked a button and moved the cursor out before
releasing, the click event was correctly prevented, but the pending
mouse-down state remained.
This caused unintended drags when the UI shifted due to magnification
settings.
Now, mouse-up clears the pending state:
- If over the button → clear state and trigger click handlers.
- If outside the button → clear state without triggering a click.
This avoids accidental drags while preserving expected click behavior.
Closes#24600
Release Notes:
- N/A
---------
Co-authored-by: Ben Kunkle <ben@zed.dev>
https://github.com/user-attachments/assets/b16e32e6-46c6-41dc-ab68-1824d288c8c2
This PR adds the first part of our planned extended notification system:
StatusToasts.
It also makes various updates to ComponentPreview and adds a `Styled`
extension in `ui::style::animation` to make it easier to animate styled
elements.
_**Note**: We will be very, very selective with what elements are
allowed to be animated in Zed. Assume PRs adding animation to elements
will all need to be manually signed off on by a designer._
## Status Toast

These are designed to be used for notifying about things that don't
require an action to be taken or don't need to be triaged. They are
designed to be ignorable, and dismiss themselves automatically after a
set time.
They can optionally include a single action.
Example: When the user enables Vim Mode, that action might let them undo
enabling it.

Status Toasts should _not_ be used when an action is required, or for
any binary choice.
If the user must provide some input, this isn't the right component!
### Out of scope
- Toasts should fade over a short time (like AnimationDuration::Fast or
Instant) when dismissed
- We should visually show when the toast will dismiss. We'll need to
pipe the `duration_remaining` from the toast layer -> ActiveToast to do
this.
- Dismiss any active toast if another notification kind is created, like
a Notification or Alert.
Release Notes:
- N/A
---------
Co-authored-by: Cole Miller <m@cole-miller.net>
Currently, when an element has only a hover listener, the attached
listener will never trigger, because within the check for whether a
hitbox has to be inserted for the given element, this case it not
considered.
That leads to the behaviour as described in
https://github.com/zed-industries/zed/pull/25602#discussion_r1970720972,
where another event listener has to be attached to the element in order
for the hover listener to work.
This PR fixes the issue by ensuring that a hitbox is also inserted when
only a hover listener is attached to the element.
Release Notes:
- N/A
This PR adds a new `restrict_scroll_to_axis` style to allow consumers to
opt-in to the scrolling behavior found on the web.
When this is enabled the behavior will be such that:
- Scrolling using the mouse wheel will only scroll the Y axis
- Scrolling using the mouse wheel with <kbd>Shift</kbd> held will only
scroll the X axis
This behavior is useful in scenarios where you have some
vertically-scrollable content that is interspersed with
horizontally-scrollable elements, as otherwise the scroll will be
constantly hijacked by the horizontally-scrollable elements while trying
to scroll up and down in the vertically-scrollable container.
I think that this behavior should be the default, but it's a bit of a
sweeping change to make all at once, so for now it remains opt-in.
Release Notes:
- N/A
This PR adds toasts for reporting success and errors from remote git
operations. This PR also adds a focus handle to notifications, in
anticipation of making them keyboard accessible.
Release Notes:
- N/A
---------
Co-authored-by: julia <julia@zed.dev>
Regression in #22644
Unfortunately not a full fix, In the case where a tooltip gets displayed
and then gets occluded after display, it will stick around until the
mouse exits the hover bounds.
Release Notes:
- N/A
Co-authored-by: Ben <ben@zed.dev>
Chatted with @as-cii about limitations in the `Window::parent_view_id()`
API (see:
https://github.com/zed-industries/zed/pull/24182/commits/662153dcfdd80804f4041761c09c4a309d79f6d4)
and realized that I shouldn't be using the dispatch tree's data
structures as they are layout dependent. I've introduced a new stack to
`Window`, `rendered_entity_stack`, that tracks exactly which view's
elements are being drawn. As such, I've also been able to remove the
`Option<>` around the previous API.
Release Notes:
- N/A
Adds a text property for controlling left, center, or right text
alignment.
#8792 should stay open since this doesn't add support for `justify`
(which would require a much bigger change since this can just alter the
origin of each line, but justify requires changing spacing, whereas
justify requires changes to each platform's shaping code).
Release Notes:
- N/A
This PR updates function signatures, docstrings, and gpui's other
documentation to reflect it's new state following the merge of `Model`
and `View` into `Entity` as well as the removal of `WindowContext`.
Release Notes:
- N/A