relay-companion 0.1.86 → 0.1.87
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/overlay/main.cjs +45 -5
- package/package.json +1 -1
package/overlay/main.cjs
CHANGED
|
@@ -20,7 +20,22 @@
|
|
|
20
20
|
// - Mutations (accept/reject/approve/decline/answer) call RelayClient with device-token
|
|
21
21
|
// auth. ack/mark-read writes state.json directly (atomic temp+rename).
|
|
22
22
|
|
|
23
|
-
const { app, BrowserWindow, Menu, Tray, ipcMain, nativeImage, powerMonitor, shell, screen, systemPreferences } = require("electron");
|
|
23
|
+
const { app, BrowserWindow, Menu, Tray, ipcMain, nativeImage, powerMonitor, powerSaveBlocker, shell, screen, systemPreferences } = require("electron");
|
|
24
|
+
|
|
25
|
+
// The pill is an accessory window that spends most of its life idle behind other
|
|
26
|
+
// apps. Both Chromium and macOS treat that as "safe to throttle", and the cost is
|
|
27
|
+
// paid by the user: the FIRST click after an idle spell waits for the renderer to
|
|
28
|
+
// spin back up (reported as "slow, then fast, then slow again"). These switches
|
|
29
|
+
// stop the OS/engine from backgrounding a window the user can still see and click.
|
|
30
|
+
// They must be set before app ready.
|
|
31
|
+
app.commandLine.appendSwitch("disable-renderer-backgrounding");
|
|
32
|
+
app.commandLine.appendSwitch("disable-background-timer-throttling");
|
|
33
|
+
app.commandLine.appendSwitch("disable-backgrounding-occluded-windows");
|
|
34
|
+
if (process.platform === "darwin") {
|
|
35
|
+
// macOS reports an always-on-top overlay as occluded far more eagerly than it
|
|
36
|
+
// deserves; Chromium then backgrounds the renderer behind the user's back.
|
|
37
|
+
app.commandLine.appendSwitch("disable-features", "MacWebContentsOcclusion");
|
|
38
|
+
}
|
|
24
39
|
|
|
25
40
|
// A closed stdout/stderr pipe must never kill the pill. When whatever launched
|
|
26
41
|
// us goes away (launchd log rotation, a terminal that spawned `relay pill`, a
|
|
@@ -961,10 +976,32 @@ function idleSecondsSafe() {
|
|
|
961
976
|
|
|
962
977
|
// Renderer timer throttling is disabled ONLY while a card's dwell runs: the
|
|
963
978
|
// 7s fold timer must be honest, but an idle hidden overlay should coast.
|
|
964
|
-
|
|
979
|
+
// Responsiveness policy: a renderer the user can SEE is never throttled. The
|
|
980
|
+
// earlier rule (throttle unless a notification dwell was running) saved idle CPU
|
|
981
|
+
// but made the first interaction after any quiet spell slow — the user feels a
|
|
982
|
+
// dead click far more than a fraction of a percent of CPU. Throttling now applies
|
|
983
|
+
// only while the window is genuinely hidden, where nobody can click it.
|
|
984
|
+
let appSuspensionBlockerId = null;
|
|
985
|
+
function applyThrottlingPolicy() {
|
|
986
|
+
const visible = Boolean(win && !win.isDestroyed() && win.isVisible());
|
|
965
987
|
try {
|
|
966
|
-
if (win && !win.isDestroyed()) win.webContents.setBackgroundThrottling(!
|
|
988
|
+
if (win && !win.isDestroyed()) win.webContents.setBackgroundThrottling(!visible);
|
|
967
989
|
} catch {}
|
|
990
|
+
// macOS App Nap suspends whole accessory processes; hold it off only while the
|
|
991
|
+
// pill is on screen, so an idle hidden pill still costs nothing.
|
|
992
|
+
try {
|
|
993
|
+
if (visible && appSuspensionBlockerId === null) {
|
|
994
|
+
appSuspensionBlockerId = powerSaveBlocker.start("prevent-app-suspension");
|
|
995
|
+
} else if (!visible && appSuspensionBlockerId !== null) {
|
|
996
|
+
powerSaveBlocker.stop(appSuspensionBlockerId);
|
|
997
|
+
appSuspensionBlockerId = null;
|
|
998
|
+
}
|
|
999
|
+
} catch {}
|
|
1000
|
+
}
|
|
1001
|
+
// Kept for the notification-dwell call sites: dwell timing still demands an
|
|
1002
|
+
// unthrottled renderer, and the visibility rule already guarantees it.
|
|
1003
|
+
function setThrottlingForShow() {
|
|
1004
|
+
applyThrottlingPolicy();
|
|
968
1005
|
}
|
|
969
1006
|
|
|
970
1007
|
function abortCurrentShow(reason) {
|
|
@@ -2340,6 +2377,9 @@ function showOverlayWindow({ force = false, reposition = true } = {}) {
|
|
|
2340
2377
|
// window would silently flip it click-through while the renderer still thinks
|
|
2341
2378
|
// the pointer handshake is live — a dead card until the pointer re-enters.
|
|
2342
2379
|
win.setIgnoreMouseEvents(true, { forward: true });
|
|
2380
|
+
// Visible again: unthrottle immediately, so the FIRST click after this is as
|
|
2381
|
+
// fast as the tenth (the "slow, then fast, then slow again" report).
|
|
2382
|
+
applyThrottlingPolicy();
|
|
2343
2383
|
win.webContents.send("shown");
|
|
2344
2384
|
// Becoming visible is when host-running freshness starts mattering for
|
|
2345
2385
|
// click routing again; the hidden poll cadence is slow, so take one
|
|
@@ -3001,7 +3041,7 @@ function hideFromTray() {
|
|
|
3001
3041
|
writeOverlayPrefs();
|
|
3002
3042
|
ghostActive = false;
|
|
3003
3043
|
trayForcedVisible = false;
|
|
3004
|
-
if (win && !win.isDestroyed() && win.isVisible()) win.hide();
|
|
3044
|
+
if (win && !win.isDestroyed() && win.isVisible()) { win.hide(); applyThrottlingPolicy(); }
|
|
3005
3045
|
syncTray();
|
|
3006
3046
|
writePillStatus();
|
|
3007
3047
|
}
|
|
@@ -3291,7 +3331,7 @@ ipcMain.on("relay:dismiss", () => {
|
|
|
3291
3331
|
writeOverlayPrefs();
|
|
3292
3332
|
ghostActive = false;
|
|
3293
3333
|
trayForcedVisible = false;
|
|
3294
|
-
if (win && !win.isDestroyed() && win.isVisible()) win.hide();
|
|
3334
|
+
if (win && !win.isDestroyed() && win.isVisible()) { win.hide(); applyThrottlingPolicy(); }
|
|
3295
3335
|
writePillStatus();
|
|
3296
3336
|
});
|
|
3297
3337
|
// The renderer finished registering every IPC listener (last line of its
|