tree: restore workspaces after monitor reconnect
This commit is contained in:
parent
eaa3b85a97
commit
7476e6f2d9
6 changed files with 80 additions and 9 deletions
|
|
@ -359,8 +359,9 @@ fn create_dummy_output(state: &Rc<State>) {
|
|||
height: 0,
|
||||
refresh_rate_millihz: 0,
|
||||
},
|
||||
"none",
|
||||
"none",
|
||||
"jay",
|
||||
"dummy-output",
|
||||
"0",
|
||||
0,
|
||||
0,
|
||||
)),
|
||||
|
|
@ -378,6 +379,7 @@ fn create_dummy_output(state: &Rc<State>) {
|
|||
});
|
||||
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<State>) {
|
|||
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()),
|
||||
|
|
|
|||
|
|
@ -70,8 +70,7 @@ pub struct WlOutputGlobal {
|
|||
pub state: Rc<State>,
|
||||
pub connector: Rc<ConnectorData>,
|
||||
pub pos: Cell<Rect>,
|
||||
pub manufacturer: String,
|
||||
pub display: String,
|
||||
pub output_id: Rc<OutputId>,
|
||||
pub mode: Cell<backend::Mode>,
|
||||
pub node: CloneCell<Option<Rc<OutputNode>>>,
|
||||
pub width_mm: i32,
|
||||
|
|
@ -82,6 +81,13 @@ pub struct WlOutputGlobal {
|
|||
pub destroyed: Cell<bool>,
|
||||
}
|
||||
|
||||
#[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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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<Self>, name: &str) -> Rc<WorkspaceNode> {
|
||||
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())));
|
||||
|
|
|
|||
|
|
@ -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<Rc<OutputNode>>,
|
||||
pub position: Cell<Rect>,
|
||||
pub container: CloneCell<Option<Rc<ContainerNode>>>,
|
||||
|
|
@ -29,6 +33,8 @@ pub struct WorkspaceNode {
|
|||
pub output_link: Cell<Option<LinkedNode<Rc<WorkspaceNode>>>>,
|
||||
pub visible: Cell<bool>,
|
||||
pub fullscreen: CloneCell<Option<Rc<dyn ToplevelNode>>>,
|
||||
pub visible_on_desired_output: Cell<bool>,
|
||||
pub desired_output: CloneCell<Rc<OutputId>>,
|
||||
}
|
||||
|
||||
impl WorkspaceNode {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue