refactor(cef): eliminate unsafe from consumer code via purego-cef safe APIs
Adopt purego-cef's new safe handler signatures and constructors: - OnPaint buffer: unsafe.Pointer → []byte - OnBeforePopup/DevToolsPopup: unsafe.Pointer → *Client, *DictionaryValue, *bool - OnAudioStreamPacket: unsafe.Pointer → [][]float32 - GetScreenPoint: unsafe.Pointer → *int32 - GetResourceRequestHandler: unsafe.Pointer → *int32 - OnSelectClientCertificate: unsafe.Pointer → []X509Certificate - KeyEvent creation: unsafe.Sizeof + unsafe.Pointer cast → NewKeyEvent() - ScreenInfo creation: unsafe.Sizeof → NewScreenInfo() - handlePaint refactored to accept []byte directly unsafe remains only in gl_loader.go and render_pipeline.go (OpenGL API).
- commit
- fed7ccae204b2e6fe41669354e460039e3825578
- author
- brice · · 2026-03-21 06:28 UTC
- committer
- brice · · 2026-03-28 04:37 UTC
- parent
- 6604a53
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
4 files · +36 -55
M internal/infrastructure/cef/input_bridge.go +7 -13
| @@ -2,7 +2,6 @@ package cef | |||
| 2 | 2 | ||
| 3 | 3 | import ( | |
| 4 | 4 | "sync" | |
| 5 | - | "unsafe" | |
| 6 | 5 | ||
| 7 | 6 | purecef "github.com/bnema/purego-cef/cef" | |
| 8 | 7 | "github.com/bnema/puregotk/v4/gdk" | |
| @@ -326,10 +325,7 @@ func (ib *inputBridge) onIMCommit(text string) { | |||
| 326 | 325 | continue | |
| 327 | 326 | } | |
| 328 | 327 | ch := uint16(r) | |
| 329 | - | var evt purecef.KeyEvent | |
| 330 | - | evt.Size = unsafe.Sizeof(evt) | |
| 331 | - | *(*int32)(unsafe.Pointer(&evt.Type)) = int32(purecef.KeyEventTypeKeyeventChar) | |
| 332 | - | evt.WindowsKeyCode = int32(ch) | |
| 328 | + | evt := purecef.NewKeyEvent(purecef.KeyEventTypeKeyeventChar, int32(ch), 0, 0) | |
| 333 | 329 | evt.Character = ch | |
| 334 | 330 | evt.UnmodifiedCharacter = ch | |
| 335 | 331 | host.SendKeyEvent(&evt) | |
| @@ -361,14 +357,12 @@ func buildMouseEvent(x, y float64, gdkMods uint, scale int32) purecef.MouseEvent | |||
| 361 | 357 | } | |
| 362 | 358 | ||
| 363 | 359 | func buildKeyEvent(keyval, keycode, gdkMods uint, eventType purecef.KeyEventType) purecef.KeyEvent { | |
| 364 | - | var evt purecef.KeyEvent | |
| 365 | - | evt.Size = unsafe.Sizeof(evt) | |
| 366 | - | // Use unsafe to set Type field — the underlying types are both int32 but | |
| 367 | - | // the struct field uses an internal (unexportable) named type. | |
| 368 | - | *(*int32)(unsafe.Pointer(&evt.Type)) = int32(eventType) | |
| 369 | - | evt.Modifiers = translateModifiers(gdkMods) | |
| 370 | - | evt.WindowsKeyCode = gdkKeyvalToWindowsVK(keyval) | |
| 371 | - | evt.NativeKeyCode = int32(keycode) | |
| 360 | + | evt := purecef.NewKeyEvent( | |
| 361 | + | eventType, | |
| 362 | + | gdkKeyvalToWindowsVK(keyval), | |
| 363 | + | int32(keycode), | |
| 364 | + | translateModifiers(gdkMods), | |
| 365 | + | ) | |
| 372 | 366 | return evt | |
| 373 | 367 | } | |
| 374 | 368 | ||
| @@ -2,7 +2,6 @@ package cef | |||||
| 2 | 2 | ||||
| 3 | import ( | 3 | import ( | ||
| 4 | "sync" | 4 | "sync" | ||
| 5 | - | "unsafe" | |||
| 6 | 5 | ||||
| 7 | purecef "github.com/bnema/purego-cef/cef" | 6 | purecef "github.com/bnema/purego-cef/cef" | ||
| 8 | "github.com/bnema/puregotk/v4/gdk" | 7 | "github.com/bnema/puregotk/v4/gdk" | ||
| @@ -326,10 +325,7 @@ func (ib *inputBridge) onIMCommit(text string) { | |||||
| 326 | continue | 325 | continue | ||
| 327 | } | 326 | } | ||
| 328 | ch := uint16(r) | 327 | ch := uint16(r) | ||
| 329 | - | var evt purecef.KeyEvent | 328 | + | evt := purecef.NewKeyEvent(purecef.KeyEventTypeKeyeventChar, int32(ch), 0, 0) |
| 330 | - | evt.Size = unsafe.Sizeof(evt) | |||
| 331 | - | *(*int32)(unsafe.Pointer(&evt.Type)) = int32(purecef.KeyEventTypeKeyeventChar) | |||
| 332 | - | evt.WindowsKeyCode = int32(ch) | |||
| 333 | evt.Character = ch | 329 | evt.Character = ch | ||
| 334 | evt.UnmodifiedCharacter = ch | 330 | evt.UnmodifiedCharacter = ch | ||
| 335 | host.SendKeyEvent(&evt) | 331 | host.SendKeyEvent(&evt) | ||
| @@ -361,14 +357,12 @@ func buildMouseEvent(x, y float64, gdkMods uint, scale int32) purecef.MouseEvent | |||||
| 361 | } | 357 | } | ||
| 362 | 358 | ||||
| 363 | func buildKeyEvent(keyval, keycode, gdkMods uint, eventType purecef.KeyEventType) purecef.KeyEvent { | 359 | func buildKeyEvent(keyval, keycode, gdkMods uint, eventType purecef.KeyEventType) purecef.KeyEvent { | ||
| 364 | - | var evt purecef.KeyEvent | 360 | + | evt := purecef.NewKeyEvent( |
| 365 | - | evt.Size = unsafe.Sizeof(evt) | 361 | + | eventType, |
| 366 | - | // Use unsafe to set Type field — the underlying types are both int32 but | 362 | + | gdkKeyvalToWindowsVK(keyval), |
| 367 | - | // the struct field uses an internal (unexportable) named type. | 363 | + | int32(keycode), |
| 368 | - | *(*int32)(unsafe.Pointer(&evt.Type)) = int32(eventType) | 364 | + | translateModifiers(gdkMods), |
| 369 | - | evt.Modifiers = translateModifiers(gdkMods) | 365 | + | ) |
| 370 | - | evt.WindowsKeyCode = gdkKeyvalToWindowsVK(keyval) | |||
| 371 | - | evt.NativeKeyCode = int32(keycode) | |||
| 372 | return evt | 366 | return evt | ||
| 373 | } | 367 | } | ||
| 374 | 368 | ||||
M internal/infrastructure/cef/render_pipeline.go +4 -5
| @@ -151,8 +151,8 @@ func newRenderPipeline(ctx context.Context, gl *glLoader, scale int32) *renderPi | |||
| 151 | 151 | // handlePaint is called from CEF's OnPaint callback (on GTK main thread via | |
| 152 | 152 | // IdleAdd). It copies dirty rect regions from the CEF buffer into the staging | |
| 153 | 153 | // buffer and queues a GL redraw. | |
| 154 | - | func (rp *renderPipeline) handlePaint(buffer unsafe.Pointer, width, height int32, rects []rect) { | |
| 155 | - | if buffer == nil || width <= 0 || height <= 0 { | |
| 154 | + | func (rp *renderPipeline) handlePaint(buffer []byte, width, height int32, rects []rect) { | |
| 155 | + | if len(buffer) == 0 || width <= 0 || height <= 0 { | |
| 156 | 156 | return | |
| 157 | 157 | } | |
| 158 | 158 | ||
| @@ -160,7 +160,6 @@ func (rp *renderPipeline) handlePaint(buffer unsafe.Pointer, width, height int32 | |||
| 160 | 160 | rp.mu.Lock() | |
| 161 | 161 | ||
| 162 | 162 | bufSize := int(int64(width) * int64(height) * 4) | |
| 163 | - | srcSlice := unsafe.Slice((*byte)(buffer), bufSize) | |
| 164 | 163 | copiedBytes := uint64(0) | |
| 165 | 164 | ||
| 166 | 165 | // Detect size change, or first paint (staging not yet allocated). | |
| @@ -170,7 +169,7 @@ func (rp *renderPipeline) handlePaint(buffer unsafe.Pointer, width, height int32 | |||
| 170 | 169 | rp.staging = make([]byte, bufSize) | |
| 171 | 170 | rp.sizeChanged = true | |
| 172 | 171 | // On size change, copy the entire buffer. | |
| 173 | - | copy(rp.staging, srcSlice) | |
| 172 | + | copy(rp.staging, buffer) | |
| 174 | 173 | copiedBytes = uint64(bufSize) | |
| 175 | 174 | } else { | |
| 176 | 175 | // Copy only dirty rect rows. | |
| @@ -180,7 +179,7 @@ func (rp *renderPipeline) handlePaint(buffer unsafe.Pointer, width, height int32 | |||
| 180 | 179 | srcOff := int(row)*stride + int(r.X)*4 | |
| 181 | 180 | dstOff := srcOff | |
| 182 | 181 | rowBytes := int(r.Width) * 4 | |
| 183 | - | copy(rp.staging[dstOff:dstOff+rowBytes], srcSlice[srcOff:srcOff+rowBytes]) | |
| 182 | + | copy(rp.staging[dstOff:dstOff+rowBytes], buffer[srcOff:srcOff+rowBytes]) | |
| 184 | 183 | copiedBytes += uint64(rowBytes) | |
| 185 | 184 | } | |
| 186 | 185 | } | |
| @@ -151,8 +151,8 @@ func newRenderPipeline(ctx context.Context, gl *glLoader, scale int32) *renderPi | |||||
| 151 | // handlePaint is called from CEF's OnPaint callback (on GTK main thread via | 151 | // handlePaint is called from CEF's OnPaint callback (on GTK main thread via | ||
| 152 | // IdleAdd). It copies dirty rect regions from the CEF buffer into the staging | 152 | // IdleAdd). It copies dirty rect regions from the CEF buffer into the staging | ||
| 153 | // buffer and queues a GL redraw. | 153 | // buffer and queues a GL redraw. | ||
| 154 | - | func (rp *renderPipeline) handlePaint(buffer unsafe.Pointer, width, height int32, rects []rect) { | 154 | + | func (rp *renderPipeline) handlePaint(buffer []byte, width, height int32, rects []rect) { |
| 155 | - | if buffer == nil || width <= 0 || height <= 0 { | 155 | + | if len(buffer) == 0 || width <= 0 || height <= 0 { |
| 156 | return | 156 | return | ||
| 157 | } | 157 | } | ||
| 158 | 158 | ||||
| @@ -160,7 +160,6 @@ func (rp *renderPipeline) handlePaint(buffer unsafe.Pointer, width, height int32 | |||||
| 160 | rp.mu.Lock() | 160 | rp.mu.Lock() | ||
| 161 | 161 | ||||
| 162 | bufSize := int(int64(width) * int64(height) * 4) | 162 | bufSize := int(int64(width) * int64(height) * 4) | ||
| 163 | - | srcSlice := unsafe.Slice((*byte)(buffer), bufSize) | |||
| 164 | copiedBytes := uint64(0) | 163 | copiedBytes := uint64(0) | ||
| 165 | 164 | ||||
| 166 | // Detect size change, or first paint (staging not yet allocated). | 165 | // Detect size change, or first paint (staging not yet allocated). | ||
| @@ -170,7 +169,7 @@ func (rp *renderPipeline) handlePaint(buffer unsafe.Pointer, width, height int32 | |||||
| 170 | rp.staging = make([]byte, bufSize) | 169 | rp.staging = make([]byte, bufSize) | ||
| 171 | rp.sizeChanged = true | 170 | rp.sizeChanged = true | ||
| 172 | // On size change, copy the entire buffer. | 171 | // On size change, copy the entire buffer. | ||
| 173 | - | copy(rp.staging, srcSlice) | 172 | + | copy(rp.staging, buffer) |
| 174 | copiedBytes = uint64(bufSize) | 173 | copiedBytes = uint64(bufSize) | ||
| 175 | } else { | 174 | } else { | ||
| 176 | // Copy only dirty rect rows. | 175 | // Copy only dirty rect rows. | ||
| @@ -180,7 +179,7 @@ func (rp *renderPipeline) handlePaint(buffer unsafe.Pointer, width, height int32 | |||||
| 180 | srcOff := int(row)*stride + int(r.X)*4 | 179 | srcOff := int(row)*stride + int(r.X)*4 | ||
| 181 | dstOff := srcOff | 180 | dstOff := srcOff | ||
| 182 | rowBytes := int(r.Width) * 4 | 181 | rowBytes := int(r.Width) * 4 | ||
| 183 | - | copy(rp.staging[dstOff:dstOff+rowBytes], srcSlice[srcOff:srcOff+rowBytes]) | 182 | + | copy(rp.staging[dstOff:dstOff+rowBytes], buffer[srcOff:srcOff+rowBytes]) |
| 184 | copiedBytes += uint64(rowBytes) | 183 | copiedBytes += uint64(rowBytes) | ||
| 185 | } | 184 | } | ||
| 186 | } | 185 | } | ||
M internal/infrastructure/cef/webview.go +0 -4
| @@ -8,7 +8,6 @@ import ( | |||
| 8 | 8 | "math" | |
| 9 | 9 | "sync" | |
| 10 | 10 | "sync/atomic" | |
| 11 | - | "unsafe" | |
| 12 | 11 | ||
| 13 | 12 | purecef "github.com/bnema/purego-cef/cef" | |
| 14 | 13 | "github.com/bnema/puregotk/v4/glib" | |
| @@ -502,6 +501,3 @@ func (wv *WebView) runOnGTK(fn func()) { | |||
| 502 | 501 | }) | |
| 503 | 502 | glib.IdleAddOnce(&cb, 0) | |
| 504 | 503 | } | |
| 505 | - | ||
| 506 | - | // suppress unused import for unsafe (used by NativeWidget via GoPointer). | |
| 507 | - | var _ = unsafe.Pointer(nil) | |
| @@ -8,7 +8,6 @@ import ( | |||||
| 8 | "math" | 8 | "math" | ||
| 9 | "sync" | 9 | "sync" | ||
| 10 | "sync/atomic" | 10 | "sync/atomic" | ||
| 11 | - | "unsafe" | |||
| 12 | 11 | ||||
| 13 | purecef "github.com/bnema/purego-cef/cef" | 12 | purecef "github.com/bnema/purego-cef/cef" | ||
| 14 | "github.com/bnema/puregotk/v4/glib" | 13 | "github.com/bnema/puregotk/v4/glib" | ||
| @@ -502,6 +501,3 @@ func (wv *WebView) runOnGTK(fn func()) { | |||||
| 502 | }) | 501 | }) | ||
| 503 | glib.IdleAddOnce(&cb, 0) | 502 | glib.IdleAddOnce(&cb, 0) | ||
| 504 | } | 503 | } | ||
| 505 | - | ||||
| 506 | - | // suppress unused import for unsafe (used by NativeWidget via GoPointer). | |||
| 507 | - | var _ = unsafe.Pointer(nil) | |||
M internal/infrastructure/cef/webview_handlers.go +25 -33
| @@ -1,8 +1,6 @@ | |||
| 1 | 1 | package cef | |
| 2 | 2 | ||
| 3 | 3 | import ( | |
| 4 | - | "unsafe" | |
| 5 | - | ||
| 6 | 4 | purecef "github.com/bnema/purego-cef/cef" | |
| 7 | 5 | ||
| 8 | 6 | "github.com/bnema/dumber/internal/application/port" | |
| @@ -63,8 +61,6 @@ func (h *handlerSet) GetAccessibilityHandler() purecef.AccessibilityHandler { re | |||
| 63 | 61 | func (h *handlerSet) GetRootScreenRect(_ purecef.Browser, _ *purecef.Rect) int32 { return 0 } | |
| 64 | 62 | ||
| 65 | 63 | // GetViewRect fills the rect struct with the pipeline dimensions. | |
| 66 | - | // The rect pointer points to a cef_rect_t: {HostLayout padding, X, Y, Width, Height} all int32. | |
| 67 | - | // The HostLayout field occupies 0 bytes on most platforms but we use the Rect type alias to be safe. | |
| 68 | 64 | func (h *handlerSet) GetViewRect(_ purecef.Browser, rect *purecef.Rect) { | |
| 69 | 65 | if rect == nil { | |
| 70 | 66 | return | |
| @@ -89,7 +85,7 @@ func (h *handlerSet) GetViewRect(_ purecef.Browser, rect *purecef.Rect) { | |||
| 89 | 85 | rect.Height = ht | |
| 90 | 86 | } | |
| 91 | 87 | ||
| 92 | - | func (h *handlerSet) GetScreenPoint(_ purecef.Browser, _, _ int32, _, _ unsafe.Pointer) int32 { | |
| 88 | + | func (h *handlerSet) GetScreenPoint(_ purecef.Browser, _, _ int32, _, _ *int32) int32 { | |
| 93 | 89 | return 0 | |
| 94 | 90 | } | |
| 95 | 91 | ||
| @@ -103,15 +99,12 @@ func (h *handlerSet) GetScreenInfo(_ purecef.Browser, info *purecef.ScreenInfo) | |||
| 103 | 99 | s := h.wv.pipeline.scale | |
| 104 | 100 | h.wv.pipeline.mu.Unlock() | |
| 105 | 101 | ||
| 106 | - | info.Size = unsafe.Sizeof(*info) | |
| 107 | - | info.DeviceScaleFactor = float32(s) | |
| 108 | - | info.Depth = 24 | |
| 109 | - | info.DepthPerComponent = 8 | |
| 110 | - | info.Rect.X = 0 | |
| 111 | - | info.Rect.Y = 0 | |
| 112 | - | info.Rect.Width = w | |
| 113 | - | info.Rect.Height = ht | |
| 114 | - | info.AvailableRect = info.Rect | |
| 102 | + | const ( | |
| 103 | + | screenDepth = 24 | |
| 104 | + | screenDepthPerComponent = 8 | |
| 105 | + | ) | |
| 106 | + | r := purecef.Rect{X: 0, Y: 0, Width: w, Height: ht} | |
| 107 | + | *info = purecef.NewScreenInfo(float32(s), screenDepth, screenDepthPerComponent, false, r, r) | |
| 115 | 108 | return 1 | |
| 116 | 109 | } | |
| 117 | 110 | ||
| @@ -124,9 +117,9 @@ func (h *handlerSet) OnPopupSize(_ purecef.Browser, _ *purecef.Rect) {} | |||
| 124 | 117 | // must first copy the transient CEF buffer before hopping back to GTK. | |
| 125 | 118 | func (h *handlerSet) OnPaint( | |
| 126 | 119 | _ purecef.Browser, _ purecef.PaintElementType, | |
| 127 | - | dirtyRects []purecef.Rect, buffer unsafe.Pointer, width, height int32, | |
| 120 | + | dirtyRects []purecef.Rect, buffer []byte, width, height int32, | |
| 128 | 121 | ) { | |
| 129 | - | if buffer == nil || width <= 0 || height <= 0 { | |
| 122 | + | if len(buffer) == 0 || width <= 0 || height <= 0 { | |
| 130 | 123 | return | |
| 131 | 124 | } | |
| 132 | 125 | rects := make([]rect, len(dirtyRects)) | |
| @@ -134,14 +127,10 @@ func (h *handlerSet) OnPaint( | |||
| 134 | 127 | rects[i] = rect{X: dr.X, Y: dr.Y, Width: dr.Width, Height: dr.Height} | |
| 135 | 128 | } | |
| 136 | 129 | if h.wv.engine != nil && h.wv.engine.multiThreadedMessageLoop { | |
| 137 | - | bufSize := int(width) * int(height) * 4 | |
| 138 | - | if bufSize <= 0 { | |
| 139 | - | return | |
| 140 | - | } | |
| 141 | - | pixels := make([]byte, bufSize) | |
| 142 | - | copy(pixels, unsafe.Slice((*byte)(buffer), bufSize)) | |
| 130 | + | pixels := make([]byte, len(buffer)) | |
| 131 | + | copy(pixels, buffer) | |
| 143 | 132 | h.wv.runOnGTK(func() { | |
| 144 | - | h.wv.pipeline.handlePaint(unsafe.Pointer(&pixels[0]), width, height, rects) | |
| 133 | + | h.wv.pipeline.handlePaint(pixels, width, height, rects) | |
| 145 | 134 | }) | |
| 146 | 135 | return | |
| 147 | 136 | } | |
| @@ -334,7 +323,7 @@ func (h *handlerSet) OnLoadEnd(_ purecef.Browser, frame purecef.Frame, httpStatu | |||
| 334 | 323 | } | |
| 335 | 324 | } | |
| 336 | 325 | ||
| 337 | - | // OnLoadError is a no-op in Phase 1. | |
| 326 | + | // OnLoadError is a no-op. | |
| 338 | 327 | func (h *handlerSet) OnLoadError(_ purecef.Browser, _ purecef.Frame, _ purecef.Errorcode, _, _ string) { | |
| 339 | 328 | } | |
| 340 | 329 | ||
| @@ -342,21 +331,24 @@ func (h *handlerSet) OnLoadError(_ purecef.Browser, _ purecef.Frame, _ purecef.E | |||
| 342 | 331 | // LifeSpanHandler (6 methods) | |
| 343 | 332 | // =========================================================================== | |
| 344 | 333 | ||
| 345 | - | // OnBeforePopup blocks all popups in Phase 1. | |
| 334 | + | // OnBeforePopup blocks all popups. | |
| 335 | + | // | |
| 336 | + | //nolint:gocritic // signature imposed by purecef.LifeSpanHandler interface | |
| 346 | 337 | func (h *handlerSet) OnBeforePopup( | |
| 347 | 338 | _ purecef.Browser, _ purecef.Frame, _ int32, _, _ string, | |
| 348 | 339 | _ purecef.WindowOpenDisposition, _ int32, _ *purecef.PopupFeatures, | |
| 349 | - | _ *purecef.WindowInfo, _ unsafe.Pointer, _ *purecef.BrowserSettings, | |
| 350 | - | _, _ unsafe.Pointer, | |
| 340 | + | _ *purecef.WindowInfo, _ *purecef.Client, _ *purecef.BrowserSettings, | |
| 341 | + | _ *purecef.DictionaryValue, _ *bool, | |
| 351 | 342 | ) bool { | |
| 352 | 343 | return true // block | |
| 353 | 344 | } | |
| 354 | 345 | ||
| 355 | 346 | func (h *handlerSet) OnBeforePopupAborted(_ purecef.Browser, _ int32) {} | |
| 356 | 347 | ||
| 348 | + | //nolint:gocritic // signature imposed by purecef.LifeSpanHandler interface | |
| 357 | 349 | func (h *handlerSet) OnBeforeDevToolsPopup( | |
| 358 | - | _ purecef.Browser, _ *purecef.WindowInfo, _ unsafe.Pointer, | |
| 359 | - | _ *purecef.BrowserSettings, _, _ unsafe.Pointer, | |
| 350 | + | _ purecef.Browser, _ *purecef.WindowInfo, _ *purecef.Client, | |
| 351 | + | _ *purecef.BrowserSettings, _ *purecef.DictionaryValue, _ *bool, | |
| 360 | 352 | ) { | |
| 361 | 353 | } | |
| 362 | 354 | ||
| @@ -421,7 +413,7 @@ func (h *handlerSet) OnOpenUrlfromTab(_ purecef.Browser, _ purecef.Frame, _ stri | |||
| 421 | 413 | ||
| 422 | 414 | func (h *handlerSet) GetResourceRequestHandler( | |
| 423 | 415 | _ purecef.Browser, _ purecef.Frame, _ purecef.Request, | |
| 424 | - | _, _ int32, _ string, _ unsafe.Pointer, | |
| 416 | + | _, _ int32, _ string, _ *int32, | |
| 425 | 417 | ) purecef.ResourceRequestHandler { | |
| 426 | 418 | return nil | |
| 427 | 419 | } | |
| @@ -438,8 +430,8 @@ func (h *handlerSet) OnCertificateError(_ purecef.Browser, _ purecef.Errorcode, | |||
| 438 | 430 | } | |
| 439 | 431 | ||
| 440 | 432 | func (h *handlerSet) OnSelectClientCertificate( | |
| 441 | - | _ purecef.Browser, _ int32, _ string, _ int32, _ int, | |
| 442 | - | _ unsafe.Pointer, _ purecef.SelectClientCertificateCallback, | |
| 433 | + | _ purecef.Browser, _ int32, _ string, _ int32, | |
| 434 | + | _ []purecef.X509Certificate, _ purecef.SelectClientCertificateCallback, | |
| 443 | 435 | ) int32 { | |
| 444 | 436 | return 0 | |
| 445 | 437 | } | |
| @@ -509,7 +501,7 @@ func (h *handlerSet) OnAudioStreamStarted(_ purecef.Browser, _ *purecef.AudioPar | |||
| 509 | 501 | h.wv.setAudioPlaying(true) | |
| 510 | 502 | } | |
| 511 | 503 | ||
| 512 | - | func (h *handlerSet) OnAudioStreamPacket(_ purecef.Browser, _ unsafe.Pointer, _ int32, _ int64) {} | |
| 504 | + | func (h *handlerSet) OnAudioStreamPacket(_ purecef.Browser, _ [][]float32, _ int32, _ int64) {} | |
| 513 | 505 | ||
| 514 | 506 | func (h *handlerSet) OnAudioStreamStopped(_ purecef.Browser) { | |
| 515 | 507 | h.wv.setAudioPlaying(false) | |
| @@ -1,8 +1,6 @@ | |||||
| 1 | package cef | 1 | package cef | ||
| 2 | 2 | ||||
| 3 | import ( | 3 | import ( | ||
| 4 | - | "unsafe" | |||
| 5 | - | ||||
| 6 | purecef "github.com/bnema/purego-cef/cef" | 4 | purecef "github.com/bnema/purego-cef/cef" | ||
| 7 | 5 | ||||
| 8 | "github.com/bnema/dumber/internal/application/port" | 6 | "github.com/bnema/dumber/internal/application/port" | ||
| @@ -63,8 +61,6 @@ func (h *handlerSet) GetAccessibilityHandler() purecef.AccessibilityHandler { re | |||||
| 63 | func (h *handlerSet) GetRootScreenRect(_ purecef.Browser, _ *purecef.Rect) int32 { return 0 } | 61 | func (h *handlerSet) GetRootScreenRect(_ purecef.Browser, _ *purecef.Rect) int32 { return 0 } | ||
| 64 | 62 | ||||
| 65 | // GetViewRect fills the rect struct with the pipeline dimensions. | 63 | // GetViewRect fills the rect struct with the pipeline dimensions. | ||
| 66 | - | // The rect pointer points to a cef_rect_t: {HostLayout padding, X, Y, Width, Height} all int32. | |||
| 67 | - | // The HostLayout field occupies 0 bytes on most platforms but we use the Rect type alias to be safe. | |||
| 68 | func (h *handlerSet) GetViewRect(_ purecef.Browser, rect *purecef.Rect) { | 64 | func (h *handlerSet) GetViewRect(_ purecef.Browser, rect *purecef.Rect) { | ||
| 69 | if rect == nil { | 65 | if rect == nil { | ||
| 70 | return | 66 | return | ||
| @@ -89,7 +85,7 @@ func (h *handlerSet) GetViewRect(_ purecef.Browser, rect *purecef.Rect) { | |||||
| 89 | rect.Height = ht | 85 | rect.Height = ht | ||
| 90 | } | 86 | } | ||
| 91 | 87 | ||||
| 92 | - | func (h *handlerSet) GetScreenPoint(_ purecef.Browser, _, _ int32, _, _ unsafe.Pointer) int32 { | 88 | + | func (h *handlerSet) GetScreenPoint(_ purecef.Browser, _, _ int32, _, _ *int32) int32 { |
| 93 | return 0 | 89 | return 0 | ||
| 94 | } | 90 | } | ||
| 95 | 91 | ||||
| @@ -103,15 +99,12 @@ func (h *handlerSet) GetScreenInfo(_ purecef.Browser, info *purecef.ScreenInfo) | |||||
| 103 | s := h.wv.pipeline.scale | 99 | s := h.wv.pipeline.scale | ||
| 104 | h.wv.pipeline.mu.Unlock() | 100 | h.wv.pipeline.mu.Unlock() | ||
| 105 | 101 | ||||
| 106 | - | info.Size = unsafe.Sizeof(*info) | 102 | + | const ( |
| 107 | - | info.DeviceScaleFactor = float32(s) | 103 | + | screenDepth = 24 |
| 108 | - | info.Depth = 24 | 104 | + | screenDepthPerComponent = 8 |
| 109 | - | info.DepthPerComponent = 8 | 105 | + | ) |
| 110 | - | info.Rect.X = 0 | 106 | + | r := purecef.Rect{X: 0, Y: 0, Width: w, Height: ht} |
| 111 | - | info.Rect.Y = 0 | 107 | + | *info = purecef.NewScreenInfo(float32(s), screenDepth, screenDepthPerComponent, false, r, r) |
| 112 | - | info.Rect.Width = w | |||
| 113 | - | info.Rect.Height = ht | |||
| 114 | - | info.AvailableRect = info.Rect | |||
| 115 | return 1 | 108 | return 1 | ||
| 116 | } | 109 | } | ||
| 117 | 110 | ||||
| @@ -124,9 +117,9 @@ func (h *handlerSet) OnPopupSize(_ purecef.Browser, _ *purecef.Rect) {} | |||||
| 124 | // must first copy the transient CEF buffer before hopping back to GTK. | 117 | // must first copy the transient CEF buffer before hopping back to GTK. | ||
| 125 | func (h *handlerSet) OnPaint( | 118 | func (h *handlerSet) OnPaint( | ||
| 126 | _ purecef.Browser, _ purecef.PaintElementType, | 119 | _ purecef.Browser, _ purecef.PaintElementType, | ||
| 127 | - | dirtyRects []purecef.Rect, buffer unsafe.Pointer, width, height int32, | 120 | + | dirtyRects []purecef.Rect, buffer []byte, width, height int32, |
| 128 | ) { | 121 | ) { | ||
| 129 | - | if buffer == nil || width <= 0 || height <= 0 { | 122 | + | if len(buffer) == 0 || width <= 0 || height <= 0 { |
| 130 | return | 123 | return | ||
| 131 | } | 124 | } | ||
| 132 | rects := make([]rect, len(dirtyRects)) | 125 | rects := make([]rect, len(dirtyRects)) | ||
| @@ -134,14 +127,10 @@ func (h *handlerSet) OnPaint( | |||||
| 134 | rects[i] = rect{X: dr.X, Y: dr.Y, Width: dr.Width, Height: dr.Height} | 127 | rects[i] = rect{X: dr.X, Y: dr.Y, Width: dr.Width, Height: dr.Height} | ||
| 135 | } | 128 | } | ||
| 136 | if h.wv.engine != nil && h.wv.engine.multiThreadedMessageLoop { | 129 | if h.wv.engine != nil && h.wv.engine.multiThreadedMessageLoop { | ||
| 137 | - | bufSize := int(width) * int(height) * 4 | 130 | + | pixels := make([]byte, len(buffer)) |
| 138 | - | if bufSize <= 0 { | 131 | + | copy(pixels, buffer) |
| 139 | - | return | |||
| 140 | - | } | |||
| 141 | - | pixels := make([]byte, bufSize) | |||
| 142 | - | copy(pixels, unsafe.Slice((*byte)(buffer), bufSize)) | |||
| 143 | h.wv.runOnGTK(func() { | 132 | h.wv.runOnGTK(func() { | ||
| 144 | - | h.wv.pipeline.handlePaint(unsafe.Pointer(&pixels[0]), width, height, rects) | 133 | + | h.wv.pipeline.handlePaint(pixels, width, height, rects) |
| 145 | }) | 134 | }) | ||
| 146 | return | 135 | return | ||
| 147 | } | 136 | } | ||
| @@ -334,7 +323,7 @@ func (h *handlerSet) OnLoadEnd(_ purecef.Browser, frame purecef.Frame, httpStatu | |||||
| 334 | } | 323 | } | ||
| 335 | } | 324 | } | ||
| 336 | 325 | ||||
| 337 | - | // OnLoadError is a no-op in Phase 1. | 326 | + | // OnLoadError is a no-op. |
| 338 | func (h *handlerSet) OnLoadError(_ purecef.Browser, _ purecef.Frame, _ purecef.Errorcode, _, _ string) { | 327 | func (h *handlerSet) OnLoadError(_ purecef.Browser, _ purecef.Frame, _ purecef.Errorcode, _, _ string) { | ||
| 339 | } | 328 | } | ||
| 340 | 329 | ||||
| @@ -342,21 +331,24 @@ func (h *handlerSet) OnLoadError(_ purecef.Browser, _ purecef.Frame, _ purecef.E | |||||
| 342 | // LifeSpanHandler (6 methods) | 331 | // LifeSpanHandler (6 methods) | ||
| 343 | // =========================================================================== | 332 | // =========================================================================== | ||
| 344 | 333 | ||||
| 345 | - | // OnBeforePopup blocks all popups in Phase 1. | 334 | + | // OnBeforePopup blocks all popups. |
| 335 | + | // | |||
| 336 | + | //nolint:gocritic // signature imposed by purecef.LifeSpanHandler interface | |||
| 346 | func (h *handlerSet) OnBeforePopup( | 337 | func (h *handlerSet) OnBeforePopup( | ||
| 347 | _ purecef.Browser, _ purecef.Frame, _ int32, _, _ string, | 338 | _ purecef.Browser, _ purecef.Frame, _ int32, _, _ string, | ||
| 348 | _ purecef.WindowOpenDisposition, _ int32, _ *purecef.PopupFeatures, | 339 | _ purecef.WindowOpenDisposition, _ int32, _ *purecef.PopupFeatures, | ||
| 349 | - | _ *purecef.WindowInfo, _ unsafe.Pointer, _ *purecef.BrowserSettings, | 340 | + | _ *purecef.WindowInfo, _ *purecef.Client, _ *purecef.BrowserSettings, |
| 350 | - | _, _ unsafe.Pointer, | 341 | + | _ *purecef.DictionaryValue, _ *bool, |
| 351 | ) bool { | 342 | ) bool { | ||
| 352 | return true // block | 343 | return true // block | ||
| 353 | } | 344 | } | ||
| 354 | 345 | ||||
| 355 | func (h *handlerSet) OnBeforePopupAborted(_ purecef.Browser, _ int32) {} | 346 | func (h *handlerSet) OnBeforePopupAborted(_ purecef.Browser, _ int32) {} | ||
| 356 | 347 | ||||
| 348 | + | //nolint:gocritic // signature imposed by purecef.LifeSpanHandler interface | |||
| 357 | func (h *handlerSet) OnBeforeDevToolsPopup( | 349 | func (h *handlerSet) OnBeforeDevToolsPopup( | ||
| 358 | - | _ purecef.Browser, _ *purecef.WindowInfo, _ unsafe.Pointer, | 350 | + | _ purecef.Browser, _ *purecef.WindowInfo, _ *purecef.Client, |
| 359 | - | _ *purecef.BrowserSettings, _, _ unsafe.Pointer, | 351 | + | _ *purecef.BrowserSettings, _ *purecef.DictionaryValue, _ *bool, |
| 360 | ) { | 352 | ) { | ||
| 361 | } | 353 | } | ||
| 362 | 354 | ||||
| @@ -421,7 +413,7 @@ func (h *handlerSet) OnOpenUrlfromTab(_ purecef.Browser, _ purecef.Frame, _ stri | |||||
| 421 | 413 | ||||
| 422 | func (h *handlerSet) GetResourceRequestHandler( | 414 | func (h *handlerSet) GetResourceRequestHandler( | ||
| 423 | _ purecef.Browser, _ purecef.Frame, _ purecef.Request, | 415 | _ purecef.Browser, _ purecef.Frame, _ purecef.Request, | ||
| 424 | - | _, _ int32, _ string, _ unsafe.Pointer, | 416 | + | _, _ int32, _ string, _ *int32, |
| 425 | ) purecef.ResourceRequestHandler { | 417 | ) purecef.ResourceRequestHandler { | ||
| 426 | return nil | 418 | return nil | ||
| 427 | } | 419 | } | ||
| @@ -438,8 +430,8 @@ func (h *handlerSet) OnCertificateError(_ purecef.Browser, _ purecef.Errorcode, | |||||
| 438 | } | 430 | } | ||
| 439 | 431 | ||||
| 440 | func (h *handlerSet) OnSelectClientCertificate( | 432 | func (h *handlerSet) OnSelectClientCertificate( | ||
| 441 | - | _ purecef.Browser, _ int32, _ string, _ int32, _ int, | 433 | + | _ purecef.Browser, _ int32, _ string, _ int32, |
| 442 | - | _ unsafe.Pointer, _ purecef.SelectClientCertificateCallback, | 434 | + | _ []purecef.X509Certificate, _ purecef.SelectClientCertificateCallback, |
| 443 | ) int32 { | 435 | ) int32 { | ||
| 444 | return 0 | 436 | return 0 | ||
| 445 | } | 437 | } | ||
| @@ -509,7 +501,7 @@ func (h *handlerSet) OnAudioStreamStarted(_ purecef.Browser, _ *purecef.AudioPar | |||||
| 509 | h.wv.setAudioPlaying(true) | 501 | h.wv.setAudioPlaying(true) | ||
| 510 | } | 502 | } | ||
| 511 | 503 | ||||
| 512 | - | func (h *handlerSet) OnAudioStreamPacket(_ purecef.Browser, _ unsafe.Pointer, _ int32, _ int64) {} | 504 | + | func (h *handlerSet) OnAudioStreamPacket(_ purecef.Browser, _ [][]float32, _ int32, _ int64) {} |
| 513 | 505 | ||||
| 514 | func (h *handlerSet) OnAudioStreamStopped(_ purecef.Browser) { | 506 | func (h *handlerSet) OnAudioStreamStopped(_ purecef.Browser) { | ||
| 515 | h.wv.setAudioPlaying(false) | 507 | h.wv.setAudioPlaying(false) | ||