v0.28.0 3cb3770

engine.go RawHistoryFolder

1// Package port defines application-layer interfaces for external capabilities.
2// Ports abstract infrastructure concerns, allowing the application layer to
3// remain independent of specific implementations (WebKit, GTK, etc.).
4package port
5
6import "context"
7
8// CookiePolicy controls cookie acceptance behavior for the engine's network session.
9type CookiePolicy string
10
11const (
12	// CookiePolicyAlways accepts all cookies.
13	CookiePolicyAlways CookiePolicy = "always"
14	// CookiePolicyNoThirdParty rejects third-party cookies.
15	CookiePolicyNoThirdParty CookiePolicy = "no_third_party"
16	// CookiePolicyNever rejects all cookies.
17	CookiePolicyNever CookiePolicy = "never"
18)
19
20// MemoryPressureConfig holds memory pressure settings for an engine process.
21// This is a value type (no infrastructure dependencies) co-located with the
22// interfaces that use it (MemoryPressureApplier, EngineOptions).
23// Zero values mean "use engine defaults".
24type MemoryPressureConfig struct {
25	// MemoryLimitMB sets the memory limit in megabytes.
26	// 0 means unset (uses engine default).
27	MemoryLimitMB int
28
29	// PollIntervalSec sets the interval for memory usage checks.
30	// 0 means unset (uses engine default: 30 seconds).
31	PollIntervalSec float64
32
33	// ConservativeThreshold sets threshold for conservative memory release.
34	// Must be in (0, 1). 0 means unset (uses engine default: 0.33).
35	ConservativeThreshold float64
36
37	// StrictThreshold sets threshold for strict memory release.
38	// Must be in (0, 1). 0 means unset (uses engine default: 0.5).
39	StrictThreshold float64
40}
41
42// IsConfigured returns true if any memory pressure setting is configured.
43func (c *MemoryPressureConfig) IsConfigured() bool {
44	if c == nil {
45		return false
46	}
47	return c.MemoryLimitMB > 0 ||
48		c.PollIntervalSec > 0 ||
49		c.ConservativeThreshold > 0 ||
50		c.StrictThreshold > 0
51}
52
53// MemoryPressureApplier applies memory pressure settings to engine processes.
54// This interface abstracts engine-specific memory pressure configuration
55// to allow testing without engine dependencies.
56type MemoryPressureApplier interface {
57	// ApplyNetworkProcessSettings applies memory pressure settings to the network process.
58	// Must be called BEFORE creating any NetworkSession.
59	ApplyNetworkProcessSettings(ctx context.Context, cfg *MemoryPressureConfig) error
60
61	// ApplyWebProcessSettings applies memory pressure settings to web processes.
62	// Returns an opaque settings object that should be passed to context creation.
63	// Returns nil if no settings are configured.
64	ApplyWebProcessSettings(ctx context.Context, cfg *MemoryPressureConfig) (any, error)
65}
66
67// EngineOptions configures engine initialization.
68type EngineOptions struct {
69	// DataDir is the directory for persistent data (cookies, storage, etc.).
70	DataDir string
71
72	// CacheDir is the directory for cache data.
73	CacheDir string
74
75	// CookiePolicy controls cookie acceptance behavior.
76	// Empty value means runtime defaults are used.
77	CookiePolicy CookiePolicy
78
79	// WebProcessMemory configures memory pressure for web processes.
80	// nil means use engine defaults.
81	WebProcessMemory *MemoryPressureConfig
82
83	// NetworkProcessMemory configures memory pressure for the network process.
84	// nil means use engine defaults.
85	NetworkProcessMemory *MemoryPressureConfig
86}
87
88// Engine is the top-level interface for a browser engine implementation.
89// It provides access to all engine subsystems and manages the lifecycle
90// of the underlying browser context.
91//
92// Engines are fully initialized by their constructor (e.g., webkit.NewEngine).
93// There is no separate Init step.
94type Engine interface {
95	// Factory returns the WebViewFactory for creating new WebView instances.
96	Factory() WebViewFactory
97
98	// Pool returns the WebViewPool for acquiring pre-warmed WebView instances.
99	Pool() WebViewPool
100
101	// ContentInjector returns the ContentInjector for injecting scripts and styles.
102	ContentInjector() ContentInjector
103
104	// SettingsApplier returns the SettingsApplier for applying browser settings.
105	SettingsApplier() SettingsApplier
106
107	// FilterApplier returns the FilterApplier for applying content filters.
108	// Returns nil if content filtering is not supported by this engine.
109	FilterApplier() FilterApplier
110
111	// FaviconDatabase returns the FaviconDatabase for async favicon lookups.
112	FaviconDatabase() FaviconDatabase
113
114	// InternalSchemePath returns the URI scheme used for internal app resources.
115	InternalSchemePath() string
116
117	// Close releases all resources held by the engine.
118	Close() error
119
120	// RegisterHandlers registers all WebUI message bridge handlers.
121	RegisterHandlers(ctx context.Context, deps HandlerDependencies) error
122
123	// RegisterAccentHandlers registers accent/dead-key input handlers.
124	RegisterAccentHandlers(ctx context.Context, handler AccentKeyHandler) error
125
126	// ConfigureDownloads sets up download handling for this engine.
127	ConfigureDownloads(ctx context.Context, downloadPath string, eventHandler DownloadEventHandler, preparer DownloadPreparer) error
128
129	// OnToolkitReady is called after the UI toolkit has initialized.
130	OnToolkitReady(ctx context.Context) error
131
132	// UpdateAppearance updates default background color for new WebViews.
133	UpdateAppearance(ctx context.Context, r, g, b, alpha float64) error
134
135	// UpdateSettings applies runtime config changes to engine internals.
136	UpdateSettings(ctx context.Context, update EngineSettingsUpdate) error
137
138	// SetHandlerContext sets the base context for message handler dispatch.
139	SetHandlerContext(ctx context.Context)
140}
141
142// EngineSettingsUpdate carries a runtime config change to the engine.
143//
144// The Raw field holds the implementation-specific config object; each engine
145// implementation type-asserts it to its concrete config type (e.g. the WebKit
146// engine asserts to *infrastructure/config.Config).
147//
148// This is the only intentional use of `any` in the Engine port. A fully typed
149// approach would require either moving the entire config schema into the domain
150// layer (a large refactor) or defining a SettingsProvider interface — which
151// would itself reduce to `any` because callers would embed engine-specific data
152// behind an empty interface. Until the config schema is promoted to domain,
153// the type assertion in the engine implementation is the least-invasive option.
154type EngineSettingsUpdate struct {
155	// Raw holds the implementation-specific config.
156	// WebKit engine expects *infrastructure/config.Config.
157	Raw any //nolint:iface // intentional: see type comment above
158}
159
160// HandlerDependencies holds use cases needed by WebUI message handlers.
161type HandlerDependencies struct {
162	HistoryUC         HomepageHistory
163	FavoritesUC       HomepageFavorites
164	Clipboard         Clipboard
165	AutoCopyConfig    AutoCopyConfig
166	OnClipboardCopied func(textLen int)
167}
168
169// SchemeHandler defines the port interface for registering custom URI schemes.
170// Implementations intercept navigation to registered schemes and serve content
171// from application code.
172type SchemeHandler interface {
173	// RegisterScheme registers a handler for the given URI scheme.
174	// The handler receives the full URI and returns the response body,
175	// MIME type, and any error.
176	RegisterScheme(scheme string, handler func(uri string) ([]byte, string, error))
177}
178
179// MessageRouter defines the port interface for bidirectional JS-to-Go messaging.
180// It allows JavaScript running in a WebView to invoke named Go handlers,
181// and allows Go code to post messages back to a specific WebView.
182type MessageRouter interface {
183	// RegisterHandler registers a named message handler callable from JavaScript.
184	// The handler receives a JSON-encoded message string and returns a
185	// JSON-encoded response string.
186	RegisterHandler(name string, handler func(message string) (string, error))
187
188	// PostMessage sends a message to the JavaScript context of the given WebView.
189	PostMessage(webviewID WebViewID, message string) error
190}
191
192// SettingsApplier defines the port interface for applying browser settings to WebViews.
193// Implementations apply engine-specific settings (security, features, etc.) uniformly
194// across a set of WebView instances.
195type SettingsApplier interface {
196	// ApplyToAll applies settings to all provided WebView instances.
197	ApplyToAll(ctx context.Context, webviews []WebView)
198}
199
200// FilterApplier defines the port interface for applying content filters to WebViews.
201// Implementations configure content blocking rules on a set of WebView instances.
202// This interface is optional; Engine.FilterApplier() returns nil if not supported.
203type FilterApplier interface {
204	// ApplyToAll applies content filters to all provided WebView instances.
205	ApplyToAll(ctx context.Context, webviews []WebView)
206}
207
208// FaviconDatabase defines the port interface for async favicon lookups.
209// Implementations retrieve favicons from an engine-managed database and
210// deliver them via callback on the main thread.
211type FaviconDatabase interface {
212	// GetFaviconAsync retrieves the favicon for the given page URL asynchronously.
213	// The callback is invoked with the favicon Texture when available.
214	GetFaviconAsync(pageURL string, callback func(Texture))
215}
216
217// ScriptRefresher defines the port interface for refreshing injected scripts
218// across multiple WebView instances (e.g., after a settings change).
219type ScriptRefresher interface {
220	// RefreshAll re-injects scripts into all provided WebView instances.
221	RefreshAll(ctx context.Context, webviews []WebView)
222}
223
224// FilterManagerProvider is an optional capability interface for engines that
225// support content filter management (e.g. ad blocking). Callers should type-assert
226// the Engine to FilterManagerProvider rather than a concrete engine type.
227type FilterManagerProvider interface {
228	InternalFilterManager() FilterManager
229}
230
231// NativeWidgetProvider is an optional capability for WebViews that can provide
232// a native widget pointer for embedding into the host toolkit's layout system.
233// For GTK-based engines this returns a *gtk.Widget pointer; other engines
234// provide their equivalent embedding handle.
235type NativeWidgetProvider interface {
236	NativeWidget() uintptr
237}

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