diff --git a/src/compositor.rs b/src/compositor.rs index 959cf32e..1d1f64f9 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -359,8 +359,9 @@ fn create_dummy_output(state: &Rc) { height: 0, refresh_rate_millihz: 0, }, - "none", - "none", + "jay", + "dummy-output", + "0", 0, 0, )), @@ -378,6 +379,7 @@ fn create_dummy_output(state: &Rc) { }); let dummy_workspace = Rc::new(WorkspaceNode { id: state.node_ids.next(), + is_dummy: true, output: CloneCell::new(dummy_output.clone()), position: Default::default(), container: Default::default(), @@ -387,6 +389,8 @@ fn create_dummy_output(state: &Rc) { output_link: Default::default(), visible: Default::default(), fullscreen: Default::default(), + visible_on_desired_output: Default::default(), + desired_output: CloneCell::new(dummy_output.global.output_id.clone()), }); dummy_workspace.output_link.set(Some( dummy_output.workspaces.add_last(dummy_workspace.clone()), diff --git a/src/ifs/wl_output.rs b/src/ifs/wl_output.rs index 1579faea..285321b4 100644 --- a/src/ifs/wl_output.rs +++ b/src/ifs/wl_output.rs @@ -70,8 +70,7 @@ pub struct WlOutputGlobal { pub state: Rc, pub connector: Rc, pub pos: Cell, - pub manufacturer: String, - pub display: String, + pub output_id: Rc, pub mode: Cell, pub node: CloneCell>>, pub width_mm: i32, @@ -82,6 +81,13 @@ pub struct WlOutputGlobal { pub destroyed: Cell, } +#[derive(Eq, PartialEq)] +pub struct OutputId { + pub manufacturer: String, + pub model: String, + pub serial_number: String, +} + impl WlOutputGlobal { pub fn clear(&self) { self.node.take(); @@ -96,6 +102,7 @@ impl WlOutputGlobal { mode: &backend::Mode, manufacturer: &str, product: &str, + serial_number: &str, width_mm: i32, height_mm: i32, ) -> Self { @@ -104,8 +111,11 @@ impl WlOutputGlobal { state: state.clone(), connector: connector.clone(), pos: Cell::new(Rect::new_sized(x1, 0, mode.width, mode.height).unwrap()), - manufacturer: manufacturer.to_string(), - display: product.to_string(), + output_id: Rc::new(OutputId { + manufacturer: manufacturer.to_string(), + model: product.to_string(), + serial_number: serial_number.to_string(), + }), mode: Cell::new(*mode), node: Default::default(), width_mm, @@ -268,8 +278,8 @@ impl WlOutput { physical_width: self.global.width_mm, physical_height: self.global.height_mm, subpixel: SP_UNKNOWN, - make: &self.global.manufacturer, - model: &self.global.display, + make: &self.global.output_id.manufacturer, + model: &self.global.output_id.model, transform: TF_NORMAL, }; self.client.event(event); diff --git a/src/state.rs b/src/state.rs index 6d37da4e..64ae1da8 100644 --- a/src/state.rs +++ b/src/state.rs @@ -395,6 +395,7 @@ impl State { } let workspace = Rc::new(WorkspaceNode { id: self.node_ids.next(), + is_dummy: false, output: CloneCell::new(output.clone()), position: Cell::new(Default::default()), container: Default::default(), @@ -404,6 +405,8 @@ impl State { output_link: Cell::new(None), visible: Cell::new(false), fullscreen: Default::default(), + visible_on_desired_output: Cell::new(false), + desired_output: CloneCell::new(output.global.output_id.clone()), }); workspace .output_link diff --git a/src/tasks/connector.rs b/src/tasks/connector.rs index beaf3b01..d58c702b 100644 --- a/src/tasks/connector.rs +++ b/src/tasks/connector.rs @@ -97,6 +97,7 @@ impl ConnectorHandler { &info.initial_mode, &info.manufacturer, &info.product, + &info.serial_number, info.width_mm, info.height_mm, )); @@ -138,6 +139,46 @@ impl ConnectorHandler { if let Some(config) = self.state.config.get() { config.connector_connected(self.id); } + { + for source in self.state.outputs.lock().values() { + if source.node.id == on.id { + continue; + } + let mut ws_to_move = vec![]; + for ws in source.node.workspaces.iter() { + if ws.is_dummy { + continue; + } + if ws.desired_output.get() == global.output_id { + ws_to_move.push(ws.clone()); + } + } + for ws in ws_to_move { + on.workspaces.add_last_existing(&ws); + if ws.visible_on_desired_output.get() && on.workspace.get().is_none() { + on.show_workspace(&ws); + } else { + ws.set_visible(false); + } + if let Some(visible) = source.node.workspace.get() { + if visible.id == ws.id { + source.node.workspace.take(); + } + } + } + if source.node.workspace.get().is_none() { + if let Some(ws) = source.node.workspaces.first() { + source.node.show_workspace(&ws); + } + } + source.node.update_render_data(); + } + if on.workspace.get().is_none() { + if let Some(ws) = on.workspaces.first() { + on.show_workspace(&ws); + } + } + } on.update_render_data(); self.state.root.outputs.set(self.id, on.clone()); self.state.root.update_extents(); @@ -177,6 +218,7 @@ impl ConnectorHandler { for ws in on.workspaces.iter() { let is_visible = !target_is_dummy && target.workspaces.is_empty() && ws.visible.get(); + ws.visible_on_desired_output.set(ws.visible.get()); ws.output.set(target.clone()); target.workspaces.add_last_existing(&ws); if is_visible { diff --git a/src/tree/output.rs b/src/tree/output.rs index e3a996c1..9fe510bc 100644 --- a/src/tree/output.rs +++ b/src/tree/output.rs @@ -168,6 +168,7 @@ impl OutputNode { }; let workspace = Rc::new(WorkspaceNode { id: self.state.node_ids.next(), + is_dummy: false, output: CloneCell::new(self.clone()), position: Default::default(), container: Default::default(), @@ -177,6 +178,8 @@ impl OutputNode { output_link: Default::default(), visible: Cell::new(true), fullscreen: Default::default(), + visible_on_desired_output: Cell::new(false), + desired_output: CloneCell::new(self.global.output_id.clone()), }); self.state.workspaces.set(name, workspace.clone()); workspace @@ -214,6 +217,7 @@ impl OutputNode { pub fn create_workspace(self: &Rc, name: &str) -> Rc { let ws = Rc::new(WorkspaceNode { id: self.state.node_ids.next(), + is_dummy: false, output: CloneCell::new(self.clone()), position: Cell::new(Default::default()), container: Default::default(), @@ -223,6 +227,8 @@ impl OutputNode { output_link: Cell::new(None), visible: Cell::new(false), fullscreen: Default::default(), + visible_on_desired_output: Cell::new(false), + desired_output: CloneCell::new(self.global.output_id.clone()), }); ws.output_link .set(Some(self.workspaces.add_last(ws.clone()))); diff --git a/src/tree/workspace.rs b/src/tree/workspace.rs index 073e4d69..a15e77bf 100644 --- a/src/tree/workspace.rs +++ b/src/tree/workspace.rs @@ -1,7 +1,10 @@ use { crate::{ cursor::KnownCursor, - ifs::wl_seat::{NodeSeatState, WlSeatGlobal}, + ifs::{ + wl_output::OutputId, + wl_seat::{NodeSeatState, WlSeatGlobal}, + }, rect::Rect, render::Renderer, tree::{ @@ -20,6 +23,7 @@ tree_id!(WorkspaceNodeId); pub struct WorkspaceNode { pub id: WorkspaceNodeId, + pub is_dummy: bool, pub output: CloneCell>, pub position: Cell, pub container: CloneCell>>, @@ -29,6 +33,8 @@ pub struct WorkspaceNode { pub output_link: Cell>>>, pub visible: Cell, pub fullscreen: CloneCell>>, + pub visible_on_desired_output: Cell, + pub desired_output: CloneCell>, } impl WorkspaceNode {