fix(input): use focus-based routing and narrow lint exclusions
- Replace visibility checks (IsOmniboxVisible/IsFindBarVisible) with focus-based type assertion on accentFocusProvider to fix misrouted keys when find bar is visible but unfocused - Scope G703/G704 gosec exclusions to specific files instead of global - Remove concrete logging dependency from RegisterAccentHandlers adapter, move log to composition root in app.go
- commit
- b6552717cfe9f1362a75f212f32e6d4cb062e620
- author
- brice · · 2026-03-12 06:16 UTC
- parent
- 3993b47
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
3 files · +19 -13
M .golangci.yml +4 -2
| @@ -149,10 +149,12 @@ linters: | |||
| 149 | 149 | - text: "G304:" | |
| 150 | 150 | linters: | |
| 151 | 151 | - gosec | |
| 152 | - | - text: "G703:" | |
| 152 | + | - path: internal/bootstrap/session\.go | |
| 153 | + | text: "G703:" | |
| 153 | 154 | linters: | |
| 154 | 155 | - gosec | |
| 155 | - | - text: "G704:" | |
| 156 | + | - path: internal/infrastructure/updater/github\.go | |
| 157 | + | text: "G704:" | |
| 156 | 158 | linters: | |
| 157 | 159 | - gosec | |
| 158 | 160 | # GTK callbacks require unused parameters | |
| @@ -149,10 +149,12 @@ linters: | |||||
| 149 | - text: "G304:" | 149 | - text: "G304:" | ||
| 150 | linters: | 150 | linters: | ||
| 151 | - gosec | 151 | - gosec | ||
| 152 | - | - text: "G703:" | 152 | + | - path: internal/bootstrap/session\.go |
| 153 | + | text: "G703:" | |||
| 153 | linters: | 154 | linters: | ||
| 154 | - gosec | 155 | - gosec | ||
| 155 | - | - text: "G704:" | 156 | + | - path: internal/infrastructure/updater/github\.go |
| 157 | + | text: "G704:" | |||
| 156 | linters: | 158 | linters: | ||
| 157 | - gosec | 159 | - gosec | ||
| 158 | # GTK callbacks require unused parameters | 160 | # GTK callbacks require unused parameters | ||
M internal/infrastructure/webkit/handlers/register.go +1 -4
| @@ -11,7 +11,6 @@ import ( | |||
| 11 | 11 | "github.com/bnema/dumber/internal/infrastructure/config" | |
| 12 | 12 | "github.com/bnema/dumber/internal/infrastructure/webkit" | |
| 13 | 13 | "github.com/bnema/dumber/internal/infrastructure/webkit/handlers/homepage" | |
| 14 | - | "github.com/bnema/dumber/internal/logging" | |
| 15 | 14 | ) | |
| 16 | 15 | ||
| 17 | 16 | // AccentKeyHandler is implemented by the InsertAccentUseCase to receive | |
| @@ -73,7 +72,7 @@ func RegisterAll(ctx context.Context, router *webkit.MessageRouter, cfg Config) | |||
| 73 | 72 | ||
| 74 | 73 | // RegisterAccentHandlers registers accent key press/release handlers with the router. | |
| 75 | 74 | // Must be called after the AccentKeyHandler is initialized (i.e., after initAccentPicker). | |
| 76 | - | func RegisterAccentHandlers(ctx context.Context, router *webkit.MessageRouter, handler AccentKeyHandler) error { | |
| 75 | + | func RegisterAccentHandlers(_ context.Context, router *webkit.MessageRouter, handler AccentKeyHandler) error { | |
| 77 | 76 | if router == nil { | |
| 78 | 77 | return fmt.Errorf("RegisterAccentHandlers: router must not be nil") | |
| 79 | 78 | } | |
| @@ -116,8 +115,6 @@ func RegisterAccentHandlers(ctx context.Context, router *webkit.MessageRouter, h | |||
| 116 | 115 | return err | |
| 117 | 116 | } | |
| 118 | 117 | ||
| 119 | - | log := logging.FromContext(ctx) | |
| 120 | - | log.Info().Msg("registered accent key handlers") | |
| 121 | 118 | return nil | |
| 122 | 119 | } | |
| 123 | 120 | ||
| @@ -11,7 +11,6 @@ import ( | |||||
| 11 | "github.com/bnema/dumber/internal/infrastructure/config" | 11 | "github.com/bnema/dumber/internal/infrastructure/config" | ||
| 12 | "github.com/bnema/dumber/internal/infrastructure/webkit" | 12 | "github.com/bnema/dumber/internal/infrastructure/webkit" | ||
| 13 | "github.com/bnema/dumber/internal/infrastructure/webkit/handlers/homepage" | 13 | "github.com/bnema/dumber/internal/infrastructure/webkit/handlers/homepage" | ||
| 14 | - | "github.com/bnema/dumber/internal/logging" | |||
| 15 | ) | 14 | ) | ||
| 16 | 15 | ||||
| 17 | // AccentKeyHandler is implemented by the InsertAccentUseCase to receive | 16 | // AccentKeyHandler is implemented by the InsertAccentUseCase to receive | ||
| @@ -73,7 +72,7 @@ func RegisterAll(ctx context.Context, router *webkit.MessageRouter, cfg Config) | |||||
| 73 | 72 | ||||
| 74 | // RegisterAccentHandlers registers accent key press/release handlers with the router. | 73 | // RegisterAccentHandlers registers accent key press/release handlers with the router. | ||
| 75 | // Must be called after the AccentKeyHandler is initialized (i.e., after initAccentPicker). | 74 | // Must be called after the AccentKeyHandler is initialized (i.e., after initAccentPicker). | ||
| 76 | - | func RegisterAccentHandlers(ctx context.Context, router *webkit.MessageRouter, handler AccentKeyHandler) error { | 75 | + | func RegisterAccentHandlers(_ context.Context, router *webkit.MessageRouter, handler AccentKeyHandler) error { |
| 77 | if router == nil { | 76 | if router == nil { | ||
| 78 | return fmt.Errorf("RegisterAccentHandlers: router must not be nil") | 77 | return fmt.Errorf("RegisterAccentHandlers: router must not be nil") | ||
| 79 | } | 78 | } | ||
| @@ -116,8 +115,6 @@ func RegisterAccentHandlers(ctx context.Context, router *webkit.MessageRouter, h | |||||
| 116 | return err | 115 | return err | ||
| 117 | } | 116 | } | ||
| 118 | 117 | ||||
| 119 | - | log := logging.FromContext(ctx) | |||
| 120 | - | log.Info().Msg("registered accent key handlers") | |||
| 121 | return nil | 118 | return nil | ||
| 122 | } | 119 | } | ||
| 123 | 120 | ||||
M internal/ui/app.go +14 -7
| @@ -555,6 +555,8 @@ func (a *App) registerAccentHandlers(ctx context.Context) { | |||
| 555 | 555 | ||
| 556 | 556 | if err := handlers.RegisterAccentHandlers(ctx, a.router, a.insertAccentUC); err != nil { | |
| 557 | 557 | log.Error().Err(err).Msg("failed to register accent handlers") | |
| 558 | + | } else { | |
| 559 | + | log.Info().Msg("registered accent key handlers") | |
| 558 | 560 | } | |
| 559 | 561 | } | |
| 560 | 562 | ||
| @@ -669,14 +671,19 @@ func (a *App) initKeyboardHandler(ctx context.Context) { | |||
| 669 | 671 | return input.RouteHandleShortcuts | |
| 670 | 672 | } | |
| 671 | 673 | ||
| 672 | - | if wsView.IsOmniboxVisible() || wsView.IsFindBarVisible() { | |
| 673 | - | // GTK Entry focused (omnibox or find bar): Alt-modified keys go to | |
| 674 | - | // shortcuts (pane navigation), other keys pass through to the widget's | |
| 675 | - | // own capture-phase key controller (which handles accent detection) | |
| 676 | - | if kc.Modifiers&input.ModAlt != 0 { | |
| 677 | - | return input.RouteHandleShortcuts | |
| 674 | + | // Check actual focus rather than visibility: find bar can remain | |
| 675 | + | // visible after focus returns to the WebView, so visibility alone | |
| 676 | + | // would misroute keys. | |
| 677 | + | if a.accentFocusProvider != nil { | |
| 678 | + | if _, ok := a.accentFocusProvider.GetFocusedInput().(*textinput.GTKEntryTarget); ok { | |
| 679 | + | // GTK Entry focused (omnibox or find bar): Alt-modified keys go to | |
| 680 | + | // shortcuts (pane navigation), other keys pass through to the widget's | |
| 681 | + | // own capture-phase key controller (which handles accent detection) | |
| 682 | + | if kc.Modifiers&input.ModAlt != 0 { | |
| 683 | + | return input.RouteHandleShortcuts | |
| 684 | + | } | |
| 685 | + | return input.RoutePassToWidget | |
| 678 | 686 | } | |
| 679 | - | return input.RoutePassToWidget | |
| 680 | 687 | } | |
| 681 | 688 | ||
| 682 | 689 | // WebView focused: text/dead keys pass through for native IM compose, | |
| @@ -555,6 +555,8 @@ func (a *App) registerAccentHandlers(ctx context.Context) { | |||||
| 555 | 555 | ||||
| 556 | if err := handlers.RegisterAccentHandlers(ctx, a.router, a.insertAccentUC); err != nil { | 556 | if err := handlers.RegisterAccentHandlers(ctx, a.router, a.insertAccentUC); err != nil { | ||
| 557 | log.Error().Err(err).Msg("failed to register accent handlers") | 557 | log.Error().Err(err).Msg("failed to register accent handlers") | ||
| 558 | + | } else { | |||
| 559 | + | log.Info().Msg("registered accent key handlers") | |||
| 558 | } | 560 | } | ||
| 559 | } | 561 | } | ||
| 560 | 562 | ||||
| @@ -669,14 +671,19 @@ func (a *App) initKeyboardHandler(ctx context.Context) { | |||||
| 669 | return input.RouteHandleShortcuts | 671 | return input.RouteHandleShortcuts | ||
| 670 | } | 672 | } | ||
| 671 | 673 | ||||
| 672 | - | if wsView.IsOmniboxVisible() || wsView.IsFindBarVisible() { | 674 | + | // Check actual focus rather than visibility: find bar can remain |
| 673 | - | // GTK Entry focused (omnibox or find bar): Alt-modified keys go to | 675 | + | // visible after focus returns to the WebView, so visibility alone |
| 674 | - | // shortcuts (pane navigation), other keys pass through to the widget's | 676 | + | // would misroute keys. |
| 675 | - | // own capture-phase key controller (which handles accent detection) | 677 | + | if a.accentFocusProvider != nil { |
| 676 | - | if kc.Modifiers&input.ModAlt != 0 { | 678 | + | if _, ok := a.accentFocusProvider.GetFocusedInput().(*textinput.GTKEntryTarget); ok { |
| 677 | - | return input.RouteHandleShortcuts | 679 | + | // GTK Entry focused (omnibox or find bar): Alt-modified keys go to |
| 680 | + | // shortcuts (pane navigation), other keys pass through to the widget's | |||
| 681 | + | // own capture-phase key controller (which handles accent detection) | |||
| 682 | + | if kc.Modifiers&input.ModAlt != 0 { | |||
| 683 | + | return input.RouteHandleShortcuts | |||
| 684 | + | } | |||
| 685 | + | return input.RoutePassToWidget | |||
| 678 | } | 686 | } | ||
| 679 | - | return input.RoutePassToWidget | |||
| 680 | } | 687 | } | ||
| 681 | 688 | ||||
| 682 | // WebView focused: text/dead keys pass through for native IM compose, | 689 | // WebView focused: text/dead keys pass through for native IM compose, | ||