fix(workspace): implement dynamic theme-aware border and background colors
- Add PrefersDarkTheme() function to webkit package for GTK theme detection - Update workspace CSS generation to use theme-specific colors: * Dark mode: #333333 borders, #2b2b2b backgrounds * Light mode: #dddddd borders, #ffffff backgrounds - Apply dynamic colors to both single panes and multi-pane workspaces - Add GTK window-level background styling to prevent white bleeding - Resolves white border issue on inactive panes in dark mode
- commit
- e09e4cff3c55f7ca4f67f1a2cadb4088946a0f03
- author
- Brice · · 2025-09-22 19:33 UTC
- parent
- 03656a2
- signature
- unsigned
3 files · +40 -3
M CHANGELOG.md +4 -0
| @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. | |||
| 4 | 4 | ||
| 5 | 5 | ## [Unreleased] | |
| 6 | 6 | ||
| 7 | + | ### Fixed | |
| 8 | + | - **Workspace theme integration**: Fixed white borders on inactive panes by implementing dynamic border colors based on GTK theme preference (dark mode: #333333 borders, light mode: #dddddd borders) | |
| 9 | + | - **GTK window background**: Added theme-aware window and pane background colors to prevent white bleeding through transparent elements | |
| 10 | + | ||
| 7 | 11 | ## [0.9.0] - 2025-09-22 | |
| 8 | 12 | ||
| 9 | 13 | ### Added | |
| @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. | |||||
| 4 | 4 | ||||
| 5 | ## [Unreleased] | 5 | ## [Unreleased] | ||
| 6 | 6 | ||||
| 7 | + | ### Fixed | |||
| 8 | + | - **Workspace theme integration**: Fixed white borders on inactive panes by implementing dynamic border colors based on GTK theme preference (dark mode: #333333 borders, light mode: #dddddd borders) | |||
| 9 | + | - **GTK window background**: Added theme-aware window and pane background colors to prevent white bleeding through transparent elements | |||
| 10 | + | ||||
| 7 | ## [0.9.0] - 2025-09-22 | 11 | ## [0.9.0] - 2025-09-22 | ||
| 8 | 12 | ||||
| 9 | ### Added | 13 | ### Added | ||
M internal/app/browser/workspace_manager.go +31 -3
| @@ -485,27 +485,55 @@ func (wm *WorkspaceManager) generateActivePaneCSS() string { | |||
| 485 | 485 | cfg := config.Get() | |
| 486 | 486 | styling := cfg.Workspace.Styling | |
| 487 | 487 | ||
| 488 | - | return fmt.Sprintf(`.workspace-pane { | |
| 489 | - | border: %dpx solid transparent; | |
| 488 | + | // Get appropriate border colors based on GTK theme preference | |
| 489 | + | var inactiveBorderColor, windowBackgroundColor string | |
| 490 | + | isDark := webkit.PrefersDarkTheme() | |
| 491 | + | if isDark { | |
| 492 | + | inactiveBorderColor = "#333333" // Dark border for dark theme | |
| 493 | + | windowBackgroundColor = "#2b2b2b" // Dark window background | |
| 494 | + | } else { | |
| 495 | + | inactiveBorderColor = "#dddddd" // Light border for light theme | |
| 496 | + | windowBackgroundColor = "#ffffff" // Light window background | |
| 497 | + | } | |
| 498 | + | ||
| 499 | + | // Log the border color values for debugging | |
| 500 | + | log.Printf("[workspace] GTK prefers dark: %v, inactive border color: %s", isDark, inactiveBorderColor) | |
| 501 | + | ||
| 502 | + | css := fmt.Sprintf(`window { | |
| 503 | + | background-color: %s; | |
| 504 | + | } | |
| 505 | + | ||
| 506 | + | .workspace-pane { | |
| 507 | + | background-color: %s; | |
| 508 | + | border: %dpx solid %s; | |
| 490 | 509 | transition: border-color %dms ease-in-out; | |
| 491 | 510 | border-radius: %dpx; | |
| 492 | 511 | } | |
| 493 | 512 | ||
| 494 | 513 | .workspace-pane.workspace-multi-pane { | |
| 495 | - | border: %dpx solid transparent; | |
| 514 | + | border: %dpx solid %s; | |
| 496 | 515 | border-radius: %dpx; | |
| 497 | 516 | } | |
| 498 | 517 | ||
| 499 | 518 | .workspace-pane.workspace-multi-pane.workspace-pane-active { | |
| 500 | 519 | border-color: %s; | |
| 501 | 520 | }`, | |
| 521 | + | windowBackgroundColor, | |
| 522 | + | windowBackgroundColor, | |
| 502 | 523 | styling.BorderWidth, | |
| 524 | + | inactiveBorderColor, | |
| 503 | 525 | styling.TransitionDuration, | |
| 504 | 526 | styling.BorderRadius, | |
| 505 | 527 | styling.BorderWidth, | |
| 528 | + | inactiveBorderColor, | |
| 506 | 529 | styling.BorderRadius, | |
| 507 | 530 | styling.BorderColor, | |
| 508 | 531 | ) | |
| 532 | + | ||
| 533 | + | // Log the actual CSS being generated | |
| 534 | + | log.Printf("[workspace] Generated CSS: %s", css) | |
| 535 | + | ||
| 536 | + | return css | |
| 509 | 537 | } | |
| 510 | 538 | ||
| 511 | 539 | func (wm *WorkspaceManager) ensureStyles() { | |
| @@ -485,27 +485,55 @@ func (wm *WorkspaceManager) generateActivePaneCSS() string { | |||||
| 485 | cfg := config.Get() | 485 | cfg := config.Get() | ||
| 486 | styling := cfg.Workspace.Styling | 486 | styling := cfg.Workspace.Styling | ||
| 487 | 487 | ||||
| 488 | - | return fmt.Sprintf(`.workspace-pane { | 488 | + | // Get appropriate border colors based on GTK theme preference |
| 489 | - | border: %dpx solid transparent; | 489 | + | var inactiveBorderColor, windowBackgroundColor string |
| 490 | + | isDark := webkit.PrefersDarkTheme() | |||
| 491 | + | if isDark { | |||
| 492 | + | inactiveBorderColor = "#333333" // Dark border for dark theme | |||
| 493 | + | windowBackgroundColor = "#2b2b2b" // Dark window background | |||
| 494 | + | } else { | |||
| 495 | + | inactiveBorderColor = "#dddddd" // Light border for light theme | |||
| 496 | + | windowBackgroundColor = "#ffffff" // Light window background | |||
| 497 | + | } | |||
| 498 | + | ||||
| 499 | + | // Log the border color values for debugging | |||
| 500 | + | log.Printf("[workspace] GTK prefers dark: %v, inactive border color: %s", isDark, inactiveBorderColor) | |||
| 501 | + | ||||
| 502 | + | css := fmt.Sprintf(`window { | |||
| 503 | + | background-color: %s; | |||
| 504 | + | } | |||
| 505 | + | ||||
| 506 | + | .workspace-pane { | |||
| 507 | + | background-color: %s; | |||
| 508 | + | border: %dpx solid %s; | |||
| 490 | transition: border-color %dms ease-in-out; | 509 | transition: border-color %dms ease-in-out; | ||
| 491 | border-radius: %dpx; | 510 | border-radius: %dpx; | ||
| 492 | } | 511 | } | ||
| 493 | 512 | ||||
| 494 | .workspace-pane.workspace-multi-pane { | 513 | .workspace-pane.workspace-multi-pane { | ||
| 495 | - | border: %dpx solid transparent; | 514 | + | border: %dpx solid %s; |
| 496 | border-radius: %dpx; | 515 | border-radius: %dpx; | ||
| 497 | } | 516 | } | ||
| 498 | 517 | ||||
| 499 | .workspace-pane.workspace-multi-pane.workspace-pane-active { | 518 | .workspace-pane.workspace-multi-pane.workspace-pane-active { | ||
| 500 | border-color: %s; | 519 | border-color: %s; | ||
| 501 | }`, | 520 | }`, | ||
| 521 | + | windowBackgroundColor, | |||
| 522 | + | windowBackgroundColor, | |||
| 502 | styling.BorderWidth, | 523 | styling.BorderWidth, | ||
| 524 | + | inactiveBorderColor, | |||
| 503 | styling.TransitionDuration, | 525 | styling.TransitionDuration, | ||
| 504 | styling.BorderRadius, | 526 | styling.BorderRadius, | ||
| 505 | styling.BorderWidth, | 527 | styling.BorderWidth, | ||
| 528 | + | inactiveBorderColor, | |||
| 506 | styling.BorderRadius, | 529 | styling.BorderRadius, | ||
| 507 | styling.BorderColor, | 530 | styling.BorderColor, | ||
| 508 | ) | 531 | ) | ||
| 532 | + | ||||
| 533 | + | // Log the actual CSS being generated | |||
| 534 | + | log.Printf("[workspace] Generated CSS: %s", css) | |||
| 535 | + | ||||
| 536 | + | return css | |||
| 509 | } | 537 | } | ||
| 510 | 538 | ||||
| 511 | func (wm *WorkspaceManager) ensureStyles() { | 539 | func (wm *WorkspaceManager) ensureStyles() { | ||
M pkg/webkit/webview_cgo.go +5 -0
| @@ -2579,3 +2579,8 @@ func (w *WebView) ID() string { | |||
| 2579 | 2579 | } | |
| 2580 | 2580 | return strconv.FormatUint(uint64(w.id), 10) | |
| 2581 | 2581 | } | |
| 2582 | + | ||
| 2583 | + | // PrefersDarkTheme returns true if GTK is configured to prefer dark theme | |
| 2584 | + | func PrefersDarkTheme() bool { | |
| 2585 | + | return C.gtk_prefers_dark() != 0 | |
| 2586 | + | } | |
| @@ -2579,3 +2579,8 @@ func (w *WebView) ID() string { | |||||
| 2579 | } | 2579 | } | ||
| 2580 | return strconv.FormatUint(uint64(w.id), 10) | 2580 | return strconv.FormatUint(uint64(w.id), 10) | ||
| 2581 | } | 2581 | } | ||
| 2582 | + | ||||
| 2583 | + | // PrefersDarkTheme returns true if GTK is configured to prefer dark theme | |||
| 2584 | + | func PrefersDarkTheme() bool { | |||
| 2585 | + | return C.gtk_prefers_dark() != 0 | |||
| 2586 | + | } | |||