shell: Track workspace amount per set

This commit is contained in:
Victoria Brekenfeld 2022-11-10 17:22:16 +01:00
parent 4f443a3aab
commit 6cec3cb7e0

View file

@ -49,7 +49,6 @@ pub struct Shell {
pub popups: PopupManager, pub popups: PopupManager,
pub outputs: Vec<Output>, pub outputs: Vec<Output>,
pub workspaces: WorkspaceMode, pub workspaces: WorkspaceMode,
pub workspace_amount: WorkspaceAmount,
pub floating_default: bool, pub floating_default: bool,
pub pending_windows: Vec<(Window, Seat<State>)>, pub pending_windows: Vec<(Window, Seat<State>)>,
pub pending_layers: Vec<(LayerSurface, Output, Seat<State>)>, pub pending_layers: Vec<(LayerSurface, Output, Seat<State>)>,
@ -65,6 +64,7 @@ pub struct Shell {
#[derive(Debug)] #[derive(Debug)]
pub struct WorkspaceSet { pub struct WorkspaceSet {
active: usize, active: usize,
amount: WorkspaceAmount,
group: WorkspaceGroupHandle, group: WorkspaceGroupHandle,
workspaces: Vec<Workspace>, workspaces: Vec<Workspace>,
} }
@ -120,6 +120,7 @@ impl WorkspaceSet {
WorkspaceSet { WorkspaceSet {
active: 0, active: 0,
amount,
group: group_handle, group: group_handle,
workspaces, workspaces,
} }
@ -136,12 +137,11 @@ impl WorkspaceSet {
fn refresh<'a>( fn refresh<'a>(
&mut self, &mut self,
amount: WorkspaceAmount,
state: &mut WorkspaceState<State>, state: &mut WorkspaceState<State>,
toplevel_info: &mut ToplevelInfoState<State>, toplevel_info: &mut ToplevelInfoState<State>,
outputs: impl Iterator<Item = (&'a Output, Point<i32, Logical>)>, outputs: impl Iterator<Item = (&'a Output, Point<i32, Logical>)>,
) { ) {
match amount { match self.amount {
WorkspaceAmount::Dynamic => self.ensure_last_empty(state, outputs), WorkspaceAmount::Dynamic => self.ensure_last_empty(state, outputs),
WorkspaceAmount::Static(len) => { WorkspaceAmount::Static(len) => {
self.ensure_static(len as usize, state, toplevel_info, outputs) self.ensure_static(len as usize, state, toplevel_info, outputs)
@ -257,7 +257,7 @@ impl WorkspaceSet {
#[derive(Debug)] #[derive(Debug)]
pub enum WorkspaceMode { pub enum WorkspaceMode {
OutputBound(HashMap<Output, WorkspaceSet>), OutputBound(HashMap<Output, WorkspaceSet>, WorkspaceAmount),
Global(WorkspaceSet), Global(WorkspaceSet),
} }
@ -271,14 +271,16 @@ impl WorkspaceMode {
crate::config::WorkspaceMode::Global => { crate::config::WorkspaceMode::Global => {
WorkspaceMode::Global(WorkspaceSet::new(state, amount)) WorkspaceMode::Global(WorkspaceSet::new(state, amount))
} }
crate::config::WorkspaceMode::OutputBound => WorkspaceMode::OutputBound(HashMap::new()), crate::config::WorkspaceMode::OutputBound => {
WorkspaceMode::OutputBound(HashMap::new(), amount)
}
} }
} }
pub fn get(&self, num: usize, output: &Output) -> Option<&Workspace> { pub fn get(&self, num: usize, output: &Output) -> Option<&Workspace> {
match self { match self {
WorkspaceMode::Global(set) => set.workspaces.get(num), WorkspaceMode::Global(set) => set.workspaces.get(num),
WorkspaceMode::OutputBound(sets) => { WorkspaceMode::OutputBound(sets, _) => {
sets.get(output).and_then(|set| set.workspaces.get(num)) sets.get(output).and_then(|set| set.workspaces.get(num))
} }
} }
@ -287,7 +289,7 @@ impl WorkspaceMode {
pub fn get_mut(&mut self, num: usize, output: &Output) -> Option<&mut Workspace> { pub fn get_mut(&mut self, num: usize, output: &Output) -> Option<&mut Workspace> {
match self { match self {
WorkspaceMode::Global(set) => set.workspaces.get_mut(num), WorkspaceMode::Global(set) => set.workspaces.get_mut(num),
WorkspaceMode::OutputBound(sets) => sets WorkspaceMode::OutputBound(sets, _) => sets
.get_mut(output) .get_mut(output)
.and_then(|set| set.workspaces.get_mut(num)), .and_then(|set| set.workspaces.get_mut(num)),
} }
@ -296,7 +298,7 @@ impl WorkspaceMode {
pub fn active(&self, output: &Output) -> &Workspace { pub fn active(&self, output: &Output) -> &Workspace {
match self { match self {
WorkspaceMode::Global(set) => &set.workspaces[set.active], WorkspaceMode::Global(set) => &set.workspaces[set.active],
WorkspaceMode::OutputBound(sets) => { WorkspaceMode::OutputBound(sets, _) => {
let set = sets.get(output).unwrap(); let set = sets.get(output).unwrap();
&set.workspaces[set.active] &set.workspaces[set.active]
} }
@ -306,17 +308,17 @@ impl WorkspaceMode {
pub fn active_mut(&mut self, output: &Output) -> &mut Workspace { pub fn active_mut(&mut self, output: &Output) -> &mut Workspace {
match self { match self {
WorkspaceMode::Global(set) => &mut set.workspaces[set.active], WorkspaceMode::Global(set) => &mut set.workspaces[set.active],
WorkspaceMode::OutputBound(sets) => { WorkspaceMode::OutputBound(sets, _) => {
let set = sets.get_mut(output).unwrap(); let set = sets.get_mut(output).unwrap();
&mut set.workspaces[set.active] &mut set.workspaces[set.active]
} }
} }
} }
fn active_num(&self, output: &Output) -> usize { pub fn active_num(&self, output: &Output) -> usize {
match self { match self {
WorkspaceMode::Global(set) => set.active, WorkspaceMode::Global(set) => set.active,
WorkspaceMode::OutputBound(sets) => { WorkspaceMode::OutputBound(sets, _) => {
let set = sets.get(output).unwrap(); let set = sets.get(output).unwrap();
set.active set.active
} }
@ -328,7 +330,7 @@ impl WorkspaceMode {
WorkspaceMode::Global(set) => { WorkspaceMode::Global(set) => {
Box::new(set.workspaces.iter()) as Box<dyn Iterator<Item = &Workspace>> Box::new(set.workspaces.iter()) as Box<dyn Iterator<Item = &Workspace>>
} }
WorkspaceMode::OutputBound(sets) => { WorkspaceMode::OutputBound(sets, _) => {
Box::new(sets.values().flat_map(|set| set.workspaces.iter())) Box::new(sets.values().flat_map(|set| set.workspaces.iter()))
} }
} }
@ -339,7 +341,7 @@ impl WorkspaceMode {
WorkspaceMode::Global(set) => { WorkspaceMode::Global(set) => {
Box::new(set.workspaces.iter()) as Box<dyn Iterator<Item = &Workspace>> Box::new(set.workspaces.iter()) as Box<dyn Iterator<Item = &Workspace>>
} }
WorkspaceMode::OutputBound(sets) => Box::new( WorkspaceMode::OutputBound(sets, _) => Box::new(
sets.get(output) sets.get(output)
.into_iter() .into_iter()
.flat_map(|set| set.workspaces.iter()), .flat_map(|set| set.workspaces.iter()),
@ -352,7 +354,7 @@ impl WorkspaceMode {
WorkspaceMode::Global(set) => { WorkspaceMode::Global(set) => {
Box::new(set.workspaces.iter_mut()) as Box<dyn Iterator<Item = &mut Workspace>> Box::new(set.workspaces.iter_mut()) as Box<dyn Iterator<Item = &mut Workspace>>
} }
WorkspaceMode::OutputBound(sets) => { WorkspaceMode::OutputBound(sets, _) => {
Box::new(sets.values_mut().flat_map(|set| set.workspaces.iter_mut())) Box::new(sets.values_mut().flat_map(|set| set.workspaces.iter_mut()))
} }
} }
@ -384,7 +386,6 @@ impl Shell {
|_| true, |_| true,
); );
let amount = config.static_conf.workspace_amount;
let mode = WorkspaceMode::new( let mode = WorkspaceMode::new(
config.static_conf.workspace_mode, config.static_conf.workspace_mode,
config.static_conf.workspace_amount, config.static_conf.workspace_amount,
@ -396,7 +397,6 @@ impl Shell {
popups: PopupManager::new(None), popups: PopupManager::new(None),
outputs: Vec::new(), outputs: Vec::new(),
workspaces: mode, workspaces: mode,
workspace_amount: amount,
floating_default, floating_default,
pending_windows: Vec::new(), pending_windows: Vec::new(),
@ -415,13 +415,10 @@ impl Shell {
let mut state = self.workspace_state.update(); let mut state = self.workspace_state.update();
match &mut self.workspaces { match &mut self.workspaces {
WorkspaceMode::OutputBound(sets) => { WorkspaceMode::OutputBound(sets, amount) => {
// TODO: Restore previously assigned workspaces, if possible! // TODO: Restore previously assigned workspaces, if possible!
if !sets.contains_key(output) { if !sets.contains_key(output) {
sets.insert( sets.insert(output.clone(), WorkspaceSet::new(&mut state, *amount));
output.clone(),
WorkspaceSet::new(&mut state, self.workspace_amount),
);
} }
for workspace in &mut sets.get_mut(output).unwrap().workspaces { for workspace in &mut sets.get_mut(output).unwrap().workspaces {
workspace.map_output(output, (0, 0).into()); workspace.map_output(output, (0, 0).into());
@ -442,7 +439,7 @@ impl Shell {
self.outputs.retain(|o| o != output); self.outputs.retain(|o| o != output);
match &mut self.workspaces { match &mut self.workspaces {
WorkspaceMode::OutputBound(sets) => { WorkspaceMode::OutputBound(sets, _) => {
if let Some(set) = sets.remove(output) { if let Some(set) = sets.remove(output) {
// TODO: Heuristic which output to move to. // TODO: Heuristic which output to move to.
// It is supposed to be the *most* internal, we just pick the first one for now // It is supposed to be the *most* internal, we just pick the first one for now
@ -504,13 +501,14 @@ impl Shell {
let mut state = self.workspace_state.update(); let mut state = self.workspace_state.update();
match (&mut self.workspaces, mode) { match (&mut self.workspaces, mode) {
(dst @ WorkspaceMode::OutputBound(_), ConfigMode::Global) => { (dst @ WorkspaceMode::OutputBound(_, _), ConfigMode::Global) => {
// rustc should really be able to infer that this doesn't need an if. // rustc should really be able to infer that this doesn't need an if.
let sets = if let &mut WorkspaceMode::OutputBound(ref mut sets) = dst { let (sets, amount) =
sets if let &mut WorkspaceMode::OutputBound(ref mut sets, ref amount) = dst {
} else { (sets, *amount)
unreachable!() } else {
}; unreachable!()
};
// in this case we have to merge our sets, preserving placing of windows as nicely as possible // in this case we have to merge our sets, preserving placing of windows as nicely as possible
let mut new_set = WorkspaceSet::new(&mut state, WorkspaceAmount::Static(0)); let mut new_set = WorkspaceSet::new(&mut state, WorkspaceAmount::Static(0));
@ -602,6 +600,7 @@ impl Shell {
state.remove_workspace_group(group); state.remove_workspace_group(group);
} }
new_set.amount = amount;
*dst = WorkspaceMode::Global(new_set); *dst = WorkspaceMode::Global(new_set);
} }
(dst @ WorkspaceMode::Global(_), ConfigMode::OutputBound) => { (dst @ WorkspaceMode::Global(_), ConfigMode::OutputBound) => {
@ -696,7 +695,10 @@ impl Shell {
} }
state.remove_workspace_group(set.group); state.remove_workspace_group(set.group);
*dst = WorkspaceMode::OutputBound(sets); for new_set in sets.values_mut() {
new_set.amount = set.amount;
}
*dst = WorkspaceMode::OutputBound(sets, set.amount);
} }
_ => {} _ => {}
} }
@ -707,7 +709,7 @@ impl Shell {
pub fn activate(&mut self, output: &Output, idx: usize) -> Option<MotionEvent> { pub fn activate(&mut self, output: &Output, idx: usize) -> Option<MotionEvent> {
match &mut self.workspaces { match &mut self.workspaces {
WorkspaceMode::OutputBound(sets) => { WorkspaceMode::OutputBound(sets, _) => {
if let Some(set) = sets.get_mut(output) { if let Some(set) = sets.get_mut(output) {
set.activate(idx, &mut self.workspace_state.update()); set.activate(idx, &mut self.workspace_state.update());
} }
@ -722,7 +724,7 @@ impl Shell {
pub fn active_space(&self, output: &Output) -> &Workspace { pub fn active_space(&self, output: &Output) -> &Workspace {
match &self.workspaces { match &self.workspaces {
WorkspaceMode::OutputBound(sets) => { WorkspaceMode::OutputBound(sets, _) => {
let set = sets.get(output).unwrap(); let set = sets.get(output).unwrap();
&set.workspaces[set.active] &set.workspaces[set.active]
} }
@ -732,7 +734,7 @@ impl Shell {
pub fn active_space_mut(&mut self, output: &Output) -> &mut Workspace { pub fn active_space_mut(&mut self, output: &Output) -> &mut Workspace {
match &mut self.workspaces { match &mut self.workspaces {
WorkspaceMode::OutputBound(sets) => { WorkspaceMode::OutputBound(sets, _) => {
let set = sets.get_mut(output).unwrap(); let set = sets.get_mut(output).unwrap();
&mut set.workspaces[set.active] &mut set.workspaces[set.active]
} }
@ -852,7 +854,7 @@ impl Shell {
) -> Point<C, Logical> { ) -> Point<C, Logical> {
match self.workspaces { match self.workspaces {
WorkspaceMode::Global(_) => global_loc.into(), WorkspaceMode::Global(_) => global_loc.into(),
WorkspaceMode::OutputBound(_) => { WorkspaceMode::OutputBound(_, _) => {
let p = global_loc.into().to_f64() - output.current_location().to_f64(); let p = global_loc.into().to_f64() - output.current_location().to_f64();
(C::from_f64(p.x), C::from_f64(p.y)).into() (C::from_f64(p.x), C::from_f64(p.y)).into()
} }
@ -866,7 +868,7 @@ impl Shell {
) -> Point<C, Logical> { ) -> Point<C, Logical> {
match self.workspaces { match self.workspaces {
WorkspaceMode::Global(_) => space_loc.into(), WorkspaceMode::Global(_) => space_loc.into(),
WorkspaceMode::OutputBound(_) => { WorkspaceMode::OutputBound(_, _) => {
let p = space_loc.into().to_f64() + output.current_location().to_f64(); let p = space_loc.into().to_f64() + output.current_location().to_f64();
(C::from_f64(p.x), C::from_f64(p.y)).into() (C::from_f64(p.x), C::from_f64(p.y)).into()
} }
@ -877,10 +879,9 @@ impl Shell {
self.popups.cleanup(); self.popups.cleanup();
match &mut self.workspaces { match &mut self.workspaces {
WorkspaceMode::OutputBound(sets) => { WorkspaceMode::OutputBound(sets, _) => {
for (output, set) in sets.iter_mut() { for (output, set) in sets.iter_mut() {
set.refresh( set.refresh(
self.workspace_amount,
&mut self.workspace_state, &mut self.workspace_state,
&mut self.toplevel_info_state, &mut self.toplevel_info_state,
std::iter::once((output, (0, 0).into())), std::iter::once((output, (0, 0).into())),
@ -888,7 +889,6 @@ impl Shell {
} }
} }
WorkspaceMode::Global(set) => set.refresh( WorkspaceMode::Global(set) => set.refresh(
self.workspace_amount,
&mut self.workspace_state, &mut self.workspace_state,
&mut self.toplevel_info_state, &mut self.toplevel_info_state,
self.outputs.iter().map(|o| (o, o.current_location())), self.outputs.iter().map(|o| (o, o.current_location())),