Commit graph

2530 commits

Author SHA1 Message Date
Xin Zhao
fa00dccc42
Fix project path handling when connecting from Unix to Windows remotes (#62038)
# Objective

Follow-up of #61374.

Zed now supports Windows as a remote target, but when connecting from a
Unix platform to Windows, some path handling still uses the native
client's path style (Unix) to construct paths, which causes weird path
displays in different areas.

One of them is the project path stored in the `settings.json` file,
which is related to the open path picker in the codebase:

5e1fd392f6/crates/open_path_prompt/src/open_path_prompt.rs (L668-L679)
For example, if I have a remote project at `D:\code\test_python` and
want to open it in remote development, I usually use path completions,
with `D:\code\` as the parent path and `test_python` as the selected
candidate. Zed directly joins them using `Path::join` on the Unix
platform, which results in `D:\code\/test_python`.

A second thing I found is the displayed name for the git repo. The
related source code is:

5e1fd392f6/crates/title_bar/src/title_bar.rs (L262-L268)
Also taking `D:\code\test_python` as an example: the passed-in
`common_dir_abs_path` is `D:\code\test_python\.git`, and
`repo_identity_path()` directly uses `Path::file_name()` and
`Path::parent()` from the standard library to handle this:

5e1fd392f6/crates/project/src/git_store.rs (L9956-L9965)
Ideally, this function should return `D:\code\test_python`. But due to
the platform mismatch, `D:\code\test_python\.git` is returned; after
further processing in the title bar, we get `D:\code\test_python\` as
the displayed name, while the expected display name is `test_python`.

In the past, only Unix-like systems could serve as remote servers, and
their path separator (`/`) is valid on Windows, so everything looked
fine. But Unix does not support `\` as a valid separator — that's the
root cause. We need to use `PathStyle`, which is designed for processing
paths across platforms, to deal with these cases.

## Solution

- Added new APIs `PathStyle::parent()` and `PathStyle::file_name()`,
which serve as replacements for `Path::parent()` and `Path::file_name()`
to process paths cross-platform.
- Adopted the new APIs in `repo_identity_path()`, and updated the
relevant call sites.
- For the open path picker, use `PathStyle::join_path()` instead of
`Path::join`.

## Testing

The added `PathStyle::parent()` and `PathStyle::file_name()` are covered
by detailed unit tests. These tests verify that the behavior matches the
corresponding methods in `Path`, just independent of the host platform.

For the path display issues, I built and tested manually; a comparison
is attached in the Showcase section.

## 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)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

<details>
  <summary>Click to view showcase</summary>

| Content | Before | After |
|:--:|:--:|:--:|
|title bar|<img width="486" height="272" alt="title_bar_before"
src="https://github.com/user-attachments/assets/d14d0e37-a1b8-43ab-b51b-fe9dd1b977eb"
/> | <img width="406" height="274" alt="title_bar_after"
src="https://github.com/user-attachments/assets/fc9193f4-d42c-47a8-a254-4ed08c806a11"
/> |
|path storage| <img width="337" height="264" alt="project_path_before"
src="https://github.com/user-attachments/assets/3352add3-20df-43b9-8a20-10ee7d96e703"
/>| <img width="319" height="262" alt="project_path_after"
src="https://github.com/user-attachments/assets/fa3d7feb-f393-416a-868d-85eb0af5cfb8"
/>|
|open remote| <img width="554" height="135" alt="open_remote_before"
src="https://github.com/user-attachments/assets/62983eca-22ad-472f-8333-8561cfc17357"
/>|<img width="562" height="176" alt="open_remote_after"
src="https://github.com/user-attachments/assets/22528a6b-0e73-4a12-a825-673ba57a63da"
/> |
</details>


## Other things to note
This PR also did a little refactoring: it moved the `PathStyle`-related
tests from the `util` crate to the `path` crate, and updated the
documentation to reflect that Windows can serve as a remote platform.

The recent project picker also suffers from the same cross-platform bug,
but it is not fixed here, because a clean fix requires dealing with
database storage, unlike the direct API changes made here. I will
address it in a follow-up PR.

This PR looks very large, but most of the changes are the test migration
and the new API implementation. I hope the unit tests and comments can
offload some of the burden for reviewers.

---

Release Notes:

- Fixed project paths being built incorrectly when connecting from Unix
machines to Windows remote servers.
2026-08-19 12:16:37 +00:00
Arnesh
4c7244790a
workspace: Activate the right tab when restoring a workspace (#62844)
@SomeoneToIgnore this is the follow up you asked for in #62692, done as
discussed.

`deserialize_to` keeps a `None` in `items` for every item that failed to
deserialize, and those are never added to the pane. Any later tab
therefore sits at a lower index in the pane than the one it was
serialized with, so activating and previewing by serialized index lands
on the tab that shifted into that slot. When the failing item is the
last one, the index points past the end of the pane and nothing is
activated or previewed.

The serialized index is now mapped to the pane's index by counting the
items before it that actually restored, and an index whose own item
failed to restore is skipped.

Closes #62843

Release Notes:

- Fixed the wrong tab being activated when restoring a workspace
containing items that fail to open

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-08-18 23:00:25 +00:00
Arnesh
aad75630f9
workspace: Keep pinned tabs correct when restoring a workspace (#62692)
Pinned tabs are the leading tabs of a pane, and that is persisted as a
plain count. Both sides of workspace serialization could leave the count
out of step with the tabs it is meant to describe:

- When serializing, `serialize_pane_handle` drops items that cannot be
serialized (a pinned diagnostics or project search tab, for example)
from the pane's children, but still stored the pane's raw pinned count.
- When restoring, `SerializedPane::deserialize_to` keeps a `None` in
`items` for every item that failed to deserialize. Those are never added
to the pane, but `self.pinned_count.min(items.len())` counted them
anyway.

In both cases the count ends up pointing past the tabs that were
actually pinned, so the tabs that shift into those slots come back
pinned even though they never were. This also explains the `Pinned tab
count (N) exceeds actual tab count (M)` warning from #33342.

Now the serialized count shrinks with each dropped pinned item, and on
restore only the pinned items that were actually restored are counted.

Closes #62003

Release Notes:

- Fixed tabs being wrongly marked as pinned after reloading a workspace
or updating Zed
2026-08-18 21:58:55 +00:00
afdul
a7d74150ac
Fix the git_gutter_width setting (#62704)
Some checks are pending
run_tests / check_style (push) Waiting to run
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
# Objective

- Fixes #62645
## Solution
Since the default value isnt constant.It now has two options 1) Default
2) custom where user inputs a value.

## 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 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)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable

## Showcase
<img width="798" height="361" alt="Screenshot 2026-08-16 at 4 29 54 PM"
src="https://github.com/user-attachments/assets/0af302f6-4733-4a23-9e93-1f9d98dd772f"
/>

<img width="798" height="92" alt="Screenshot 2026-08-16 at 4 30 13 PM"
src="https://github.com/user-attachments/assets/2c87c2a3-2947-45c7-8495-f6a0b36dd793"
/>

Release Notes:

- Added git_gutter_width setting to the Settings UI with default
(font-size-scaled) and custom (fixed pixel width) options

---------

Co-authored-by: Abdul Rafey Ahmed <abdul.r@hyperverge.co>
Co-authored-by: MrSubidubi <finn@zed.dev>
2026-08-18 12:40:18 +00:00
Remco Smits
2893b86b04
gpui_macos: Add simple fullscreen mode that covers the notch (#60020)
Closes #60013

# Objective

Right now Zed can go full screen but it does not allow you to fix the
hole screen,
by that I mean that Zed can go behind the notch so you don't have extra
useless room left.

## Solution

You can now use the `fullscreen_mode` = `simple` setting to use the new
simple full screen feature, that lives besides the normal full screen
feature. But allows you to have an option to go 100% full screen without
losing any useless space on your macbook screen.
**Note** this is mostly usefull when you have a macbook that has a notch
whitch is kinda in the way of your work flow.

## 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

## Showcase

**Before**
<img width="5712" height="4284" alt="IMG_0339"
src="https://github.com/user-attachments/assets/9f908ffd-7cef-4999-a454-c80f72c40dc8"
/>

**After** (Note now Zed is behind your notch when using the simple full
screen feature)
<img width="5712" height="4284" alt="IMG_0360"
src="https://github.com/user-attachments/assets/5917ed4d-2a64-4464-a794-bc46fd034521"
/>


---

Release Notes:

- Added support for simple fullscreen mode using the `fullscreen_mode`
setting, set it to `simple` to try it out.
2026-08-18 07:00:34 +00:00
Austin Cummings
6721ea2e5c
workspace: Reset all configured dock panels (#62552)
Closes #57388.

When a dock is listed in `resize_all_panels_in_dock`, reset its
compatible panels to the active panel's default size. This applies to
the reset actions and resize-handle double-clicks. Docks not listed in
the setting continue to reset only the active panel.

Adds regression coverage for fixed panels with different defaults,
flexible panels, and active-panel-only resets.

Release Notes:

- Fixed dock size reset commands only resetting the active panel when
`resize_all_panels_in_dock` is enabled.

---------

Co-authored-by: dino <dinojoaocosta@gmail.com>
2026-08-17 22:28:04 +00:00
Akihiro Okuno
90eb566f32
sidebar: Make project reordering key-bindable (#62695)
# Objective

- The sidebar already supports moving project groups through its **Move
Up** and **Move Down** context-menu entries, but those entries use
callbacks that cannot be referenced from `keymap.json`. Moving a project
several positions therefore requires reopening the menu for every step.
- Follow-up to #57448. Related to #61647.

## Solution

- Add `multi_workspace::MoveProjectUp` and
`multi_workspace::MoveProjectDown` actions. The handlers resolve the
active project group and delegate to the existing `MultiWorkspace`
reordering methods, keeping ordering and persistence behavior unchanged.
- Associate the actions with the existing context-menu entries so
configured shortcuts are shown alongside the menu commands. The menu
callbacks still operate on the project that was clicked.

## Testing

- Added a GPUI test that dispatches both actions and verifies that the
active project group moves in the expected direction and remains
unchanged at list boundaries:
- `cargo test -p workspace test_move_active_project_group_actions --
--nocapture`
- Manually verified on macOS with an isolated Zed user-data directory
and three project folders:
  - Assigned custom shortcuts to both actions in `keymap.json`.
  - Confirmed that the active project moves up and down in the sidebar.
- Ran formatting, compilation, and lint checks:
  - `cargo fmt --all -- --check`
  - `cargo check -p sidebar`
- `./script/clippy -p workspace -p sidebar -p gpui_platform --features
gpui_platform/runtime_shaders`

## 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

## Showcase

<details>
  <summary>Move projects with custom keybindings</summary>


https://github.com/user-attachments/assets/09432817-318b-484e-b630-a6012e9599cd

</details>

---

Release Notes:

- Sidebar: Added key-bindable actions for moving projects up and down.
2026-08-17 07:49:57 +00:00
Kirill Bulatov
b2d9c2e122
Fixed the zoomed agent panel closing unexpectedly on rewind (#62711)
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
`ThreadView::regenerate` does `thread.rewind()` which de-focused the
message editor mid-flight causing the zoomed panel to disappear.

* workspace: Keep zoomed panels open when window focus is lost

Commit adds a test + tweaks a default, generic, fallback to be more
lenient: instead of focusing the workspace (and hiding all panels right
away), try to fall back to whatever panel open

* gpui: Restore focus to nearest surviving ancestor when focus is lost

Commit tries to push it down to a library level and add a way to fall
back to closest ancestor that's still visible with the focus instead.


Release Notes:

- Fixed the zoomed agent panel closing unexpectedly on rewind
2026-08-16 14:42:24 +00:00
Kirill Bulatov
18be72fd68
Make file scanner less eager in non-git-tracked directory trees (#62583)
Fixes https://github.com/zed-industries/zed/issues/35780
Collab schema migration PR:
https://github.com/zed-industries/cloud/pull/3422
The corresponding database schema migration has been created in the
Cloud repo and applied to the production database.

Before, Zed scanned each and every entry in the tree down from the
directory it was opened in, except gitignored files and scan exclusions.
The approach is unchanged, if Zed detects it was open inside a git
repository: e.g. the directory open in Zed contains `.git` directory.

For the rest of the projects, 2 optimizations are made:

* Limit the depth of file scan traversal.
Now, `file_scan_depth` (default `5`) restricts Zed from traversing any
directory that has same number or more segments in its file path.


Such directories behave similar to gitignored directories: their
contents is not available in file finder, project search and project
panel, but can be lazily traversed when the directory is expanded (e.g.
project panel expands it or a nested file is open by path via terminal,
etc.)

To indicate that to the users, a status entry is shown firs time the
limitation is hit in the project:

<img width="858" height="133" alt="image"
src="https://github.com/user-attachments/assets/7da6cfbb-98b4-4cc3-bf2a-8902a9597a15"
/>

* During the scan, any git repositories that are not direct children of
the directory open in Zed (depth >= 2), are traversed and indexed
normally, but their git metadata is never fetched eagerly.

Only when Zed opens a buffer from that repo the git metadata is fetched
and applied.

All that combined now uses a way more moderate amount of CPU and RAM
when opening `~`:

<img width="1717" height="368" alt="Screenshot 2026-08-13 at 17 43 53"
src="https://github.com/user-attachments/assets/ec83e2a9-f7cc-452b-8eb7-af158284ca4e"
/>

File scan inclusions and exclusions are considered still for such
projects.
Set `file_scan_depth` to `0` to enable old behavior.
The setting is supported in the project settings, so custom values can
be set based on the project's structure.

---

Release Notes:

- Fixed Zed using a lot of memory and CPU in large, non-git-tracked,
directory trees
2026-08-13 17:07:06 +00:00
Kirill Bulatov
1271f8b0e8
Bump rustc to 1.97 (#62395)
Some checks failed
extension_auto_bump / detect_changed_extensions (push) Has been cancelled
extension_auto_bump / bump_extension_versions (push) Has been cancelled
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
Release Notes:

- N/A
2026-08-09 22:29:52 +00:00
Piotr Osiewicz
c24358d96c
deps: Bump pathfinder_simd & fix upcoming rustc warnings (#62170)
While building Zed with nightly rustc I've noticed it doesn't compile
because of good old pathfinder_simd. It also emits a bunch of warnings
about use of f64 literals where f32 is expected, so I've fixed them - it
should make future upgrades more straightforward.
2026-08-07 10:16:57 +00:00
Ben Kunkle
158c16f51c
workspace: Choose the replacement workspace inside MultiWorkspace::remove (#62141)
# Objective

Follow-up to #62028. When archiving removed a thread's workspace, the
replacement
was derived from whichever sidebar row sat adjacent to the archived one.
Rows are
a flat list with project headers as separators, so archiving the oldest
thread in
a project selected the next project's newest thread and moved the user
out of the
project they were working in — and when that neighbor was remote,
connected to
its host just to pick a fallback.

# Solution

- `MultiWorkspace::remove` now chooses the replacement itself from a
`RemovalIntent` (keep the project vs close it): a live workspace in the
same
project, the project's own roots when kept, the nearest retained
neighbor,
an adjacent local project, then an empty workspace. The workspaces being
  removed are excluded from that search in one place instead of five.
- Sidebar neighbor selection stays within the entry's project section.
- The three archive paths now share one removal orchestration, and the
three
  "open the closed workspace first" helpers collapse into one.

# Testing

New tests cover: the keep-project fallback, neighbor selection staying
inside the
project section, and archiving with a mock-remote neighboring project
never
connecting to it. Each was verified to fail against the previous
behavior.

## 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:

- Fixed archiving a thread switching the window to a different project.
- Fixed a possible crash when archiving a thread while its window was
closing.
2026-08-05 02:48:46 +00:00
Ben Kunkle
4aad57fd1f
workspace: Return the created workspace when opening a remote project (#62028)
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
# Objective

Fix the `fallback workspace must not be one of the workspaces being
removed` panic.

Fixes FR-148
Fixes ZED-AKR
Fixes ZED-97M

# Solution

The remote path of `find_or_create_workspace` opened a project, then
returned the
window's *active* workspace instead of the one it created. The open
awaits toolchain
loading and item restoration, and a save prompt from a concurrent
workspace removal
can re-activate a workspace being removed during that wait; the stale
return value
then trips the assert in `MultiWorkspace::remove`.

Return the created workspace from `open_remote_project_inner` and use it
at the
call sites instead of re-reading the active workspace after the await.

# Testing

Added
`test_find_or_create_workspace_returns_the_created_remote_workspace`:
opens a
mock remote project and re-activates the previous workspace mid-open
(standing in
for the save prompt), then asserts the open returns the workspace it
created.
Verified it fails against the pre-fix behavior.

## 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:

- Fixed a crash when a workspace was removed while a remote project was
opening in the same window.
2026-08-03 20:43:45 +00:00
Matei Oprea
2318f45f4c
multi_workspace: Allow closing of currently selected project (#60602)
# Objective

When working across multiple projects open in the same window, closing
the **currently selected** project requried a two-step flow: switch to
another project first then close the one that you initially wanted to.
The project's close button was hidden on the active project, so the only
way to remove the project was to navigate away first.

## Solution

Always render the close button in the project picker, including for the
active project. Closing the active project now removes it and switches
to a neighboring project automatically.
This worked well for local projects but broke for remote ones. For any
remote neighbor it actually fell through to an empty workspace.

There are 3 cases now: 
1. Activate the neighbor's already open workspace when one exists (now
either if its local or remote)
2. Load the neighbor through the host-aware **find_or_create_workspace**
which connects and opens a remote neighbor when it isn't already open
3. Fallback to an empty workspace only when no neighbor remains

## Testing

- Did you test these changes? If so, how?
- Are there any parts that need more testing?
- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?

## 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

## Showcase

> This section is optional. If this PR does not include a visual change
or does not add a new user-facing feature, you can delete this section.

- Help others understand the result of this PR by showcasing your
awesome work!
- If this PR includes a visual change, consider adding a screenshot,
GIF, or video
- A before/after comparison is very useful for changes to existing
features!

While a showcase should aim to be brief and digestible, you can use a
toggleable section to save space on longer showcases:

<details>
  <summary>Click to view showcase</summary>


https://github.com/user-attachments/assets/6e1d1968-702a-4f13-9442-5e90fe7ae9f9

</details>

---

Release Notes:

- Improved the project switcher to allow closing the currently selected
project, switching to a neighboring project (local or remote)
automatically.

---------

Co-authored-by: dino <dinojoaocosta@gmail.com>
2026-07-31 12:55:11 +00:00
CarboFish
1ac840ab2f
workspace: Fix dropping Windows files onto a WSL remote (#57146)
Dropping a local Windows file (e.g. `E:\foo\bar.md`) onto a Zed window
connected to a WSL remote previously forwarded the path verbatim. On the
remote Linux side `E:\foo\bar.md` isn't absolute, so it got joined with
the worktree CWD, producing nonsense like `/home/user/E:\foo\bar.md` and
a "failed to canonicalize root path" error from the worktree scanner.

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 is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Closes #49915

before:
<img width="1343" height="331" alt="before"
src="https://github.com/user-attachments/assets/193cfbf6-d07e-4c5f-b941-75e4a0c62345"
/>

after:
<img width="1181" height="288" alt="after"
src="https://github.com/user-attachments/assets/7ad56e13-3723-4b48-aa3d-59eca6038a7f"
/>


Release Notes:

- Fixed dragging local Windows files onto a Zed window connected to a
WSL remote.
2026-07-31 10:49:11 +00:00
Tai Nguyen
a5615f092d
Reset panel saved size when default_size changes (#61855)
Closes #59235

When a panel's `default_size` changes (e.g. `git_panel.default_width` is
edited in settings), the persisted per-workspace size is now cleared so
the new default takes effect immediately. Previously the saved dragged
size took precedence forever, making `default_width` effectively useless
after the first manual resize.

This fix is at the Dock level (`crates/workspace/src/dock.rs`), so it
applies to all panels — Git Panel, Project Panel, Terminal Panel, etc.

Release Notes:

- Fixed panel `default_width` setting being ignored after manually
resizing the panel


https://github.com/user-attachments/assets/97ef69b2-387f-4e29-bc4c-0f336f24eb0b
2026-07-31 09:27:11 +00:00
Mayank Verma
e99616cdd4
gpui: Add resizable and minimizable state to Window (#61473)
### Objective

PR #36859 made native macOS and Windows controls respect `is_resizable`
and `is_minimizable`, but custom window decorations cannot access those
values from `Window`. Linux custom controls and client-side resize
interactions remain active, macOS custom titlebar double-click does not
check either option and custom Windows caption buttons still appear
enabled even though the backend blocks their actions.

### Solution

Expose `is_resizable` and `is_minimizable` on `Window`. Use them to
disable custom window controls and titlebar actions and omit client-side
resize cursors and hitboxes for non-resizable windows.

## 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 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)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- N/A
2026-07-31 06:38:08 +00:00
Ayush Patil
998fbf30ff
Register Git submodules under their own project path (#61859)
Closes #61671

A submodule's `.git` is a file pointing into the superproject's
`.git/modules/<name>`, which looks just like a linked worktree's `.git`
file. The identity-path resolution used for recent projects and project
grouping treated them the same, so submodules got registered under
`.git/modules/<name>` instead of their own folder.

The fix detects submodule git dirs (`is_submodule_git_dir`) and skips
resolution for them, so a submodule keeps its own working directory as
its identity. Linked worktrees and bare repos are unaffected.

### Current vs. Expected

Current: opening submodule `Foo/Bar` registers the path as
`Foo/.git/modules/Bar`.
Expected: it registers as `Foo/Bar`, like any other project.

### Video


https://github.com/user-attachments/assets/e2eee5e7-ef64-47ed-9780-6fcafda5ae30

### Tests

- `is_submodule_git_dir` unit test
- `resolve_git_worktree_to_main_repo` returns `None` for a submodule
- persistence test asserting the submodule identity stays at its own
folder

Release Notes:

- Fixed Git submodules being registered under the parent repository's
`.git/modules` directory instead of their own path
2026-07-30 19:44:22 +00:00
Dino
8780e3a1e2
project_panel: Refactor undo and redo error messages (#60186)
# Objective

Improve the error messages shown when undoing or redoing project panel
operations fail. Right now we're mostly relying on the error message
generated by the underlying function or method that attempts to apply
the inverse operation, which might not be the best UX.

## Solution

* Update the style used in the `Workspace::show_notification` call,
under `project_panel::undo::Inner::show_error`, in order to use markdown
styling. This allows paths to stand out a little bit better, which is
helpful seeing as pretty much all error messages will contain path
information in the notification's body.
* Update the way paths are displayed so as to show the full relative
path and, if multiple worktrees are present, include the worktree name.
This helps disambiguate cases where multiple worktrees might have the
same path, for example, `src/lib.rs`.
* Update each specific operation's error message to better convey what
exactly failed.

## Testing

Manually tested each of the scenarios outlined in the `Showcase`
section. Please refer to the screenshots in that section to see before
and after comparisons

## 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 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)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

### Undo failures

<details>
<summary>1. Move conflict</summary>

| Steps | Before | After |
| --- | --- | --- |
| 1. Move `a.txt` into `docs/` (cut/paste or drag)<br>2. Run `touch
a.txt`<br>3. Undo | <img width="2736" height="1586" alt="1_before"
src="https://github.com/user-attachments/assets/d60660d1-ba85-4a08-82a3-a6e3f6d84506"
/> | <img width="2736" height="1586" alt="1_after"
src="https://github.com/user-attachments/assets/c050f287-b186-42db-8995-57102d1db4d2"
/> |

</details>

<details>
<summary>2. Rename conflict</summary>

| Steps | Before | After |
| --- | --- | --- |
| 1. Rename `a.txt` → `b.txt`<br>2. Run `touch a.txt`<br>3. Undo | <img
width="2736" height="1586" alt="2_before"
src="https://github.com/user-attachments/assets/0c0eb0bc-ea01-4642-a63a-69687b2ba13e"
/> | <img width="2736" height="1586" alt="2_after"
src="https://github.com/user-attachments/assets/68dba045-60b2-462e-9f34-5bb038a4a245"
/> |

</details>

<details>
<summary>3. Source no longer exists</summary>

| Steps | Before | After |
| --- | --- | --- |
| 1. Move `a.txt` into `docs/`<br>2. Run `rm docs/a.txt`<br>3. Undo |
<img width="2736" height="1586" alt="3_before"
src="https://github.com/user-attachments/assets/2f55327c-d478-44f5-ac85-5e0b10044a52"
/> | <img width="2736" height="1586" alt="3_after"
src="https://github.com/user-attachments/assets/5296b431-c2a1-408e-8920-9f2d5c1d169a"
/> |

</details>

<details>
<summary>4. Restore from emptied Trash</summary>

| Steps | Before | After |
| --- | --- | --- |
| 1. Delete `a.txt` (moves it to Trash)<br>2. Empty it from the system
Trash<br>3. Undo | <img width="2736" height="1586" alt="4_before"
src="https://github.com/user-attachments/assets/41966e44-409a-4ae2-ada1-59992658f1b5"
/> | <img width="2736" height="1586" alt="4_after"
src="https://github.com/user-attachments/assets/f6df01f9-0702-4f28-80aa-eb2289077ea5"
/> |

</details>

<details>
<summary>5. Restore collision</summary>

| Steps | Before | After |
| --- | --- | --- |
| 1. Delete `a.txt` (to Trash)<br>2. Run `touch a.txt`<br>3. Undo | <img
width="2736" height="1586" alt="5_before"
src="https://github.com/user-attachments/assets/f4151e85-7668-4dab-8cf4-b45ef0fdb741"
/> | <img width="2736" height="1586" alt="5_after"
src="https://github.com/user-attachments/assets/3f25aa56-1b59-4230-9a15-b39a0d280a48"
/> |

</details>

<details>
<summary>6. Trash a file that's gone</summary>

| Steps | Before | After |
| --- | --- | --- |
| 1. Create `empty.txt` in the panel<br>2. Run `rm empty.txt`<br>3. Undo
| <img width="2736" height="1586" alt="6_before"
src="https://github.com/user-attachments/assets/077edeb8-3618-4b72-b49f-9d1cc3a801d5"
/> | <img width="2736" height="1586" alt="6_after"
src="https://github.com/user-attachments/assets/4b1d6689-93b1-4725-8829-2f71b4b586e9"
/> |

</details>

### Redo failures

<details>
<summary>7. Redo a move into an occupied destination</summary>

| Steps | Before | After |
| --- | --- | --- |
| 1. Move `a.txt` into `docs/`, then Undo (file back at root)<br>2. Run
`touch docs/a.txt`<br>3. Redo | <img width="2736" height="1586"
alt="7_before"
src="https://github.com/user-attachments/assets/d6591d08-b0a1-4992-866f-fcc26491ba8c"
/> | <img width="2736" height="1586" alt="7_after"
src="https://github.com/user-attachments/assets/b46d5fe2-09be-4264-9834-f5965f5f1150"
/> |

</details>

<details>
<summary>8. Redo a restore after the Trash was emptied</summary>

| Steps | Before | After |
| --- | --- | --- |
| 1. Create `empty.txt`, then Undo (it gets trashed)<br>2. Empty it from
the system Trash<br>3. Redo | <img width="2736" height="1586"
alt="8_before"
src="https://github.com/user-attachments/assets/9ced2696-1bdf-4b33-aaaf-abc015787505"
/> | <img width="2736" height="1586" alt="8_after"
src="https://github.com/user-attachments/assets/bfc84fc3-c97f-474d-857c-3d5137d06b83"
/> |

</details>

<details>
<summary>9. Redo a re-trash of a deleted file</summary>

| Steps | Before | After |
| --- | --- | --- |
| 1. Delete `a.txt` (to Trash), then Undo (restores it)<br>2. Run `rm
a.txt`<br>3. Redo | <img width="2736" height="1586" alt="9_before"
src="https://github.com/user-attachments/assets/3152787d-c02c-482e-a70a-600e97a44b3b"
/> | <img width="2736" height="1586" alt="9_after"
src="https://github.com/user-attachments/assets/7dd40497-0dfc-41fa-a6ac-772562d29258"
/> |

</details>

---

Release Notes:

- N/A
2026-07-28 12:22:11 +00:00
Kevin Bravo
4a1df1f7ca
markdown_preview: Open relative links at line (#60864)
Closes #60733

# Objective

Markdown Preview treats a relative `path:line[:column]` destination as a
literal filename. When that file does not exist, the link falls through
to the system URL handler instead of opening the workspace file at the
requested position.

## Solution

- Recognize position suffixes on relative Markdown links.
- Convert GitHub-style `#L42` fragments into the same positioned target
used by `path:42`, so both forms share one resolution and opening path.
- Resolve links with `workspace::path_link::possible_open_target` using
the Markdown source directory. This keeps the remote-project path
resolution added in #61438.
- Open resolved targets with `editor::items::open_resolved_target`,
including its one-based row and column handling.
- Preserve valid URI schemes and fall back to the existing Markdown link
behavior when no workspace target resolves.

## Testing

- Extended the Markdown Preview GPUI regression test to cover relative
`path:line:column`, GitHub-style `#Lline`, subfolder-relative
resolution, and custom URI schemes.
- `git diff --check` passes.
- The focused Rust test could not start in the current macOS environment
because the Rust toolchain binaries hang in the dynamic loader before
Cargo runs. PR Actions are awaiting maintainer approval.

## Self-Review Checklist:

- [x] I have reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed UI and icon guidelines
- [x] Tests cover the new and changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- Fixed Markdown Preview links using workspace-relative paths with line
and column suffixes.

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-07-28 05:45:13 +00:00
Ben Kunkle
94c6647995
Fix zoomed panels closing when focus moves within the panel (#59439)
Closes FR-139

Most focus-lost issues that close the agent panel in Zen mode stem from
panels returning a transient child editor's focus handle from
`Focusable::focus_handle`. The Zen-mode check closes the zoomed panel
when the focused element is not a descendant of the panel's focus
handle, so any focus movement inside the panel that landed outside that
child editor looked like the panel losing focus.

This PR separates the two roles that handle was serving:

- `Focusable::focus_handle` now always returns a stable handle tracked
at the panel's root element, used for containment checks (Zen-mode
auto-close, `toggle_panel_focus`, dock focus subscriptions).
- The new `Panel::activation_focus_handle` returns what should receive
focus when the panel is activated (e.g. a filter/commit/message editor)
and must be a focus-tree descendant of the root handle. All "focus the
panel" callsites in workspace/dock now use it.

Migrated panels: `AgentPanel` (including thread views and the toolbar
title editor), `CollabPanel`, `GitPanel`, `OutlinePanel`, and
`TerminalPanel` (previously delegated to the active pane, so focus in a
non-active pane dropped containment). `CollabPanel` activation falls
back to the panel root when signed out or collaboration is disabled,
since the filter editor isn't rendered in those states. Also fixes
duplicate element ids for tool calls with multiple content blocks.

Tests: a regression test that clicks tool-call output and focuses the
thread title editor while zoomed (both previously closed Zen mode), and
a dock-level test asserting the activation handle receives focus on
panel activation while the panel root reports containment.

Release Notes:

- Fixed zoomed panels (e.g. the agent panel in Zen mode) closing
unexpectedly when focus moved to elements inside the panel, such as tool
call output or the thread title editor.
2026-07-27 17:11:33 +00:00
Lukas Wirth
23cb8712ba
workspace: Retain panes while saving (#61683)
Save tasks can suspend while waiting for prompts, formatting, or
filesystem I/O. Holding only a WeakEntity<Pane> allowed the pane to be
released during those suspension points, surfacing an internal 'entity
released' error as a failed save.

Instead upgrade the pane once the save operation starts so we can ensure
it finishes.


---

Release Notes:

- N/A or Added/Fixed/Improved ...
2026-07-26 19:59:54 +00:00
Anthony Eid
dbdea58349
collab: Fix multiworkspace location out of sync bugs (#61598)
### Summary

This PR fixes three small bugs that could cause a multi-workspace's
reported location to be out of sync with its actual location, which
causes following to break in multiplayer collaboration sessions.

The first bug was that each child workspace's title bar within a
multi-workspace had its own `cx.observe_window_activation` subscription
that would set the associated child workspace's project location. This
caused problems because it ran for all child workspaces instead of just
the active workspace within the multi-workspace. The fix was moving
`cx.observe_window_activation` to the `cx.observe_new` call in the
`call` crate that tracks newly created windows/multi-workspaces.

The second bug was caused by an incorrect `if` statement in a
`MultiWorkspace` subscription that would return early if the window was
active and the event emitted by `MultiWorkspace` wasn't
`ActiveWorkspaceChanged`. This caused issues when the window was
inactive because it would incorrectly set the active call's location to
the wrong project. The fix was making the early return happen if the
window wasn't active.

The third bug was that every child `Workspace` also observed window
activation and called `update_active_view_for_followers`. This allowed
hidden workspaces to report their active view instead of only the active
workspace.

### Testing

I added a property test for bugs one/two and another prop test for bug 3


Release Notes:

- collab: Fix out of sync following bugs
2026-07-25 03:39:45 +00:00
saberoueslati
d23aaeebea
workspace: Rename read-only tab controls from File to Tab (#61202)
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
## Context

The editor tab's read-only controls used "File" terminology in their
tooltips and the tab context menu ("Make File Read-Only", "Locked File",
"Read-Only File", etc.). This was misleading in two ways: the option
also appears on unsaved and non-file tabs that have no file on disk, and
the toggle only controls whether the buffer is editable in the editor,
it does not change filesystem permissions. This renames the labels to
lock/unlock "Tab" language, matching the lock icon shown when the tab is
toggled.

Closes #60079.

Behavior after the change :

[Screencast from 2026-07-17
15-35-30.webm](https://github.com/user-attachments/assets/5fb018cb-515f-449c-a57e-0c0bead250bd)


## How to Review

1 file changed:

**crates/workspace/src/pane.rs**
Renames three sets of user-facing strings, all pure text changes with no
behavior change. The read-only toggle button tooltips become "Unlock
Tab" / "This will make this tab editable" and "Locked Tab" / "This tab
is read-only". The tab tooltip meta label becomes "Read-Only Tab". The
context menu entry, whose label already depends on
`capability.editable()`, becomes "Lock Tab for Editing" (when currently
editable) and "Unlock Tab for Editing" (when currently read-only); the
click handler still calls `toggle_read_only`, so the mapping from label
to action is preserved.

## 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
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- Improved read-only tab controls to use "Tab" instead of "File" in
tooltips and the tab context menu, since the toggle affects editability
in the editor rather than filesystem permissions.

---------

Co-authored-by: Nathan Sobo <nathan@zed.dev>
2026-07-24 22:54:30 +00:00
Richard Feldman
ec3d887507
gpui: Defer element arena clears while an enclosing draw is in progress (#60295)
GPUI allocates every element for a draw in a single per-App bump arena,
and `Arena::clear()` assumed no draw was in progress. But draws can
nest: on Windows, the window procedure re-enters whenever the main
thread pumps messages mid-draw (cross-thread `SendMessage` dispatch,
modal message loops entered by COM/OLE calls such as clipboard reads),
and on any platform a draw can be triggered from within another draw
(e.g. `open_window`). When a nested draw finished, its arena clear freed
and rewound memory the outer draw was still using. The `ArenaBox`
validity flag only guards new derefs, so `&mut` references already held
by the outer draw silently pointed into reused memory. That
use-after-free corrupted element-state keys
(`GlobalElementId`/`SharedString` Arcs) and heap metadata, crashing
later in innocent-looking frames — seen in the wild as
`EXCEPTION_ACCESS_VIOLATION_READ / 0xffffffffffffffff` in
`Frame::finish` and element allocation
([ZED-9QN](https://zed-dev.sentry.io/issues/7577818040/),
[ZED-7JC](https://sentry.io/organizations/zed-dev/issues/7465778926/),
[ZED-7C6](https://zed-dev.sentry.io/issues/7460258444/)), plus
occasional "attempted to dereference an ArenaRef after its Arena was
cleared" panics (ZED-96P, ZED-8XN), Windows-dominant and spanning
versions 1.1.7–1.8.2.

The fix makes the arena sound under nesting: `ElementArenaScope` tracks
a scope depth on the arena, and `Arena::clear()` is deferred while any
scope is active — the outermost draw's clear drops both draws'
allocations. Since arena chunks are stable heap blocks and allocation
only appends, nested allocation was already safe; the mid-draw clear was
the only destructive operation. Scopes are ended via a consuming
`exit(arena)` call that asserts arena identity (by pointer comparison,
never dereferencing), and `ArenaClearNeeded::clear(cx)` reaches the
arena through the App, so this bookkeeping contains no unsafe code
beyond what existed before. A panic that unwinds a draw balances the
scope depth in the guard's `Drop`, so later clears still run; only the
unwound draw's own clear token is never produced, leaving the arena
populated until the next draw's clear — a one-frame leak at worst, never
a use-after-free.

Additionally, draws are no longer run re-entrantly: GPUI's
`on_request_frame` callback skips requests that arrive while a draw is
already on the thread's stack (remembering `force_render` for the next
frame), and on Windows a `DrawCoordinator` owned by the platform and
shared with every window additionally guards the wider `draw_window`
span (presentation, IME updates). Deferred windows validate their update
region (so nested message pumps don't busy-loop on WM_PAINT) and are
repainted at most one vsync later by the vsync thread's existing
per-tick invalidation.

An integration test opens a window from within an element's paint;
without the deferred clear it reproduces the exact "ArenaRef after its
Arena was cleared" panic seen in the wild. Deferrals are logged so the
diagnosis can be confirmed from user logs.

Closes FR-110

Closes FR-114

Release Notes:

- Fixed a crash on Windows caused by re-entrant window drawing
corrupting UI element memory.
2026-07-22 15:25:22 +00:00
Smit Barmase
9d0ef37a25
markdown_preview: Fix relative links in remote Markdown subfolders (#61438)
Closes #58270

In remote projects, Markdown previews resolved relative links from the
project root instead of the Markdown file's folder. Links worked for
files in the root but could fail or open the wrong file for files in
subfolders.

Zed now resolves these links from the Markdown file's folder. The fix
updates base path handling in `open_url_or_file`. Only Markdown Preview
passes a base path to this function.

I tested it on macOS with a Linux SSH host and on Windows with WSL.

Release Notes:

- Fixed relative links in Markdown previews for files in subfolders when
using SSH or WSL.
2026-07-22 09:10:58 +00:00
David
4ebc1545d2
Fix workspace::ReopenLastPicker action when which_key helper is enabled (#61002)
Some checks are pending
Congratsbot / congrats (push) Blocked by required conditions
Congratsbot / check-author (push) Waiting to run
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
# Objective

Fixes #60612 

`workspace::ReopenLastPicker` should open the stashed picker _after_ the
active model is dismissed

## Solution

Queue reopen requests when another modal is active, then reveal the
stashed modal after `hide_modal` clears the layer. Reset queued reveals
when explicitly opening a new modal.

## Testing

Confirmed `ReopenLastPicker` keybind working even when which_key is
enabled with delay=`0ms`. Tested with file_finder and text_finder.

## 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:

- Fixed `workspace::ReopenLastPicker` when `which_key` helper menu is
enabled

Co-authored-by: Yara 🏳️‍⚧️ <git@yara.blue>
2026-07-22 01:11:53 +00:00
Ruslan Semagin
6b594a43b0
Show runnable task results in gutter (#61095)
# Objective

- Make runnable task results visible directly in the editor gutter after
running a test or task.
- This makes it easier to see whether the last run passed or failed
without looking at the terminal output.

## Solution

- Track the completion result for scheduled runnable tasks.
- Show the last runnable result in the gutter:
  - running task: accent play icon
  - successful task: success check icon
  - failed/cancelled task: error icon
- Apply the same status update path when running from the gutter play
button and from inline code lens actions such as `Run Test`.

## Testing

- Ran `cargo check -p editor -p workspace`.
- Ran `cargo test -p workspace
test_schedule_resolved_task_with_completion_reports_success`.
- Manually tested running a GPUI test from the gutter play button.
- Manually tested running a GPUI test from the inline `Run Test` code
lens.
- Verified the gutter icon updates after completion in both cases.

## 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

## Showcase

Before:
<img width="1897" height="691" alt="before"
src="https://github.com/user-attachments/assets/614c2811-ee0a-43c0-8619-d0301836aa62"
/>

After:
<img width="1897" height="691" alt="after"
src="https://github.com/user-attachments/assets/a3db19f2-71e6-4c9b-824d-43a4f020a6b7"
/>

---

Release Notes:

- Improved runnable tasks by showing the last run result in the editor
gutter.
2026-07-21 05:36:42 +00:00
Aks
8f6f8a54b9
Fix active pane border and pane opacity dimming showing simultaneously on editor panes and terminal panes (#56595)
When `active_pane_modifiers.border_size` is set in `settings.json`, both
the active editor pane and the active terminal pane would display a
border simultaneously, making it impossible to tell which pane actually
has focus. The pane opacity dimming also renders simultaneously before
this fix.

1. Before fix: impossible to tell which pane has focus
<img width="901" height="732" alt="image"
src="https://github.com/user-attachments/assets/cbcad798-0d72-420c-9585-2dafa867ff2b"
/>

2. After fix: only one pane has focus
<img width="902" height="731" alt="image"
src="https://github.com/user-attachments/assets/97f2238e-4789-41b3-97e3-98cb9a0c82ef"
/>

The root cause is that both the workspace center and the terminal panel
pass their own `active_pane` to `PaneRenderContext`, so each pane group
unconditionally marks its active pane for border rendering. The fix adds
a focus check so `active_pane_ix` is only set when the pane actually has
keyboard focus, ensuring only the truly focused pane gets the border
(and the inactive_opacity dimming applies correctly to unfocused
groups).

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 is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable


Release Notes:

- Fixed active pane border being drawn on both the editor pane and
terminal pane simultaneously

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-07-20 14:16:00 +00:00
Jakub Konka
339f4237c4
workspace: Fix crash when closing active item mid-update (#61336)
Closes https://github.com/zed-industries/zed/issues/61182

Supersedes https://github.com/zed-industries/zed/pull/61232

Closes FR-128

Release Notes:

- Fixed crash when closing active item while the workspace was
mid-update (double-lease panic).

Co-authored-by: apoorva-01 <vermaapoorva0510@gmail.com>
2026-07-20 12:39:07 +00:00
Agani Daniel .S
f7d9ae33b5
workspace: Rename "Discard" to "Discard Edits" in file conflict prompt (#55870)
When a file has unsaved edits and has also changed on disk, the conflict
prompt offered "Overwrite / Discard / Cancel". Both "Overwrite" and
"Discard" were directionally ambiguous, it wasn't clear whether the disk
contents or the buffer edits would be lost. "Discard Edits" makes it
explicit that the buffer edits are thrown away and the disk version is
reloaded.

Release Notes:

- Improved the file conflict prompt by renaming the "Discard" button to
"Discard Edits" to clarify that unsaved edits are discarded in favor of
the on-disk contents.

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-07-20 06:58:37 +00:00
Austin Cummings
339d96b5a8
Fix preview button acting on the focused editor instead of its own pane (#61218)
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
Closes #54951

## Problem

The quick action bar's preview button (markdown, SVG, and CSV behind the
feature flag) resolved everything through `workspace.active_item()` —
the globally *focused* item — instead of the item of the pane the button
sits in. With `A.md` in the left pane and focus in `B.md` in the right
pane:

- Clicking the eye button in **A.md's** toolbar opened a preview of
**B.md**, in the right pane.
- Focusing a non-previewable file (e.g. `B.sh`) in one pane hid the
button in **every** pane's toolbar, making `A.md` unpreviewable by
mouse.

Clicking the button dispatched the `OpenPreview` action, whose
workspace-level handler re-resolved the focused editor — so a click on a
specific pane's toolbar was functionally identical to pressing the
keybinding, discarding the pane the click happened in.

## Fix

Make the flow pane-explicit end to end:

- **Visibility:** each pane's `QuickActionBar` resolves the preview type
from its own `active_item` (set via `set_active_pane_item`) instead of
the workspace's focused item.
- **Click:** no more action dispatch. The handler resolves its pane via
`Workspace::pane_for` and calls new pane-explicit helpers —
`open_preview_in_pane` / `open_preview_to_the_side_of_pane` — extracted
from the action-handler bodies in all three preview crates. Keyboard
actions keep their focus-based semantics and route through the same
helpers with the focused editor and active pane.
- **Alt-click** (open in split) now splits relative to the button's pane
via the new `Workspace::adjacent_pane_of` (the existing `adjacent_pane`
delegates to it).

Notably *not* done: focusing the button's pane and re-dispatching the
action. `workspace.active_pane` only updates when pane focus-in
listeners fire at the end of the next draw, while dispatched actions run
before it — the handler would still read the stale pane.

## Additional changes

- Existing-preview lookup now happens **before** view construction,
instead of building a full preview view (subscriptions, initial parse)
and discarding it when one already exists.
- The `focus` flag now also applies to the activate-existing branch, so
open-to-the-side never steals focus — previously the *first* invocation
left focus in the editor but a *repeat* invocation focused the existing
preview (and cancelled collaborator-following in that pane as a side
effect).
- SVG handlers no longer double-check `is_svg_file`; CSV handlers reuse
`resolve_active_item_as_csv_editor` instead of inlining it;
`is_markdown_file` takes `&App` instead of a needless `&mut Context<V>`.

## Testing

- New regression test
`preview_opens_for_the_given_pane_not_the_focused_editor` reproducing
the issue's setup (two panes, focus in the second, preview invoked for
the first pane's editor), asserting the preview opens in the invoking
pane bound to that pane's editor with the focused pane untouched.
- Markdown/SVG/CSV preview suites and the full `workspace` suite pass;
`./script/clippy` is clean.

Release Notes:

- Fixed the preview button (Markdown/SVG) previewing the focused file
instead of the file in the pane the button belongs to when multiple
panes are open
2026-07-20 04:08:28 +00:00
ᴀᴍᴛᴏᴀᴇʀ
ac09219cad
workspace: Fix bottom dock clipping when resizing windows (#61161)
# Objective

Fixes #59983.

Reducing the Zed window height with the terminal open can clip the
Bottom Dock and terminal content. The dock should shrink to remain
within the workspace instead of extending beyond the window.

## Solution

Restore height clamping for Bottom Dock panels by skipping
`clamp_panel_size` only when a panel actually uses flexible width.
Flexible sizing remains unchanged for the Left and Right Docks, while
Bottom Dock panels once again reduce their stored height to fit the
available workspace.

## Testing

Added a regression test that distinguishes flexible Bottom and Right
Dock behavior. It confirms that the Bottom Dock is clamped while the
flexible-width Right Dock is not. The test failed with the previous
condition and passed with this change.

Manually verified the reported window-resizing scenario locally.


## 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

## Showcase

+ Before


https://github.com/user-attachments/assets/c56995a8-47c6-45b6-aeb4-b0b56477c737

+ After


https://github.com/user-attachments/assets/97b5ca6f-cf6f-4dd5-b981-e44bd8139490

---

Release Notes:

- Fixed bottom dock clipping when resizing windows.
2026-07-20 03:31:10 +00:00
Lukas Wirth
ab234b1946
workspace: Run possible_open_target logic on the background (#61257)
This is a lot of computation work which otherwise hangs the ui thread

Closes FR-122

Release Notes:

- Fixed a cause for ui hangs when interacting with the agent panel
2026-07-18 14:45:31 +00:00
Eric Holk
9d7ab04436
Round window corners on the sidebar side on Linux (#61229)
Some checks are pending
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
On Linux with client-side decorations, opening the workspace sidebar
squared off the window corners on the sidebar's side while the rest of
the window stayed rounded:

Before:
<img width="366" height="239" alt="image"
src="https://github.com/user-attachments/assets/e0ee8d28-6143-42ea-bfd2-10d069df5492"
/>

After:
<img width="426" height="219" alt="image"
src="https://github.com/user-attachments/assets/51d2979d-0103-4742-90bd-a97f5837d99b"
/>

Previously, `client_side_decorations` took a `border_radius_tiling`
override that `MultiWorkspace` used to deliberately square the window
shape on the sidebar's side, since the sidebar painted a square
background that would otherwise poke out past the rounded window border.
The title bar and status bar already skip rounding their corners on the
sidebar side, implying the sidebar is expected to own those window
corners — it just never rounded them.

This PR makes the sidebar round its outer corners the same way the title
bar and status bar do (including overlapping the 1px window border on
untiled edges to avoid a transparent gap in the rounded corners), and
removes the now-unneeded `border_radius_tiling` parameter so the window
border and backdrop round purely based on actual tiling state.

Only applies when the window uses client-side decorations, so macOS and
Windows are unaffected.

Fixes #54724 

Release Notes:

- Fixed square window corners on the sidebar side of client-decorated
(Linux) windows when the workspace sidebar is open.

---------

Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com>
2026-07-17 23:58:06 +00:00
Daniel Strobusch
93b846b2a6
file_finder: Add include_ignored parameter to Toggle action (#59568)
# Objective

Allow keybindings to open the file finder with ignored files
pre-included, regardless of the global `file_finder.include_ignored`
setting:

```json
  {
    "bindings": {
      "ctrl-shift-o": ["file_finder::Toggle", { "include_ignored": true }]
    }
  }
```

Closes https://github.com/zed-industries/zed/discussions/42575

## Solution

- Describe the solution used to achieve the objective above.

## Testing

- Did you test these changes? If so, how?
   manually locally and a unit test.
- Are there any parts that need more testing?
  no
- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
   no
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?
  macOS

## 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

## Showcase

> This section is optional. If this PR does not include a visual change
or does not add a new user-facing feature, you can delete this section.

- Help others understand the result of this PR by showcasing your
awesome work!
- If this PR includes a visual change, consider adding a screenshot,
GIF, or video
- A before/after comparison is very useful for changes to existing
features!

While a showcase should aim to be brief and digestible, you can use a
toggleable section to save space on longer showcases:

<details>
  <summary>Click to view showcase</summary>

My super cool demos here

</details>

---

Release Notes:

- Added `include_ignored` parameter to `file_finder::Toggle` action,
allowing keybindings to open the file finder with ignored files
pre-included.

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-07-16 10:30:16 +00:00
i18u
40102ee7c2
workspace: Prevent overwriting window bounds when window is not active (#60950)
# Objective

- Prevent the Zed window height from shrinking to the built-in MacBook
screen's height after macOS screen lock or display sleep in
multi-monitor setups.
- Related to #41246.

## Solution

- Ignore window bounds change events in `observe_window_bounds` if the
window is currently inactive (`!window.is_window_active()`).
- **Explanation**: When the system locks or sleeps, macOS reconfigures
displays (monitors power down, and macOS temporarily treats the built-in
screen as the only primary display). This triggers a resize event on
inactive Zed windows to fit them onto the built-in display. Because the
window was inactive, the `observe_window_bounds` listener still
triggered and scheduled `save_window_bounds`, immediately overwriting
the workspace database with the temporary shrunk dimensions.
- By ignoring bounds updates when the window is inactive, we preserve
the correct original bounds in the database. Since a user-initiated
resize/move always activates/focuses the window first, bounds will still
be correctly persisted for intentional manual updates.

## Testing

- Yes, tested locally on macOS (Sequoia).
- Verified that compiling the `workspace` crate succeeds (`cargo check
-p workspace`).
- Ran all 220 unit tests in the `workspace` crate (`cargo test -p
workspace`), and all passed successfully.
- **How to test**:
1. Open Zed on an external monitor and set it to a large size (or
maximize).
  2. Lock the screen (or let the displays sleep).
  3. Wake/unlock the screen.
4. Verify that the window recovers and maintains its original height
instead of shrinking.

## 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:

- Fixed an issue where the Zed window would shrink to the built-in
display's height on macOS after screen lock or display sleep in
multi-monitor setups.

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-07-16 10:06:41 +00:00
Shuhei Kadowaki
367cd75963
workspace: Add visual indicator for editor zoom (#61039)
The earlier editor-only zoom implementation in #32860 rendered the
active pane with padding, a border, rounded corners, and a shadow. In
addition to keeping docks visible, that treatment made the transient
editor zoom mode apparent.

The current `ToggleEditorZoom` implementation (#53911) only omits
sibling panes from the pane group, without any visual indication.
Without a persistent control or decoration, the result can look like an
ordinary single-pane layout, so users cannot tell whether toggling the
command will restore hidden splits.

So this commit renders the maximized pane as an inset card with padding,
a subtle theme border, rounded corners, and a shadow. Keeping this
treatment in `PaneGroup` makes it apply only to editor zoom, leaves
docks untouched, and distinguishes it from `ToggleZoom`'s square
workspace overlay.

## Showcase

<img width="862" height="415" alt="Screenshot 2026-07-15 at 18 51 30"
src="https://github.com/user-attachments/assets/f61c61ce-79b7-4e3a-a9c4-0775931fa90d"
/>

---

Release Notes:

- N/A

---------

Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
2026-07-15 23:21:16 +00:00
Lukas Wirth
f181a2f47b
Split out RelPath into a separate crate (#61029)
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 ...
2026-07-15 08:33:25 +00:00
Xin Zhao
febe242c0b
workspace: Fix toolchain not recovered correctly in remote development (#60030)
# Objective

Closes #55925
Closes #59094

When a Python project is opened and a toolchain is selected, Zed
stores/persists this choice in the database. When the project is
reopened later, that saved toolchain should be automatically selected.
However, this recovery mechanism requires the associated worktree to be
loaded first.

In local development, the worktrees are loaded first, after which the
toolchain is restored and activated:

afaef857b9/crates/workspace/src/workspace.rs (L1916-L1955)

But in remote development, the toolchain restoration block runs at the
very beginning of initialization, before any worktrees are loaded:

afaef857b9/crates/workspace/src/workspace.rs (L10381-L10413)

Because the worktree does not exist yet when the toolchain is processed,
`find_worktree` always returns `None`, and the saved toolchain is never
activated. This breaks toolchain persistence for remote workspaces.

## Solution

Move the toolchain activation block in `open_remote_project_inner` so it
runs after the worktrees have been loaded, matching the sequence used in
`new_local`. This ensures the worktree is present in the project when we
perform the ID lookup and activate the toolchain.

## Testing

Tested locally with a Windows client connecting to a remote Linux
server, verifying that the previously selected virtual environment is
correctly restored upon reopening the workspace.

## 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)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

---

Release Notes:

- Fixed Python virtual environments not automatically restoring when
reopening a remote development workspace.

Co-authored-by: Lukas Wirth <lukas@zed.dev>
2026-07-15 08:28:00 +00:00
Ollie Rutherfurd
fca4016aef
workspace: Add ToggleEditorZoom action to maximize active pane (#53911)
VS Code has a command called "Toggle Maximize Editor Group" (`Cmd+K
Cmd+M`) that expands the active editor pane to fill the entire center
area, hiding editor split panes, but leaving docks and panels visible.
Zed's existing `ToggleZoom` hides all panels and is closer to VS Code's
Zen Mode. VS Code has both — it would be useful for Zed to as well.

This is particularly useful for people working on laptops, and has been
raised before (#32715, #4897, #32860), but the addition of the project
panel alongside the agent panel has made it more relevant. I work with
the editor split vertically, but with the project and agent panels both
visible, on a laptop screen there's really only room for a single editor
pane. This command makes it easy to switch to and from that mode.

**Behavior:**
- New action: `workspace::ToggleEditorZoom`
- When activated, the active editor pane expands to fill 100% of the
center/editor area, hiding sibling split panes
- Docks and panels remain visible and unaffected
- Toggling again restores the previous split layout
- If `ToggleZoom` is active, it unzooms first, then maximizes

Here's a demo:


https://github.com/user-attachments/assets/fcf6748e-6c45-4c4a-8d9f-f106c6cd58ea

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 is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Closes #32715

Release Notes:

- Added `workspace::ToggleEditorZoom` action to maximize the active
editor pane within the center area while keeping panels visible.
2026-07-14 20:36:17 +00:00
Kirill Bulatov
d06ebb7c03
Disable all spinners in Zed (#60614)
Closes https://github.com/zed-industries/zed/pull/48577
Part of https://github.com/zed-industries/zed/issues/8043
See
https://zed-industries.slack.com/archives/C07NUKHLVUZ/p1783335475957139
for context.

Release Notes:

- Allow to reduce animations with `"reduce_motion": "on"` settings
2026-07-14 14:49:06 +00:00
Cameron Mcloughlin
2268045a11
a11y: Landmarks and menu improvements (#60397)
Fixes menu a11y, and adds landmarks with `F6`-navigation.

Also fixes a GPUI bug, and adds debug actions for dumping a11y tree
info.

Since `F6` was already in use by the pause debugger keybind, also
tightens up the debugger keybind context so they require an active
debugger session. When there is one active, `F6` stays as pause
debugger. `ctrl-F6` always works to go to the next landmark.

Also adds an "accessible mode" setting. Currently, this only controls
whether we show all menus all the time, but I suspect it will expand
significantly in the future.

Also adds `.aria_keyshortcuts()` API, but it's not wired up within
accesskit adapters, so is not yet reported to screen readers.

---

Release Notes:

- N/A or Added/Fixed/Improved ...
2026-07-13 16:37:28 +00:00
Mikayla Maki
74b5207744
Unify Render and RenderOnce into View (#58087)
This allows us to build powerful and flexible Input and TextArea
components

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 is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- N/A

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 15:52:48 +00:00
liam
d4dfe87ce0
workspace: Skip closed items that cannot be reopened (#56299)
Resolves https://github.com/zed-industries/zed/issues/55600

This diff fixes `pane::ReopenClosedItem` getting stuck when the
closed-item stack contains entries that cannot be reopened, such as
Project Search, untitled buffers, or Default Settings. Previously,
`Workspace::navigate_history_impl` would pop the newest closed entry and
stop if that item was no longer present in the pane and had no path
recorded for reopening. That made `cmd- shift-t` appear to do nothing
until enough attempts had consumed those unreopenable entries.

With this change, closed-item navigation keeps scanning when it
encounters an entry that cannot be activated or reopened by path. This
preserves the current path-based reopening behavior for normal files,
while avoiding no-op shortcuts caused by non-file items in the closed
stack.

This made me wonder whether or not we'd eventually want full reopen
support for non-traditional items like Project Search or bundled
settings editors. Supporting that properly would require storing
item-specific restoration state, such as search query/options for
Project Search or a bundled-file descriptor for Default Settings, and
teaching closed-item navigation how to recreate those items from that
state. Something definitely out of scope for this PR.

| Before | After |
| --- | --- |
| <video
src="https://github.com/user-attachments/assets/c7044423-4531-4857-84f2-4e9651826c6a"
controls width="500" title="Before"></video> | <video
src="https://github.com/user-attachments/assets/c89dcefb-1796-4cdf-bb21-f165145e678e"
controls width="500" title="After"></video> |

Release Notes:
- Fixed reopening closed tabs getting stuck on closed items that cannot
be reopened.
2026-07-08 11:57:02 +00:00
Shreyash Saitwal
811fe501a7
workspace: Fix missing icons on non-terminal tabs during drag (#53637)
Previously, only terminal tabs displayed their icon while being dragged,
all other tab types showed just the label, making the drag preview
inconsistent with the actual tab appearance.


https://github.com/user-attachments/assets/7c055945-79d6-4f6e-8969-279a4fb1ff58

This PR fixes that by rendering each tab's icon alongside its label, so
the dragged preview now accurately reflects the tab regardless of type.


https://github.com/user-attachments/assets/3ad5a99b-5ba7-41d2-a6b3-51101b1f9650

Release Notes:

- Fixed missing icons on non-terminal tabs when dragging

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-07-07 09:29:38 +00:00
Salman Farooq
5d6c88cdb7
workspace: Use ellipsis character in "New" tooltip (#60467)
Explanation by @danilo-leal at
https://github.com/zed-industries/zed/pull/60181#issuecomment-4866118310

## Testing

Ran with `cargo run` and tooltip appears correctly.

## Release Notes:

- N/A
2026-07-06 15:56:59 +00:00
Anant Goel
ea87b05794
Fix worktree grouping for bare checkouts (#59968)
Summary

- Track whether a worktree root is itself a linked Git worktree.
- Use that metadata when computing project group keys so bare checkout
worktrees group under the repository identity path.
- Propagate the metadata through remote worktree protocols and add
local/remote regression coverage.

Background

Bare checkout layouts can place linked worktrees under the repository
identity directory, e.g. `/monty/.bare` with worktrees like
`/monty/feature-a`. We were treating those linked worktree paths as
separate project identities, which caused the sidebar to move agent
threads under the active worktree instead of the shared repository
group.
We also exclude adding this to collab intentionally, we can open a
different PR for that if we need to.

Closes #59910
Closes AI-431

Test Plan

- `cargo fmt --package project --package worktree --package
remote_server --package workspace --package collab --package proto`
- `git --no-pager diff --check`
- `cargo test -p project test_project_group_key -- --nocapture`
- `cargo test -p remote_server test_remote_root_repo_common_dir --
--nocapture`
- `cargo test -p worktree remote_worktree -- --nocapture`
- `cargo test -p workspace
test_remote_project_root_dir_changes_update_groups -- --nocapture`
- `cargo check -p collab`

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

Release Notes:

- Fixed agent thread/sidebar grouping for Git worktrees backed by bare
checkouts.

---------

Co-authored-by: Anthony Eid <anthony@zed.dev>
2026-07-02 18:14:11 +00:00
Smit Barmase
7eb4cb2bfa
workspace: Fix panic when discarding a draft workspace (#60279)
To reproduce:

1. Open a git project with the agent sidebar, ideally with no other
threads in the sidebar.
2. Create a thread in a new git worktree and type into it without
sending.
3. While still in that worktree workspace, hit New Thread. The parked
draft must now be the last activatable entry in the sidebar.
4. Hover the parked draft → click Discard Draft
5. 💥

Release Notes:

- Fixed a panic when discarding a draft workspace.
2026-07-02 13:13:46 +00:00
Sudarsh
f964172a69
project_panel: Wrap filenames in code spans in confirmation dialogs (#53068)
Closes #53060 

Filenames with double underscores (e.g. __init__.py) were rendered as
Markdown bold in confirmation dialogs because the prompt renderer
interprets the message as Markdown. Wrap filenames in backticks so they
render as inline code instead.

Release Notes:
- Fixed filenames with double underscores rendering as bold in project
panel confirmation dialogs
 
 

<img width="327" height="186" alt="image"
src="https://github.com/user-attachments/assets/ea178055-e7e9-4a4c-80de-587fda53d894"
/>
<img width="328" height="129" alt="image"
src="https://github.com/user-attachments/assets/de93eb43-da71-41b1-9bb2-c02b86205051"
/>
<img width="329" height="175" alt="image"
src="https://github.com/user-attachments/assets/eed19f8a-1a99-4485-abf6-57c506e01e00"
/>

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-07-02 09:11:26 +00:00