feat(config): add ui_scale setting for workspace styling
- Add UIScale field to WorkspaceStylingConfig (default: 1.0) - Add validation: must be between 0.5 and 3.0 - Wire up to Viper config system for TOML/JSON/YAML support - Allows users to scale UI elements like title bars (1.2 = 120% size)
- commit
- cbb091413a0713f3b4849b9e164ee06ce6c960c4
- author
- bnema · · 2025-11-16 18:36 UTC
- committer
- bnema · · 2025-11-16 17:59 UTC
- parent
- 92941be
- signature
- unsigned
3 files · +8 -0
M internal/config/config.go +3 -0
| @@ -313,6 +313,8 @@ type WorkspaceStylingConfig struct { | |||
| 313 | 313 | TransitionDuration int `mapstructure:"transition_duration" yaml:"transition_duration" json:"transition_duration"` | |
| 314 | 314 | // BorderRadius in pixels for pane border corners | |
| 315 | 315 | BorderRadius int `mapstructure:"border_radius" yaml:"border_radius" json:"border_radius"` | |
| 316 | + | // UIScale is a multiplier for UI elements like title bars (1.0 = 100%, 1.2 = 120%) | |
| 317 | + | UIScale float64 `mapstructure:"ui_scale" yaml:"ui_scale" json:"ui_scale"` | |
| 316 | 318 | } | |
| 317 | 319 | ||
| 318 | 320 | // Manager handles configuration loading, watching, and reloading. | |
| @@ -711,6 +713,7 @@ func (m *Manager) setDefaults() { | |||
| 711 | 713 | m.viper.SetDefault("workspace.styling.pane_mode_border_color", defaults.Workspace.Styling.PaneModeBorderColor) | |
| 712 | 714 | m.viper.SetDefault("workspace.styling.transition_duration", defaults.Workspace.Styling.TransitionDuration) | |
| 713 | 715 | m.viper.SetDefault("workspace.styling.border_radius", defaults.Workspace.Styling.BorderRadius) | |
| 716 | + | m.viper.SetDefault("workspace.styling.ui_scale", defaults.Workspace.Styling.UIScale) | |
| 714 | 717 | } | |
| 715 | 718 | ||
| 716 | 719 | // createDefaultConfig creates a default configuration file. | |
| @@ -313,6 +313,8 @@ type WorkspaceStylingConfig struct { | |||||
| 313 | TransitionDuration int `mapstructure:"transition_duration" yaml:"transition_duration" json:"transition_duration"` | 313 | TransitionDuration int `mapstructure:"transition_duration" yaml:"transition_duration" json:"transition_duration"` | ||
| 314 | // BorderRadius in pixels for pane border corners | 314 | // BorderRadius in pixels for pane border corners | ||
| 315 | BorderRadius int `mapstructure:"border_radius" yaml:"border_radius" json:"border_radius"` | 315 | BorderRadius int `mapstructure:"border_radius" yaml:"border_radius" json:"border_radius"` | ||
| 316 | + | // UIScale is a multiplier for UI elements like title bars (1.0 = 100%, 1.2 = 120%) | |||
| 317 | + | UIScale float64 `mapstructure:"ui_scale" yaml:"ui_scale" json:"ui_scale"` | |||
| 316 | } | 318 | } | ||
| 317 | 319 | ||||
| 318 | // Manager handles configuration loading, watching, and reloading. | 320 | // Manager handles configuration loading, watching, and reloading. | ||
| @@ -711,6 +713,7 @@ func (m *Manager) setDefaults() { | |||||
| 711 | m.viper.SetDefault("workspace.styling.pane_mode_border_color", defaults.Workspace.Styling.PaneModeBorderColor) | 713 | m.viper.SetDefault("workspace.styling.pane_mode_border_color", defaults.Workspace.Styling.PaneModeBorderColor) | ||
| 712 | m.viper.SetDefault("workspace.styling.transition_duration", defaults.Workspace.Styling.TransitionDuration) | 714 | m.viper.SetDefault("workspace.styling.transition_duration", defaults.Workspace.Styling.TransitionDuration) | ||
| 713 | m.viper.SetDefault("workspace.styling.border_radius", defaults.Workspace.Styling.BorderRadius) | 715 | m.viper.SetDefault("workspace.styling.border_radius", defaults.Workspace.Styling.BorderRadius) | ||
| 716 | + | m.viper.SetDefault("workspace.styling.ui_scale", defaults.Workspace.Styling.UIScale) | |||
| 714 | } | 717 | } | ||
| 715 | 718 | ||||
| 716 | // createDefaultConfig creates a default configuration file. | 719 | // createDefaultConfig creates a default configuration file. | ||
M internal/config/defaults.go +2 -0
| @@ -32,6 +32,7 @@ const ( | |||
| 32 | 32 | defaultPaneModeBorderColor = "#FFA500" // Orange for pane mode indicator | |
| 33 | 33 | defaultTransitionDuration = 120 | |
| 34 | 34 | defaultBorderRadius = 0 | |
| 35 | + | defaultUIScale = 1.0 // UI scale multiplier (1.0 = 100%, 1.2 = 120%) | |
| 35 | 36 | ) | |
| 36 | 37 | ||
| 37 | 38 | // getDefaultLogDir returns the default log directory, falls back to empty string on error | |
| @@ -183,6 +184,7 @@ func DefaultConfig() *Config { | |||
| 183 | 184 | PaneModeBorderColor: defaultPaneModeBorderColor, | |
| 184 | 185 | TransitionDuration: defaultTransitionDuration, | |
| 185 | 186 | BorderRadius: defaultBorderRadius, | |
| 187 | + | UIScale: defaultUIScale, | |
| 186 | 188 | }, | |
| 187 | 189 | }, | |
| 188 | 190 | ContentFilteringWhitelist: []string{ | |
| @@ -32,6 +32,7 @@ const ( | |||||
| 32 | defaultPaneModeBorderColor = "#FFA500" // Orange for pane mode indicator | 32 | defaultPaneModeBorderColor = "#FFA500" // Orange for pane mode indicator | ||
| 33 | defaultTransitionDuration = 120 | 33 | defaultTransitionDuration = 120 | ||
| 34 | defaultBorderRadius = 0 | 34 | defaultBorderRadius = 0 | ||
| 35 | + | defaultUIScale = 1.0 // UI scale multiplier (1.0 = 100%, 1.2 = 120%) | |||
| 35 | ) | 36 | ) | ||
| 36 | 37 | ||||
| 37 | // getDefaultLogDir returns the default log directory, falls back to empty string on error | 38 | // getDefaultLogDir returns the default log directory, falls back to empty string on error | ||
| @@ -183,6 +184,7 @@ func DefaultConfig() *Config { | |||||
| 183 | PaneModeBorderColor: defaultPaneModeBorderColor, | 184 | PaneModeBorderColor: defaultPaneModeBorderColor, | ||
| 184 | TransitionDuration: defaultTransitionDuration, | 185 | TransitionDuration: defaultTransitionDuration, | ||
| 185 | BorderRadius: defaultBorderRadius, | 186 | BorderRadius: defaultBorderRadius, | ||
| 187 | + | UIScale: defaultUIScale, | |||
| 186 | }, | 188 | }, | ||
| 187 | }, | 189 | }, | ||
| 188 | ContentFilteringWhitelist: []string{ | 190 | ContentFilteringWhitelist: []string{ | ||
M internal/config/validation.go +3 -0
| @@ -79,6 +79,9 @@ func validateConfig(config *Config) error { | |||
| 79 | 79 | if config.Workspace.Styling.BorderRadius < 0 { | |
| 80 | 80 | validationErrors = append(validationErrors, "workspace.styling.border_radius must be non-negative") | |
| 81 | 81 | } | |
| 82 | + | if config.Workspace.Styling.UIScale < 0.5 || config.Workspace.Styling.UIScale > 3.0 { | |
| 83 | + | validationErrors = append(validationErrors, "workspace.styling.ui_scale must be between 0.5 and 3.0") | |
| 84 | + | } | |
| 82 | 85 | ||
| 83 | 86 | // Validate pane mode timeout | |
| 84 | 87 | if config.Workspace.PaneMode.TimeoutMilliseconds < 0 { | |
| @@ -79,6 +79,9 @@ func validateConfig(config *Config) error { | |||||
| 79 | if config.Workspace.Styling.BorderRadius < 0 { | 79 | if config.Workspace.Styling.BorderRadius < 0 { | ||
| 80 | validationErrors = append(validationErrors, "workspace.styling.border_radius must be non-negative") | 80 | validationErrors = append(validationErrors, "workspace.styling.border_radius must be non-negative") | ||
| 81 | } | 81 | } | ||
| 82 | + | if config.Workspace.Styling.UIScale < 0.5 || config.Workspace.Styling.UIScale > 3.0 { | |||
| 83 | + | validationErrors = append(validationErrors, "workspace.styling.ui_scale must be between 0.5 and 3.0") | |||
| 84 | + | } | |||
| 82 | 85 | ||||
| 83 | // Validate pane mode timeout | 86 | // Validate pane mode timeout | ||
| 84 | if config.Workspace.PaneMode.TimeoutMilliseconds < 0 { | 87 | if config.Workspace.PaneMode.TimeoutMilliseconds < 0 { | ||