fix: suppress cross-PID spurious focus bounce on tag switch#165
fix: suppress cross-PID spurious focus bounce on tag switch#165typester merged 4 commits intotypester:mainfrom
Conversation
When switching to a tag containing certain Chromium-based apps (e.g., Dia browser), macOS sends a spurious FocusedWindowChanged event ~90ms later pointing back to the previously focused (now hidden) window of a different app. The auto-tag-switch logic interpreted this as a user-initiated external focus change and reverted the tag switch. The existing FocusIntent suppression only handled same-PID focus redirects. This adds cross-PID suppression: when FocusIntent is active and focus bounces to a hidden window of a different app, the event is suppressed without calling refocus_window (which would create an infinite bounce loop).
|
Hi ka2u-san, long time no see! Hope you're doing well. Thanks for the PR! The approach looks good to me. There's an ongoing long-running fix task in #161 that touches the same area, so I'd like to take over and incorporate this change on my end. One question: is the 200ms suppression window sufficient here? I'm wondering if it might not be enough when the machine is under heavy load. In #161, I've been increasing the cross-display suppression window up to 1000ms and observing the results before merging (which is why that branch hasn't been merged yet). |
|
Hi typester-san, Thanks, I'm doing great! Hope you're well. The approach of extending the suppression window makes sense. The 200ms was inherited from the existing FocusIntent::SUPPRESSION_DURATION_MS — in the debug logs the bounce happened at ~90ms, so 200ms covered Using a longer window (like the 500ms or 1000ms being explored in #161) seems safer for cross-PID suppression since the only downside is a slightly longer period where a real user-initiated focus change to a Happy to have this incorporated into #161. Thank you for your consideration. |
ae29b06 to
cded12b
Compare
|
@ka2u I made some minor refactoring, but I'll keep the SUPPRESSION_DURATION at 200ms for now. I'm going to merge this as-is. Please let me know if you run into any issues! |
## 🤖 New release * `yashiki-ipc`: 0.12.0 -> 0.12.1 * `yashiki`: 0.12.0 -> 0.12.1 * `yashiki-layout-tatami`: 0.12.0 -> 0.12.1 * `yashiki-layout-byobu`: 0.12.0 -> 0.12.1 <details><summary><i><b>Changelog</b></i></summary><p> ## `yashiki-ipc` <blockquote> ## [0.12.0](yashiki-ipc-v0.11.6...yashiki-ipc-v0.12.0) - 2026-02-25 ### Added - [**breaking**] add keybinding mode system (river-style) ([#157](#157)) </blockquote> ## `yashiki` <blockquote> ## [0.12.1](yashiki-v0.12.0...yashiki-v0.12.1) - 2026-04-13 ### Fixed - suppress cross-PID spurious focus bounce on tag switch ([#165](#165)) - suppress unintended tag switch from macOS auto-activation after app termination ([#161](#161)) </blockquote> ## `yashiki-layout-tatami` <blockquote> ## [0.7.3](yashiki-layout-tatami-v0.7.2...yashiki-layout-tatami-v0.7.3) - 2026-01-20 ### Other - update Cargo.lock dependencies </blockquote> ## `yashiki-layout-byobu` <blockquote> ## [0.7.3](yashiki-layout-byobu-v0.7.2...yashiki-layout-byobu-v0.7.3) - 2026-01-20 ### Other - update Cargo.lock dependencies </blockquote> </p></details> --- This PR was generated with [release-plz](https://github.com/release-plz/release-plz/). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
When switching to a tag containing certain Chromium-based apps (e.g., Dia
browser), macOS sends a spurious FocusedWindowChanged event ~90ms later
pointing back to the previously focused (now hidden) window of a different
app. The auto-tag-switch logic interpreted this as a user-initiated external
focus change and reverted the tag switch.
The existing FocusIntent suppression only handled same-PID focus redirects.
This adds cross-PID suppression: when FocusIntent is active and focus
bounces to a hidden window of a different app, the event is suppressed
without calling refocus_window (which would create an infinite bounce loop).
fixes #164