detached a5f2194

fix: use purego-cef v0.7.3 sized constructors and correct sqlite driver name

CEF 145 rejects structs where Size == 0. Migrate all zero-value struct
literals to New*() constructors (NewWindowInfo, NewBrowserSettings,
NewKeyEvent, NewScreenInfo) which pre-fill Size automatically.

Also fix sqlite driver name mismatch: purego-sqlite registers as
"sqlite3", not "sqlite".
commit
a5f2194c966989f454337c6d572c40cb449dabec
author
brice · · 2026-03-28 08:56 UTC
parent
c46cae7
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
6 files · +25 -25
M internal/infrastructure/cef/factory.go +2 -2
@@ -118,12 +118,12 @@ func (f *WebViewFactory) Create(ctx context.Context) (port.WebView, error) {
118118 wv.client = client
119119
120120 // Configure WindowInfo for off-screen rendering (OSR).
121- windowInfo := purecef.WindowInfo{}
121+ windowInfo := purecef.NewWindowInfo()
122122 windowInfo.WindowlessRenderingEnabled = 1
123123 windowInfo.ExternalBeginFrameEnabled = 1
124124
125125 // Configure BrowserSettings.
126- settings := purecef.BrowserSettings{}
126+ settings := purecef.NewBrowserSettings()
127127 settings.WindowlessFrameRate = f.windowlessFrameRate
128128 settings.LocalStorage = 1 // CEF_STATE_ENABLED
129129 if bg := f.bgColor.Load(); bg != 0 {
@@ -118,12 +118,12 @@ func (f *WebViewFactory) Create(ctx context.Context) (port.WebView, error) {
118 wv.client = client118 wv.client = client
119 119
120 // Configure WindowInfo for off-screen rendering (OSR).120 // Configure WindowInfo for off-screen rendering (OSR).
121- windowInfo := purecef.WindowInfo{}121+ windowInfo := purecef.NewWindowInfo()
122 windowInfo.WindowlessRenderingEnabled = 1122 windowInfo.WindowlessRenderingEnabled = 1
123 windowInfo.ExternalBeginFrameEnabled = 1123 windowInfo.ExternalBeginFrameEnabled = 1
124 124
125 // Configure BrowserSettings.125 // Configure BrowserSettings.
126- settings := purecef.BrowserSettings{}126+ settings := purecef.NewBrowserSettings()
127 settings.WindowlessFrameRate = f.windowlessFrameRate127 settings.WindowlessFrameRate = f.windowlessFrameRate
128 settings.LocalStorage = 1 // CEF_STATE_ENABLED128 settings.LocalStorage = 1 // CEF_STATE_ENABLED
129 if bg := f.bgColor.Load(); bg != 0 {129 if bg := f.bgColor.Load(); bg != 0 {
M internal/infrastructure/cef/input_bridge.go +11 -12
@@ -385,12 +385,11 @@ func (ib *inputBridge) onIMCommit(text string) {
385385 continue
386386 }
387387 ch := uint16(r)
388- evt := purecef.KeyEvent{
389- Type: purecef.KeyEventTypeKeyeventChar,
390- WindowsKeyCode: int32(ch),
391- Character: ch,
392- UnmodifiedCharacter: ch,
393- }
388+ evt := purecef.NewKeyEvent()
389+ evt.Type = purecef.KeyEventTypeKeyeventChar
390+ evt.WindowsKeyCode = int32(ch)
391+ evt.Character = ch
392+ evt.UnmodifiedCharacter = ch
394393 host.SendKeyEvent(&evt)
395394 }
396395 }
@@ -490,12 +489,12 @@ func buildMouseEvent(x, y float64, gdkMods uint, scale int32) purecef.MouseEvent
490489 }
491490
492491 func buildKeyEvent(keyval, keycode, gdkMods uint, eventType purecef.KeyEventType) purecef.KeyEvent {
493- return purecef.KeyEvent{
494- Type: eventType,
495- WindowsKeyCode: gdkKeyvalToWindowsVK(keyval),
496- NativeKeyCode: int32(keycode),
497- Modifiers: translateModifiers(gdkMods),
498- }
492+ evt := purecef.NewKeyEvent()
493+ evt.Type = eventType
494+ evt.WindowsKeyCode = gdkKeyvalToWindowsVK(keyval)
495+ evt.NativeKeyCode = int32(keycode)
496+ evt.Modifiers = translateModifiers(gdkMods)
497+ return evt
499498 }
500499
501500 // translateModifiers maps GDK modifier masks to CEF EventFlags values.
@@ -385,12 +385,11 @@ func (ib *inputBridge) onIMCommit(text string) {
385 continue385 continue
386 }386 }
387 ch := uint16(r)387 ch := uint16(r)
388- evt := purecef.KeyEvent{388+ evt := purecef.NewKeyEvent()
389- Type: purecef.KeyEventTypeKeyeventChar,389+ evt.Type = purecef.KeyEventTypeKeyeventChar
390- WindowsKeyCode: int32(ch),390+ evt.WindowsKeyCode = int32(ch)
391- Character: ch,391+ evt.Character = ch
392- UnmodifiedCharacter: ch,392+ evt.UnmodifiedCharacter = ch
393- }
394 host.SendKeyEvent(&evt)393 host.SendKeyEvent(&evt)
395 }394 }
396 }395 }
@@ -490,12 +489,12 @@ func buildMouseEvent(x, y float64, gdkMods uint, scale int32) purecef.MouseEvent
490 }489 }
491 490
492 func buildKeyEvent(keyval, keycode, gdkMods uint, eventType purecef.KeyEventType) purecef.KeyEvent {491 func buildKeyEvent(keyval, keycode, gdkMods uint, eventType purecef.KeyEventType) purecef.KeyEvent {
493- return purecef.KeyEvent{492+ evt := purecef.NewKeyEvent()
494- Type: eventType,493+ evt.Type = eventType
495- WindowsKeyCode: gdkKeyvalToWindowsVK(keyval),494+ evt.WindowsKeyCode = gdkKeyvalToWindowsVK(keyval)
496- NativeKeyCode: int32(keycode),495+ evt.NativeKeyCode = int32(keycode)
497- Modifiers: translateModifiers(gdkMods),496+ evt.Modifiers = translateModifiers(gdkMods)
498- }497+ return evt
499 }498 }
500 499
501 // translateModifiers maps GDK modifier masks to CEF EventFlags values.500 // translateModifiers maps GDK modifier masks to CEF EventFlags values.
M internal/infrastructure/cef/webview.go +2 -2
@@ -391,8 +391,8 @@ func (wv *WebView) OpenDevTools() {
391391 if host == nil {
392392 return
393393 }
394- windowInfo := purecef.WindowInfo{}
395- settings := purecef.BrowserSettings{}
394+ windowInfo := purecef.NewWindowInfo()
395+ settings := purecef.NewBrowserSettings()
396396 host.ShowDevTools(&windowInfo, nil, &settings, nil)
397397 }
398398
@@ -391,8 +391,8 @@ func (wv *WebView) OpenDevTools() {
391 if host == nil {391 if host == nil {
392 return392 return
393 }393 }
394- windowInfo := purecef.WindowInfo{}394+ windowInfo := purecef.NewWindowInfo()
395- settings := purecef.BrowserSettings{}395+ settings := purecef.NewBrowserSettings()
396 host.ShowDevTools(&windowInfo, nil, &settings, nil)396 host.ShowDevTools(&windowInfo, nil, &settings, nil)
397 }397 }
398 398
M internal/infrastructure/cef/webview_handlers.go +7 -7
@@ -145,13 +145,13 @@ func (h *handlerSet) GetScreenInfo(_ purecef.Browser, info *purecef.ScreenInfo)
145145 screenDepthPerComponent = 8
146146 )
147147 r := purecef.Rect{X: 0, Y: 0, Width: w, Height: ht}
148- *info = purecef.ScreenInfo{
149- DeviceScaleFactor: float32(s),
150- Depth: screenDepth,
151- DepthPerComponent: screenDepthPerComponent,
152- Rect: r,
153- AvailableRect: r,
154- }
148+ si := purecef.NewScreenInfo()
149+ si.DeviceScaleFactor = float32(s)
150+ si.Depth = screenDepth
151+ si.DepthPerComponent = screenDepthPerComponent
152+ si.Rect = r
153+ si.AvailableRect = r
154+ *info = si
155155 if h.wv != nil && h.wv.ctx != nil {
156156 logging.FromContext(h.wv.ctx).Debug().
157157 Uint64("screen_info_seq", callSeq).
@@ -145,13 +145,13 @@ func (h *handlerSet) GetScreenInfo(_ purecef.Browser, info *purecef.ScreenInfo)
145 screenDepthPerComponent = 8145 screenDepthPerComponent = 8
146 )146 )
147 r := purecef.Rect{X: 0, Y: 0, Width: w, Height: ht}147 r := purecef.Rect{X: 0, Y: 0, Width: w, Height: ht}
148- *info = purecef.ScreenInfo{148+ si := purecef.NewScreenInfo()
149- DeviceScaleFactor: float32(s),149+ si.DeviceScaleFactor = float32(s)
150- Depth: screenDepth,150+ si.Depth = screenDepth
151- DepthPerComponent: screenDepthPerComponent,151+ si.DepthPerComponent = screenDepthPerComponent
152- Rect: r,152+ si.Rect = r
153- AvailableRect: r,153+ si.AvailableRect = r
154- }154+ *info = si
155 if h.wv != nil && h.wv.ctx != nil {155 if h.wv != nil && h.wv.ctx != nil {
156 logging.FromContext(h.wv.ctx).Debug().156 logging.FromContext(h.wv.ctx).Debug().
157 Uint64("screen_info_seq", callSeq).157 Uint64("screen_info_seq", callSeq).
M internal/infrastructure/cef/webview_handlers_test.go +2 -1
@@ -83,7 +83,8 @@ func TestGetViewRectUsesDIPCoordinates(t *testing.T) {
8383 }
8484
8585 func TestGetScreenInfoUsesDIPRectAndScale(t *testing.T) {
86- info := &purecef.ScreenInfo{}
86+ si := purecef.NewScreenInfo()
87+ info := &si
8788 h := &handlerSet{
8889 wv: &WebView{
8990 ctx: context.Background(),
@@ -83,7 +83,8 @@ func TestGetViewRectUsesDIPCoordinates(t *testing.T) {
83 }83 }
84 84
85 func TestGetScreenInfoUsesDIPRectAndScale(t *testing.T) {85 func TestGetScreenInfoUsesDIPRectAndScale(t *testing.T) {
86- info := &purecef.ScreenInfo{}86+ si := purecef.NewScreenInfo()
87+ info := &si
87 h := &handlerSet{88 h := &handlerSet{
88 wv: &WebView{89 wv: &WebView{
89 ctx: context.Background(),90 ctx: context.Background(),
M internal/infrastructure/persistence/sqlite/connection.go +1 -1
@@ -27,7 +27,7 @@ func NewConnection(ctx context.Context, dbPath string) (*sql.DB, error) {
2727 }
2828
2929 // Open database connection
30- db, err := sql.Open("sqlite", dbPath)
30+ db, err := sql.Open("sqlite3", dbPath)
3131 if err != nil {
3232 return nil, fmt.Errorf("failed to open database: %w", err)
3333 }
@@ -27,7 +27,7 @@ func NewConnection(ctx context.Context, dbPath string) (*sql.DB, error) {
27 }27 }
28 28
29 // Open database connection29 // Open database connection
30- db, err := sql.Open("sqlite", dbPath)30+ db, err := sql.Open("sqlite3", dbPath)
31 if err != nil {31 if err != nil {
32 return nil, fmt.Errorf("failed to open database: %w", err)32 return nil, fmt.Errorf("failed to open database: %w", err)
33 }33 }

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