diff --git a/default-config/src/lib.rs b/default-config/src/lib.rs index 2c34e9b5..ba5d14a5 100644 --- a/default-config/src/lib.rs +++ b/default-config/src/lib.rs @@ -78,6 +78,7 @@ fn configure_seat(s: Seat) { for (i, sym) in fnkeys2.into_iter().enumerate() { let ws = get_workspace(&format!("{}", i + 1)); s.bind(MOD | sym, move || s.show_workspace(ws)); + s.bind(MOD | SHIFT | sym, move || s.set_workspace(ws)); } s.bind(MOD | SYM_a, || { diff --git a/src/config/handler.rs b/src/config/handler.rs index f89e88ad..3e5cf969 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -7,9 +7,9 @@ use { compositor::MAX_EXTENTS, ifs::wl_seat::{SeatId, WlSeatGlobal}, state::{ConnectorData, DeviceHandlerData, OutputData, State}, - tree::{ContainerNode, ContainerSplit, FloatNode, Node, NodeVisitorBase, WorkspaceNode}, + tree::{ContainerNode, ContainerSplit, FloatNode, Node, NodeVisitorBase}, utils::{ - clonecell::CloneCell, copyhashmap::CopyHashMap, debug_fn::debug_fn, errorfmt::ErrorFmt, + copyhashmap::CopyHashMap, debug_fn::debug_fn, errorfmt::ErrorFmt, numcell::NumCell, stack::Stack, }, xkbcommon::{XkbCommonError, XkbKeymap}, @@ -434,26 +434,7 @@ impl ConfigProxyHandler { let name = self.get_workspace(ws)?; let workspace = match self.state.workspaces.get(name.deref()) { Some(ws) => ws, - _ => { - let output = seat.get_output(); - let ws = Rc::new(WorkspaceNode { - id: self.state.node_ids.next(), - output: CloneCell::new(output.clone()), - position: Cell::new(Default::default()), - container: Default::default(), - stacked: Default::default(), - seat_state: Default::default(), - name: name.to_string(), - output_link: Cell::new(None), - visible: Cell::new(false), - fullscreen: Default::default(), - }); - ws.output_link - .set(Some(output.workspaces.add_last(ws.clone()))); - self.state.workspaces.set(name.to_string(), ws.clone()); - output.update_render_data(); - ws - } + _ => seat.get_output().create_workspace(name.deref()), }; seat.set_workspace(&workspace); Ok(()) diff --git a/src/ifs/wl_seat.rs b/src/ifs/wl_seat.rs index 76879f88..8106f461 100644 --- a/src/ifs/wl_seat.rs +++ b/src/ifs/wl_seat.rs @@ -199,7 +199,38 @@ impl WlSeatGlobal { self.output.get() } - pub fn set_workspace(&self, _ws: &Rc) {} + pub fn set_workspace(&self, ws: &Rc) { + let tl = match self.keyboard_node.get().node_toplevel() { + Some(tl) => tl, + _ => return, + }; + if tl.tl_data().is_fullscreen.get() { + return; + } + let old_ws = match tl.tl_data().workspace.get() { + Some(ws) => ws, + _ => return, + }; + if old_ws.id == ws.id { + return; + } + let cn = match tl.tl_data().parent.get().and_then(|p| p.node_into_containing_node()) { + Some(cn) => cn, + _ => return, + }; + let kb_foci = collect_kb_foci(tl.clone().tl_into_node()); + cn.cnode_remove_child2(tl.tl_as_node(), true); + if !ws.visible.get() { + for focus in kb_foci { + old_ws.clone().node_do_focus(&focus, Direction::Unspecified); + } + } + if tl.tl_data().is_floating.get() { + self.state.map_floating(tl.clone(), tl.tl_data().float_width.get(), tl.tl_data().float_height.get(), ws); + } else { + self.state.map_tiled_on(tl, ws); + } + } pub fn mark_last_active(self: &Rc) { self.queue_link diff --git a/src/state.rs b/src/state.rs index 598da0b0..b248a063 100644 --- a/src/state.rs +++ b/src/state.rs @@ -223,6 +223,10 @@ impl State { .or_else(|| self.dummy_output.get()) .unwrap(); let ws = output.ensure_workspace(); + self.map_tiled_on(node, &ws); + } + + pub fn map_tiled_on(self: &Rc, node: Rc, ws: &Rc) { if let Some(c) = ws.container.get() { let la = c.tl_last_active_child(); let lap = la diff --git a/src/tree/output.rs b/src/tree/output.rs index 284b30a6..5768872e 100644 --- a/src/tree/output.rs +++ b/src/tree/output.rs @@ -168,6 +168,29 @@ impl OutputNode { true } + pub fn create_workspace(self: &Rc, name: &str) -> Rc { + let ws = Rc::new(WorkspaceNode { + id: self.state.node_ids.next(), + output: CloneCell::new(self.clone()), + position: Cell::new(Default::default()), + container: Default::default(), + stacked: Default::default(), + seat_state: Default::default(), + name: name.to_string(), + output_link: Cell::new(None), + visible: Cell::new(false), + fullscreen: Default::default(), + }); + ws.output_link + .set(Some(self.workspaces.add_last(ws.clone()))); + self.state.workspaces.set(name.to_string(), ws.clone()); + if self.workspace.get().is_none() { + self.show_workspace(&ws); + } + self.update_render_data(); + ws + } + fn workspace_rect(&self) -> Rect { let rect = self.global.pos.get(); let th = self.state.theme.title_height.get();