This PR adds a feature to automatically cycle through screen shares
during calls, designed for demo days or any call that has a lot of
screen share use.
This is a preliminary attempt behind a feature flag so we can dogfood
and iterate, or toss it out.
There's a new toggle next to the active channel name in the collab
panel: **Auto Watch Screens**.
https://github.com/user-attachments/assets/ae6eccec-7921-4c1f-8921-c8093631c705
This video demonstrates some cases:
Basic auto-watch
- Toggle on → automatically opens the next screen share that starts
- When the watched screen share ends, switches to the next available
share
Queuing
- Someone starts sharing while another share is active → doesn't
interrupt the current share
- When the current share ends, the queued share is picked up
automatically
Paused while sharing
- Auto-watch pauses when you start sharing your own screen, so other
shares don't pop up during your presentation
- When you stop sharing, auto-watch resumes and opens the next available
share
Multiple watchers
- Multiple people can have auto-watch enabled independently — they all
see the same transitions
Note that we don't manage the screenshares, livekit does, so this change
is entirely on the client. I think that's mostly fine, but there is a
chance 2 separate clients queues up a different person as the next
watched peer if they both engage screenshare around the same time,
depending on how it hits the clients, but it seems pretty edge case. We
can move the implementation to collab, but it will be more of a project,
and adding a secondary source alongside of livekit that could get out of
sync and have its own issues.
UI/UX needs work (@danilo-leal for suggestions)
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 #ISSUE
Release Notes:
- N/A
---------
Co-authored-by: Yara 🏳️⚧️ <11743287+yara-blue@users.noreply.github.com>
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
We've decided to remove rodio backend for audio as we didn't have time
to get it to a nice spot. I personally believe we should eventually
re-land it (the composable pipelines are quite nice!), but given that we
need audio to work, this seems like the best way forward. We won't have
to worry about all the ways in which the legacy pipeline interoped with
rodio's.
## 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:
- audio: Experimental rodio audio backend has been removed.
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Co-authored-by: Yara <git@yara.blue>
Release Notes:
- Fixed a weird niche interaction between niri and nixos that broke
screensharing
---------
Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
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
```
## Context
This allows using of Rodio's effects library within our home brewn audio
pipeline. The alternative would be inlining Rodio's effects which is
problematic from a legal stance. We would then have to make clear that
code is not owned by zed-industries while the code would be surrounded
by zed-industries owned code.
This adaptor does incur a slight performance penalty (copying into a
pre-allocated vec and back) however the impact will be immeasurably low.
There is no latency impact.
## How to Review
- Adds an adapter for Rodio effects
- Enables the adapter and effects only when the setting is enabled
-Makes the setting pub(crate) so we can use it from livekit playback
## 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:
- Added Automatic volume control to calls
Release Notes:
- Added call diagnostics when collaborating with other Zed users in
collab.
---------
Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
Co-authored-by: Piotr Osiewicz <piotr@zed.dev>
Co-authored-by: Danilo Leal <danilo@zed.dev>
Release Notes:
- Fixed: echo's on experimental audio pipeline
Some more context:
- `EchoCanceller` was not implemented on the output side
- removes the planned migration to a different sample rate (44100) and
channel count (1)
- de-duplicate the interleaved `#cfg[]`'s and centralized them in
`echo_canceller.rs`
Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
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:
- Improve recovery of audio latency after CPU-intensive period.
Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
Co-authored-by: Jakub Konka <jakub@zed.dev>
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:
- Fixed issues with tremendous audio latency in long-running collab
calls.
Co-authored-by: Jakub Konka <jakub@zed.dev>
Fixes a panic in livekit's process_reverse_stream for non-matching
channel counts, e.g., upmixing 2->4, or downmixing 2->1.
Release Notes:
- Fixed a panic in livekit when joining a channel using legacy audio
using a device with less or more than 2 channels.
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
Use `BackgroundExecutor::spawn_with_priority(Priority::RealtimeAudio,
fut)` to spawn the audio input thread with correct thread priority much
like we do for audio output. Under-the-hood, `spawn_with_priority +
Priority::RealtimeAudio` boils down to calling `std:🧵:spawn` and
setting appropriate thread priority.
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>
This PR adds ability to select and test audio input/output devices for
use in collaboration setting (which is what the team at Zed relies
heavily on). Currently, we only ever used whatever the system default is
and it worked well until it didn't - for some reason, when I am on my
Linux laptop, I am unable to force Zed to use my external mic +
headphones via external USB audio interface. With this PR, now I can
list all available devices and select the one I want.
There are still a couple of caveats that we should be aware of:
* I've decided to list *all* available devices meaning on Linux it is
quite possible that you may discover that what your desktop environment
is reporting to you is a significantly shorter list than what your sound
framework/hw is actually exposing. I think this makes sense given my
inexperience with audio drivers/devices and frameworks on various OSes
so that we get full control over what is available with the goal of
being able to come up with some filtering heuristic as we go along.
* We currently populate the list of available audio devices only once at
startup meaning if you unplug your device while you have Zed running
this will not register until you restart Zed which is a PITA. However,
in order to keep the changes manageable I thought it would be best to do
minimal work in this regard now, and iterate on this some more in the
near future. After all, we don't really monitor device changes on any
platform except macOS anyhow, so it might be the case that when I get
round to implementing this I will have the opportunity to tackle both at
the same time.
* In order to get a valid list of all audio devices using `cpal` crate
(which is the building block of `rodio`), I had to bump `cpal` to 0.17,
and pin `rodio` to a more recent commit sha as a result, so if you see
any regressions, lemme know and/or feel free to revert this PR.
* Finally, I've done my best to integrate this with the settings UI, but
I am sure more could be done in terms of styling, etc.
Some screenshots:
<img width="1152" height="949" alt="Screenshot From 2026-02-12 11-40-04"
src="https://github.com/user-attachments/assets/e147c153-1902-49d6-bf68-3ac317a6a7b0"
/>
<img width="1152" height="949" alt="Screenshot From 2026-02-12 11-40-16"
src="https://github.com/user-attachments/assets/b4e9a2f8-b38e-4de0-b910-067cc432b5bc"
/>
Release Notes:
- Added ability to select audio input/output devices as part of
Collaboration page in Settings. Added ability to test selected devices
with a simple playback loop routing input directly into output for
easier debugging of your audio devices.
---------
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
This can block the mainthread for several milliseconds given large
enough screensizes
Release Notes:
- Fixed screensharing performance on windows and linux
## Motivation
This PR unifies the async execution infrastructure between GPUI and
other components that depend on the `scheduler` crate (such as our cloud
codebase). By having a scheduler that lives independently of GPUI, we
can enable deterministic testing across the entire stack - testing GPUI
applications alongside cloud services with a single, unified scheduler.
## Summary
This PR completes the integration of the `scheduler` crate into GPUI,
unifying async execution and enabling deterministic testing of GPUI
combined with other components that depend on the scheduler crate.
## Key Changes
### Scheduler Integration (Phases 1-5, previously completed)
- `TestDispatcher` now delegates to `TestScheduler` for timing, clock,
RNG, and task scheduling
- `PlatformScheduler` implements the `Scheduler` trait for production
use
- GPUI executors wrap scheduler executors, selecting `TestScheduler` or
`PlatformScheduler` based on environment
- Unified blocking logic via `Scheduler::block()`
### Dead Code Cleanup
- Deleted orphaned `crates/gpui/src/platform/platform_scheduler.rs`
(older incompatible version)
## Intentional Removals
### `spawn_labeled` and `deprioritize` removed
The `TaskLabel` system (`spawn_labeled`, `deprioritize`) was removed
during this integration. It was only used in a few places for test
ordering control.
cc @maxbrunsfeld @as-cii - The new priority-weighted scheduling in
`TestScheduler` provides similar functionality through
`Priority::High/Medium/Low`. If `deprioritize` is important for specific
test scenarios, we could add it back to the scheduler crate. Let me know
if this is blocking anything.
### `start_waiting` / `finish_waiting` debug methods removed
Replaced by `TracingWaker` in `TestScheduler` - run tests with
`PENDING_TRACES=1` to see backtraces of pending futures when parking is
forbidden.
### Realtime Priority removed
The realtime priority feature was unused in the codebase. I'd prefer to
reintroduce it when we have an actual use case, as the implementation
(bounded channel with capacity 1) could potentially block the main
thread. Having a real use case will help us validate the design.
## Testing
- All GPUI tests pass
- All scheduler tests pass
- Clippy clean
## Architecture
```
┌─────────────────────────────────────────────────────────────┐
│ GPUI │
│ ┌──────────────────────┐ ┌────────────────────────────┐ │
│ │ gpui::Background- │ │ gpui::ForegroundExecutor │ │
│ │ Executor │ │ - wraps scheduler:: │ │
│ │ - scheduler: Arc< │ │ ForegroundExecutor │ │
│ │ dyn Scheduler> │ └────────────┬───────────────┘ │
│ └──────────┬───────────┘ │ │
│ │ │ │
│ └──────────┬──────────────────┘ │
│ ▼ │
│ ┌───────────────────────┐ │
│ │ Arc<dyn Scheduler> │ │
│ └───────────┬───────────┘ │
│ ┌──────────────┴──────────────┐ │
│ ▼ ▼ │
│ ┌──────────────────┐ ┌────────────────────┐ │
│ │ PlatformScheduler│ │ TestScheduler │ │
│ │ (production) │ │ (deterministic) │ │
│ └──────────────────┘ └────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
Release Notes:
- N/A
---------
Co-authored-by: Antonio Scandurra <me@as-cii.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Yara <git@yara.blue>
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
Release Notes:
- Fixed an issue on macOS where audio playback would become temporarily
scrambled when doing lots of IO operations, such as when running `git
pull` or `git checkout` while in a call.
Release Notes:
- N/A
---
https://github.com/user-attachments/assets/d46b77ae-88ba-43da-93ad-3656a7fecaf9
The system menu is only support for macOS, so here just modify the macOS
platform special code.
The Windows, Linux used `ApplicationMenu`, I have already added
`checked` option to Zed's ContextMenu.
Then later when this PR merged, we can improve "View" menu to show check
state to panels (Project Panel, Outline Panel, ...).
We've been considering removing workspace-hack for a couple reasons:
- Lukas ran into a situation where its build script seemed to be causing
spurious rebuilds. This seems more likely to be a cargo bug than an
issue with workspace-hack itself (given that it has an empty build
script), but we don't necessarily want to take the time to hunt that
down right now.
- Marshall mentioned hakari interacts poorly with automated crate
updates (in our case provided by rennovate) because you'd need to have
`cargo hakari generate && cargo hakari manage-deps` after their changes
and we prefer to not have actions that make commits.
Currently removing workspace-hack causes our workspace to grow from
~1700 to ~2000 crates being built (depending on platform), which is
mainly a problem when you're building the whole workspace or running
tests across the the normal and remote binaries (which is where
feature-unification nets us the most sharing). It doesn't impact
incremental times noticeably when you're just iterating on `-p zed`, and
we'll hopefully get these savings back in the future when
rust-lang/cargo#14774 (which re-implements the functionality of hakari)
is finished.
Release Notes:
- N/A
Uses the previously merged denoising crate (and fixes a bug in it that
snug in during refactoring) to add denoising to the microphone input.
Adds automatic volume control for microphone and output.
Prepares for migrating to 16kHz SR mono:
The experimental audio path now picks the samplerate and channel count depending on a setting. It can handle incoming streams with both the current (future legacy) and new samplerate & channel count. These are url-encoded into the livekit track name
Release Notes:
- N/A
It was just a bunch of finnickery around UI layout. It affected Linux
too.
Release Notes:
* Fixed aspect ratio of peer screen share when using Linux/Windows
builds.
Uses the previously merged denoising crate (and fixes a bug in it that snug in during refactoring) in the microphone input. The experimental audio path now picks the samplerate and channel count depending on a setting. It can handle incoming streams with both the current (future legacy) and new samplerate & channel count. These are url-encoded into the livekit track name.
Follow up on https://github.com/zed-industries/zed/pull/37786
adds conditional cmp removing use of libwebrtc on windows/freebsd
They cant compile livekit yet. This removes microphone and echo
cancellation on those platforms however they can not join calls due to
the same cause so it does not matter.
Documentation and error handing improvements
Release Notes:
- N/A
---------
Co-authored-by: Richard <richard@zed.dev>
Rodio parts are well tested and need less configuration then the livekit
parts. I suspect there is a bug in the livekit configuration regarding
resampling. Rather then investigate that it seemed faster & easier to
swap in Rodio.
This opens the door to using other Rodio parts like:
- Decibel based volume control
- Limiter (prevents sound from becoming too loud)
- Automatic gain control
To use this add to settings:
```
"audio": {
"experimental.rodio_audio": true
}
```
Release Notes:
- N/A
Co-authored-by: Mikayla <mikayla@zed.dev>
Co-authored-by: Antonio Scandurra <me@as-cii.com>
This removes around 900 unnecessary clones, ranging from cloning a few
ints all the way to large data structures and images.
A lot of these were fixed using `cargo clippy --fix --workspace
--all-targets`, however it often breaks other lints and needs to be run
again. This was then followed up with some manual fixing.
I understand this is a large diff, but all the changes are pretty
trivial. Rust is doing some heavy lifting here for us. Once I get it up
to speed with main, I'd appreciate this getting merged rather sooner
than later.
Release Notes:
- N/A
Adds component NotificationFrame. It implements a subset of MessageNotification as a Component and refactors MessageNotification to use NotificationFrame. Having some notification UI Component is nice as it allows us to easily build new types of notifications.
Uses the new NotificationFrame component for CaptureAudioNotification.
Adds a CaptureAudio action in the dev namespace (not meant for
end-users). It records 10 seconds of audio and saves that to a wav file.
Release Notes:
- N/A
---------
Co-authored-by: Mikayla <mikayla@zed.dev>
the change was made in https://github.com/zed-industries/zed/pull/34223
for unknown reason. it wasn't required actually, and the code can be
safely left as before
update: after this revert Zed compiles with MinGW as before
Release Notes:
- N/A
Instead of selecting a screen to share arbitrarily, we'll now allow user
to select the screen to share. Note that sharing multiple screens at the
time is still not supported (though prolly not too far-fetched).
Related to #4666

Release Notes:
- Added screen selector dropdown to screen share button
---------
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
Co-authored-by: Cole Miller <cole@zed.dev>