Closes#51417
I noticed this bug in the settings menu where when I opened the settings
menu, I could not scroll down through all the available options, eg. on
the initial page I wasn't able to scroll down to privacy. When I saw
that no one else had reported this issue, I figured it may be due to my
setup, and it turns out that using Aerospace, the window manager I use,
was what made this bug visible to me. Because aerospace resizes the
window right after it launches, the originally computed heights for the
list are incorrect, meaning the scroll bar is the wrong size as well.
in the relevant code there was a comment that says "If the width of the
list has changed, invalidate all cached item heights" which wasn't
incorrect per-se, but it just invalidated them without triggering any
re-computation, causing incorrect scroll bars.
My intuition is that window resizes/events that change the width of the
list bounds are fairly rare, so there shouldn't be a large performance
hit from the change.
Also implemented a test that directly showcases the behavior, if you run
the test without the change it fails, as the max_offset_for_scrollbar
will be wrong.
Videos:
Before
https://github.com/user-attachments/assets/2b680222-7071-4098-863f-519361f0756a
After:
https://github.com/user-attachments/assets/1222a299-23d7-4007-8e88-55d2daccce64
[x] Tests
[x] Video of behavior
Release Notes:
- gpui: fixed list height re-computation when the list width changes.
- **Fix race condition in test_collaborating_with_completion**
- **WIP: Integrate scheduler crate into GPUI TestDispatcher**
- **WIP: scheduler integration debugging**
- **Fix formatting**
- **Unify RunnableMeta and add execution tracking to TestScheduler**
- **Remove unused execution tracking from TestScheduler and
TestDispatcher**
- **Add is_ready() to GPUI Task for API parity with scheduler**
- **Eliminate RunnableVariant::Compat - all runnables now have source
location metadata**
- **Update integration plans to reflect completed phases**
- **Simplify RunnableVariant to type alias**
- **Delegate TestDispatcher task queues to TestScheduler (Phase 2b)**
- **Remove waiting_hint/waiting_backtrace and debug logging from
TestDispatcher**
- **Remove wrapper methods from TestDispatcher - access scheduler()
directly**
- **Update integration plan with complete state and instructions for
full scheduler migration**
- **Use scheduler's native timer() and simplify TestDispatcher**
- **Fix rng() usage to lock mutex, update plan with SharedRng wrapper**
- **Add SharedRng wrapper for ergonomic random number generation**
- **Update plan: mark Phase 1 (SharedRng) as complete**
- **Update scheduler integration plan with Phase 2 investigation notes**
- **Phase 3: Delegate simulate_random_delay to
scheduler.yield_random()**
- **Phase 4: Remove TaskLabel**
- **Phase 5 (WIP): Simplify block_internal and remove unparkers**
- **Phase 5 Complete: Scheduler integration finished**
- **Update integration plan with code review findings**
- **Phase 6 & 7: Restore realtime priority support and delete dead
code**
- **Add TestApp and TestAppWindow for cleaner GPUI testing**
- **Fix formatting across the branch**
- **Fix Linux build: add explicit type annotation and rename
probability() to weight()**
- **Add TestApp and TestAppWindow for cleaner GPUI testing**
- **Rename TestAppWindow to TestWindow, internal TestWindow to
TestPlatformWindow**
- **Remove unused RunnableVariant imports on Linux**
- **Add STATUS.md for next agent**
- **Run cargo fmt**
- **Use per-app element arena only and scope test draws**
- **Fix collab tests for scheduler timing and ordering**
- **Store element arena on App and route element allocations through
draw scope**
- **Fix TestScheduler lock ordering between rng and state**
- **Fix inlay hints test by explicitly triggering refresh after viewport
setup**
- **Add scheduler integration regression risk analysis doc**
- **Fix tests: avoid caching Entity in global OnceLock for Codestral API
key**
- **Document learned weak point: global cached Entity handles break
across App contexts**
- **Add scheduler regression test for block_with_timeout continuation
and explicit time advancement**
- **Document TestScheduler timeout tick budget behavior and explicit
time advancement guidance**
- **Add test asserting realtime priority spawns panic under
TestDispatcher**
- **Document realtime priority determinism contract in tests**
- **Remove realtime priority until we have a concrete use case (cc
@localcc)**
- **Update STATUS for scheduler integration decisions and realtime
priority removal**
- **Fix prettier docs and clippy in scheduler tests**
- **Remove unused imports from Windows dispatcher**
- **WIP: scheduler integration debugging + agent terminal diagnostics**
- **Update scheduler integration status**
- **Remove temporary planning docs, consolidate into scheduler
integration doc**
- **Remove unrelated changes from scheduler integration**
- **Fix clippy errors**
- **Add STATUS.md with debugging instructions for Linux/Windows hang**
- **WIP: local changes needed by ex**
- **Add pointer capture API for stable drag handling**
- **Add pointer capture API for stable drag handling**
- **chore: update generated cargo manifests**
- **gpui: Expose ShapedLine::width() for pen advancement**
- **Remove git2 usage from util test.rs**
- **Store DiagnosticQuad bounds in logical Pixels**
- **WIP: executor and test_app changes for scheduler integration**
- **Expose font APIs publicly**
- **gpui: add typed diagnostics and record_diagnostic API**
- **WIP: gpui test window diagnostics changes**
- **Add LineCacheKey trait and shape_line_cached API for
content-addressable shaping**
- **Fix RenderGlyphParams field additions for Ex compatibility**
- **Add doc comment for recommended_rendering_mode, fix formatting**
- **Add scheduler_executor() method for Ex compatibility**
- **Fix TestWindow -> TestPlatformWindow in test_context.rs**
- **Add headless metal renderer and window focus improvements**
- **Fix double borrow in TestWindow::simulate_resize**
- **Fix cbindgen panic: remove default type parameter from
Diagnostic<T>**
- **Implement AppContext for HeadlessMetalAppContext**
- **Missing trait impls**
- **Add ShapedLine::split_at and eliminate re-shaping in soft wraps**
- **Add handoff doc for platform-neutral-tests merge**
- **Remove ex-only test infrastructure before merging main**
- **Add cross-platform HeadlessAppContext with pluggable text system**
- **Export platform_text_system() from gpui_windows for cross-platform
tests**
- **Restore TestApp/TestAppWindow with pluggable text system support**
- **Add TestApp::open_window_sized for tests that need specific window
dimensions**
- **Fix some warnings**
- **Fixes**
- **Add a platform-neutral headless renderer interface**
- **Synchronize Managed texture before CPU readback on discrete GPUs**
- **Allow creating TestDispatcher with custom scheduler**
Release Notes:
- N/A
---------
Co-authored-by: Nathan Sobo <nathan@zed.dev>
Co-authored-by: John Tur <john-tur@outlook.com>
Co-authored-by: Agus Zubiaga <agus@zed.dev>
Co-authored-by: Antonio Scandurra <me@as-cii.com>
# Summary
This PR simply adds the missing `aspect_ratio` and `aspect_square`
helper functions to the `Styled` trait.
Release Notes:
- N/A
Co-authored-by: MrSubidubi <finn@zed.dev>
This will help with test times (in some cases), as nextest cannot figure
out whether a given rdep is actually an alive edge of the build graph
Closes #ISSUE
Before you mark this PR as ready for review, make sure that you have:
- [ ] Added a solid test coverage and/or screenshots from doing manual
testing
- [ ] Done a self-review taking into account security and performance
aspects
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A
Fixes#42444
- Changed `accepts_text_input` on the editor to be more precise.
Previously, it returned `true` only in insert mode. Now it also returns
`true` when an operator is pending.
- On Windows, we disable the IME whenever there is no input handler
which `accepts_text_input`.
- How this improves Vim mode: in insert mode, the IME is enabled; in
normal mode, it is disabled (command keys are not intercepted); when an
operator is pending, the IME is re-enabled.
Release Notes:
- On Windows, the IME is disabled in Vim normal and visual modes.
Updates #50970
While investigating the executor shutdown code, Claude noticed that we
never
actually drop the app because of a reference cycle.
Release Notes:
- N/A
Co-Authored-By: Eric Holk <eric@zed.dev>
In app drop we had been calling `.close()` on the executors. This caused
problems with the BackgroundExecutor on Linux because it raced with
concurrent work: If task A was running and about to poll task B, the
poll to task B would panic with "Task polled after completion". This
didn't really matter (because the app was shutting down anyway) but
inflated our panic metrics on Linux.
It turns out that the call to `.close()` is not needed. It was added to
prevent foreground tasks being scheduled after the app was dropped; but
on all platforms the App run method does not return until after the
ForegroundExecutor is stopped (so no further tasks will run anyway).
The background case is more interesting. In test code it didn't matter
(the background executor is simulated on the main thread so tests can't
leak tasks); in app code it also didn't really make a difference. When
`fn main` returns (which it does immediately after the app is dropped)
all the background threads will be cancelled anyway.
Further confounding debugging, it turns out that the App does not get
dropped on macOS and Windows due to a reference cycle; so this was only
happening on Linux where the app quit callback is dropped instead of
retained after being called. (Fix in #50985)
Release Notes:
- N/A
---------
Co-authored-by: Eric Holk <eric@zed.dev>
Closes#50624
The empty bottom section of the project panel showed a horizontal
scrollbar on hover, but scrolling didn't work there. Added a scroll
wheel handler to the blank area that forwards scroll events to the
uniform list's scroll handle, making both horizontal and vertical
scrolling work from anywhere in the panel.
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/zedindustries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- Fixed project panel empty area showing a non-functional scrollbar;
scrolling now works from anywhere in the panel
---------
Co-authored-by: MrSubidubi <finn@zed.dev>
Deferred draws previously didn't use a content mask, so you could
horizontally scroll an EP popover all the way out of the containing
pane.
This also affects other UI elements that use the deferred draw system; I
think in practice it doesn't make much difference because most of those
seem to require something in the editor to be hovered, so if you scroll
horizontally the element goes away.
Release Notes:
- Fixed being able to scroll the edit prediction popover out of the
containing pane.
This does not yet allow for finding task <-> entity cycles
unfortunately, but at least it does catch entity <-> entity cycles for
the time being
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Implements a basic web platform for the wasm32-unknown-unknown target
for gpui
Release Notes:
- N/A *or* Added/Fixed/Improved ...
---------
Co-authored-by: John Tur <john-tur@outlook.com>
Should close#49566
Inside `on_request_frame`, it’s conceptually incorrect to update the
application directly. Instead, we should read the thermal state through
the window handle, just like in the rest of the callback. That path uses
`try_borrow_mut` internally, so if the application is already being
updated elsewhere, we can safely skip checking the thermal state for
that frame and retry on the next one.
Before you mark this PR as ready for review, make sure that you have:
- [ ] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A
Closes #ISSUE
Before you mark this PR as ready for review, make sure that you have:
- [ ] Added a solid test coverage and/or screenshots from doing manual
testing
- [ ] Done a self-review taking into account security and performance
aspects
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A
Closes #ISSUE
Before you mark this PR as ready for review, make sure that you have:
- [ ] Added a solid test coverage and/or screenshots from doing manual
testing
- [ ] Done a self-review taking into account security and performance
aspects
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A
#2874 on steroids
Before you mark this PR as ready for review, make sure that you have:
- [ ] Added a solid test coverage and/or screenshots from doing manual
testing
- [ ] Done a self-review taking into account security and performance
aspects
- [ ] 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: Eric Holk <eric@zed.dev>
Closes#49172
- Fixes a regression on X11 where content size was divided by the scale
factor twice after the wgpu migration, causing half-sized rendering on
HiDPI screens.
- Aligns X11 [content_size()] behavior with Wayland by returning logical
pixel bounds directly.
Video :
[Screencast from 2026-02-14
18-58-36.webm](https://github.com/user-attachments/assets/cf4edf3b-7b93-4ded-bf46-e900be44b22b)
Release Notes:
- N/A
Delete all the hacks and do things properly instead.
Closes https://github.com/zed-industries/zed/issues/45574
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
Release Notes:
- N/A
Follow-up to #49187.
Instead of silently skipping updates when `try_borrow_mut` fails, this
PR defers the update by spawning it on the foreground executor. This
ensures the state change is eventually processed after the current
borrow completes.
Release Notes:
- N/A
The `on_thermal_state_change` and `on_keyboard_layout_change` callbacks
in `App::new_app()` called `borrow_mut()` unconditionally. These
callbacks are invoked asynchronously by macOS via dispatch queues when
the system's thermal or keyboard state changes, which can happen while
the app's RefCell is already borrowed during an update cycle, causing a
panic.
This change uses `try_borrow_mut()` instead. If the borrow fails
(because the app is already borrowed), the callback silently skips the
update - the state can be queried on the next frame.
Fixes [ZED-4WM](https://zed-dev.sentry.io/issues/ZED-4WM)
Closes#49181
Release Notes:
- Fixed a crash on macOS caused by thermal or keyboard layout state
changes occurring during UI updates.
on windows 10, When a laptop is plugged into or unplugged from a
monitor, Zed and my using GPUI app will restore from minimized state to
the foreground.
Closes #ISSUE
- [ ] Tests or screenshots needed?
- [ ] Code Reviewed
- [ ] Manual QA
Release Notes:
- N/A *or* Added/Fixed/Improved ...
---------
Co-authored-by: John Tur <john-tur@outlook.com>
Here's some backstory:
* on macOS, @cole-miller and I noticed that since roughly Oct 2025, due
to some changes to latest macOS Tahoe, for any spawned child process we
needed to reset Mach exception ports
(https://github.com/zed-industries/zed/issues/36754 +
https://github.com/RemiKalbe/zed/commit/6e8f2d2ebe5a93753625a3026aeb996de8cb436b)
* the changes in that PR achieve that via `pre_exec` hook on
`std::process::Command` which then abandons `posix_spawn` syscall for
`fork` + `execve` dance on macOS (we tracked it down in Rust's std
implementation)
* as it turns out, `fork` + `execve` is pretty expensive on macOS
(apparently way more so than on other OSes like Linux) and `fork` takes
a process-wide lock on the allocator which is bad
* however, since we wanna reset exception ports on the child, the only
official way supported by Rust's std is to use `pre_exec` hook
* posix_spawn on macOS exposes this tho via a macOS specific extension
to that syscall `posix_spawnattr_setexceptionports_np` but there is no
way to use that via any standard interfaces in `std::process::Command`
* thus, it seemed like a good idea to instead create our own custom
Command wrapper that on non-macOS hosts is a zero-cost wrapper of
`smol::process::Command`, while on macOS we reimplement the minimum to
achieve `smol::process::Command` with `posix_spawn` under-the-hood
Notably, this changeset improves git-blame in very large repos
significantly.
Release Notes:
- Fixed performance spawning child processes on macOS by always forcing
`posix_spawn` no matter what.
---------
Co-authored-by: Cole Miller <cole@zed.dev>
Closes https://github.com/zed-industries/zed/issues/33430
Two changes:
1. Fix `observe_global_in` to not permanently remove observers when the
window is transiently unavailable (e.g. temporarily taken during a
nested update). Previously this returned false and silently removed the
observer from the subscriber set. Now it checks whether the entity is
actually dropped before removing — if the entity is alive but the window
is just unavailable, it keeps the observer alive.
2. Extend `dock_to_preserve` in `handle_pane_focused` to also preserve
docks whose active panel has focus, not just docks whose panel's inner
pane matches the focused pane. Panels like `AgentPanel` don't implement
`pane()` (only panels like `TerminalPanel` that contain panes do), so
the existing preservation logic never identified the agent panel's dock
as needing protection. This meant that when the agent panel was zoomed
and a center pane received focus (e.g. during macOS window activation
events), `dismiss_zoomed_items_to_reveal` would close the dock, making
the panel disappear unexpectedly.
Closes AI-16
Release Notes:
- Fixed agent panel unexpectedly closing when zoomed and the window
regains focus.
`read_fd` calls `File::from_raw_fd(fd.as_raw_fd())`, which creates a new
`File` that assumes ownership of the raw fd, while the original
`FileDescriptor` also retains ownership. when both drop at the end of
the function, the same fd is closed twice. between the two closes
another thread can receive that fd number from the kernel for an
unrelated file/socket, and the second close silently kills it. this can
cause hard to diagnose data corruption or i/o failures.
fix: use `fd.into_raw_fd()` instead of `fd.as_raw_fd()` to transfer
ownership to the `File` without running `FileDescriptor`'s drop.
Release Notes:
- N/A
Release Notes:
- N/A
Make this change to let `div().child(...)` support any types that have
impl `Into<SharedString>`, for example: `Cow<'static, str>`.
```rs
// From somewhere get a `Cow<'static, str>` type.
let label = Cow::Borrowed("Hello");
div()
.child(label);
```
## Summary
Fixes an issue where GPUI's handling of `WM_NCLBUTTONDOWN` prevented
Windows from processing default titlebar interactions (dragging, caption
buttons, and border resize).
## Changes
- Allow OS to handle `WM_NCLBUTTONDOWN` events for `HTCAPTION`, caption
button areas, and resize border areas (`HTLEFT`, `HTRIGHT`, `HTTOP`,
`HTBOTTOM`, `HTTOPLEFT`, `HTTOPRIGHT`, `HTBOTTOMLEFT`, `HTBOTTOMRIGHT`)
- Use current cursor position in `WM_NCHITTEST` for accurate hit-testing
## Testing
- Manual testing on Windows: titlebar dragging works
- Manual testing on Windows: minimize/maximize/close buttons work
- Manual testing on Windows: window border resize works in all
directions
Release Notes:
- N/A
Closes#47489
The search worker pool was sized as `num_cpus - 1`, which spawned zero
workers when a devcontainer exposed only 1 CPU. All search channels
closed immediately and the search yielded zero results, while file
finder and LSP symbols worked fine.
The fix ensures at least 1 worker is always spawned: `(num_cpus -
1).max(1)`. A `num_cpus` override on `TestDispatcher` and a new test
reproduce the bug with `server_cx.executor().set_num_cpus(1)`.
## Manual testing
Add a `.devcontainer/` directory to a new project with these files:
```
// docker-compose.yml
services:
dev:
image: debian:bookworm-slim
cpuset: "0"
volumes:
- ..:/workspace:cached
command: sleep infinity
```
```
// devcontainer.json
{
"name": "zed-sandbox (1 CPU)",
"dockerComposeFile": "docker-compose.yml",
"service": "dev",
"workspaceFolder": "/workspace"
}
```
Build zed and point it at the new project:
```
cargo run -p zed -- ~/Repos/zed-sandbox-project
```
Open the built-in terminal, confirm `nproc` prints `1`.
Finally, run a project search (`Cmd+Shift+F`) and search for contents
that exist in it.
Results should appear 🎉
Release Notes:
- Fixed project search returning no results in devcontainers with a
single visible CPU.
after a successful file drag-drop, conclude_drag_operation did not reset
external_files_dragged to false. since dragging_exited (the only place
that resets this flag) is never called for successful drops (only for
cancelled ones), the flag stayed true permanently. this caused synthetic
drags (used for text selection during buffer scrolling) to be suppressed
for the lifetime of the window.
Release Notes:
- N/A
---------
Co-authored-by: MrSubidubi <finn@zed.dev>
Apple recommends checking the system’s thermal state and adjusting
behavior to reduce resource usage, giving the system a chance to cool
down. While this API is macOS-specific, the same idea likely applies to
other platforms - those are intentionally out of scope for this PR.
As a first step, we cap the frame rate at 60 fps when the system reports
a critical thermal state. In that situation, pushing higher frame rates
doesn’t buy us anything and just adds more heat. This also gives us a
hook for future improvements, like reducing other work when the system
is under sustained thermal pressure.
Ref:
https://developer.apple.com/library/archive/documentation/Performance/Conceptual/power_efficiency_guidelines_osx/RespondToThermalStateChanges.html
Release Notes:
- Zed now reduces resource usage when the system is under high thermal
stress
---------
Signed-off-by: Marco Mihai Condrache <52580954+marcocondrache@users.noreply.github.com>
Co-authored-by: Anthony Eid <anthony@zed.dev>