mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-04-24 09:38:32 +02:00
feat(wm): add per-workspace tiling config + toggle
Added two commands, 'komorebic toggle-tiling' and 'komorebic workspace-tiling MONITOR_IDX WORKSPACE_IDX on|off' which allow for tiling on the currently focused workspace to be toggled on and off, and for the tiling for a specific workspace to be set to on or off (useful if you want a specific workspace to always have tiling set to off at startup). resolve #5
This commit is contained in:
@@ -40,6 +40,7 @@ pub enum SocketMessage {
|
|||||||
// Monitor and Workspace Commands
|
// Monitor and Workspace Commands
|
||||||
EnsureWorkspaces(usize, usize),
|
EnsureWorkspaces(usize, usize),
|
||||||
NewWorkspace,
|
NewWorkspace,
|
||||||
|
ToggleTiling,
|
||||||
Stop,
|
Stop,
|
||||||
TogglePause,
|
TogglePause,
|
||||||
Retile,
|
Retile,
|
||||||
@@ -47,6 +48,7 @@ pub enum SocketMessage {
|
|||||||
FocusWorkspaceNumber(usize),
|
FocusWorkspaceNumber(usize),
|
||||||
ContainerPadding(usize, usize, i32),
|
ContainerPadding(usize, usize, i32),
|
||||||
WorkspacePadding(usize, usize, i32),
|
WorkspacePadding(usize, usize, i32),
|
||||||
|
WorkspaceTiling(usize, usize, bool),
|
||||||
WorkspaceName(usize, usize, String),
|
WorkspaceName(usize, usize, String),
|
||||||
WorkspaceLayout(usize, usize, Layout),
|
WorkspaceLayout(usize, usize, Layout),
|
||||||
// Configuration
|
// Configuration
|
||||||
|
|||||||
@@ -102,6 +102,9 @@ impl WindowManager {
|
|||||||
tracing::info!("pausing");
|
tracing::info!("pausing");
|
||||||
self.is_paused = !self.is_paused;
|
self.is_paused = !self.is_paused;
|
||||||
}
|
}
|
||||||
|
SocketMessage::ToggleTiling => {
|
||||||
|
self.toggle_tiling()?;
|
||||||
|
}
|
||||||
SocketMessage::FocusMonitorNumber(monitor_idx) => {
|
SocketMessage::FocusMonitorNumber(monitor_idx) => {
|
||||||
self.focus_monitor(monitor_idx)?;
|
self.focus_monitor(monitor_idx)?;
|
||||||
self.update_focused_workspace(true)?;
|
self.update_focused_workspace(true)?;
|
||||||
@@ -123,6 +126,9 @@ impl WindowManager {
|
|||||||
}
|
}
|
||||||
SocketMessage::FlipLayout(layout_flip) => self.flip_layout(layout_flip)?,
|
SocketMessage::FlipLayout(layout_flip) => self.flip_layout(layout_flip)?,
|
||||||
SocketMessage::ChangeLayout(layout) => self.change_workspace_layout(layout)?,
|
SocketMessage::ChangeLayout(layout) => self.change_workspace_layout(layout)?,
|
||||||
|
SocketMessage::WorkspaceTiling(monitor_idx, workspace_idx, tile) => {
|
||||||
|
self.set_workspace_tiling(monitor_idx, workspace_idx, tile)?;
|
||||||
|
}
|
||||||
SocketMessage::WorkspaceLayout(monitor_idx, workspace_idx, layout) => {
|
SocketMessage::WorkspaceLayout(monitor_idx, workspace_idx, layout) => {
|
||||||
self.set_workspace_layout(monitor_idx, workspace_idx, layout)?;
|
self.set_workspace_layout(monitor_idx, workspace_idx, layout)?;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -326,6 +326,13 @@ impl WindowManager {
|
|||||||
self.update_focused_workspace(true)
|
self.update_focused_workspace(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self))]
|
||||||
|
pub fn toggle_tiling(&mut self) -> Result<()> {
|
||||||
|
let workspace = self.focused_workspace_mut()?;
|
||||||
|
workspace.set_tile(!workspace.tile());
|
||||||
|
self.update_focused_workspace(false)
|
||||||
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip(self))]
|
#[tracing::instrument(skip(self))]
|
||||||
pub fn toggle_float(&mut self) -> Result<()> {
|
pub fn toggle_float(&mut self) -> Result<()> {
|
||||||
let hwnd = WindowsApi::top_visible_window()?;
|
let hwnd = WindowsApi::top_visible_window()?;
|
||||||
@@ -496,6 +503,28 @@ impl WindowManager {
|
|||||||
self.update_focused_workspace(false)
|
self.update_focused_workspace(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self))]
|
||||||
|
pub fn set_workspace_tiling(
|
||||||
|
&mut self,
|
||||||
|
monitor_idx: usize,
|
||||||
|
workspace_idx: usize,
|
||||||
|
tile: bool,
|
||||||
|
) -> Result<()> {
|
||||||
|
let monitor = self
|
||||||
|
.monitors_mut()
|
||||||
|
.get_mut(monitor_idx)
|
||||||
|
.context("there is no monitor")?;
|
||||||
|
|
||||||
|
let workspace = monitor
|
||||||
|
.workspaces_mut()
|
||||||
|
.get_mut(workspace_idx)
|
||||||
|
.context("there is no monitor")?;
|
||||||
|
|
||||||
|
workspace.set_tile(tile);
|
||||||
|
|
||||||
|
self.update_focused_workspace(false)
|
||||||
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip(self))]
|
#[tracing::instrument(skip(self))]
|
||||||
pub fn set_workspace_layout(
|
pub fn set_workspace_layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ pub struct Workspace {
|
|||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
#[getset(get = "pub", get_mut = "pub")]
|
#[getset(get = "pub", get_mut = "pub")]
|
||||||
resize_dimensions: Vec<Option<Rect>>,
|
resize_dimensions: Vec<Option<Rect>>,
|
||||||
|
#[getset(get = "pub", set = "pub")]
|
||||||
|
tile: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_ring_elements!(Workspace, Container);
|
impl_ring_elements!(Workspace, Container);
|
||||||
@@ -62,6 +64,7 @@ impl Default for Workspace {
|
|||||||
container_padding: Option::from(10),
|
container_padding: Option::from(10),
|
||||||
latest_layout: vec![],
|
latest_layout: vec![],
|
||||||
resize_dimensions: vec![],
|
resize_dimensions: vec![],
|
||||||
|
tile: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,33 +105,37 @@ impl Workspace {
|
|||||||
|
|
||||||
self.enforce_resize_constraints();
|
self.enforce_resize_constraints();
|
||||||
|
|
||||||
if let Some(container) = self.monocle_container_mut() {
|
if *self.tile() {
|
||||||
if let Some(window) = container.focused_window_mut() {
|
if let Some(container) = self.monocle_container_mut() {
|
||||||
window.set_position(&adjusted_work_area, true)?;
|
if let Some(window) = container.focused_window_mut() {
|
||||||
}
|
window.set_position(&adjusted_work_area, true)?;
|
||||||
} else {
|
|
||||||
let layouts = self.layout().calculate(
|
|
||||||
&adjusted_work_area,
|
|
||||||
self.containers().len(),
|
|
||||||
self.container_padding(),
|
|
||||||
self.layout_flip(),
|
|
||||||
self.resize_dimensions(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let windows = self.visible_windows_mut();
|
|
||||||
for (i, window) in windows.into_iter().enumerate() {
|
|
||||||
if let (Some(window), Some(layout)) = (window, layouts.get(i)) {
|
|
||||||
window.set_position(layout, false)?;
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
let layouts = self.layout().calculate(
|
||||||
|
&adjusted_work_area,
|
||||||
|
self.containers().len(),
|
||||||
|
self.container_padding(),
|
||||||
|
self.layout_flip(),
|
||||||
|
self.resize_dimensions(),
|
||||||
|
);
|
||||||
|
|
||||||
// Always make sure that the length of the resize dimensions vec is the same as the
|
let windows = self.visible_windows_mut();
|
||||||
// number of layouts / containers. This should never actually truncate as the remove_window
|
for (i, window) in windows.into_iter().enumerate() {
|
||||||
// function takes care of cleaning up resize dimensions when destroying empty containers
|
if let (Some(window), Some(layout)) = (window, layouts.get(i)) {
|
||||||
self.resize_dimensions_mut().resize(layouts.len(), None);
|
window.set_position(layout, false)?;
|
||||||
self.set_latest_layout(layouts);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.set_latest_layout(layouts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Always make sure that the length of the resize dimensions vec is the same as the
|
||||||
|
// number of layouts / containers. This should never actually truncate as the remove_window
|
||||||
|
// function takes care of cleaning up resize dimensions when destroying empty containers
|
||||||
|
let container_count = self.containers().len();
|
||||||
|
self.resize_dimensions_mut().resize(container_count, None);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,9 @@ enum SubCommand {
|
|||||||
ContainerPadding(SizeForMonitorWorkspace),
|
ContainerPadding(SizeForMonitorWorkspace),
|
||||||
WorkspacePadding(SizeForMonitorWorkspace),
|
WorkspacePadding(SizeForMonitorWorkspace),
|
||||||
WorkspaceLayout(LayoutForMonitorWorkspace),
|
WorkspaceLayout(LayoutForMonitorWorkspace),
|
||||||
|
WorkspaceTiling(TilingForMonitorWorkspace),
|
||||||
WorkspaceName(NameForMonitorWorkspace),
|
WorkspaceName(NameForMonitorWorkspace),
|
||||||
|
ToggleTiling,
|
||||||
ToggleFloat,
|
ToggleFloat,
|
||||||
TogglePause,
|
TogglePause,
|
||||||
ToggleMonocle,
|
ToggleMonocle,
|
||||||
@@ -91,6 +93,22 @@ struct LayoutForMonitorWorkspace {
|
|||||||
layout: Layout,
|
layout: Layout,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_or_off(s: &str) -> Result<bool, &'static str> {
|
||||||
|
match s {
|
||||||
|
"on" => Ok(true),
|
||||||
|
"off" => Ok(false),
|
||||||
|
_ => Err("expected `on` or `off`"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clap)]
|
||||||
|
struct TilingForMonitorWorkspace {
|
||||||
|
monitor: usize,
|
||||||
|
workspace: usize,
|
||||||
|
#[clap(parse(try_from_str = on_or_off))]
|
||||||
|
tile: bool,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clap)]
|
#[derive(Clap)]
|
||||||
struct Target {
|
struct Target {
|
||||||
number: usize,
|
number: usize,
|
||||||
@@ -187,6 +205,9 @@ fn main() -> Result<()> {
|
|||||||
.as_bytes()?,
|
.as_bytes()?,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
SubCommand::ToggleTiling => {
|
||||||
|
send_message(&*SocketMessage::ToggleTiling.as_bytes()?)?;
|
||||||
|
}
|
||||||
SubCommand::ToggleFloat => {
|
SubCommand::ToggleFloat => {
|
||||||
send_message(&*SocketMessage::ToggleFloat.as_bytes()?)?;
|
send_message(&*SocketMessage::ToggleFloat.as_bytes()?)?;
|
||||||
}
|
}
|
||||||
@@ -199,6 +220,12 @@ fn main() -> Result<()> {
|
|||||||
.as_bytes()?,
|
.as_bytes()?,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
SubCommand::WorkspaceTiling(layout) => {
|
||||||
|
send_message(
|
||||||
|
&*SocketMessage::WorkspaceTiling(layout.monitor, layout.workspace, layout.tile)
|
||||||
|
.as_bytes()?,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
SubCommand::Start => {
|
SubCommand::Start => {
|
||||||
let script = r#"Start-Process komorebi -WindowStyle hidden"#;
|
let script = r#"Start-Process komorebi -WindowStyle hidden"#;
|
||||||
match powershell_script::run(script, true) {
|
match powershell_script::run(script, true) {
|
||||||
|
|||||||
Reference in New Issue
Block a user