select: use xdg_output logical_position for per-monitor surface origin
This commit is contained in:
parent
fa28415c7a
commit
0e910d73cc
1 changed files with 56 additions and 4 deletions
|
|
@ -19,6 +19,10 @@ use wayland_protocols::wp::cursor_shape::v1::client::{
|
|||
wp_cursor_shape_device_v1::{Shape as CursorShape, WpCursorShapeDeviceV1},
|
||||
wp_cursor_shape_manager_v1::WpCursorShapeManagerV1,
|
||||
};
|
||||
use wayland_protocols::xdg::xdg_output::zv1::client::{
|
||||
zxdg_output_manager_v1::ZxdgOutputManagerV1,
|
||||
zxdg_output_v1::{self, ZxdgOutputV1},
|
||||
};
|
||||
use wayland_protocols_wlr::layer_shell::v1::client::{
|
||||
zwlr_layer_shell_v1::ZwlrLayerShellV1,
|
||||
zwlr_layer_surface_v1::{self, ZwlrLayerSurfaceV1},
|
||||
|
|
@ -67,6 +71,7 @@ pub struct HintBox {
|
|||
struct PendingOut {
|
||||
wl: wl_output::WlOutput,
|
||||
name: Option<String>,
|
||||
wl_name: u32,
|
||||
ox: i32,
|
||||
oy: i32,
|
||||
scale: i32,
|
||||
|
|
@ -109,6 +114,8 @@ struct St {
|
|||
keyboard: Option<wl_keyboard::WlKeyboard>,
|
||||
cursor_shape: Option<WpCursorShapeManagerV1>,
|
||||
|
||||
_xdg_outputs: Vec<ZxdgOutputV1>,
|
||||
|
||||
pending: Vec<PendingOut>,
|
||||
surfs: Vec<Surf>,
|
||||
configured: usize, // count of configure events received
|
||||
|
|
@ -750,6 +757,29 @@ impl Dispatch<wl_shm::WlShm, ()> for St {
|
|||
}
|
||||
}
|
||||
|
||||
impl Dispatch<ZxdgOutputV1, u32> for St {
|
||||
fn event(
|
||||
state: &mut Self,
|
||||
_: &ZxdgOutputV1,
|
||||
event: zxdg_output_v1::Event,
|
||||
wl_name: &u32,
|
||||
_: &Connection,
|
||||
_: &QueueHandle<Self>,
|
||||
) {
|
||||
let Some(p) = state.pending.iter_mut().find(|p| p.wl_name == *wl_name) else {
|
||||
return;
|
||||
};
|
||||
match event {
|
||||
zxdg_output_v1::Event::LogicalPosition { x, y } => {
|
||||
p.ox = x;
|
||||
p.oy = y;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delegate_noop!(St: ignore ZxdgOutputManagerV1);
|
||||
delegate_noop!(St: ignore wl_compositor::WlCompositor);
|
||||
delegate_noop!(St: ignore wl_surface::WlSurface);
|
||||
delegate_noop!(St: ignore wl_shm_pool::WlShmPool);
|
||||
|
|
@ -783,19 +813,25 @@ pub fn select_region(
|
|||
.bind::<wl_seat::WlSeat, _, _>(&qh, 1..=8, ())
|
||||
.map_err(|e| BlastError::Selection(format!("seat: {e}")))?;
|
||||
|
||||
let pending: Vec<PendingOut> = globals
|
||||
let out_globals: Vec<(u32, u32)> = globals // (wl_global_name, version)
|
||||
.contents()
|
||||
.clone_list()
|
||||
.iter()
|
||||
.filter(|g| g.interface == "wl_output")
|
||||
.map(|g| PendingOut {
|
||||
.map(|g| (g.name, g.version))
|
||||
.collect();
|
||||
|
||||
let pending: Vec<PendingOut> = out_globals
|
||||
.iter()
|
||||
.map(|&(gname, ver)| PendingOut {
|
||||
wl: globals.registry().bind::<wl_output::WlOutput, _, _>(
|
||||
g.name,
|
||||
g.version.min(4),
|
||||
gname,
|
||||
ver.min(4),
|
||||
&qh,
|
||||
(),
|
||||
),
|
||||
name: None,
|
||||
wl_name: gname,
|
||||
ox: 0,
|
||||
oy: 0,
|
||||
scale: 1,
|
||||
|
|
@ -822,6 +858,7 @@ pub fn select_region(
|
|||
pointer: None,
|
||||
keyboard: None,
|
||||
cursor_shape,
|
||||
_xdg_outputs: Vec::new(),
|
||||
pending,
|
||||
surfs: Vec::new(),
|
||||
configured: 0,
|
||||
|
|
@ -843,6 +880,21 @@ pub fn select_region(
|
|||
st.roundtrip()?;
|
||||
st.roundtrip()?; // second pass to get pointer/keyboard from capabilities
|
||||
|
||||
// Fetch logical positions from xdg_output so that surfaces on non-primary
|
||||
// monitors get the correct (lx, ly) origin. wl_output.geometry is unreliable
|
||||
// on compositors with fractional scaling — they may always report (0, 0) there
|
||||
// and only set the real position via xdg_output.logical_position.
|
||||
if let Ok(xdg_mgr) = globals.bind::<ZxdgOutputManagerV1, _, _>(&st.qh, 2..=3, ()) {
|
||||
let xdg_outputs: Vec<ZxdgOutputV1> = st
|
||||
.pending
|
||||
.iter()
|
||||
.map(|p| xdg_mgr.get_xdg_output(&p.wl, &st.qh, p.wl_name))
|
||||
.collect();
|
||||
st._xdg_outputs = xdg_outputs;
|
||||
st.roundtrip()?; // receive logical_position events, updating p.ox / p.oy
|
||||
drop(xdg_mgr);
|
||||
}
|
||||
|
||||
st.create_surfaces()?;
|
||||
|
||||
let expected = st.surfs.len();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue