fix(workspace): properly remove pane mode border after splits
Refactored pane mode border implementation from CSS-based to GTK margin-based approach. The previous CSS method didn't properly remove the border after pane splits because the root container reference changed. Changes: - Use GTK widget margins instead of CSS borders for pane mode indicator - Save container reference when applying margins to ensure proper cleanup - Add configurable pane_mode_border_color (defaults to #FFA500 orange) - Window background color shows through margins to create border effect The new approach ensures the border is always removed from the correct container, even after the workspace tree structure changes.
- commit
- 1896eba40b8317aed08913f27f7797ba530774da
- author
- bamen · · 2025-10-13 17:59 UTC
- committer
- bamen · · 2025-10-13 17:50 UTC
- parent
- 5675ccb
- signature
- unsigned
5 files · +80 -33
M internal/app/browser/workspace_css.go +13 -12
| @@ -73,10 +73,10 @@ func (wm *WorkspaceManager) generateWorkspaceCSS() string { | |||
| 73 | 73 | ||
| 74 | 74 | activeBorderColor := getActivePaneBorderColor(styling, isDark) | |
| 75 | 75 | ||
| 76 | - | // Pane mode border color (brighter/more prominent than active pane border) | |
| 77 | - | paneModeColor := "#FFA500" // Orange for pane mode | |
| 78 | - | if styling.BorderColor != "" && strings.HasPrefix(styling.BorderColor, "@") { | |
| 79 | - | paneModeColor = styling.BorderColor // Use theme variable if configured | |
| 76 | + | // Pane mode border color - use configured value or fallback to orange | |
| 77 | + | paneModeColor := styling.PaneModeBorderColor | |
| 78 | + | if paneModeColor == "" { | |
| 79 | + | paneModeColor = "#FFA500" // Fallback to orange if not configured | |
| 80 | 80 | } | |
| 81 | 81 | ||
| 82 | 82 | css := fmt.Sprintf(`window { | |
| @@ -85,15 +85,15 @@ func (wm *WorkspaceManager) generateWorkspaceCSS() string { | |||
| 85 | 85 | margin: 0; | |
| 86 | 86 | } | |
| 87 | 87 | ||
| 88 | - | /* Workspace root container - normal state */ | |
| 89 | - | paned, box { | |
| 90 | - | border: 0px solid transparent; | |
| 91 | - | transition: border-width 150ms ease-in-out, border-color 150ms ease-in-out; | |
| 88 | + | /* Pane mode active - change window background to border color */ | |
| 89 | + | window.pane-mode-active { | |
| 90 | + | background-color: %s; | |
| 92 | 91 | } | |
| 93 | 92 | ||
| 94 | - | /* Pane mode active - thick orange border around workspace root */ | |
| 95 | - | .workspace-pane-mode-active { | |
| 96 | - | border: 4px solid %s !important; | |
| 93 | + | /* Workspace root container */ | |
| 94 | + | paned, box { | |
| 95 | + | background-color: %s; | |
| 96 | + | transition: margin 150ms ease-in-out; | |
| 97 | 97 | } | |
| 98 | 98 | ||
| 99 | 99 | /* Base pane styling - subtle border for inactive panes */ | |
| @@ -149,7 +149,8 @@ func (wm *WorkspaceManager) generateWorkspaceCSS() string { | |||
| 149 | 149 | /* Collapsed panes are hidden - handled in code via widget visibility */ | |
| 150 | 150 | }`, | |
| 151 | 151 | windowBackgroundColor, // window background | |
| 152 | - | paneModeColor, // workspace-pane-mode-active border color | |
| 152 | + | paneModeColor, // window.pane-mode-active background (border color) | |
| 153 | + | windowBackgroundColor, // paned, box background | |
| 153 | 154 | inactiveBorderColor, // base pane border color (inactive) | |
| 154 | 155 | styling.BorderRadius, // base pane border radius | |
| 155 | 156 | styling.TransitionDuration, // base pane border transition | |
| @@ -73,10 +73,10 @@ func (wm *WorkspaceManager) generateWorkspaceCSS() string { | |||||
| 73 | 73 | ||||
| 74 | activeBorderColor := getActivePaneBorderColor(styling, isDark) | 74 | activeBorderColor := getActivePaneBorderColor(styling, isDark) | ||
| 75 | 75 | ||||
| 76 | - | // Pane mode border color (brighter/more prominent than active pane border) | 76 | + | // Pane mode border color - use configured value or fallback to orange |
| 77 | - | paneModeColor := "#FFA500" // Orange for pane mode | 77 | + | paneModeColor := styling.PaneModeBorderColor |
| 78 | - | if styling.BorderColor != "" && strings.HasPrefix(styling.BorderColor, "@") { | 78 | + | if paneModeColor == "" { |
| 79 | - | paneModeColor = styling.BorderColor // Use theme variable if configured | 79 | + | paneModeColor = "#FFA500" // Fallback to orange if not configured |
| 80 | } | 80 | } | ||
| 81 | 81 | ||||
| 82 | css := fmt.Sprintf(`window { | 82 | css := fmt.Sprintf(`window { | ||
| @@ -85,15 +85,15 @@ func (wm *WorkspaceManager) generateWorkspaceCSS() string { | |||||
| 85 | margin: 0; | 85 | margin: 0; | ||
| 86 | } | 86 | } | ||
| 87 | 87 | ||||
| 88 | - | /* Workspace root container - normal state */ | 88 | + | /* Pane mode active - change window background to border color */ |
| 89 | - | paned, box { | 89 | + | window.pane-mode-active { |
| 90 | - | border: 0px solid transparent; | 90 | + | background-color: %s; |
| 91 | - | transition: border-width 150ms ease-in-out, border-color 150ms ease-in-out; | |||
| 92 | } | 91 | } | ||
| 93 | 92 | ||||
| 94 | - | /* Pane mode active - thick orange border around workspace root */ | 93 | + | /* Workspace root container */ |
| 95 | - | .workspace-pane-mode-active { | 94 | + | paned, box { |
| 96 | - | border: 4px solid %s !important; | 95 | + | background-color: %s; |
| 96 | + | transition: margin 150ms ease-in-out; | |||
| 97 | } | 97 | } | ||
| 98 | 98 | ||||
| 99 | /* Base pane styling - subtle border for inactive panes */ | 99 | /* Base pane styling - subtle border for inactive panes */ | ||
| @@ -149,7 +149,8 @@ func (wm *WorkspaceManager) generateWorkspaceCSS() string { | |||||
| 149 | /* Collapsed panes are hidden - handled in code via widget visibility */ | 149 | /* Collapsed panes are hidden - handled in code via widget visibility */ | ||
| 150 | }`, | 150 | }`, | ||
| 151 | windowBackgroundColor, // window background | 151 | windowBackgroundColor, // window background | ||
| 152 | - | paneModeColor, // workspace-pane-mode-active border color | 152 | + | paneModeColor, // window.pane-mode-active background (border color) |
| 153 | + | windowBackgroundColor, // paned, box background | |||
| 153 | inactiveBorderColor, // base pane border color (inactive) | 154 | inactiveBorderColor, // base pane border color (inactive) | ||
| 154 | styling.BorderRadius, // base pane border radius | 155 | styling.BorderRadius, // base pane border radius | ||
| 155 | styling.TransitionDuration, // base pane border transition | 156 | styling.TransitionDuration, // base pane border transition | ||
M internal/app/browser/workspace_manager.go +2 -0
| @@ -13,6 +13,7 @@ import ( | |||
| 13 | 13 | "github.com/bnema/dumber/internal/app/messaging" | |
| 14 | 14 | "github.com/bnema/dumber/pkg/webkit" | |
| 15 | 15 | "github.com/diamondburned/gotk4/pkg/glib/v2" | |
| 16 | + | "github.com/diamondburned/gotk4/pkg/gtk/v4" | |
| 16 | 17 | ) | |
| 17 | 18 | ||
| 18 | 19 | // WorkspaceManager coordinates Zellij-style pane operations. | |
| @@ -33,6 +34,7 @@ type WorkspaceManager struct { | |||
| 33 | 34 | // Coordination fields for preventing duplicate events | |
| 34 | 35 | paneModeSource *webkit.WebView // Which webview initiated pane mode | |
| 35 | 36 | paneModeActivePane *paneNode // Which pane node has pane mode active | |
| 37 | + | paneModeContainer gtk.Widgetter // The container widget that has margin applied | |
| 36 | 38 | paneMutex sync.Mutex // Protects pane mode state | |
| 37 | 39 | ||
| 38 | 40 | // Focus throttling fields to prevent infinite loops | |
| @@ -13,6 +13,7 @@ import ( | |||||
| 13 | "github.com/bnema/dumber/internal/app/messaging" | 13 | "github.com/bnema/dumber/internal/app/messaging" | ||
| 14 | "github.com/bnema/dumber/pkg/webkit" | 14 | "github.com/bnema/dumber/pkg/webkit" | ||
| 15 | "github.com/diamondburned/gotk4/pkg/glib/v2" | 15 | "github.com/diamondburned/gotk4/pkg/glib/v2" | ||
| 16 | + | "github.com/diamondburned/gotk4/pkg/gtk/v4" | |||
| 16 | ) | 17 | ) | ||
| 17 | 18 | ||||
| 18 | // WorkspaceManager coordinates Zellij-style pane operations. | 19 | // WorkspaceManager coordinates Zellij-style pane operations. | ||
| @@ -33,6 +34,7 @@ type WorkspaceManager struct { | |||||
| 33 | // Coordination fields for preventing duplicate events | 34 | // Coordination fields for preventing duplicate events | ||
| 34 | paneModeSource *webkit.WebView // Which webview initiated pane mode | 35 | paneModeSource *webkit.WebView // Which webview initiated pane mode | ||
| 35 | paneModeActivePane *paneNode // Which pane node has pane mode active | 36 | paneModeActivePane *paneNode // Which pane node has pane mode active | ||
| 37 | + | paneModeContainer gtk.Widgetter // The container widget that has margin applied | |||
| 36 | paneMutex sync.Mutex // Protects pane mode state | 38 | paneMutex sync.Mutex // Protects pane mode state | ||
| 37 | 39 | ||||
| 38 | // Focus throttling fields to prevent infinite loops | 40 | // Focus throttling fields to prevent infinite loops | ||
M internal/app/browser/workspace_pane_mode.go +51 -13
| @@ -173,28 +173,66 @@ func (wm *WorkspaceManager) dispatchPaneModeEvent(event string, detail string) { | |||
| 173 | 173 | } | |
| 174 | 174 | } | |
| 175 | 175 | ||
| 176 | - | // applyPaneModeBorder adds the pane mode CSS class to the workspace root container | |
| 176 | + | // applyPaneModeBorder applies pane mode visual indicator using GTK margins | |
| 177 | 177 | func (wm *WorkspaceManager) applyPaneModeBorder() { | |
| 178 | - | if wm.root == nil || wm.root.container == nil { | |
| 178 | + | if wm.root == nil || wm.root.container == nil || wm.window == nil { | |
| 179 | 179 | return | |
| 180 | 180 | } | |
| 181 | 181 | ||
| 182 | - | // Add CSS class to root container for Zellij-style border | |
| 183 | - | if !webkit.WidgetHasCSSClass(wm.root.container, "workspace-pane-mode-active") { | |
| 184 | - | webkit.WidgetAddCSSClass(wm.root.container, "workspace-pane-mode-active") | |
| 185 | - | log.Printf("[pane-mode] Applied border to workspace root") | |
| 186 | - | } | |
| 182 | + | // Save the container reference so we can remove margins from it later | |
| 183 | + | // (even if wm.root.container changes due to splits) | |
| 184 | + | wm.paneModeContainer = wm.root.container | |
| 185 | + | ||
| 186 | + | // Apply 4px margins to root container to create space for the border | |
| 187 | + | webkit.WidgetSetMargin(wm.root.container, 4) | |
| 188 | + | ||
| 189 | + | // Add CSS class to window for background color (the "border" color shows in the margin space) | |
| 190 | + | webkit.WidgetAddCSSClass(wm.window.AsWindow(), "pane-mode-active") | |
| 191 | + | ||
| 192 | + | // Force resize/allocation to apply margin changes immediately | |
| 193 | + | webkit.WidgetQueueResize(wm.root.container) | |
| 194 | + | webkit.WidgetQueueAllocate(wm.root.container) | |
| 195 | + | ||
| 196 | + | // Queue redraw to show changes | |
| 197 | + | webkit.WidgetQueueDraw(wm.window.AsWindow()) | |
| 198 | + | webkit.WidgetQueueDraw(wm.root.container) | |
| 199 | + | ||
| 200 | + | log.Printf("[pane-mode] Applied border to workspace root using margins (container=%p)", wm.root.container) | |
| 187 | 201 | } | |
| 188 | 202 | ||
| 189 | - | // removePaneModeBorder removes the pane mode CSS class from the workspace root container | |
| 203 | + | // removePaneModeBorder removes the pane mode visual indicator | |
| 190 | 204 | func (wm *WorkspaceManager) removePaneModeBorder() { | |
| 191 | - | if wm.root == nil || wm.root.container == nil { | |
| 205 | + | if wm.window == nil { | |
| 192 | 206 | return | |
| 193 | 207 | } | |
| 194 | 208 | ||
| 195 | - | // Remove CSS class from root container | |
| 196 | - | if webkit.WidgetHasCSSClass(wm.root.container, "workspace-pane-mode-active") { | |
| 197 | - | webkit.WidgetRemoveCSSClass(wm.root.container, "workspace-pane-mode-active") | |
| 198 | - | log.Printf("[pane-mode] Removed border from workspace root") | |
| 209 | + | // Use the saved container reference (the one that had margins applied) | |
| 210 | + | // This is important because wm.root.container may have changed due to splits | |
| 211 | + | container := wm.paneModeContainer | |
| 212 | + | if container == nil { | |
| 213 | + | log.Printf("[pane-mode] Warning: no saved container, trying current root") | |
| 214 | + | if wm.root == nil || wm.root.container == nil { | |
| 215 | + | return | |
| 216 | + | } | |
| 217 | + | container = wm.root.container | |
| 199 | 218 | } | |
| 219 | + | ||
| 220 | + | // Remove margins from the container that had them applied | |
| 221 | + | webkit.WidgetSetMargin(container, 0) | |
| 222 | + | ||
| 223 | + | // Remove CSS class from window | |
| 224 | + | webkit.WidgetRemoveCSSClass(wm.window.AsWindow(), "pane-mode-active") | |
| 225 | + | ||
| 226 | + | // Force resize/allocation to apply margin changes immediately | |
| 227 | + | webkit.WidgetQueueResize(container) | |
| 228 | + | webkit.WidgetQueueAllocate(container) | |
| 229 | + | ||
| 230 | + | // Queue redraw to show changes | |
| 231 | + | webkit.WidgetQueueDraw(wm.window.AsWindow()) | |
| 232 | + | webkit.WidgetQueueDraw(container) | |
| 233 | + | ||
| 234 | + | // Clear the saved container reference | |
| 235 | + | wm.paneModeContainer = nil | |
| 236 | + | ||
| 237 | + | log.Printf("[pane-mode] Removed border from workspace root (container=%p)", container) | |
| 200 | 238 | } | |
| @@ -173,28 +173,66 @@ func (wm *WorkspaceManager) dispatchPaneModeEvent(event string, detail string) { | |||||
| 173 | } | 173 | } | ||
| 174 | } | 174 | } | ||
| 175 | 175 | ||||
| 176 | - | // applyPaneModeBorder adds the pane mode CSS class to the workspace root container | 176 | + | // applyPaneModeBorder applies pane mode visual indicator using GTK margins |
| 177 | func (wm *WorkspaceManager) applyPaneModeBorder() { | 177 | func (wm *WorkspaceManager) applyPaneModeBorder() { | ||
| 178 | - | if wm.root == nil || wm.root.container == nil { | 178 | + | if wm.root == nil || wm.root.container == nil || wm.window == nil { |
| 179 | return | 179 | return | ||
| 180 | } | 180 | } | ||
| 181 | 181 | ||||
| 182 | - | // Add CSS class to root container for Zellij-style border | 182 | + | // Save the container reference so we can remove margins from it later |
| 183 | - | if !webkit.WidgetHasCSSClass(wm.root.container, "workspace-pane-mode-active") { | 183 | + | // (even if wm.root.container changes due to splits) |
| 184 | - | webkit.WidgetAddCSSClass(wm.root.container, "workspace-pane-mode-active") | 184 | + | wm.paneModeContainer = wm.root.container |
| 185 | - | log.Printf("[pane-mode] Applied border to workspace root") | 185 | + | |
| 186 | - | } | 186 | + | // Apply 4px margins to root container to create space for the border |
| 187 | + | webkit.WidgetSetMargin(wm.root.container, 4) | |||
| 188 | + | ||||
| 189 | + | // Add CSS class to window for background color (the "border" color shows in the margin space) | |||
| 190 | + | webkit.WidgetAddCSSClass(wm.window.AsWindow(), "pane-mode-active") | |||
| 191 | + | ||||
| 192 | + | // Force resize/allocation to apply margin changes immediately | |||
| 193 | + | webkit.WidgetQueueResize(wm.root.container) | |||
| 194 | + | webkit.WidgetQueueAllocate(wm.root.container) | |||
| 195 | + | ||||
| 196 | + | // Queue redraw to show changes | |||
| 197 | + | webkit.WidgetQueueDraw(wm.window.AsWindow()) | |||
| 198 | + | webkit.WidgetQueueDraw(wm.root.container) | |||
| 199 | + | ||||
| 200 | + | log.Printf("[pane-mode] Applied border to workspace root using margins (container=%p)", wm.root.container) | |||
| 187 | } | 201 | } | ||
| 188 | 202 | ||||
| 189 | - | // removePaneModeBorder removes the pane mode CSS class from the workspace root container | 203 | + | // removePaneModeBorder removes the pane mode visual indicator |
| 190 | func (wm *WorkspaceManager) removePaneModeBorder() { | 204 | func (wm *WorkspaceManager) removePaneModeBorder() { | ||
| 191 | - | if wm.root == nil || wm.root.container == nil { | 205 | + | if wm.window == nil { |
| 192 | return | 206 | return | ||
| 193 | } | 207 | } | ||
| 194 | 208 | ||||
| 195 | - | // Remove CSS class from root container | 209 | + | // Use the saved container reference (the one that had margins applied) |
| 196 | - | if webkit.WidgetHasCSSClass(wm.root.container, "workspace-pane-mode-active") { | 210 | + | // This is important because wm.root.container may have changed due to splits |
| 197 | - | webkit.WidgetRemoveCSSClass(wm.root.container, "workspace-pane-mode-active") | 211 | + | container := wm.paneModeContainer |
| 198 | - | log.Printf("[pane-mode] Removed border from workspace root") | 212 | + | if container == nil { |
| 213 | + | log.Printf("[pane-mode] Warning: no saved container, trying current root") | |||
| 214 | + | if wm.root == nil || wm.root.container == nil { | |||
| 215 | + | return | |||
| 216 | + | } | |||
| 217 | + | container = wm.root.container | |||
| 199 | } | 218 | } | ||
| 219 | + | ||||
| 220 | + | // Remove margins from the container that had them applied | |||
| 221 | + | webkit.WidgetSetMargin(container, 0) | |||
| 222 | + | ||||
| 223 | + | // Remove CSS class from window | |||
| 224 | + | webkit.WidgetRemoveCSSClass(wm.window.AsWindow(), "pane-mode-active") | |||
| 225 | + | ||||
| 226 | + | // Force resize/allocation to apply margin changes immediately | |||
| 227 | + | webkit.WidgetQueueResize(container) | |||
| 228 | + | webkit.WidgetQueueAllocate(container) | |||
| 229 | + | ||||
| 230 | + | // Queue redraw to show changes | |||
| 231 | + | webkit.WidgetQueueDraw(wm.window.AsWindow()) | |||
| 232 | + | webkit.WidgetQueueDraw(container) | |||
| 233 | + | ||||
| 234 | + | // Clear the saved container reference | |||
| 235 | + | wm.paneModeContainer = nil | |||
| 236 | + | ||||
| 237 | + | log.Printf("[pane-mode] Removed border from workspace root (container=%p)", container) | |||
| 200 | } | 238 | } | ||
M internal/config/config.go +4 -0
| @@ -328,6 +328,9 @@ type WorkspaceStylingConfig struct { | |||
| 328 | 328 | BorderWidth int `mapstructure:"border_width" yaml:"border_width" json:"border_width"` | |
| 329 | 329 | // BorderColor for focused panes (CSS color value or theme variable) | |
| 330 | 330 | BorderColor string `mapstructure:"border_color" yaml:"border_color" json:"border_color"` | |
| 331 | + | // PaneModeBorderColor for the pane mode indicator border (CSS color value or theme variable) | |
| 332 | + | // Defaults to "#FFA500" (orange) if not set | |
| 333 | + | PaneModeBorderColor string `mapstructure:"pane_mode_border_color" yaml:"pane_mode_border_color" json:"pane_mode_border_color"` | |
| 331 | 334 | // TransitionDuration in milliseconds for border animations | |
| 332 | 335 | TransitionDuration int `mapstructure:"transition_duration" yaml:"transition_duration" json:"transition_duration"` | |
| 333 | 336 | // BorderRadius in pixels for pane border corners | |
| @@ -767,6 +770,7 @@ func (m *Manager) setDefaults() { | |||
| 767 | 770 | m.viper.SetDefault("workspace.popups.oauth_auto_close", defaults.Workspace.Popups.OAuthAutoClose) | |
| 768 | 771 | m.viper.SetDefault("workspace.styling.border_width", defaults.Workspace.Styling.BorderWidth) | |
| 769 | 772 | m.viper.SetDefault("workspace.styling.border_color", defaults.Workspace.Styling.BorderColor) | |
| 773 | + | m.viper.SetDefault("workspace.styling.pane_mode_border_color", defaults.Workspace.Styling.PaneModeBorderColor) | |
| 770 | 774 | m.viper.SetDefault("workspace.styling.transition_duration", defaults.Workspace.Styling.TransitionDuration) | |
| 771 | 775 | m.viper.SetDefault("workspace.styling.border_radius", defaults.Workspace.Styling.BorderRadius) | |
| 772 | 776 | } | |
| @@ -328,6 +328,9 @@ type WorkspaceStylingConfig struct { | |||||
| 328 | BorderWidth int `mapstructure:"border_width" yaml:"border_width" json:"border_width"` | 328 | BorderWidth int `mapstructure:"border_width" yaml:"border_width" json:"border_width"` | ||
| 329 | // BorderColor for focused panes (CSS color value or theme variable) | 329 | // BorderColor for focused panes (CSS color value or theme variable) | ||
| 330 | BorderColor string `mapstructure:"border_color" yaml:"border_color" json:"border_color"` | 330 | BorderColor string `mapstructure:"border_color" yaml:"border_color" json:"border_color"` | ||
| 331 | + | // PaneModeBorderColor for the pane mode indicator border (CSS color value or theme variable) | |||
| 332 | + | // Defaults to "#FFA500" (orange) if not set | |||
| 333 | + | PaneModeBorderColor string `mapstructure:"pane_mode_border_color" yaml:"pane_mode_border_color" json:"pane_mode_border_color"` | |||
| 331 | // TransitionDuration in milliseconds for border animations | 334 | // TransitionDuration in milliseconds for border animations | ||
| 332 | TransitionDuration int `mapstructure:"transition_duration" yaml:"transition_duration" json:"transition_duration"` | 335 | TransitionDuration int `mapstructure:"transition_duration" yaml:"transition_duration" json:"transition_duration"` | ||
| 333 | // BorderRadius in pixels for pane border corners | 336 | // BorderRadius in pixels for pane border corners | ||
| @@ -767,6 +770,7 @@ func (m *Manager) setDefaults() { | |||||
| 767 | m.viper.SetDefault("workspace.popups.oauth_auto_close", defaults.Workspace.Popups.OAuthAutoClose) | 770 | m.viper.SetDefault("workspace.popups.oauth_auto_close", defaults.Workspace.Popups.OAuthAutoClose) | ||
| 768 | m.viper.SetDefault("workspace.styling.border_width", defaults.Workspace.Styling.BorderWidth) | 771 | m.viper.SetDefault("workspace.styling.border_width", defaults.Workspace.Styling.BorderWidth) | ||
| 769 | m.viper.SetDefault("workspace.styling.border_color", defaults.Workspace.Styling.BorderColor) | 772 | m.viper.SetDefault("workspace.styling.border_color", defaults.Workspace.Styling.BorderColor) | ||
| 773 | + | m.viper.SetDefault("workspace.styling.pane_mode_border_color", defaults.Workspace.Styling.PaneModeBorderColor) | |||
| 770 | m.viper.SetDefault("workspace.styling.transition_duration", defaults.Workspace.Styling.TransitionDuration) | 774 | m.viper.SetDefault("workspace.styling.transition_duration", defaults.Workspace.Styling.TransitionDuration) | ||
| 771 | m.viper.SetDefault("workspace.styling.border_radius", defaults.Workspace.Styling.BorderRadius) | 775 | m.viper.SetDefault("workspace.styling.border_radius", defaults.Workspace.Styling.BorderRadius) | ||
| 772 | } | 776 | } | ||
M internal/config/defaults.go +10 -8
| @@ -32,10 +32,11 @@ const ( | |||
| 32 | 32 | defaultPopupPlacement = "right" | |
| 33 | 33 | ||
| 34 | 34 | // Workspace styling defaults | |
| 35 | - | defaultBorderWidth = 2 | |
| 36 | - | defaultBorderColor = "@theme_selected_bg_color" | |
| 37 | - | defaultTransitionDuration = 120 | |
| 38 | - | defaultBorderRadius = 0 | |
| 35 | + | defaultBorderWidth = 2 | |
| 36 | + | defaultBorderColor = "@theme_selected_bg_color" | |
| 37 | + | defaultPaneModeBorderColor = "#FFA500" // Orange for pane mode indicator | |
| 38 | + | defaultTransitionDuration = 120 | |
| 39 | + | defaultBorderRadius = 0 | |
| 39 | 40 | ) | |
| 40 | 41 | ||
| 41 | 42 | // getDefaultLogDir returns the default log directory, falls back to empty string on error | |
| @@ -200,10 +201,11 @@ func DefaultConfig() *Config { | |||
| 200 | 201 | OAuthAutoClose: true, // Auto-close OAuth popups on success | |
| 201 | 202 | }, | |
| 202 | 203 | Styling: WorkspaceStylingConfig{ | |
| 203 | - | BorderWidth: defaultBorderWidth, | |
| 204 | - | BorderColor: defaultBorderColor, | |
| 205 | - | TransitionDuration: defaultTransitionDuration, | |
| 206 | - | BorderRadius: defaultBorderRadius, | |
| 204 | + | BorderWidth: defaultBorderWidth, | |
| 205 | + | BorderColor: defaultBorderColor, | |
| 206 | + | PaneModeBorderColor: defaultPaneModeBorderColor, | |
| 207 | + | TransitionDuration: defaultTransitionDuration, | |
| 208 | + | BorderRadius: defaultBorderRadius, | |
| 207 | 209 | }, | |
| 208 | 210 | }, | |
| 209 | 211 | ContentFilteringWhitelist: []string{ | |
| @@ -32,10 +32,11 @@ const ( | |||||
| 32 | defaultPopupPlacement = "right" | 32 | defaultPopupPlacement = "right" | ||
| 33 | 33 | ||||
| 34 | // Workspace styling defaults | 34 | // Workspace styling defaults | ||
| 35 | - | defaultBorderWidth = 2 | 35 | + | defaultBorderWidth = 2 |
| 36 | - | defaultBorderColor = "@theme_selected_bg_color" | 36 | + | defaultBorderColor = "@theme_selected_bg_color" |
| 37 | - | defaultTransitionDuration = 120 | 37 | + | defaultPaneModeBorderColor = "#FFA500" // Orange for pane mode indicator |
| 38 | - | defaultBorderRadius = 0 | 38 | + | defaultTransitionDuration = 120 |
| 39 | + | defaultBorderRadius = 0 | |||
| 39 | ) | 40 | ) | ||
| 40 | 41 | ||||
| 41 | // getDefaultLogDir returns the default log directory, falls back to empty string on error | 42 | // getDefaultLogDir returns the default log directory, falls back to empty string on error | ||
| @@ -200,10 +201,11 @@ func DefaultConfig() *Config { | |||||
| 200 | OAuthAutoClose: true, // Auto-close OAuth popups on success | 201 | OAuthAutoClose: true, // Auto-close OAuth popups on success | ||
| 201 | }, | 202 | }, | ||
| 202 | Styling: WorkspaceStylingConfig{ | 203 | Styling: WorkspaceStylingConfig{ | ||
| 203 | - | BorderWidth: defaultBorderWidth, | 204 | + | BorderWidth: defaultBorderWidth, |
| 204 | - | BorderColor: defaultBorderColor, | 205 | + | BorderColor: defaultBorderColor, |
| 205 | - | TransitionDuration: defaultTransitionDuration, | 206 | + | PaneModeBorderColor: defaultPaneModeBorderColor, |
| 206 | - | BorderRadius: defaultBorderRadius, | 207 | + | TransitionDuration: defaultTransitionDuration, |
| 208 | + | BorderRadius: defaultBorderRadius, | |||
| 207 | }, | 209 | }, | ||
| 208 | }, | 210 | }, | ||
| 209 | ContentFilteringWhitelist: []string{ | 211 | ContentFilteringWhitelist: []string{ | ||