fix(core): drive auto-lock idle from real input, not widget focus
The auto-lock idle clock was reset whenever any ImGui item was active, so a text field left focused (a half-filled send form, say) counted as continuous activity and kept the wallet unlocked indefinitely, well past the configured idle timeout. - The idle clock is now fed by real input events (key, text, mouse, touch, pen, gamepad button) as they are ingested on the main thread, plus a still-held mouse button so a drag or scrollbar grab that emits no new event still counts. A focused but untouched widget no longer does. - A new header-only IdleTracker owns the clock and never moves backwards, so an event stamped before the previous one cannot shorten the idle time. Behaviour change: a form left focused and idle past the timeout now auto-locks. The form's buffers are app state and survive the lock and unlock, so nothing typed is lost. Tests: a new IdleTracker case covers idle time growing with no events (enough to trip a 900s lock), activity resetting it, the clock never moving backwards, and a query before the last activity reading zero rather than a negative value. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+7
-4
@@ -868,14 +868,17 @@ void App::update()
|
||||
// If a wallet switch's daemon failed to start, revert to the previous wallet (main-thread-safe).
|
||||
processWalletSwitchRevert();
|
||||
|
||||
// Track user interaction for auto-lock. Not in the background: a minimized window runs update() without
|
||||
// new frames, so the IO state is the last frame's, and a stale mouse delta kept auto-lock from ever firing.
|
||||
// Real input arrives through App::noteUserInput() (main.cpp event ingest). What stays here covers input
|
||||
// that produces no new SDL event this frame: a held mouse button (a drag or scrollbar grab without
|
||||
// motion). NOT in the background: a minimized window runs update() with the last frame's IO, and a stale
|
||||
// mouse delta once kept auto-lock from ever firing. Deliberately NOT IsAnyItemActive(): a focused text
|
||||
// field stays active indefinitely (C21).
|
||||
if (!window_background_ &&
|
||||
(io.MouseDelta.x != 0 || io.MouseDelta.y != 0 ||
|
||||
io.MouseClicked[0] || io.MouseClicked[1] ||
|
||||
io.InputQueueCharacters.Size > 0 ||
|
||||
ImGui::IsAnyItemActive())) {
|
||||
last_interaction_ = std::chrono::steady_clock::now();
|
||||
ImGui::IsAnyMouseDown())) {
|
||||
idle_.noteActivity();
|
||||
}
|
||||
|
||||
// Advance the refresh timers by the real time since the last update BEFORE the RPC results are
|
||||
|
||||
Reference in New Issue
Block a user