detached dc03f2e

feat(layout): add event controller support to widget interface

commit
dc03f2e0fd37c07a765d1a1aa948b148a19972e1
author
brice · · 2025-12-16 18:00 UTC
committer
brice · · 2025-12-16 17:45 UTC
parent
5252d9a
signature
unsigned
2 files · +24 -14
M internal/ui/layout/gtk_widgets.go +21 -14
@@ -54,8 +54,9 @@ func (w *gtkWidget) GetParent() Widget {
5454 return &gtkWidget{inner: parent}
5555 }
5656
57-func (w *gtkWidget) GetAllocatedWidth() int { return w.inner.GetAllocatedWidth() }
58-func (w *gtkWidget) GetAllocatedHeight() int { return w.inner.GetAllocatedHeight() }
57+func (w *gtkWidget) GetAllocatedWidth() int { return w.inner.GetAllocatedWidth() }
58+func (w *gtkWidget) GetAllocatedHeight() int { return w.inner.GetAllocatedHeight() }
59+func (w *gtkWidget) AddController(c *gtk.EventController) { w.inner.AddController(c) }
5960
6061 func (w *gtkWidget) ComputePoint(target Widget) (x, y float64, ok bool) {
6162 srcPoint := &graphene.Point{X: 0, Y: 0}
@@ -167,8 +168,9 @@ func (p *gtkPaned) AddTickCallback(callback func() bool) uint {
167168 return p.inner.AddTickCallback(&cb, 0, nil)
168169 }
169170
170-func (p *gtkPaned) GetAllocatedWidth() int { return p.inner.GetAllocatedWidth() }
171-func (p *gtkPaned) GetAllocatedHeight() int { return p.inner.GetAllocatedHeight() }
171+func (p *gtkPaned) GetAllocatedWidth() int { return p.inner.GetAllocatedWidth() }
172+func (p *gtkPaned) GetAllocatedHeight() int { return p.inner.GetAllocatedHeight() }
173+func (p *gtkPaned) AddController(c *gtk.EventController) { p.inner.AddController(c) }
172174
173175 func (p *gtkPaned) ComputePoint(target Widget) (x, y float64, ok bool) {
174176 srcPoint := &graphene.Point{X: 0, Y: 0}
@@ -271,8 +273,9 @@ func (b *gtkBox) GetSpacing() int { return b.inner.GetSpacing() }
271273 func (b *gtkBox) SetOrientation(o Orientation) { b.inner.SetOrientation(o) }
272274 func (b *gtkBox) GetOrientation() Orientation { return b.inner.GetOrientation() }
273275
274-func (b *gtkBox) GetAllocatedWidth() int { return b.inner.GetAllocatedWidth() }
275-func (b *gtkBox) GetAllocatedHeight() int { return b.inner.GetAllocatedHeight() }
276+func (b *gtkBox) GetAllocatedWidth() int { return b.inner.GetAllocatedWidth() }
277+func (b *gtkBox) GetAllocatedHeight() int { return b.inner.GetAllocatedHeight() }
278+func (b *gtkBox) AddController(c *gtk.EventController) { b.inner.AddController(c) }
276279
277280 func (b *gtkBox) ComputePoint(target Widget) (x, y float64, ok bool) {
278281 srcPoint := &graphene.Point{X: 0, Y: 0}
@@ -383,8 +386,9 @@ func (o *gtkOverlay) GetMeasureOverlay(overlay Widget) bool {
383386 return o.inner.GetMeasureOverlay(overlay.GtkWidget())
384387 }
385388
386-func (o *gtkOverlay) GetAllocatedWidth() int { return o.inner.GetAllocatedWidth() }
387-func (o *gtkOverlay) GetAllocatedHeight() int { return o.inner.GetAllocatedHeight() }
389+func (o *gtkOverlay) GetAllocatedWidth() int { return o.inner.GetAllocatedWidth() }
390+func (o *gtkOverlay) GetAllocatedHeight() int { return o.inner.GetAllocatedHeight() }
391+func (o *gtkOverlay) AddController(c *gtk.EventController) { o.inner.AddController(c) }
388392
389393 func (o *gtkOverlay) ComputePoint(target Widget) (x, y float64, ok bool) {
390394 srcPoint := &graphene.Point{X: 0, Y: 0}
@@ -444,8 +448,9 @@ func (l *gtkLabel) SetEllipsize(mode EllipsizeMode) { l.inner.SetEllipsize(pango
444448 func (l *gtkLabel) SetMaxWidthChars(n int) { l.inner.SetMaxWidthChars(n) }
445449 func (l *gtkLabel) SetXalign(x float32) { l.inner.SetXalign(x) }
446450
447-func (l *gtkLabel) GetAllocatedWidth() int { return l.inner.GetAllocatedWidth() }
448-func (l *gtkLabel) GetAllocatedHeight() int { return l.inner.GetAllocatedHeight() }
451+func (l *gtkLabel) GetAllocatedWidth() int { return l.inner.GetAllocatedWidth() }
452+func (l *gtkLabel) GetAllocatedHeight() int { return l.inner.GetAllocatedHeight() }
453+func (l *gtkLabel) AddController(c *gtk.EventController) { l.inner.AddController(c) }
449454
450455 func (l *gtkLabel) ComputePoint(target Widget) (x, y float64, ok bool) {
451456 srcPoint := &graphene.Point{X: 0, Y: 0}
@@ -524,8 +529,9 @@ func (btn *gtkButton) ConnectClicked(callback func()) uint32 {
524529 return btn.inner.ConnectClicked(&cb)
525530 }
526531
527-func (btn *gtkButton) GetAllocatedWidth() int { return btn.inner.GetAllocatedWidth() }
528-func (btn *gtkButton) GetAllocatedHeight() int { return btn.inner.GetAllocatedHeight() }
532+func (btn *gtkButton) GetAllocatedWidth() int { return btn.inner.GetAllocatedWidth() }
533+func (btn *gtkButton) GetAllocatedHeight() int { return btn.inner.GetAllocatedHeight() }
534+func (btn *gtkButton) AddController(c *gtk.EventController) { btn.inner.AddController(c) }
529535
530536 func (btn *gtkButton) ComputePoint(target Widget) (x, y float64, ok bool) {
531537 srcPoint := &graphene.Point{X: 0, Y: 0}
@@ -594,8 +600,9 @@ func (img *gtkImage) SetFromPaintable(p Paintable) {
594600 func (img *gtkImage) SetPixelSize(size int) { img.inner.SetPixelSize(size) }
595601 func (img *gtkImage) Clear() { img.inner.Clear() }
596602
597-func (img *gtkImage) GetAllocatedWidth() int { return img.inner.GetAllocatedWidth() }
598-func (img *gtkImage) GetAllocatedHeight() int { return img.inner.GetAllocatedHeight() }
603+func (img *gtkImage) GetAllocatedWidth() int { return img.inner.GetAllocatedWidth() }
604+func (img *gtkImage) GetAllocatedHeight() int { return img.inner.GetAllocatedHeight() }
605+func (img *gtkImage) AddController(c *gtk.EventController) { img.inner.AddController(c) }
599606
600607 func (img *gtkImage) ComputePoint(target Widget) (x, y float64, ok bool) {
601608 srcPoint := &graphene.Point{X: 0, Y: 0}
@@ -54,8 +54,9 @@ func (w *gtkWidget) GetParent() Widget {
54 return &gtkWidget{inner: parent}54 return &gtkWidget{inner: parent}
55 }55 }
56 56
57-func (w *gtkWidget) GetAllocatedWidth() int { return w.inner.GetAllocatedWidth() }57+func (w *gtkWidget) GetAllocatedWidth() int { return w.inner.GetAllocatedWidth() }
58-func (w *gtkWidget) GetAllocatedHeight() int { return w.inner.GetAllocatedHeight() }58+func (w *gtkWidget) GetAllocatedHeight() int { return w.inner.GetAllocatedHeight() }
59+func (w *gtkWidget) AddController(c *gtk.EventController) { w.inner.AddController(c) }
59 60
60 func (w *gtkWidget) ComputePoint(target Widget) (x, y float64, ok bool) {61 func (w *gtkWidget) ComputePoint(target Widget) (x, y float64, ok bool) {
61 srcPoint := &graphene.Point{X: 0, Y: 0}62 srcPoint := &graphene.Point{X: 0, Y: 0}
@@ -167,8 +168,9 @@ func (p *gtkPaned) AddTickCallback(callback func() bool) uint {
167 return p.inner.AddTickCallback(&cb, 0, nil)168 return p.inner.AddTickCallback(&cb, 0, nil)
168 }169 }
169 170
170-func (p *gtkPaned) GetAllocatedWidth() int { return p.inner.GetAllocatedWidth() }171+func (p *gtkPaned) GetAllocatedWidth() int { return p.inner.GetAllocatedWidth() }
171-func (p *gtkPaned) GetAllocatedHeight() int { return p.inner.GetAllocatedHeight() }172+func (p *gtkPaned) GetAllocatedHeight() int { return p.inner.GetAllocatedHeight() }
173+func (p *gtkPaned) AddController(c *gtk.EventController) { p.inner.AddController(c) }
172 174
173 func (p *gtkPaned) ComputePoint(target Widget) (x, y float64, ok bool) {175 func (p *gtkPaned) ComputePoint(target Widget) (x, y float64, ok bool) {
174 srcPoint := &graphene.Point{X: 0, Y: 0}176 srcPoint := &graphene.Point{X: 0, Y: 0}
@@ -271,8 +273,9 @@ func (b *gtkBox) GetSpacing() int { return b.inner.GetSpacing() }
271 func (b *gtkBox) SetOrientation(o Orientation) { b.inner.SetOrientation(o) }273 func (b *gtkBox) SetOrientation(o Orientation) { b.inner.SetOrientation(o) }
272 func (b *gtkBox) GetOrientation() Orientation { return b.inner.GetOrientation() }274 func (b *gtkBox) GetOrientation() Orientation { return b.inner.GetOrientation() }
273 275
274-func (b *gtkBox) GetAllocatedWidth() int { return b.inner.GetAllocatedWidth() }276+func (b *gtkBox) GetAllocatedWidth() int { return b.inner.GetAllocatedWidth() }
275-func (b *gtkBox) GetAllocatedHeight() int { return b.inner.GetAllocatedHeight() }277+func (b *gtkBox) GetAllocatedHeight() int { return b.inner.GetAllocatedHeight() }
278+func (b *gtkBox) AddController(c *gtk.EventController) { b.inner.AddController(c) }
276 279
277 func (b *gtkBox) ComputePoint(target Widget) (x, y float64, ok bool) {280 func (b *gtkBox) ComputePoint(target Widget) (x, y float64, ok bool) {
278 srcPoint := &graphene.Point{X: 0, Y: 0}281 srcPoint := &graphene.Point{X: 0, Y: 0}
@@ -383,8 +386,9 @@ func (o *gtkOverlay) GetMeasureOverlay(overlay Widget) bool {
383 return o.inner.GetMeasureOverlay(overlay.GtkWidget())386 return o.inner.GetMeasureOverlay(overlay.GtkWidget())
384 }387 }
385 388
386-func (o *gtkOverlay) GetAllocatedWidth() int { return o.inner.GetAllocatedWidth() }389+func (o *gtkOverlay) GetAllocatedWidth() int { return o.inner.GetAllocatedWidth() }
387-func (o *gtkOverlay) GetAllocatedHeight() int { return o.inner.GetAllocatedHeight() }390+func (o *gtkOverlay) GetAllocatedHeight() int { return o.inner.GetAllocatedHeight() }
391+func (o *gtkOverlay) AddController(c *gtk.EventController) { o.inner.AddController(c) }
388 392
389 func (o *gtkOverlay) ComputePoint(target Widget) (x, y float64, ok bool) {393 func (o *gtkOverlay) ComputePoint(target Widget) (x, y float64, ok bool) {
390 srcPoint := &graphene.Point{X: 0, Y: 0}394 srcPoint := &graphene.Point{X: 0, Y: 0}
@@ -444,8 +448,9 @@ func (l *gtkLabel) SetEllipsize(mode EllipsizeMode) { l.inner.SetEllipsize(pango
444 func (l *gtkLabel) SetMaxWidthChars(n int) { l.inner.SetMaxWidthChars(n) }448 func (l *gtkLabel) SetMaxWidthChars(n int) { l.inner.SetMaxWidthChars(n) }
445 func (l *gtkLabel) SetXalign(x float32) { l.inner.SetXalign(x) }449 func (l *gtkLabel) SetXalign(x float32) { l.inner.SetXalign(x) }
446 450
447-func (l *gtkLabel) GetAllocatedWidth() int { return l.inner.GetAllocatedWidth() }451+func (l *gtkLabel) GetAllocatedWidth() int { return l.inner.GetAllocatedWidth() }
448-func (l *gtkLabel) GetAllocatedHeight() int { return l.inner.GetAllocatedHeight() }452+func (l *gtkLabel) GetAllocatedHeight() int { return l.inner.GetAllocatedHeight() }
453+func (l *gtkLabel) AddController(c *gtk.EventController) { l.inner.AddController(c) }
449 454
450 func (l *gtkLabel) ComputePoint(target Widget) (x, y float64, ok bool) {455 func (l *gtkLabel) ComputePoint(target Widget) (x, y float64, ok bool) {
451 srcPoint := &graphene.Point{X: 0, Y: 0}456 srcPoint := &graphene.Point{X: 0, Y: 0}
@@ -524,8 +529,9 @@ func (btn *gtkButton) ConnectClicked(callback func()) uint32 {
524 return btn.inner.ConnectClicked(&cb)529 return btn.inner.ConnectClicked(&cb)
525 }530 }
526 531
527-func (btn *gtkButton) GetAllocatedWidth() int { return btn.inner.GetAllocatedWidth() }532+func (btn *gtkButton) GetAllocatedWidth() int { return btn.inner.GetAllocatedWidth() }
528-func (btn *gtkButton) GetAllocatedHeight() int { return btn.inner.GetAllocatedHeight() }533+func (btn *gtkButton) GetAllocatedHeight() int { return btn.inner.GetAllocatedHeight() }
534+func (btn *gtkButton) AddController(c *gtk.EventController) { btn.inner.AddController(c) }
529 535
530 func (btn *gtkButton) ComputePoint(target Widget) (x, y float64, ok bool) {536 func (btn *gtkButton) ComputePoint(target Widget) (x, y float64, ok bool) {
531 srcPoint := &graphene.Point{X: 0, Y: 0}537 srcPoint := &graphene.Point{X: 0, Y: 0}
@@ -594,8 +600,9 @@ func (img *gtkImage) SetFromPaintable(p Paintable) {
594 func (img *gtkImage) SetPixelSize(size int) { img.inner.SetPixelSize(size) }600 func (img *gtkImage) SetPixelSize(size int) { img.inner.SetPixelSize(size) }
595 func (img *gtkImage) Clear() { img.inner.Clear() }601 func (img *gtkImage) Clear() { img.inner.Clear() }
596 602
597-func (img *gtkImage) GetAllocatedWidth() int { return img.inner.GetAllocatedWidth() }603+func (img *gtkImage) GetAllocatedWidth() int { return img.inner.GetAllocatedWidth() }
598-func (img *gtkImage) GetAllocatedHeight() int { return img.inner.GetAllocatedHeight() }604+func (img *gtkImage) GetAllocatedHeight() int { return img.inner.GetAllocatedHeight() }
605+func (img *gtkImage) AddController(c *gtk.EventController) { img.inner.AddController(c) }
599 606
600 func (img *gtkImage) ComputePoint(target Widget) (x, y float64, ok bool) {607 func (img *gtkImage) ComputePoint(target Widget) (x, y float64, ok bool) {
601 srcPoint := &graphene.Point{X: 0, Y: 0}608 srcPoint := &graphene.Point{X: 0, Y: 0}
M internal/ui/layout/widgets.go +3 -0
@@ -61,6 +61,9 @@ type Widget interface {
6161
6262 // GTK interop - returns the underlying GTK widget for embedding
6363 GtkWidget() *gtk.Widget
64+
65+ // AddController adds an event controller to the widget
66+ AddController(controller *gtk.EventController)
6467 }
6568
6669 // PanedWidget wraps gtk.Paned for creating split views.
@@ -61,6 +61,9 @@ type Widget interface {
61 61
62 // GTK interop - returns the underlying GTK widget for embedding62 // GTK interop - returns the underlying GTK widget for embedding
63 GtkWidget() *gtk.Widget63 GtkWidget() *gtk.Widget
64+
65+ // AddController adds an event controller to the widget
66+ AddController(controller *gtk.EventController)
64 }67 }
65 68
66 // PanedWidget wraps gtk.Paned for creating split views.69 // PanedWidget wraps gtk.Paned for creating split views.

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