Race condition in dock hide when switching windows with oneshot Alt-Tab (keyd)
- Dominant language
- Vala
- Stars
- 302
- Forks
- 83
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 7
Description
### What Happened?
I have the dock setting "Hide Dock" set to "When the focused window overlaps the dock".
This issue is triggered when using [keyd](https://github.com/rvaiya/keyd), a Linux key remapping daemon that intercepts keyboard events at the evdev level and re-emits modified events through a virtual `uinput` device. I was unfortunately not able to reproduce the problem without it.
When switching windows using a oneshot `Alt-Tab` configuration from `keyd`, dock visibility can become stale relative to the newly focused window. This reproduces 100% of the time with the event sequence described below.
My configuration includes:
```
leftalt = oneshot(alt)
```
A oneshot modifier is a key that, when tapped, temporarily activates a modifier state for the next key press without needing to hold it down.
So, with this configuration, I tap `Alt` once, then tap `Tab`, instead of holding `Alt` while pressing `Tab`.
Physically, I do:
```
Alt down -> Alt up -> Tab down -> Tab up
```
Because of the oneshot behavior, the compositor effectively sees:
```
Alt down -> Tab down -> Tab up -> Alt up
```
The important detail is that `Tab up` and `Alt up` **occur almost back-to-back**.
Under this timing, dock visibility can become latched from the previous context. There are two observable manifestations, but I believe they are the same underlying issue.
1. Stuck visible mode
- switching from a window that does not overlap the dock area to a window that overlaps the dock area (such as a fullscreen window): the dock incorrectly remains visible
- switching in the opposite direction appears correct
2. Stuck hidden mode
- switching from a window that overlaps the dock area to a window that does not overlap the dock area: the dock incorrectly remains hidden
- switching in the opposite direction appears correct
After a reboot or fresh session, the dominant broken direction can flip. This suggests a single timing or state issue with opposite visible outcomes depending on session state, rather than two separate bugs.
Don't know if this is going to help, but from reading the code, the hide logic for `OVERLAPPING_FOCUS_WINDOW` is computed in `PanelWindow.vala`, but the "focused" window seems to be inferred via `InternalUtils.get_mru_window()` rather than directly using the compositor's current focused window.
Under tight timing, it appears that the focus change event can fire while the MRU or user-time ordering has not yet updated to reflect the newly activated window. In that case, overlap is computed against the previously focused window, and the dock visibility decision is based on stale state. No later signal necessarily corrects it, so the dock visibility remains latched.
The same focus-based path is used for the following hide modes, so they are likely affected as well:
- `OVERLAPPING_FOCUS_WINDOW`
- `MAXIMIZED_FOCUS_WINDOW`
- `NEVER`
I am attaching a short screencast below that shows the issue occurring.
https://github.com/user-attachments/assets/2ed2ec2e-d89d-48ce-a6dd-9de0f7f7b2bc
### Steps to Reproduce
1. In System Settings, go to Desktop -> Dock & Panel.
2. Set "Hide Dock" to "When the focused window overlaps the dock".
3. Install and enable [keyd](https://github.com/rvaiya/keyd).
4. Use the following minimal configuration:
```
[ids]
*
[global]
leftalt = oneshot(alt)
```
5. Open one window that does not overlap the dock area, so the dock is visible.
6. Open another window that overlaps the dock area, for example a fullscreen window.
7. Switch between them by tapping `Alt` once, then tapping `Tab`.
Depending on session state, one direction of the switch will consistently leave the dock in the wrong visibility state.
### Expected Behavior
Each `Alt-Tab` should update dock visibility to match the newly focused window. The dock should hide when the focused window overlaps the dock area, and reveal when it does not. Visibility should not depend on tight timing between `Tab up` and `Alt up`, and should never remain latched from the previous context.
### OS Version
8.x (Circe)
### OS Architecture
amd64 (on most hardwares)
### Session Type
Secure Session (Wayland, This is the default)
### Software Version
Latest release (I have run all updates)
### Log Output
```shell
```
### Hardware Info
_No response_
Contributor guide
Assessment
This issue has not been assessed yet.