From 2dd40ecfe882c1659e0e46c761974702c7ab5fde Mon Sep 17 00:00:00 2001 From: Shawn Wallace Date: Sat, 25 Oct 2025 15:57:30 -0400 Subject: [PATCH] server: add SlideX/Y constraint adjustment to popups Allows popups that would normally go offscreen to stay visible. X11 doesn't seem to like windows whose bounds go less than 0x0, so we adjust the position reported to X11 to make it happy. I am worried this will have some other implications with popups, but we'll see what happens. --- src/server/event.rs | 4 ++-- src/server/mod.rs | 3 +++ testwl/src/lib.rs | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/server/event.rs b/src/server/event.rs index c877b7d..0da6206 100644 --- a/src/server/event.rs +++ b/src/server/event.rs @@ -227,8 +227,8 @@ impl SurfaceEvents { let (scale_factor, window, window_data) = query.get().unwrap(); let window = *window; - let x = (pending.x as f64 * scale_factor.0) as i32 + window_data.output_offset.x; - let y = (pending.y as f64 * scale_factor.0) as i32 + window_data.output_offset.y; + let x = (pending.x.max(0) as f64 * scale_factor.0) as i32 + window_data.output_offset.x; + let y = (pending.y.max(0) as f64 * scale_factor.0) as i32 + window_data.output_offset.y; let width = if pending.width > 0 { (pending.width as f64 * scale_factor.0) as u16 } else { diff --git a/src/server/mod.rs b/src/server/mod.rs index 4f7d57f..ce6af7b 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -25,6 +25,7 @@ use wayland_protocols::xdg::decoration::zv1::client::zxdg_decoration_manager_v1: use wayland_protocols::xdg::decoration::zv1::client::zxdg_toplevel_decoration_v1::{ self, ZxdgToplevelDecorationV1, }; +use wayland_protocols::xdg::shell::client::xdg_positioner::ConstraintAdjustment; use wayland_protocols::{ wp::{ fractional_scale::v1::client::wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1, @@ -1407,6 +1408,8 @@ impl InnerServerState { (parent_window.attrs.dims.width as f64 / initial_scale) as i32, (parent_window.attrs.dims.height as f64 / initial_scale) as i32, ); + positioner + .set_constraint_adjustment(ConstraintAdjustment::SlideX | ConstraintAdjustment::SlideY); let popup = xdg.get_popup( Some(&parent_role.xdg().unwrap().surface), &positioner, diff --git a/testwl/src/lib.rs b/testwl/src/lib.rs index b79f367..899e0b4 100644 --- a/testwl/src/lib.rs +++ b/testwl/src/lib.rs @@ -1740,6 +1740,7 @@ impl Dispatch for State { xdg_positioner::Request::Destroy => { data.remove(); } + xdg_positioner::Request::SetConstraintAdjustment { .. } => {} other => todo!("unhandled positioner request {other:?}"), } }