fix(linux): zoom ghost-pixel fix via CSS transition#228
Open
AgentU-asaf wants to merge 1 commit intomainfrom
Open
fix(linux): zoom ghost-pixel fix via CSS transition#228AgentU-asaf wants to merge 1 commit intomainfrom
AgentU-asaf wants to merge 1 commit intomainfrom
Conversation
WebKitGTK leaves ghost pixels in the area vacated when a zoomed element shrinks (zoom: var(--zoomfactor) going from e.g. 1.2 → 1.0). WebKit does not repaint the vacated region because it considers only the new (smaller) bounding box dirty. Fix: set --zoom-transition-dur: 80ms on <html> in initChromeZoom() and add `transition: zoom var(--zoom-transition-dur, 0ms) ease-out` to every element that carries zoom: var(--zoomfactor): - .block-frame-default-header (block.scss) - .statusbar (StatusBar.scss) - .window-drag-header (window-header.linux.scss) The 80 ms transition forces WebKitGTK's animation engine to invalidate and repaint the full pre-transition bounding box on each zoom change, clearing the ghosts. The variable defaults to 0ms so non-Linux builds and any element that doesn't set the var are unaffected. NOTE: this approach introduces a scroll-opacity regression on Linux (transparent window flashes opaque during scroll because the always-on transition creates GPU compositing layers that temporarily drop alpha). The fix needs to be gated to fire only during actual zoom changes, not permanently. See docs/retro-opacity-transparency-2026-03-25.md. Also adds retro document covering the full opacity/transparency investigation and recommended path forward. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
ReAgent Diagnostics
| Field | Value |
|---|---|
| ReAgent Version | 5.12.4 |
| Project Context | CLAUDE.md loaded |
| Model | claude-opus-4-6 |
| Effort | high |
| Ref Repos | Disabled |
| Merge Analysis | Clean |
| Review Time | 30.3s |
| Timestamp | 2026-03-25T12:03:06Z |
| Repository | agentmuxai/agentmux |
| PR | #228 |
Issues:
- package.json:3 - Version downgrade detected: 0.32.83 → 0.32.82. Versions must increase; rebase on main and bump to 0.32.84+
- frontend/app/window/window-header.linux.scss:33 - Hardcodes
80msinstead of usingvar(--zoom-transition-dur, 0ms)like block.scss and StatusBar.scss. If the duration changes, this file will be out of sync
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
--zoom-transition-dur: 80msininitChromeZoom()so WebKitGTK's animation engine invalidates ghost pixels left behind whenzoom: var(--zoomfactor)elements shrink on zoom-outtransition: zoom var(--zoom-transition-dur, 0ms) ease-outto block headers, statusbar, and window drag header (the three elements carrying the CSS zoom)docs/retro-opacity-transparency-2026-03-25.md) covering the full investigation and recommended path forwardKnown issue (not fixed in this PR)
The always-on transition creates GPU compositing layers in WebKitGTK that temporarily drop alpha during scroll, causing the window to flash opaque. The ghost fix needs to be gated to fire only during actual zoom operations (not permanently). This is documented in the retro and should be addressed separately.
Test plan
🤖 Generated with Claude Code