Skip to content

emrg: gui — fix .conv-item hover flicker in Electron scroll container (compositing layer) - #1061

Merged
argszero merged 1 commit into
masterfrom
feature/fix-conv-item-hover-flicker
Aug 28, 2026
Merged

emrg: gui — fix .conv-item hover flicker in Electron scroll container (compositing layer)#1061
argszero merged 1 commit into
masterfrom
feature/fix-conv-item-hover-flicker

Conversation

@argszero

Copy link
Copy Markdown
Owner

Summary

Fixes intermittent whole-row flicker/shake on the left open-sessions .conv-item list on hover (0.2.85, Electron 31.7.7 + macOS 26.5.2). Rant: 2026-08-28T13:31:55.

Root cause

The logic layer was ruled out (no hover show/hide, no React hover events, no periodic re-render, low-frequency broadcast, stable store refs, opaque colors). The only structural difference vs vanilla: .react-shell-sidebar carries overflow-y: auto (added in #1040) — making the sidebar a scroll container in which the .conv-item:hover 150ms background-color transition triggers main-thread repaint flicker on this Electron (Chromium 126) / macOS 26 combo.

Changes

  1. renderer/css/components.css.conv-item gets a persistent compositing layer (transform: translateZ(0) + will-change: background-color). The hover background transition now runs on the GPU layer instead of repainting the scroll container on the main thread. The layer exists before hover, so there is no mid-transition promotion.

  2. renderer/src/shell.css — drop the redundant overflow-y: auto from .react-shell-sidebar (vanilla #sidebar has none — scrolling belongs to the list itself). Add .react-shell-sidebar .react-sidebar { display: flex; flex-direction: column; flex: 1; min-height: 0 } so #open-sessions' max-height: 40% + overflow-y: auto resolves against a definite height and the list keeps scrolling. The sidebar is no longer a scroll container, removing the flicker-trigger environment entirely.

Verification

  • Renderer: Sidebar/Shell vitest 43/43, tsc --noEmit clean
  • GUI node tests: 87 pass / 8 skip (theme-guard included — no hardcoded colors introduced)
  • No Python changes

… (compositing layer)
Rant 2026-08-28T13:31:55: on 0.2.85 + Electron 31.7.7 (Chromium 126) +
macOS 26.5.2, the left open-sessions .conv-item rows intermittently
flicker/shake on hover. Logic layer ruled out; the structural difference
vs vanilla is .react-shell-sidebar carrying overflow-y:auto (added in
#1040) — making the sidebar a scroll container in which the
background-color 150ms hover transition triggers main-thread repaint
flicker on this Electron/macOS combo.
- components.css .conv-item: persistent compositing layer promotion
(transform: translateZ(0) + will-change: background-color) — the hover
background transition now runs on the GPU layer instead of repainting
the scroll container on the main thread. Layer exists before hover, so
no mid-transition promotion.
- shell.css .react-shell-sidebar: drop the redundant overflow-y:auto
(vanilla #sidebar has none — scrolling belongs to the list itself).
Add .react-shell-sidebar .react-sidebar { display:flex;
flex-direction:column; flex:1; min-height:0 } so #open-sessions'
max-height:40% + overflow-y:auto resolves against a definite height
and the list keeps scrolling. Sidebar is no longer a scroll container,
removing the flicker trigger environment entirely.
Verified: renderer Sidebar/Shell tests 43/43, tsc clean, GUI node tests
87 pass/8 skip (theme-guard included).

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 20260828-135253

Flicker fix verified against the rant's root-cause analysis:

  1. .conv-item gets a persistent compositing layer (transform: translateZ(0) + will-change: background-color) — the hover background-color 150ms transition now runs on the GPU layer, not the scroll container's main-thread repaint. Layer exists before hover (no mid-transition promotion).
  2. .react-shell-sidebar drops the redundant overflow-y:auto (vanilla #sidebar has none); .react-sidebar becomes flex:1 + min-height:0 so #open-sessions' max-height:40% + overflow-y:auto resolves against a definite height — scroll behavior preserved, sidebar is no longer a scroll container.
  3. No hardcoded colors (theme-guard passed), no logic/React changes.

Local verification on this head: Sidebar/Shell vitest 43/43, tsc clean, GUI node 87 pass/8 skip. CI test + test-windows green.

@how2how2how2-arch

Copy link
Copy Markdown
Contributor

Independent verification (contributor): fetched the PR head and validated the change. The .conv-item fix (translateZ(0) + will-change: background-color) correctly promotes the hover transition to a compositing layer — the standard fix for main-thread repaint flicker inside Electron scroll containers. The shell.css restructure (dropping overflow-y:auto from .react-shell-sidebar, scrolling via .react-sidebar with flex:1 + min-height:0) also addresses the root cause by making #open-sessions max-height:40% resolve against the inner column, matching the vanilla #sidebar layout. CSS on the head is balanced/valid (238+34 braces, no new custom properties so the theme-integrity guard is unaffected). Renderer suite 449 passed locally; CI test + test-windows double-green.

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 20260828-140759

Independent re-review of the diff on head f80b988:

  1. components.css .conv-item: transform: translateZ(0) + will-change: background-color — persistent compositing layer before hover, so the 150ms background-color transition runs on the GPU layer and no longer forces the scroll container's main-thread repaint (the Electron 31.7.7/Chromium 126 on macOS 26 flicker).
  2. shell.css: overflow-y:auto removed from .react-shell-sidebar (vanilla #sidebar parity), .react-sidebar now flex:1 + min-height:0 so #open-sessions' max-height:40% + overflow-y:auto resolves against a definite height — scroll behavior preserved, sidebar is no longer a scroll container.
  3. grep confirms exactly one .react-sidebar rule exists (no conflicting selectors); only theme variables used (theme-guard 2/2 passed).

Local verification on head: Sidebar/Shell vitest 43/43, theme-guard 2/2. CI test + test-windows both green (run 33146418628).

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 20260828-141707

Third consecutive LGTM (135253 → 140759 → 141707, no ❌ in between). Head f80b988 unchanged since cycle 140759 re-review; CI test + test-windows still green (run 33146418628); mergeable. Merge after the v0.2.86 tag so the flicker fix lands in v0.2.87 as intended.

@argszero
argszero merged commit 361574b into masterAug 28, 2026
2 checks passed
@argszero
argszero deleted the feature/fix-conv-item-hover-flicker branch August 28, 2026 06:20
argszero added a commit that referenced this pull request Aug 28, 2026
…ix, tiptap Stage 1+2) (#1064)
Co-authored-by: EMRG Evolution <emrg@argszero.dev>
Sign up for freeto 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.

2 participants

@argszero@how2how2how2-arch