use crate::{PhysicalRect, PopupInput, ShellError, WindowId};
use core::ptr;
use super::WaylandShell;
use super::protocol::wayland::{wl_compositor, wl_region, wl_surface};
use super::text_input::logical_rect;
impl WaylandShell {
pub(super) fn apply_input_region(
&mut self,
window: WindowId,
region: Option<&[PhysicalRect]>,
) -> Result<(), ShellError> {
let state = self.window(window)?;
if state.popup_input == Some(PopupInput::Passthrough) {
return Ok(());
}
let (surface, scale) = (state.surface, state.scale_factor());
let compositor = self.conn.compositor;
let built = match region {
None => ptr::null_mut(),
Some(_) if compositor.is_null() => {
return Err(ShellError::Backend(
"the compositor withdrew wl_compositor, so no region can be made".to_string(),
));
}
Some(rects) => {
let built = unsafe { wl_compositor::create_region(compositor) };
if built.is_null() {
return Err(ShellError::Backend(
"wl_compositor.create_region failed".to_string(),
));
}
for &rect in rects {
let [x, y, width, height] = logical_rect(rect, scale);
if width > 0 && height > 0 {
unsafe { wl_region::add(built, x, y, width, height) };
}
}
built
}
};
unsafe {
wl_surface::set_input_region(surface, built);
if !built.is_null() {
wl_region::destroy(built);
}
wl_surface::commit(surface);
}
self.conn.flush();
Ok(())
}
}