diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/bookmarks.js b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/bookmarks.js index 0db185d..766a56d 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/bookmarks.js +++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/bookmarks.js @@ -394,28 +394,31 @@ async function bmApply(bm) { scheduleSpectrumDraw(); } - // --- Fire-and-forget: send mode, bandwidth, and frequency in parallel --- - // The UI is already updated optimistically above; don't block on the - // network round-trips so the bookmark click feels instant. - const modePromise = (async () => { + // Take scheduler control up front, then apply mode before bandwidth so a + // late SetMode cannot revert a saved WFM bookmark bandwidth to 180 kHz. + const tunePromise = (async () => { + if (typeof vchanTakeSchedulerControl === "function") { + await vchanTakeSchedulerControl(); + } + const onVirtual = typeof vchanInterceptMode === "function" && await vchanInterceptMode(bm.mode); if (!onVirtual) { await postPath("/set_mode?mode=" + encodeURIComponent(bm.mode)); } - })(); - const bwPromise = bm.bandwidth_hz ? (async () => { - const bwHandledByVchan = typeof vchanInterceptBandwidth === "function" - && await vchanInterceptBandwidth(bm.bandwidth_hz); - if (!bwHandledByVchan) { - await postPath("/set_bandwidth?hz=" + bm.bandwidth_hz); + + if (bm.bandwidth_hz) { + const bwHandledByVchan = typeof vchanInterceptBandwidth === "function" + && await vchanInterceptBandwidth(bm.bandwidth_hz); + if (!bwHandledByVchan) { + await postPath("/set_bandwidth?hz=" + bm.bandwidth_hz); + } } - })() : Promise.resolve(); - // setRigFrequency is wrapped by vchan.js to redirect to the channel API - // when on a virtual channel, so this call works correctly in both cases. - // It also does its own optimistic update (applyLocalTunedFrequency) but - // that's a no-op since we already set the same value above. - const freqPromise = (async () => { + + // setRigFrequency is wrapped by vchan.js to redirect to the channel API + // when on a virtual channel, so this call works correctly in both cases. + // It also does its own optimistic update (applyLocalTunedFrequency) but + // that's a no-op since we already set the same value above. if (typeof setRigFrequency === "function") { await setRigFrequency(bm.freq_hz); } else { @@ -439,7 +442,7 @@ async function bmApply(bm) { })() : Promise.resolve(); // Don't await — let the network calls settle in the background. // Errors are logged but don't block the UI. - Promise.all([modePromise, bwPromise, freqPromise, decoderPromise]).catch( + Promise.all([tunePromise, decoderPromise]).catch( (err) => console.error("Bookmark apply background error:", err) ); } catch (err) { diff --git a/src/trx-client/trx-frontend/trx-frontend-http/src/scheduler.rs b/src/trx-client/trx-frontend/trx-frontend-http/src/scheduler.rs index 00f1b86..b9899e9 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/src/scheduler.rs +++ b/src/trx-client/trx-frontend/trx-frontend-http/src/scheduler.rs @@ -534,6 +534,19 @@ async fn apply_scheduler_target( ) .await?; + if let Some(bandwidth_hz) = bookmark + .bandwidth_hz + .filter(|bw| *bw > 0 && *bw <= u32::MAX as u64) + .map(|bw| bw as u32) + { + scheduler_send( + rig_tx, + RigCommand::SetBandwidth(bandwidth_hz), + remote.to_string(), + ) + .await?; + } + apply_scheduler_decoders(rig_tx, remote, &bookmark, &extra_bookmarks).await; let status = SchedulerStatus {