1
0
Fork 0
forked from wry/wry

wayland: don't store direct output references

This commit is contained in:
Julian Orth 2024-04-25 19:38:19 +02:00
parent 0605438d56
commit 4651f760f0
13 changed files with 123 additions and 65 deletions

View file

@ -57,20 +57,20 @@ impl ExtSessionLockV1RequestHandler for ExtSessionLockV1 {
surface, surface,
tracker: Default::default(), tracker: Default::default(),
serial: Default::default(), serial: Default::default(),
output: output.global.node.get(), output: output.global.clone(),
seat_state: Default::default(), seat_state: Default::default(),
version: self.version, version: self.version,
}); });
track!(new.client, new); track!(new.client, new);
new.install()?; new.install()?;
self.client.add_client_obj(&new)?; self.client.add_client_obj(&new)?;
if !output.global.destroyed.get() && !self.finished.get() { if !self.finished.get() {
if let Some(node) = output.global.node.get() { if let Some(node) = output.global.node() {
if node.lock_surface.is_some() { if node.lock_surface.is_some() {
return Err(ExtSessionLockV1Error::OutputAlreadyLocked); return Err(ExtSessionLockV1Error::OutputAlreadyLocked);
} }
node.set_lock_surface(Some(new.clone())); node.set_lock_surface(Some(new.clone()));
let pos = output.global.pos.get(); let pos = node.global.pos.get();
new.change_extents(pos); new.change_extents(pos);
self.client.state.tree_changed(); self.client.state.tree_changed();
} }

View file

@ -21,7 +21,7 @@ use {
leaks::Tracker, leaks::Tracker,
object::{Object, Version}, object::{Object, Version},
screenshoter::take_screenshot, screenshoter::take_screenshot,
utils::{clonecell::CloneCell, errorfmt::ErrorFmt}, utils::errorfmt::ErrorFmt,
wire::{jay_compositor::*, JayCompositorId, JayScreenshotId}, wire::{jay_compositor::*, JayCompositorId, JayScreenshotId},
}, },
bstr::ByteSlice, bstr::ByteSlice,
@ -264,12 +264,12 @@ impl JayCompositorRequestHandler for JayCompositor {
let jo = Rc::new(JayOutput { let jo = Rc::new(JayOutput {
id: req.id, id: req.id,
client: self.client.clone(), client: self.client.clone(),
output: CloneCell::new(output.global.node.get()), output: output.global.clone(),
tracker: Default::default(), tracker: Default::default(),
}); });
track!(self.client, jo); track!(self.client, jo);
self.client.add_client_obj(&jo)?; self.client.add_client_obj(&jo)?;
if let Some(node) = jo.output.get() { if let Some(node) = jo.output.node() {
node.jay_outputs.set((self.client.id, req.id), jo.clone()); node.jay_outputs.set((self.client.id, req.id), jo.clone());
jo.send_linear_id(); jo.send_linear_id();
} else { } else {

View file

@ -1,10 +1,9 @@
use { use {
crate::{ crate::{
client::{Client, ClientError}, client::{Client, ClientError},
ifs::wl_output::OutputGlobalOpt,
leaks::Tracker, leaks::Tracker,
object::{Object, Version}, object::{Object, Version},
tree::OutputNode,
utils::clonecell::CloneCell,
wire::{jay_output::*, JayOutputId}, wire::{jay_output::*, JayOutputId},
}, },
std::rc::Rc, std::rc::Rc,
@ -14,7 +13,7 @@ use {
pub struct JayOutput { pub struct JayOutput {
pub id: JayOutputId, pub id: JayOutputId,
pub client: Rc<Client>, pub client: Rc<Client>,
pub output: CloneCell<Option<Rc<OutputNode>>>, pub output: Rc<OutputGlobalOpt>,
pub tracker: Tracker<Self>, pub tracker: Tracker<Self>,
} }
@ -24,7 +23,7 @@ impl JayOutput {
} }
pub fn send_linear_id(&self) { pub fn send_linear_id(&self) {
if let Some(output) = self.output.get() { if let Some(output) = self.output.node() {
self.client.event(LinearId { self.client.event(LinearId {
self_id: self.id, self_id: self.id,
linear_id: output.id.raw(), linear_id: output.id.raw(),
@ -33,7 +32,7 @@ impl JayOutput {
} }
fn remove_from_node(&self) { fn remove_from_node(&self) {
if let Some(output) = self.output.get() { if let Some(output) = self.output.node() {
output.jay_outputs.remove(&(self.client.id, self.id)); output.jay_outputs.remove(&(self.client.id, self.id));
} }
} }

View file

@ -519,7 +519,7 @@ impl JayScreencastRequestHandler for JayScreencast {
if let Some(new) = target { if let Some(new) = target {
match new { match new {
PendingTarget::Output(o) => { PendingTarget::Output(o) => {
let Some(o) = o.output.get() else { let Some(o) = o.output.node() else {
self.do_destroy(); self.do_destroy();
return Ok(()); return Ok(());
}; };

View file

@ -55,13 +55,34 @@ pub struct WlOutputGlobal {
pub output_id: Rc<OutputId>, pub output_id: Rc<OutputId>,
pub mode: Cell<backend::Mode>, pub mode: Cell<backend::Mode>,
pub modes: Vec<backend::Mode>, pub modes: Vec<backend::Mode>,
pub node: CloneCell<Option<Rc<OutputNode>>>,
pub width_mm: i32, pub width_mm: i32,
pub height_mm: i32, pub height_mm: i32,
pub bindings: RefCell<AHashMap<ClientId, AHashMap<WlOutputId, Rc<WlOutput>>>>, pub bindings: RefCell<AHashMap<ClientId, AHashMap<WlOutputId, Rc<WlOutput>>>>,
pub destroyed: Cell<bool>, pub destroyed: Cell<bool>,
pub legacy_scale: Cell<u32>, pub legacy_scale: Cell<u32>,
pub persistent: Rc<PersistentOutputState>, pub persistent: Rc<PersistentOutputState>,
pub opt: Rc<OutputGlobalOpt>,
}
#[derive(Default)]
pub struct OutputGlobalOpt {
pub global: CloneCell<Option<Rc<WlOutputGlobal>>>,
pub node: CloneCell<Option<Rc<OutputNode>>>,
}
impl OutputGlobalOpt {
pub fn get(&self) -> Option<Rc<WlOutputGlobal>> {
self.global.get()
}
pub fn node(&self) -> Option<Rc<OutputNode>> {
self.node.get()
}
pub fn clear(&self) {
self.node.take();
self.global.take();
}
} }
pub struct PersistentOutputState { pub struct PersistentOutputState {
@ -80,7 +101,7 @@ pub struct OutputId {
impl WlOutputGlobal { impl WlOutputGlobal {
pub fn clear(&self) { pub fn clear(&self) {
self.node.take(); self.opt.clear();
self.bindings.borrow_mut().clear(); self.bindings.borrow_mut().clear();
} }
@ -110,13 +131,13 @@ impl WlOutputGlobal {
output_id: output_id.clone(), output_id: output_id.clone(),
mode: Cell::new(*mode), mode: Cell::new(*mode),
modes, modes,
node: Default::default(),
width_mm, width_mm,
height_mm, height_mm,
bindings: Default::default(), bindings: Default::default(),
destroyed: Cell::new(false), destroyed: Cell::new(false),
legacy_scale: Cell::new(scale.round_up()), legacy_scale: Cell::new(scale.round_up()),
persistent: persistent_state.clone(), persistent: persistent_state.clone(),
opt: Default::default(),
} }
} }
@ -169,7 +190,7 @@ impl WlOutputGlobal {
version: Version, version: Version,
) -> Result<(), WlOutputError> { ) -> Result<(), WlOutputError> {
let obj = Rc::new(WlOutput { let obj = Rc::new(WlOutput {
global: self.clone(), global: self.opt.clone(),
id, id,
xdg_outputs: Default::default(), xdg_outputs: Default::default(),
client: client.clone(), client: client.clone(),
@ -225,7 +246,7 @@ impl Global for WlOutputGlobal {
dedicated_add_global!(WlOutputGlobal, outputs); dedicated_add_global!(WlOutputGlobal, outputs);
pub struct WlOutput { pub struct WlOutput {
pub global: Rc<WlOutputGlobal>, pub global: Rc<OutputGlobalOpt>,
pub id: WlOutputId, pub id: WlOutputId,
pub xdg_outputs: CopyHashMap<ZxdgOutputV1Id, Rc<ZxdgOutputV1>>, pub xdg_outputs: CopyHashMap<ZxdgOutputV1Id, Rc<ZxdgOutputV1>>,
client: Rc<Client>, client: Rc<Client>,
@ -239,23 +260,29 @@ pub const SEND_NAME_SINCE: Version = Version(4);
impl WlOutput { impl WlOutput {
fn send_geometry(&self) { fn send_geometry(&self) {
let pos = self.global.pos.get(); let Some(global) = self.global.get() else {
return;
};
let pos = global.pos.get();
let event = Geometry { let event = Geometry {
self_id: self.id, self_id: self.id,
x: pos.x1(), x: pos.x1(),
y: pos.y1(), y: pos.y1(),
physical_width: self.global.width_mm, physical_width: global.width_mm,
physical_height: self.global.height_mm, physical_height: global.height_mm,
subpixel: SP_UNKNOWN, subpixel: SP_UNKNOWN,
make: &self.global.output_id.manufacturer, make: &global.output_id.manufacturer,
model: &self.global.output_id.model, model: &global.output_id.model,
transform: self.global.persistent.transform.get().to_wl(), transform: global.persistent.transform.get().to_wl(),
}; };
self.client.event(event); self.client.event(event);
} }
fn send_mode(&self) { fn send_mode(&self) {
let mode = self.global.mode.get(); let Some(global) = self.global.get() else {
return;
};
let mode = global.mode.get();
let event = Mode { let event = Mode {
self_id: self.id, self_id: self.id,
flags: MODE_CURRENT, flags: MODE_CURRENT,
@ -267,17 +294,23 @@ impl WlOutput {
} }
fn send_scale(self: &Rc<Self>) { fn send_scale(self: &Rc<Self>) {
let Some(global) = self.global.get() else {
return;
};
let event = Scale { let event = Scale {
self_id: self.id, self_id: self.id,
factor: self.global.legacy_scale.get() as _, factor: global.legacy_scale.get() as _,
}; };
self.client.event(event); self.client.event(event);
} }
fn send_name(&self) { fn send_name(&self) {
let Some(global) = self.global.get() else {
return;
};
self.client.event(Name { self.client.event(Name {
self_id: self.id, self_id: self.id,
name: &self.global.connector.name, name: &global.connector.name,
}); });
} }
@ -287,12 +320,15 @@ impl WlOutput {
} }
fn remove_binding(&self) { fn remove_binding(&self) {
if let Entry::Occupied(mut e) = self.global.bindings.borrow_mut().entry(self.client.id) { let Some(global) = self.global.get() else {
return;
};
if let Entry::Occupied(mut e) = global.bindings.borrow_mut().entry(self.client.id) {
e.get_mut().remove(&self.id); e.get_mut().remove(&self.id);
if e.get().is_empty() { if e.get().is_empty() {
e.remove(); e.remove();
} }
} };
} }
} }

View file

@ -3,13 +3,14 @@ use {
client::{Client, ClientError}, client::{Client, ClientError},
fixed::Fixed, fixed::Fixed,
ifs::{ ifs::{
wl_output::OutputGlobalOpt,
wl_seat::{NodeSeatState, WlSeatGlobal}, wl_seat::{NodeSeatState, WlSeatGlobal},
wl_surface::{SurfaceExt, SurfaceRole, WlSurface, WlSurfaceError}, wl_surface::{SurfaceExt, SurfaceRole, WlSurface, WlSurfaceError},
}, },
leaks::Tracker, leaks::Tracker,
object::{Object, Version}, object::{Object, Version},
rect::Rect, rect::Rect,
tree::{FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId, NodeVisitor, OutputNode}, tree::{FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId, NodeVisitor},
utils::numcell::NumCell, utils::numcell::NumCell,
wire::{ext_session_lock_surface_v1::*, ExtSessionLockSurfaceV1Id, WlSurfaceId}, wire::{ext_session_lock_surface_v1::*, ExtSessionLockSurfaceV1Id, WlSurfaceId},
}, },
@ -24,7 +25,7 @@ pub struct ExtSessionLockSurfaceV1 {
pub surface: Rc<WlSurface>, pub surface: Rc<WlSurface>,
pub tracker: Tracker<Self>, pub tracker: Tracker<Self>,
pub serial: NumCell<u32>, pub serial: NumCell<u32>,
pub output: Option<Rc<OutputNode>>, pub output: Rc<OutputGlobalOpt>,
pub seat_state: NodeSeatState, pub seat_state: NodeSeatState,
pub version: Version, pub version: Version,
} }
@ -73,7 +74,7 @@ impl ExtSessionLockSurfaceV1RequestHandler for ExtSessionLockSurfaceV1 {
impl ExtSessionLockSurfaceV1 { impl ExtSessionLockSurfaceV1 {
pub fn destroy_node(&self) { pub fn destroy_node(&self) {
if let Some(output) = &self.output { if let Some(output) = &self.output.node() {
if let Some(ls) = output.lock_surface.get() { if let Some(ls) = output.lock_surface.get() {
if ls.node_id == self.node_id { if ls.node_id == self.node_id {
output.set_lock_surface(None); output.set_lock_surface(None);

View file

@ -321,7 +321,7 @@ impl XdgToplevelRequestHandler for XdgToplevel {
self.states.borrow_mut().insert(STATE_FULLSCREEN); self.states.borrow_mut().insert(STATE_FULLSCREEN);
'set_fullscreen: { 'set_fullscreen: {
let output = if req.output.is_some() { let output = if req.output.is_some() {
match client.lookup(req.output)?.global.node.get() { match client.lookup(req.output)?.global.node() {
Some(node) => node, Some(node) => node,
_ => { _ => {
log::error!("Output global has no node attached"); log::error!("Output global has no node attached");

View file

@ -2,6 +2,7 @@ use {
crate::{ crate::{
client::{Client, ClientError}, client::{Client, ClientError},
ifs::{ ifs::{
wl_output::OutputGlobalOpt,
wl_seat::NodeSeatState, wl_seat::NodeSeatState,
wl_surface::{PendingState, SurfaceExt, SurfaceRole, WlSurface, WlSurfaceError}, wl_surface::{PendingState, SurfaceExt, SurfaceRole, WlSurface, WlSurfaceError},
zwlr_layer_shell_v1::{ZwlrLayerShellV1, OVERLAY}, zwlr_layer_shell_v1::{ZwlrLayerShellV1, OVERLAY},
@ -10,7 +11,7 @@ use {
object::Object, object::Object,
rect::Rect, rect::Rect,
renderer::Renderer, renderer::Renderer,
tree::{FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId, NodeVisitor, OutputNode}, tree::{FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId, NodeVisitor},
utils::{ utils::{
bitflags::BitflagsExt, cell_ext::CellExt, linkedlist::LinkedNode, numcell::NumCell, bitflags::BitflagsExt, cell_ext::CellExt, linkedlist::LinkedNode, numcell::NumCell,
option_ext::OptionExt, option_ext::OptionExt,
@ -43,7 +44,7 @@ pub struct ZwlrLayerSurfaceV1 {
pub shell: Rc<ZwlrLayerShellV1>, pub shell: Rc<ZwlrLayerShellV1>,
pub client: Rc<Client>, pub client: Rc<Client>,
pub surface: Rc<WlSurface>, pub surface: Rc<WlSurface>,
pub output: Rc<OutputNode>, pub output: Rc<OutputGlobalOpt>,
pub namespace: String, pub namespace: String,
pub tracker: Tracker<Self>, pub tracker: Tracker<Self>,
output_pos: Cell<Rect>, output_pos: Cell<Rect>,
@ -96,7 +97,7 @@ impl ZwlrLayerSurfaceV1 {
id: ZwlrLayerSurfaceV1Id, id: ZwlrLayerSurfaceV1Id,
shell: &Rc<ZwlrLayerShellV1>, shell: &Rc<ZwlrLayerShellV1>,
surface: &Rc<WlSurface>, surface: &Rc<WlSurface>,
output: &Rc<OutputNode>, output: &Rc<OutputGlobalOpt>,
layer: u32, layer: u32,
namespace: &str, namespace: &str,
) -> Self { ) -> Self {
@ -131,7 +132,9 @@ impl ZwlrLayerSurfaceV1 {
return Err(ZwlrLayerSurfaceV1Error::AlreadyAttached(self.surface.id)); return Err(ZwlrLayerSurfaceV1Error::AlreadyAttached(self.surface.id));
} }
self.surface.ext.set(self.clone()); self.surface.ext.set(self.clone());
self.surface.set_output(&self.output); if let Some(output) = self.output.node() {
self.surface.set_output(&output);
}
Ok(()) Ok(())
} }
@ -241,6 +244,9 @@ impl ZwlrLayerSurfaceV1RequestHandler for ZwlrLayerSurfaceV1 {
impl ZwlrLayerSurfaceV1 { impl ZwlrLayerSurfaceV1 {
fn pre_commit(&self, pending: &mut PendingState) -> Result<(), ZwlrLayerSurfaceV1Error> { fn pre_commit(&self, pending: &mut PendingState) -> Result<(), ZwlrLayerSurfaceV1Error> {
let Some(global) = self.output.get() else {
return Ok(());
};
let pending = pending.layer_surface.get_or_insert_default_ext(); let pending = pending.layer_surface.get_or_insert_default_ext();
let mut send_configure = mem::replace(&mut pending.any, false); let mut send_configure = mem::replace(&mut pending.any, false);
if let Some(size) = pending.size.take() { if let Some(size) = pending.size.take() {
@ -269,14 +275,14 @@ impl ZwlrLayerSurfaceV1 {
return Err(ZwlrLayerSurfaceV1Error::WidthZero); return Err(ZwlrLayerSurfaceV1Error::WidthZero);
} }
send_configure = true; send_configure = true;
width = self.output.global.position().width(); width = global.position().width();
} }
if height == 0 { if height == 0 {
if !anchor.contains(TOP | BOTTOM) { if !anchor.contains(TOP | BOTTOM) {
return Err(ZwlrLayerSurfaceV1Error::HeightZero); return Err(ZwlrLayerSurfaceV1Error::HeightZero);
} }
send_configure = true; send_configure = true;
height = self.output.global.position().height(); height = global.position().height();
} }
self.size.set((width, height)); self.size.set((width, height));
} }
@ -300,12 +306,15 @@ impl ZwlrLayerSurfaceV1 {
} }
pub fn compute_position(&self) { pub fn compute_position(&self) {
let Some(global) = self.output.get() else {
return;
};
let (width, height) = self.size.get(); let (width, height) = self.size.get();
let mut anchor = self.anchor.get(); let mut anchor = self.anchor.get();
if anchor == 0 { if anchor == 0 {
anchor = LEFT | RIGHT | TOP | BOTTOM; anchor = LEFT | RIGHT | TOP | BOTTOM;
} }
let opos = self.output.global.pos.get(); let opos = global.pos.get();
let mut x1 = 0; let mut x1 = 0;
let mut y1 = 0; let mut y1 = 0;
if anchor.contains(LEFT) { if anchor.contains(LEFT) {
@ -349,6 +358,9 @@ impl SurfaceExt for ZwlrLayerSurfaceV1 {
} }
fn after_apply_commit(self: Rc<Self>) { fn after_apply_commit(self: Rc<Self>) {
let Some(output) = self.output.node() else {
return;
};
let buffer_is_some = self.surface.buffer.is_some(); let buffer_is_some = self.surface.buffer.is_some();
let was_mapped = self.mapped.get(); let was_mapped = self.mapped.get();
if self.mapped.get() { if self.mapped.get() {
@ -362,13 +374,13 @@ impl SurfaceExt for ZwlrLayerSurfaceV1 {
} }
} }
} else if buffer_is_some { } else if buffer_is_some {
let layer = &self.output.layers[self.layer.get() as usize]; let layer = &output.layers[self.layer.get() as usize];
self.link.set(Some(layer.add_last(self.clone()))); self.link.set(Some(layer.add_last(self.clone())));
self.mapped.set(true); self.mapped.set(true);
self.compute_position(); self.compute_position();
} }
if self.mapped.get() != was_mapped { if self.mapped.get() != was_mapped {
self.output.update_visible(); output.update_visible();
} }
if self.mapped.get() { if self.mapped.get() {
match self.keyboard_interactivity.get() { match self.keyboard_interactivity.get() {

View file

@ -57,17 +57,17 @@ impl ZwlrLayerShellV1RequestHandler for ZwlrLayerShellV1 {
let surface = self.client.lookup(req.surface)?; let surface = self.client.lookup(req.surface)?;
let output = 'get_output: { let output = 'get_output: {
if req.output.is_some() { if req.output.is_some() {
self.client.lookup(req.output)?.global.node.get().unwrap() self.client.lookup(req.output)?.global.clone()
} else { } else {
for seat in self.client.state.seat_queue.rev_iter() { for seat in self.client.state.seat_queue.rev_iter() {
let output = seat.get_output(); let output = seat.get_output();
if !output.is_dummy { if !output.is_dummy {
break 'get_output output; break 'get_output output.global.opt.clone();
} }
} }
let outputs = self.client.state.outputs.lock(); let outputs = self.client.state.outputs.lock();
if let Some(output) = outputs.values().next() { if let Some(output) = outputs.values().next() {
break 'get_output output.node.clone(); break 'get_output output.node.global.opt.clone();
} }
return Err(ZwlrLayerShellV1Error::NoOutputs); return Err(ZwlrLayerShellV1Error::NoOutputs);
} }

View file

@ -4,7 +4,7 @@ use {
format::XRGB8888, format::XRGB8888,
ifs::{ ifs::{
wl_buffer::{WlBuffer, WlBufferError, WlBufferStorage}, wl_buffer::{WlBuffer, WlBufferError, WlBufferStorage},
wl_output::WlOutputGlobal, wl_output::OutputGlobalOpt,
}, },
leaks::Tracker, leaks::Tracker,
object::{Object, Version}, object::{Object, Version},
@ -22,7 +22,7 @@ pub struct ZwlrScreencopyFrameV1 {
pub id: ZwlrScreencopyFrameV1Id, pub id: ZwlrScreencopyFrameV1Id,
pub client: Rc<Client>, pub client: Rc<Client>,
pub tracker: Tracker<Self>, pub tracker: Tracker<Self>,
pub output: Rc<WlOutputGlobal>, pub output: Rc<OutputGlobalOpt>,
pub rect: Rect, pub rect: Rect,
pub overlay_cursor: bool, pub overlay_cursor: bool,
pub used: Cell<bool>, pub used: Cell<bool>,
@ -46,14 +46,16 @@ impl ZwlrScreencopyFrameV1 {
} }
pub fn send_damage(&self) { pub fn send_damage(&self) {
let pos = self.output.pos.get(); if let Some(output) = self.output.get() {
self.client.event(Damage { let pos = output.pos.get();
self_id: self.id, self.client.event(Damage {
x: 0, self_id: self.id,
y: 0, x: 0,
width: pos.width() as _, y: 0,
height: pos.height() as _, width: pos.width() as _,
}); height: pos.height() as _,
});
}
} }
pub fn send_buffer(&self) { pub fn send_buffer(&self) {
@ -95,7 +97,7 @@ impl ZwlrScreencopyFrameV1 {
if self.used.replace(true) { if self.used.replace(true) {
return Err(ZwlrScreencopyFrameV1Error::AlreadyUsed); return Err(ZwlrScreencopyFrameV1Error::AlreadyUsed);
} }
let Some(node) = self.output.node.get() else { let Some(node) = self.output.node() else {
self.send_failed(); self.send_failed();
return Ok(()); return Ok(());
}; };
@ -114,7 +116,9 @@ impl ZwlrScreencopyFrameV1 {
} }
self.buffer.set(Some(buffer)); self.buffer.set(Some(buffer));
if !with_damage { if !with_damage {
self.output.connector.connector.damage(); if let Some(global) = self.output.get() {
global.connector.connector.damage();
}
} }
self.with_damage.set(with_damage); self.with_damage.set(with_damage);
node.screencopies node.screencopies
@ -124,7 +128,7 @@ impl ZwlrScreencopyFrameV1 {
} }
fn detach(&self) { fn detach(&self) {
if let Some(node) = self.output.node.get() { if let Some(node) = self.output.node() {
node.screencopies.remove(&(self.client.id, self.id)); node.screencopies.remove(&(self.client.id, self.id));
node.screencast_changed(); node.screencast_changed();
} }

View file

@ -105,10 +105,13 @@ impl ZwlrScreencopyManagerV1 {
region: Option<Rect>, region: Option<Rect>,
) -> Result<(), ZwlrScreencopyManagerV1Error> { ) -> Result<(), ZwlrScreencopyManagerV1Error> {
let output = self.client.lookup(output)?; let output = self.client.lookup(output)?;
let mode = output.global.mode.get(); let Some(global) = output.global.get() else {
return Ok(());
};
let mode = global.mode.get();
let mut rect = Rect::new_sized(0, 0, mode.width, mode.height).unwrap(); let mut rect = Rect::new_sized(0, 0, mode.width, mode.height).unwrap();
if let Some(region) = region { if let Some(region) = region {
let scale = output.global.persistent.scale.get().to_f64(); let scale = global.persistent.scale.get().to_f64();
let x1 = (region.x1() as f64 * scale).round() as i32; let x1 = (region.x1() as f64 * scale).round() as i32;
let y1 = (region.y1() as f64 * scale).round() as i32; let y1 = (region.y1() as f64 * scale).round() as i32;
let x2 = (region.x2() as f64 * scale).round() as i32; let x2 = (region.x2() as f64 * scale).round() as i32;

View file

@ -60,11 +60,14 @@ impl ZxdgOutputV1 {
} }
pub fn send_updates(&self) { pub fn send_updates(&self) {
let pos = self.output.global.position(); let Some(global) = self.output.global.get() else {
return;
};
let pos = global.position();
self.send_logical_position(pos.x1(), pos.y1()); self.send_logical_position(pos.x1(), pos.y1());
self.send_logical_size(pos.width(), pos.height()); self.send_logical_size(pos.width(), pos.height());
if self.version >= NAME_SINCE { if self.version >= NAME_SINCE {
self.send_name(&self.output.global.connector.name); self.send_name(&global.connector.name);
} }
if self.version >= NO_DONE_SINCE { if self.version >= NO_DONE_SINCE {
if self.output.version >= SEND_DONE_SINCE { if self.output.version >= SEND_DONE_SINCE {

View file

@ -158,7 +158,8 @@ impl ConnectorHandler {
node: on.clone(), node: on.clone(),
}); });
self.state.outputs.set(self.id, output_data); self.state.outputs.set(self.id, output_data);
global.node.set(Some(on.clone())); global.opt.node.set(Some(on.clone()));
global.opt.global.set(Some(global.clone()));
let mut ws_to_move = VecDeque::new(); let mut ws_to_move = VecDeque::new();
if self.state.outputs.len() == 1 { if self.state.outputs.len() == 1 {
let seats = self.state.globals.seats.lock(); let seats = self.state.globals.seats.lock();
@ -227,10 +228,9 @@ impl ConnectorHandler {
if let Some(config) = self.state.config.get() { if let Some(config) = self.state.config.get() {
config.connector_disconnected(self.id); config.connector_disconnected(self.id);
} }
global.node.set(None); global.clear();
for (_, jo) in on.jay_outputs.lock().drain() { for (_, jo) in on.jay_outputs.lock().drain() {
jo.send_destroyed(); jo.send_destroyed();
jo.output.take();
} }
let screencasts: Vec<_> = on.screencasts.lock().values().cloned().collect(); let screencasts: Vec<_> = on.screencasts.lock().values().cloned().collect();
for sc in screencasts { for sc in screencasts {