refactor(input): pass context as first parameter in keyboard and modal handlers
Remove stored ctx and logger fields from KeyboardHandler and ModalState. Update all methods (EnterTabMode, EnterPaneMode, ExitMode, AttachTo) to accept context as first parameter, following project convention of using log := logging.FromContext(ctx) in each method. KeyboardHandler keeps ctx field for GTK callback requirements.
- commit
- 39222bfc29e7df6c74d98b9bc55c1a8d860faeff
- author
- brice · · 2025-12-17 06:44 UTC
- parent
- 7a7144e
- signature
- unsigned
2 files · +27 -24
M internal/ui/input/keyboard.go +18 -15
| @@ -30,9 +30,8 @@ type KeyboardHandler struct { | |||
| 30 | 30 | // GTK controller (nil until attached) | |
| 31 | 31 | controller *gtk.EventControllerKey | |
| 32 | 32 | ||
| 33 | - | ctx context.Context | |
| 34 | - | logger zerolog.Logger | |
| 35 | - | mu sync.RWMutex | |
| 33 | + | ctx context.Context | |
| 34 | + | mu sync.RWMutex | |
| 36 | 35 | } | |
| 37 | 36 | ||
| 38 | 37 | // NewKeyboardHandler creates a new keyboard handler. | |
| @@ -42,12 +41,13 @@ func NewKeyboardHandler( | |||
| 42 | 41 | ) *KeyboardHandler { | |
| 43 | 42 | log := logging.FromContext(ctx) | |
| 44 | 43 | ||
| 44 | + | log.Debug().Msg("creating keyboard handler") | |
| 45 | + | ||
| 45 | 46 | h := &KeyboardHandler{ | |
| 46 | 47 | shortcuts: NewShortcutSet(ctx, cfg), | |
| 47 | 48 | modal: NewModalState(ctx), | |
| 48 | 49 | cfg: cfg, | |
| 49 | 50 | ctx: ctx, | |
| 50 | - | logger: log.With().Str("component", "keyboard-handler").Logger(), | |
| 51 | 51 | } | |
| 52 | 52 | ||
| 53 | 53 | return h | |
| @@ -73,14 +73,16 @@ func (h *KeyboardHandler) Mode() Mode { | |||
| 73 | 73 | // AttachTo attaches the keyboard handler to a GTK window. | |
| 74 | 74 | // The handler will intercept key events in the capture phase. | |
| 75 | 75 | func (h *KeyboardHandler) AttachTo(window *gtk.ApplicationWindow) { | |
| 76 | + | log := logging.FromContext(h.ctx) | |
| 77 | + | ||
| 76 | 78 | if window == nil { | |
| 77 | - | h.logger.Error().Msg("cannot attach keyboard handler to nil window") | |
| 79 | + | log.Error().Msg("cannot attach keyboard handler to nil window") | |
| 78 | 80 | return | |
| 79 | 81 | } | |
| 80 | 82 | ||
| 81 | 83 | h.controller = gtk.NewEventControllerKey() | |
| 82 | 84 | if h.controller == nil { | |
| 83 | - | h.logger.Error().Msg("failed to create event controller key") | |
| 85 | + | log.Error().Msg("failed to create event controller key") | |
| 84 | 86 | return | |
| 85 | 87 | } | |
| 86 | 88 | ||
| @@ -96,7 +98,7 @@ func (h *KeyboardHandler) AttachTo(window *gtk.ApplicationWindow) { | |||
| 96 | 98 | // Add controller to window | |
| 97 | 99 | window.AddController(&h.controller.EventController) | |
| 98 | 100 | ||
| 99 | - | h.logger.Debug().Msg("keyboard handler attached to window") | |
| 101 | + | log.Debug().Msg("keyboard handler attached to window") | |
| 100 | 102 | } | |
| 101 | 103 | ||
| 102 | 104 | // Detach removes the keyboard handler. | |
| @@ -134,16 +136,16 @@ func (h *KeyboardHandler) handleKeyPress(keyval uint, keycode uint, state gdk.Mo | |||
| 134 | 136 | switch action { | |
| 135 | 137 | case ActionEnterTabMode: | |
| 136 | 138 | timeout := time.Duration(h.cfg.TabMode.TimeoutMilliseconds) * time.Millisecond | |
| 137 | - | h.modal.EnterTabMode(timeout) | |
| 139 | + | h.modal.EnterTabMode(h.ctx, timeout) | |
| 138 | 140 | return true | |
| 139 | 141 | ||
| 140 | 142 | case ActionEnterPaneMode: | |
| 141 | 143 | timeout := time.Duration(h.cfg.PaneMode.TimeoutMilliseconds) * time.Millisecond | |
| 142 | - | h.modal.EnterPaneMode(timeout) | |
| 144 | + | h.modal.EnterPaneMode(h.ctx, timeout) | |
| 143 | 145 | return true | |
| 144 | 146 | ||
| 145 | 147 | case ActionExitMode: | |
| 146 | - | h.modal.ExitMode() | |
| 148 | + | h.modal.ExitMode(h.ctx) | |
| 147 | 149 | return true | |
| 148 | 150 | } | |
| 149 | 151 | ||
| @@ -154,7 +156,8 @@ func (h *KeyboardHandler) handleKeyPress(keyval uint, keycode uint, state gdk.Mo | |||
| 154 | 156 | ||
| 155 | 157 | if handler != nil { | |
| 156 | 158 | if err := handler(h.ctx, action); err != nil { | |
| 157 | - | h.logger.Error(). | |
| 159 | + | log := logging.FromContext(h.ctx) | |
| 160 | + | log.Error(). | |
| 158 | 161 | Err(err). | |
| 159 | 162 | Str("action", string(action)). | |
| 160 | 163 | Msg("action handler error") | |
| @@ -163,7 +166,7 @@ func (h *KeyboardHandler) handleKeyPress(keyval uint, keycode uint, state gdk.Mo | |||
| 163 | 166 | ||
| 164 | 167 | // Auto-exit modal mode after certain actions | |
| 165 | 168 | if mode != ModeNormal && ShouldAutoExitMode(action) { | |
| 166 | - | h.modal.ExitMode() | |
| 169 | + | h.modal.ExitMode(h.ctx) | |
| 167 | 170 | } | |
| 168 | 171 | ||
| 169 | 172 | return true // Consumed the key | |
| @@ -173,18 +176,18 @@ func (h *KeyboardHandler) handleKeyPress(keyval uint, keycode uint, state gdk.Mo | |||
| 173 | 176 | // Useful for testing or programmatic mode changes. | |
| 174 | 177 | func (h *KeyboardHandler) EnterTabMode() { | |
| 175 | 178 | timeout := time.Duration(h.cfg.TabMode.TimeoutMilliseconds) * time.Millisecond | |
| 176 | - | h.modal.EnterTabMode(timeout) | |
| 179 | + | h.modal.EnterTabMode(h.ctx, timeout) | |
| 177 | 180 | } | |
| 178 | 181 | ||
| 179 | 182 | // EnterPaneMode programmatically enters pane mode. | |
| 180 | 183 | // Useful for testing or programmatic mode changes. | |
| 181 | 184 | func (h *KeyboardHandler) EnterPaneMode() { | |
| 182 | 185 | timeout := time.Duration(h.cfg.PaneMode.TimeoutMilliseconds) * time.Millisecond | |
| 183 | - | h.modal.EnterPaneMode(timeout) | |
| 186 | + | h.modal.EnterPaneMode(h.ctx, timeout) | |
| 184 | 187 | } | |
| 185 | 188 | ||
| 186 | 189 | // ExitMode programmatically exits modal mode. | |
| 187 | 190 | // Useful for testing or programmatic mode changes. | |
| 188 | 191 | func (h *KeyboardHandler) ExitMode() { | |
| 189 | - | h.modal.ExitMode() | |
| 192 | + | h.modal.ExitMode(h.ctx) | |
| 190 | 193 | } | |
| @@ -30,9 +30,8 @@ type KeyboardHandler struct { | |||||
| 30 | // GTK controller (nil until attached) | 30 | // GTK controller (nil until attached) | ||
| 31 | controller *gtk.EventControllerKey | 31 | controller *gtk.EventControllerKey | ||
| 32 | 32 | ||||
| 33 | - | ctx context.Context | 33 | + | ctx context.Context |
| 34 | - | logger zerolog.Logger | 34 | + | mu sync.RWMutex |
| 35 | - | mu sync.RWMutex | |||
| 36 | } | 35 | } | ||
| 37 | 36 | ||||
| 38 | // NewKeyboardHandler creates a new keyboard handler. | 37 | // NewKeyboardHandler creates a new keyboard handler. | ||
| @@ -42,12 +41,13 @@ func NewKeyboardHandler( | |||||
| 42 | ) *KeyboardHandler { | 41 | ) *KeyboardHandler { | ||
| 43 | log := logging.FromContext(ctx) | 42 | log := logging.FromContext(ctx) | ||
| 44 | 43 | ||||
| 44 | + | log.Debug().Msg("creating keyboard handler") | |||
| 45 | + | ||||
| 45 | h := &KeyboardHandler{ | 46 | h := &KeyboardHandler{ | ||
| 46 | shortcuts: NewShortcutSet(ctx, cfg), | 47 | shortcuts: NewShortcutSet(ctx, cfg), | ||
| 47 | modal: NewModalState(ctx), | 48 | modal: NewModalState(ctx), | ||
| 48 | cfg: cfg, | 49 | cfg: cfg, | ||
| 49 | ctx: ctx, | 50 | ctx: ctx, | ||
| 50 | - | logger: log.With().Str("component", "keyboard-handler").Logger(), | |||
| 51 | } | 51 | } | ||
| 52 | 52 | ||||
| 53 | return h | 53 | return h | ||
| @@ -73,14 +73,16 @@ func (h *KeyboardHandler) Mode() Mode { | |||||
| 73 | // AttachTo attaches the keyboard handler to a GTK window. | 73 | // AttachTo attaches the keyboard handler to a GTK window. | ||
| 74 | // The handler will intercept key events in the capture phase. | 74 | // The handler will intercept key events in the capture phase. | ||
| 75 | func (h *KeyboardHandler) AttachTo(window *gtk.ApplicationWindow) { | 75 | func (h *KeyboardHandler) AttachTo(window *gtk.ApplicationWindow) { | ||
| 76 | + | log := logging.FromContext(h.ctx) | |||
| 77 | + | ||||
| 76 | if window == nil { | 78 | if window == nil { | ||
| 77 | - | h.logger.Error().Msg("cannot attach keyboard handler to nil window") | 79 | + | log.Error().Msg("cannot attach keyboard handler to nil window") |
| 78 | return | 80 | return | ||
| 79 | } | 81 | } | ||
| 80 | 82 | ||||
| 81 | h.controller = gtk.NewEventControllerKey() | 83 | h.controller = gtk.NewEventControllerKey() | ||
| 82 | if h.controller == nil { | 84 | if h.controller == nil { | ||
| 83 | - | h.logger.Error().Msg("failed to create event controller key") | 85 | + | log.Error().Msg("failed to create event controller key") |
| 84 | return | 86 | return | ||
| 85 | } | 87 | } | ||
| 86 | 88 | ||||
| @@ -96,7 +98,7 @@ func (h *KeyboardHandler) AttachTo(window *gtk.ApplicationWindow) { | |||||
| 96 | // Add controller to window | 98 | // Add controller to window | ||
| 97 | window.AddController(&h.controller.EventController) | 99 | window.AddController(&h.controller.EventController) | ||
| 98 | 100 | ||||
| 99 | - | h.logger.Debug().Msg("keyboard handler attached to window") | 101 | + | log.Debug().Msg("keyboard handler attached to window") |
| 100 | } | 102 | } | ||
| 101 | 103 | ||||
| 102 | // Detach removes the keyboard handler. | 104 | // Detach removes the keyboard handler. | ||
| @@ -134,16 +136,16 @@ func (h *KeyboardHandler) handleKeyPress(keyval uint, keycode uint, state gdk.Mo | |||||
| 134 | switch action { | 136 | switch action { | ||
| 135 | case ActionEnterTabMode: | 137 | case ActionEnterTabMode: | ||
| 136 | timeout := time.Duration(h.cfg.TabMode.TimeoutMilliseconds) * time.Millisecond | 138 | timeout := time.Duration(h.cfg.TabMode.TimeoutMilliseconds) * time.Millisecond | ||
| 137 | - | h.modal.EnterTabMode(timeout) | 139 | + | h.modal.EnterTabMode(h.ctx, timeout) |
| 138 | return true | 140 | return true | ||
| 139 | 141 | ||||
| 140 | case ActionEnterPaneMode: | 142 | case ActionEnterPaneMode: | ||
| 141 | timeout := time.Duration(h.cfg.PaneMode.TimeoutMilliseconds) * time.Millisecond | 143 | timeout := time.Duration(h.cfg.PaneMode.TimeoutMilliseconds) * time.Millisecond | ||
| 142 | - | h.modal.EnterPaneMode(timeout) | 144 | + | h.modal.EnterPaneMode(h.ctx, timeout) |
| 143 | return true | 145 | return true | ||
| 144 | 146 | ||||
| 145 | case ActionExitMode: | 147 | case ActionExitMode: | ||
| 146 | - | h.modal.ExitMode() | 148 | + | h.modal.ExitMode(h.ctx) |
| 147 | return true | 149 | return true | ||
| 148 | } | 150 | } | ||
| 149 | 151 | ||||
| @@ -154,7 +156,8 @@ func (h *KeyboardHandler) handleKeyPress(keyval uint, keycode uint, state gdk.Mo | |||||
| 154 | 156 | ||||
| 155 | if handler != nil { | 157 | if handler != nil { | ||
| 156 | if err := handler(h.ctx, action); err != nil { | 158 | if err := handler(h.ctx, action); err != nil { | ||
| 157 | - | h.logger.Error(). | 159 | + | log := logging.FromContext(h.ctx) |
| 160 | + | log.Error(). | |||
| 158 | Err(err). | 161 | Err(err). | ||
| 159 | Str("action", string(action)). | 162 | Str("action", string(action)). | ||
| 160 | Msg("action handler error") | 163 | Msg("action handler error") | ||
| @@ -163,7 +166,7 @@ func (h *KeyboardHandler) handleKeyPress(keyval uint, keycode uint, state gdk.Mo | |||||
| 163 | 166 | ||||
| 164 | // Auto-exit modal mode after certain actions | 167 | // Auto-exit modal mode after certain actions | ||
| 165 | if mode != ModeNormal && ShouldAutoExitMode(action) { | 168 | if mode != ModeNormal && ShouldAutoExitMode(action) { | ||
| 166 | - | h.modal.ExitMode() | 169 | + | h.modal.ExitMode(h.ctx) |
| 167 | } | 170 | } | ||
| 168 | 171 | ||||
| 169 | return true // Consumed the key | 172 | return true // Consumed the key | ||
| @@ -173,18 +176,18 @@ func (h *KeyboardHandler) handleKeyPress(keyval uint, keycode uint, state gdk.Mo | |||||
| 173 | // Useful for testing or programmatic mode changes. | 176 | // Useful for testing or programmatic mode changes. | ||
| 174 | func (h *KeyboardHandler) EnterTabMode() { | 177 | func (h *KeyboardHandler) EnterTabMode() { | ||
| 175 | timeout := time.Duration(h.cfg.TabMode.TimeoutMilliseconds) * time.Millisecond | 178 | timeout := time.Duration(h.cfg.TabMode.TimeoutMilliseconds) * time.Millisecond | ||
| 176 | - | h.modal.EnterTabMode(timeout) | 179 | + | h.modal.EnterTabMode(h.ctx, timeout) |
| 177 | } | 180 | } | ||
| 178 | 181 | ||||
| 179 | // EnterPaneMode programmatically enters pane mode. | 182 | // EnterPaneMode programmatically enters pane mode. | ||
| 180 | // Useful for testing or programmatic mode changes. | 183 | // Useful for testing or programmatic mode changes. | ||
| 181 | func (h *KeyboardHandler) EnterPaneMode() { | 184 | func (h *KeyboardHandler) EnterPaneMode() { | ||
| 182 | timeout := time.Duration(h.cfg.PaneMode.TimeoutMilliseconds) * time.Millisecond | 185 | timeout := time.Duration(h.cfg.PaneMode.TimeoutMilliseconds) * time.Millisecond | ||
| 183 | - | h.modal.EnterPaneMode(timeout) | 186 | + | h.modal.EnterPaneMode(h.ctx, timeout) |
| 184 | } | 187 | } | ||
| 185 | 188 | ||||
| 186 | // ExitMode programmatically exits modal mode. | 189 | // ExitMode programmatically exits modal mode. | ||
| 187 | // Useful for testing or programmatic mode changes. | 190 | // Useful for testing or programmatic mode changes. | ||
| 188 | func (h *KeyboardHandler) ExitMode() { | 191 | func (h *KeyboardHandler) ExitMode() { | ||
| 189 | - | h.modal.ExitMode() | 192 | + | h.modal.ExitMode(h.ctx) |
| 190 | } | 193 | } | ||
M internal/ui/input/modal.go +9 -9
| @@ -43,15 +43,15 @@ type ModalState struct { | |||
| 43 | 43 | // Callback for mode changes (called synchronously under lock). | |
| 44 | 44 | onModeChange func(from, to Mode) | |
| 45 | 45 | ||
| 46 | - | ctx context.Context | |
| 47 | - | mu sync.RWMutex | |
| 46 | + | mu sync.RWMutex | |
| 48 | 47 | } | |
| 49 | 48 | ||
| 50 | 49 | // NewModalState creates a new modal state manager. | |
| 51 | 50 | func NewModalState(ctx context.Context) *ModalState { | |
| 51 | + | log := logging.FromContext(ctx) | |
| 52 | + | log.Debug().Msg("creating modal state") | |
| 52 | 53 | return &ModalState{ | |
| 53 | 54 | mode: ModeNormal, | |
| 54 | - | ctx: ctx, | |
| 55 | 55 | } | |
| 56 | 56 | } | |
| 57 | 57 | ||
| @@ -64,8 +64,8 @@ func (m *ModalState) Mode() Mode { | |||
| 64 | 64 | ||
| 65 | 65 | // EnterTabMode switches to tab mode with an optional timeout. | |
| 66 | 66 | // If timeout is 0, the mode stays until explicitly exited. | |
| 67 | - | func (m *ModalState) EnterTabMode(timeout time.Duration) { | |
| 68 | - | log := logging.FromContext(m.ctx) | |
| 67 | + | func (m *ModalState) EnterTabMode(ctx context.Context, timeout time.Duration) { | |
| 68 | + | log := logging.FromContext(ctx) | |
| 69 | 69 | m.mu.Lock() | |
| 70 | 70 | defer m.mu.Unlock() | |
| 71 | 71 | ||
| @@ -99,8 +99,8 @@ func (m *ModalState) EnterTabMode(timeout time.Duration) { | |||
| 99 | 99 | ||
| 100 | 100 | // EnterPaneMode switches to pane mode with an optional timeout. | |
| 101 | 101 | // If timeout is 0, the mode stays until explicitly exited. | |
| 102 | - | func (m *ModalState) EnterPaneMode(timeout time.Duration) { | |
| 103 | - | log := logging.FromContext(m.ctx) | |
| 102 | + | func (m *ModalState) EnterPaneMode(ctx context.Context, timeout time.Duration) { | |
| 103 | + | log := logging.FromContext(ctx) | |
| 104 | 104 | m.mu.Lock() | |
| 105 | 105 | defer m.mu.Unlock() | |
| 106 | 106 | ||
| @@ -133,8 +133,8 @@ func (m *ModalState) EnterPaneMode(timeout time.Duration) { | |||
| 133 | 133 | } | |
| 134 | 134 | ||
| 135 | 135 | // ExitMode returns to normal mode. | |
| 136 | - | func (m *ModalState) ExitMode() { | |
| 137 | - | log := logging.FromContext(m.ctx) | |
| 136 | + | func (m *ModalState) ExitMode(ctx context.Context) { | |
| 137 | + | log := logging.FromContext(ctx) | |
| 138 | 138 | m.mu.Lock() | |
| 139 | 139 | defer m.mu.Unlock() | |
| 140 | 140 | ||
| @@ -43,15 +43,15 @@ type ModalState struct { | |||||
| 43 | // Callback for mode changes (called synchronously under lock). | 43 | // Callback for mode changes (called synchronously under lock). | ||
| 44 | onModeChange func(from, to Mode) | 44 | onModeChange func(from, to Mode) | ||
| 45 | 45 | ||||
| 46 | - | ctx context.Context | 46 | + | mu sync.RWMutex |
| 47 | - | mu sync.RWMutex | |||
| 48 | } | 47 | } | ||
| 49 | 48 | ||||
| 50 | // NewModalState creates a new modal state manager. | 49 | // NewModalState creates a new modal state manager. | ||
| 51 | func NewModalState(ctx context.Context) *ModalState { | 50 | func NewModalState(ctx context.Context) *ModalState { | ||
| 51 | + | log := logging.FromContext(ctx) | |||
| 52 | + | log.Debug().Msg("creating modal state") | |||
| 52 | return &ModalState{ | 53 | return &ModalState{ | ||
| 53 | mode: ModeNormal, | 54 | mode: ModeNormal, | ||
| 54 | - | ctx: ctx, | |||
| 55 | } | 55 | } | ||
| 56 | } | 56 | } | ||
| 57 | 57 | ||||
| @@ -64,8 +64,8 @@ func (m *ModalState) Mode() Mode { | |||||
| 64 | 64 | ||||
| 65 | // EnterTabMode switches to tab mode with an optional timeout. | 65 | // EnterTabMode switches to tab mode with an optional timeout. | ||
| 66 | // If timeout is 0, the mode stays until explicitly exited. | 66 | // If timeout is 0, the mode stays until explicitly exited. | ||
| 67 | - | func (m *ModalState) EnterTabMode(timeout time.Duration) { | 67 | + | func (m *ModalState) EnterTabMode(ctx context.Context, timeout time.Duration) { |
| 68 | - | log := logging.FromContext(m.ctx) | 68 | + | log := logging.FromContext(ctx) |
| 69 | m.mu.Lock() | 69 | m.mu.Lock() | ||
| 70 | defer m.mu.Unlock() | 70 | defer m.mu.Unlock() | ||
| 71 | 71 | ||||
| @@ -99,8 +99,8 @@ func (m *ModalState) EnterTabMode(timeout time.Duration) { | |||||
| 99 | 99 | ||||
| 100 | // EnterPaneMode switches to pane mode with an optional timeout. | 100 | // EnterPaneMode switches to pane mode with an optional timeout. | ||
| 101 | // If timeout is 0, the mode stays until explicitly exited. | 101 | // If timeout is 0, the mode stays until explicitly exited. | ||
| 102 | - | func (m *ModalState) EnterPaneMode(timeout time.Duration) { | 102 | + | func (m *ModalState) EnterPaneMode(ctx context.Context, timeout time.Duration) { |
| 103 | - | log := logging.FromContext(m.ctx) | 103 | + | log := logging.FromContext(ctx) |
| 104 | m.mu.Lock() | 104 | m.mu.Lock() | ||
| 105 | defer m.mu.Unlock() | 105 | defer m.mu.Unlock() | ||
| 106 | 106 | ||||
| @@ -133,8 +133,8 @@ func (m *ModalState) EnterPaneMode(timeout time.Duration) { | |||||
| 133 | } | 133 | } | ||
| 134 | 134 | ||||
| 135 | // ExitMode returns to normal mode. | 135 | // ExitMode returns to normal mode. | ||
| 136 | - | func (m *ModalState) ExitMode() { | 136 | + | func (m *ModalState) ExitMode(ctx context.Context) { |
| 137 | - | log := logging.FromContext(m.ctx) | 137 | + | log := logging.FromContext(ctx) |
| 138 | m.mu.Lock() | 138 | m.mu.Lock() | ||
| 139 | defer m.mu.Unlock() | 139 | defer m.mu.Unlock() | ||
| 140 | 140 | ||||