detached b655271

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 VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
3 files · +19 -13
M .golangci.yml +4 -2
@@ -149,10 +149,12 @@ linters:
149149 - text: "G304:"
150150 linters:
151151 - gosec
152- - text: "G703:"
152+ - path: internal/bootstrap/session\.go
153+ text: "G703:"
153154 linters:
154155 - gosec
155- - text: "G704:"
156+ - path: internal/infrastructure/updater/github\.go
157+ text: "G704:"
156158 linters:
157159 - gosec
158160 # GTK callbacks require unused parameters
@@ -149,10 +149,12 @@ linters:
149 - text: "G304:"149 - text: "G304:"
150 linters:150 linters:
151 - gosec151 - gosec
152- - text: "G703:"152+ - path: internal/bootstrap/session\.go
153+ text: "G703:"
153 linters:154 linters:
154 - gosec155 - gosec
155- - text: "G704:"156+ - path: internal/infrastructure/updater/github\.go
157+ text: "G704:"
156 linters:158 linters:
157 - gosec159 - gosec
158 # GTK callbacks require unused parameters160 # GTK callbacks require unused parameters
M internal/infrastructure/webkit/handlers/register.go +1 -4
@@ -11,7 +11,6 @@ import (
1111 "github.com/bnema/dumber/internal/infrastructure/config"
1212 "github.com/bnema/dumber/internal/infrastructure/webkit"
1313 "github.com/bnema/dumber/internal/infrastructure/webkit/handlers/homepage"
14- "github.com/bnema/dumber/internal/logging"
1514 )
1615
1716 // AccentKeyHandler is implemented by the InsertAccentUseCase to receive
@@ -73,7 +72,7 @@ func RegisterAll(ctx context.Context, router *webkit.MessageRouter, cfg Config)
7372
7473 // RegisterAccentHandlers registers accent key press/release handlers with the router.
7574 // 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 {
7776 if router == nil {
7877 return fmt.Errorf("RegisterAccentHandlers: router must not be nil")
7978 }
@@ -116,8 +115,6 @@ func RegisterAccentHandlers(ctx context.Context, router *webkit.MessageRouter, h
116115 return err
117116 }
118117
119- log := logging.FromContext(ctx)
120- log.Info().Msg("registered accent key handlers")
121118 return nil
122119 }
123120
@@ -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 receive16 // 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 err115 return err
117 }116 }
118 117
119- log := logging.FromContext(ctx)
120- log.Info().Msg("registered accent key handlers")
121 return nil118 return nil
122 }119 }
123 120
M internal/ui/app.go +14 -7
@@ -555,6 +555,8 @@ func (a *App) registerAccentHandlers(ctx context.Context) {
555555
556556 if err := handlers.RegisterAccentHandlers(ctx, a.router, a.insertAccentUC); err != nil {
557557 log.Error().Err(err).Msg("failed to register accent handlers")
558+ } else {
559+ log.Info().Msg("registered accent key handlers")
558560 }
559561 }
560562
@@ -669,14 +671,19 @@ func (a *App) initKeyboardHandler(ctx context.Context) {
669671 return input.RouteHandleShortcuts
670672 }
671673
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
678686 }
679- return input.RoutePassToWidget
680687 }
681688
682689 // 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.RouteHandleShortcuts671 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 to675+ // visible after focus returns to the WebView, so visibility alone
674- // shortcuts (pane navigation), other keys pass through to the widget's676+ // 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.RouteHandleShortcuts679+ // 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,

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close