Wayland input_region and exclusive_zone + WGPU panic fix (#82)

This commit is contained in:
Philipp Schaffrath
2026-06-22 21:59:02 -04:00
committed by GitHub
parent f9a8c62bd9
commit 0610782953
4 changed files with 63 additions and 1 deletions
+2
View File
@@ -703,6 +703,8 @@ pub trait PlatformWindow: HasWindowHandle + HasDisplayHandle {
fn show_window_menu(&self, _position: Point<Pixels>) {}
fn start_window_move(&self) {}
fn start_window_resize(&self, _edge: ResizeEdge) {}
fn set_input_region(&self, _rects: &[Bounds<Pixels>]) {}
fn set_exclusive_zone(&self, _zone: Pixels) {}
fn window_decorations(&self) -> Decorations {
Decorations::Server
}
+15
View File
@@ -1945,6 +1945,21 @@ impl Window {
self.platform_window.request_decorations(decorations);
}
/// Set the window's input region to the union of `rects`. Pointer events
/// outside the region pass through to whatever is below the window.
/// An empty slice resets the input region, so the window will receive all
/// pointer events again. (wayland only)
pub fn set_input_region(&self, rects: &[Bounds<Pixels>]) {
self.platform_window.set_input_region(rects);
}
/// Controls how a surface interacts with surrounding screen space.
/// Positive values reserve space, 0 avoids reserved space, and -1 ignores
/// reserved space and may extend underneath other surfaces. (wayland only)
pub fn set_exclusive_zone(&self, zone: Pixels) {
self.platform_window.set_exclusive_zone(zone);
}
/// Start a window resize operation (Wayland)
pub fn start_window_resize(&self, edge: ResizeEdge) {
self.platform_window.start_window_resize(edge);
@@ -286,6 +286,14 @@ impl WaylandSurfaceState {
}
}
fn set_exclusive_zone(&self, zone: i32) {
if let WaylandSurfaceState::LayerShell(WaylandLayerSurfaceState { layer_surface, .. }) =
self
{
layer_surface.set_exclusive_zone(zone);
}
}
fn destroy(&mut self) {
match self {
WaylandSurfaceState::Xdg(WaylandXdgSurfaceState {
@@ -1471,6 +1479,40 @@ impl PlatformWindow for WaylandWindow {
}
}
fn set_input_region(&self, rects: &[Bounds<Pixels>]) {
let state = self.borrow();
if rects.is_empty() {
state.surface.set_input_region(None);
} else {
let region = state
.globals
.compositor
.create_region(&state.globals.qh, ());
rects
.iter()
.map(|rect| rect.map(|pixels| f32::from(pixels) as i32))
.for_each(|rect| {
region.add(
rect.origin.x,
rect.origin.y,
rect.size.width,
rect.size.height,
)
});
state.surface.set_input_region(Some(&region));
region.destroy();
}
state.surface.commit();
}
fn set_exclusive_zone(&self, zone: Pixels) {
let state = self.borrow();
state
.surface_state
.set_exclusive_zone(f32::from(zone) as i32);
state.surface.commit();
}
fn window_decorations(&self) -> Decorations {
let state = self.borrow();
match state.decorations {
+4 -1
View File
@@ -1189,7 +1189,10 @@ impl WgpuRenderer {
self.surface_config.height = clamped_height.max(1);
let surface_config = self.surface_config.clone();
let resources = self.resources_mut();
// GPU resources may not exist yet, skip rather than panicking
let Some(resources) = self.resources.as_mut() else {
return;
};
// Wait for any in-flight GPU work to complete before destroying textures
if let Err(e) = resources.device.poll(wgpu::PollType::Wait {