- Render PDF pages on-demand per active page instead of stitching entire document into one giant texture (fixing 22k px Vulkan texture atlas overflow and driver crash).
- Add toolbar navigation buttons (previous, next, page indicator).
- Add keyboard shortcuts (PageUp/PageDown, Left/Right arrows, j/k, Home/End) for page navigation.
- Add status bar metadata for active PDF page index and total page count.
This prepares for the keybinding hints PR.
To reproduce, press `ctrl-b` in a GPUI app with `ctrl-b h` and `ctrl-b
j` bindings, then call `window.blur()`. The live pending state clears,
but observers still report `ctrl-b`.
`Window::blur` now clears pending input and notifies observers after the
current effect cycle. I don't think we currently exercise this path in
Zed, and I was only able to reproduce it with an example GPUI app.
Release Notes:
- N/A
Follow-up to https://github.com/zed-industries/zed/pull/60477Closes#25022
We have more places that need a similar synchronization before quitting
the app: restarts on update, reloading the workspace.
On top of it, two more findings:
* `on_app_will_quit` was redundant: the global `on_app_quit` hook
flushes a strict superset of the same tasks and runs before windows are
cleared, while the entity hook held only a weak handle and could never
flush the `Window`-dependent workspace state anyway.
* previously, shutdown was run as `cx.spawn`, yet main threads got
parked on app shutdown: now using `cx.background_spawn` instead
Release Notes:
- Improved data persistence during various app shutdown cases
---------
Co-authored-by: Kostia R <k-bx@k-bx.com>
# Objective
Let git indicators — the editor gutter, file colors, and `git::Diff` —
show all changes on the current branch relative to its merge base with
the default branch, instead of only uncommitted changes.
Supersedes #60398; thanks to @samuelcolvin for the original
implementation and motivation.
Closes FR-135
## Solution
- New `git.diff_base` setting (`"head"` | `"default_branch"`), applied
live and toggleable per session from the editor controls menu ("Diff
Against Default Branch").
- Statuses come from a real merge-base-to-worktree tree diff (`git diff
--merge-base`), so local edits that revert branch changes correctly show
as unchanged.
- `GitStore` shares one `DiffBufferList` per repository with the Branch
Diff view; `repo_snapshots` and `project_path_git_status` keep returning
index/worktree truth, while display surfaces use separate `display_*`
APIs.
- `BufferDiff` now records what its base is (`DiffBaseKind`); hunks
whose base isn't HEAD are read-only in the gutter — stage/restore
buttons and keybindings are inert, so committed work can't be silently
rewritten.
- `git::Diff` follows the setting; new `git::DiffHead` always opens the
HEAD diff; `git::BranchDiff` is renamed `git::DiffBranch` (deprecated
alias kept).
Tradeoffs / known limitations:
- Hunk-level staging is unavailable while in `default_branch` mode
(whole-file staging via the git panel still works). Staging just the
uncommitted sub-ranges of a branch hunk is a follow-up.
- Remote hosts running an older server ignore the new
`GetTreeDiff.includes_worktree` proto field and degrade to
committed-changes-only branch diffs.
- Repositories with no resolvable default branch fall back to
HEAD-relative behavior; a failed first resolution retries on the next
branch-list change.
## Testing
- Real-git-repo tests for the merge-base-to-worktree diff's edge cases:
files recreated after index deletion, committed deletions recreated on
disk, and symlinks.
- GPUI tests for status semantics (a branch change reverted on disk
shows clean), `git::Diff` routing, live setting changes, and read-only
hunk enforcement (restore/stage leave buffer and index untouched).
## Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
---
Release Notes:
- Git: Added a `git.diff_base` setting (`"head"` or `"default_branch"`)
that makes the editor gutter, file colors, and diff view show all
changes on the current branch since its merge base with the default
branch, instead of only uncommitted changes.
---------
Co-authored-by: Ben Kunkle <ben@zed.dev>
When the image viewer reloads an image after the underlying file
changes, it now tracks the `RenderImage` currently displayed by the view
and drops that image’s atlas entry before replacing it with a newly
decoded render image. This prevents rapidly updated images from
accumulating atlas textures per reload while keeping cleanup scoped to
the window that displayed the image.
Closes#35894
Release Notes:
- Fixed a memory leak when previewing images that are repeatedly updated
on disk.
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Allows you to click on the zoom percent to edit it. Right clicking the
percentage resets to 100%.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Added support for editing image viewer zoom levels directly from the
toolbar.
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
This is necessary to remove some `util` dependencies from crates, as
well as better sharing for our projects. This also includes the WIP
AbsPath abstraction as well as some bug fixes from internal tooling.
Release Notes:
- N/A or Added/Fixed/Improved ...
Resolves https://github.com/zed-industries/zed/issues/55617
This diff makes the standard Reveal in Finder/File Manager shortcut work
when an image tab is focused. Image tabs already expose the reveal
action from the tab context menu, but the keyboard shortcut was only
bound in the `Editor` context, so pressing `cmd-k r` on macOS or `ctrl-k
r` on Linux/Windows did nothing while focus was in the image viewer.
With this change, `ImageView` handles the existing
`editor::RevealInFileManager` action, and the default keymaps bind the
same reveal shortcut in the `ImageViewer` context. This keeps image tabs
consistent with text editor tabs while reusing the same project path
reveal path used elsewhere.
Release Notes:
- Fixed Reveal in Finder/File Manager shortcuts not working when an
image tab is focused.
Co-authored-by: Joseph T. Lyons <JosephTLyons@gmail.com>
Closes#51312
- Remove platform-specific #[cfg] gates from PinchEvent, event
listeners, and dispatch logic in GPUI
- Windows: Intercept Ctrl+ScrollWheel (emitted by precision trackpads
for pinch gestures) and convert them to GPUI PinchEvents
- Image Viewer: remove redundant platform-specific blocks
- X11: Bump XInput version to 2.4 and implement handlers for
XinputGesturePinch events
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- Pinching gestures now available on all devices.
---------
Co-authored-by: John Tur <john-tur@outlook.com>
Self-Review Checklist:
- [ ] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable
Closes #ISSUE
Release Notes:
- N/A
All of the important changes are in
[`db.rs`](https://github.com/zed-industries/zed/pull/51809/changes#diff-2f644eab943bfa58feec29256281a3d9e8d4d7784cd34783e845af8beb15b16d).
Consider reading the commit log in order to review this work.
The DB crate's macro and API was changed to fix flakiness observed in
the MultiWorkspace tests when run locally. This flakiness was caused by
a shared `static LazyLock`, that caused concurrent test runs to interact
with the same underlying in-memory database. This flakiness wasn't
possible on CI due to it's usage of `cargo nextest`, whose
process-per-test approach masked this problem.
Essentially, I've changed the `static_connection` macro to remove the
static database variable and redone the internal model. Now, all
database types are thin wrappers around a generic `AppDatabase`. The
`AppDatabase` collects all of the individual table's migrations via the
`inventory` crate, and so only runs the migrations once on startup,
rather than a dozen times on startup.
The new API requires a `cx` so that we can replace the database returned
at runtime, rather than relying exclusively on a process-global
thread-local. However, we are still using a `static LazyLock` so that we
only need to take an `&App`, instead of an `&mut App`. These databases
types are `Clone + Send + Sync`, so you can easily capture-and-move the
database into background tasks and other places that don't have a `cx`.
For tests that require database isolation, it is now possible to set
their own database in init. See
[`workspace::init_test`](https://github.com/zed-industries/zed/pull/51809/changes#diff-041673bbd1947a35d45945636c0055429dfc8b5985faf93f8a8a960c9ad31e28R13610),
for the flakiness fix.
Best part, this change should be entirely compiler driven, so the Zed
agent was able to make the app-wide refactor easily.
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A
---------
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
Remove the BreadcrumbText struct from workspace and use the existing
HighlightedText struct from the language crate instead. The per-segment
font field is replaced by returning an optional Font alongside the
segments from the breadcrumbs() method, since the font was always
uniform across all segments of a given item.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
As we have checkerboard, used same pattern as git diff inside Image
Viewer.
Now that CPU instructions aren't an issue, perhaps size can be lowered
to 16/24 for base boxes.
Release Notes:
- N/A
Replaces a bunch of `impl FnMut` parameters with `&mut dyn FnMut` for
functions where this is the sole generic parameter.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Currently we always compute breadcrumbs and sticky headers on every
editor paint which is not cheap to do especially in bigger files, moving
this off to be computed on event handling where they change and then
caching them can save serveral milliseconds per render in bigger files.
This also puts matching brackets refreshing and document highlights on a
background task, as this tends to block the main task for prolonged time
as well.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Implemented Pan and Zoom on the Image Viewer.
Demo:
https://github.com/user-attachments/assets/855bafe8-fdc2-4945-9bfb-e48382264806Closes#9584
Release Notes:
- Add zoom in/out, reset, fit-to-view and zoom-to-actual actions
- Support scroll-wheel zoom with modifier, click-and-drag panning
- Renders a zoom percentage overlay.
- ImageView Toolbar Added to control zoom in/out and fit view.
---------
Co-authored-by: MrSubidubi <finn@zed.dev>
This reverts commit 555f8c244b.
The logic changed in the [original
PR](https://github.com/zed-industries/zed/pull/45969) is either
misplaced or lacks a counterpart that reacts on `gpui::Image` drop one
way or another.
The change was dropping the texture out of the global rendering atlas
when an image preview tab was disposed of, while in reality, another
instance (agent panel or another image preview tab) could require the
very same atlas entry to be rendered meanwhile.
Currently, only `RetainAllImageCache` in Zed does any kind of image
cleanup, and any other image usages will leak memory.
What makes it harder is that the atlas entry needs to live as long as a
particular `Arc<Image>` lives, and some public `gpui` API expects this
type to stay:
https://github.com/zed-industries/zed/blob/c4a13352027a6a6a86368c364e34ecf19b010140/crates/gpui/src/platform.rs#L1851-L1866
For image viewer in particular, we need to consider why
`RetainAllImageCache` is not used there; for the global, normal fix, we
need to consider ways to have `cx` and `window` and a way to react on
`Image` drop.
As an option, we could break the `gpui` API (as it [happens
periodically](https://github.com/zed-industries/zed/issues/46183)
already) and use `Entity<Image>` instead of `Arc`, then react with
`cx.on_release_in` for each such image.
Closes https://github.com/zed-industries/zed/issues/46755
Closes https://github.com/zed-industries/zed/issues/46435
Release Notes:
- Fixed panics on concurrent image handling
The failure would happen if the current version of the file was open as
an editor. This happened because the git blob and current version of the
buffer would have the same `ProjectPath`.
The fix was adding a new `DiskState::Historic` variant to represent
buffers that are past versions of a file (usually a snapshot from
version control). Historic buffers don't return a `ProjectPath` because
the file isn't real, thus there isn't and shouldn't be a `ProjectPath`
to it. (At least with the current way we represent a project path)
I also change the display name to use the local OS's path style instead
of being hardcoded to Posix, and cleaned up some code too.
Release Notes:
- N/A
---------
Co-authored-by: Cole Miller <cole@zed.dev>
Co-authored-by: cameron <cameron.studdstreet@gmail.com>
Co-authored-by: xipengjin <jinxp18@gmail.com>
Tiny thing I noticed; the image metadata showing on the status bar was
previously a button, but given that nothing happens when you click it,
it doesn't need to be one. Having hover, active, and all other states
was confusing.
Release Notes:
- N/A
When trying to split and clone a non clone-able workspace item we now
attempt split and move instead of doing nothing. Additionally we disable
the split menu buttons if we can't split the active item at all.
Release Notes:
- Improved handling of unsplittable panes
Split out from https://github.com/zed-industries/zed/pull/40774 to
reduce the size of the reland of that PR (once I figure out the cause of
the issue)
Release Notes:
- N/A *or* Added/Fixed/Improved ...
We were spawning the process on the foreground thread before which can
block an arbitrary amount of time. Likewise we no longer block
deserialization on the terminal loading.
Release Notes:
- Improved startup time on systems with slow process spawning
capabilities
We've been considering removing workspace-hack for a couple reasons:
- Lukas ran into a situation where its build script seemed to be causing
spurious rebuilds. This seems more likely to be a cargo bug than an
issue with workspace-hack itself (given that it has an empty build
script), but we don't necessarily want to take the time to hunt that
down right now.
- Marshall mentioned hakari interacts poorly with automated crate
updates (in our case provided by rennovate) because you'd need to have
`cargo hakari generate && cargo hakari manage-deps` after their changes
and we prefer to not have actions that make commits.
Currently removing workspace-hack causes our workspace to grow from
~1700 to ~2000 crates being built (depending on platform), which is
mainly a problem when you're building the whole workspace or running
tests across the the normal and remote binaries (which is where
feature-unification nets us the most sharing). It doesn't impact
incremental times noticeably when you're just iterating on `-p zed`, and
we'll hopefully get these savings back in the future when
rust-lang/cargo#14774 (which re-implements the functionality of hakari)
is finished.
Release Notes:
- N/A
This is a follow-up PR to
https://github.com/zed-industries/zed/pull/39609, and attempts to
address hidden status bar items still contributing to the layout and
creating extra spacing.

- 203cbd634bfb1489b8afa4952d9594615a956b77 Adds a `.none()` method to
the `gpui::Styled` helper trait, so that status items can set their
display type to none inside their `render` method.
- 249f06e3de63b0ab32814f20e7105d8e2b642f02 Applies `.none()` to all the
status items.
- ~~499f564906c88336608c81615b11ebc9ab43d832~~ At first I was adding an
`is_visible` method to the `StatusBarView` trait, which would be used to
skip status bar items which would just render an empty div anyway, but I
felt duplicating the conditions for hiding the buttons between the
status items `is_visible` and `render` methods could be an attraction
for bugs, so I tried to find another approach. This commit contains
those changes, reverted immediately (if the `is_visible` approach is
preferred I can bring it back!)
- f37cb75f0519ceea1f3e1cc4f97087a5cb34b0fd (bonus!) Adds a condition to
the vim mode indicator to avoid a leading space when there are no
pending keys.
Release Notes:
- N/A
This makes it easier to see the image bounds for images with transparent
backgrounds.
<img width="2560" height="1377" alt="png"
src="https://github.com/user-attachments/assets/e1555576-39a2-4240-b9d3-67574df76f0d"
/>
Release Notes:
- Updated image preview background checkboxes to match the actual image
size, making it easier to see the bounds of images with transparent
backgrounds.