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).
![before_after](https://github.com/zed-industries/zed/assets/482957/c8120b07-1dbd-4776-834a-d040e569a71e)
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 PR moves the Clippy configuration up to the workspace level.
We're using the [`lints`
table](https://doc.rust-lang.org/cargo/reference/workspaces.html#the-lints-table)
to configure the Clippy ruleset in the workspace's `Cargo.toml`.
Each crate in the workspace now has the following in their own
`Cargo.toml` to inherit the lints from the workspace:
```toml
[lints]
workspace = true
```
This allows for configuring rust-analyzer to show Clippy lints in the
editor by using the following configuration in your Zed `settings.json`:
```json
{
"lsp": {
"rust-analyzer": {
"initialization_options": {
"check": {
"command": "clippy"
}
}
}
}
```
Release Notes:
- N/A
This PR extends the `experimental.theme_overrides` to allow overriding
the player colors.
Release Notes:
- Added the ability to override player colors using
`experimenta.theme_overrides`.
This practice makes it difficult to locate todo!s in my code when I'm
working. Let's take out the bang if we want to keep doing this.
Release Notes:
- N/A
This small inconsistency was mentioned on the discord. This fixes it.
Release Notes:
- Themes: Renamed `scrollbar_thumb.background` to
`scrollbar.thumb.background` to be consistent with other style
properties.
---------
Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
This PR makes it so the One themes—One Dark and One Light—are used as a
fallback when trying to reload a theme that no longer exists in the
registry.
This makes it so when an extension providing the current theme is
removed, the active theme will change to either One Dark or One Light
(based on the system appearance) instead of retaining a cached version
of the theme.
Release Notes:
- Changed the behavior when uninstalling a theme to default to One Dark
or One Light (based on system appearance) rather than keeping a cached
version of the old theme.
This PR updates the various spots where we reload the theme to use
`ThemeSettings::reload_current_theme` instead of duplicating the code
each time.
Release Notes:
- N/A
This PR extends the extension directory watcher to also watch and reload
themes defined in extensions.
Release Notes:
- N/A
Co-authored-by: Max <max@zed.dev>
This PR adds the initial support for loading extensions in Zed.
### Extensions Directory
Extensions are loaded from the extensions directory.
The extensions directory has the following structure:
```
extensions/
installed/
extension-a/
grammars/
languages/
extension-b/
themes/
manifest.json
```
The `manifest.json` file is used internally by Zed to keep track of
which extensions are installed. This file should be maintained
automatically, and shouldn't require any direct interaction with it.
Extensions can provide Tree-sitter grammars, languages, and themes.
Release Notes:
- N/A
---------
Co-authored-by: Marshall <marshall@zed.dev>
This PR changes our approach to initializing the `SystemAppearance` so
that we can do it earlier in the startup process.
Previously we were using the appearance from the window, meaning that we
couldn't initialize the value until we first opened the window.
Now we read the `window_appearance` from the `AppContext`. On macOS this
is backed by the
[`effectiveAppearance`](https://developer.apple.com/documentation/appkit/nsapplication/2967171-effectiveappearance)
on the `NSApplication`.
We currently still watch for changes to the appearance at the window
level, as the only hook I could find in the documentation is
[`viewDidChangeEffectiveAppearance`](https://developer.apple.com/documentation/appkit/nsview/2977088-viewdidchangeeffectiveappearance),
which is at the `NSView` level.
In my testing this makes it so Zed appropriately chooses the correct
light/dark theme on startup.
Release Notes:
- N/A
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 PR adds support for configuring both a light and dark theme in
`settings.json`.
In addition to accepting just a theme name, the `theme` field now also
accepts an object in the following form:
```jsonc
{
"theme": {
"mode": "system",
"light": "One Light",
"dark": "One Dark"
}
}
```
Both `light` and `dark` are required, and indicate which theme should be
used when the system is in light mode and dark mode, respectively.
The `mode` field is optional and indicates which theme should be used:
- `"system"` - Use the theme that corresponds to the system's
appearance.
- `"light"` - Use the theme indicated by the `light` field.
- `"dark"` - Use the theme indicated by the `dark` field.
Thank you to @Yesterday17 for taking a first stab at this in #6881!
Release Notes:
- Added support for configuring both a light and dark theme and
switching between them based on system preference.
This PR improves the contrast of the default `search_match_background`
colors.
Release Notes:
- Improved the contrast of the default `search.match_background` colors.
This PR makes Zed watch the themes directory for changes.
When theme files are added or modified, we reload the theme and apply
any changes to Zed.
Release Notes:
- Added live reloading for the themes directory.
This PR fixes some formatting issues in some of the `Cargo.toml` files.
I tried to fix most of these in #7126, but there were a few that I
missed.
Release Notes:
- N/A
This PR sorts the dependency lists in our `Cargo.toml` files so that
they are in alphabetical order.
This should make them easier to visually scan when looking for a
dependency.
Apologies in advance for any merge conflicts 🙈
Release Notes:
- N/A
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>
This PR is a follow-up to #7084, where I noted that I wasn't satisfied
with using `SharedUri` to represent both URIs and paths on the local
filesystem:
> I'm still not entirely happy with this naming, as the file paths that
we can store in here are not _really_ URIs, as they are lacking a
protocol.
>
> I want to explore changing `SharedUri` / `SharedUrl` back to alway
storing a URL and treat local filepaths differently, as it seems we're
conflating two different concerns under the same umbrella, at the
moment.
`SharedUri` has now been reverted to just containing a `SharedString`
with a URI.
`ImageSource` now has a new `File` variant that is used to load an image
from a `PathBuf`.
Release Notes:
- N/A
This PR renames `SharedUrl` to `SharedUri` to better reflect its intent.
I'm still not entirely happy with this naming, as the file paths that we
can store in here are not _really_ URIs, as they are lacking a protocol.
I want to explore changing `SharedUri` / `SharedUrl` back to alway
storing a URL and treat local filepaths differently, as it seems we're
conflating two different concerns under the same umbrella, at the
moment.
Release Notes:
- N/A
This PR implements support for loading and displaying images from a
local file using gpui's `img` element.
API Changes:
- Changed `SharedUrl` to `SharedUrl::File`, `SharedUrl::Network`
Usage:
```rust
// load from network
img(SharedUrl::network(...)) // previously img(SharedUrl(...)
// load from filesystem
img(SharedUrl::file(...))
```
This will be useful when implementing markdown image support, because we
need to be able to render images from the filesystem (relative/absolute
path), e.g. when implementing markdown preview #5064.
I also added an example `image` to the gpui crate, let me know if this
is useful. Showcase:
<img width="872" alt="image"
src="https://github.com/zed-industries/zed/assets/53836821/b4310a26-db81-44fa-9a7b-61e7d0ad4349">
**Note**: The example is fetching images from [Lorem
Picsum](https://picsum.photos) ([Github
Repo](https://github.com/DMarby/picsum-photos)), which is a free
resource for fetching images in a specific size. Please let me know if
you're okay with using this in the example.
This PR adds support for loading user themes in Zed.
Themes are loaded from the `themes` directory under the Zed config:
`~/.config/zed/themes`. This directory should contain JSON files
containing a `ThemeFamilyContent`.
Here's an example of the general structure of a theme family file:
```jsonc
{
"name": "Vitesse",
"author": "Anthony Fu",
"themes": [
{
"name": "Vitesse Dark Soft",
"appearance": "dark",
"style": {
"border": "#252525",
// ...
}
}
]
}
```
Themes placed in this directory will be loaded and available in the
theme selector.
Release Notes:
- Added support for loading user themes from `~/.config/zed/themes`.
This PR adds a newtype wrapper around the global `ThemeRegistry`.
This allows us to limit where the `ThemeRegistry` can be accessed
directly via `cx.global` et al., without going through the dedicated
methods on the `ThemeRegistry`.
Release Notes:
- N/A
This PR reworks how we access the `ThemeRegistry` global.
Previously we were making calls directly on the context, like
`cx.global::<ThemeRegistry>`. However, one problem with this is that it
spreads out the knowledge of exactly what type is stored in the global.
In order to make it easier to adjust the type we store in the context
(e.g., wrapping the `ThemeRegistry` in an `Arc`), we now call methods on
the `ThemeRegistry` itself for accessing the global.
It would also be interesting to see how we could prevent access to the
`ThemeRegistry` without going through one of these dedicated methods 🤔
Release Notes:
- N/A
This PR improves the theme loading to gracefully handle when a theme
couldn't be loaded.
Trying to debug a panic that happens on startup in Nightly.
Release Notes:
- N/A
This PR removes the themes defined using the `UserTheme` types, as we're
now loading the themes via JSON.
The `theme_importer` has also been reworked to read in a VS Code theme
and output a new JSON theme.
Release Notes:
- N/A
This PR changes the theme loading to use the JSON themes bundled with
the binary rather then the Rust theme definitions.
### Performance
I profiled this using `cargo run --release` to see what the speed
differences would be now that we're deserializing JSON:
**Before:** `ThemeRegistry::load_user_themes` took 16.656666ms
**After:** `ThemeRegistry::load_user_themes` took 18.784875ms
It's slightly slower, but not by much. There is probably some work we
could do here to bring down the theme loading time in general.
Release Notes:
- N/A
This PR adds serialized versions of each of the themes that currently
ship with Zed.
In a future PR we'll be looking to make these the canonical
representations of the built-in themes.
Note that we're intentionally repurposing the `theme_importer` to do
this, so that crate is a bit rough-and-ready at the moment.
Release Notes:
- N/A
JSON LSP adapter now caches the schema. `workspace_configuration` is
back to being async, and we are also no longer asking for font names
twice while constructing the schema.
Release Notes:
- Improved performance when opening the .json files.
---------
Co-authored-by: Kirill <kirill@zed.dev>
This PR adds **experimental** support for overriding theme values in the
current theme.
Be advised that both the existence of this setting and the structure of
the theme itself are subject to change.
But this is a first step towards allowing Zed users to customize or
bring their own themes.
### How it works
There is a new `experimental.theme_overrides` setting in
`settings.json`.
This accepts an object containing overrides for values in the theme. All
values are optional, and will be overlaid on top of whatever theme you
currently have set by the `theme` field.
There is JSON schema support to show which values are supported.
### Example
Here's an example of it in action:
https://github.com/zed-industries/zed/assets/1486634/173b94b1-4d88-4333-b980-8fed937e6f6d
Release Notes:
- Added `experimental.theme_overrides` to `settings.json` to allow for
customizing the current theme.
- This setting is experimental and subject to change.
- [x] Fill in GPL license text.
- [x] live_kit_client depends on live_kit_server as non-dev dependency,
even though it seems to only be used for tests. Is that an issue?
Release Notes:
- N/A