Handle xdg configure states properly

This commit is contained in:
Val Packett 2026-03-20 00:22:37 -03:00
parent 36c87d4638
commit de494a0453

View file

@ -184,6 +184,12 @@ impl ClientXdgToplevel {
}
}
enum ToplevelState {
Normal,
Maximixed,
Fullscreen,
}
impl XdgToplevelHandler for ClientXdgToplevel {
fn handle_set_title(&mut self, slf: &Rc<XdgToplevel>, title: &str) {
slf.send_set_title(title);
@ -213,9 +219,51 @@ impl XdgToplevelHandler for ClientXdgToplevel {
slf.send_unset_fullscreen();
}
fn handle_configure(&mut self, slf: &Rc<XdgToplevel>, width: i32, height: i32, _states: &[u8]) {
let states = (1u64 << 32 | XdgToplevelState::TILED_TOP.0 as u64).to_ne_bytes();
fn handle_configure(&mut self, slf: &Rc<XdgToplevel>, width: i32, height: i32, states: &[u8]) {
log::debug!("configure {slf:?}: {width}x{height}, {states:?}");
let (_prefix, states, _suffix) = unsafe { states.align_to::<u32>() };
let mut top_state = ToplevelState::Normal;
let mut resizing = false;
let mut activated = false;
let mut suspended = false;
for state in states {
if *state == XdgToplevelState::RESIZING.0 {
resizing = true;
} else if *state == XdgToplevelState::ACTIVATED.0 {
activated = true;
} else if *state == XdgToplevelState::SUSPENDED.0 {
suspended = true;
} else if *state == XdgToplevelState::MAXIMIZED.0 {
top_state = ToplevelState::Maximixed;
} else if *state == XdgToplevelState::FULLSCREEN.0 {
top_state = ToplevelState::Fullscreen;
}
}
let mut outer_state = Vec::with_capacity(8);
if resizing {
outer_state.push(XdgToplevelState::RESIZING);
}
if activated {
outer_state.push(XdgToplevelState::ACTIVATED);
}
if suspended {
outer_state.push(XdgToplevelState::SUSPENDED);
}
match top_state {
ToplevelState::Normal => {
// Let the client think it's tiled, so that it avoids drawing its own deco/shadows
outer_state.push(XdgToplevelState::TILED_TOP);
outer_state.push(XdgToplevelState::TILED_RIGHT);
outer_state.push(XdgToplevelState::TILED_BOTTOM);
outer_state.push(XdgToplevelState::TILED_LEFT);
}
ToplevelState::Maximixed => outer_state.push(XdgToplevelState::MAXIMIZED),
ToplevelState::Fullscreen => outer_state.push(XdgToplevelState::FULLSCREEN),
};
let (width, height) = self.deco.transform_configure(width, height);
let (_prefix, states, _suffix) = unsafe { outer_state.align_to::<u8>() };
slf.send_configure(width, height, &states[..]);
}