~eliasnaur/gio-patches

gio: app/internal/wm: use Option method to initialize windows v1 PROPOSED

~pierrec
~pierrec: 1
 app/internal/wm: use Option method to initialize windows

 10 files changed, 207 insertions(+), 110 deletions(-)
#475705 apple.yml success
#475706 freebsd.yml success
#475707 linux.yml success
#475708 openbsd.yml success
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~eliasnaur/gio-patches/patches/21748/mbox | git am -3
Learn more about email & git
View this thread in the archives

[PATCH gio] app/internal/wm: use Option method to initialize windows Export this patch

~pierrec
From: pierre <pierre.curto@gmail.com>

Added (*w.window).Option methods to the backends and use them for setting the initial options passed into NewWindow.

Signed-off-by: pierre <pierre.curto@gmail.com>
---
-

 app/internal/windows/windows.go | 17 ++++++-
 app/internal/wm/os_android.go   |  2 +
 app/internal/wm/os_ios.go       |  2 +
 app/internal/wm/os_js.go        | 10 ++--
 app/internal/wm/os_macos.go     | 90 ++++++++++++++++++++-------------
 app/internal/wm/os_macos.m      | 25 ++++++++-
 app/internal/wm/os_wayland.go   | 24 +++++----
 app/internal/wm/os_windows.go   | 66 +++++++++++++++---------
 app/internal/wm/os_x11.go       | 78 +++++++++++++++-------------
 app/internal/wm/window.go       |  3 ++
 10 files changed, 207 insertions(+), 110 deletions(-)

diff --git a/app/internal/windows/windows.go b/app/internal/windows/windows.go
index 1601172e..8af575e7 100644
--- a/app/internal/windows/windows.go
+++ b/app/internal/windows/windows.go
@@ -271,6 +271,7 @@ var (
	_LoadImage                   = user32.NewProc("LoadImageW")
	_MonitorFromPoint            = user32.NewProc("MonitorFromPoint")
	_MonitorFromWindow           = user32.NewProc("MonitorFromWindow")
	_MoveWindow                  = user32.NewProc("MoveWindow")
	_MsgWaitForMultipleObjectsEx = user32.NewProc("MsgWaitForMultipleObjectsEx")
	_OpenClipboard               = user32.NewProc("OpenClipboard")
	_PeekMessage                 = user32.NewProc("PeekMessageW")
@@ -289,8 +290,9 @@ var (
	_SetProcessDPIAware          = user32.NewProc("SetProcessDPIAware")
	_SetTimer                    = user32.NewProc("SetTimer")
	_SetWindowLong               = user32.NewProc("SetWindowLongPtrW")
	_SetWindowPos                = user32.NewProc("SetWindowPos")
	_SetWindowPlacement          = user32.NewProc("SetWindowPlacement")
	_SetWindowPos                = user32.NewProc("SetWindowPos")
	_SetWindowText               = user32.NewProc("SetWindowTextW")
	_TranslateMessage            = user32.NewProc("TranslateMessage")
	_UnregisterClass             = user32.NewProc("UnregisterClassW")
	_UpdateWindow                = user32.NewProc("UpdateWindow")
@@ -486,6 +488,11 @@ func SetWindowPos(hwnd syscall.Handle, hwndInsertAfter uint32, x, y, dx, dy int3
	)
}

func SetWindowText(hwnd syscall.Handle, title string) {
	wname := syscall.StringToUTF16Ptr(title)
	_SetWindowText.Call(uintptr(hwnd), uintptr(unsafe.Pointer(wname)))
}

func GlobalAlloc(size int) (syscall.Handle, error) {
	r, _, err := _GlobalAlloc.Call(GHND, uintptr(size))
	if r == 0 {
@@ -534,6 +541,14 @@ func LoadImage(hInst syscall.Handle, res uint32, typ uint32, cx, cy int, fuload
	return syscall.Handle(h), nil
}

func MoveWindow(hwnd syscall.Handle, x, y, width, height int32, repaint bool) {
	var paint uintptr
	if repaint {
		paint = TRUE
	}
	_MoveWindow.Call(uintptr(hwnd), uintptr(x), uintptr(y), uintptr(width), uintptr(height), paint)
}

func monitorFromPoint(pt Point, flags uint32) syscall.Handle {
	r, _, _ := _MonitorFromPoint.Call(uintptr(pt.X), uintptr(pt.Y), uintptr(flags))
	return syscall.Handle(r)
diff --git a/app/internal/wm/os_android.go b/app/internal/wm/os_android.go
index 3b463cdf..287ef5bf 100644
--- a/app/internal/wm/os_android.go
+++ b/app/internal/wm/os_android.go
@@ -676,6 +676,8 @@ func (w *window) ReadClipboard() {
	})
}

func (w *window) Option(opts *Options) {}

func (w *window) SetCursor(name pointer.CursorName) {
	w.setState(func(state *windowState) {
		state.cursor = &name
diff --git a/app/internal/wm/os_ios.go b/app/internal/wm/os_ios.go
index a5d023a5..1730af2c 100644
--- a/app/internal/wm/os_ios.go
+++ b/app/internal/wm/os_ios.go
@@ -239,6 +239,8 @@ func (w *window) WriteClipboard(s string) {
	})
}

func (w *window) Option(opts *Options) {}

func (w *window) SetAnimating(anim bool) {
	v := w.view
	if v == 0 {
diff --git a/app/internal/wm/os_js.go b/app/internal/wm/os_js.go
index 7eb627b9..b24419a7 100644
--- a/app/internal/wm/os_js.go
+++ b/app/internal/wm/os_js.go
@@ -82,9 +82,7 @@ func NewWindow(win Callbacks, opts *Options) error {
	})
	w.addEventListeners()
	w.addHistory()
	if o := opts.WindowMode; o != nil {
		w.windowMode(*o)
	}
	w.Option(opts)
	w.w = win

	go func() {
@@ -476,6 +474,12 @@ func (w *window) WriteClipboard(s string) {
	w.clipboard.Call("writeText", s)
}

func (w *window) Option(opts *Options) {
	if o := opts.WindowMode; o != nil {
		w.windowMode(*o)
	}
}

func (w *window) SetCursor(name pointer.CursorName) {
	style := w.cnv.Get("style")
	style.Set("cursor", string(name))
diff --git a/app/internal/wm/os_macos.go b/app/internal/wm/os_macos.go
index b82c8d0f..d088a924 100644
--- a/app/internal/wm/os_macos.go
+++ b/app/internal/wm/os_macos.go
@@ -46,6 +46,10 @@ __attribute__ ((visibility ("hidden"))) CFTypeRef gio_createWindow(CFTypeRef vie
__attribute__ ((visibility ("hidden"))) void gio_makeKeyAndOrderFront(CFTypeRef windowRef);
__attribute__ ((visibility ("hidden"))) NSPoint gio_cascadeTopLeftFromPoint(CFTypeRef windowRef, NSPoint topLeft);
__attribute__ ((visibility ("hidden"))) void gio_close(CFTypeRef windowRef);
__attribute__ ((visibility ("hidden"))) void gio_setSize(CFTypeRef windowRef, CGFloat width, CGFloat height);
__attribute__ ((visibility ("hidden"))) void gio_setMinSize(CFTypeRef windowRef, CGFloat width, CGFloat height);
__attribute__ ((visibility ("hidden"))) void gio_setMaxSize(CFTypeRef windowRef, CGFloat width, CGFloat height);
__attribute__ ((visibility ("hidden"))) void gio_setTitle(CFTypeRef windowRef, const char *title);
*/
import "C"

@@ -126,6 +130,45 @@ func (w *window) WriteClipboard(s string) {
	})
}

func (w *window) Option(opts *Options) {
	w.runOnMain(func() {
		screenScale := float32(C.gio_getScreenBackingScale())
		cfg := configFor(screenScale)
		val := func(v unit.Value) float32 {
			return float32(cfg.Px(v)) / screenScale
		}
		if o := opts.Size; o != nil {
			width := val(o.Width)
			height := val(o.Height)
			if width > 0 || height > 0 {
				C.gio_setSize(w.window, C.CGFloat(width), C.CGFloat(height))
			}
		}
		if o := opts.MinSize; o != nil {
			width := val(o.Width)
			height := val(o.Height)
			if width > 0 || height > 0 {
				C.gio_setMinSize(w.window, C.CGFloat(width), C.CGFloat(height))
			}
		}
		if o := opts.MaxSize; o != nil {
			width := val(o.Width)
			height := val(o.Height)
			if width > 0 || height > 0 {
				C.gio_setMaxSize(w.window, C.CGFloat(width), C.CGFloat(height))
			}
		}
		if o := opts.Title; o != nil {
			title := C.CString(*o)
			defer C.free(unsafe.Pointer(title))
			C.gio_setTitle(w.window, title)
		}
		if o := opts.WindowMode; o != nil {
			w.SetWindowMode(*o)
		}
	})
}

func (w *window) SetWindowMode(mode WindowMode) {
	switch mode {
	case w.mode:
@@ -150,16 +193,22 @@ func (w *window) SetAnimating(anim bool) {
	}
}

func (w *window) Close() {
func (w *window) runOnMain(f func()) {
	runOnMain(func() {
		// Make sure the view is still valid. The window might've been closed
		// during the switch to the main thread.
		if w.view != 0 {
			C.gio_close(w.window)
			f()
		}
	})
}

func (w *window) Close() {
	w.runOnMain(func() {
		C.gio_close(w.window)
	})
}

func (w *window) setStage(stage system.Stage) {
	if stage == w.stage {
		return
@@ -336,35 +385,11 @@ func NewWindow(win Callbacks, opts *Options) error {
			errch <- err
			return
		}
		screenScale := float32(C.gio_getScreenBackingScale())
		cfg := configFor(screenScale)
		// Window sizes is in unscaled screen coordinates, not device pixels.
		var width, height int
		if o := opts.Size; o != nil {
			width = int(float32(cfg.Px(o.Width)) / screenScale)
			height = int(float32(cfg.Px(o.Height)) / screenScale)
		}
		var minWidth, minHeight int
		if o := opts.MinSize; o != nil {
			minWidth = int(float32(cfg.Px(o.Width)) / screenScale)
			minHeight = int(float32(cfg.Px(o.Height)) / screenScale)
		}
		var maxWidth, maxHeight int
		if o := opts.MaxSize; o != nil {
			maxWidth = int(float32(cfg.Px(o.Width)) / screenScale)
			maxHeight = int(float32(cfg.Px(o.Height)) / screenScale)
		}
		var title string
		if o := opts.Title; o != nil {
			title = *o
		}
		ctitle := C.CString(title)
		defer C.free(unsafe.Pointer(ctitle))
		errch <- nil
		win.SetDriver(w)
		w.w = win
		w.window = C.gio_createWindow(w.view, ctitle, C.CGFloat(width), C.CGFloat(height),
			C.CGFloat(minWidth), C.CGFloat(minHeight), C.CGFloat(maxWidth), C.CGFloat(maxHeight))
		w.window = C.gio_createWindow(w.view, nil, 0, 0, 0, 0, 0, 0)
		w.Option(opts)
		if nextTopLeft.x == 0 && nextTopLeft.y == 0 {
			// cascadeTopLeftFromPoint treats (0, 0) as a no-op,
			// and just returns the offset we need for the first window.
@@ -372,9 +397,6 @@ func NewWindow(win Callbacks, opts *Options) error {
		}
		nextTopLeft = C.gio_cascadeTopLeftFromPoint(w.window, nextTopLeft)
		C.gio_makeKeyAndOrderFront(w.window)
		if o := opts.WindowMode; o != nil {
			w.SetWindowMode(*o)
		}
	})
	return <-errch
}
@@ -390,10 +412,8 @@ func newWindow(opts *Options) (*window, error) {
		scale: scale,
	}
	dl, err := NewDisplayLink(func() {
		runOnMain(func() {
			if w.view != 0 {
				C.gio_setNeedsDisplay(w.view)
			}
		w.runOnMain(func() {
			C.gio_setNeedsDisplay(w.view)
		})
	})
	w.displayLink = dl
diff --git a/app/internal/wm/os_macos.m b/app/internal/wm/os_macos.m
index 24c906cb..7980d532 100644
--- a/app/internal/wm/os_macos.m
+++ b/app/internal/wm/os_macos.m
@@ -191,7 +191,9 @@ CFTypeRef gio_createWindow(CFTypeRef viewRef, const char *title, CGFloat width,
			window.contentMaxSize = NSMakeSize(maxWidth, maxHeight);
		}
		[window setAcceptsMouseMovedEvents:YES];
		window.title = [NSString stringWithUTF8String: title];
		if (title != nil) {
		    window.title = [NSString stringWithUTF8String: title];
		}
		NSView *view = (__bridge NSView *)viewRef;
		[window setContentView:view];
		[window makeFirstResponder:view];
@@ -206,6 +208,27 @@ void gio_close(CFTypeRef windowRef) {
  [window performClose:nil];
}

void gio_setSize(CFTypeRef windowRef, CGFloat width, CGFloat height) {
  NSWindow* window = (__bridge NSWindow *)windowRef;
  NSSize size = NSMakeSize(width, height);
  [window setContentSize:size];
}

void gio_setMinSize(CFTypeRef windowRef, CGFloat width, CGFloat height) {
  NSWindow* window = (__bridge NSWindow *)windowRef;
  window.contentMinSize = NSMakeSize(width, height);
}

void gio_setMaxSize(CFTypeRef windowRef, CGFloat width, CGFloat height) {
  NSWindow* window = (__bridge NSWindow *)windowRef;
  window.contentMaxSize = NSMakeSize(width, height);
}

void gio_setTitle(CFTypeRef windowRef, const char *title) {
  NSWindow* window = (__bridge NSWindow *)windowRef;
  window.title = [NSString stringWithUTF8String: title];
}

@implementation GioAppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
	[[NSRunningApplication currentApplication] activateWithOptions:(NSApplicationActivateAllWindows | NSApplicationActivateIgnoringOtherApps)];
diff --git a/app/internal/wm/os_wayland.go b/app/internal/wm/os_wayland.go
index 4a52078c..1e8c59d9 100644
--- a/app/internal/wm/os_wayland.go
+++ b/app/internal/wm/os_wayland.go
@@ -357,17 +357,8 @@ func (d *wlDisplay) createNativeWindow(opts *Options) (*window, error) {
	C.xdg_surface_add_listener(w.wmSurf, &C.gio_xdg_surface_listener, unsafe.Pointer(w.surf))
	C.xdg_toplevel_add_listener(w.topLvl, &C.gio_xdg_toplevel_listener, unsafe.Pointer(w.surf))

	if o := opts.Title; o != nil {
		title := C.CString(*o)
		C.xdg_toplevel_set_title(w.topLvl, title)
		C.free(unsafe.Pointer(title))
	}
	w.Option(opts)

	_, _, cfg := w.config()
	if o := opts.Size; o != nil {
		w.width = cfg.Px(o.Width)
		w.height = cfg.Px(o.Height)
	}
	if d.decor != nil {
		// Request server side decorations.
		w.decor = C.zxdg_decoration_manager_v1_get_toplevel_decoration(d.decor, w.topLvl)
@@ -918,6 +909,19 @@ func (w *window) WriteClipboard(s string) {
	w.disp.wakeup()
}

func (w *window) Option(opts *Options) {
	_, _, cfg := w.config()
	if o := opts.Size; o != nil {
		w.width = cfg.Px(o.Width)
		w.height = cfg.Px(o.Height)
	}
	if o := opts.Title; o != nil {
		title := C.CString(*o)
		C.xdg_toplevel_set_title(w.topLvl, title)
		C.free(unsafe.Pointer(title))
	}
}

func (w *window) SetCursor(name pointer.CursorName) {
	if name == pointer.CursorNone {
		C.wl_pointer_set_cursor(w.disp.seat.pointer, w.serial, nil, 0, 0)
diff --git a/app/internal/wm/os_windows.go b/app/internal/wm/os_windows.go
index fe2daf4e..611c7cb0 100644
--- a/app/internal/wm/os_windows.go
+++ b/app/internal/wm/os_windows.go
@@ -116,15 +116,13 @@ func NewWindow(window Callbacks, opts *Options) error {
		w.w = window
		w.w.SetDriver(w)
		defer w.w.Event(system.DestroyEvent{})
		w.Option(opts)
		windows.ShowWindow(w.hwnd, windows.SW_SHOWDEFAULT)
		windows.SetForegroundWindow(w.hwnd)
		windows.SetFocus(w.hwnd)
		// Since the window class for the cursor is null,
		// set it here to show the cursor.
		w.SetCursor(pointer.CursorDefault)
		if o := opts.WindowMode; o != nil {
			w.SetWindowMode(*o)
		}
		if err := w.loop(); err != nil {
			panic(err)
		}
@@ -185,33 +183,15 @@ func createNativeWindow(opts *Options) (*window, error) {
	}
	dpi := windows.GetSystemDPI()
	cfg := configForDPI(dpi)
	var wr windows.Rect
	if o := opts.Size; o != nil {
		wr.Right = int32(cfg.Px(o.Width))
		wr.Bottom = int32(cfg.Px(o.Height))
	}
	dwStyle := uint32(windows.WS_OVERLAPPEDWINDOW)
	dwExStyle := uint32(windows.WS_EX_APPWINDOW | windows.WS_EX_WINDOWEDGE)
	deltas := winDeltas{
		width:  wr.Right,
		height: wr.Bottom,
	}
	windows.AdjustWindowRectEx(&wr, dwStyle, 0, dwExStyle)
	deltas.width = wr.Right - wr.Left - deltas.width
	deltas.height = wr.Bottom - wr.Top - deltas.height

	var title string
	if o := opts.Title; o != nil {
		title = *o
	}

	hwnd, err := windows.CreateWindowEx(dwExStyle,
		resources.class,
		title,
		"",
		dwStyle|windows.WS_CLIPSIBLINGS|windows.WS_CLIPCHILDREN,
		windows.CW_USEDEFAULT, windows.CW_USEDEFAULT,
		wr.Right-wr.Left,
		wr.Bottom-wr.Top,
		windows.CW_USEDEFAULT, windows.CW_USEDEFAULT,
		0,
		0,
		resources.handle,
@@ -222,7 +202,6 @@ func createNativeWindow(opts *Options) (*window, error) {
	w := &window{
		hwnd:   hwnd,
		minmax: getWindowConstraints(cfg, opts),
		deltas: deltas,
		opts:   opts,
	}
	w.hdc, err = windows.GetDC(hwnd)
@@ -540,6 +519,45 @@ func (w *window) readClipboard() error {
	return nil
}

func (w *window) Option(opts *Options) {
	if o := opts.Size; o != nil {
		dpi := windows.GetSystemDPI()
		cfg := configForDPI(dpi)
		width := int32(cfg.Px(o.Width))
		height := int32(cfg.Px(o.Height))

		// Include the window decorations.
		wr := windows.Rect{
			Right:  width,
			Bottom: height,
		}
		dwStyle := uint32(windows.WS_OVERLAPPEDWINDOW)
		dwExStyle := uint32(windows.WS_EX_APPWINDOW | windows.WS_EX_WINDOWEDGE)
		windows.AdjustWindowRectEx(&wr, dwStyle, 0, dwExStyle)

		dw, dh := width, height
		width = wr.Right - wr.Left
		height = wr.Bottom - wr.Top
		w.deltas.width = width - dw
		w.deltas.height = height - dh

		w.opts.Size = o
		windows.MoveWindow(w.hwnd, 0, 0, width, height, true)
	}
	if o := opts.MinSize; o != nil {
		w.opts.MinSize = o
	}
	if o := opts.MaxSize; o != nil {
		w.opts.MaxSize = o
	}
	if o := opts.Title; o != nil {
		windows.SetWindowText(w.hwnd, *opts.Title)
	}
	if o := opts.WindowMode; o != nil {
		w.SetWindowMode(*o)
	}
}

func (w *window) SetWindowMode(mode WindowMode) {
	// https://devblogs.microsoft.com/oldnewthing/20100412-00/?p=14353
	switch mode {
diff --git a/app/internal/wm/os_x11.go b/app/internal/wm/os_x11.go
index 671fd4a9..b921d468 100644
--- a/app/internal/wm/os_x11.go
+++ b/app/internal/wm/os_x11.go
@@ -123,6 +123,47 @@ func (w *x11Window) WriteClipboard(s string) {
	w.wakeup()
}

func (w *x11Window) Option(opts *Options) {
	dpy := w.x
	win := w.xw
	cfg := w.cfg
	var shints C.XSizeHints
	if o := opts.MinSize; o != nil {
		shints.min_width = C.int(cfg.Px(o.Width))
		shints.min_height = C.int(cfg.Px(o.Height))
		shints.flags = C.PMinSize
	}
	if o := opts.MaxSize; o != nil {
		shints.max_width = C.int(cfg.Px(o.Width))
		shints.max_height = C.int(cfg.Px(o.Height))
		shints.flags = shints.flags | C.PMaxSize
	}
	if shints.flags != 0 {
		C.XSetWMNormalHints(dpy, win, &shints)
	}

	var title string
	if o := opts.Title; o != nil {
		title = *o
	}
	ctitle := C.CString(title)
	defer C.free(unsafe.Pointer(ctitle))
	C.XStoreName(dpy, win, ctitle)
	// set _NET_WM_NAME as well for UTF-8 support in window title.
	C.XSetTextProperty(dpy, win,
		&C.XTextProperty{
			value:    (*C.uchar)(unsafe.Pointer(ctitle)),
			encoding: w.atoms.utf8string,
			format:   8,
			nitems:   C.ulong(len(title)),
		},
		w.atoms.wmName)

	if o := opts.WindowMode; o != nil {
		w.SetWindowMode(*o)
	}
}

func (w *x11Window) SetCursor(name pointer.CursorName) {
	switch name {
	case pointer.CursorNone:
@@ -607,21 +648,6 @@ func newX11Window(gioWin Callbacks, opts *Options) error {
	hints.flags = C.InputHint
	C.XSetWMHints(dpy, win, &hints)

	var shints C.XSizeHints
	if o := opts.MinSize; o != nil && (o.Width.V != 0 || o.Height.V != 0) {
		shints.min_width = C.int(cfg.Px(o.Width))
		shints.min_height = C.int(cfg.Px(o.Height))
		shints.flags = C.PMinSize
	}
	if o := opts.MaxSize; o != nil && (o.Width.V != 0 || o.Height.V != 0) {
		shints.max_width = C.int(cfg.Px(o.Width))
		shints.max_height = C.int(cfg.Px(o.Height))
		shints.flags = shints.flags | C.PMaxSize
	}
	if shints.flags != 0 {
		C.XSetWMNormalHints(dpy, win, &shints)
	}

	name := C.CString(filepath.Base(os.Args[0]))
	defer C.free(unsafe.Pointer(name))
	wmhints := C.XClassHint{name, name}
@@ -639,30 +665,10 @@ func newX11Window(gioWin Callbacks, opts *Options) error {
	w.atoms.wmState = w.atom("_NET_WM_STATE", false)
	w.atoms.wmStateFullscreen = w.atom("_NET_WM_STATE_FULLSCREEN", false)

	// set the name
	var title string
	if o := opts.Title; o != nil {
		title = *o
	}
	ctitle := C.CString(title)
	defer C.free(unsafe.Pointer(ctitle))
	C.XStoreName(dpy, win, ctitle)
	// set _NET_WM_NAME as well for UTF-8 support in window title.
	C.XSetTextProperty(dpy, win,
		&C.XTextProperty{
			value:    (*C.uchar)(unsafe.Pointer(ctitle)),
			encoding: w.atoms.utf8string,
			format:   8,
			nitems:   C.ulong(len(title)),
		},
		w.atoms.wmName)

	// extensions
	C.XSetWMProtocols(dpy, win, &w.atoms.evDelWindow, 1)

	if o := opts.WindowMode; o != nil {
		w.SetWindowMode(*o)
	}
	w.Option(opts)

	// make the window visible on the screen
	C.XMapWindow(dpy, win)
diff --git a/app/internal/wm/window.go b/app/internal/wm/window.go
index 7eb51f2d..168d4d6d 100644
--- a/app/internal/wm/window.go
+++ b/app/internal/wm/window.go
@@ -74,6 +74,9 @@ type Driver interface {
	// WriteClipboard requests a clipboard write.
	WriteClipboard(s string)

	// Option processes option changes.
	Option(opts *Options)

	// SetCursor updates the current cursor to name.
	SetCursor(name pointer.CursorName)

-- 
2.30.2
builds.sr.ht
gio/patches: SUCCESS in 36m10s

[app/internal/wm: use Option method to initialize windows][0] from [~pierrec][1]

[0]: https://lists.sr.ht/~eliasnaur/gio-patches/patches/21748
[1]: mailto:pierre.curto@gmail.com

✓ #475707 SUCCESS gio/patches/linux.yml   https://builds.sr.ht/~eliasnaur/job/475707
✓ #475708 SUCCESS gio/patches/openbsd.yml https://builds.sr.ht/~eliasnaur/job/475708
✓ #475706 SUCCESS gio/patches/freebsd.yml https://builds.sr.ht/~eliasnaur/job/475706
✓ #475705 SUCCESS gio/patches/apple.yml   https://builds.sr.ht/~eliasnaur/job/475705
Thanks, merged.

Elias