collab: Make unsupported for MinGW toolchain (#23518)

Maksim Bondarenkov created

Closes #23451

reverts #23117 for MinGW. collab can't be compiled for MinGW because
webrtc itself doesn't support MinGW compilers

Release Notes:

- N/A

Change summary

crates/call/src/cross_platform/participant.rs | 10 +
crates/call/src/cross_platform/room.rs        | 96 +++++++++++++++++---
crates/livekit_client/Cargo.toml              |  4 
crates/livekit_client/src/livekit_client.rs   | 58 +++++++++++-
crates/livekit_client/src/test.rs             | 30 ++++++
crates/livekit_client/src/test/participant.rs |  5 +
crates/livekit_client/src/test/publication.rs |  5 +
crates/livekit_client/src/test/track.rs       | 13 ++
docs/src/development/local-collaboration.md   |  2 
docs/src/development/windows.md               |  2 
10 files changed, 199 insertions(+), 26 deletions(-)

Detailed changes

crates/call/src/cross_platform/participant.rs 🔗

@@ -1,3 +1,5 @@
+#![cfg_attr(all(target_os = "windows", target_env = "gnu"), allow(unused))]
+
 use anyhow::{anyhow, Result};
 use client::{proto, ParticipantIndex, User};
 use collections::HashMap;
@@ -6,6 +8,7 @@ use livekit_client::AudioStream;
 use project::Project;
 use std::sync::Arc;
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 pub use livekit_client::id::TrackSid;
 pub use livekit_client::track::{RemoteAudioTrack, RemoteVideoTrack};
 
@@ -58,13 +61,18 @@ pub struct RemoteParticipant {
     pub participant_index: ParticipantIndex,
     pub muted: bool,
     pub speaking: bool,
+    #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
     pub video_tracks: HashMap<TrackSid, RemoteVideoTrack>,
+    #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
     pub audio_tracks: HashMap<TrackSid, (RemoteAudioTrack, AudioStream)>,
 }
 
 impl RemoteParticipant {
     pub fn has_video_tracks(&self) -> bool {
-        !self.video_tracks.is_empty()
+        #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
+        return !self.video_tracks.is_empty();
+        #[cfg(all(target_os = "windows", target_env = "gnu"))]
+        return false;
     }
 
     pub fn can_write(&self) -> bool {

crates/call/src/cross_platform/room.rs 🔗

@@ -1,3 +1,5 @@
+#![cfg_attr(all(target_os = "windows", target_env = "gnu"), allow(unused))]
+
 use crate::{
     call_settings::CallSettings,
     participant::{LocalParticipant, ParticipantLocation, RemoteParticipant},
@@ -13,6 +15,7 @@ use fs::Fs;
 use futures::{FutureExt, StreamExt};
 use gpui::{App, AppContext, AsyncAppContext, Context, Entity, EventEmitter, Task, WeakEntity};
 use language::LanguageRegistry;
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 use livekit::{
     capture_local_audio_track, capture_local_video_track,
     id::ParticipantIdentity,
@@ -22,6 +25,8 @@ use livekit::{
     track::{TrackKind, TrackSource},
     RoomEvent, RoomOptions,
 };
+#[cfg(all(target_os = "windows", target_env = "gnu"))]
+use livekit::{publication::LocalTrackPublication, RoomEvent};
 use livekit_client as livekit;
 use postage::{sink::Sink, stream::Stream, watch};
 use project::Project;
@@ -99,7 +104,10 @@ impl Room {
         !self.shared_projects.is_empty()
     }
 
-    #[cfg(any(test, feature = "test-support"))]
+    #[cfg(all(
+        any(test, feature = "test-support"),
+        not(all(target_os = "windows", target_env = "gnu"))
+    ))]
     pub fn is_connected(&self) -> bool {
         if let Some(live_kit) = self.live_kit.as_ref() {
             live_kit.room.connection_state() == livekit::ConnectionState::Connected
@@ -664,6 +672,12 @@ impl Room {
         }
     }
 
+    #[cfg(all(target_os = "windows", target_env = "gnu"))]
+    fn start_room_connection(&self, mut room: proto::Room, cx: &mut Context<Self>) -> Task<()> {
+        Task::ready(())
+    }
+
+    #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
     fn start_room_connection(&self, mut room: proto::Room, cx: &mut Context<Self>) -> Task<()> {
         // Filter ourselves out from the room's participants.
         let local_participant_ix = room
@@ -816,6 +830,7 @@ impl Room {
                                     muted: true,
                                     speaking: false,
                                     video_tracks: Default::default(),
+                                    #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
                                     audio_tracks: Default::default(),
                                 },
                             );
@@ -918,6 +933,7 @@ impl Room {
         );
 
         match event {
+            #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
             RoomEvent::TrackSubscribed {
                 track,
                 participant,
@@ -952,6 +968,7 @@ impl Room {
                 }
             }
 
+            #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
             RoomEvent::TrackUnsubscribed {
                 track, participant, ..
             } => {
@@ -979,6 +996,7 @@ impl Room {
                 }
             }
 
+            #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
             RoomEvent::ActiveSpeakersChanged { speakers } => {
                 let mut speaker_ids = speakers
                     .into_iter()
@@ -995,6 +1013,7 @@ impl Room {
                 }
             }
 
+            #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
             RoomEvent::TrackMuted {
                 participant,
                 publication,
@@ -1019,6 +1038,7 @@ impl Room {
                 }
             }
 
+            #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
             RoomEvent::LocalTrackUnpublished { publication, .. } => {
                 log::info!("unpublished track {}", publication.sid());
                 if let Some(room) = &mut self.live_kit {
@@ -1041,10 +1061,12 @@ impl Room {
                 }
             }
 
+            #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
             RoomEvent::LocalTrackPublished { publication, .. } => {
                 log::info!("published track {:?}", publication.sid());
             }
 
+            #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
             RoomEvent::Disconnected { reason } => {
                 log::info!("disconnected from room: {reason:?}");
                 self.leave(cx).detach_and_log_err(cx);
@@ -1274,6 +1296,13 @@ impl Room {
     pub fn can_use_microphone(&self) -> bool {
         use proto::ChannelRole::*;
 
+        #[cfg(not(any(test, feature = "test-support")))]
+        {
+            if cfg!(all(target_os = "windows", target_env = "gnu")) {
+                return false;
+            }
+        }
+
         match self.local_participant.role {
             Admin | Member | Talker => true,
             Guest | Banned => false,
@@ -1288,6 +1317,12 @@ impl Room {
         }
     }
 
+    #[cfg(all(target_os = "windows", target_env = "gnu"))]
+    pub fn share_microphone(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
+        Task::ready(Err(anyhow!("MinGW is not supported yet")))
+    }
+
+    #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
     #[track_caller]
     pub fn share_microphone(&mut self, cx: &mut Context<Self>) -> Task<Result<()>> {
         if self.status.is_offline() {
@@ -1365,6 +1400,12 @@ impl Room {
         })
     }
 
+    #[cfg(all(target_os = "windows", target_env = "gnu"))]
+    pub fn share_screen(&mut self, cx: &mut Context<Self>) -> Task<Result<()>> {
+        Task::ready(Err(anyhow!("MinGW is not supported yet")))
+    }
+
+    #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
     pub fn share_screen(&mut self, cx: &mut Context<Self>) -> Task<Result<()>> {
         if self.status.is_offline() {
             return Task::ready(Err(anyhow!("room is offline")));
@@ -1512,12 +1553,15 @@ impl Room {
             LocalTrack::Published {
                 track_publication, ..
             } => {
-                let local_participant = live_kit.room.local_participant();
-                let sid = track_publication.sid();
-                cx.background_executor()
-                    .spawn(async move { local_participant.unpublish_track(&sid).await })
-                    .detach_and_log_err(cx);
-                cx.notify();
+                #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
+                {
+                    let local_participant = live_kit.room.local_participant();
+                    let sid = track_publication.sid();
+                    cx.background_executor()
+                        .spawn(async move { local_participant.unpublish_track(&sid).await })
+                        .detach_and_log_err(cx);
+                    cx.notify();
+                }
 
                 Audio::play_sound(Sound::StopScreenshare, cx);
                 Ok(())
@@ -1526,12 +1570,15 @@ impl Room {
     }
 
     fn set_deafened(&mut self, deafened: bool, cx: &mut Context<Self>) -> Option<()> {
-        let live_kit = self.live_kit.as_mut()?;
-        cx.notify();
-        for (_, participant) in live_kit.room.remote_participants() {
-            for (_, publication) in participant.track_publications() {
-                if publication.kind() == TrackKind::Audio {
-                    publication.set_enabled(!deafened);
+        #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
+        {
+            let live_kit = self.live_kit.as_mut()?;
+            cx.notify();
+            for (_, participant) in live_kit.room.remote_participants() {
+                for (_, publication) in participant.track_publications() {
+                    if publication.kind() == TrackKind::Audio {
+                        publication.set_enabled(!deafened);
+                    }
                 }
             }
         }
@@ -1561,10 +1608,13 @@ impl Room {
             LocalTrack::Published {
                 track_publication, ..
             } => {
-                if should_mute {
-                    track_publication.mute()
-                } else {
-                    track_publication.unmute()
+                #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
+                {
+                    if should_mute {
+                        track_publication.mute()
+                    } else {
+                        track_publication.unmute()
+                    }
                 }
 
                 None
@@ -1573,6 +1623,14 @@ impl Room {
     }
 }
 
+#[cfg(all(target_os = "windows", target_env = "gnu"))]
+fn spawn_room_connection(
+    livekit_connection_info: Option<proto::LiveKitConnectionInfo>,
+    cx: &mut ModelContext<'_, Room>,
+) {
+}
+
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 fn spawn_room_connection(
     livekit_connection_info: Option<proto::LiveKitConnectionInfo>,
     cx: &mut Context<'_, Room>,
@@ -1637,6 +1695,10 @@ struct LiveKitRoom {
 }
 
 impl LiveKitRoom {
+    #[cfg(all(target_os = "windows", target_env = "gnu"))]
+    fn stop_publishing(&mut self, _cx: &mut Context<Room>) {}
+
+    #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
     fn stop_publishing(&mut self, cx: &mut Context<Room>) {
         let mut tracks_to_unpublish = Vec::new();
         if let LocalTrack::Published {

crates/livekit_client/Cargo.toml 🔗

@@ -28,7 +28,6 @@ cpal = "0.15"
 futures.workspace = true
 gpui.workspace = true
 http_2 = { package = "http", version = "0.2.1" }
-livekit.workspace = true
 livekit_server.workspace = true
 log.workspace = true
 media.workspace = true
@@ -40,6 +39,9 @@ http_client.workspace = true
 smallvec.workspace = true
 image.workspace = true
 
+[target.'cfg(not(all(target_os = "windows", target_env = "gnu")))'.dependencies]
+livekit.workspace = true
+
 [target.'cfg(target_os = "macos")'.dependencies]
 core-foundation.workspace = true
 coreaudio-rs = "0.12.1"

crates/livekit_client/src/livekit_client.rs 🔗

@@ -1,5 +1,11 @@
+#![cfg_attr(all(target_os = "windows", target_env = "gnu"), allow(unused))]
+
 mod remote_video_track_view;
-#[cfg(any(test, feature = "test-support"))]
+#[cfg(any(
+    test,
+    feature = "test-support",
+    all(target_os = "windows", target_env = "gnu")
+))]
 pub mod test;
 
 use anyhow::{anyhow, Context as _, Result};
@@ -11,6 +17,7 @@ use gpui::{
 use parking_lot::Mutex;
 use std::{borrow::Cow, collections::VecDeque, future::Future, pin::Pin, sync::Arc, thread};
 use util::{debug_panic, ResultExt as _};
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 use webrtc::{
     audio_frame::AudioFrame,
     audio_source::{native::NativeAudioSource, AudioSourceOptions, RtcAudioSource},
@@ -20,13 +27,27 @@ use webrtc::{
     video_stream::native::NativeVideoStream,
 };
 
-#[cfg(not(any(test, feature = "test-support")))]
+#[cfg(all(
+    not(any(test, feature = "test-support")),
+    not(all(target_os = "windows", target_env = "gnu"))
+))]
 use livekit::track::RemoteAudioTrack;
-#[cfg(not(any(test, feature = "test-support")))]
+#[cfg(all(
+    not(any(test, feature = "test-support")),
+    not(all(target_os = "windows", target_env = "gnu"))
+))]
 pub use livekit::*;
-#[cfg(any(test, feature = "test-support"))]
+#[cfg(any(
+    test,
+    feature = "test-support",
+    all(target_os = "windows", target_env = "gnu")
+))]
 use test::track::RemoteAudioTrack;
-#[cfg(any(test, feature = "test-support"))]
+#[cfg(any(
+    test,
+    feature = "test-support",
+    all(target_os = "windows", target_env = "gnu")
+))]
 pub use test::*;
 
 pub use remote_video_track_view::{RemoteVideoTrackView, RemoteVideoTrackViewEvent};
@@ -43,6 +64,7 @@ pub enum AudioStream {
 
 struct Dispatcher(Arc<dyn gpui::PlatformDispatcher>);
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 impl livekit::dispatcher::Dispatcher for Dispatcher {
     fn dispatch(&self, runnable: livekit::dispatcher::Runnable) {
         self.0.dispatch(runnable, None);
@@ -64,6 +86,7 @@ fn http_2_status(status: http_client::http::StatusCode) -> http_2::StatusCode {
         .expect("valid status code to status code conversion")
 }
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 impl livekit::dispatcher::HttpClient for HttpClientAdapter {
     fn get(
         &self,
@@ -118,6 +141,14 @@ impl livekit::dispatcher::HttpClient for HttpClientAdapter {
     }
 }
 
+#[cfg(all(target_os = "windows", target_env = "gnu"))]
+pub fn init(
+    dispatcher: Arc<dyn gpui::PlatformDispatcher>,
+    http_client: Arc<dyn http_client::HttpClient>,
+) {
+}
+
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 pub fn init(
     dispatcher: Arc<dyn gpui::PlatformDispatcher>,
     http_client: Arc<dyn http_client::HttpClient>,
@@ -126,6 +157,7 @@ pub fn init(
     livekit::dispatcher::set_http_client(HttpClientAdapter(http_client));
 }
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 pub async fn capture_local_video_track(
     capture_source: &dyn ScreenCaptureSource,
 ) -> Result<(track::LocalVideoTrack, Box<dyn ScreenCaptureStream>)> {
@@ -159,6 +191,7 @@ pub async fn capture_local_video_track(
     ))
 }
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 pub fn capture_local_audio_track(
     background_executor: &BackgroundExecutor,
 ) -> Result<Task<(track::LocalAudioTrack, AudioStream)>> {
@@ -250,6 +283,7 @@ pub fn capture_local_audio_track(
     }))
 }
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 pub fn play_remote_audio_track(
     track: &RemoteAudioTrack,
     background_executor: &BackgroundExecutor,
@@ -320,6 +354,7 @@ fn default_device(input: bool) -> anyhow::Result<(cpal::Device, cpal::SupportedS
     Ok((device, config))
 }
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 fn get_default_output() -> anyhow::Result<(cpal::Device, cpal::SupportedStreamConfig)> {
     let host = cpal::default_host();
     let output_device = host
@@ -329,6 +364,7 @@ fn get_default_output() -> anyhow::Result<(cpal::Device, cpal::SupportedStreamCo
     Ok((output_device, output_config))
 }
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 fn start_output_stream(
     output_config: cpal::SupportedStreamConfig,
     output_device: cpal::Device,
@@ -413,6 +449,14 @@ fn start_output_stream(
     (receive_task, thread)
 }
 
+#[cfg(all(target_os = "windows", target_env = "gnu"))]
+pub fn play_remote_video_track(
+    track: &track::RemoteVideoTrack,
+) -> impl Stream<Item = RemoteVideoFrame> {
+    futures::stream::empty()
+}
+
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 pub fn play_remote_video_track(
     track: &track::RemoteVideoTrack,
 ) -> impl Stream<Item = RemoteVideoFrame> {
@@ -440,7 +484,7 @@ fn video_frame_buffer_from_webrtc(buffer: Box<dyn VideoBuffer>) -> Option<Remote
 #[cfg(not(target_os = "macos"))]
 pub type RemoteVideoFrame = Arc<gpui::RenderImage>;
 
-#[cfg(not(target_os = "macos"))]
+#[cfg(not(any(target_os = "macos", all(target_os = "windows", target_env = "gnu"))))]
 fn video_frame_buffer_from_webrtc(buffer: Box<dyn VideoBuffer>) -> Option<RemoteVideoFrame> {
     use gpui::RenderImage;
     use image::{Frame, RgbaImage};
@@ -491,7 +535,7 @@ fn video_frame_buffer_to_webrtc(frame: ScreenCaptureFrame) -> Option<impl AsRef<
     }
 }
 
-#[cfg(not(target_os = "macos"))]
+#[cfg(not(any(target_os = "macos", all(target_os = "windows", target_env = "gnu"))))]
 fn video_frame_buffer_to_webrtc(_frame: ScreenCaptureFrame) -> Option<impl AsRef<dyn VideoBuffer>> {
     None as Option<Box<dyn VideoBuffer>>
 }

crates/livekit_client/src/test.rs 🔗

@@ -1,14 +1,18 @@
 pub mod participant;
 pub mod publication;
 pub mod track;
+
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 pub mod webrtc;
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 use self::id::*;
 use self::{participant::*, publication::*, track::*};
 use anyhow::{anyhow, Context as _, Result};
 use async_trait::async_trait;
 use collections::{btree_map::Entry as BTreeEntry, hash_map::Entry, BTreeMap, HashMap, HashSet};
 use gpui::BackgroundExecutor;
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 use livekit::options::TrackPublishOptions;
 use livekit_server::{proto, token};
 use parking_lot::Mutex;
@@ -18,6 +22,7 @@ use std::sync::{
     Arc, Weak,
 };
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 pub use livekit::{id, options, ConnectionState, DisconnectReason, RoomOptions};
 
 static SERVERS: Mutex<BTreeMap<String, Arc<TestServer>>> = Mutex::new(BTreeMap::new());
@@ -26,10 +31,12 @@ pub struct TestServer {
     pub url: String,
     pub api_key: String,
     pub secret_key: String,
+    #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
     rooms: Mutex<HashMap<String, TestServerRoom>>,
     executor: BackgroundExecutor,
 }
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 impl TestServer {
     pub fn create(
         url: String,
@@ -527,6 +534,7 @@ impl TestServer {
     }
 }
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 #[derive(Default, Debug)]
 struct TestServerRoom {
     client_rooms: HashMap<ParticipantIdentity, Room>,
@@ -535,6 +543,7 @@ struct TestServerRoom {
     participant_permissions: HashMap<ParticipantIdentity, proto::ParticipantPermission>,
 }
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 #[derive(Debug)]
 struct TestServerVideoTrack {
     sid: TrackSid,
@@ -542,6 +551,7 @@ struct TestServerVideoTrack {
     // frames_rx: async_broadcast::Receiver<Frame>,
 }
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 #[derive(Debug)]
 struct TestServerAudioTrack {
     sid: TrackSid,
@@ -580,6 +590,7 @@ pub enum RoomEvent {
     TrackSubscriptionFailed {
         participant: RemoteParticipant,
         error: String,
+        #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
         track_sid: TrackSid,
     },
     TrackPublished {
@@ -615,10 +626,12 @@ pub enum RoomEvent {
     ActiveSpeakersChanged {
         speakers: Vec<Participant>,
     },
+    #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
     ConnectionStateChanged(ConnectionState),
     Connected {
         participants_with_tracks: Vec<(RemoteParticipant, Vec<RemoteTrackPublication>)>,
     },
+    #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
     Disconnected {
         reason: DisconnectReason,
     },
@@ -626,6 +639,7 @@ pub enum RoomEvent {
     Reconnected,
 }
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 #[async_trait]
 impl livekit_server::api::Client for TestApiClient {
     fn url(&self) -> &str {
@@ -689,8 +703,11 @@ impl livekit_server::api::Client for TestApiClient {
 struct RoomState {
     url: String,
     token: String,
+    #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
     local_identity: ParticipantIdentity,
+    #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
     connection_state: ConnectionState,
+    #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
     paused_audio_tracks: HashSet<TrackSid>,
     updates_tx: mpsc::Sender<RoomEvent>,
 }
@@ -701,6 +718,7 @@ pub struct Room(Arc<Mutex<RoomState>>);
 #[derive(Clone, Debug)]
 pub(crate) struct WeakRoom(Weak<Mutex<RoomState>>);
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 impl std::fmt::Debug for RoomState {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         f.debug_struct("Room")
@@ -713,6 +731,17 @@ impl std::fmt::Debug for RoomState {
     }
 }
 
+#[cfg(all(target_os = "windows", target_env = "gnu"))]
+impl std::fmt::Debug for RoomState {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.debug_struct("Room")
+            .field("url", &self.url)
+            .field("token", &self.token)
+            .finish()
+    }
+}
+
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 impl Room {
     fn downgrade(&self) -> WeakRoom {
         WeakRoom(Arc::downgrade(&self.0))
@@ -774,6 +803,7 @@ impl Room {
     }
 }
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 impl Drop for RoomState {
     fn drop(&mut self) {
         if self.connection_state == ConnectionState::Connected {

crates/livekit_client/src/test/participant.rs 🔗

@@ -8,16 +8,19 @@ pub enum Participant {
 
 #[derive(Clone, Debug)]
 pub struct LocalParticipant {
+    #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
     pub(super) identity: ParticipantIdentity,
     pub(super) room: Room,
 }
 
 #[derive(Clone, Debug)]
 pub struct RemoteParticipant {
+    #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
     pub(super) identity: ParticipantIdentity,
     pub(super) room: WeakRoom,
 }
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 impl Participant {
     pub fn identity(&self) -> ParticipantIdentity {
         match self {
@@ -27,6 +30,7 @@ impl Participant {
     }
 }
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 impl LocalParticipant {
     pub async fn unpublish_track(&self, track: &TrackSid) -> Result<()> {
         self.room
@@ -60,6 +64,7 @@ impl LocalParticipant {
     }
 }
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 impl RemoteParticipant {
     pub fn track_publications(&self) -> HashMap<TrackSid, RemoteTrackPublication> {
         if let Some(room) = self.room.upgrade() {

crates/livekit_client/src/test/publication.rs 🔗

@@ -8,17 +8,20 @@ pub enum TrackPublication {
 
 #[derive(Clone, Debug)]
 pub struct LocalTrackPublication {
+    #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
     pub(crate) sid: TrackSid,
     pub(crate) room: WeakRoom,
 }
 
 #[derive(Clone, Debug)]
 pub struct RemoteTrackPublication {
+    #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
     pub(crate) sid: TrackSid,
     pub(crate) room: WeakRoom,
     pub(crate) track: RemoteTrack,
 }
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 impl TrackPublication {
     pub fn sid(&self) -> TrackSid {
         match self {
@@ -35,6 +38,7 @@ impl TrackPublication {
     }
 }
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 impl LocalTrackPublication {
     pub fn sid(&self) -> TrackSid {
         self.sid.clone()
@@ -67,6 +71,7 @@ impl LocalTrackPublication {
     }
 }
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 impl RemoteTrackPublication {
     pub fn sid(&self) -> TrackSid {
         self.sid.clone()

crates/livekit_client/src/test/track.rs 🔗

@@ -1,6 +1,8 @@
 use super::*;
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 use webrtc::{audio_source::RtcAudioSource, video_source::RtcVideoSource};
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 pub use livekit::track::{TrackKind, TrackSource};
 
 #[derive(Clone, Debug)]
@@ -23,12 +25,14 @@ pub struct LocalAudioTrack {}
 
 #[derive(Clone, Debug)]
 pub struct RemoteVideoTrack {
+    #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
     pub(super) server_track: Arc<TestServerVideoTrack>,
     pub(super) _room: WeakRoom,
 }
 
 #[derive(Clone, Debug)]
 pub struct RemoteAudioTrack {
+    #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
     pub(super) server_track: Arc<TestServerAudioTrack>,
     pub(super) room: WeakRoom,
 }
@@ -39,14 +43,17 @@ pub enum RtcTrack {
 }
 
 pub struct RtcAudioTrack {
+    #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
     pub(super) server_track: Arc<TestServerAudioTrack>,
     pub(super) room: WeakRoom,
 }
 
 pub struct RtcVideoTrack {
+    #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
     pub(super) _server_track: Arc<TestServerVideoTrack>,
 }
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 impl RemoteTrack {
     pub fn sid(&self) -> TrackSid {
         match self {
@@ -77,18 +84,21 @@ impl RemoteTrack {
     }
 }
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 impl LocalVideoTrack {
     pub fn create_video_track(_name: &str, _source: RtcVideoSource) -> Self {
         Self {}
     }
 }
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 impl LocalAudioTrack {
     pub fn create_audio_track(_name: &str, _source: RtcAudioSource) -> Self {
         Self {}
     }
 }
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 impl RemoteAudioTrack {
     pub fn sid(&self) -> TrackSid {
         self.server_track.sid.clone()
@@ -124,6 +134,7 @@ impl RemoteAudioTrack {
     }
 }
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 impl RemoteVideoTrack {
     pub fn sid(&self) -> TrackSid {
         self.server_track.sid.clone()
@@ -140,6 +151,7 @@ impl RemoteVideoTrack {
     }
 }
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 impl RtcTrack {
     pub fn enabled(&self) -> bool {
         match self {
@@ -156,6 +168,7 @@ impl RtcTrack {
     }
 }
 
+#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
 impl RtcAudioTrack {
     pub fn set_enabled(&self, enabled: bool) {
         if let Some(room) = self.room.upgrade() {

docs/src/development/local-collaboration.md 🔗

@@ -6,6 +6,8 @@ First, make sure you've installed Zed's backend dependencies for your platform:
 - [Linux](./linux.md#backend-dependencies)
 - [Windows](./windows.md#backend-dependencies)
 
+Note that `collab` can be compiled only with MSVC toolchain on Windows
+
 ## Database setup
 
 Before you can run the `collab` server locally, you'll need to set up a `zed` Postgres database.

docs/src/development/windows.md 🔗

@@ -110,6 +110,8 @@ You can see the [build script](https://github.com/msys2/MINGW-packages/blob/mast
 
 > Please, report any issue in [msys2/MINGW-packages/issues](https://github.com/msys2/MINGW-packages/issues?q=is%3Aissue+is%3Aopen+zed) first.
 
+Note that `collab` is not supported for msys2.
+
 ## Troubleshooting
 
 ### Setting `RUSTFLAGS` env var breaks builds