Skip to content

Commit 62b717a

Browse files
committed
Listeners may never attach if root window isn’t ready; retry until available
1 parent f84689a commit 62b717a

File tree

1 file changed

+64
-63
lines changed

1 file changed

+64
-63
lines changed

src/app/main/screenLock.ts

Lines changed: 64 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -118,76 +118,77 @@ export const setupScreenLock = (): void => {
118118
listen(WEBVIEW_USER_LOGGED_IN, onUserActivity);
119119

120120
// Attach listeners to root window to detect activity
121-
getRootWindow()
122-
.then((rootWindow) => {
123-
// Clear timer on focus (user returned to app)
124-
rootWindow.addListener('focus', () => {
125-
rootWindowFocused = true;
126-
suspended = false;
127-
if (blurStartTimeout) {
128-
clearTimeout(blurStartTimeout);
129-
blurStartTimeout = null;
130-
}
131-
clearTimer('focus');
132-
});
133-
134-
// Start timer on blur (user left the app) — delay start slightly to avoid races
135-
rootWindow.addListener('blur', () => {
136-
rootWindowFocused = false;
137-
suspended = false;
138-
lastBlurAt = Date.now();
139-
if (blurStartTimeout) {
140-
clearTimeout(blurStartTimeout);
141-
}
142-
blurStartTimeout = setTimeout(() => {
143-
blurStartTimeout = null;
144-
// Only start the timer if the window is still unfocused
145-
try {
146-
if (!rootWindow.isFocused()) {
147-
startTimer();
148-
}
149-
} catch (e) {
150-
// ignore
121+
const attachRootWindowListeners = () => {
122+
getRootWindow()
123+
.then((rootWindow) => {
124+
// Clear timer on focus (user returned to app)
125+
rootWindow.addListener('focus', () => {
126+
rootWindowFocused = true;
127+
suspended = false;
128+
if (blurStartTimeout) {
129+
clearTimeout(blurStartTimeout);
130+
blurStartTimeout = null;
151131
}
152-
}, BLUR_START_DELAY_MS);
153-
});
154-
155-
// Any input while focused is activity: clear timer
156-
rootWindow.webContents.on('before-input-event', () => {
157-
suspended = false;
158-
if (blurStartTimeout) {
159-
clearTimeout(blurStartTimeout);
160-
blurStartTimeout = null;
161-
}
162-
clearTimer('before-input-event');
163-
});
132+
clearTimer('focus');
133+
});
164134

165-
// IPC messages from renderer indicate activity: clear timer
166-
rootWindow.webContents.on('ipc-message', () => {
167-
try {
168-
// Ignore IPCs that happen immediately after blur (they may be caused
169-
// by blur handling in renderers). Use a small grace window.
170-
const now = Date.now();
171-
if (now - lastBlurAt < GRACE_WINDOW_MS) {
172-
return;
173-
}
174-
if (!rootWindow.isFocused()) {
175-
return;
135+
// Start timer on blur (user left the app) — delay start slightly to avoid races
136+
rootWindow.addListener('blur', () => {
137+
rootWindowFocused = false;
138+
suspended = false;
139+
lastBlurAt = Date.now();
140+
if (blurStartTimeout) {
141+
clearTimeout(blurStartTimeout);
176142
}
143+
blurStartTimeout = setTimeout(() => {
144+
blurStartTimeout = null;
145+
// Only start the timer if the window is still unfocused
146+
try {
147+
if (!rootWindow.isFocused()) {
148+
startTimer();
149+
}
150+
} catch (e) {
151+
// ignore
152+
}
153+
}, BLUR_START_DELAY_MS);
154+
});
155+
156+
// Any input while focused is activity: clear timer
157+
rootWindow.webContents.on('before-input-event', () => {
177158
suspended = false;
178159
if (blurStartTimeout) {
179160
clearTimeout(blurStartTimeout);
180161
blurStartTimeout = null;
181162
}
182-
clearTimer('ipc-message');
183-
} catch (e) {
184-
// ignore
185-
}
163+
clearTimer('before-input-event');
164+
});
165+
166+
// IPC messages from renderer indicate activity: clear timer
167+
rootWindow.webContents.on('ipc-message', () => {
168+
try {
169+
// Ignore IPCs that happen immediately after blur (they may be caused
170+
// by blur handling in renderers). Use a small grace window.
171+
const now = Date.now();
172+
if (now - lastBlurAt < GRACE_WINDOW_MS) {
173+
return;
174+
}
175+
if (!rootWindow.isFocused()) {
176+
return;
177+
}
178+
suspended = false;
179+
if (blurStartTimeout) {
180+
clearTimeout(blurStartTimeout);
181+
blurStartTimeout = null;
182+
}
183+
clearTimer('ipc-message');
184+
} catch (e) {
185+
// ignore
186+
}
187+
});
188+
})
189+
.catch(() => {
190+
setTimeout(attachRootWindowListeners, 500);
186191
});
187-
})
188-
.catch(() => {
189-
// If root window isn't ready yet, watch again later when it's created elsewhere.
190-
// We rely on the watch above to start timer when timeout changes and root window will
191-
// be available soon after application start.
192-
});
192+
};
193+
attachRootWindowListeners();
193194
};

0 commit comments

Comments
 (0)