mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-03-23 18:01:12 +01:00
feat(wm): add vertical & horizontal stack layouts
This commit ports the CenterMain, MainAndVertStack, and MainAndHorizontalStack layouts from LeftWM to komorebi as UltrawideVerticalStack, VerticalStack and HorizontalStack. These layouts are fixed-size layouts, meaning that individual containers cannot be resized. The VerticalStack and UltrawideVerticalStack layouts support horizontal flipping, whereas the HorizontalStack layout supports vertical flipping. resolve #48
This commit is contained in:
24
Cargo.lock
generated
24
Cargo.lock
generated
@@ -199,9 +199,9 @@ checksum = "fb58b6451e8c2a812ad979ed1d83378caa5e927eef2622017a45f251457c2c9d"
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.2"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b"
|
||||
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
@@ -425,9 +425,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hotwatch"
|
||||
version = "0.4.5"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d61ee702e77f237b41761361a82e5c4bf6277dbb4bc8b6b7d745cb249cc82b31"
|
||||
checksum = "39301670a6f5798b75f36a1b149a379a50df5aa7c71be50f4b41ec6eab445cb8"
|
||||
dependencies = [
|
||||
"log",
|
||||
"notify",
|
||||
@@ -853,9 +853,9 @@ checksum = "36d62894f5590e88d99d0d82918742ba8e5bff1985af15d4906b6a65f635adb2"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.10"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
|
||||
checksum = "c3ca011bd0129ff4ae15cd04c4eef202cadf6c51c21e47aba319b4e0501db741"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
@@ -883,9 +883,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.29"
|
||||
version = "1.0.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d"
|
||||
checksum = "edc3358ebc67bc8b7fa0c007f945b0b18226f78437d61bec735a9eb96b61ee70"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
@@ -1113,18 +1113,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sharded-slab"
|
||||
version = "0.1.3"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "740223c51853f3145fe7c90360d2d4232f2b62e3449489c207eccde818979982"
|
||||
checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.4"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590"
|
||||
checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
|
||||
@@ -306,9 +306,13 @@ used [is available here](komorebi.sample.with.lib.ahk).
|
||||
- [x] Mouse drag to swap window container position
|
||||
- [x] Mouse drag to resize window container
|
||||
- [x] Configurable workspace and container gaps
|
||||
- [x] BSP tree layout
|
||||
- [x] BSP tree layout (`bsp`)
|
||||
- [x] Flip BSP tree layout horizontally or vertically
|
||||
- [x] Equal-width, max-height column layout
|
||||
- [x] Equal-width, max-height column layout (`columns`)
|
||||
- [x] Equal-height, max-width row layout (`rows`)
|
||||
- [x] Main half-height window with vertical stack layout (`horizontal-stack`)
|
||||
- [x] Main half-width window with horizontal stack layout (`vertical-stack`)
|
||||
- [x] 2x Main window (half and quarter-width) with horizontal stack layout (`ultrawide-vertical-stack`)
|
||||
- [x] Floating rules based on exe name, window title and class
|
||||
- [x] Workspace rules based on exe name and window class
|
||||
- [x] Additional manage rules based on exe name and window class
|
||||
|
||||
@@ -16,6 +16,9 @@ pub enum Layout {
|
||||
BSP,
|
||||
Columns,
|
||||
Rows,
|
||||
VerticalStack,
|
||||
HorizontalStack,
|
||||
UltrawideVerticalStack,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ArgEnum)]
|
||||
@@ -131,7 +134,11 @@ impl Layout {
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
#[allow(clippy::cast_possible_truncation, clippy::cast_possible_wrap)]
|
||||
#[allow(
|
||||
clippy::cast_possible_truncation,
|
||||
clippy::cast_possible_wrap,
|
||||
clippy::too_many_lines
|
||||
)]
|
||||
pub fn calculate(
|
||||
&self,
|
||||
area: &Rect,
|
||||
@@ -185,6 +192,176 @@ impl Layout {
|
||||
|
||||
layouts
|
||||
}
|
||||
Layout::VerticalStack => {
|
||||
let mut layouts: Vec<Rect> = vec![];
|
||||
layouts.resize(len, Rect::default());
|
||||
|
||||
let primary_right = match len {
|
||||
1 => area.right,
|
||||
_ => area.right / 2,
|
||||
};
|
||||
|
||||
let mut main_left = area.left;
|
||||
let mut stack_left = area.left + primary_right;
|
||||
|
||||
match layout_flip {
|
||||
Some(Flip::Horizontal | Flip::HorizontalAndVertical) if len > 1 => {
|
||||
main_left = main_left + area.right - primary_right;
|
||||
stack_left = area.left;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let mut iter = layouts.iter_mut();
|
||||
{
|
||||
if let Some(first) = iter.next() {
|
||||
first.left = main_left;
|
||||
first.top = area.top;
|
||||
first.right = primary_right;
|
||||
first.bottom = area.bottom;
|
||||
}
|
||||
}
|
||||
|
||||
let bottom = area.bottom / (len - 1) as i32;
|
||||
let mut top = 0;
|
||||
|
||||
for next in iter {
|
||||
next.left = stack_left;
|
||||
next.top = area.top + top;
|
||||
next.right = area.right - primary_right;
|
||||
next.bottom = bottom;
|
||||
|
||||
top += bottom;
|
||||
}
|
||||
|
||||
layouts
|
||||
}
|
||||
Layout::HorizontalStack => {
|
||||
let mut layouts: Vec<Rect> = vec![];
|
||||
layouts.resize(len, Rect::default());
|
||||
|
||||
let bottom = match len {
|
||||
1 => area.bottom,
|
||||
_ => area.bottom / 2,
|
||||
};
|
||||
|
||||
let mut main_top = area.top;
|
||||
let mut stack_top = area.top + bottom;
|
||||
|
||||
match layout_flip {
|
||||
Some(Flip::Vertical | Flip::HorizontalAndVertical) if len > 1 => {
|
||||
main_top = main_top + area.bottom - bottom;
|
||||
stack_top = area.top;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let mut iter = layouts.iter_mut();
|
||||
{
|
||||
if let Some(first) = iter.next() {
|
||||
first.left = area.left;
|
||||
first.top = main_top;
|
||||
first.right = area.right;
|
||||
first.bottom = bottom;
|
||||
}
|
||||
}
|
||||
|
||||
let right = area.right / (len - 1) as i32;
|
||||
let mut left = 0;
|
||||
|
||||
for next in iter {
|
||||
next.left = area.left + left;
|
||||
next.top = stack_top;
|
||||
next.right = right;
|
||||
next.bottom = area.bottom - bottom;
|
||||
|
||||
left += right;
|
||||
}
|
||||
|
||||
layouts
|
||||
}
|
||||
Layout::UltrawideVerticalStack => {
|
||||
let mut layouts: Vec<Rect> = vec![];
|
||||
layouts.resize(len, Rect::default());
|
||||
|
||||
let primary_right = match len {
|
||||
1 => area.right,
|
||||
_ => area.right / 2,
|
||||
};
|
||||
|
||||
let secondary_right = match len {
|
||||
1 => 0,
|
||||
2 => area.right - primary_right,
|
||||
_ => (area.right - primary_right) / 2,
|
||||
};
|
||||
|
||||
let (primary_left, secondary_left, stack_left) = match len {
|
||||
1 => (area.left, 0, 0),
|
||||
2 => {
|
||||
let mut primary = area.left + secondary_right;
|
||||
let mut secondary = area.left;
|
||||
|
||||
match layout_flip {
|
||||
Some(Flip::Horizontal | Flip::HorizontalAndVertical) if len > 1 => {
|
||||
primary = area.left;
|
||||
secondary = area.left + primary_right;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
(primary, secondary, 0)
|
||||
}
|
||||
_ => {
|
||||
let primary = area.left + secondary_right;
|
||||
let mut secondary = area.left;
|
||||
let mut stack = area.left + primary_right + secondary_right;
|
||||
|
||||
match layout_flip {
|
||||
Some(Flip::Horizontal | Flip::HorizontalAndVertical) if len > 1 => {
|
||||
secondary = area.left + primary_right + secondary_right;
|
||||
stack = area.left;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
(primary, secondary, stack)
|
||||
}
|
||||
};
|
||||
|
||||
let mut iter = layouts.iter_mut();
|
||||
|
||||
{
|
||||
if let Some(first) = iter.next() {
|
||||
first.left = primary_left;
|
||||
first.top = area.top;
|
||||
first.right = primary_right;
|
||||
first.bottom = area.bottom;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if let Some(second) = iter.next() {
|
||||
second.left = secondary_left;
|
||||
second.top = area.top;
|
||||
second.right = secondary_right;
|
||||
second.bottom = area.bottom;
|
||||
}
|
||||
}
|
||||
|
||||
if len > 2 {
|
||||
let height = area.bottom / (len - 2) as i32;
|
||||
let mut y = 0;
|
||||
|
||||
for next in iter {
|
||||
next.left = stack_left;
|
||||
next.top = area.top + y;
|
||||
next.right = secondary_right;
|
||||
next.bottom = height;
|
||||
y += height;
|
||||
}
|
||||
}
|
||||
layouts
|
||||
}
|
||||
};
|
||||
|
||||
dimensions
|
||||
|
||||
@@ -60,22 +60,36 @@ impl OperationDirection {
|
||||
Self::Up => match layout {
|
||||
Layout::BSP => len > 2 && idx != 0 && idx != 1,
|
||||
Layout::Columns => false,
|
||||
Layout::Rows => idx != 0,
|
||||
Layout::Rows | Layout::HorizontalStack => idx != 0,
|
||||
Layout::VerticalStack => idx != 0 && idx != 1,
|
||||
Layout::UltrawideVerticalStack => idx > 2,
|
||||
},
|
||||
Self::Down => match layout {
|
||||
Layout::BSP => len > 2 && idx != len - 1 && idx % 2 != 0,
|
||||
Layout::Columns => false,
|
||||
Layout::Rows => idx != len - 1,
|
||||
Layout::VerticalStack => idx != 0 && idx != len - 1,
|
||||
Layout::HorizontalStack => idx == 0,
|
||||
Layout::UltrawideVerticalStack => idx > 1 && idx != len - 1,
|
||||
},
|
||||
Self::Left => match layout {
|
||||
Layout::BSP => len > 1 && idx != 0,
|
||||
Layout::Columns => idx != 0,
|
||||
Layout::Columns | Layout::VerticalStack => idx != 0,
|
||||
Layout::Rows => false,
|
||||
Layout::HorizontalStack => idx != 0 && idx != 1,
|
||||
Layout::UltrawideVerticalStack => len > 1 && idx != 1,
|
||||
},
|
||||
Self::Right => match layout {
|
||||
Layout::BSP => len > 1 && idx % 2 == 0 && idx != len - 1,
|
||||
Layout::Columns => idx != len - 1,
|
||||
Layout::Rows => false,
|
||||
Layout::VerticalStack => idx == 0,
|
||||
Layout::HorizontalStack => idx != 0 && idx != len - 1,
|
||||
Layout::UltrawideVerticalStack => match len {
|
||||
0 | 1 => false,
|
||||
2 => idx != 0,
|
||||
_ => idx < 2,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -92,11 +106,16 @@ impl OperationDirection {
|
||||
}
|
||||
}
|
||||
Layout::Columns => unreachable!(),
|
||||
Layout::Rows => idx - 1,
|
||||
Layout::Rows | Layout::VerticalStack | Layout::UltrawideVerticalStack => idx - 1,
|
||||
Layout::HorizontalStack => 0,
|
||||
},
|
||||
Self::Down => match layout {
|
||||
Layout::BSP | Layout::Rows => idx + 1,
|
||||
Layout::BSP
|
||||
| Layout::Rows
|
||||
| Layout::VerticalStack
|
||||
| Layout::UltrawideVerticalStack => idx + 1,
|
||||
Layout::Columns => unreachable!(),
|
||||
Layout::HorizontalStack => 1,
|
||||
},
|
||||
Self::Left => match layout {
|
||||
Layout::BSP => {
|
||||
@@ -106,12 +125,24 @@ impl OperationDirection {
|
||||
idx - 1
|
||||
}
|
||||
}
|
||||
Layout::Columns => idx - 1,
|
||||
Layout::Columns | Layout::HorizontalStack => idx - 1,
|
||||
Layout::Rows => unreachable!(),
|
||||
Layout::VerticalStack => 0,
|
||||
Layout::UltrawideVerticalStack => match idx {
|
||||
0 => 1,
|
||||
1 => unreachable!(),
|
||||
_ => 0,
|
||||
},
|
||||
},
|
||||
Self::Right => match layout {
|
||||
Layout::BSP | Layout::Columns => idx + 1,
|
||||
Layout::BSP | Layout::Columns | Layout::HorizontalStack => idx + 1,
|
||||
Layout::Rows => unreachable!(),
|
||||
Layout::VerticalStack => 1,
|
||||
Layout::UltrawideVerticalStack => match idx {
|
||||
1 => 0,
|
||||
0 => 2,
|
||||
_ => unreachable!(),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user