mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-01-11 22:12:53 +01:00
feat(wm): add padding per monitor
This commit adds the ability to set container and workspace padding per monitor. To do so (and to simplify any future need of changing some value per monitor), and have it pass through to each workspace a new field was added to `Workspace` called `globals` which has a new struct called `WorkspaceGlobals`. `WorkspaceGlobals` includes any global values that might be needed by the workspace. This field is updated by the monitor for all its workspaces whenever the config is loaded or reloaded. It is also updated on `RetileAll` and on the function `update_focused_workspace`. This should make sure that every time a workspace needs to use it's `update` function, it has all the `globals` up to date! This also means that now the `update` function from workspaces doesn't take any argument at all, reducing all the need to get all the `work_area`, `work_area_offset`, `window_based_work_area_offset` or `window_based_work_area_offset_limit` simplifying the callers of this function quite a bit. Lastly this commit has also (sort of accidentaly) fixed an existing bug with the `move_workspace_to_monitor` function. This was previous removing the workspace from a monitor, but wasn't changing it's `focused_workspace_idx`, meaning that komorebi would get all messed up after that command. For example, the `border_manager` would get stuck and the komorebi-bar would crash. Now, the `remove_focused_workspace` function also focuses the previous workspace (which in turn will create a new workspace in case the removed workspace was the last workspace).
This commit is contained in:
@@ -48,6 +48,7 @@ pub use komorebi::ring::Ring;
|
||||
pub use komorebi::window::Window;
|
||||
pub use komorebi::window_manager_event::WindowManagerEvent;
|
||||
pub use komorebi::workspace::Workspace;
|
||||
pub use komorebi::workspace::WorkspaceGlobals;
|
||||
pub use komorebi::workspace::WorkspaceLayer;
|
||||
pub use komorebi::AnimationsConfig;
|
||||
pub use komorebi::AspectRatio;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::collections::HashMap;
|
||||
use std::collections::VecDeque;
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
use color_eyre::eyre::anyhow;
|
||||
use color_eyre::eyre::bail;
|
||||
@@ -21,6 +22,8 @@ use crate::DefaultLayout;
|
||||
use crate::Layout;
|
||||
use crate::OperationDirection;
|
||||
use crate::WindowsApi;
|
||||
use crate::DEFAULT_CONTAINER_PADDING;
|
||||
use crate::DEFAULT_WORKSPACE_PADDING;
|
||||
|
||||
#[derive(
|
||||
Debug,
|
||||
@@ -61,6 +64,10 @@ pub struct Monitor {
|
||||
pub last_focused_workspace: Option<usize>,
|
||||
#[getset(get_mut = "pub")]
|
||||
pub workspace_names: HashMap<usize, String>,
|
||||
#[getset(get_copy = "pub", set = "pub")]
|
||||
pub container_padding: Option<i32>,
|
||||
#[getset(get_copy = "pub", set = "pub")]
|
||||
pub workspace_padding: Option<i32>,
|
||||
}
|
||||
|
||||
impl_ring_elements!(Monitor, Workspace);
|
||||
@@ -114,6 +121,8 @@ pub fn new(
|
||||
workspaces,
|
||||
last_focused_workspace: None,
|
||||
workspace_names: HashMap::default(),
|
||||
container_padding: None,
|
||||
workspace_padding: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,6 +162,8 @@ impl Monitor {
|
||||
workspaces: Default::default(),
|
||||
last_focused_workspace: None,
|
||||
workspace_names: Default::default(),
|
||||
container_padding: None,
|
||||
workspace_padding: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,6 +186,52 @@ impl Monitor {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Updates the `globals` field of all workspaces
|
||||
pub fn update_workspaces_globals(&mut self, offset: Option<Rect>) {
|
||||
let container_padding = self
|
||||
.container_padding()
|
||||
.or(Some(DEFAULT_CONTAINER_PADDING.load(Ordering::SeqCst)));
|
||||
let workspace_padding = self
|
||||
.workspace_padding()
|
||||
.or(Some(DEFAULT_WORKSPACE_PADDING.load(Ordering::SeqCst)));
|
||||
let work_area = *self.work_area_size();
|
||||
let offset = self.work_area_offset.or(offset);
|
||||
let window_based_work_area_offset = self.window_based_work_area_offset();
|
||||
let limit = self.window_based_work_area_offset_limit();
|
||||
|
||||
for workspace in self.workspaces_mut() {
|
||||
workspace.globals_mut().container_padding = container_padding;
|
||||
workspace.globals_mut().workspace_padding = workspace_padding;
|
||||
workspace.globals_mut().work_area = work_area;
|
||||
workspace.globals_mut().work_area_offset = offset;
|
||||
workspace.globals_mut().window_based_work_area_offset = window_based_work_area_offset;
|
||||
workspace.globals_mut().window_based_work_area_offset_limit = limit;
|
||||
}
|
||||
}
|
||||
|
||||
/// Updates the `globals` field of workspace with index `workspace_idx`
|
||||
pub fn update_workspace_globals(&mut self, workspace_idx: usize, offset: Option<Rect>) {
|
||||
let container_padding = self
|
||||
.container_padding()
|
||||
.or(Some(DEFAULT_CONTAINER_PADDING.load(Ordering::SeqCst)));
|
||||
let workspace_padding = self
|
||||
.workspace_padding()
|
||||
.or(Some(DEFAULT_WORKSPACE_PADDING.load(Ordering::SeqCst)));
|
||||
let work_area = *self.work_area_size();
|
||||
let offset = self.work_area_offset.or(offset);
|
||||
let window_based_work_area_offset = self.window_based_work_area_offset();
|
||||
let limit = self.window_based_work_area_offset_limit();
|
||||
|
||||
if let Some(workspace) = self.workspaces_mut().get_mut(workspace_idx) {
|
||||
workspace.globals_mut().container_padding = container_padding;
|
||||
workspace.globals_mut().workspace_padding = workspace_padding;
|
||||
workspace.globals_mut().work_area = work_area;
|
||||
workspace.globals_mut().work_area_offset = offset;
|
||||
workspace.globals_mut().window_based_work_area_offset = window_based_work_area_offset;
|
||||
workspace.globals_mut().window_based_work_area_offset_limit = limit;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_container(
|
||||
&mut self,
|
||||
container: Container,
|
||||
@@ -401,21 +458,17 @@ impl Monitor {
|
||||
}
|
||||
|
||||
pub fn update_focused_workspace(&mut self, offset: Option<Rect>) -> Result<()> {
|
||||
let work_area = *self.work_area_size();
|
||||
let window_based_work_area_offset = (
|
||||
self.window_based_work_area_offset_limit(),
|
||||
self.window_based_work_area_offset(),
|
||||
);
|
||||
|
||||
let offset = if self.work_area_offset().is_some() {
|
||||
self.work_area_offset()
|
||||
} else {
|
||||
offset
|
||||
};
|
||||
|
||||
let focused_workspace_idx = self.focused_workspace_idx();
|
||||
self.update_workspace_globals(focused_workspace_idx, offset);
|
||||
self.focused_workspace_mut()
|
||||
.ok_or_else(|| anyhow!("there is no workspace"))?
|
||||
.update(&work_area, offset, window_based_work_area_offset)?;
|
||||
.update()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -70,24 +70,12 @@ fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result<()>
|
||||
for notification in receiver {
|
||||
let orphan_hwnds = notification.0;
|
||||
let mut wm = wm.lock();
|
||||
let offset = wm.work_area_offset;
|
||||
|
||||
let mut update_borders = false;
|
||||
|
||||
for (hwnd, (m_idx, w_idx)) in orphan_hwnds.iter() {
|
||||
if let Some(monitor) = wm.monitors_mut().get_mut(*m_idx) {
|
||||
let focused_workspace_idx = monitor.focused_workspace_idx();
|
||||
let work_area = *monitor.work_area_size();
|
||||
let window_based_work_area_offset = (
|
||||
monitor.window_based_work_area_offset_limit(),
|
||||
monitor.window_based_work_area_offset(),
|
||||
);
|
||||
|
||||
let offset = if monitor.work_area_offset().is_some() {
|
||||
monitor.work_area_offset()
|
||||
} else {
|
||||
offset
|
||||
};
|
||||
|
||||
if let Some(workspace) = monitor.workspaces_mut().get_mut(*w_idx) {
|
||||
// Remove orphan window
|
||||
@@ -105,7 +93,7 @@ fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result<()>
|
||||
// If this is not a focused workspace there is no need to update the
|
||||
// workspace or the borders. That will already be done when the user
|
||||
// changes to this workspace.
|
||||
workspace.update(&work_area, offset, window_based_work_area_offset)?;
|
||||
workspace.update()?;
|
||||
update_borders = true;
|
||||
}
|
||||
tracing::info!(
|
||||
|
||||
@@ -140,7 +140,7 @@ pub struct WorkspaceConfig {
|
||||
/// Container padding (default: global)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub container_padding: Option<i32>,
|
||||
/// Container padding (default: global)
|
||||
/// Workspace padding (default: global)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub workspace_padding: Option<i32>,
|
||||
/// Initial workspace application rules
|
||||
@@ -256,6 +256,12 @@ pub struct MonitorConfig {
|
||||
/// Open window limit after which the window based work area offset will no longer be applied (default: 1)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub window_based_work_area_offset_limit: Option<isize>,
|
||||
/// Container padding (default: global)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub container_padding: Option<i32>,
|
||||
/// Workspace padding (default: global)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub workspace_padding: Option<i32>,
|
||||
}
|
||||
|
||||
impl From<&Monitor> for MonitorConfig {
|
||||
@@ -265,11 +271,32 @@ impl From<&Monitor> for MonitorConfig {
|
||||
workspaces.push(WorkspaceConfig::from(w));
|
||||
}
|
||||
|
||||
let default_container_padding = DEFAULT_CONTAINER_PADDING.load(Ordering::SeqCst);
|
||||
let default_workspace_padding = DEFAULT_WORKSPACE_PADDING.load(Ordering::SeqCst);
|
||||
|
||||
let container_padding = value.container_padding().and_then(|container_padding| {
|
||||
if container_padding == default_container_padding {
|
||||
None
|
||||
} else {
|
||||
Option::from(container_padding)
|
||||
}
|
||||
});
|
||||
|
||||
let workspace_padding = value.workspace_padding().and_then(|workspace_padding| {
|
||||
if workspace_padding == default_workspace_padding {
|
||||
None
|
||||
} else {
|
||||
Option::from(workspace_padding)
|
||||
}
|
||||
});
|
||||
|
||||
Self {
|
||||
workspaces,
|
||||
work_area_offset: value.work_area_offset(),
|
||||
window_based_work_area_offset: value.window_based_work_area_offset(),
|
||||
window_based_work_area_offset_limit: Some(value.window_based_work_area_offset_limit()),
|
||||
container_padding,
|
||||
workspace_padding,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1250,6 +1277,7 @@ impl StaticConfig {
|
||||
workspace_matching_rules.clear();
|
||||
drop(workspace_matching_rules);
|
||||
|
||||
let offset = wm.work_area_offset;
|
||||
for (i, monitor) in wm.monitors_mut().iter_mut().enumerate() {
|
||||
let preferred_config_idx = {
|
||||
let display_index_preferences = DISPLAY_INDEX_PREFERENCES.lock();
|
||||
@@ -1295,7 +1323,10 @@ impl StaticConfig {
|
||||
.window_based_work_area_offset_limit
|
||||
.unwrap_or(1),
|
||||
);
|
||||
monitor.set_container_padding(monitor_config.container_padding);
|
||||
monitor.set_workspace_padding(monitor_config.workspace_padding);
|
||||
|
||||
monitor.update_workspaces_globals(offset);
|
||||
for (j, ws) in monitor.workspaces_mut().iter_mut().enumerate() {
|
||||
if let Some(workspace_config) = monitor_config.workspaces.get(j) {
|
||||
ws.load_static_config(workspace_config)?;
|
||||
@@ -1377,6 +1408,10 @@ impl StaticConfig {
|
||||
.window_based_work_area_offset_limit
|
||||
.unwrap_or(1),
|
||||
);
|
||||
m.set_container_padding(monitor_config.container_padding);
|
||||
m.set_workspace_padding(monitor_config.workspace_padding);
|
||||
|
||||
m.update_workspaces_globals(offset);
|
||||
|
||||
for (j, ws) in m.workspaces_mut().iter_mut().enumerate() {
|
||||
if let Some(workspace_config) = monitor_config.workspaces.get(j) {
|
||||
@@ -1411,6 +1446,7 @@ impl StaticConfig {
|
||||
workspace_matching_rules.clear();
|
||||
drop(workspace_matching_rules);
|
||||
|
||||
let offset = wm.work_area_offset;
|
||||
for (i, monitor) in wm.monitors_mut().iter_mut().enumerate() {
|
||||
let preferred_config_idx = {
|
||||
let display_index_preferences = DISPLAY_INDEX_PREFERENCES.lock();
|
||||
@@ -1458,6 +1494,10 @@ impl StaticConfig {
|
||||
.window_based_work_area_offset_limit
|
||||
.unwrap_or(1),
|
||||
);
|
||||
monitor.set_container_padding(monitor_config.container_padding);
|
||||
monitor.set_workspace_padding(monitor_config.workspace_padding);
|
||||
|
||||
monitor.update_workspaces_globals(offset);
|
||||
|
||||
for (j, ws) in monitor.workspaces_mut().iter_mut().enumerate() {
|
||||
if let Some(workspace_config) = monitor_config.workspaces.get(j) {
|
||||
@@ -1540,6 +1580,10 @@ impl StaticConfig {
|
||||
.window_based_work_area_offset_limit
|
||||
.unwrap_or(1),
|
||||
);
|
||||
m.set_container_padding(monitor_config.container_padding);
|
||||
m.set_workspace_padding(monitor_config.workspace_padding);
|
||||
|
||||
m.update_workspaces_globals(offset);
|
||||
|
||||
for (j, ws) in m.workspaces_mut().iter_mut().enumerate() {
|
||||
if let Some(workspace_config) = monitor_config.workspaces.get(j) {
|
||||
|
||||
@@ -337,6 +337,7 @@ impl From<&WindowManager> for State {
|
||||
.clone(),
|
||||
float_override: workspace.float_override,
|
||||
layer: workspace.layer,
|
||||
globals: workspace.globals,
|
||||
workspace_config: None,
|
||||
})
|
||||
.collect::<VecDeque<_>>();
|
||||
@@ -345,6 +346,8 @@ impl From<&WindowManager> for State {
|
||||
},
|
||||
last_focused_workspace: monitor.last_focused_workspace,
|
||||
workspace_names: monitor.workspace_names.clone(),
|
||||
container_padding: monitor.container_padding,
|
||||
workspace_padding: monitor.workspace_padding,
|
||||
})
|
||||
.collect::<VecDeque<_>>();
|
||||
stripped_monitors.focus(wm.monitors.focused_idx());
|
||||
@@ -979,18 +982,15 @@ impl WindowManager {
|
||||
let offset = self.work_area_offset;
|
||||
|
||||
for monitor in self.monitors_mut() {
|
||||
let work_area = *monitor.work_area_size();
|
||||
let window_based_work_area_offset = (
|
||||
monitor.window_based_work_area_offset_limit(),
|
||||
monitor.window_based_work_area_offset(),
|
||||
);
|
||||
|
||||
let offset = if monitor.work_area_offset().is_some() {
|
||||
monitor.work_area_offset()
|
||||
} else {
|
||||
offset
|
||||
};
|
||||
|
||||
let focused_workspace_idx = monitor.focused_workspace_idx();
|
||||
monitor.update_workspace_globals(focused_workspace_idx, offset);
|
||||
|
||||
let workspace = monitor
|
||||
.focused_workspace_mut()
|
||||
.ok_or_else(|| anyhow!("there is no workspace"))?;
|
||||
@@ -1002,7 +1002,7 @@ impl WindowManager {
|
||||
}
|
||||
}
|
||||
|
||||
workspace.update(&work_area, offset, window_based_work_area_offset)?;
|
||||
workspace.update()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -1704,6 +1704,7 @@ impl WindowManager {
|
||||
return Ok(());
|
||||
}
|
||||
let mouse_follows_focus = self.mouse_follows_focus;
|
||||
let offset = self.work_area_offset;
|
||||
let first_focused_workspace = {
|
||||
let first_monitor = self
|
||||
.monitors()
|
||||
@@ -1748,11 +1749,13 @@ impl WindowManager {
|
||||
|
||||
// Set the focused workspaces for the first and second monitors
|
||||
if let Some(first_monitor) = self.monitors_mut().get_mut(first_idx) {
|
||||
first_monitor.update_workspaces_globals(offset);
|
||||
first_monitor.focus_workspace(second_focused_workspace)?;
|
||||
first_monitor.load_focused_workspace(mouse_follows_focus)?;
|
||||
}
|
||||
|
||||
if let Some(second_monitor) = self.monitors_mut().get_mut(second_idx) {
|
||||
second_monitor.update_workspaces_globals(offset);
|
||||
second_monitor.focus_workspace(first_focused_workspace)?;
|
||||
second_monitor.load_focused_workspace(mouse_follows_focus)?;
|
||||
}
|
||||
@@ -1920,13 +1923,22 @@ impl WindowManager {
|
||||
pub fn remove_focused_workspace(&mut self) -> Option<Workspace> {
|
||||
let focused_monitor: &mut Monitor = self.focused_monitor_mut()?;
|
||||
let focused_workspace_idx = focused_monitor.focused_workspace_idx();
|
||||
focused_monitor.remove_workspace_by_idx(focused_workspace_idx)
|
||||
let workspace = focused_monitor.remove_workspace_by_idx(focused_workspace_idx);
|
||||
if let Err(error) = focused_monitor.focus_workspace(focused_workspace_idx.saturating_sub(1))
|
||||
{
|
||||
tracing::error!(
|
||||
"Error focusing previous workspace while removing the focused workspace: {}",
|
||||
error
|
||||
);
|
||||
}
|
||||
workspace
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub fn move_workspace_to_monitor(&mut self, idx: usize) -> Result<()> {
|
||||
tracing::info!("moving workspace");
|
||||
let mouse_follows_focus = self.mouse_follows_focus;
|
||||
let offset = self.work_area_offset;
|
||||
let workspace = self
|
||||
.remove_focused_workspace()
|
||||
.ok_or_else(|| anyhow!("there is no workspace"))?;
|
||||
@@ -1938,6 +1950,7 @@ impl WindowManager {
|
||||
.ok_or_else(|| anyhow!("there is no monitor"))?;
|
||||
|
||||
target_monitor.workspaces_mut().push_back(workspace);
|
||||
target_monitor.update_workspaces_globals(offset);
|
||||
target_monitor.focus_workspace(target_monitor.workspaces().len().saturating_sub(1))?;
|
||||
target_monitor.load_focused_workspace(mouse_follows_focus)?;
|
||||
}
|
||||
@@ -3082,7 +3095,6 @@ impl WindowManager {
|
||||
) -> Result<()> {
|
||||
tracing::info!("setting workspace layout");
|
||||
|
||||
let offset = self.work_area_offset;
|
||||
let focused_monitor_idx = self.focused_monitor_idx();
|
||||
|
||||
let monitor = self
|
||||
@@ -3090,18 +3102,7 @@ impl WindowManager {
|
||||
.get_mut(monitor_idx)
|
||||
.ok_or_else(|| anyhow!("there is no monitor"))?;
|
||||
|
||||
let work_area = *monitor.work_area_size();
|
||||
let window_based_work_area_offset = (
|
||||
monitor.window_based_work_area_offset_limit(),
|
||||
monitor.window_based_work_area_offset(),
|
||||
);
|
||||
|
||||
let focused_workspace_idx = monitor.focused_workspace_idx();
|
||||
let offset = if monitor.work_area_offset().is_some() {
|
||||
monitor.work_area_offset()
|
||||
} else {
|
||||
offset
|
||||
};
|
||||
|
||||
let workspace = monitor
|
||||
.workspaces_mut()
|
||||
@@ -3115,7 +3116,7 @@ impl WindowManager {
|
||||
|
||||
// If this is the focused workspace on a non-focused screen, let's update it
|
||||
if focused_monitor_idx != monitor_idx && focused_workspace_idx == workspace_idx {
|
||||
workspace.update(&work_area, offset, window_based_work_area_offset)?;
|
||||
workspace.update()?;
|
||||
Ok(())
|
||||
} else {
|
||||
Ok(self.update_focused_workspace(false, false)?)
|
||||
@@ -3135,7 +3136,6 @@ impl WindowManager {
|
||||
{
|
||||
tracing::info!("setting workspace layout");
|
||||
|
||||
let offset = self.work_area_offset;
|
||||
let focused_monitor_idx = self.focused_monitor_idx();
|
||||
|
||||
let monitor = self
|
||||
@@ -3143,18 +3143,7 @@ impl WindowManager {
|
||||
.get_mut(monitor_idx)
|
||||
.ok_or_else(|| anyhow!("there is no monitor"))?;
|
||||
|
||||
let work_area = *monitor.work_area_size();
|
||||
let window_based_work_area_offset = (
|
||||
monitor.window_based_work_area_offset_limit(),
|
||||
monitor.window_based_work_area_offset(),
|
||||
);
|
||||
|
||||
let focused_workspace_idx = monitor.focused_workspace_idx();
|
||||
let offset = if monitor.work_area_offset().is_some() {
|
||||
monitor.work_area_offset()
|
||||
} else {
|
||||
offset
|
||||
};
|
||||
|
||||
let workspace = monitor
|
||||
.workspaces_mut()
|
||||
@@ -3170,7 +3159,7 @@ impl WindowManager {
|
||||
|
||||
// If this is the focused workspace on a non-focused screen, let's update it
|
||||
if focused_monitor_idx != monitor_idx && focused_workspace_idx == workspace_idx {
|
||||
workspace.update(&work_area, offset, window_based_work_area_offset)?;
|
||||
workspace.update()?;
|
||||
Ok(())
|
||||
} else {
|
||||
Ok(self.update_focused_workspace(false, false)?)
|
||||
@@ -3185,7 +3174,6 @@ impl WindowManager {
|
||||
) -> Result<()> {
|
||||
tracing::info!("setting workspace layout");
|
||||
|
||||
let offset = self.work_area_offset;
|
||||
let focused_monitor_idx = self.focused_monitor_idx();
|
||||
|
||||
let monitor = self
|
||||
@@ -3193,18 +3181,7 @@ impl WindowManager {
|
||||
.get_mut(monitor_idx)
|
||||
.ok_or_else(|| anyhow!("there is no monitor"))?;
|
||||
|
||||
let work_area = *monitor.work_area_size();
|
||||
let window_based_work_area_offset = (
|
||||
monitor.window_based_work_area_offset_limit(),
|
||||
monitor.window_based_work_area_offset(),
|
||||
);
|
||||
|
||||
let focused_workspace_idx = monitor.focused_workspace_idx();
|
||||
let offset = if monitor.work_area_offset().is_some() {
|
||||
monitor.work_area_offset()
|
||||
} else {
|
||||
offset
|
||||
};
|
||||
|
||||
let workspace = monitor
|
||||
.workspaces_mut()
|
||||
@@ -3216,7 +3193,7 @@ impl WindowManager {
|
||||
|
||||
// If this is the focused workspace on a non-focused screen, let's update it
|
||||
if focused_monitor_idx != monitor_idx && focused_workspace_idx == workspace_idx {
|
||||
workspace.update(&work_area, offset, window_based_work_area_offset)?;
|
||||
workspace.update()?;
|
||||
Ok(())
|
||||
} else {
|
||||
Ok(self.update_focused_workspace(false, false)?)
|
||||
@@ -3232,7 +3209,6 @@ impl WindowManager {
|
||||
) -> Result<()> {
|
||||
tracing::info!("setting workspace layout");
|
||||
|
||||
let offset = self.work_area_offset;
|
||||
let focused_monitor_idx = self.focused_monitor_idx();
|
||||
|
||||
let monitor = self
|
||||
@@ -3240,18 +3216,7 @@ impl WindowManager {
|
||||
.get_mut(monitor_idx)
|
||||
.ok_or_else(|| anyhow!("there is no monitor"))?;
|
||||
|
||||
let work_area = *monitor.work_area_size();
|
||||
let window_based_work_area_offset = (
|
||||
monitor.window_based_work_area_offset_limit(),
|
||||
monitor.window_based_work_area_offset(),
|
||||
);
|
||||
|
||||
let focused_workspace_idx = monitor.focused_workspace_idx();
|
||||
let offset = if monitor.work_area_offset().is_some() {
|
||||
monitor.work_area_offset()
|
||||
} else {
|
||||
offset
|
||||
};
|
||||
|
||||
let workspace = monitor
|
||||
.workspaces_mut()
|
||||
@@ -3262,7 +3227,7 @@ impl WindowManager {
|
||||
|
||||
// If this is the focused workspace on a non-focused screen, let's update it
|
||||
if focused_monitor_idx != monitor_idx && focused_workspace_idx == workspace_idx {
|
||||
workspace.update(&work_area, offset, window_based_work_area_offset)?;
|
||||
workspace.update()?;
|
||||
Ok(())
|
||||
} else {
|
||||
Ok(self.update_focused_workspace(false, false)?)
|
||||
@@ -3281,7 +3246,6 @@ impl WindowManager {
|
||||
{
|
||||
tracing::info!("setting workspace layout");
|
||||
let layout = CustomLayout::from_path(path)?;
|
||||
let offset = self.work_area_offset;
|
||||
let focused_monitor_idx = self.focused_monitor_idx();
|
||||
|
||||
let monitor = self
|
||||
@@ -3289,18 +3253,7 @@ impl WindowManager {
|
||||
.get_mut(monitor_idx)
|
||||
.ok_or_else(|| anyhow!("there is no monitor"))?;
|
||||
|
||||
let work_area = *monitor.work_area_size();
|
||||
let window_based_work_area_offset = (
|
||||
monitor.window_based_work_area_offset_limit(),
|
||||
monitor.window_based_work_area_offset(),
|
||||
);
|
||||
|
||||
let focused_workspace_idx = monitor.focused_workspace_idx();
|
||||
let offset = if monitor.work_area_offset().is_some() {
|
||||
monitor.work_area_offset()
|
||||
} else {
|
||||
offset
|
||||
};
|
||||
|
||||
let workspace = monitor
|
||||
.workspaces_mut()
|
||||
@@ -3312,7 +3265,7 @@ impl WindowManager {
|
||||
|
||||
// If this is the focused workspace on a non-focused screen, let's update it
|
||||
if focused_monitor_idx != monitor_idx && focused_workspace_idx == workspace_idx {
|
||||
workspace.update(&work_area, offset, window_based_work_area_offset)?;
|
||||
workspace.update()?;
|
||||
Ok(())
|
||||
} else {
|
||||
Ok(self.update_focused_workspace(false, false)?)
|
||||
|
||||
@@ -95,6 +95,8 @@ pub struct Workspace {
|
||||
#[getset(get = "pub", get_mut = "pub", set = "pub")]
|
||||
pub float_override: Option<bool>,
|
||||
#[getset(get = "pub", get_mut = "pub", set = "pub")]
|
||||
pub globals: WorkspaceGlobals,
|
||||
#[getset(get = "pub", get_mut = "pub", set = "pub")]
|
||||
pub layer: WorkspaceLayer,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[getset(get = "pub", set = "pub")]
|
||||
@@ -141,8 +143,9 @@ impl Default for Workspace {
|
||||
window_container_behaviour: None,
|
||||
window_container_behaviour_rules: None,
|
||||
float_override: None,
|
||||
workspace_config: None,
|
||||
layer: Default::default(),
|
||||
globals: Default::default(),
|
||||
workspace_config: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,21 +158,37 @@ pub enum WorkspaceWindowLocation {
|
||||
Floating(usize), // idx in floating_windows
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Debug,
|
||||
Default,
|
||||
Copy,
|
||||
Clone,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Getters,
|
||||
CopyGetters,
|
||||
MutGetters,
|
||||
Setters,
|
||||
JsonSchema,
|
||||
PartialEq,
|
||||
)]
|
||||
/// Settings setup either by the parent monitor or by the `WindowManager`
|
||||
pub struct WorkspaceGlobals {
|
||||
pub container_padding: Option<i32>,
|
||||
pub workspace_padding: Option<i32>,
|
||||
pub work_area: Rect,
|
||||
pub work_area_offset: Option<Rect>,
|
||||
pub window_based_work_area_offset: Option<Rect>,
|
||||
pub window_based_work_area_offset_limit: isize,
|
||||
}
|
||||
|
||||
impl Workspace {
|
||||
pub fn load_static_config(&mut self, config: &WorkspaceConfig) -> Result<()> {
|
||||
self.name = Option::from(config.name.clone());
|
||||
|
||||
if config.container_padding.is_some() {
|
||||
self.set_container_padding(config.container_padding);
|
||||
} else {
|
||||
self.set_container_padding(Some(DEFAULT_CONTAINER_PADDING.load(Ordering::SeqCst)));
|
||||
}
|
||||
self.set_container_padding(config.container_padding);
|
||||
|
||||
if config.workspace_padding.is_some() {
|
||||
self.set_workspace_padding(config.workspace_padding);
|
||||
} else {
|
||||
self.set_container_padding(Some(DEFAULT_WORKSPACE_PADDING.load(Ordering::SeqCst)));
|
||||
}
|
||||
self.set_workspace_padding(config.workspace_padding);
|
||||
|
||||
if let Some(layout) = &config.layout {
|
||||
self.layout = Layout::Default(*layout);
|
||||
@@ -315,24 +334,29 @@ impl Workspace {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn update(
|
||||
&mut self,
|
||||
work_area: &Rect,
|
||||
work_area_offset: Option<Rect>,
|
||||
window_based_work_area_offset: (isize, Option<Rect>),
|
||||
) -> Result<()> {
|
||||
pub fn update(&mut self) -> Result<()> {
|
||||
if !INITIAL_CONFIGURATION_LOADED.load(Ordering::SeqCst) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let (window_based_work_area_offset_limit, window_based_work_area_offset) =
|
||||
window_based_work_area_offset;
|
||||
let container_padding = self
|
||||
.container_padding()
|
||||
.or(self.globals().container_padding)
|
||||
.unwrap_or_default();
|
||||
let workspace_padding = self
|
||||
.workspace_padding()
|
||||
.or(self.globals().workspace_padding)
|
||||
.unwrap_or_default();
|
||||
let work_area = self.globals().work_area;
|
||||
let work_area_offset = self.globals().work_area_offset;
|
||||
let window_based_work_area_offset = self.globals().window_based_work_area_offset;
|
||||
let window_based_work_area_offset_limit =
|
||||
self.globals().window_based_work_area_offset_limit;
|
||||
|
||||
let container_padding = self.container_padding();
|
||||
let mut adjusted_work_area = work_area_offset.map_or_else(
|
||||
|| *work_area,
|
||||
|| work_area,
|
||||
|offset| {
|
||||
let mut with_offset = *work_area;
|
||||
let mut with_offset = work_area;
|
||||
with_offset.left += offset.left;
|
||||
with_offset.top += offset.top;
|
||||
with_offset.right -= offset.right;
|
||||
@@ -360,7 +384,7 @@ impl Workspace {
|
||||
);
|
||||
}
|
||||
|
||||
adjusted_work_area.add_padding(self.workspace_padding().unwrap_or_default());
|
||||
adjusted_work_area.add_padding(workspace_padding);
|
||||
|
||||
self.enforce_resize_constraints();
|
||||
|
||||
@@ -394,7 +418,7 @@ impl Workspace {
|
||||
if *self.tile() {
|
||||
if let Some(container) = self.monocle_container_mut() {
|
||||
if let Some(window) = container.focused_window_mut() {
|
||||
adjusted_work_area.add_padding(container_padding.unwrap_or_default());
|
||||
adjusted_work_area.add_padding(container_padding);
|
||||
{
|
||||
let border_offset = BORDER_OFFSET.load(Ordering::SeqCst);
|
||||
adjusted_work_area.add_padding(border_offset);
|
||||
@@ -413,7 +437,7 @@ impl Workspace {
|
||||
"there must be at least one container to calculate a workspace layout"
|
||||
)
|
||||
})?,
|
||||
self.container_padding(),
|
||||
Some(container_padding),
|
||||
self.layout_flip(),
|
||||
self.resize_dimensions(),
|
||||
);
|
||||
@@ -422,7 +446,6 @@ impl Workspace {
|
||||
let no_titlebar = NO_TITLEBAR.lock().clone();
|
||||
let regex_identifiers = REGEX_IDENTIFIERS.lock().clone();
|
||||
|
||||
let container_padding = self.container_padding().unwrap_or(0);
|
||||
let containers = self.containers_mut();
|
||||
|
||||
for (i, container) in containers.iter_mut().enumerate() {
|
||||
|
||||
12
schema.json
12
schema.json
@@ -1075,6 +1075,11 @@
|
||||
"workspaces"
|
||||
],
|
||||
"properties": {
|
||||
"container_padding": {
|
||||
"description": "Container padding (default: global)",
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"window_based_work_area_offset": {
|
||||
"description": "Window based work area offset (default: None)",
|
||||
"type": "object",
|
||||
@@ -1144,6 +1149,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"workspace_padding": {
|
||||
"description": "Workspace padding (default: global)",
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"workspaces": {
|
||||
"description": "Workspace configurations",
|
||||
"type": "array",
|
||||
@@ -1346,7 +1356,7 @@
|
||||
}
|
||||
},
|
||||
"workspace_padding": {
|
||||
"description": "Container padding (default: global)",
|
||||
"description": "Workspace padding (default: global)",
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user