feat(coordinator): wire gesture handler to webviews and keyboard dispatcher
- commit
- 1fe5ab80fe620637710e1c065213480676e7322d
- author
- brice · · 2025-12-16 22:54 UTC
- committer
- brice · · 2025-12-16 20:10 UTC
- parent
- dc03f2e
- signature
- unsigned
2 files · +26 -1
M internal/ui/app.go +5 -0
| @@ -320,6 +320,11 @@ func (a *App) initCoordinators(ctx context.Context) { | |||
| 320 | 320 | ) | |
| 321 | 321 | a.kbDispatcher.SetOnQuit(a.Quit) | |
| 322 | 322 | ||
| 323 | + | // Wire gesture handler to dispatcher (for mouse button 8/9 navigation) | |
| 324 | + | a.contentCoord.SetGestureActionHandler(func(ctx context.Context, action input.Action) error { | |
| 325 | + | return a.kbDispatcher.Dispatch(ctx, action) | |
| 326 | + | }) | |
| 327 | + | ||
| 323 | 328 | log.Debug().Msg("coordinators initialized") | |
| 324 | 329 | } | |
| 325 | 330 | ||
| @@ -320,6 +320,11 @@ func (a *App) initCoordinators(ctx context.Context) { | |||||
| 320 | ) | 320 | ) | ||
| 321 | a.kbDispatcher.SetOnQuit(a.Quit) | 321 | a.kbDispatcher.SetOnQuit(a.Quit) | ||
| 322 | 322 | ||||
| 323 | + | // Wire gesture handler to dispatcher (for mouse button 8/9 navigation) | |||
| 324 | + | a.contentCoord.SetGestureActionHandler(func(ctx context.Context, action input.Action) error { | |||
| 325 | + | return a.kbDispatcher.Dispatch(ctx, action) | |||
| 326 | + | }) | |||
| 327 | + | ||||
| 323 | log.Debug().Msg("coordinators initialized") | 328 | log.Debug().Msg("coordinators initialized") | ||
| 324 | } | 329 | } | ||
| 325 | 330 | ||||
M internal/ui/coordinator/content.go +21 -1
| @@ -11,6 +11,7 @@ import ( | |||
| 11 | 11 | "github.com/bnema/dumber/internal/logging" | |
| 12 | 12 | "github.com/bnema/dumber/internal/ui/cache" | |
| 13 | 13 | "github.com/bnema/dumber/internal/ui/component" | |
| 14 | + | "github.com/bnema/dumber/internal/ui/input" | |
| 14 | 15 | "github.com/bnema/dumber/internal/ui/layout" | |
| 15 | 16 | "github.com/jwijenbergh/puregotk/v4/gdk" | |
| 16 | 17 | ) | |
| @@ -36,6 +37,9 @@ type ContentCoordinator struct { | |||
| 36 | 37 | ||
| 37 | 38 | // Callback when title changes (for history persistence) | |
| 38 | 39 | onTitleUpdated func(ctx context.Context, paneID entity.PaneID, url, title string) | |
| 40 | + | ||
| 41 | + | // Gesture action handler for mouse button navigation | |
| 42 | + | gestureActionHandler input.ActionHandler | |
| 39 | 43 | } | |
| 40 | 44 | ||
| 41 | 45 | // NewContentCoordinator creates a new ContentCoordinator. | |
| @@ -67,6 +71,11 @@ func (c *ContentCoordinator) SetOnTitleUpdated(fn func(ctx context.Context, pane | |||
| 67 | 71 | c.onTitleUpdated = fn | |
| 68 | 72 | } | |
| 69 | 73 | ||
| 74 | + | // SetGestureActionHandler sets the callback for mouse button navigation gestures. | |
| 75 | + | func (c *ContentCoordinator) SetGestureActionHandler(handler input.ActionHandler) { | |
| 76 | + | c.gestureActionHandler = handler | |
| 77 | + | } | |
| 78 | + | ||
| 70 | 79 | // EnsureWebView acquires or reuses a WebView for the given pane. | |
| 71 | 80 | func (c *ContentCoordinator) EnsureWebView(ctx context.Context, paneID entity.PaneID) (*webkit.WebView, error) { | |
| 72 | 81 | log := logging.FromContext(ctx) | |
| @@ -174,6 +183,7 @@ func (c *ContentCoordinator) AttachToWorkspace(ctx context.Context, ws *entity.W | |||
| 174 | 183 | } | |
| 175 | 184 | ||
| 176 | 185 | // WrapWidget converts a WebView to a layout.Widget for embedding. | |
| 186 | + | // It also attaches gesture handlers for mouse button navigation. | |
| 177 | 187 | func (c *ContentCoordinator) WrapWidget(ctx context.Context, wv *webkit.WebView) layout.Widget { | |
| 178 | 188 | log := logging.FromContext(ctx) | |
| 179 | 189 | ||
| @@ -187,7 +197,17 @@ func (c *ContentCoordinator) WrapWidget(ctx context.Context, wv *webkit.WebView) | |||
| 187 | 197 | return nil | |
| 188 | 198 | } | |
| 189 | 199 | ||
| 190 | - | return c.widgetFactory.WrapWidget(>kView.Widget) | |
| 200 | + | widget := c.widgetFactory.WrapWidget(>kView.Widget) | |
| 201 | + | ||
| 202 | + | // Attach gesture handler for mouse button 8/9 navigation | |
| 203 | + | if widget != nil && c.gestureActionHandler != nil { | |
| 204 | + | gestureHandler := input.NewGestureHandler(ctx) | |
| 205 | + | gestureHandler.SetOnAction(c.gestureActionHandler) | |
| 206 | + | gestureHandler.AttachTo(widget.GtkWidget()) | |
| 207 | + | log.Debug().Msg("gesture handler attached to webview") | |
| 208 | + | } | |
| 209 | + | ||
| 210 | + | return widget | |
| 191 | 211 | } | |
| 192 | 212 | ||
| 193 | 213 | // ActiveWebView returns the WebView for the active pane. | |
| @@ -11,6 +11,7 @@ import ( | |||||
| 11 | "github.com/bnema/dumber/internal/logging" | 11 | "github.com/bnema/dumber/internal/logging" | ||
| 12 | "github.com/bnema/dumber/internal/ui/cache" | 12 | "github.com/bnema/dumber/internal/ui/cache" | ||
| 13 | "github.com/bnema/dumber/internal/ui/component" | 13 | "github.com/bnema/dumber/internal/ui/component" | ||
| 14 | + | "github.com/bnema/dumber/internal/ui/input" | |||
| 14 | "github.com/bnema/dumber/internal/ui/layout" | 15 | "github.com/bnema/dumber/internal/ui/layout" | ||
| 15 | "github.com/jwijenbergh/puregotk/v4/gdk" | 16 | "github.com/jwijenbergh/puregotk/v4/gdk" | ||
| 16 | ) | 17 | ) | ||
| @@ -36,6 +37,9 @@ type ContentCoordinator struct { | |||||
| 36 | 37 | ||||
| 37 | // Callback when title changes (for history persistence) | 38 | // Callback when title changes (for history persistence) | ||
| 38 | onTitleUpdated func(ctx context.Context, paneID entity.PaneID, url, title string) | 39 | onTitleUpdated func(ctx context.Context, paneID entity.PaneID, url, title string) | ||
| 40 | + | ||||
| 41 | + | // Gesture action handler for mouse button navigation | |||
| 42 | + | gestureActionHandler input.ActionHandler | |||
| 39 | } | 43 | } | ||
| 40 | 44 | ||||
| 41 | // NewContentCoordinator creates a new ContentCoordinator. | 45 | // NewContentCoordinator creates a new ContentCoordinator. | ||
| @@ -67,6 +71,11 @@ func (c *ContentCoordinator) SetOnTitleUpdated(fn func(ctx context.Context, pane | |||||
| 67 | c.onTitleUpdated = fn | 71 | c.onTitleUpdated = fn | ||
| 68 | } | 72 | } | ||
| 69 | 73 | ||||
| 74 | + | // SetGestureActionHandler sets the callback for mouse button navigation gestures. | |||
| 75 | + | func (c *ContentCoordinator) SetGestureActionHandler(handler input.ActionHandler) { | |||
| 76 | + | c.gestureActionHandler = handler | |||
| 77 | + | } | |||
| 78 | + | ||||
| 70 | // EnsureWebView acquires or reuses a WebView for the given pane. | 79 | // EnsureWebView acquires or reuses a WebView for the given pane. | ||
| 71 | func (c *ContentCoordinator) EnsureWebView(ctx context.Context, paneID entity.PaneID) (*webkit.WebView, error) { | 80 | func (c *ContentCoordinator) EnsureWebView(ctx context.Context, paneID entity.PaneID) (*webkit.WebView, error) { | ||
| 72 | log := logging.FromContext(ctx) | 81 | log := logging.FromContext(ctx) | ||
| @@ -174,6 +183,7 @@ func (c *ContentCoordinator) AttachToWorkspace(ctx context.Context, ws *entity.W | |||||
| 174 | } | 183 | } | ||
| 175 | 184 | ||||
| 176 | // WrapWidget converts a WebView to a layout.Widget for embedding. | 185 | // WrapWidget converts a WebView to a layout.Widget for embedding. | ||
| 186 | + | // It also attaches gesture handlers for mouse button navigation. | |||
| 177 | func (c *ContentCoordinator) WrapWidget(ctx context.Context, wv *webkit.WebView) layout.Widget { | 187 | func (c *ContentCoordinator) WrapWidget(ctx context.Context, wv *webkit.WebView) layout.Widget { | ||
| 178 | log := logging.FromContext(ctx) | 188 | log := logging.FromContext(ctx) | ||
| 179 | 189 | ||||
| @@ -187,7 +197,17 @@ func (c *ContentCoordinator) WrapWidget(ctx context.Context, wv *webkit.WebView) | |||||
| 187 | return nil | 197 | return nil | ||
| 188 | } | 198 | } | ||
| 189 | 199 | ||||
| 190 | - | return c.widgetFactory.WrapWidget(>kView.Widget) | 200 | + | widget := c.widgetFactory.WrapWidget(>kView.Widget) |
| 201 | + | ||||
| 202 | + | // Attach gesture handler for mouse button 8/9 navigation | |||
| 203 | + | if widget != nil && c.gestureActionHandler != nil { | |||
| 204 | + | gestureHandler := input.NewGestureHandler(ctx) | |||
| 205 | + | gestureHandler.SetOnAction(c.gestureActionHandler) | |||
| 206 | + | gestureHandler.AttachTo(widget.GtkWidget()) | |||
| 207 | + | log.Debug().Msg("gesture handler attached to webview") | |||
| 208 | + | } | |||
| 209 | + | ||||
| 210 | + | return widget | |||
| 191 | } | 211 | } | ||
| 192 | 212 | ||||
| 193 | // ActiveWebView returns the WebView for the active pane. | 213 | // ActiveWebView returns the WebView for the active pane. | ||