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) { | |||
| 221 | 221 | ||
| 222 | 222 | // Apply CSS classes to border container (provides border styling) | |
| 223 | 223 | if ctx.borderContainer != nil { | |
| 224 | + | // Check if this container already has the active class to avoid redundant operations | |
| 225 | + | var alreadyActive bool | |
| 224 | 226 | 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) | |
| 227 | 232 | 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 | 246 | // removeActivePaneBorder removes the active pane visual border using the centralized system | |
| @@ -240,16 +252,26 @@ func (wm *WorkspaceManager) removeActivePaneBorder(node *paneNode) { | |||
| 240 | 252 | ||
| 241 | 253 | // Remove CSS classes from border container | |
| 242 | 254 | if ctx.borderContainer != nil { | |
| 255 | + | // Check if this container has the active class before attempting removal | |
| 256 | + | var hasActiveClass bool | |
| 243 | 257 | 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") | |
| 247 | 261 | } | |
| 262 | + | hasActiveClass = webkit.WidgetHasCSSClass(containerPtr, activePaneClass) | |
| 248 | 263 | 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 | 277 | // 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 set | 227 | + | // 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 nil | 232 | 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 system | 246 | // 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 container | 253 | // 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 exists | 258 | + | // 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 nil | 263 | 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 system | 277 | // removeActivePaneBorderFromAll removes active pane borders from all containers using centralized system | ||