Tighten battery capture: cover lazily-spawned capture processes, widen warmup

Follow-up polish after the EcoQoS fix landed and recordings improved:

- Re-apply the EcoQoS opt-out when the stream backend reports it is active.
  Chromium spawns/upgrades its GPU and screen-capture utility processes only
  once the desktop stream actually starts — after the session-start sweep —
  so they could still be born throttled. Hooking the capture:state transition
  to 'stream' catches them the moment they appear.

- Raise the warmup cap from 1500ms to 3000ms. The recorder window stays
  visible during warmup (the user hasn't started their workflow yet) and the
  common path still proceeds the instant the stream is ready, so the extra
  headroom only matters when stream startup is slow on battery — where it
  buys a real pre-click frame for the very first click instead of a
  post-click fresh shot.
This commit is contained in:
2026-06-16 08:15:46 -05:00
parent f580759337
commit 3def598528
2 changed files with 24 additions and 4 deletions
+8 -3
View File
@@ -56,9 +56,14 @@ const DEFAULT_CLICK_DEBOUNCE_MS = 200;
// representation that carries root coordinates) before firing without them.
const LINUX_CLICK_TWIN_MS = 25;
// Longest the window stays visible warming up the recorder at recording
// start. A slow capture-stream start (Windows can take several seconds) must
// not keep the window up and recording un-armed indefinitely.
const WARMUP_MAX_MS = 1500;
// start. A slow capture-stream start (Windows can take several seconds,
// especially on battery) must not keep the window up and recording un-armed
// indefinitely — but the window is still visible during warmup, so the user
// hasn't begun their workflow yet, and the common case still proceeds the
// instant the stream is ready. The cap only bites when startup is slow, where
// a little more headroom buys a pre-click frame for the very first click
// instead of a post-click fresh shot.
const WARMUP_MAX_MS = 3000;
// Idle gap between legacy frame-loop grabs. Must stay well above zero:
// grabbing back-to-back starves the main-process event loop, which delays
// delivery of click events from the OS watcher by whole seconds. (The
+16 -1
View File
@@ -733,11 +733,26 @@ if (!gotLock) {
settings = new Settings(store.settingsDir);
searchIndex = new SearchIndex(store.indexDir);
templates = new TemplateManager(store.templatesDir);
// Bringing up the desktop-capture stream spawns/upgrades Chromium's GPU
// and screen-capture utility processes — which can be born after a session
// already started, so the start-time EcoQoS opt-out misses them. Re-apply
// it the moment the backend reports it is streaming.
let lastClickFrameSource = null;
const captureNotify = (channel, payload) => {
sendToRenderer(channel, payload);
if (channel === 'capture:state' && payload && payload.clickFrameSource !== lastClickFrameSource) {
lastClickFrameSource = payload.clickFrameSource;
if (payload.clickFrameSource === 'stream') {
try { keepProcessesResponsive(app.getAppMetrics().map((m) => m.pid)); } catch { /* best effort */ }
}
}
};
capture = new CaptureService({
store,
settings,
getWindow: () => mainWindow,
notify: sendToRenderer,
notify: captureNotify,
});
applyTheme();