Skip to content

comp: add smooth fade transition to active window hint - #2810

Open
DavidDaza2906 wants to merge 1 commit into
pop-os:masterfrom
DavidDaza2906:focus-hint-fade
Open

comp: add smooth fade transition to active window hint#2810
DavidDaza2906 wants to merge 1 commit into
pop-os:masterfrom
DavidDaza2906:focus-hint-fade

Conversation

@DavidDaza2906

@DavidDaza2906 DavidDaza2906 commented Sep 1, 2026

Copy link
Copy Markdown
  • I have disclosed use of any AI generated code in my commit messages.
    • If you are using an LLM, and do not fully understand the changes it is making to the code base, do not create a PR.
    • In our experience, AI generated code often results in overly complex code that lacks enough context for a proper fix or feature inclusion. This results in considerably longer code reviews. Due to this, AI authored or partially authored PRs may be closed without comment.
  • I understand these changes in full and will be able to respond to review comments.
  • My change is accurately described in the commit message.
  • My contribution is tested and working as described.
  • I have read the Developer Certificate of Origin and certify my contribution under its conditions.

Focus indicator fade transition (focus_transition_ms)

Partially addresses #989 (adds a smooth transition to the active window hint instead of a temporary hint; happy to extend toward that UX)

Attribution: implemented with AI assistance; the feature design, scope, testing,
and validation are mine (also disclosed in the commit message).

Problem

The focus indicator ("active hint") currently toggles on/off in a single frame. With
focus_follows_cursor enabled and overlapping windows, focus changes feel abrupt/aggressive:
the border pops in and out on every hover.

Approach

This adds an opt-in fade of the focus indicator on activation changes:

  • New compositor option focus_transition_ms in CosmicCompConfig (default 0 = exact
    current behavior, no extra allocations or render work).
  • Shell::update_active now returns which windows changed activation state, and each
    CosmicMapped stores its transition state (from_alpha, direction) so re-triggered
    transitions resume from the currently displayed alpha instead of restarting — rapid
    focus changes (e.g. double events from a single click) degrade to a continuous fade
    instead of flickering.
  • A single repeating calloop timer drives ~60fps redraws while any transition is active
    and self-cancels once they all finish (rendering one final settled frame).
  • The floating and tiling render paths share the interpolation via
    CosmicMapped::focus_indicator_{alpha,visible}:
    • the newly focused window fades in,
    • the previously focused window fades out (cross-fade).

Tiling resize/swap indicators keep their existing behavior; only the alpha of the
focus indicator is interpolated.

Notes

  • Default 0 means byte-identical rendering to before for users who don't opt in
    (the interpolation branch is skipped entirely).
  • The transition works for both pointer-driven focus changes (focus_follows_cursor)
    and keyboard-driven ones, and also fires on workspace switches via refresh_focus.
  • Groups/backdrops and swap-mode indicators are intentionally left at full alpha.
  • The forced-redraw timer relies on schedule_render, which is a no-op on the winit
    backend (see State::schedule_render); the fade animates on X11 and KMS backends.
    Happy to adapt if upstream prefers a different redraw-scheduling mechanism.

Testing

  • cargo check/build on Arch (rustc 1.97, smithay git e3d461a).
  • Manual testing nested (X11 backend inside a COSMIC session): open several windows,
    change focus with Super+arrows / focus-follows-cursor / clicks, observe the cross-fade
    of the hint.
  • Verified that with focus_transition_ms: 0 rendering is unchanged.
  • Pixel-level verification with an artificially long transition (30s): the hint
    border renders at intermediate alpha during the transition (e.g. RGB
    57,102,109 mid-fade) and reaches the exact full-accent color (99,208,223) when it
    completes, for both fade-in and fade-out directions.
  • Repeated rapid clicking (the initial implementation flickered here) was fixed by the
    resume-from-current-alpha model and verified clean.

@DavidDaza2906
DavidDaza2906 marked this pull request as ready for review September 1, 2026 22:57
@leviport

leviport commented Sep 1, 2026

Copy link
Copy Markdown
Member

The PR template is required. Please add it back and fill it out.

@DavidDaza2906

Copy link
Copy Markdown
Author

Sorry about that — I accidentally replaced the template when writing the description. It's filled out now, and I've also added the AI disclosure to the commit message itself, as required by the first checkbox.

Add an opt-in 'focus_transition_ms' config option (default 0 = exact
current behavior) that fades the focused window's active hint in and
the previously focused window's hint out, instead of switching both in
a single frame.

- cosmic-comp-config: add focus_transition_ms (u64, default 0)
- config: hot-reload handler for the new key
- shell: track focus indicator transition state (from_alpha, direction)
  on CosmicMapped; update_active() returns the windows whose activation
  changed; re-triggered transitions resume from the currently displayed
  alpha so rapid focus changes never flicker
- shell: a single repeating calloop timer drives ~60fps redraws while
  any transition is active and self-cancels once they all finish
- render: floating and tiling layouts share the alpha interpolation via
  CosmicMapped::focus_indicator_{alpha,visible}, fading the hint in on
  the newly focused window and out on the previously focused one

With focus_follows_cursor enabled and overlapping windows, the focus
indicator currently jumps abruptly between windows. A short fade makes
the change read as continuous rather than aggressive. Partially
addresses pop-os#989.

Implemented with AI assistance; the feature design, scope, testing, and
validation were done by the submitter, who understands the changes in
full.

Signed-off-by: DavidDaza2906 <99994731+DavidDaza2906@users.noreply.github.com>
@Drakulix

Drakulix commented Sep 2, 2026

Copy link
Copy Markdown
Member

This change would need to go through @pop-os/ux first, to determine if we want that feature. The referenced issue doesn't indicate that this happened yet.

* A single repeating calloop timer drives ~60fps redraws while any transition is active
  and self-cancels once they all finish (rendering one final settled frame).

Code-wise this is also not acceptable. We already have animation logic, this should re-use that.

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.

3 participants