~eliasnaur/gio-patches

gio: app: [Wayland] handle multiple global registry event orders v1 PROPOSED

Chris Waldon: 1
 app: [Wayland] handle multiple global registry event orders

 1 files changed, 15 insertions(+), 9 deletions(-)
#782505 apple.yml success
#782506 freebsd.yml success
#782507 linux.yml success
#782508 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/33085/mbox | git am -3
Learn more about email & git

[PATCH gio] app: [Wayland] handle multiple global registry event orders Export this patch

Not all wayland compositors advertise the global registry events
in the same order. In particular, river and sway differ in that
sway advertises the data_device_manager before the seat, and river
does it after. This commit updates our code to correctly bind
the data_device so that we can work with the clipboard regardless
of the registry event order.

Special thanks to Isaac Freund (river maintainer) for helping me
find the root of this problem. You can see Isaac's extremely helpful
and detailed analysis here:

https://github.com/riverwm/river/issues/554#issuecomment-1059750874

Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
---
 app/os_wayland.go | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/app/os_wayland.go b/app/os_wayland.go
index 6fe5bb1e..ea2a4332 100644
--- a/app/os_wayland.go
+++ b/app/os_wayland.go
@@ -628,15 +628,7 @@ func gio_onRegistryGlobal(data unsafe.Pointer, reg *C.struct_wl_registry, name C
		}
		callbackStore(unsafe.Pointer(s), d.seat)
		C.wl_seat_add_listener(s, &C.gio_seat_listener, unsafe.Pointer(s))
		if d.dataDeviceManager == nil {
			break
		}
		d.seat.dataDev = C.wl_data_device_manager_get_data_device(d.dataDeviceManager, s)
		if d.seat.dataDev == nil {
			break
		}
		callbackStore(unsafe.Pointer(d.seat.dataDev), d.seat)
		C.wl_data_device_add_listener(d.seat.dataDev, &C.gio_data_device_listener, unsafe.Pointer(d.seat.dataDev))
		d.bindDataDevice()
	case "wl_shm":
		d.shm = (*C.struct_wl_shm)(C.wl_registry_bind(reg, name, &C.wl_shm_interface, 1))
	case "xdg_wm_base":
@@ -648,6 +640,7 @@ func gio_onRegistryGlobal(data unsafe.Pointer, reg *C.struct_wl_registry, name C
		d.imm = (*C.struct_zwp_text_input_manager_v3)(C.wl_registry_bind(reg, name, &C.zwp_text_input_manager_v3_interface, 1))*/
	case "wl_data_device_manager":
		d.dataDeviceManager = (*C.struct_wl_data_device_manager)(C.wl_registry_bind(reg, name, &C.wl_data_device_manager_interface, 3))
		d.bindDataDevice()
	}
}

@@ -1303,6 +1296,19 @@ func (w *window) loop() error {
	return nil
}

// bindDataDevice initializes the dataDev field if and only if both
// the seat and dataDeviceManager fields are initialized.
func (d *wlDisplay) bindDataDevice() {
	if d.seat != nil && d.dataDeviceManager != nil {
		d.seat.dataDev = C.wl_data_device_manager_get_data_device(d.dataDeviceManager, d.seat.seat)
		if d.seat.dataDev == nil {
			return
		}
		callbackStore(unsafe.Pointer(d.seat.dataDev), d.seat)
		C.wl_data_device_add_listener(d.seat.dataDev, &C.gio_data_device_listener, unsafe.Pointer(d.seat.dataDev))
	}
}

func (d *wlDisplay) dispatch(p *poller) error {
	dispfd := C.wl_display_get_fd(d.disp)
	// Poll for events and notifications.
-- 
2.36.1
gio/patches: SUCCESS in 21m28s

[app: [Wayland] handle multiple global registry event orders][0] from [Chris Waldon][1]

[0]: https://lists.sr.ht/~eliasnaur/gio-patches/patches/33085
[1]: mailto:christopher.waldon.dev@gmail.com

✓ #782507 SUCCESS gio/patches/linux.yml   https://builds.sr.ht/~eliasnaur/job/782507
✓ #782506 SUCCESS gio/patches/freebsd.yml https://builds.sr.ht/~eliasnaur/job/782506
✓ #782508 SUCCESS gio/patches/openbsd.yml https://builds.sr.ht/~eliasnaur/job/782508
✓ #782505 SUCCESS gio/patches/apple.yml   https://builds.sr.ht/~eliasnaur/job/782505
Thank you for digging into this. Merged.

Elias