fix(accent-picker): regain focus on mouse hover for escape to work
- commit
- 82bed3262731e4b2186c044601be22d542852e8b
- author
- brice · · 2025-12-29 17:50 UTC
- committer
- brice · · 2025-12-30 13:48 UTC
- parent
- 4372359
- signature
- unsigned
1 file · +23 -0
M internal/ui/component/accent_picker.go +23 -0
| @@ -76,6 +76,9 @@ func NewAccentPicker(factory layout.WidgetFactory) *AccentPicker { | |||
| 76 | 76 | // Set up key event handling | |
| 77 | 77 | ap.setupKeyboardHandling() | |
| 78 | 78 | ||
| 79 | + | // Set up hover-to-focus: regain focus when mouse enters | |
| 80 | + | ap.setupHoverFocus() | |
| 81 | + | ||
| 79 | 82 | return ap | |
| 80 | 83 | } | |
| 81 | 84 | ||
| @@ -209,6 +212,26 @@ func (ap *AccentPicker) setupKeyboardHandling() { | |||
| 209 | 212 | ap.container.AddController(&keyCtrl.EventController) | |
| 210 | 213 | } | |
| 211 | 214 | ||
| 215 | + | // setupHoverFocus sets up mouse hover to regain focus. | |
| 216 | + | // This ensures the picker regains focus when the mouse enters, | |
| 217 | + | // so keyboard navigation (including Escape) continues to work. | |
| 218 | + | func (ap *AccentPicker) setupHoverFocus() { | |
| 219 | + | motionCtrl := gtk.NewEventControllerMotion() | |
| 220 | + | ||
| 221 | + | enterCb := func(_ gtk.EventControllerMotion, _ float64, _ float64) { | |
| 222 | + | ap.mu.Lock() | |
| 223 | + | visible := ap.visible | |
| 224 | + | ap.mu.Unlock() | |
| 225 | + | ||
| 226 | + | if visible { | |
| 227 | + | ap.container.GrabFocus() | |
| 228 | + | } | |
| 229 | + | } | |
| 230 | + | ||
| 231 | + | motionCtrl.ConnectEnter(&enterCb) | |
| 232 | + | ap.container.AddController(&motionCtrl.EventController) | |
| 233 | + | } | |
| 234 | + | ||
| 212 | 235 | // handleKeyPress processes a key press event. | |
| 213 | 236 | // Returns true if the key was handled. | |
| 214 | 237 | func (ap *AccentPicker) handleKeyPress(keyval uint) bool { | |
| @@ -76,6 +76,9 @@ func NewAccentPicker(factory layout.WidgetFactory) *AccentPicker { | |||||
| 76 | // Set up key event handling | 76 | // Set up key event handling | ||
| 77 | ap.setupKeyboardHandling() | 77 | ap.setupKeyboardHandling() | ||
| 78 | 78 | ||||
| 79 | + | // Set up hover-to-focus: regain focus when mouse enters | |||
| 80 | + | ap.setupHoverFocus() | |||
| 81 | + | ||||
| 79 | return ap | 82 | return ap | ||
| 80 | } | 83 | } | ||
| 81 | 84 | ||||
| @@ -209,6 +212,26 @@ func (ap *AccentPicker) setupKeyboardHandling() { | |||||
| 209 | ap.container.AddController(&keyCtrl.EventController) | 212 | ap.container.AddController(&keyCtrl.EventController) | ||
| 210 | } | 213 | } | ||
| 211 | 214 | ||||
| 215 | + | // setupHoverFocus sets up mouse hover to regain focus. | |||
| 216 | + | // This ensures the picker regains focus when the mouse enters, | |||
| 217 | + | // so keyboard navigation (including Escape) continues to work. | |||
| 218 | + | func (ap *AccentPicker) setupHoverFocus() { | |||
| 219 | + | motionCtrl := gtk.NewEventControllerMotion() | |||
| 220 | + | ||||
| 221 | + | enterCb := func(_ gtk.EventControllerMotion, _ float64, _ float64) { | |||
| 222 | + | ap.mu.Lock() | |||
| 223 | + | visible := ap.visible | |||
| 224 | + | ap.mu.Unlock() | |||
| 225 | + | ||||
| 226 | + | if visible { | |||
| 227 | + | ap.container.GrabFocus() | |||
| 228 | + | } | |||
| 229 | + | } | |||
| 230 | + | ||||
| 231 | + | motionCtrl.ConnectEnter(&enterCb) | |||
| 232 | + | ap.container.AddController(&motionCtrl.EventController) | |||
| 233 | + | } | |||
| 234 | + | ||||
| 212 | // handleKeyPress processes a key press event. | 235 | // handleKeyPress processes a key press event. | ||
| 213 | // Returns true if the key was handled. | 236 | // Returns true if the key was handled. | ||
| 214 | func (ap *AccentPicker) handleKeyPress(keyval uint) bool { | 237 | func (ap *AccentPicker) handleKeyPress(keyval uint) bool { | ||