Skip to content

Race condition in dock hide when switching windows with oneshot Alt-Tab (keyd) #2780

@lobre

Description

@lobre

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, 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
  1. 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.

gala_keyd_race.webm

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.

  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

Hardware Info

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    IncompleteNeeds more information before we can take action

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions