~eliasnaur/gio-patches

gio: app: support changing Window options at runtime v1 PROPOSED

~pierrec
~pierrec: 1
 app: support changing Window options at runtime

 5 files changed, 60 insertions(+), 3 deletions(-)
#478785 apple.yml success
#478786 freebsd.yml success
#478787 linux.yml success
#478788 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/21839/mbox | git am -3
Learn more about email & git
View this thread in the archives

[PATCH gio] app: support changing Window options at runtime Export this patch

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

A Window can now be requested to change its options after
it has been started via its Option method.

All options are supported on macOS, Windows and X11.
On Wayland, only the Size and Title options can be changed
at runtime.

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

 app/internal/wm/os_macos.go   |  5 ++---
 app/internal/wm/os_wayland.go |  2 ++
 app/internal/wm/os_windows.go | 13 +++++++++++++
 app/internal/wm/os_x11.go     | 32 ++++++++++++++++++++++++++++++++
 app/window.go                 | 11 +++++++++++
 5 files changed, 60 insertions(+), 3 deletions(-)

diff --git a/app/internal/wm/os_macos.go b/app/internal/wm/os_macos.go
index d088a924..b9266d83 100644
--- a/app/internal/wm/os_macos.go
+++ b/app/internal/wm/os_macos.go
@@ -172,11 +172,10 @@ func (w *window) Option(opts *Options) {
func (w *window) SetWindowMode(mode WindowMode) {
	switch mode {
	case w.mode:
		return
	case Fullscreen:
	case Windowed, Fullscreen:
		C.gio_toggleFullScreen(w.window)
		w.mode = mode
	}
	w.mode = mode
}

func (w *window) SetCursor(name pointer.CursorName) {
diff --git a/app/internal/wm/os_wayland.go b/app/internal/wm/os_wayland.go
index 1e8c59d9..25e86898 100644
--- a/app/internal/wm/os_wayland.go
+++ b/app/internal/wm/os_wayland.go
@@ -910,6 +910,8 @@ func (w *window) WriteClipboard(s string) {
}

func (w *window) Option(opts *Options) {
	w.mu.Lock()
	defer w.mu.Unlock()
	_, _, cfg := w.config()
	if o := opts.Size; o != nil {
		w.width = cfg.Px(o.Width)
diff --git a/app/internal/wm/os_windows.go b/app/internal/wm/os_windows.go
index 611c7cb0..94f0662d 100644
--- a/app/internal/wm/os_windows.go
+++ b/app/internal/wm/os_windows.go
@@ -66,6 +66,7 @@ type window struct {
const (
	_WM_REDRAW = windows.WM_USER + iota
	_WM_CURSOR
	_WM_OPTION
)

type gpuAPI struct {
@@ -317,6 +318,8 @@ func windowProc(hwnd syscall.Handle, msg uint32, wParam, lParam uintptr) uintptr
			windows.SetCursor(w.cursor)
			return windows.TRUE
		}
	case _WM_OPTION:
		w.setOptions()
	}

	return windows.DefWindowProc(hwnd, msg, wParam, lParam)
@@ -520,6 +523,16 @@ func (w *window) readClipboard() error {
}

func (w *window) Option(opts *Options) {
	w.opts = opts
	if err := windows.PostMessage(w.hwnd, _WM_OPTION, 0, 0); err != nil {
		panic(err)
	}
}

func (w *window) setOptions() {
	w.mu.Lock()
	defer w.mu.Unlock()
	opts := w.opts
	if o := opts.Size; o != nil {
		dpi := windows.GetSystemDPI()
		cfg := configForDPI(dpi)
diff --git a/app/internal/wm/os_x11.go b/app/internal/wm/os_x11.go
index b921d468..d149716d 100644
--- a/app/internal/wm/os_x11.go
+++ b/app/internal/wm/os_x11.go
@@ -98,6 +98,7 @@ type x11Window struct {
		content []byte
	}
	cursor pointer.CursorName
	mode   WindowMode
}

func (w *x11Window) SetAnimating(anim bool) {
@@ -124,6 +125,8 @@ func (w *x11Window) WriteClipboard(s string) {
}

func (w *x11Window) Option(opts *Options) {
	w.mu.Lock()
	defer w.mu.Unlock()
	dpy := w.x
	win := w.xw
	cfg := w.cfg
@@ -190,6 +193,8 @@ func (w *x11Window) SetCursor(name pointer.CursorName) {

func (w *x11Window) SetWindowMode(mode WindowMode) {
	switch mode {
	case w.mode:
		return
	case Windowed:
		C.XDeleteProperty(w.x, w.xw, w.atoms.wmStateFullscreen)
	case Fullscreen:
@@ -197,7 +202,34 @@ func (w *x11Window) SetWindowMode(mode WindowMode) {
			32, C.PropModeReplace,
			(*C.uchar)(unsafe.Pointer(&w.atoms.wmStateFullscreen)), 1,
		)
	default:
		return
	}
	w.mode = mode
	// "A Client wishing to change the state of a window MUST send
	//  a _NET_WM_STATE client message to the root window (see below)."
	var xev C.XEvent
	ev := (*C.XClientMessageEvent)(unsafe.Pointer(&xev))
	*ev = C.XClientMessageEvent{
		_type:        C.ClientMessage,
		display:      w.x,
		window:       w.xw,
		message_type: w.atoms.wmState,
		format:       32,
	}
	arr := (*[5]C.long)(unsafe.Pointer(&ev.data))
	arr[0] = 2 // _NET_WM_STATE_TOGGLE
	arr[1] = C.long(w.atoms.wmStateFullscreen)
	arr[2] = 0
	arr[3] = 1 // application
	arr[4] = 0
	C.XSendEvent(
		w.x,
		C.XDefaultRootWindow(w.x), // MUST be the root window
		C.False,
		C.SubstructureNotifyMask|C.SubstructureRedirectMask,
		&xev,
	)
}

func (w *x11Window) ShowTextInput(show bool) {}
diff --git a/app/window.go b/app/window.go
index e8f691a9..20ee8b07 100644
--- a/app/window.go
+++ b/app/window.go
@@ -211,6 +211,17 @@ func (w *Window) Invalidate() {
	}
}

// Option applies the options to the window.
func (w *Window) Option(opts ...Option) {
	go w.driverDo(func() {
		o := new(wm.Options)
		for _, opt := range opts {
			opt(o)
		}
		w.driver.Option(o)
	})
}

// ReadClipboard initiates a read of the clipboard in the form
// of a clipboard.Event. Multiple reads may be coalesced
// to a single event.
-- 
2.30.2
builds.sr.ht
gio/patches: SUCCESS in 20m23s

[app: support changing Window options at runtime][0] from [~pierrec][1]

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

✓ #478787 SUCCESS gio/patches/linux.yml   https://builds.sr.ht/~eliasnaur/job/478787
✓ #478786 SUCCESS gio/patches/freebsd.yml https://builds.sr.ht/~eliasnaur/job/478786
✓ #478788 SUCCESS gio/patches/openbsd.yml https://builds.sr.ht/~eliasnaur/job/478788
✓ #478785 SUCCESS gio/patches/apple.yml   https://builds.sr.ht/~eliasnaur/job/478785