workspace_hover.go RawHistoryFolder
1// workspace_hover.go - Hover handler management for workspace panes
2package browser
3
4import (
5 "fmt"
6
7 "github.com/bnema/dumber/internal/logging"
8 "github.com/bnema/dumber/pkg/webkit"
9 "github.com/diamondburned/gotk4/pkg/glib/v2"
10)
11
12// ensureHover attaches hover handlers to a pane node for mouse-based focus changes
13func (wm *WorkspaceManager) ensureHover(node *paneNode) {
14 if wm == nil || node == nil || !node.isLeaf {
15 return
16 }
17
18 // Skip if already attached or no container
19 if node.container == nil || node.hoverToken != nil {
20 return
21 }
22
23 // Attach hover handler to the pane container
24 controller := webkit.WidgetAddHoverHandler(node.container, func() {
25 if wm == nil || node == nil {
26 return
27 }
28
29 // Skip if this pane is already active to avoid redundant focus churn.
30 if wm.GetActiveNode() == node {
31 return
32 }
33
34 // Debounce hover events to prevent rapid focus changes (minimum 150ms between hover-triggered focus changes)
35 now := glib.GetMonotonicTime()
36 if node.lastHoverTime > 0 && (now-node.lastHoverTime) < 150000 { // 150ms in microseconds
37 return
38 }
39 node.lastHoverTime = now
40
41 // Request focus change when mouse enters the pane
42 wm.SetActivePane(node, SourceMouse)
43 })
44
45 if controller != nil {
46 node.hoverToken = controller
47 logging.Debug(fmt.Sprintf("[workspace] Attached hover handler to pane %p (controller=%p)", node, controller))
48 } else {
49 logging.Error(fmt.Sprintf("[workspace] Failed to attach hover handler to pane %p", node))
50 }
51}
52
53// detachHover removes hover handlers from a pane node
54func (wm *WorkspaceManager) detachHover(node *paneNode) {
55 if wm == nil || node == nil || node.hoverToken == nil {
56 return
57 }
58
59 if node.container == nil {
60 node.hoverToken = nil
61 return
62 }
63
64 webkit.WidgetRemoveHoverHandler(node.container, node.hoverToken)
65 logging.Debug(fmt.Sprintf("[workspace] Detached hover handler from pane %p (controller=%p)", node, node.hoverToken))
66 node.hoverToken = nil
67}
68
69// attachHoverHandlersToAllPanes attaches hover handlers to all leaf panes
70func (wm *WorkspaceManager) attachHoverHandlersToAllPanes() {
71 if wm == nil {
72 return
73 }
74
75 leaves := wm.collectLeaves()
76 for _, leaf := range leaves {
77 wm.ensureHover(leaf)
78 }
79
80 logging.Debug(fmt.Sprintf("[workspace] Attached hover handlers to %d panes", len(leaves)))
81}