From 5a8840b12e1319d3d1b3e9f430e8ec48c5c08423 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Fri, 27 Jan 2023 13:26:28 +0100 Subject: [PATCH] shell: Properly propagate tiling state --- config.ron | 2 +- src/config/mod.rs | 4 +-- src/shell/mod.rs | 72 +++++++++++++++++++++++++++++++++--------- src/shell/workspace.rs | 4 +-- 4 files changed, 62 insertions(+), 20 deletions(-) diff --git a/config.ron b/config.ron index acd9d5e3..8d0e5a68 100644 --- a/config.ron +++ b/config.ron @@ -92,5 +92,5 @@ }, workspace_mode: OutputBound, workspace_amount: Dynamic, - floating_default: false, + tiling_enabled: false, ) diff --git a/src/config/mod.rs b/src/config/mod.rs index 4e38600d..5afe1d0e 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -35,7 +35,7 @@ pub struct StaticConfig { pub key_bindings: HashMap, pub workspace_mode: WorkspaceMode, pub workspace_amount: WorkspaceAmount, - pub floating_default: bool, + pub tiling_enabled: bool, } #[derive(Debug, Deserialize, Clone, Copy, PartialEq, Eq)] @@ -219,7 +219,7 @@ impl Config { key_bindings: HashMap::new(), workspace_mode: WorkspaceMode::Global, workspace_amount: WorkspaceAmount::Dynamic, - floating_default: false, + tiling_enabled: false, } } diff --git a/src/shell/mod.rs b/src/shell/mod.rs index e9f75f47..25ba8f4c 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -58,7 +58,7 @@ pub struct Shell { pub popups: PopupManager, pub outputs: Vec, pub workspaces: WorkspaceMode, - pub floating_default: bool, + pub tiling_enabled: bool, pub pending_windows: Vec<(CosmicSurface, Seat)>, pub pending_layers: Vec<(LayerSurface, Output, Seat)>, pub override_redirect_windows: Vec, @@ -90,6 +90,7 @@ pub struct WorkspaceSet { amount: WorkspaceAmount, group: WorkspaceGroupHandle, idx: usize, + tiling_enabled: bool, pub(crate) workspaces: Vec, } @@ -103,6 +104,7 @@ fn create_workspace( state: &mut WorkspaceUpdateGuard<'_, State>, group_handle: &WorkspaceGroupHandle, active: bool, + tiling: bool, ) -> Workspace { let workspace_handle = state.create_workspace(&group_handle).unwrap(); if active { @@ -112,7 +114,7 @@ fn create_workspace( &workspace_handle, [WorkspaceCapabilities::Activate].into_iter(), ); - Workspace::new(workspace_handle) + Workspace::new(workspace_handle, tiling) } impl WorkspaceSet { @@ -120,12 +122,13 @@ impl WorkspaceSet { state: &mut WorkspaceUpdateGuard<'_, State>, amount: WorkspaceAmount, idx: usize, + tiling_enabled: bool, ) -> WorkspaceSet { let group_handle = state.create_workspace_group(); let workspaces = match amount { WorkspaceAmount::Dynamic => { - let workspace = create_workspace(state, &group_handle, true); + let workspace = create_workspace(state, &group_handle, true, tiling_enabled); workspace_set_idx(state, 1, idx, &workspace.handle); state.set_workspace_capabilities( &workspace.handle, @@ -135,7 +138,7 @@ impl WorkspaceSet { } WorkspaceAmount::Static(len) => (0..len) .map(|i| { - let workspace = create_workspace(state, &group_handle, i == 0); + let workspace = create_workspace(state, &group_handle, i == 0, tiling_enabled); workspace_set_idx(state, i + 1, idx, &workspace.handle); state.set_workspace_capabilities( &workspace.handle, @@ -151,6 +154,7 @@ impl WorkspaceSet { amount, group: group_handle, idx, + tiling_enabled, workspaces, } } @@ -188,7 +192,8 @@ impl WorkspaceSet { // add empty at the end, if necessary if self.workspaces.last().unwrap().windows().next().is_some() { - let mut workspace = create_workspace(&mut state, &self.group, false); + let mut workspace = + create_workspace(&mut state, &self.group, false, self.tiling_enabled); workspace_set_idx( &mut state, self.workspaces.len() as u8 + 1, @@ -271,7 +276,8 @@ impl WorkspaceSet { // add empty ones let outputs = outputs.collect::>(); while amount > self.workspaces.len() { - let mut workspace = create_workspace(&mut state, &self.group, false); + let mut workspace = + create_workspace(&mut state, &self.group, false, self.tiling_enabled); workspace_set_idx( &mut state, self.workspaces.len() as u8 + 1, @@ -296,6 +302,15 @@ impl WorkspaceSet { workspace_set_idx(state, i as u8 + 1, idx, &workspace.handle); } } + + fn update_tiling_status(&mut self, seat: &Seat, tiling_enabled: bool) { + self.tiling_enabled = tiling_enabled; + for workspace in &mut self.workspaces { + if workspace.tiling_enabled != tiling_enabled { + workspace.toggle_tiling(seat); + } + } + } } #[derive(Debug)] @@ -309,10 +324,11 @@ impl WorkspaceMode { config: crate::config::WorkspaceMode, amount: WorkspaceAmount, state: &mut WorkspaceUpdateGuard<'_, State>, + tiling_enabled: bool, ) -> WorkspaceMode { match config { crate::config::WorkspaceMode::Global => { - WorkspaceMode::Global(WorkspaceSet::new(state, amount, 0)) + WorkspaceMode::Global(WorkspaceSet::new(state, amount, 0, tiling_enabled)) } crate::config::WorkspaceMode::OutputBound => { WorkspaceMode::OutputBound(HashMap::new(), amount) @@ -412,6 +428,17 @@ impl WorkspaceMode { } } } + + pub fn update_tiling_status(&mut self, seat: &Seat, tiling: bool) { + match self { + WorkspaceMode::Global(set) => set.update_tiling_status(seat, tiling), + WorkspaceMode::OutputBound(sets, _) => { + for set in sets.values_mut() { + set.update_tiling_status(seat, tiling) + } + } + } + } } impl Shell { @@ -439,18 +466,19 @@ impl Shell { |_| true, ); + let tiling_enabled = config.static_conf.tiling_enabled; let mode = WorkspaceMode::new( config.static_conf.workspace_mode, config.static_conf.workspace_amount, &mut workspace_state.update(), + tiling_enabled, ); - let floating_default = config.static_conf.floating_default; Shell { popups: PopupManager::new(None), outputs: Vec::new(), workspaces: mode, - floating_default, + tiling_enabled, pending_windows: Vec::new(), pending_layers: Vec::new(), @@ -476,7 +504,8 @@ impl Shell { WorkspaceMode::OutputBound(sets, amount) => { // TODO: Restore previously assigned workspaces, if possible! if !sets.contains_key(output) { - let set = WorkspaceSet::new(&mut state, *amount, sets.len()); + let set = + WorkspaceSet::new(&mut state, *amount, sets.len(), self.tiling_enabled); state.add_group_output(&set.group, &output); sets.insert(output.clone(), set); } @@ -521,6 +550,9 @@ impl Shell { match &mut self.workspaces { WorkspaceMode::OutputBound(sets, _) => { + // TODO: + // If amount::static merge them instead of appending + if let Some(set) = sets.remove(output) { // TODO: Heuristic which output to move to. // It is supposed to be the *most* internal, we just pick the first one for now @@ -599,7 +631,12 @@ impl Shell { }; // 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), 0); + let mut new_set = WorkspaceSet::new( + &mut state, + WorkspaceAmount::Static(0), + 0, + self.tiling_enabled, + ); for output in &self.outputs { state.add_group_output(&new_set.group, output); } @@ -660,7 +697,7 @@ impl Shell { ); workspace_set_idx(&mut state, i as u8 + 1, 0, &workspace_handle); - let mut new_workspace = Workspace::new(workspace_handle); + let mut new_workspace = Workspace::new(workspace_handle, self.tiling_enabled); for output in self.outputs.iter() { new_workspace.map_output(output, output.current_location()); } @@ -705,7 +742,12 @@ impl Shell { // split workspaces apart, preserving window positions relative to their outputs let mut sets = HashMap::new(); for (i, output) in self.outputs.iter().enumerate() { - let set = WorkspaceSet::new(&mut state, WorkspaceAmount::Static(0), i); + let set = WorkspaceSet::new( + &mut state, + WorkspaceAmount::Static(0), + i, + self.tiling_enabled, + ); state.add_group_output(&set.group, output); sets.insert(output.clone(), set); } @@ -770,7 +812,7 @@ impl Shell { .filter(|(key, _)| *key == output) .map(|(o, w)| (o.clone(), w.clone())) .collect(), - ..Workspace::new(new_workspace_handle) + ..Workspace::new(new_workspace_handle, true) }; for toplevel in new_workspace.windows() { self.toplevel_info_state @@ -1036,7 +1078,7 @@ impl Shell { { mapped.set_debug(state.common.egui.active); } - if layout::should_be_floating(&window) || state.common.shell.floating_default { + if layout::should_be_floating(&window) || !workspace.tiling_enabled { workspace.floating_layer.map(mapped.clone(), &seat, None); } else { let focus_stack = workspace.focus_stack.get(&seat); diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index f89f4c81..bec5a07e 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -61,11 +61,11 @@ pub enum ManagedState { } impl Workspace { - pub fn new(handle: WorkspaceHandle) -> Workspace { + pub fn new(handle: WorkspaceHandle, tiling_enabled: bool) -> Workspace { Workspace { tiling_layer: TilingLayout::new(), floating_layer: FloatingLayout::new(), - tiling_enabled: true, + tiling_enabled, fullscreen: HashMap::new(), handle, focus_stack: FocusStacks::default(),