diff --git a/src/core/mod.rs b/src/core/mod.rs index e3bc8d9..afd8341 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -1816,17 +1816,26 @@ async fn run_core_loop( } CoreCommand::SetNetworkMode(mode) => { - network_mode = mode; - // Rebuild the persistent stack to the new posture immediately if - // idle; if a call is active, defer to the next Leave/Join so the - // live call isn't disrupted (preserves "applies on next join"). - if active_session.is_none() { - let lookup = net.memory_lookup.clone(); - net.shutdown().await; - let publish = presence_mode.lock().unwrap().publishes_to_discovery(); - net = build_net_stack(secret_key.clone(), network_mode, lookup, friends_handler.clone(), publish).await?; - } else { - net_rebuild_pending = true; + // Skip when the posture is unchanged. The GUI re-sends the saved + // network mode as part of its startup config-sync, and that mode + // usually already matches the freshly-built stack — rebuilding the + // iroh endpoint for an identical posture just churns the network + // and adds a needless ~1s teardown+rebuild bounce at every launch + // (seen on both Linux and Windows/Wine). A real change still + // rebuilds exactly as before. + if mode != network_mode { + network_mode = mode; + // Rebuild the persistent stack to the new posture immediately if + // idle; if a call is active, defer to the next Leave/Join so the + // live call isn't disrupted (preserves "applies on next join"). + if active_session.is_none() { + let lookup = net.memory_lookup.clone(); + net.shutdown().await; + let publish = presence_mode.lock().unwrap().publishes_to_discovery(); + net = build_net_stack(secret_key.clone(), network_mode, lookup, friends_handler.clone(), publish).await?; + } else { + net_rebuild_pending = true; + } } }