srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates/wayland/src/udev/platform.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/wayland/src/udev/platform.rs')
-rw-r--r--crates/wayland/src/udev/platform.rs40
1 files changed, 40 insertions, 0 deletions
diff --git a/crates/wayland/src/udev/platform.rs b/crates/wayland/src/udev/platform.rs
index 9023cb9..b09bd4b 100644
--- a/crates/wayland/src/udev/platform.rs
+++ b/crates/wayland/src/udev/platform.rs
@@ -162,6 +162,7 @@ impl UdevPlatform {
card: card.clone(),
renderer,
heads,
+ virtual_heads: Vec::new(),
active: true,
pointer_pos: (width as f64 / 2.0, height as f64 / 2.0).into(),
secondary_cursors: std::collections::HashMap::new(),
@@ -621,6 +622,22 @@ impl Platform for UdevPlatform {
for (pid, window) in pin_requests {
self.state.set_virtual_pointer_pin(pid, window);
}
+ // Applies any `srd dispatch create fake-monitor`/`remove fake-
+ // monitor` IPC requests queued since the last poll - see
+ // `crates/wayland/src/udev/virtual_heads.rs`'s own module doc
+ // comment.
+ let create_fake_monitor_requests = self.state.wm.borrow_mut().drain_create_fake_monitor_requests();
+ for (name, width, height) in create_fake_monitor_requests {
+ if let Err(e) = self.state.create_virtual_head(name.clone(), width as i32, height as i32) {
+ log::warn!("fake monitor: failed to create {name}: {e}");
+ }
+ }
+ let remove_fake_monitor_requests = self.state.wm.borrow_mut().drain_remove_fake_monitor_requests();
+ for name in remove_fake_monitor_requests {
+ if let Err(e) = self.state.remove_virtual_head(&name) {
+ log::warn!("fake monitor: failed to remove {name}: {e}");
+ }
+ }
// Throttled the same way and for the same underlying reason as the
// `ipc.poll()` call above - this is the *other*, larger half of
// this cycle's needless work at the dead-pipe-driven spin rate.
@@ -648,6 +665,12 @@ impl Platform for UdevPlatform {
const RENDER_INTERVAL: Duration = Duration::from_millis(8);
if self.last_render.elapsed() >= RENDER_INTERVAL {
self.last_render = Instant::now();
+ // Before `render_udev_frame` drains `self.screencopy_pending`
+ // for real heads - see `service_virtual_head_captures`'s own
+ // doc comment for why a fake-monitor capture must never reach
+ // that drain at all (it would wait forever for a real page-
+ // flip that will never come).
+ self.state.service_virtual_head_captures();
self.state.render_udev_frame();
}
Ok(self.pending.borrow_mut().drain(..).collect())
@@ -826,6 +849,23 @@ impl Platform for UdevPlatform {
next_id += 1;
}
}
+ // Fake monitors (`virtual_heads.rs`) get the same treatment a real
+ // head does, minus the layer-shell exclusive-zone/reservation math
+ // (nothing binds a bar/dock to one in this phase, so there is
+ // never a zone to shrink `usable` by) and minus `srd.monitor.
+ // split` (a fake monitor already *is* exactly the size it was
+ // created at - splitting it further is a real, separate ask this
+ // phase doesn't attempt). `full == usable == maximize`, `scale`
+ // always `1.0` - see `VirtualHead`'s own doc comment for why.
+ for head in &udev.virtual_heads {
+ let full = srdwm_core::Rect::new(head.location.x, head.location.y, head.size.0 as u32, head.size.1 as u32);
+ let mut m = srdwm_core::Monitor::new(next_id, head.name.clone(), full);
+ m.full_geometry = full;
+ m.maximize_geometry = full;
+ m.primary = false;
+ out.push(m);
+ next_id += 1;
+ }
Ok(out)
}