Skip to content

fix(border): debounce border redraws adaptively to prevent flicker without lag - #204

Open
lekifier wants to merge 1 commit into
FelixKratz:mainfrom
lekifier:fix/border-flicker-debounce
Open

lekifier wants to merge 1 commit into
FelixKratz:mainfrom
lekifier:fix/border-flicker-debounce

Conversation

@lekifier

@lekifier lekifier commented Aug 2, 2026

Copy link
Copy Markdown

Problem

When switching spaces with yabai's instant (scripting-addition) switch, the focused window's border visibly flickers — it gets redrawn several times in quick succession. This does not happen with macOS's native (animated) space switching. Reported in #79.

Root cause

On a space change, a window is hit by a burst of events — Unhide, Level, Reorder, and Focus — each of which calls border_update(), and each redraw is a visible flash. The focused border is therefore repainted ~4-5 times within ~50ms.

Fix

An adaptive per-border debounce in border_update():

  • A constant 80ms debounce (my first attempt) kills the flicker but makes the border visibly lag behind fast focus changes, because every update reschedules the wait. So the delay is now context-dependent:
  • borders already receives EVENT_SPACE_CHANGE (space_handler in events.c); when it fires, a 500ms transition window opens.
  • Inside the window, updates are debounced by 80ms, collapsing the burst into a single redraw with the final state (anti-flicker).
  • Outside the window, updates are debounced by only 5ms, so the border tracks focus changes almost instantly.
  • Each border keeps an incrementing update_generation counter; a newer request supersedes older scheduled ones in both modes.

Also drops the unreachable async path left in border_update() (border_update_async_proc).

Tested with yabai instant space switching and fast window cycling: no flicker on space change, border tracks focus immediately otherwise.

Fixes #79

@lekifier
lekifier force-pushed the fix/border-flicker-debounce branch 2 times, most recently from 685abf1 to d9a62b6 Compare August 2, 2026 14:54
…thout lag

During a space change, a window is hit by a burst of events (unhide, level, reorder, focus) that each trigger border_update, producing a visible flicker for every redraw.

An earlier version of this fix debounced every redraw by 80ms. That removes the flicker but makes the border visibly lag behind fast focus changes (e.g. window cycling), because every update reschedules the wait.

Make the debounce adaptive instead:

- borders already receives EVENT_SPACE_CHANGE (space_handler in events.c); when it fires, open a 500ms transition window.
- While inside the window, border_update() debounces by 80ms, so the burst collapses into a single redraw with the final state.
- Outside the window, debounce by only 5ms, so the border tracks focus changes almost instantly.

The per-border update_generation counter supersedes stale scheduled updates in both modes. Also drop the unreachable async path left behind (border_update_async_proc).

Fixes FelixKratz#79
@lekifier
lekifier force-pushed the fix/border-flicker-debounce branch from d9a62b6 to 84eedcd Compare August 6, 2026 17:23
@lekifier lekifier changed the title fix(border): debounce rapid border redraws to eliminate flicker on space change fix(border): debounce border redraws adaptively to prevent flicker without lag Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Borders flicker few times on space change with yabai

1 participant