diff --git a/src/globals.rs b/src/globals.rs index e73fe0bf..41aeb925 100644 --- a/src/globals.rs +++ b/src/globals.rs @@ -127,6 +127,7 @@ pub trait Global: GlobalBase { pub struct Globals { next_name: NumCell, registry: CopyHashMap>, + removed: CopyHashMap>, pub outputs: CopyHashMap>, pub seats: CopyHashMap>, } @@ -136,6 +137,7 @@ impl Globals { let slf = Self { next_name: NumCell::new(1), registry: CopyHashMap::new(), + removed: CopyHashMap::new(), outputs: Default::default(), seats: Default::default(), }; @@ -241,9 +243,17 @@ impl Globals { Ok(global) } - pub fn remove(&self, state: &State, global: &T) -> Result<(), GlobalsError> { + pub fn remove( + &self, + state: &State, + global: &T, + ) -> Result<(), GlobalsError> { let _global = self.take(global.name(), true)?; global.remove(self); + let replacement = global.create_replacement(); + assert_eq!(global.name(), replacement.name()); + assert_eq!(global.interface().0, replacement.interface().0); + self.removed.set(global.name(), replacement); self.broadcast(state, global.required_caps(), global.xwayland_only(), |r| { r.send_global_remove(global.name()) }); @@ -295,7 +305,10 @@ impl Globals { let res = if remove { self.registry.remove(&name) } else { - self.registry.get(&name) + match self.registry.get(&name) { + Some(res) => Some(res), + _ => self.removed.get(&name), + } }; match res { Some(g) => Ok(g), @@ -330,3 +343,7 @@ pub trait WaylandGlobal: Global + 'static { let _ = globals; } } + +pub trait RemovableWaylandGlobal: WaylandGlobal { + fn create_replacement(&self) -> Rc; +} diff --git a/src/ifs/ext_session_lock_v1.rs b/src/ifs/ext_session_lock_v1.rs index ca2db3af..6fad8599 100644 --- a/src/ifs/ext_session_lock_v1.rs +++ b/src/ifs/ext_session_lock_v1.rs @@ -57,20 +57,20 @@ impl ExtSessionLockV1RequestHandler for ExtSessionLockV1 { surface, tracker: Default::default(), serial: Default::default(), - output: output.global.node.get(), + output: output.global.clone(), seat_state: Default::default(), version: self.version, }); track!(new.client, new); new.install()?; self.client.add_client_obj(&new)?; - if !output.global.destroyed.get() && !self.finished.get() { - if let Some(node) = output.global.node.get() { + if !self.finished.get() { + if let Some(node) = output.global.node() { if node.lock_surface.is_some() { return Err(ExtSessionLockV1Error::OutputAlreadyLocked); } node.set_lock_surface(Some(new.clone())); - let pos = output.global.pos.get(); + let pos = node.global.pos.get(); new.change_extents(pos); self.client.state.tree_changed(); } diff --git a/src/ifs/jay_compositor.rs b/src/ifs/jay_compositor.rs index d98580de..a25ff3ee 100644 --- a/src/ifs/jay_compositor.rs +++ b/src/ifs/jay_compositor.rs @@ -21,7 +21,7 @@ use { leaks::Tracker, object::{Object, Version}, screenshoter::take_screenshot, - utils::{clonecell::CloneCell, errorfmt::ErrorFmt}, + utils::errorfmt::ErrorFmt, wire::{jay_compositor::*, JayCompositorId, JayScreenshotId}, }, bstr::ByteSlice, @@ -264,12 +264,12 @@ impl JayCompositorRequestHandler for JayCompositor { let jo = Rc::new(JayOutput { id: req.id, client: self.client.clone(), - output: CloneCell::new(output.global.node.get()), + output: output.global.clone(), tracker: Default::default(), }); track!(self.client, 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()); jo.send_linear_id(); } else { diff --git a/src/ifs/jay_output.rs b/src/ifs/jay_output.rs index b56ec159..e6532b73 100644 --- a/src/ifs/jay_output.rs +++ b/src/ifs/jay_output.rs @@ -1,10 +1,9 @@ use { crate::{ client::{Client, ClientError}, + ifs::wl_output::OutputGlobalOpt, leaks::Tracker, object::{Object, Version}, - tree::OutputNode, - utils::clonecell::CloneCell, wire::{jay_output::*, JayOutputId}, }, std::rc::Rc, @@ -14,7 +13,7 @@ use { pub struct JayOutput { pub id: JayOutputId, pub client: Rc, - pub output: CloneCell>>, + pub output: Rc, pub tracker: Tracker, } @@ -24,7 +23,7 @@ impl JayOutput { } 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_id: self.id, linear_id: output.id.raw(), @@ -33,7 +32,7 @@ impl JayOutput { } 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)); } } diff --git a/src/ifs/jay_screencast.rs b/src/ifs/jay_screencast.rs index cd4215ad..e5308f4b 100644 --- a/src/ifs/jay_screencast.rs +++ b/src/ifs/jay_screencast.rs @@ -519,7 +519,7 @@ impl JayScreencastRequestHandler for JayScreencast { if let Some(new) = target { match new { PendingTarget::Output(o) => { - let Some(o) = o.output.get() else { + let Some(o) = o.output.node() else { self.do_destroy(); return Ok(()); }; diff --git a/src/ifs/wl_output.rs b/src/ifs/wl_output.rs index 75cd943c..0e9c5ea8 100644 --- a/src/ifs/wl_output.rs +++ b/src/ifs/wl_output.rs @@ -1,3 +1,5 @@ +mod removed_output; + use { crate::{ backend, @@ -55,13 +57,34 @@ pub struct WlOutputGlobal { pub output_id: Rc, pub mode: Cell, pub modes: Vec, - pub node: CloneCell>>, pub width_mm: i32, pub height_mm: i32, pub bindings: RefCell>>>, pub destroyed: Cell, pub legacy_scale: Cell, pub persistent: Rc, + pub opt: Rc, +} + +#[derive(Default)] +pub struct OutputGlobalOpt { + pub global: CloneCell>>, + pub node: CloneCell>>, +} + +impl OutputGlobalOpt { + pub fn get(&self) -> Option> { + self.global.get() + } + + pub fn node(&self) -> Option> { + self.node.get() + } + + pub fn clear(&self) { + self.node.take(); + self.global.take(); + } } pub struct PersistentOutputState { @@ -80,7 +103,7 @@ pub struct OutputId { impl WlOutputGlobal { pub fn clear(&self) { - self.node.take(); + self.opt.clear(); self.bindings.borrow_mut().clear(); } @@ -110,13 +133,13 @@ impl WlOutputGlobal { output_id: output_id.clone(), mode: Cell::new(*mode), modes, - node: Default::default(), width_mm, height_mm, bindings: Default::default(), destroyed: Cell::new(false), legacy_scale: Cell::new(scale.round_up()), persistent: persistent_state.clone(), + opt: Default::default(), } } @@ -169,7 +192,7 @@ impl WlOutputGlobal { version: Version, ) -> Result<(), WlOutputError> { let obj = Rc::new(WlOutput { - global: self.clone(), + global: self.opt.clone(), id, xdg_outputs: Default::default(), client: client.clone(), @@ -208,13 +231,15 @@ impl WlOutputGlobal { global_base!(WlOutputGlobal, WlOutput, WlOutputError); +const OUTPUT_VERSION: u32 = 4; + impl Global for WlOutputGlobal { fn singleton(&self) -> bool { false } fn version(&self) -> u32 { - 4 + OUTPUT_VERSION } fn break_loops(&self) { @@ -225,7 +250,7 @@ impl Global for WlOutputGlobal { dedicated_add_global!(WlOutputGlobal, outputs); pub struct WlOutput { - pub global: Rc, + pub global: Rc, pub id: WlOutputId, pub xdg_outputs: CopyHashMap>, client: Rc, @@ -239,23 +264,29 @@ pub const SEND_NAME_SINCE: Version = Version(4); impl WlOutput { 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 { self_id: self.id, x: pos.x1(), y: pos.y1(), - physical_width: self.global.width_mm, - physical_height: self.global.height_mm, + physical_width: global.width_mm, + physical_height: global.height_mm, subpixel: SP_UNKNOWN, - make: &self.global.output_id.manufacturer, - model: &self.global.output_id.model, - transform: self.global.persistent.transform.get().to_wl(), + make: &global.output_id.manufacturer, + model: &global.output_id.model, + transform: global.persistent.transform.get().to_wl(), }; self.client.event(event); } 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 { self_id: self.id, flags: MODE_CURRENT, @@ -267,17 +298,23 @@ impl WlOutput { } fn send_scale(self: &Rc) { + let Some(global) = self.global.get() else { + return; + }; let event = Scale { self_id: self.id, - factor: self.global.legacy_scale.get() as _, + factor: global.legacy_scale.get() as _, }; self.client.event(event); } fn send_name(&self) { + let Some(global) = self.global.get() else { + return; + }; self.client.event(Name { self_id: self.id, - name: &self.global.connector.name, + name: &global.connector.name, }); } @@ -287,12 +324,15 @@ impl WlOutput { } 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); if e.get().is_empty() { e.remove(); } - } + }; } } diff --git a/src/ifs/wl_output/removed_output.rs b/src/ifs/wl_output/removed_output.rs new file mode 100644 index 00000000..67072aec --- /dev/null +++ b/src/ifs/wl_output/removed_output.rs @@ -0,0 +1,63 @@ +use { + crate::{ + client::{Client, ClientError}, + globals::{Global, GlobalName, RemovableWaylandGlobal}, + ifs::wl_output::{WlOutput, WlOutputGlobal, OUTPUT_VERSION}, + object::Version, + wire::WlOutputId, + }, + std::rc::Rc, + thiserror::Error, +}; + +struct RemovedOutputGlobal { + name: GlobalName, +} + +impl RemovedOutputGlobal { + fn bind_( + self: Rc, + id: WlOutputId, + client: &Rc, + version: Version, + ) -> Result<(), RemovedOutputError> { + let obj = Rc::new(WlOutput { + global: Default::default(), + id, + xdg_outputs: Default::default(), + client: client.clone(), + version, + tracker: Default::default(), + }); + track!(client, obj); + client.add_client_obj(&obj)?; + Ok(()) + } +} + +global_base!(RemovedOutputGlobal, WlOutput, RemovedOutputError); + +impl Global for RemovedOutputGlobal { + fn singleton(&self) -> bool { + false + } + + fn version(&self) -> u32 { + OUTPUT_VERSION + } +} + +simple_add_global!(RemovedOutputGlobal); + +impl RemovableWaylandGlobal for WlOutputGlobal { + fn create_replacement(&self) -> Rc { + Rc::new(RemovedOutputGlobal { name: self.name }) + } +} + +#[derive(Debug, Error)] +enum RemovedOutputError { + #[error(transparent)] + ClientError(Box), +} +efrom!(RemovedOutputError, ClientError); diff --git a/src/ifs/wl_surface/ext_session_lock_surface_v1.rs b/src/ifs/wl_surface/ext_session_lock_surface_v1.rs index dcc36b78..485a9a75 100644 --- a/src/ifs/wl_surface/ext_session_lock_surface_v1.rs +++ b/src/ifs/wl_surface/ext_session_lock_surface_v1.rs @@ -3,13 +3,14 @@ use { client::{Client, ClientError}, fixed::Fixed, ifs::{ + wl_output::OutputGlobalOpt, wl_seat::{NodeSeatState, WlSeatGlobal}, wl_surface::{SurfaceExt, SurfaceRole, WlSurface, WlSurfaceError}, }, leaks::Tracker, object::{Object, Version}, rect::Rect, - tree::{FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId, NodeVisitor, OutputNode}, + tree::{FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId, NodeVisitor}, utils::numcell::NumCell, wire::{ext_session_lock_surface_v1::*, ExtSessionLockSurfaceV1Id, WlSurfaceId}, }, @@ -24,7 +25,7 @@ pub struct ExtSessionLockSurfaceV1 { pub surface: Rc, pub tracker: Tracker, pub serial: NumCell, - pub output: Option>, + pub output: Rc, pub seat_state: NodeSeatState, pub version: Version, } @@ -73,7 +74,7 @@ impl ExtSessionLockSurfaceV1RequestHandler for ExtSessionLockSurfaceV1 { impl ExtSessionLockSurfaceV1 { 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 ls.node_id == self.node_id { output.set_lock_surface(None); diff --git a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs index 1922da73..31ab0432 100644 --- a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs +++ b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs @@ -321,7 +321,7 @@ impl XdgToplevelRequestHandler for XdgToplevel { self.states.borrow_mut().insert(STATE_FULLSCREEN); 'set_fullscreen: { 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, _ => { log::error!("Output global has no node attached"); diff --git a/src/ifs/wl_surface/zwlr_layer_surface_v1.rs b/src/ifs/wl_surface/zwlr_layer_surface_v1.rs index c47de002..52cf702f 100644 --- a/src/ifs/wl_surface/zwlr_layer_surface_v1.rs +++ b/src/ifs/wl_surface/zwlr_layer_surface_v1.rs @@ -2,6 +2,7 @@ use { crate::{ client::{Client, ClientError}, ifs::{ + wl_output::OutputGlobalOpt, wl_seat::NodeSeatState, wl_surface::{PendingState, SurfaceExt, SurfaceRole, WlSurface, WlSurfaceError}, zwlr_layer_shell_v1::{ZwlrLayerShellV1, OVERLAY}, @@ -10,7 +11,7 @@ use { object::Object, rect::Rect, renderer::Renderer, - tree::{FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId, NodeVisitor, OutputNode}, + tree::{FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId, NodeVisitor}, utils::{ bitflags::BitflagsExt, cell_ext::CellExt, linkedlist::LinkedNode, numcell::NumCell, option_ext::OptionExt, @@ -43,7 +44,7 @@ pub struct ZwlrLayerSurfaceV1 { pub shell: Rc, pub client: Rc, pub surface: Rc, - pub output: Rc, + pub output: Rc, pub namespace: String, pub tracker: Tracker, output_pos: Cell, @@ -96,7 +97,7 @@ impl ZwlrLayerSurfaceV1 { id: ZwlrLayerSurfaceV1Id, shell: &Rc, surface: &Rc, - output: &Rc, + output: &Rc, layer: u32, namespace: &str, ) -> Self { @@ -131,7 +132,9 @@ impl ZwlrLayerSurfaceV1 { return Err(ZwlrLayerSurfaceV1Error::AlreadyAttached(self.surface.id)); } 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(()) } @@ -241,6 +244,9 @@ impl ZwlrLayerSurfaceV1RequestHandler for ZwlrLayerSurfaceV1 { impl ZwlrLayerSurfaceV1 { 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 mut send_configure = mem::replace(&mut pending.any, false); if let Some(size) = pending.size.take() { @@ -269,14 +275,14 @@ impl ZwlrLayerSurfaceV1 { return Err(ZwlrLayerSurfaceV1Error::WidthZero); } send_configure = true; - width = self.output.global.position().width(); + width = global.position().width(); } if height == 0 { if !anchor.contains(TOP | BOTTOM) { return Err(ZwlrLayerSurfaceV1Error::HeightZero); } send_configure = true; - height = self.output.global.position().height(); + height = global.position().height(); } self.size.set((width, height)); } @@ -300,12 +306,15 @@ impl ZwlrLayerSurfaceV1 { } pub fn compute_position(&self) { + let Some(global) = self.output.get() else { + return; + }; let (width, height) = self.size.get(); let mut anchor = self.anchor.get(); if anchor == 0 { anchor = LEFT | RIGHT | TOP | BOTTOM; } - let opos = self.output.global.pos.get(); + let opos = global.pos.get(); let mut x1 = 0; let mut y1 = 0; if anchor.contains(LEFT) { @@ -349,6 +358,9 @@ impl SurfaceExt for ZwlrLayerSurfaceV1 { } fn after_apply_commit(self: Rc) { + let Some(output) = self.output.node() else { + return; + }; let buffer_is_some = self.surface.buffer.is_some(); let was_mapped = self.mapped.get(); if self.mapped.get() { @@ -362,13 +374,13 @@ impl SurfaceExt for ZwlrLayerSurfaceV1 { } } } 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.mapped.set(true); self.compute_position(); } if self.mapped.get() != was_mapped { - self.output.update_visible(); + output.update_visible(); } if self.mapped.get() { match self.keyboard_interactivity.get() { diff --git a/src/ifs/zwlr_layer_shell_v1.rs b/src/ifs/zwlr_layer_shell_v1.rs index 7391cea0..c192fb38 100644 --- a/src/ifs/zwlr_layer_shell_v1.rs +++ b/src/ifs/zwlr_layer_shell_v1.rs @@ -57,17 +57,17 @@ impl ZwlrLayerShellV1RequestHandler for ZwlrLayerShellV1 { let surface = self.client.lookup(req.surface)?; let output = 'get_output: { if req.output.is_some() { - self.client.lookup(req.output)?.global.node.get().unwrap() + self.client.lookup(req.output)?.global.clone() } else { for seat in self.client.state.seat_queue.rev_iter() { let output = seat.get_output(); if !output.is_dummy { - break 'get_output output; + break 'get_output output.global.opt.clone(); } } let outputs = self.client.state.outputs.lock(); 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); } diff --git a/src/ifs/zwlr_screencopy_frame_v1.rs b/src/ifs/zwlr_screencopy_frame_v1.rs index f8f121d5..710bab74 100644 --- a/src/ifs/zwlr_screencopy_frame_v1.rs +++ b/src/ifs/zwlr_screencopy_frame_v1.rs @@ -4,7 +4,7 @@ use { format::XRGB8888, ifs::{ wl_buffer::{WlBuffer, WlBufferError, WlBufferStorage}, - wl_output::WlOutputGlobal, + wl_output::OutputGlobalOpt, }, leaks::Tracker, object::{Object, Version}, @@ -22,7 +22,7 @@ pub struct ZwlrScreencopyFrameV1 { pub id: ZwlrScreencopyFrameV1Id, pub client: Rc, pub tracker: Tracker, - pub output: Rc, + pub output: Rc, pub rect: Rect, pub overlay_cursor: bool, pub used: Cell, @@ -46,14 +46,16 @@ impl ZwlrScreencopyFrameV1 { } pub fn send_damage(&self) { - let pos = self.output.pos.get(); - self.client.event(Damage { - self_id: self.id, - x: 0, - y: 0, - width: pos.width() as _, - height: pos.height() as _, - }); + if let Some(output) = self.output.get() { + let pos = output.pos.get(); + self.client.event(Damage { + self_id: self.id, + x: 0, + y: 0, + width: pos.width() as _, + height: pos.height() as _, + }); + } } pub fn send_buffer(&self) { @@ -95,7 +97,7 @@ impl ZwlrScreencopyFrameV1 { if self.used.replace(true) { return Err(ZwlrScreencopyFrameV1Error::AlreadyUsed); } - let Some(node) = self.output.node.get() else { + let Some(node) = self.output.node() else { self.send_failed(); return Ok(()); }; @@ -114,7 +116,9 @@ impl ZwlrScreencopyFrameV1 { } self.buffer.set(Some(buffer)); 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); node.screencopies @@ -124,7 +128,7 @@ impl ZwlrScreencopyFrameV1 { } 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.screencast_changed(); } diff --git a/src/ifs/zwlr_screencopy_manager_v1.rs b/src/ifs/zwlr_screencopy_manager_v1.rs index 5df2a52f..07452ca4 100644 --- a/src/ifs/zwlr_screencopy_manager_v1.rs +++ b/src/ifs/zwlr_screencopy_manager_v1.rs @@ -105,10 +105,13 @@ impl ZwlrScreencopyManagerV1 { region: Option, ) -> Result<(), ZwlrScreencopyManagerV1Error> { 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(); 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 y1 = (region.y1() as f64 * scale).round() as i32; let x2 = (region.x2() as f64 * scale).round() as i32; diff --git a/src/ifs/zxdg_output_v1.rs b/src/ifs/zxdg_output_v1.rs index 8c3377de..a309f751 100644 --- a/src/ifs/zxdg_output_v1.rs +++ b/src/ifs/zxdg_output_v1.rs @@ -60,11 +60,14 @@ impl ZxdgOutputV1 { } 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_size(pos.width(), pos.height()); 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.output.version >= SEND_DONE_SINCE { diff --git a/src/state.rs b/src/state.rs index fe49b79e..be8797f7 100644 --- a/src/state.rs +++ b/src/state.rs @@ -22,7 +22,7 @@ use { SyncFile, }, gfx_apis::create_gfx_context, - globals::{Globals, GlobalsError, WaylandGlobal}, + globals::{Globals, GlobalsError, RemovableWaylandGlobal, WaylandGlobal}, ifs::{ ext_foreign_toplevel_list_v1::ExtForeignToplevelListV1, ext_session_lock_v1::ExtSessionLockV1, @@ -511,7 +511,7 @@ impl State { self.globals.add_global(self, global) } - pub fn remove_global(&self, global: &T) -> Result<(), GlobalsError> { + pub fn remove_global(&self, global: &T) -> Result<(), GlobalsError> { self.globals.remove(self, global) } diff --git a/src/tasks/connector.rs b/src/tasks/connector.rs index 9cf069c2..2b574556 100644 --- a/src/tasks/connector.rs +++ b/src/tasks/connector.rs @@ -158,7 +158,8 @@ impl ConnectorHandler { node: on.clone(), }); 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(); if self.state.outputs.len() == 1 { let seats = self.state.globals.seats.lock(); @@ -227,10 +228,9 @@ impl ConnectorHandler { if let Some(config) = self.state.config.get() { config.connector_disconnected(self.id); } - global.node.set(None); + global.clear(); for (_, jo) in on.jay_outputs.lock().drain() { jo.send_destroyed(); - jo.output.take(); } let screencasts: Vec<_> = on.screencasts.lock().values().cloned().collect(); for sc in screencasts {