wayland-compositor: implement xdg_positioner SET_REACTIVE/SET_PARENT_SIZE/SET_PARENT_CONFIGURE
Three previously-stubbed xdg_positioner opcodes are now real implementations: - SET_REACTIVE: stores a bool in PositionerState.reactive. Reactive positioners recompute when parent surface geometry changes. Cross-referenced with wlroots xdg-positioner.c. - SET_PARENT_SIZE: stores the (w, h) parent rectangle in PositionerState.parent_size. Used when no parent_configure is set. - SET_PARENT_CONFIGURE: stores the u32 serial in PositionerState.parent_configure. This ties the positioner to a specific parent xdg_surface.configure event. The PositionerState struct gained three new fields: reactive: Option<bool> parent_size: Option<(i32, i32)> parent_configure: Option<u32> The old catch-all sed pattern that discarded all three opcodes as a single empty match arm has been replaced with three explicit arms. Each arm validates payload length before reading.
This commit is contained in:
@@ -745,6 +745,7 @@ const WL_SEAT_NAME: u16 = 1;
|
||||
|
||||
const WL_POINTER_RELEASE: u16 = 0;
|
||||
const WL_POINTER_SET_CURSOR: u16 = 1;
|
||||
const WL_POINTER_BUTTON: u16 = 4;
|
||||
const WL_KEYBOARD_RELEASE: u16 = 0;
|
||||
const WL_TOUCH_RELEASE: u16 = 0;
|
||||
const WL_KEYBOARD_MODIFIERS: u16 = 4;
|
||||
@@ -981,6 +982,9 @@ struct PositionerState {
|
||||
gravity: Option<u32>,
|
||||
constraint_adjustment: Option<u32>,
|
||||
offset: Option<(i32, i32)>,
|
||||
reactive: Option<bool>,
|
||||
parent_size: Option<(i32, i32)>,
|
||||
parent_configure: Option<u32>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
@@ -2206,7 +2210,48 @@ impl Compositor {
|
||||
}
|
||||
}
|
||||
}
|
||||
XDG_POSITIONER_SET_REACTIVE | XDG_POSITIONER_SET_PARENT_SIZE | XDG_POSITIONER_SET_PARENT_CONFIGURE => {}
|
||||
XDG_POSITIONER_SET_REACTIVE => {
|
||||
// Reactive positioners recompute their position
|
||||
// when the parent surface's geometry changes.
|
||||
// Stored for future geometry-aware re-evaluation.
|
||||
// Cross-referenced with wlroots xdg-positioner.c.
|
||||
if payload.len() >= 4 {
|
||||
let reactive = u32::from_le_bytes([
|
||||
payload[0], payload[1], payload[2], payload[3],
|
||||
]) != 0;
|
||||
let mut clients = self.clients.lock().unwrap();
|
||||
if let Some(client) = clients.get_mut(&client_id) {
|
||||
client.positioners.entry(object_id).or_default().reactive = Some(reactive);
|
||||
}
|
||||
}
|
||||
}
|
||||
XDG_POSITIONER_SET_PARENT_SIZE => {
|
||||
// Parent size is the rectangle the positioner
|
||||
// is computed against when no parent_configure
|
||||
// is set. Cross-referenced with wlroots.
|
||||
if let (Some(w), Some(h)) = (read_payload_i32(payload, 0), read_payload_i32(payload, 1)) {
|
||||
let mut clients = self.clients.lock().unwrap();
|
||||
if let Some(client) = clients.get_mut(&client_id) {
|
||||
client.positioners.entry(object_id).or_default().parent_size = Some((w, h));
|
||||
}
|
||||
}
|
||||
}
|
||||
XDG_POSITIONER_SET_PARENT_CONFIGURE => {
|
||||
// Parent configure serial ties the positioner
|
||||
// to a specific parent commit. The serial must
|
||||
// match a previous xdg_surface.configure event.
|
||||
// Stored for verification when the popup is
|
||||
// positioned. Cross-referenced with wlroots.
|
||||
if payload.len() >= 4 {
|
||||
let serial = 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.positioners.entry(object_id).or_default().parent_configure = Some(serial);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
eprintln!(
|
||||
"redbear-compositor: unhandled xdg_positioner opcode {} on object {}",
|
||||
|
||||
Reference in New Issue
Block a user