detached ca280a9

refactor(browser): migrate workspace_manager.go to gotk4 API

Replace all direct widget method calls with webkit helper functions:
- Replace container.Hide/Show() with webkit.WidgetHide/Show()
- Replace container.QueueResize/QueueDraw() with webkit.WidgetQueueResize/WidgetQueueDraw()

Fix type mismatches for gotk4:
- Change pendingIdle map key type from gtk.Widgetter to uintptr
- Fix WebView ID comparison: convert uint64 to string with fmt.Sprintf

Remove obsolete Config fields:
- Remove cfg.CreateWindow assignment (no longer exists in gotk4)
- Update comment to reflect gotk4's default behavior

All 8 compilation errors in workspace_manager.go now resolved.
commit
ca280a90ed0e27a283c6e5ab0a5a013c833ccd77
author
bamen · · 2025-10-08 18:51 UTC
committer
bamen · · 2025-10-08 19:48 UTC
parent
2b5245e
signature
unsigned
1 file · +10 -12
M internal/app/browser/workspace_manager.go +10 -12
@@ -67,7 +67,7 @@ type WorkspaceManager struct {
6767
6868 // Cleanup tracking
6969 cleanupCounter uint
70- pendingIdle map[gtk.Widgetter][]*paneNode
70+ pendingIdle map[uintptr][]*paneNode
7171 }
7272
7373 // Workspace navigation shortcuts are now handled globally by WindowShortcutHandler
@@ -116,10 +116,8 @@ func NewWorkspaceManager(app *BrowserApp, rootPane *BrowserPane) *WorkspaceManag
116116 return nil, err
117117 }
118118 // Pane WebViews are embedded inside the main application window, so they do not
119- // need their own toplevel GtkWindow. Avoid creating per-pane windows to keep GTK
120- // ownership simple (Epiphany follows the same pattern) and to prevent premature
121- // swapchain destruction when panes are closed.
122- cfg.CreateWindow = false
119+ // need their own toplevel GtkWindow. In gotk4, this is the default behavior when
120+ // using webkit.NewWebView() without creating a separate window.
123121 return webkit.NewWebView(cfg)
124122 }
125123 manager.createPaneFn = func(view *webkit.WebView) (*BrowserPane, error) {
@@ -380,7 +378,7 @@ func (wm *WorkspaceManager) OnWorkspaceMessage(source *webkit.WebView, msg messa
380378 // Find the popup pane by webview ID
381379 var targetNode *paneNode
382380 for webView, node := range wm.viewToNode {
383- if webView != nil && webView.ID() == msg.WebViewID {
381+ if webView != nil && fmt.Sprintf("%d", webView.ID()) == msg.WebViewID {
384382 targetNode = node
385383 break
386384 }
@@ -464,7 +462,7 @@ func (wm *WorkspaceManager) OnWorkspaceMessage(source *webkit.WebView, msg messa
464462 log.Printf("[workspace] Fixing parent pane rendering after popup close")
465463
466464 // CRITICAL: Hide parent container to disconnect WebKitGTK rendering pipeline
467- parentNode.container.Hide()
465+ webkit.WidgetHide(parentNode.container)
468466
469467 // Schedule showing and forcing GTK to reconnect rendering
470468 wm.scheduleIdleGuarded(func() bool {
@@ -472,17 +470,17 @@ func (wm *WorkspaceManager) OnWorkspaceMessage(source *webkit.WebView, msg messa
472470 return false
473471 }
474472 // Show widget to reconnect WebKit rendering pipeline
475- parentNode.container.Show()
473+ webkit.WidgetShow(parentNode.container)
476474 // Force GTK to recalculate size and recreate rendering surface
477- parentNode.container.QueueResize()
478- parentNode.container.QueueDraw()
475+ webkit.WidgetQueueResize(parentNode.container)
476+ webkit.WidgetQueueDraw(parentNode.container)
479477
480478 // Also queue resize+draw on the WebView widget itself
481479 if parentNode.pane != nil && parentNode.pane.WebView() != nil {
482480 webViewWidget := parentNode.pane.WebView().Widget()
483481 if webViewWidget != nil {
484- webViewWidget.QueueResize()
485- webViewWidget.QueueDraw()
482+ webkit.WidgetQueueResize(webViewWidget)
483+ webkit.WidgetQueueDraw(webViewWidget)
486484 log.Printf("[workspace] Queued resize+draw for parent WebView widget")
487485 }
488486 }
@@ -67,7 +67,7 @@ type WorkspaceManager struct {
67 67
68 // Cleanup tracking68 // Cleanup tracking
69 cleanupCounter uint69 cleanupCounter uint
70- pendingIdle map[gtk.Widgetter][]*paneNode70+ pendingIdle map[uintptr][]*paneNode
71 }71 }
72 72
73 // Workspace navigation shortcuts are now handled globally by WindowShortcutHandler73 // Workspace navigation shortcuts are now handled globally by WindowShortcutHandler
@@ -116,10 +116,8 @@ func NewWorkspaceManager(app *BrowserApp, rootPane *BrowserPane) *WorkspaceManag
116 return nil, err116 return nil, err
117 }117 }
118 // Pane WebViews are embedded inside the main application window, so they do not118 // Pane WebViews are embedded inside the main application window, so they do not
119- // need their own toplevel GtkWindow. Avoid creating per-pane windows to keep GTK119+ // need their own toplevel GtkWindow. In gotk4, this is the default behavior when
120- // ownership simple (Epiphany follows the same pattern) and to prevent premature120+ // using webkit.NewWebView() without creating a separate window.
121- // swapchain destruction when panes are closed.
122- cfg.CreateWindow = false
123 return webkit.NewWebView(cfg)121 return webkit.NewWebView(cfg)
124 }122 }
125 manager.createPaneFn = func(view *webkit.WebView) (*BrowserPane, error) {123 manager.createPaneFn = func(view *webkit.WebView) (*BrowserPane, error) {
@@ -380,7 +378,7 @@ func (wm *WorkspaceManager) OnWorkspaceMessage(source *webkit.WebView, msg messa
380 // Find the popup pane by webview ID378 // Find the popup pane by webview ID
381 var targetNode *paneNode379 var targetNode *paneNode
382 for webView, node := range wm.viewToNode {380 for webView, node := range wm.viewToNode {
383- if webView != nil && webView.ID() == msg.WebViewID {381+ if webView != nil && fmt.Sprintf("%d", webView.ID()) == msg.WebViewID {
384 targetNode = node382 targetNode = node
385 break383 break
386 }384 }
@@ -464,7 +462,7 @@ func (wm *WorkspaceManager) OnWorkspaceMessage(source *webkit.WebView, msg messa
464 log.Printf("[workspace] Fixing parent pane rendering after popup close")462 log.Printf("[workspace] Fixing parent pane rendering after popup close")
465 463
466 // CRITICAL: Hide parent container to disconnect WebKitGTK rendering pipeline464 // CRITICAL: Hide parent container to disconnect WebKitGTK rendering pipeline
467- parentNode.container.Hide()465+ webkit.WidgetHide(parentNode.container)
468 466
469 // Schedule showing and forcing GTK to reconnect rendering467 // Schedule showing and forcing GTK to reconnect rendering
470 wm.scheduleIdleGuarded(func() bool {468 wm.scheduleIdleGuarded(func() bool {
@@ -472,17 +470,17 @@ func (wm *WorkspaceManager) OnWorkspaceMessage(source *webkit.WebView, msg messa
472 return false470 return false
473 }471 }
474 // Show widget to reconnect WebKit rendering pipeline472 // Show widget to reconnect WebKit rendering pipeline
475- parentNode.container.Show()473+ webkit.WidgetShow(parentNode.container)
476 // Force GTK to recalculate size and recreate rendering surface474 // Force GTK to recalculate size and recreate rendering surface
477- parentNode.container.QueueResize()475+ webkit.WidgetQueueResize(parentNode.container)
478- parentNode.container.QueueDraw()476+ webkit.WidgetQueueDraw(parentNode.container)
479 477
480 // Also queue resize+draw on the WebView widget itself478 // Also queue resize+draw on the WebView widget itself
481 if parentNode.pane != nil && parentNode.pane.WebView() != nil {479 if parentNode.pane != nil && parentNode.pane.WebView() != nil {
482 webViewWidget := parentNode.pane.WebView().Widget()480 webViewWidget := parentNode.pane.WebView().Widget()
483 if webViewWidget != nil {481 if webViewWidget != nil {
484- webViewWidget.QueueResize()482+ webkit.WidgetQueueResize(webViewWidget)
485- webViewWidget.QueueDraw()483+ webkit.WidgetQueueDraw(webViewWidget)
486 log.Printf("[workspace] Queued resize+draw for parent WebView widget")484 log.Printf("[workspace] Queued resize+draw for parent WebView widget")
487 }485 }
488 }486 }

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