File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 199199.status-waiting .tab-status-dot : nth-child (8 ) { animation-delay : 0.15s ; }
200200.status-waiting .tab-status-dot : nth-child (9 ) { animation-delay : 0.3s ; }
201201
202+ /* Linux variant — single static dot, no animation, no box-shadow blur.
203+ The 9-dot wave/snake/ripple loops + box-shadow halos peg WebKit2GTK +
204+ Cairo (no compositor-thread opacity for non-promoted layers; box-shadow
205+ blur re-rasters on CPU each frame). Sized up to 5px so a lone dot reads
206+ as deliberate. Color still conveys idle/working/waiting via the status-
207+ class background-color rules above; we override box-shadow here to kill
208+ the halo. Specificity (0,2,0) matches the status-* rules and source
209+ order wins. */
210+ .tab-status-grid--static {
211+ grid-template-columns : 5px ;
212+ grid-template-rows : 5px ;
213+ }
214+ .tab-status-grid--static .tab-status-dot {
215+ width : 5px ;
216+ height : 5px ;
217+ animation : none;
218+ box-shadow : none;
219+ }
220+
202221/* ─── Terminal Wrapper ─── */
203222
204223.terminal-wrapper {
Original file line number Diff line number Diff line change @@ -169,7 +169,7 @@ const SvgInstaller = () => (
169169 brand icon and together they pegged WebKit + coffee-cli at
170170 ~1.2 cores idle on Wayland (verified live via SSH /proc
171171 sampling). Static `d` on Linux = no steam drift, full glyph. */ }
172- { ! navigator . userAgent . toLowerCase ( ) . includes ( 'linux' ) && (
172+ { ! __IS_LINUX__ && (
173173 < animate
174174 attributeName = "d"
175175 dur = "3s"
@@ -1141,8 +1141,17 @@ export function CenterPanel() {
11411141 session . tool === 'vibeid' || session . tool === 'insights_prerun'
11421142 ? 'working'
11431143 : ( session . agentStatus === 'wait_input' ? 'waiting' : session . agentStatus ?? 'idle' )
1144- } `} >
1145- { Array . from ( { length : 9 } , ( _ , i ) => < div key = { i } className = "tab-status-dot" /> ) }
1144+ } ${ __IS_LINUX__ ? ' tab-status-grid--static' : '' } `} >
1145+ { /* Linux gate — the 9 dot wave/snake/ripple animations are
1146+ opacity-loop infinites with box-shadow halos. WebKit2GTK
1147+ + Cairo doesn't promote these to compositor layers, so
1148+ each frame re-rasters the box-shadow blur on CPU; with
1149+ N tabs that's 9N indefinite repaints. Linux gets a
1150+ single static colored dot instead — same idle/working/
1151+ waiting color signal, zero animation cost. */ }
1152+ { __IS_LINUX__
1153+ ? < div className = "tab-status-dot tab-status-dot--solo" />
1154+ : Array . from ( { length : 9 } , ( _ , i ) => < div key = { i } className = "tab-status-dot" /> ) }
11461155 </ div >
11471156 ) }
11481157 < button
Original file line number Diff line number Diff line change @@ -239,7 +239,7 @@ export function ChatReader({ sessionId }: { sessionId: string }) {
239239 < path fill = "none" stroke = "#fff" strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = "2"
240240 d = "M8 -8c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4M12 -8c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4M16 -8c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4" >
241241 { /* Linux gate — see Explorer.tsx brand-icon for full rationale. */ }
242- { ! navigator . userAgent . toLowerCase ( ) . includes ( 'linux' ) && (
242+ { ! __IS_LINUX__ && (
243243 < animate attributeName = "d" dur = "3s" repeatCount = "indefinite"
244244 values = "M8 0c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4M12 0c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4M16 0c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4;M8 -8c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4M12 -8c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4M16 -8c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4" />
245245 ) }
Original file line number Diff line number Diff line change @@ -496,7 +496,7 @@ export function DosPlayer({ sessionId }: { sessionId: string }) {
496496 < path fill = "none" stroke = "#fff" strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = "2"
497497 d = "M8 -8c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4M12 -8c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4M16 -8c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4" >
498498 { /* Linux gate — see Explorer.tsx brand-icon for full rationale. */ }
499- { ! navigator . userAgent . toLowerCase ( ) . includes ( 'linux' ) && (
499+ { ! __IS_LINUX__ && (
500500 < animate attributeName = "d" dur = "3s" repeatCount = "indefinite"
501501 values = "M8 0c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4M12 0c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4M16 0c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4;M8 -8c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4M12 -8c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4M16 -8c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4" />
502502 ) }
Original file line number Diff line number Diff line change @@ -1103,7 +1103,7 @@ function TierTerminalImpl({
11031103 < path fill = "none" stroke = "#fff" strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = "2"
11041104 d = "M8 -8c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4M12 -8c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4M16 -8c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4" >
11051105 { /* Linux gate — see Explorer.tsx brand-icon for full rationale. */ }
1106- { ! navigator . userAgent . toLowerCase ( ) . includes ( 'linux' ) && (
1106+ { ! __IS_LINUX__ && (
11071107 < animate attributeName = "d" dur = "3s" repeatCount = "indefinite"
11081108 values = "M8 0c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4M12 0c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4M16 0c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4;M8 -8c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4M12 -8c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4M16 -8c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4" />
11091109 ) }
Original file line number Diff line number Diff line change @@ -1103,7 +1103,7 @@ export function Explorer() {
11031103 SMIL). Static `d` on Linux means the steam stops drifting
11041104 upward but the cup glyph itself is fully intact. */ }
11051105 < path fill = "none" stroke = "#fff" strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = "2" d = "M8 -8c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4M12 -8c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4M16 -8c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4" >
1106- { ! navigator . userAgent . toLowerCase ( ) . includes ( 'linux' ) && (
1106+ { ! __IS_LINUX__ && (
11071107 < animate attributeName = "d" dur = "3s" repeatCount = "indefinite" values = "M8 0c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4M12 0c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4M16 0c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4;M8 -8c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4M12 -8c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4M16 -8c0 2 -2 2 -2 4s2 2 2 4s-2 2 -2 4s2 2 2 4" />
11081108 ) }
11091109 </ path >
Original file line number Diff line number Diff line change 1+ /// <reference types="vite/client" />
2+
3+ // Build-time platform constant injected by vite.config.ts via `define`.
4+ // True iff the binary was built on a Linux CI runner. Used to gate
5+ // CPU-expensive WebKit2GTK animations (SMIL path morphs in masks, dot
6+ // grids with box-shadow opacity loops) that are essentially free on
7+ // WebView2 / WKWebView but peg cores on TextureMapper + Cairo.
8+ declare const __IS_LINUX__ : boolean ;
Original file line number Diff line number Diff line change @@ -12,6 +12,15 @@ export default defineConfig({
1212 } ,
1313 // Allow Tauri IPC
1414 envPrefix : [ 'VITE_' , 'TAURI_' ] ,
15+ // Build-time platform constant. Each platform's installer is built on its
16+ // own CI runner (release.yml: ubuntu-22.04 / windows-latest / macos-13),
17+ // so process.platform here = the target platform of the binary being
18+ // produced. Far more reliable than navigator.userAgent — WebKit2GTK's UA
19+ // string is configurable and has been observed to omit "Linux" on some
20+ // distro/Tauri-version combos, defeating the runtime gate.
21+ define : {
22+ __IS_LINUX__ : JSON . stringify ( process . platform === 'linux' ) ,
23+ } ,
1524 build : {
1625 // Tauri supports es2021
1726 target : [ 'es2021' , 'chrome105' , 'safari15' ] ,
You can’t perform that action at this time.
0 commit comments