hook: ask who is in front before hooking over them - #545
Conversation
The exclusion list is only ever consulted when the foreground *changes*. `on_focus_changed` is the sole reader, and it fires on a WinEvent — so a game already in front when the engine starts, or when a layout is re-applied over it, was never announced, the pause never engaged, and LBM hooked straight over an excluded process. It stayed that way until the user alt-tabbed out and back, which is the only thing that produces the event the decision was waiting for. Reported in #541, where adding the game to the exclusion list changed nothing: the entry was right, it was simply never consulted at a moment when it could still matter. Starting LBM after the game was always enough to reproduce it, but live update (#525) made it ordinary rather than rare by re-Running on every edit of the layout. `Run` is the one moment the daemon decides to hook, so it is the one place the answer changes anything: it now reads the foreground itself, right after re-reading the list, and lets go of the hook if an earlier Run had already taken it over an excluded app. An unknown foreground — no window, an owner that will not resolve, a platform that does not answer — leaves the flag as it stands rather than guess. Guessing "not excluded" would unpause over a game, which is the failure this commit exists to remove. Linux answers `None` by design: the query would mean opening an X connection from whichever thread asked, and the focus watcher already owns one and already reports the active window once when it connects, so the case is covered there by that initial report. The decision is split from the OS query so it can be tested without a desktop; three tests cover the excluded, not-excluded and unknown paths. Tested: cargo test 84/84 on Linux, cargo check --all-targets clean for x86_64-pc-windows-gnu (which compiles the Windows paths this touches), clippy quiet on the touched files, fmt-clean on them. Not tested: the Windows behaviour itself. Needs a run with a game in the exclusion list already in the foreground when the engine starts — the engine must not hook — and the same after alt-tabbing away and back. Co-Authored-By: Claude <noreply@anthropic.com>
|
Correction to this PR's rationale, from the reporter of #541 after it was merged. The commit message and the description above both say live update (#525) is what made this frequent. That is wrong for the case that produced the report: the reporter uses Apply On Click, not Live Update, and never had live update on when the escapes happened. The real trigger is display changes. The daemon unhooks itself over any display change, and the UI re-hooks once the configuration settles ( The fix itself is unaffected — Worth noting that the UI already assumed the pause would survive that re-hook: |
Addresses the exclusion half of #541.
The exclusion list is only ever consulted when the foreground changes.
on_focus_changedis its sole reader, and it fires on a WinEvent — so a game already in front when the engine starts, or when a layout is re-applied over it, was never announced, the pause never engaged, and LBM hooked straight over an excluded process. It stayed that way until the user alt-tabbed out and back, which is the only thing that produces the event the decision was waiting for.That is why the reporter of #541 saw no effect from adding the game: the entry was right, it was simply never consulted at a moment when it could still matter.
Starting LBM after the game was always enough to reproduce it. Live update (#525) made it ordinary rather than rare, by re-Running on every edit of the layout.
The change
Runis the one moment the daemon decides to hook, so it is the one place the answer changes anything. It now reads the foreground itself, right after re-reading the list, and lets go of the hook if an earlierRunhad already taken it over an excluded app.Three deliberate choices:
Noneby design. The query would mean opening an X connection from whichever thread asked; the focus watcher already owns one and already reports the active window once when it connects, so the case is covered there by that initial report instead.Tested
cargo test84/84 on Linux — three new tests covering the excluded, not-excluded and unknown pathscargo check --all-targetsclean forx86_64-pc-windows-gnu, which actually compiles the Windows paths this touches rather than only the Linux onescargo clippyquiet on the touched files (the pre-existing warnings elsewhere are unchanged),cargo fmtclean on themNot tested — needs Windows
The behaviour itself. The checklist:
Scope
This is the part of #541 that is a bug on our side. The reporter also has Pause in games switched off and border sections set to
Move: 0, which explain the escapes independently of this — asked about both in the issue.🤖 Generated with Claude Code