This puts the Linux platform implementation at a similar code style and
quality to the macOS platform. The largest change is that I collapsed
the `LinuxPlatform` -> `[Backend]` -> `[Backend]State` ->
`[Backend]StateInner` to just `[Backend]` and `[Backend]State`, and in
the process removed most of the `Rc`s and `RefCell`s.
TODO:
- [x] Make sure that this is on-par with the existing implementation
- [x] Review in detail, now that the large changes are done.
- [ ] Update the roadmap
Release Notes:
- N/A
Refs #9647
Fixes https://github.com/zed-industries/zed/issues/9792
This pull request moves the computation of scrollbar markers off the
main thread, to prevent them from grinding the editor to a halt when we
have a lot of them (e.g., when there are lots of search results on a
large file). With these changes we also avoid generating multiple quads
for adjacent markers, thus fixing an issue where we stop drawing other
primitives because we've drawn too many quads in the scrollbar.
Release Notes:
- Improved editor performance when displaying lots of search results,
diagnostics, or symbol highlights in the scrollbar
([#9792](https://github.com/zed-industries/zed/issues/9792)).
---------
Co-authored-by: Antonio Scandurra <me@as-cii.com>
Co-authored-by: Nathan <nathan@zed.dev>
Sharing a project displays a notification (window) on every screen.
Previously there was an issue with the positioning of windows on all
screens except the primary screen.
As you can see here:

Now:

@mikayla-maki and I also decided to refactor the `WindowOptions` a bit.
Previously you could specify bounds which controlled the positioning and
size of the window in the global coordinate space, while also providing
a display id (which screen to show the window on). This can lead to
unusual behavior because you could theoretically specify a global bound
which does not even belong to the display id which was provided.
Therefore we changed the api to this:
```rust
struct WindowOptions {
/// The bounds of the window in screen coordinates
/// None -> inherit, Some(bounds) -> set bounds.
pub bounds: Option<Bounds<DevicePixels>>,
/// The display to create the window on, if this is None,
/// the window will be created on the main display
pub display_id: Option<DisplayId>,
}
```
This lets you specify a display id, which maps to the screen where the
window should be created and bounds relative to the upper left of the
screen.
Release Notes:
- Fixed positioning of popup windows (e.g. when sharing a project) when
using multiple external displays.
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This pull request introduces a new `InlineCompletionProvider` trait,
which enables making `Editor` copilot-agnostic and lets us push all the
copilot functionality into the `copilot_ui` module. Long-term, I would
like to merge `copilot` and `copilot_ui`, but right now `project`
depends on `copilot`, which makes this impossible.
The reason for adding this new trait is so that we can experiment with
other inline completion providers and swap them at runtime using config
settings.
Please, note also that we renamed some of the existing copilot actions
to be more agnostic (see release notes below). We still kept the old
actions bound for backwards-compatibility, but we should probably remove
them at some later version.
Also, as a drive-by, we added new methods to the `Global` trait that let
you read or mutate a global directly, e.g.:
```rs
MyGlobal::update(cx, |global, cx| {
});
```
Release Notes:
- Renamed the `copilot::Suggest` action to
`editor::ShowInlineCompletion`
- Renamed the `copilot::NextSuggestion` action to
`editor::NextInlineCompletion`
- Renamed the `copilot::PreviousSuggestion` action to
`editor::PreviousInlineCompletion`
- Renamed the `editor::AcceptPartialCopilotSuggestion` action to
`editor::AcceptPartialInlineCompletion`
---------
Co-authored-by: Nathan <nathan@zed.dev>
Co-authored-by: Kyle <kylek@zed.dev>
Co-authored-by: Kyle Kelley <rgbkrk@gmail.com>
Separate from #9451
On Windows, a new window may already active immediate after creation.
Release Notes:
- N/A
---------
Co-authored-by: Mikayla <mikayla@zed.dev>
This PR adds support for handling action releases — events that
are fired when the user releases all the modifier keys that were part of
an action-triggering shortcut.
If the user holds modifiers and invokes several actions sequentially via
shortcuts (same or different), only the last action is "released" when
its modifier keys released.
~The following methods were added to `Div`:~
- ~`capture_action_release()`~
- ~`on_action_release()`~
- ~`on_boxed_action_release()`~
~They work similarly to `capture_action()`, `on_action()` and
`on_boxed_action()`.~
See the implementation details in [this
comment](https://github.com/zed-industries/zed/pull/8782#issuecomment-2009154646).
Release Notes:
- Added a fast-switch mode to the file finder: hit `p` or `shift-p`
while holding down `cmd` to select a file immediately. (#8258).
Related Issues:
- Implements #8757
- Implements #8258
- Part of #7653
Co-authored-by: @ConradIrwin
This reverts #9053 and #9375 because they introduced a regression on
`main` that broke the titlebars on macOS:

Two things are off:
- Left padding is missing
- Titlebar height is less than it was before, which means the
traffic-light buttons are not centered vertically
What @as-cii and I noticed while looking into this: the `cfg!(macos)`
macros that were used don't work like that. You need to check for
`cfg!(target = "macos")` etc. Means that on macOS we never used the
macOS-specific code because the condition was always false.
Overall height, we're not sure about.
Release Notes:
- N/A
Fixes https://github.com/zed-industries/zed/issues/9340
The flickering was caused by the pane trying to restore focus on a
`FocusHandle` that wasn't being rendered anymore. This commit uses the
new `WeakFocusHandle` to avoid retaining a reference to focus handles
that don't exist anymore.
Release Notes:
- Fixed a bug that caused flickering when interacting with the language
server logs
([#9340](https://github.com/zed-industries/zed/issues/9340)).
Before this change we didn't consistently trigger focus events when
toggling between with windows `Cmd-backtick`. We only triggered them
when the OS decided to trigger a redraw.
That lead to a nasty bug that showed up in Vim mode where a cursor would
still be active in the hidden window, even though it was deactivated.
One then had to manually try to trigger a focus event in the new window
to activate the cursor.
With this change, we call `cx.refresh` when the window activation status
changed which triggers focus events consistently and fixes this bug.
With logging we can observe this:
**BEFORE**:
https://github.com/zed-industries/zed/assets/1185253/e1ad8878-129c-44ba-9d8b-c720f9dca5b6
**AFTER**:
https://github.com/zed-industries/zed/assets/1185253/733fdadb-d1ea-47fe-a2c1-7b50af299cc0
Release Notes:
- Fixed focus not being consistently changed when switching between
multiple Zed windows via `Cmd-backtick`.
---------
Co-authored-by: Manu Raj <git@manuraj.dev>
Co-authored-by: Antonio <antonio@zed.dev>
This PR changes GPUI to open windows with a default size and location,
and to otherwise inherit from their spawning window.
Note: The linux build now crashes on startup.
Release Notes:
- N/A
---------
Co-authored-by: Nathan <nathan@zed.dev>
Co-authored-by: Ezekiel Warren <zaucy@users.noreply.github.com>
See https://zed.dev/channel/gpui-536
Fixes https://github.com/zed-industries/zed/issues/9010
Fixes https://github.com/zed-industries/zed/issues/8883
Fixes https://github.com/zed-industries/zed/issues/8640
Fixes https://github.com/zed-industries/zed/issues/8598
Fixes https://github.com/zed-industries/zed/issues/8579
Fixes https://github.com/zed-industries/zed/issues/8363
Fixes https://github.com/zed-industries/zed/issues/8207
### Problem
After transitioning Zed to GPUI 2, we started noticing that interacting
with the mouse on many UI elements would lead to a pretty annoying
flicker. The main issue with the old approach was that hover state was
calculated based on the previous frame. That is, when computing whether
a given element was hovered in the current frame, we would use
information about the same element in the previous frame.
However, inspecting the previous frame tells us very little about what
should be hovered in the current frame, as elements in the current frame
may have changed significantly.
### Solution
This pull request's main contribution is the introduction of a new
`after_layout` phase when redrawing the window. The key idea is that
we'll give every element a chance to register a hitbox (see
`ElementContext::insert_hitbox`) before painting anything. Then, during
the `paint` phase, elements can determine whether they're the topmost
and draw their hover state accordingly.
We are also removing the ability to give an arbitrary z-index to
elements. Instead, we will follow the much simpler painter's algorithm.
That is, an element that gets painted after will be drawn on top of an
element that got painted earlier. Elements can still escape their
current "stacking context" by using the new `ElementContext::defer_draw`
method (see `Overlay` for an example). Elements drawn using this method
will still be logically considered as being children of their original
parent (for keybinding, focus and cache invalidation purposes) but their
layout and paint passes will be deferred until the currently-drawn
element is done.
With these changes we also reworked geometry batching within the
`Scene`. The new approach uses an AABB tree to determine geometry
occlusion, which allows the GPU to render non-overlapping geometry in
parallel.
### Performance
Performance is slightly better than on `main` even though this new
approach is more correct and we're maintaining an extra data structure
(the AABB tree).

Release Notes:
- Fixed a bug that was causing popovers to flicker.
---------
Co-authored-by: Nathan Sobo <nathan@zed.dev>
Co-authored-by: Thorsten <thorsten@zed.dev>
This adds a GPUI fallback for window prompts. Linux does not support
this feature by default, so we have to implement it ourselves.
This implementation also makes it possible for GPUI clients to override
the platform prompts with their own implementations.
This is just a first pass. These alerts are not keyboard accessible yet,
does not reflect the prompt level, they're implemented in-window, rather
than as popups, and the whole feature need a pass from a designer.
Regardless, this gets us one step closer to Linux support :)
<img width="650" alt="Screenshot 2024-03-06 at 5 58 08 PM"
src="https://github.com/zed-industries/zed/assets/2280405/972ebb55-fd1f-4066-969c-a87f63b22a6f">
Release Notes:
- N/A
This reverts commit 0cebf68306.
Although this thing is very cool, it is a top source of crashes.
Example crash:
```
Segmentation fault: 11 on thread 26
objc_retain +16
invocation function for block in Overlay::onCommandBufferCommit(id<MTLCommandBuffer>) +60
MTLDispatchListApply +52
```
Release Notes:
- Removed "Toggle Graphics Profiler" as it crashes too much.
This uses bounds checking alone to determine hover state to avoid
flicker. It's a short-term solution because the rendering is incorrect.
We think this is better than flickering though and buys us some time as
we work on a more robust solution overall.
Release Notes:
- Fixed flickering when hovering.
---------
Co-authored-by: Nathan <nathan@zed.dev>
[Profiling](https://crates.io/crates/profiling) crate allows easy
integration with various profiler tools. The best thing is - annotations
compile to nothing unless you request a specific feature.
For example, I used this command to enable Tracy support:
```bash
cargo run --features profiling/profile-with-tracy
```
At the same time I had Tracy tool open and waiting for connection. It
gathered nice stats from the run:

Release Notes:
- N/A
Release Notes:
- Added `workspace::SendKeystrokes` to enable mapping from one key to a
sequence of others
([#7033](https://github.com/zed-industries/zed/issues/7033)).
Improves #7033. Big thank you to @ConradIrwin who did most of the heavy
lifting on this one.
This PR allows the user to send multiple keystrokes via custom
keybinding. For example, the following keybinding would go down four
lines and then right four characters.
```json
[
{
"context": "Editor && VimControl && !VimWaiting && !menu",
"bindings": {
"g z": [
"workspace::SendKeystrokes",
"j j j j l l l l"
],
}
}
]
```
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Closes#7973
This fixes a leak in GPUI when the user didn't override
`on_should_close_window`.
Release Notes:
- N/A
---------
Co-authored-by: Thorsten <thorsten@zed.dev>
On macOS, this will enable or disable the Metal HUD at runtime. Note
that this only works when Zed is bundled because it requires to set the
`MetalHudEnabled` key in the Info.plist.
Release Notes:
- Added a new `ToggleGraphicsProfiler` command that can be used as an
action (or via the `Help -> Toggle Graphics Profiler` menu) to
investigate graphics performance.
Release Notes:
- Fixed a bug that caused Zed to render at 60fps even on ProMotion
displays.
- Fixed a bug that could saturate the main thread event loop in certain
circumstances.
---------
Co-authored-by: Thorsten <thorsten@zed.dev>
Co-authored-by: Nathan <nathan@zed.dev>
Co-authored-by: Max <max@zed.dev>
Reverts zed-industries/zed#7481
This would regress performance because we'd be using the standard
library's hash maps everywhere, so reverting for now.
This takes down LLVM IR size of theme_selector from 316k to ~250k. Note
that I do not care about theme_selector in particular, though it acts as
a benchmark for smaller crates to me ("how much static overhead in
compile time does gpui have").
The title is a bit dramatic, so just to shed some light: by leaking a
type I mean forcing downstream crates to codegen it's methods/know about
it's drop code. Since SubscriberSet is no longer used directly in the
generic (==inlineable) methods, users no longer have to codegen `insert`
and co.
Release Notes:
- N/A
This was causing an issue where windows about 1/10 of the way across the
display would hang for a fully second after being deactivated.
Release Notes:
- N/A
Co-authored-by: max <max@zed.dev>
Co-authored-by: nathan <nathan@zed.dev>
Co-authored-by: antonio <antonio@zed.dev>
This fixes `cmd+k` in the terminal taking 1s to have an effect. It is
now immediate.
It also fixes#7270 by ensuring that we don't set a bad state when
matching keybindings.
It matches keybindings per context and if it finds a match on a lower
context it doesn't keep pending keystrokes. If it finds two matches on
the same context level, requiring more keystrokes, then it waits.
Release Notes:
- Fixed `cmd-k` in terminal taking 1s to have an effect. Also fixed
sporadic non-matching of keybindings if there are overlapping
keybindings.
([#7270](https://github.com/zed-industries/zed/issues/7270)).
---------
Co-authored-by: Conrad <conrad@zed.dev>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This re-introduces the changes of #7305 but this time we create a
display link using the `NSScreen` associated with the window. We're
hoping we'll get these frame requests more reliably, and this seems
supported by the fact that awakening my laptop restores the frame
requests.
Release Notes:
- See #7305.
Co-authored-by: Nathan <nathan@zed.dev>
This is achieved by starting a `CADisplayLink` that will invoke the
`on_request_frame` callback at the refresh interval of the display.
We only actually draw frames when the window was dirty, or for 2 extra
seconds after the last input event to ensure ProMotion doesn't downclock
the refresh rate when the user is actively interacting with the window.
Release Notes:
- Improved performance when using a ProMotion display with fast key
repeat rates.
---------
Co-authored-by: Nathan Sobo <nathan@zed.dev>
This improves a performance problem we were observing when having
multiple windows updating at the same time, where each window would
invalidate the other window's layout cache.
Release Notes:
- Improved performance when having multiple Zed windows open.
Co-authored-by: Max Brunsfeld <max@zed.dev>
This should prevent a class of bugs where one queries the wrong type of
global, which results in oddities at runtime.
Release Notes:
- N/A
---------
Co-authored-by: Marshall <marshall@zed.dev>
Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
We recently doubled the size of the `ELEMENT_ARENA` after someone ran
into a panic due to the arena running out of space.
This adds some logging so that we can hopefully develop a better
understanding of when the element area's allocation is elevated.
Co-authored-by: Antonio <antonio@zed.dev>