detached 6ec492a

fix(browser): prevent GTK CSS counting bloom filter errors

- Add CSS class state checking before add/remove operations
- Prevent redundant WidgetAddCSSClass/WidgetRemoveCSSClass calls
- Add container pointer validation in border functions
- Reduce GTK CSS operation overhead and logging noise
- Fixes 'assertion failed: (self->buckets[bucket] > 0)' GTK errors
commit
6ec492ab361cc0529787ae3c022a90f727da87f5
author
Brice · · 2025-09-27 21:47 UTC
parent
1d5172c
signature
unsigned
1 file · +31 -9
M internal/app/browser/workspace_utils.go +31 -9
@@ -221,14 +221,26 @@ func (wm *WorkspaceManager) applyActivePaneBorder(node *paneNode) {
221221
222222 // Apply CSS classes to border container (provides border styling)
223223 if ctx.borderContainer != nil {
224+ // Check if this container already has the active class to avoid redundant operations
225+ var alreadyActive bool
224226 ctx.borderContainer.Execute(func(containerPtr uintptr) error {
225- // Only add the active class - base classes should already be set
226- webkit.WidgetAddCSSClass(containerPtr, activePaneClass)
227+ // Safety check: verify container pointer is valid
228+ if containerPtr == 0 {
229+ return fmt.Errorf("invalid container pointer")
230+ }
231+ alreadyActive = webkit.WidgetHasCSSClass(containerPtr, activePaneClass)
227232 return nil
228233 })
229- }
230234
231- log.Printf("[workspace] Applied border to %s pane: %p", ctx.paneType, node)
235+ // Only apply if not already active (prevents redundant GTK operations)
236+ if !alreadyActive {
237+ ctx.borderContainer.Execute(func(containerPtr uintptr) error {
238+ webkit.WidgetAddCSSClass(containerPtr, activePaneClass)
239+ return nil
240+ })
241+ log.Printf("[workspace] Applied border to %s pane: %p", ctx.paneType, node)
242+ }
243+ }
232244 }
233245
234246 // removeActivePaneBorder removes the active pane visual border using the centralized system
@@ -240,16 +252,26 @@ func (wm *WorkspaceManager) removeActivePaneBorder(node *paneNode) {
240252
241253 // Remove CSS classes from border container
242254 if ctx.borderContainer != nil {
255+ // Check if this container has the active class before attempting removal
256+ var hasActiveClass bool
243257 ctx.borderContainer.Execute(func(containerPtr uintptr) error {
244- // Only remove the active class if it exists
245- if webkit.WidgetHasCSSClass(containerPtr, activePaneClass) {
246- webkit.WidgetRemoveCSSClass(containerPtr, activePaneClass)
258+ // Safety check: verify container pointer is valid
259+ if containerPtr == 0 {
260+ return fmt.Errorf("invalid container pointer")
247261 }
262+ hasActiveClass = webkit.WidgetHasCSSClass(containerPtr, activePaneClass)
248263 return nil
249264 })
250- }
251265
252- log.Printf("[workspace] Removed border from %s pane: %p", ctx.paneType, node)
266+ // Only remove if it actually has the class (prevents redundant GTK operations)
267+ if hasActiveClass {
268+ ctx.borderContainer.Execute(func(containerPtr uintptr) error {
269+ webkit.WidgetRemoveCSSClass(containerPtr, activePaneClass)
270+ return nil
271+ })
272+ log.Printf("[workspace] Removed border from %s pane: %p", ctx.paneType, node)
273+ }
274+ }
253275 }
254276
255277 // removeActivePaneBorderFromAll removes active pane borders from all containers using centralized system
@@ -221,14 +221,26 @@ func (wm *WorkspaceManager) applyActivePaneBorder(node *paneNode) {
221 221
222 // Apply CSS classes to border container (provides border styling)222 // Apply CSS classes to border container (provides border styling)
223 if ctx.borderContainer != nil {223 if ctx.borderContainer != nil {
224+ // Check if this container already has the active class to avoid redundant operations
225+ var alreadyActive bool
224 ctx.borderContainer.Execute(func(containerPtr uintptr) error {226 ctx.borderContainer.Execute(func(containerPtr uintptr) error {
225- // Only add the active class - base classes should already be set227+ // Safety check: verify container pointer is valid
226- webkit.WidgetAddCSSClass(containerPtr, activePaneClass)228+ if containerPtr == 0 {
229+ return fmt.Errorf("invalid container pointer")
230+ }
231+ alreadyActive = webkit.WidgetHasCSSClass(containerPtr, activePaneClass)
227 return nil232 return nil
228 })233 })
229- }
230 234
231- log.Printf("[workspace] Applied border to %s pane: %p", ctx.paneType, node)235+ // Only apply if not already active (prevents redundant GTK operations)
236+ if !alreadyActive {
237+ ctx.borderContainer.Execute(func(containerPtr uintptr) error {
238+ webkit.WidgetAddCSSClass(containerPtr, activePaneClass)
239+ return nil
240+ })
241+ log.Printf("[workspace] Applied border to %s pane: %p", ctx.paneType, node)
242+ }
243+ }
232 }244 }
233 245
234 // removeActivePaneBorder removes the active pane visual border using the centralized system246 // removeActivePaneBorder removes the active pane visual border using the centralized system
@@ -240,16 +252,26 @@ func (wm *WorkspaceManager) removeActivePaneBorder(node *paneNode) {
240 252
241 // Remove CSS classes from border container253 // Remove CSS classes from border container
242 if ctx.borderContainer != nil {254 if ctx.borderContainer != nil {
255+ // Check if this container has the active class before attempting removal
256+ var hasActiveClass bool
243 ctx.borderContainer.Execute(func(containerPtr uintptr) error {257 ctx.borderContainer.Execute(func(containerPtr uintptr) error {
244- // Only remove the active class if it exists258+ // Safety check: verify container pointer is valid
245- if webkit.WidgetHasCSSClass(containerPtr, activePaneClass) {259+ if containerPtr == 0 {
246- webkit.WidgetRemoveCSSClass(containerPtr, activePaneClass)260+ return fmt.Errorf("invalid container pointer")
247 }261 }
262+ hasActiveClass = webkit.WidgetHasCSSClass(containerPtr, activePaneClass)
248 return nil263 return nil
249 })264 })
250- }
251 265
252- log.Printf("[workspace] Removed border from %s pane: %p", ctx.paneType, node)266+ // Only remove if it actually has the class (prevents redundant GTK operations)
267+ if hasActiveClass {
268+ ctx.borderContainer.Execute(func(containerPtr uintptr) error {
269+ webkit.WidgetRemoveCSSClass(containerPtr, activePaneClass)
270+ return nil
271+ })
272+ log.Printf("[workspace] Removed border from %s pane: %p", ctx.paneType, node)
273+ }
274+ }
253 }275 }
254 276
255 // removeActivePaneBorderFromAll removes active pane borders from all containers using centralized system277 // removeActivePaneBorderFromAll removes active pane borders from all containers using centralized system

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