diff --git a/apps/desktop/src/components/ScreenSourcePicker.tsx b/apps/desktop/src/components/ScreenSourcePicker.tsx index 6089d1c..567e155 100644 --- a/apps/desktop/src/components/ScreenSourcePicker.tsx +++ b/apps/desktop/src/components/ScreenSourcePicker.tsx @@ -79,16 +79,18 @@ export function ScreenSourcePicker({ open, onClose, onStart }: Props) { // one setState — cuts re-renders from O(N) to O(frames) during the // initial fan-in and prevents consecutive 10-30 ms long tasks from // stacking in one frame. - const pendingUrls: Record = {}; + // + // Previously `batch` was aliased to `pendingUrls` and then we cleared + // pendingUrls via `delete` — which emptied batch too (same reference) + // and every flush ended up spreading nothing into the state. Clone + // first, then clear, so the batch keeps its entries. + let pendingUrls: Record = {}; let rafScheduled = false; const flush = () => { rafScheduled = false; - if (Object.keys(pendingUrls).length === 0) return; const batch = pendingUrls; - // Capture then reset so new arrivals during the commit land in a - // fresh batch instead of double-applying. - const keys = Object.keys(batch); - for (const k of keys) delete (pendingUrls as Record)[k]; + if (Object.keys(batch).length === 0) return; + pendingUrls = {}; startTransition(() => { setThumbnailUrls((prev) => ({ ...prev, ...batch })); });