Skip to content

Commit f267209

Browse files
authored
🤖 fix: improve code review auto-refresh reliability in Electron (#1268)
Add window.focus event listener alongside visibilitychange to handle cases where the Electron app loses/gains focus without the document becoming hidden (e.g., app behind other windows, different desktop/space). The visibilitychange API is designed for browser tab visibility, which doesn't map perfectly to Electron window focus states. Adding the focus event ensures pending refreshes are flushed when the user returns to the app regardless of how they left. --- _Generated with `mux` • Model: `anthropic:claude-opus-4-5` • Thinking: `high`_
1 parent c02774d commit f267209

File tree

2 files changed

+13
-5
lines changed

2 files changed

+13
-5
lines changed

src/browser/hooks/useReviewRefreshController.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@ describe("useReviewRefreshController design", () => {
5959

6060
test("visibility contract: hidden tab queues refresh for later", () => {
6161
// Contract: When document.hidden is true, refresh is queued.
62-
// When visibilitychange fires and document.hidden becomes false, queued refresh executes.
62+
// When visibilitychange fires or window.focus fires (and document is visible),
63+
// queued refresh executes. Uses both events since visibilitychange alone is
64+
// unreliable in Electron when app is behind other windows or on different desktop.
6365
// This prevents wasted git operations when user isn't looking.
6466
expect(true).toBe(true);
6567
});

src/browser/hooks/useReviewRefreshController.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -238,17 +238,23 @@ export function useReviewRefreshController(
238238
// eslint-disable-next-line react-hooks/exhaustive-deps
239239
}, [api, workspaceId, isCreating]);
240240

241-
// Handle visibility changes - flush pending refresh when tab becomes visible
241+
// Handle visibility/focus changes - flush pending refresh when user returns.
242+
// Uses both visibilitychange (for browser tab hidden state) and window focus
243+
// (for Electron app focus) since visibilitychange alone is unreliable in Electron
244+
// when the app is behind other windows or on a different desktop/space.
242245
useEffect(() => {
243-
const handleVisibilityChange = () => {
246+
const handleReturn = () => {
247+
// Only flush if document is actually visible
244248
if (!document.hidden) {
245249
flushPending("hidden");
246250
}
247251
};
248252

249-
document.addEventListener("visibilitychange", handleVisibilityChange);
253+
document.addEventListener("visibilitychange", handleReturn);
254+
window.addEventListener("focus", handleReturn);
250255
return () => {
251-
document.removeEventListener("visibilitychange", handleVisibilityChange);
256+
document.removeEventListener("visibilitychange", handleReturn);
257+
window.removeEventListener("focus", handleReturn);
252258
};
253259
// flushPending is stable (only uses refs internally)
254260
// eslint-disable-next-line react-hooks/exhaustive-deps

0 commit comments

Comments
 (0)