The previous modifier detection treated `AltGr` presses as `Ctrl+Alt`,
which broke entering characters produced by AltGr. For example, on a
Hungarian layout `{` is typed with `AltGr+B`; our code saw that as
`Ctrl+Alt+B` and the keybind took precedence, so the character couldn’t
be entered.
On Windows, AltGr isn’t a first-class modifier. It’s emulated as a
combination of `Right Alt (VK_RMENU)` plus a synthetic `Left Ctrl
(VK_LCONTROL)` press. When users press AltGr, `GetKeyState` reports both
Ctrl and Alt as down, which makes AltGr indistinguishable from a real
`Ctrl+Alt` chord if we only look at aggregate modifier state.
Fix: detect the AltGr pattern by checking `VK_RMENU && VK_LCONTROL`.
When that pattern is present, treat it as text-entry intent and suppress
`control` and `alt` in `current_modifiers()`. This prevents
AltGr-produced characters from colliding with `Ctrl+Alt` keybinds while
keeping other modifiers intact.
Limitation: there is no Windows API to tell whether the active layout
actually has AltGr. As a result, on non-AltGr layouts (e.g. US),
pressing `Right Alt + Left Ctrl` will be interpreted as AltGr and will
not trigger `Ctrl+Alt` keybinds. This is an acceptable trade-off to
ensure AltGr layouts can reliably enter characters; users can still
invoke `Ctrl+Alt` keybinds using `Left Alt` or by choosing bindings that
avoid common AltGr pairs.
I based this on https://github.com/zed-industries/zed/pull/36115 after
trying other different approaches, but this one is a bit more specific.
Does this approach make sense, or is slightly breaking US input in favor
of fixing international input a no-go? I think the benefit - being able
to type certain characters _at all_ - outweighs the shortcomings.
Otherwise, there's a way to detect if the keyboard layout uses AltGr or
not, but it's quite hacky, and involves reading the registry to find the
current layout dll's name, opening that dll, manually declaring struct
layouts that it uses, then parsing out the AltGr flag from a function
call result. I don't think that's worth it, but if needed, I can give
that a shot, let me know.
Release Notes:
- windows: Fixed handling of AltGr to avoid keybinds preventing
character input
Prior we only logged the crate in `log_err`, which is not too helpful.
We now assemble the module path from the file system path.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Closes#5355
Release Notes:
- Fixed rendering glitches with files with more than 16 million lines
(that occured due to floating number rounding errors).
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Fixes titlebar double-click behavior to properly handle the macOS system
setting when "Do Nothing" is selected in System Settings > Desktop &
Dock > "Double-click a window's title bar to".
Closes https://github.com/zed-industries/zed/issues/39102
Release Notes:
- Fixed macOS Do Nothing window double click setting not being
respected.
Fixes titlebar double-click behavior to properly handle the macOS system
setting when "Do Nothing" is selected in System Settings > Desktop &
Dock > "Double-click a window's title bar to".
Closes#39102
Release Notes:
- Fixed macOS `Do Nothing` window double click setting not be respected
std commands can block for an arbitrary duration and so runs risk of
blocking tasks for too long. This replaces all such uses where sensible
with async processes.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
This reverts commit ed7bd5a8ed.
We noticed this PR causes the editor to hang if you hold down any of the
menu item actions like ctrl+z, ctrl+x, etc
Release Notes:
- Fixed macOS menu item actions hanging the editor when their key
combination is held down
On macOS, traditionally when a keyboard shortcut is activated, the menu
in the menu bar flashes to indicate that the action was recognised.
<img width="289" height="172" alt="image"
src="https://github.com/user-attachments/assets/a03ecd2f-f159-4f82-b4fd-227f34393703"
/>
This PR adds this functionality to GPUI, where when a keybind is pressed
that triggers an action in the menu, the menu flashes.
Release Notes:
- N/A
Closes#36287
Release Notes:
- Windows: Fixed an issue where a Zed window would stay minimized when
opening an existing file in that window via the Zed CLI.
This has noticeable misbehavior when framerates are low (in my case this
sometimes happens when CPUs are throttled and compilation is happening),
as now a batch of x11 events can contain events over the span of 100s of
millis. So in that case, key press repetitions with quite normal typing
are skipped.
Under normal operating conditions it can be reproduced by running this
and quickly switching to Zed:
> sleep 1; for i in {1..5}; do xdotool type --delay 5 "aaaaaa "; xdotool
key Return; done
Output before looks like:
```
aaa
aaaaa
aaa
aaa
aaaa
```
Output after looks like:
```
aaaaaa
aaaaaa
aaaaaa
aaaaaa
aaaaaa
```
This behavior was added in #13955.
Release Notes:
- N/A
Check whether the GPU/driver supports the StructuredBuffer feature
required by our shaders. If it doesn’t, log an error and skip that
GPU/driver, so Windows can fall back to the software renderer.
Release Notes:
- N/A
Removes IME bounds scaling on Wayland since it uses logical pixels,
unlike X11. We now scale only on X11. Windows and macOS don’t use these
bounds for IME anyway.
Release Notes:
- Fixed an issue where the IME popover could appear outside the window
or fail to show on Wayland.
Updates blade-graphics from e0ec4e7 to bfa594e to fix GPU crashes on
Wayland with AMD graphics cards.
The crash was caused by incorrect BLAS scratch buffer alignment - the
old version hardcoded 256-byte alignment, but AMD GPUs require different
alignment values. The newer Blade version uses the GPU's actual
alignment requirements instead of hardcoding.
Closes#37448
Release Notes:
- Migrate to newer version of Blade upstream
Extracts and cleans up GPUI's scheduler code into a new `scheduler`
crate, making it pluggable by external runtimes. This will enable
deterministic integration testing with cloud components by providing a
unified test scheduler across Zed and backend code. In Zed, it will
replace the existing GPUI scheduler for consistent async task management
across platforms.
## Changes
- **Core Implementation**: `TestScheduler` with seed-based
randomization, session tracking (`SessionId`), and foreground/background
task separation for reproducible testing.
- **Executors**: `ForegroundExecutor` (!Send, thread-local) and
`BackgroundExecutor` (Send, with blocking/timeout support) as
GPUI-compatible wrappers.
- **Clock and Timer**: Controllable `TestClock` and future-based `Timer`
for time-sensitive tests.
- **Testing APIs**: `once()`, `with_seed()`, and `many()` methods for
configurable test runs.
- **Dependencies**: Added `async-task`, `chrono`, `futures`, etc., with
updates to `Cargo.toml` and lock file.
## Benefits
- **Integration Testing**: Facilitates reliable async tests involving
cloud sessions, reducing flakiness via deterministic execution.
- **Pluggability**: Trait-based design (`Scheduler`) allows easy
integration into non-GPUI runtimes while maintaining GPUI compatibility.
- **Cleanup**: Refactors GPUI scheduler logic for clarity, correctness
(no `unwrap()`, proper error handling), and extensibility.
Follows Rust guidelines; run `./script/clippy` for verification.
- [x] Define and test a core scheduler that we think can power our cloud
code and GPUI
- [ ] Replace GPUI's scheduler
Release Notes:
- N/A
---------
Co-authored-by: Antonio Scandurra <me@as-cii.com>
Now we only keep a single copy of the GPU device. The GPU lost handling
got broken after #35376, but it’s properly handled again now.
Release Notes:
- N/A
This reverts commit 40199266b6.
The issue with the commit is: ContentMask<Pixels>::intersect is doing
intersection of corner radii which makes inner containers use the max
corner radius out of all the parents when it should be more complex to
correctly clip children (clip sorting..?)
Release Notes:
- N/A
Previously, we were using `PostThreadMessage` to pass messages to
`WindowsPlatform`. This PR switches to an approach similar to `winit`
which using a hidden window as the message window (I guess that’s why
winit uses a hidden window?). The difference is that this PR creates it
as a message-only window.
Thanks to @reflectronic for the original PR #37255, this implementation
just fits better with the current code style.
Release Notes:
- N/A
---------
Co-authored-by: reflectronic <john-tur@outlook.com>
This improves emoji rendering on windows removing artifacts at the edges
by using premultiplied alpha. A bit more context can be found in #37167
Release Notes:
- N/A
This PR fixes a typo in the Windows alpha correction shader that is now
caught by https://github.com/zed-industries/zed/pull/37314.
Another case that could be addressed by Bors.
Release Notes:
- N/A
Closes#36023
This improves font rendering quality by doing perceptual gamma+contrast
correction which makes font edges look nicer and more legible.
A comparison image: (left is old, right is new)
<img width="1638" height="854" alt="Screenshot 2025-08-29 140015"
src="https://github.com/user-attachments/assets/85ca9818-0d55-4af0-a796-19e8cf9ed36b"
/>
This is most noticeable on smaller fonts / low-dpi displays
Release Notes:
- Improved font rendering quality
Currently when we render text with differing styles adjacently we might
form a ligature between the text, causing the ligature forming
characters to take on one of the two styles. This can especially become
confusing when a ligature is formed between actual text and inlay hints.
Annoyingly, the only ways to prevent this with core text is to either
render each run separately, or to insert a zero-width non-joiner to
force core text to break the ligatures apart, as it otherwise will merge
subsequent font runs of the same fonts.
We currently do layouting on a per line basis and it is unlikely we want
to change that as it would incur a lot of complexity and annoyances to
merge things back into a line, so this goes with the other approach of
inserting ZWNJ characters instead.
Note that neither linux nor windows seem to currently render ligatures,
so this only concerns macOS rendering at the moment.
Release Notes:
- Fixed ligatures forming between real text and inlay hints on macOS
Follow up of https://github.com/zed-industries/zed/pull/33334
After chatting with @MrSubidubi we found out that he had an old defaults
setting (most likely from when he encountered a previous window tabbing
bug):
```
❯ defaults read dev.zed.Zed-Nightly
{
NSNavPanelExpandedSizeForOpenMode = "{800, 448}";
NSNavPanelExpandedSizeForSaveMode = "{800, 448}";
NSNavPanelExpandedStateForSaveMode = 1;
NSOSPLastRootDirectory = {length = 828, bytes = 0x626f6f6b 3c030000 00000410 30000000 ... dc010000 00000000 };
"NSWindow Frame NSNavPanelAutosaveName" = "557 1726 800 448 -323 982 2560 1440 ";
"NSWindowTabbingShoudShowTabBarKey-GPUIWindow-GPUIWindow-(null)-HT-FS" = 1;
}
```
> That suffix is AppKit’s fallback autosave name when no tabbing
identifier is set. It encodes the NSWindow subclass (GPUIWindow), plus
traits like HT (hidden titlebar) and FS (fullscreen).
Which explains why it only happened on the Nightly build, since each
bundle has it's own defaults. It also explains why the tabbar would
disappear when he activated the `use_system_window_tabs` setting,
because with that setting activated, the tabbing identifier becomes
"zed" (instead of the default one when omitted) for which he didn't have
the `NSWindowTabbingShoudShowTabBarKey` default.
The original implementation was perhaps a bit naive and relied fully on
macOS to determine if the tabbar should be shown. I've updated the code
to always hide the tabbar, if the setting is turned off and there is
only 1 tab entry.
While testing, I also noticed that the menu's like 'merge all windows'
wouldn't become active when the setting was turned on, only after a full
workspace reload. So I added a setting observer as well, to immediately
set the correct window properties to enable all the features without a
reload.
Release Notes:
- N/A