Fixes ZED-5K1
Release Notes:
- Fixed a panic on windows when a monitor disappears from windows
monitor enumeration
---------
Co-authored-by: John Tur <john-tur@outlook.com>
Self-Review Checklist:
- [ ] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable
Release Notes:
- Added a prompt to move Zed to /Applications on macOS when run from
within the .dmg
Instead of manually handing hiding the cursor on keyboard input at the
editor level, GPUI will now take care of it.
This makes it significantly easier to handle the edge cases, and allows
delegating the cursor restoration to the platform itself in the macOS
case. On Linux and Windows, we still have to restore the cursor on
movement ourselves, but this now happens at the platform-specific level.
Bugs fixed by this change:
- No cursor when "Unsaved edits" prompt appears
- Cursor disappears when clicking a panel button if it contains a search
bar (e.g. collab panel)
### Setting rename
The `hide_mouse` setting value `"on_typing_and_movement"` has been
renamed to `"on_typing_and_action"` to better reflect what it actually
does — it hides the cursor when a keystroke resolves to an action (e.g.
cursor movement, deletion). Existing settings are migrated
automatically.
### Tested platforms
- [x] macOS
- [x] Wayland
- [x] X11
- [x] Windows
- [x] Web
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)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Renamed the `hide_mouse` setting value `on_typing_and_movement` to
`on_typing_and_action` to better describe its behavior (existing
settings are auto-migrated)
- Fixed a few situations where the mouse cursor would be incorrectly
hidden
We were storing a cursor hidden boolean in the window state, but that
state is actually global to the application.
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)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
Regression introduced in #48029, applying the same workaround here that
we seem to use for `setDocumentEdited`
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:
- (Preview only) Fixed an issue on macOS where the traffic light
position would be wrong when opening the project search
Apple's text rendering stack dilates glyph outlines for text rendered
with a light foreground color. Zed doesn't consider this nuance today;
we populate our atlas using glyphs rendered with a dark foreground
color. This means that, particularly in dark themes, text in Zed looks
thin and blurry, and doesn't match the look of native macOS
applications.
This pull request replicates the native behavior of Core Graphics. Some
reverse-engineering revealed that CG computes the foreground color
luminance using the Rec. 709 formula ($Y=0.2126R + 0.7152B + 0.0722G$)
and quantizes it into five levels (0, 0.25, 0.5, 0.75, and 1). Each
level uses a different dilation factor.
With this patch, we calculate this same luminance bucket and supply it
as the foreground color during rasterization. The correct dilation will
be applied, and we'll store this glyph in the atlas keyed by this
luminance bucket. So, we'll generate and use up to 5 different bitmaps
for each glyph based on its foreground color.
I've confirmed that text rendered by Zed now exactly matches native
applications like Safari, TextEdit, etc.
Release Notes:
- Improved text rendering clarity on macOS, particularly in dark themes.
---------
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
#48029 introduced `set_document_path` which is frequently (we are also
working on a PR to make it less frequent) called as tabs and panes
update. Apparently, the AppKit function it uses
(`NSWindow::setRepresentedFilename`) can cause the current cursor style
to be reset, producing flicker as the cursor would change to `Arrow`
temporarily until the right cursor style is set again in the next frame.
This PR reworks how we set the cursor to use AppKit's
`resetCursorRects`, giving us a chance to re-set the cursor when the OS
decides to invalidate it.
Finally, it fixes a separate bug introduced in #50827 where moving the
mouse while typing in an editor would cause to the cursor to flicker
between `None` (hidden) -> `Arrow` -> `IBeam`. This was caused by
incorrectly resetting the cursor to `Arrow` when the last input came
from the keyboard.
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)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
---------
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
PR #51415 introduced the `PlatformHeadlessRenderer` trait and
`PlatformWindow::render_to_image` method in `gpui`, both gated on
`#[cfg(any(test, feature = "test-support"))]`, plus corresponding impls
in `gpui_macos` (`window.rs` and `metal_renderer.rs`) gated on the same
cfg.
A dependent crate's `cfg(test)` flag does **not** propagate to its
dependencies. So when `cargo test -p gpui_macos` is run in isolation,
`gpui_macos`'s own `cfg(test)` is true (its impls get compiled) but
`gpui` is just a regular dependency without `test-support` enabled (the
trait and method don't exist), and the build fails:
```
error[E0405]: cannot find trait `PlatformHeadlessRenderer` in crate `gpui`
error[E0407]: method `render_to_image` is not a member of trait `PlatformWindow`
```
The fix is to enable `gpui/test-support` as a dev-dependency, so the
feature is on exactly when `gpui_macos`'s tests are being built.
This bug is latent on `main` — workspace-level `cargo test` typically
pulls in `gpui/test-support` transitively from other crates, masking it.
Running `cargo test -p gpui_macos` alone is what surfaces it.
Release Notes:
- N/A
release `TISInputSource` returned by
`TISCopyCurrentKeyboardLayoutInputSource` in `MacKeyboardLayout::new()`,
and `CFUUIDRef` returned by `CGDisplayCreateUUIDFromDisplayID` in
`MacDisplay::uuid()`. both follow the core foundation create rule and
must be released by the caller.
Release Notes:
- N/A
This sets the accessibility document property (AXDocument) of the
window, which other apps can use to understand what file the current
window represents. Document-based apps on macOS are generally expected
to set this property.
The document path is set via `Window::set_document_path()` which calls
`setRepresentedFilename:` on the underlying NSWindow. The workspace
updates this path in `update_window_title()` whenever the active item or
project structure changes. For tests, instead of trying to somehow
assemble a proper NSWindow, we store the document path on the window
mock used for testing and check its value.
Motivation: I am the developer of Timing, an automatic time tracking app
for Mac. Timing uses the `AXDocument` property (a standard property of
most document-based app windows on macOS) to understand what document
the user is working on. With this change, Timing is able to understand
which directory the user is working in. Without this, Timing would only
record the window title, i.e. the filename without information about the
containing directory. I've had several users ask for better support for
Zed.
Here's a screenshot of the macOS Accessibility Inspector showing the
`AXDocument` property with this change. The UI of Zed itself does not
change. However, in my dev build of Zed, the traffic lights are a bit
too large and misaligned. However, this happens even when building
`main`, so I assume it’s unrelated to my changes.
<img width="1370" height="1162" alt="Screenshot 2026-01-30 at 16 18 25"
src="https://github.com/user-attachments/assets/dc260252-91fb-41e1-97a9-e6fb843c6a70"
/>
Release Notes:
- Set the represented filename property of windows on macOS
---------
Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
This PR adds support for rendering **Netpbm** image formats (`.pbm`,
`.ppm`, `.pgm`) within Zed's built-in image viewer.
These formats are particularly useful for projects that want minimal
external dependencies, a common scenario in academic environments and
low-level graphics programming.
Since the underlying `image` crate and `GPUI` already provide support
for these codecs, this change explicitly exposes the `Pnm` variant
within `gpui::ImageFormat` by mapping it to `image::ImageFormat::Pnm`.
## Screenshots/Examples
Below is an example of `.pbm`, `.ppm`, and `.pgm` files being rendered
correctly in the image preview (images taken from
https://filesamples.com):
<img width="1917" height="1012" alt="pnm_example"
src="https://github.com/user-attachments/assets/0056133f-908c-4c91-ba9d-53aef0657b05"
/>
Release Notes:
- Added support for PNM image previews (`.pbm`, `.ppm`, `.pgm`).
This reverts commit 5be9dc1781.
This change breaks dragging directories onto the App icon (or using the
directories listed in the menu on the app icon in the doc)
Release Notes:
- N/A
Corresponding font-kit commit:
94b0f28166
Before, Zed has 3 different versions of `dirs` crate to compile, this PR
bumps the related dependencies to have one, latest, version of `dirs`
instead.
Release Notes:
- N/A
Closes#47140Closes#44691
When launching Zed from the CLI (`zed .`), macOS delivers the path as a
`kAEGetURL` Apple Event via Launch Services. Zed relied on the
`application:openURLs:` delegate method to receive this, but its timing
relative to `applicationDidFinishLaunching:` is not guaranteed by macOS.
In release builds, the app reaches `didFinishLaunching` before the URL
is delivered, causing it to be missed and a duplicate window to be
opened. This does not reproduce in debug builds due to slower
initialization, which is why the issue was hard to reproduce from
source.
This replaces `application:openURLs:` with a custom `kAEGetURL` Apple
Event handler registered in `applicationWillFinishLaunching:`. Apple
Events are guaranteed to be delivered synchronously between
`willFinishLaunching` and `didFinishLaunching`, ensuring the URL is
always available before startup logic runs.
Release Notes:
- Fixed duplicate window creation when opening files/directories from
the CLI on macOS.
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
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
Relates to #5303 and
https://github.com/zed-industries/zed/issues/40826#issuecomment-3684556858
although I haven't found anywhere an actual request for `gpui` itself to
support a system alert sound.
### What
Basically, this PR adds a function that triggers an OS-dependent alert
sound, commonly used by terminal applications for `\a` / `BEL`, and GUI
applications to indicate an action failed in some small way (e.g. no
search results found, unable to move cursor, button disabled).
Also updated the `input` example, which now plays the bell if the user
presses <kbd>backspace</kbd> with nothing behind the cursor to delete,
or <kbd>delete</kbd> with nothing in front of the cursor.
Test with `cargo run --example input --features gpui_platform/font-kit`.
### Why
If this is merged, I plan to take a second step:
- Add a new Zed setting (probably something like
`terminal.audible_bell`)
- If enabled, `printf '\a'`, `tput bel` etc. would call this new API to
play an audible sound
This isn't the super-shiny dream of #5303 but it would allow users to
more easily configure tasks to notify when done. Plus, any TUI/CLI apps
that expect this functionality will work. Also, I think many terminal
users expect something like this (WezTerm, iTerm, etc. almost all
support this).
### Notes
~I was only able to test on macOS and Windows, so if there are any Linux
users who could verify this works for X11 / Wayland that would be a huge
help! If not I can try~
Confirmed Wayland + X11 both working when I ran the example on a NixOS
desktop
Release Notes:
- N/A
Linear gradients in dark color ranges (5-15% lightness) show visible
banding due to 8-bit quantization — only ~7 distinct values exist in
that range, producing hard steps instead of smooth transitions. This
affects every dark theme in Zed.
## What this does
Adds triangular-distributed dithering after gradient interpolation in
both the Metal and HLSL fragment shaders. The noise breaks up
quantization steps at the sub-pixel level, producing perceptually smooth
gradients.
## How it works
Two hash-based pseudo-random values (seeded from fragment position x
golden ratio) are summed to produce a triangular probability
distribution. This is added to the RGB channels at +/-1/255 amplitude.
- **Triangular PDF** — mean-zero, so no brightness shift across the
gradient
- **+/-1/255 amplitude** — below perceptual threshold, invisible on
bright gradients where 8-bit precision is already sufficient
- **Deterministic per-pixel** — seeded from position, no temporal
flickering
- **Zero-cost** — a couple of `fract`/`sin` per fragment, negligible vs.
the existing gradient math
### Channel-specific amplitudes
| Channel | Amplitude | Rationale |
|---------|-----------|----------------------------------------------------------------------------------------------------|
| RGB | ±2/255 | Breaks dark-on-dark banding where adjacent 8-bit values
are perceptually close |
| Alpha | ±3/255 | Alpha gradients over dark backgrounds need stronger
noise — α × dark color = tiny composited steps |
The higher alpha amplitude is necessary because when a semi-transparent
gradient (e.g., 0.4 → 0.0 alpha) composites over a dark background, the
effective visible difference per quantization step is smaller than the
RGB case. ±3/255 is still well below the perceptual threshold on
bright/opaque elements.
## Scope
Two files changed, purely additive:
| File | Change |
|------|--------|
| `crates/gpui_macos/src/shaders.metal` | 13 lines after `mix()` in
`fill_color()` |
| `crates/gpui_windows/src/shaders.hlsl` | 13 lines after `lerp()` in
`gradient_color()` |
No changes to Rust code, no API changes, no new dependencies.
## Screenshots
<img width="1886" height="1003" alt="gradient_dithering_before"
src="https://github.com/user-attachments/assets/f75ae93b-b142-4d0e-9b61-e08f30fe1758"
/>
_Before_
<img width="1902" height="1052" alt="gradient_dithering_after"
src="https://github.com/user-attachments/assets/7aee9a36-f578-4e08-a846-44d092bcf043"
/>
_After_
## Test plan
This is a shader-level fix; no Rust test harness exists for visual
output. Manual testing is appropriate here. Visual regression tests
cover UI layout, not sub-pixel rendering quality.
**Manual (macOS):**
- [x] Dark gradients (5-13% lightness range) — banding eliminated
- [x] Bright gradients — no visible difference (dither amplitude below
precision threshold)
- [x] Oklab and sRGB color spaces — both paths dithered
- [x] Solid colours, pattern fills, checkerboard — unaffected (dither
only applies to LinearGradient case)
- [x] Alpha gradients (semi-transparent over dark bg) — banding
eliminated with alpha dithering
- [x] Path gradients (paint_path) — same fill_colour() function,
dithering applies
**Windows:** HLSL change is identical logic with HLSL built-ins
(`frac`/`lerp` vs `fract`/`mix`) — not tested locally.
Release Notes:
- Improved linear gradient rendering by adding dithering to eliminate
visible banding in dark color ranges
Liam
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
Manual testing performed successfully on Tahoe 26.2.
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- Fixed missing right- and middle-mouse button drag on MacOS
Co-authored-by: MrSubidubi <finn@zed.dev>
Previously, the GPUI profiler allocates one CircularBuffer per thread,
and `CircularBuffer<N>` always preallocates space for N entries. As a
result it allocates ~20MB/thread, and on my machine about 33 threads are
created at startup for a total of 600MB used.
In this PR I change it to use a VecDeque that can gradually grow up to
20MB as data is written. At least in my experiments it seems that this
caps overall usage at about 21MB perhaps because only one thread writes
very much usage data.
Since this is fixed overhead for everyone running Zed it seems like a
worthwhile gain.
This also folds duplicated code across platforms into the common gpui
profiler.
Before:
<img width="4804" height="2192" alt="Image"
src="https://github.com/user-attachments/assets/7060ee5b-ef80-49cb-b7be-de33e9a2e7a5"
/>
After:
<img width="5052" height="1858" alt="image"
src="https://github.com/user-attachments/assets/513494df-0974-4604-9796-15a12ef1c134"
/>
I got here from #35780 but I don't think this is tree-size related, it
seems to be fixed overhead.
Release Notes:
- Improved: Significantly less memory used to record internal profiling
information.
---------
Co-authored-by: MrSubidubi <finn@zed.dev>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
MetalAtlas::remove() used tiles_by_key.get(key) to look up the texture
ID but only called tiles_by_key.remove(key) when the texture became
fully unreferenced. When a tile was removed while other tiles remained
on the same texture, the key stayed in tiles_by_key as a stale entry.
Once subsequent removals deleted the texture, get_or_insert_with could
return the stale tile referencing a now-deleted texture slot, causing an
unwrap panic in MetalAtlasState::texture().
Fix: change .get(key) to .remove(key) unconditionally, matching the WGPU
and DirectX atlas implementations which already do this correctly.
Closes ZED-5KV
Release Notes:
- N/A or Added/Fixed/Improved ...
## Fixes
Closes#28174
Closes #30393Closes#36610Closes#38616
Updates #31819
Updates #21136
## Context
There was an issue where CJK input could not be entered correctly when
certain keys used during IME composition conflicted with custom
keybindings while the CJK IME was enabled.
(In particular, in Vim mode, the `jj` keybinding in INSERT MODE could
not be entered correctly.)
This issue had already been fixed on Windows, but not on macOS (and
judging from the code, it is likely also present on Linux, although this
has not been verified).
In this change, we aligned the behavior with Windows.
Currently, on Windows, when the CJK ( or other ) IME is enabled, IME
input is prioritized.
Following this behavior, we updated macOS to also prioritize IME input.
| Input source | Source type | ASCII-capable | Result | Behavior |
|---|---|---|---|---|
| Japanese Hiragana | `KeyboardInputMode` | `false` | `true` | IME
handles key first |
| Japanese Romaji | `KeyboardInputMode` | `true` | `false` | Keybinding
matching first |
| Korean | `KeyboardInputMode` | `false` | `true` | IME handles key
first |
| Chinese Pinyin | `KeyboardInputMode` | `false` | `true` | IME handles
key first |
| Armenian | `KeyboardLayout` | `false` | `false` | Keybinding matching
first |
| Ukrainian | `KeyboardLayout` | `false` | `false` | Keybinding matching
first |
| English (ABC) | `KeyboardLayout` | `true` | `false` | Keybinding
matching first |
(Since similar approaches are used in tools like Vim and Neovim, we
consider this policy to be appropriate.)
## Videos
### before fix
https://github.com/user-attachments/assets/9b204220-d0de-4819-8dc4-00ba85169ef6
### after fix
https://github.com/user-attachments/assets/045cc808-8d29-42d2-9de5-f903fcb602db
## How to Review
This change modifies the gpui layer rather than Zed itself, so please
verify the behavior at the gpui level, not just within Zed.
## Self-Review Checklist
<!-- Check before requesting review: -->
- [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 IME composition on macOS in Vim insert mode with multi-stroke keybindings like `jj`
MacWindow methods like activate(), zoom(), toggle_fullscreen(),
resize(), prompt(), and titlebar_double_click() capture the raw
native_window pointer and spawn detached async tasks on the foreground
executor. If the window is closed between the spawn and execution (e.g.
the user clicks the close button), the task sends AppKit messages to a
closed NSWindow, which throws an ObjC exception in
_changeKeyAndMainLimitedOK: and aborts the process.
Add an isVisible check inside each deferred task before sending messages
to the native window. After [NSWindow close], isVisible returns NO, so
the guard prevents the crash. Both the check and the subsequent AppKit
call execute synchronously within the same main-thread task, so there is
no TOCTOU race.
For prompt(), the else branch releases the alert object to avoid leaking
it; the oneshot sender inside the completion block is dropped, which
cancels the channel and propagates as an error to the caller.
Closes ZED-5TN
Release Notes:
- N/A or Added/Fixed/Improved ...
Continue #39876 to add `disabled` state to `MenuItem`.
Make this change for #44047 ready to have disabled state.
1. Add `disabled` state to `MenuItem`.
2. Add some builder methods to `Menu` and `MenuItem`.
3. Improve `set_menus` method to receive a `impl IntoIterator<Item =
Menu>`.
Release Notes:
- N/A
--
<img width="294" height="204" alt="image"
src="https://github.com/user-attachments/assets/688e0db8-6c4e-4f9b-a832-8228db0e95d8"
/>
```bash
cargo run -p gpui --example set_menus
```
Part of #29026
## Summary
https://github.com/user-attachments/assets/35b4f969-1fcf-45f4-88cd-cbc27ad9696e
macOS Finder places file paths on the system pasteboard using
`NSFilenamesPboardType` when files are copied. Previously, the project
panel only supported its own internal clipboard for copy/cut/paste
operations and ignored system clipboard content entirely. This meant
that copying files in Finder and pasting them in Zed's project panel did
nothing.
This PR adds support for reading file paths from the macOS system
pasteboard, enabling a natural workflow where users can copy files in
Finder (or other file managers) and paste them directly into Zed's
project panel.
> **Note:** Pasting files from a system file manager currently only
works on macOS. The project panel changes are cross-platform, but the
clipboard reading of file paths (`ExternalPaths`) is only implemented in
the macOS pasteboard. Windows and Linux would need equivalent changes in
their respective platform clipboard implementations to support this.
Copying/cutting files from the project panel to the system clipboard as
plain text works on all platforms.
### Changes
**`crates/gpui/src/platform/mac/pasteboard.rs`**
- Read `NSFilenamesPboardType` from the system pasteboard and surface
file paths as `ClipboardEntry::ExternalPaths`
- Check for file paths before plain text, since Finder puts both types
on the pasteboard (without this priority, file paths would be returned
as plain text strings)
- Extract the string-reading logic into `read_string_from_pasteboard()`
to allow reuse
**`crates/project_panel/src/project_panel.rs`**
- On paste, check the system clipboard for external file paths and use
the existing `drop_external_files` mechanism to copy them into the
project
- On copy/cut, write the selected entries' absolute paths to the system
clipboard so other apps can consume them
- Update the "Paste" context menu item to also be enabled when the
system clipboard contains file paths, not just when the internal
clipboard has entries
## Test plan
- [ ] Copy one or more files in Finder, paste in the project panel —
files should be copied into the selected directory
- [ ] Copy files within the project panel, paste — existing internal
copy/paste behavior is preserved
- [ ] Cut files within the project panel, paste — existing internal
cut/paste behavior is preserved
- [ ] Copy files in the project panel, paste in Finder or another app —
paths are available as plain text
- [ ] Right-click context menu shows "Paste" enabled when system
clipboard has file paths
- [ ] Right-click context menu shows "Paste" disabled when both internal
and system clipboards are empty
Release Notes:
- Added support for pasting files from Finder (and other file managers)
into the project panel via the system clipboard (macOS only). Copying or
cutting files in the project panel now also writes their paths to the
system clipboard for use in other apps.
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Closes#50151
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:
- Fixed a deadlock that froze the entire app when opening a new window
from a PopUp window or switching focus between multiple windows on
macOS.
Closes#51297
On non-QWERTY layouts, all Cmd+key events are routed through the macOS
IME because `key_char` is always `None` when Cmd is held. For certain
characters (dead keys like backtick, and non-dead keys like ç), the IME
calls `insertText:` instead of `doCommandBySelector:`, consuming the
event before it reaches GPUI's keybinding system or macOS system
shortcuts.
This adds `!platform` to the IME-path condition in `handle_key_event` so
Cmd+key events bypass the IME (except when composing). GPUI handles them
if a binding matches, otherwise `performKeyEquivalent:` returns `NO` and
macOS handles them.
**This won't fully fix Cmd+backtick window cycling by itself** because
Zed's key_equivalents system maps default keybindings onto the physical
backtick key on various layouts. For example, `cmd-'`
(ToggleSelectedDiffHunks) maps to the backtick key on Spanish, `cmd-=`
(IncreaseBufferFontSize) on Scandinavian layouts, `cmd-"`
(ExpandAllDiffHunks) on German/Portuguese/Swiss, and `cmd-}`
(ActivateNextItem) on Spanish-ISO. These Zed bindings shadow the
backtick key and consume the event before macOS can cycle windows. I'd
appreciate guidance on the preferred approach to resolve these
keybinding conflicts -- IMO, Zed's default shortcuts should not be
interfering with Cmd+backtick for any layout.
Release Notes:
- Fixed Cmd+key shortcuts being consumed by the IME on non-QWERTY
keyboard layouts, preventing Zed keybindings and macOS system shortcuts
from working with special characters.
- **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>
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>
Fixes ZED-5G8
If `DisplayLink::new` fails, `frame_requests` is dropped . It is not
valid to destroy a DispatchSource that is not `resume()`d. So, ensure we
call `resume()` before there's a chance for anything to fail.
Release Notes:
- Fixed a crash that could occur on macOS when changing monitor
configurations
`send_file_drop_event` was the only event dispatch site in window.rs
that called the event callback while still holding the `MacWindowState`
mutex. every other callback site in the file uses the established
`take() / drop(lock) / callback()` pattern which releases the lock
before invoking user code.
this is a latent code quality issue: no deadlock occurs today because
the current file-drop callback chain does not reenter `MacWindowState`'s
mutex (`Window::mouse_position()` returns a cached field
`Window::refresh()` only marks a dirty flag and `cx.activate()` uses a
separate `MacPlatform` mutex). but `parking_lot::Mutex` is not entering
so any future platform call added inside a filedrop handler would
deadlock immediately and silently.
the fix brings `send_file_drop_event` in line with the rest of the file
by taking the callback out of the state dropping the lock invoking the
callback then reacquiring the lock to restore the callback and update
state.
Release Notes:
- N/A
Third attempt to land this improvement: (#45577, #44273)
The previous PR didn’t work on Intel MacBooks because I made a wrong
assumption about the unified memory check. `has_unified_memory` only
tells us that the CPU and GPU share memory. It does not mean we’re
running on an Apple GPU family.
Memoryless textures are only supported on Apple GPUs. Some Intel Macs
report unified memory, but they don’t support memoryless textures, which
is why the previous change failed there.
So instead of relying on unified memory, we now explicitly check that
we’re running on an Apple GPU family before enabling memoryless
textures.
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:
- Reduced memory usage on macOS
---------
Signed-off-by: Marco Mihai Condrache <52580954+marcocondrache@users.noreply.github.com>
#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>