v0.31.0 bf0756b

engine.go RawHistoryFolder

1package config
2
3import "os"
4
5const (
6	EngineTypeWebKit = "webkit"
7	EngineTypeCEF    = "cef"
8)
9
10// CEFRenderStack selects Dumber's CEF GPU render stack.
11type CEFRenderStack string
12
13const (
14	CEFRenderStackVulkan CEFRenderStack = "vulkan"
15	CEFRenderStackEGL    CEFRenderStack = "egl"
16)
17
18// EngineConfig holds engine selection and universal engine options.
19type EngineConfig struct {
20	Type             string             `mapstructure:"type" toml:"type" yaml:"type"`
21	PoolPrewarmCount int                `mapstructure:"pool_prewarm_count" toml:"pool_prewarm_count" yaml:"pool_prewarm_count"`
22	ZoomCacheSize    int                `mapstructure:"zoom_cache_size" toml:"zoom_cache_size" yaml:"zoom_cache_size"`
23	Profile          PerformanceProfile `mapstructure:"profile" toml:"profile" yaml:"profile"`
24	CookiePolicy     CookiePolicy       `mapstructure:"cookie_policy" toml:"cookie_policy" yaml:"cookie_policy"`
25	WebKit           WebKitEngineConfig `mapstructure:"webkit" toml:"webkit" yaml:"webkit"`
26	CEF              CEFEngineConfig    `mapstructure:"cef" toml:"cef" yaml:"cef"`
27}
28
29// ResolveEngineType returns the effective engine type from config + env override.
30// It defaults to "cef" when no type is configured, and allows DUMBER_ENGINE
31// to override the configured value for smoke testing.
32func (e *EngineConfig) ResolveEngineType() string {
33	engineType := e.Type
34	if engineType == "" {
35		engineType = EngineTypeCEF
36	}
37	if envEngine := os.Getenv("DUMBER_ENGINE"); envEngine != "" {
38		engineType = envEngine
39	}
40	return engineType
41}
42
43// WebKitEngineConfig holds WebKit-specific engine options.
44type WebKitEngineConfig struct {
45	// Skia rendering threads
46	SkiaCPUPaintingThreads int  `mapstructure:"skia_cpu_painting_threads" toml:"skia_cpu_painting_threads" yaml:"skia_cpu_painting_threads"`
47	SkiaGPUPaintingThreads int  `mapstructure:"skia_gpu_painting_threads" toml:"skia_gpu_painting_threads" yaml:"skia_gpu_painting_threads"`
48	SkiaEnableCPURendering bool `mapstructure:"skia_enable_cpu_rendering" toml:"skia_enable_cpu_rendering" yaml:"skia_enable_cpu_rendering"`
49
50	// WebKit compositor
51	DisableDMABufRenderer  bool `mapstructure:"disable_dmabuf_renderer" toml:"disable_dmabuf_renderer" yaml:"disable_dmabuf_renderer"`
52	ForceCompositingMode   bool `mapstructure:"force_compositing_mode" toml:"force_compositing_mode" yaml:"force_compositing_mode"`
53	DisableCompositingMode bool `mapstructure:"disable_compositing_mode" toml:"disable_compositing_mode" yaml:"disable_compositing_mode"`
54
55	// GTK/GSK
56	GSKRenderer    GSKRendererMode `mapstructure:"gsk_renderer" toml:"gsk_renderer" yaml:"gsk_renderer"`
57	DisableMipmaps bool            `mapstructure:"disable_mipmaps" toml:"disable_mipmaps" yaml:"disable_mipmaps"`
58	PreferGL       bool            `mapstructure:"prefer_gl" toml:"prefer_gl" yaml:"prefer_gl"`
59
60	// Debug
61	ShowFPS                   bool `mapstructure:"show_fps" toml:"show_fps" yaml:"show_fps"`
62	SampleMemory              bool `mapstructure:"sample_memory" toml:"sample_memory" yaml:"sample_memory"`
63	DebugFrames               bool `mapstructure:"debug_frames" toml:"debug_frames" yaml:"debug_frames"`
64	DrawCompositingIndicators bool `mapstructure:"draw_compositing_indicators" toml:"draw_compositing_indicators" yaml:"draw_compositing_indicators"` //nolint:lll // struct tags exceed lll limit
65
66	// Privacy (WebKit-specific)
67	ITPEnabled bool `mapstructure:"itp_enabled" toml:"itp_enabled" yaml:"itp_enabled"`
68
69	// GStreamer
70	ForceVSync          bool            `mapstructure:"force_vsync" toml:"force_vsync" yaml:"force_vsync"`
71	GLRenderingMode     GLRenderingMode `mapstructure:"gl_rendering_mode" toml:"gl_rendering_mode" yaml:"gl_rendering_mode"`
72	GStreamerDebugLevel int             `mapstructure:"gstreamer_debug_level" toml:"gstreamer_debug_level" yaml:"gstreamer_debug_level"`
73
74	// Runtime prefix for WebKitGTK libraries
75	Prefix string `mapstructure:"prefix" toml:"prefix" yaml:"prefix"`
76
77	// Web process memory pressure
78	WebProcessMemoryLimitMB               int     `mapstructure:"web_process_memory_limit_mb" toml:"web_process_memory_limit_mb" yaml:"web_process_memory_limit_mb"`                                           //nolint:lll // struct tags exceed lll limit
79	WebProcessMemoryPollIntervalSec       float64 `mapstructure:"web_process_memory_poll_interval_sec" toml:"web_process_memory_poll_interval_sec" yaml:"web_process_memory_poll_interval_sec"`                //nolint:lll // struct tags exceed lll limit
80	WebProcessMemoryConservativeThreshold float64 `mapstructure:"web_process_memory_conservative_threshold" toml:"web_process_memory_conservative_threshold" yaml:"web_process_memory_conservative_threshold"` //nolint:lll // struct tags exceed lll limit
81	WebProcessMemoryStrictThreshold       float64 `mapstructure:"web_process_memory_strict_threshold" toml:"web_process_memory_strict_threshold" yaml:"web_process_memory_strict_threshold"`                   //nolint:lll // struct tags exceed lll limit
82
83	// Network process memory pressure
84	NetworkProcessMemoryLimitMB               int     `mapstructure:"network_process_memory_limit_mb" toml:"network_process_memory_limit_mb" yaml:"network_process_memory_limit_mb"`                                           //nolint:lll // struct tags exceed lll limit
85	NetworkProcessMemoryPollIntervalSec       float64 `mapstructure:"network_process_memory_poll_interval_sec" toml:"network_process_memory_poll_interval_sec" yaml:"network_process_memory_poll_interval_sec"`                //nolint:lll // struct tags exceed lll limit
86	NetworkProcessMemoryConservativeThreshold float64 `mapstructure:"network_process_memory_conservative_threshold" toml:"network_process_memory_conservative_threshold" yaml:"network_process_memory_conservative_threshold"` //nolint:lll // struct tags exceed lll limit
87	NetworkProcessMemoryStrictThreshold       float64 `mapstructure:"network_process_memory_strict_threshold" toml:"network_process_memory_strict_threshold" yaml:"network_process_memory_strict_threshold"`                   //nolint:lll // struct tags exceed lll limit
88}
89
90// CEFEngineConfig holds CEF-specific engine options.
91type CEFEngineConfig struct {
92	// CEFDir is the path to the CEF framework directory containing
93	// libcef.so and the Resources/locales subdirectories.
94	CEFDir string `mapstructure:"cef_dir" toml:"cef_dir" yaml:"cef_dir"`
95	// LogFile overrides the CEF internal log destination. When empty,
96	// Dumber uses the resolved runtime-profile default engine log path.
97	LogFile string `mapstructure:"log_file" toml:"log_file" yaml:"log_file"`
98	// LogSeverity controls CEF's internal log verbosity.
99	// 0 = default, 1 = verbose, 2 = info, 3 = warning, 4 = error, 99 = disable.
100	LogSeverity int32 `mapstructure:"log_severity" toml:"log_severity" yaml:"log_severity"`
101	// RenderStack selects the CEF GPU render stack. Empty falls back to vulkan.
102	RenderStack CEFRenderStack `mapstructure:"render_stack" toml:"render_stack" yaml:"render_stack"`
103	// AdaptiveWindowlessFrameRate polls the active Wayland monitor refresh rate
104	// and updates CEF's OSR frame-rate while the browser moves across monitors.
105	// It is ignored when WindowlessFrameRate is explicitly set.
106	AdaptiveWindowlessFrameRate bool `mapstructure:"adaptive_windowless_frame_rate" toml:"adaptive_windowless_frame_rate" yaml:"adaptive_windowless_frame_rate"` //nolint:lll // struct tags exceed lll limit
107	// WindowlessFrameRate is the maximum frame rate for off-screen rendering.
108	// When 0 and adaptive_windowless_frame_rate is true, Dumber adapts to the
109	// active Wayland monitor refresh rate.
110	WindowlessFrameRate int32 `mapstructure:"windowless_frame_rate" toml:"windowless_frame_rate" yaml:"windowless_frame_rate"` //nolint:lll // struct tags exceed lll limit
111	// WindowlessFrameRateMax is the hard cap for adaptive monitor refresh rates.
112	WindowlessFrameRateMax int32 `mapstructure:"windowless_frame_rate_max" toml:"windowless_frame_rate_max" yaml:"windowless_frame_rate_max"` //nolint:lll // struct tags exceed lll limit
113	// Input controls GTK input translation before events are forwarded to CEF.
114	Input CEFInputConfig `mapstructure:"input" toml:"input" yaml:"input"`
115	// EnableAudioHandler opts into the experimental CEF AudioHandler bridge.
116	EnableAudioHandler bool `mapstructure:"enable_audio_handler" toml:"enable_audio_handler" yaml:"enable_audio_handler"`
117	// TraceHandlers enables purego-cef handler/refcount tracing for diagnostics.
118	TraceHandlers bool `mapstructure:"trace_handlers" toml:"trace_handlers" yaml:"trace_handlers"`
119}
120
121// CEFInputConfig holds CEF-specific input translation options.
122type CEFInputConfig struct {
123	ScrollWheelMultiplier              float64 `mapstructure:"scroll_wheel_multiplier" toml:"scroll_wheel_multiplier" yaml:"scroll_wheel_multiplier"`                                              //nolint:lll // struct tags exceed lll limit
124	ScrollPreciseMultiplier            float64 `mapstructure:"scroll_precise_multiplier" toml:"scroll_precise_multiplier" yaml:"scroll_precise_multiplier"`                                        //nolint:lll // struct tags exceed lll limit
125	ScrollHorizontalMultiplier         float64 `mapstructure:"scroll_horizontal_multiplier" toml:"scroll_horizontal_multiplier" yaml:"scroll_horizontal_multiplier"`                               //nolint:lll // struct tags exceed lll limit
126	ScrollVerticalMultiplier           float64 `mapstructure:"scroll_vertical_multiplier" toml:"scroll_vertical_multiplier" yaml:"scroll_vertical_multiplier"`                                     //nolint:lll // struct tags exceed lll limit
127	ScrollMaxDelta                     int32   `mapstructure:"scroll_max_delta" toml:"scroll_max_delta" yaml:"scroll_max_delta"`                                                                   //nolint:lll // struct tags exceed lll limit
128	TouchpadNavigationEnabled          bool    `mapstructure:"touchpad_navigation_enabled" toml:"touchpad_navigation_enabled" yaml:"touchpad_navigation_enabled"`                                  //nolint:lll // struct tags exceed lll limit
129	TouchpadNavigationMinDelta         float64 `mapstructure:"touchpad_navigation_min_delta" toml:"touchpad_navigation_min_delta" yaml:"touchpad_navigation_min_delta"`                            //nolint:lll // struct tags exceed lll limit
130	TouchpadNavigationMaxVerticalRatio float64 `mapstructure:"touchpad_navigation_max_vertical_ratio" toml:"touchpad_navigation_max_vertical_ratio" yaml:"touchpad_navigation_max_vertical_ratio"` //nolint:lll // struct tags exceed lll limit
131}
132
133// CEFRenderStack returns the effective CEF GPU render stack.
134func (c CEFEngineConfig) CEFRenderStack() CEFRenderStack {
135	if c.RenderStack != "" {
136		return c.RenderStack
137	}
138	return CEFRenderStackVulkan
139}
140
141// CEFWindowlessFrameRate returns the effective OSR frame rate.
142// A non-positive value falls back to the built-in default to avoid accidentally
143// matching high-refresh monitors and burning CPU while idling.
144func (c CEFEngineConfig) CEFWindowlessFrameRate() int32 {
145	if c.WindowlessFrameRate > 0 {
146		return c.WindowlessFrameRate
147	}
148	return defaultCEFWindowlessFrameRate
149}
150
151func (c CEFEngineConfig) CEFWindowlessFrameRateMax() int32 {
152	if c.WindowlessFrameRateMax > 0 {
153		return c.WindowlessFrameRateMax
154	}
155	return defaultCEFWindowlessFrameRateMax
156}
157
158func (c CEFEngineConfig) CEFAdaptiveWindowlessFrameRate() bool {
159	return c.AdaptiveWindowlessFrameRate && c.WindowlessFrameRate <= 0
160}
161
162// PerformanceConfigFromEngine constructs a PerformanceConfig from the
163// new [engine] config section, for use with ResolvePerformanceProfile.
164func PerformanceConfigFromEngine(e *EngineConfig) PerformanceConfig {
165	if e == nil {
166		return PerformanceConfig{}
167	}
168	return PerformanceConfig{
169		Profile:                                   e.Profile,
170		ZoomCacheSize:                             e.ZoomCacheSize,
171		WebViewPoolPrewarmCount:                   e.PoolPrewarmCount,
172		SkiaCPUPaintingThreads:                    e.WebKit.SkiaCPUPaintingThreads,
173		SkiaGPUPaintingThreads:                    e.WebKit.SkiaGPUPaintingThreads,
174		SkiaEnableCPURendering:                    e.WebKit.SkiaEnableCPURendering,
175		WebProcessMemoryLimitMB:                   e.WebKit.WebProcessMemoryLimitMB,
176		WebProcessMemoryPollIntervalSec:           e.WebKit.WebProcessMemoryPollIntervalSec,
177		WebProcessMemoryConservativeThreshold:     e.WebKit.WebProcessMemoryConservativeThreshold,
178		WebProcessMemoryStrictThreshold:           e.WebKit.WebProcessMemoryStrictThreshold,
179		NetworkProcessMemoryLimitMB:               e.WebKit.NetworkProcessMemoryLimitMB,
180		NetworkProcessMemoryPollIntervalSec:       e.WebKit.NetworkProcessMemoryPollIntervalSec,
181		NetworkProcessMemoryConservativeThreshold: e.WebKit.NetworkProcessMemoryConservativeThreshold,
182		NetworkProcessMemoryStrictThreshold:       e.WebKit.NetworkProcessMemoryStrictThreshold,
183	}
184}

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