1
0
Fork 0
forked from wry/wry

tree: restore workspaces after monitor reconnect

This commit is contained in:
Julian Orth 2022-05-20 12:55:45 +02:00
parent eaa3b85a97
commit 7476e6f2d9
6 changed files with 80 additions and 9 deletions

View file

@ -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()),

View file

@ -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);

View file

@ -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

View file

@ -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 {

View file

@ -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())));

View file

@ -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 {