detached 94c2fc4

fix(config): add media configuration schema and hardware decoding modes

commit
94c2fc491c372039b648a2b70d4ccf5bc2c9759a
author
brice · · 2025-12-18 18:27 UTC
parent
40983c7
signature
unsigned
3 files · +47 -0
M internal/infrastructure/config/defaults.go +5 -0
@@ -186,6 +186,11 @@ func DefaultConfig() *Config {
186186 Omnibox: OmniboxConfig{
187187 InitialBehavior: defaultOmniboxInitialBehavior,
188188 },
189+ Media: MediaConfig{
190+ HardwareDecodingMode: HardwareDecodingAuto, // THE FIX: auto allows sw fallback
191+ PreferAV1: true, // AV1 is most efficient codec
192+ ShowDiagnosticsOnStartup: true, // Warn users if HW accel unavailable
193+ },
189194 }
190195 }
191196
@@ -186,6 +186,11 @@ func DefaultConfig() *Config {
186 Omnibox: OmniboxConfig{186 Omnibox: OmniboxConfig{
187 InitialBehavior: defaultOmniboxInitialBehavior,187 InitialBehavior: defaultOmniboxInitialBehavior,
188 },188 },
189+ Media: MediaConfig{
190+ HardwareDecodingMode: HardwareDecodingAuto, // THE FIX: auto allows sw fallback
191+ PreferAV1: true, // AV1 is most efficient codec
192+ ShowDiagnosticsOnStartup: true, // Warn users if HW accel unavailable
193+ },
189 }194 }
190 }195 }
191 196
M internal/infrastructure/config/loader.go +17 -0
@@ -146,6 +146,18 @@ func (m *Manager) Load() error {
146146 config.Appearance.ColorScheme = ThemeDefault
147147 }
148148
149+ // Validate Media.HardwareDecodingMode using switch statement
150+ switch strings.ToLower(string(config.Media.HardwareDecodingMode)) {
151+ case "", string(HardwareDecodingAuto):
152+ config.Media.HardwareDecodingMode = HardwareDecodingAuto
153+ case string(HardwareDecodingForce):
154+ config.Media.HardwareDecodingMode = HardwareDecodingForce
155+ case string(HardwareDecodingDisable):
156+ config.Media.HardwareDecodingMode = HardwareDecodingDisable
157+ default:
158+ config.Media.HardwareDecodingMode = HardwareDecodingAuto
159+ }
160+
149161 // Validate all config values
150162 if err := validateConfig(config); err != nil {
151163 return fmt.Errorf("configuration validation failed: %w", err)
@@ -277,6 +289,11 @@ func (m *Manager) setDefaults() {
277289
278290 // Omnibox defaults
279291 m.viper.SetDefault("omnibox.initial_behavior", defaults.Omnibox.InitialBehavior)
292+
293+ // Media defaults
294+ m.viper.SetDefault("media.hardware_decoding", string(defaults.Media.HardwareDecodingMode))
295+ m.viper.SetDefault("media.prefer_av1", defaults.Media.PreferAV1)
296+ m.viper.SetDefault("media.show_diagnostics", defaults.Media.ShowDiagnosticsOnStartup)
280297 }
281298
282299 // New returns a new default configuration instance.
@@ -146,6 +146,18 @@ func (m *Manager) Load() error {
146 config.Appearance.ColorScheme = ThemeDefault146 config.Appearance.ColorScheme = ThemeDefault
147 }147 }
148 148
149+ // Validate Media.HardwareDecodingMode using switch statement
150+ switch strings.ToLower(string(config.Media.HardwareDecodingMode)) {
151+ case "", string(HardwareDecodingAuto):
152+ config.Media.HardwareDecodingMode = HardwareDecodingAuto
153+ case string(HardwareDecodingForce):
154+ config.Media.HardwareDecodingMode = HardwareDecodingForce
155+ case string(HardwareDecodingDisable):
156+ config.Media.HardwareDecodingMode = HardwareDecodingDisable
157+ default:
158+ config.Media.HardwareDecodingMode = HardwareDecodingAuto
159+ }
160+
149 // Validate all config values161 // Validate all config values
150 if err := validateConfig(config); err != nil {162 if err := validateConfig(config); err != nil {
151 return fmt.Errorf("configuration validation failed: %w", err)163 return fmt.Errorf("configuration validation failed: %w", err)
@@ -277,6 +289,11 @@ func (m *Manager) setDefaults() {
277 289
278 // Omnibox defaults290 // Omnibox defaults
279 m.viper.SetDefault("omnibox.initial_behavior", defaults.Omnibox.InitialBehavior)291 m.viper.SetDefault("omnibox.initial_behavior", defaults.Omnibox.InitialBehavior)
292+
293+ // Media defaults
294+ m.viper.SetDefault("media.hardware_decoding", string(defaults.Media.HardwareDecodingMode))
295+ m.viper.SetDefault("media.prefer_av1", defaults.Media.PreferAV1)
296+ m.viper.SetDefault("media.show_diagnostics", defaults.Media.ShowDiagnosticsOnStartup)
280 }297 }
281 298
282 // New returns a new default configuration instance.299 // New returns a new default configuration instance.
M internal/infrastructure/config/schema.go +25 -0
@@ -23,6 +23,8 @@ type Config struct {
2323 ContentFiltering ContentFilteringConfig `mapstructure:"content_filtering" yaml:"content_filtering" toml:"content_filtering"`
2424 // Omnibox controls the omnibox behavior (initial history display)
2525 Omnibox OmniboxConfig `mapstructure:"omnibox" yaml:"omnibox" toml:"omnibox"`
26+ // Media controls video playback and hardware acceleration
27+ Media MediaConfig `mapstructure:"media" yaml:"media" toml:"media"`
2628 }
2729
2830 // RenderingMode selects GPU vs CPU rendering.
@@ -34,9 +36,32 @@ const (
3436 RenderingModeCPU RenderingMode = "cpu"
3537 )
3638
39+// HardwareDecodingMode controls video hardware acceleration.
40+type HardwareDecodingMode string
41+
42+const (
43+ // HardwareDecodingAuto lets GStreamer choose (hw preferred, sw fallback)
44+ HardwareDecodingAuto HardwareDecodingMode = "auto"
45+ // HardwareDecodingForce requires hardware decoding (fails if unavailable)
46+ HardwareDecodingForce HardwareDecodingMode = "force"
47+ // HardwareDecodingDisable uses software decoding only
48+ HardwareDecodingDisable HardwareDecodingMode = "disable"
49+)
50+
3751 // ThemeDefault is the default theme setting (follows system).
3852 const ThemeDefault = "default"
3953
54+// MediaConfig holds video playback and hardware acceleration preferences.
55+type MediaConfig struct {
56+ // HardwareDecodingMode controls hardware vs software video decoding
57+ // Values: "auto" (default), "force", "disable"
58+ HardwareDecodingMode HardwareDecodingMode `mapstructure:"hardware_decoding" yaml:"hardware_decoding" toml:"hardware_decoding"`
59+ // PreferAV1 prioritizes AV1 codec (most efficient) when available
60+ PreferAV1 bool `mapstructure:"prefer_av1" yaml:"prefer_av1" toml:"prefer_av1"`
61+ // ShowDiagnosticsOnStartup shows media capability warnings at startup
62+ ShowDiagnosticsOnStartup bool `mapstructure:"show_diagnostics" yaml:"show_diagnostics" toml:"show_diagnostics"`
63+}
64+
4065 // DatabaseConfig holds database-related configuration.
4166 type DatabaseConfig struct {
4267 Path string `mapstructure:"path" yaml:"path" toml:"path"`
@@ -23,6 +23,8 @@ type Config struct {
23 ContentFiltering ContentFilteringConfig `mapstructure:"content_filtering" yaml:"content_filtering" toml:"content_filtering"`23 ContentFiltering ContentFilteringConfig `mapstructure:"content_filtering" yaml:"content_filtering" toml:"content_filtering"`
24 // Omnibox controls the omnibox behavior (initial history display)24 // Omnibox controls the omnibox behavior (initial history display)
25 Omnibox OmniboxConfig `mapstructure:"omnibox" yaml:"omnibox" toml:"omnibox"`25 Omnibox OmniboxConfig `mapstructure:"omnibox" yaml:"omnibox" toml:"omnibox"`
26+ // Media controls video playback and hardware acceleration
27+ Media MediaConfig `mapstructure:"media" yaml:"media" toml:"media"`
26 }28 }
27 29
28 // RenderingMode selects GPU vs CPU rendering.30 // RenderingMode selects GPU vs CPU rendering.
@@ -34,9 +36,32 @@ const (
34 RenderingModeCPU RenderingMode = "cpu"36 RenderingModeCPU RenderingMode = "cpu"
35 )37 )
36 38
39+// HardwareDecodingMode controls video hardware acceleration.
40+type HardwareDecodingMode string
41+
42+const (
43+ // HardwareDecodingAuto lets GStreamer choose (hw preferred, sw fallback)
44+ HardwareDecodingAuto HardwareDecodingMode = "auto"
45+ // HardwareDecodingForce requires hardware decoding (fails if unavailable)
46+ HardwareDecodingForce HardwareDecodingMode = "force"
47+ // HardwareDecodingDisable uses software decoding only
48+ HardwareDecodingDisable HardwareDecodingMode = "disable"
49+)
50+
37 // ThemeDefault is the default theme setting (follows system).51 // ThemeDefault is the default theme setting (follows system).
38 const ThemeDefault = "default"52 const ThemeDefault = "default"
39 53
54+// MediaConfig holds video playback and hardware acceleration preferences.
55+type MediaConfig struct {
56+ // HardwareDecodingMode controls hardware vs software video decoding
57+ // Values: "auto" (default), "force", "disable"
58+ HardwareDecodingMode HardwareDecodingMode `mapstructure:"hardware_decoding" yaml:"hardware_decoding" toml:"hardware_decoding"`
59+ // PreferAV1 prioritizes AV1 codec (most efficient) when available
60+ PreferAV1 bool `mapstructure:"prefer_av1" yaml:"prefer_av1" toml:"prefer_av1"`
61+ // ShowDiagnosticsOnStartup shows media capability warnings at startup
62+ ShowDiagnosticsOnStartup bool `mapstructure:"show_diagnostics" yaml:"show_diagnostics" toml:"show_diagnostics"`
63+}
64+
40 // DatabaseConfig holds database-related configuration.65 // DatabaseConfig holds database-related configuration.
41 type DatabaseConfig struct {66 type DatabaseConfig struct {
42 Path string `mapstructure:"path" yaml:"path" toml:"path"`67 Path string `mapstructure:"path" yaml:"path" toml:"path"`

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close