aboutsummaryrefslogtreecommitdiff
path: root/src/layout/monitor.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/layout/monitor.rs')
-rw-r--r--src/layout/monitor.rs93
1 files changed, 84 insertions, 9 deletions
diff --git a/src/layout/monitor.rs b/src/layout/monitor.rs
index 52e73cce..b2afb9e3 100644
--- a/src/layout/monitor.rs
+++ b/src/layout/monitor.rs
@@ -86,6 +86,20 @@ impl WorkspaceSwitch {
}
}
+ pub fn offset(&mut self, delta: isize) {
+ match self {
+ WorkspaceSwitch::Animation(anim) => anim.offset(delta as f64),
+ WorkspaceSwitch::Gesture(gesture) => {
+ if delta >= 0 {
+ gesture.center_idx += delta as usize;
+ } else {
+ gesture.center_idx -= (-delta) as usize;
+ }
+ gesture.current_idx += delta as f64;
+ }
+ }
+ }
+
/// Returns `true` if the workspace switch is [`Animation`].
///
/// [`Animation`]: WorkspaceSwitch::Animation
@@ -158,6 +172,20 @@ impl<W: LayoutElement> Monitor<W> {
self.windows().any(|win| win.id() == window)
}
+ pub fn add_workspace_top(&mut self) {
+ let ws = Workspace::new(
+ self.output.clone(),
+ self.clock.clone(),
+ self.options.clone(),
+ );
+ self.workspaces.insert(0, ws);
+ self.active_workspace_idx += 1;
+
+ if let Some(switch) = &mut self.workspace_switch {
+ switch.offset(1);
+ }
+ }
+
pub fn add_workspace_bottom(&mut self) {
let ws = Workspace::new(
self.output.clone(),
@@ -194,7 +222,7 @@ impl<W: LayoutElement> Monitor<W> {
pub fn add_window(
&mut self,
- workspace_idx: usize,
+ mut workspace_idx: usize,
window: W,
activate: bool,
width: ColumnWidth,
@@ -208,10 +236,14 @@ impl<W: LayoutElement> Monitor<W> {
workspace.original_output = OutputId::new(&self.output);
if workspace_idx == self.workspaces.len() - 1 {
- // Insert a new empty workspace.
self.add_workspace_bottom();
}
+ if self.options.empty_workspace_above_first && workspace_idx == 0 {
+ self.add_workspace_top();
+ workspace_idx += 1;
+ }
+
if activate {
self.activate_workspace(workspace_idx);
}
@@ -240,7 +272,7 @@ impl<W: LayoutElement> Monitor<W> {
// cannot be the last one, so we never need to insert a new empty workspace.
}
- pub fn add_column(&mut self, workspace_idx: usize, column: Column<W>, activate: bool) {
+ pub fn add_column(&mut self, mut workspace_idx: usize, column: Column<W>, activate: bool) {
let workspace = &mut self.workspaces[workspace_idx];
workspace.add_column(None, column, activate, None);
@@ -249,9 +281,12 @@ impl<W: LayoutElement> Monitor<W> {
workspace.original_output = OutputId::new(&self.output);
if workspace_idx == self.workspaces.len() - 1 {
- // Insert a new empty workspace.
self.add_workspace_bottom();
}
+ if self.options.empty_workspace_above_first && workspace_idx == 0 {
+ self.add_workspace_top();
+ workspace_idx += 1;
+ }
if activate {
self.activate_workspace(workspace_idx);
@@ -260,7 +295,7 @@ impl<W: LayoutElement> Monitor<W> {
pub fn add_tile(
&mut self,
- workspace_idx: usize,
+ mut workspace_idx: usize,
column_idx: Option<usize>,
tile: Tile<W>,
activate: bool,
@@ -279,6 +314,11 @@ impl<W: LayoutElement> Monitor<W> {
self.add_workspace_bottom();
}
+ if self.options.empty_workspace_above_first && workspace_idx == 0 {
+ self.add_workspace_top();
+ workspace_idx += 1;
+ }
+
if activate {
self.activate_workspace(workspace_idx);
}
@@ -310,18 +350,32 @@ impl<W: LayoutElement> Monitor<W> {
pub fn clean_up_workspaces(&mut self) {
assert!(self.workspace_switch.is_none());
- for idx in (0..self.workspaces.len() - 1).rev() {
+ let range_start = if self.options.empty_workspace_above_first {
+ 1
+ } else {
+ 0
+ };
+ for idx in (range_start..self.workspaces.len() - 1).rev() {
if self.active_workspace_idx == idx {
continue;
}
- if !self.workspaces[idx].has_windows() && self.workspaces[idx].name.is_none() {
+ if !self.workspaces[idx].has_windows_or_name() {
self.workspaces.remove(idx);
if self.active_workspace_idx > idx {
self.active_workspace_idx -= 1;
}
}
}
+
+ // Special case handling when empty_workspace_above_first is set and all workspaces
+ // are empty.
+ if self.options.empty_workspace_above_first && self.workspaces.len() == 2 {
+ assert!(!self.workspaces[0].has_windows_or_name());
+ assert!(!self.workspaces[1].has_windows_or_name());
+ self.workspaces.remove(1);
+ self.active_workspace_idx = 0;
+ }
}
pub fn unname_workspace(&mut self, workspace_name: &str) -> bool {
@@ -792,6 +846,17 @@ impl<W: LayoutElement> Monitor<W> {
}
pub fn update_config(&mut self, options: Rc<Options>) {
+ if self.options.empty_workspace_above_first != options.empty_workspace_above_first
+ && self.workspaces.len() > 1
+ {
+ if options.empty_workspace_above_first {
+ self.add_workspace_top();
+ } else if self.workspace_switch.is_none() && self.active_workspace_idx != 0 {
+ self.workspaces.remove(0);
+ self.active_workspace_idx = self.active_workspace_idx.saturating_sub(1);
+ }
+ }
+
for ws in &mut self.workspaces {
ws.update_config(options.clone());
}
@@ -823,7 +888,7 @@ impl<W: LayoutElement> Monitor<W> {
}
pub fn move_workspace_down(&mut self) {
- let new_idx = min(self.active_workspace_idx + 1, self.workspaces.len() - 1);
+ let mut new_idx = min(self.active_workspace_idx + 1, self.workspaces.len() - 1);
if new_idx == self.active_workspace_idx {
return;
}
@@ -835,6 +900,11 @@ impl<W: LayoutElement> Monitor<W> {
self.add_workspace_bottom();
}
+ if self.options.empty_workspace_above_first && self.active_workspace_idx == 0 {
+ self.add_workspace_top();
+ new_idx += 1;
+ }
+
let previous_workspace_id = self.previous_workspace_id;
self.activate_workspace(new_idx);
self.workspace_switch = None;
@@ -844,7 +914,7 @@ impl<W: LayoutElement> Monitor<W> {
}
pub fn move_workspace_up(&mut self) {
- let new_idx = self.active_workspace_idx.saturating_sub(1);
+ let mut new_idx = self.active_workspace_idx.saturating_sub(1);
if new_idx == self.active_workspace_idx {
return;
}
@@ -856,6 +926,11 @@ impl<W: LayoutElement> Monitor<W> {
self.add_workspace_bottom();
}
+ if self.options.empty_workspace_above_first && new_idx == 0 {
+ self.add_workspace_top();
+ new_idx += 1;
+ }
+
let previous_workspace_id = self.previous_workspace_id;
self.activate_workspace(new_idx);
self.workspace_switch = None;