fix: compositor handles wl_data_device_manager and wl_subcompositor

- get_data_device: stores wl_data_device in client object map
- get_subsurface: stores wl_subsurface in client object map
- data_device/subsurface requests accepted silently (Qt6 needs
  these proxies to exist for initialization even though we don't
  implement clipboard or subsurface compositing yet)

Instrumentation confirmed: setupConnection() completes with valid
registry=0x44f230. Crash is in Qt6 global binding path during
forceRoundTrip(), not in compositor protocol handling.
This commit is contained in:
2026-05-06 13:29:23 +01:00
parent 962a2f1670
commit 6a5f569a27
@@ -401,6 +401,13 @@ const OBJECT_TYPE_WL_POINTER: u32 = 15;
const OBJECT_TYPE_WL_KEYBOARD: u32 = 16;
const OBJECT_TYPE_WL_DATA_DEVICE_MANAGER: u32 = 17;
const OBJECT_TYPE_WL_SUBCOMPOSITOR: u32 = 18;
const OBJECT_TYPE_WL_DATA_DEVICE: u32 = 19;
const OBJECT_TYPE_WL_SUBSURFACE: u32 = 20;
// wl_data_device_manager opcodes
const WL_DATA_DEVICE_MANAGER_GET_DATA_DEVICE: u16 = 1;
// wl_subcompositor opcodes
const WL_SUBCOMPOSITOR_GET_SUBSURFACE: u16 = 1;
struct Global {
name: u32,
@@ -1078,13 +1085,49 @@ impl Compositor {
| OBJECT_TYPE_XDG_TOPLEVEL
| OBJECT_TYPE_WL_POINTER
| OBJECT_TYPE_WL_KEYBOARD
| OBJECT_TYPE_WL_DATA_DEVICE_MANAGER
| OBJECT_TYPE_WL_SUBCOMPOSITOR => {
eprintln!(
"redbear-compositor: unhandled opcode {} on object {}",
opcode, object_id
);
}
| OBJECT_TYPE_WL_DATA_DEVICE_MANAGER => match opcode {
WL_DATA_DEVICE_MANAGER_GET_DATA_DEVICE => {
if payload.len() >= 4 {
let new_id = u32::from_le_bytes([
payload[0], payload[1], payload[2], payload[3],
]);
let mut clients = self.clients.lock().unwrap();
if let Some(client) = clients.get_mut(&client_id) {
client.objects.insert(new_id, OBJECT_TYPE_WL_DATA_DEVICE);
}
}
}
_ => {
eprintln!(
"redbear-compositor: unhandled data_device_manager opcode {} on object {}",
opcode, object_id
);
}
},
OBJECT_TYPE_WL_SUBCOMPOSITOR => match opcode {
WL_SUBCOMPOSITOR_GET_SUBSURFACE => {
if payload.len() >= 4 {
let new_id = u32::from_le_bytes([
payload[0], payload[1], payload[2], payload[3],
]);
let mut clients = self.clients.lock().unwrap();
if let Some(client) = clients.get_mut(&client_id) {
client.objects.insert(new_id, OBJECT_TYPE_WL_SUBSURFACE);
}
}
}
_ => {
eprintln!(
"redbear-compositor: unhandled subcompositor opcode {} on object {}",
opcode, object_id
);
}
},
OBJECT_TYPE_WL_DATA_DEVICE | OBJECT_TYPE_WL_SUBSURFACE => {
// Accept all requests silently — Qt6 needs these proxies
// to exist for initialization but we don't implement
// clipboard or subsurface compositing yet.
},
_ => {
eprintln!(
"redbear-compositor: unhandled object {} opcode {}",