forked from joejulian/gio
app: [Wayland] handle multiple global registry event orders
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>
This commit is contained in:
+15
-9
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user