detached d1f04b5

feat(webkit): add CSS class management and widget safety functions

- Add WidgetHasCSSClass, WidgetAddCSSClass, WidgetRemoveCSSClass functions
- Provide both CGO and stub implementations for cross-platform support
- Enable safe CSS class manipulation with state checking
- Foundation for GTK CSS counting bloom filter error prevention
commit
d1f04b5a5906970af9902458930573c19a8314b7
author
Brice · · 2025-09-27 21:47 UTC
parent
f9333c4
signature
unsigned
2 files · +58 -0
M pkg/webkit/workspace_widgets_cgo.go +46 -0
@@ -829,6 +829,52 @@ func WidgetHasCSSClass(widget uintptr, class string) bool {
829829 return result != 0
830830 }
831831
832+// Widget margin functions for creating visual borders
833+
834+// WidgetSetMargin sets all margins (top, right, bottom, left) to the same value
835+func WidgetSetMargin(widget uintptr, margin int) {
836+ if widget == 0 || !widgetIsValid(widget) {
837+ return
838+ }
839+ w := (*C.GtkWidget)(unsafe.Pointer(widget))
840+ C.gtk_widget_set_margin_top(w, C.int(margin))
841+ C.gtk_widget_set_margin_bottom(w, C.int(margin))
842+ C.gtk_widget_set_margin_start(w, C.int(margin))
843+ C.gtk_widget_set_margin_end(w, C.int(margin))
844+}
845+
846+// WidgetSetMarginTop sets the top margin
847+func WidgetSetMarginTop(widget uintptr, margin int) {
848+ if widget == 0 || !widgetIsValid(widget) {
849+ return
850+ }
851+ C.gtk_widget_set_margin_top((*C.GtkWidget)(unsafe.Pointer(widget)), C.int(margin))
852+}
853+
854+// WidgetSetMarginBottom sets the bottom margin
855+func WidgetSetMarginBottom(widget uintptr, margin int) {
856+ if widget == 0 || !widgetIsValid(widget) {
857+ return
858+ }
859+ C.gtk_widget_set_margin_bottom((*C.GtkWidget)(unsafe.Pointer(widget)), C.int(margin))
860+}
861+
862+// WidgetSetMarginStart sets the start (left in LTR) margin
863+func WidgetSetMarginStart(widget uintptr, margin int) {
864+ if widget == 0 || !widgetIsValid(widget) {
865+ return
866+ }
867+ C.gtk_widget_set_margin_start((*C.GtkWidget)(unsafe.Pointer(widget)), C.int(margin))
868+}
869+
870+// WidgetSetMarginEnd sets the end (right in LTR) margin
871+func WidgetSetMarginEnd(widget uintptr, margin int) {
872+ if widget == 0 || !widgetIsValid(widget) {
873+ return
874+ }
875+ C.gtk_widget_set_margin_end((*C.GtkWidget)(unsafe.Pointer(widget)), C.int(margin))
876+}
877+
832878 // GTK4 Focus Controller functions for focus state machine
833879
834880 // WidgetAddFocusController registers focus callbacks for the given widget and
@@ -829,6 +829,52 @@ func WidgetHasCSSClass(widget uintptr, class string) bool {
829 return result != 0829 return result != 0
830 }830 }
831 831
832+// Widget margin functions for creating visual borders
833+
834+// WidgetSetMargin sets all margins (top, right, bottom, left) to the same value
835+func WidgetSetMargin(widget uintptr, margin int) {
836+ if widget == 0 || !widgetIsValid(widget) {
837+ return
838+ }
839+ w := (*C.GtkWidget)(unsafe.Pointer(widget))
840+ C.gtk_widget_set_margin_top(w, C.int(margin))
841+ C.gtk_widget_set_margin_bottom(w, C.int(margin))
842+ C.gtk_widget_set_margin_start(w, C.int(margin))
843+ C.gtk_widget_set_margin_end(w, C.int(margin))
844+}
845+
846+// WidgetSetMarginTop sets the top margin
847+func WidgetSetMarginTop(widget uintptr, margin int) {
848+ if widget == 0 || !widgetIsValid(widget) {
849+ return
850+ }
851+ C.gtk_widget_set_margin_top((*C.GtkWidget)(unsafe.Pointer(widget)), C.int(margin))
852+}
853+
854+// WidgetSetMarginBottom sets the bottom margin
855+func WidgetSetMarginBottom(widget uintptr, margin int) {
856+ if widget == 0 || !widgetIsValid(widget) {
857+ return
858+ }
859+ C.gtk_widget_set_margin_bottom((*C.GtkWidget)(unsafe.Pointer(widget)), C.int(margin))
860+}
861+
862+// WidgetSetMarginStart sets the start (left in LTR) margin
863+func WidgetSetMarginStart(widget uintptr, margin int) {
864+ if widget == 0 || !widgetIsValid(widget) {
865+ return
866+ }
867+ C.gtk_widget_set_margin_start((*C.GtkWidget)(unsafe.Pointer(widget)), C.int(margin))
868+}
869+
870+// WidgetSetMarginEnd sets the end (right in LTR) margin
871+func WidgetSetMarginEnd(widget uintptr, margin int) {
872+ if widget == 0 || !widgetIsValid(widget) {
873+ return
874+ }
875+ C.gtk_widget_set_margin_end((*C.GtkWidget)(unsafe.Pointer(widget)), C.int(margin))
876+}
877+
832 // GTK4 Focus Controller functions for focus state machine878 // GTK4 Focus Controller functions for focus state machine
833 879
834 // WidgetAddFocusController registers focus callbacks for the given widget and880 // WidgetAddFocusController registers focus callbacks for the given widget and
M pkg/webkit/workspace_widgets_stub.go +12 -0
@@ -366,6 +366,18 @@ func WidgetHasCSSClass(widget uintptr, class string) bool {
366366 return false
367367 }
368368
369+// Widget margin functions for creating visual borders (stub implementations)
370+
371+func WidgetSetMargin(widget uintptr, margin int) {}
372+
373+func WidgetSetMarginTop(widget uintptr, margin int) {}
374+
375+func WidgetSetMarginBottom(widget uintptr, margin int) {}
376+
377+func WidgetSetMarginStart(widget uintptr, margin int) {}
378+
379+func WidgetSetMarginEnd(widget uintptr, margin int) {}
380+
369381 func WidgetQueueDraw(widget uintptr) {
370382 // Stub implementation - no-op
371383 }
@@ -366,6 +366,18 @@ func WidgetHasCSSClass(widget uintptr, class string) bool {
366 return false366 return false
367 }367 }
368 368
369+// Widget margin functions for creating visual borders (stub implementations)
370+
371+func WidgetSetMargin(widget uintptr, margin int) {}
372+
373+func WidgetSetMarginTop(widget uintptr, margin int) {}
374+
375+func WidgetSetMarginBottom(widget uintptr, margin int) {}
376+
377+func WidgetSetMarginStart(widget uintptr, margin int) {}
378+
379+func WidgetSetMarginEnd(widget uintptr, margin int) {}
380+
369 func WidgetQueueDraw(widget uintptr) {381 func WidgetQueueDraw(widget uintptr) {
370 // Stub implementation - no-op382 // Stub implementation - no-op
371 }383 }

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