refactor(layouts): extract independent komorebi-layouts crate

This commit moves layout-related code into a new workspace crate
komorebi-layouts, with the intention of re-using it all in komorebi for
Mac instead of maintaining two separate implementations.
This commit is contained in:
LGUG2Z
2026-02-07 13:03:39 -08:00
parent 22e8a79833
commit 0b5141e7a4
19 changed files with 135 additions and 53 deletions

16
Cargo.lock generated
View File

@@ -3134,6 +3134,7 @@ dependencies = [
"dirs 6.0.0", "dirs 6.0.0",
"ed25519-dalek", "ed25519-dalek",
"hotwatch", "hotwatch",
"komorebi-layouts",
"komorebi-themes", "komorebi-themes",
"lazy_static", "lazy_static",
"miow", "miow",
@@ -3231,6 +3232,21 @@ dependencies = [
"windows-core 0.62.2", "windows-core 0.62.2",
] ]
[[package]]
name = "komorebi-layouts"
version = "0.1.40"
dependencies = [
"clap",
"color-eyre",
"schemars 1.2.1",
"serde",
"serde_json_lenient",
"serde_yaml 0.9.34+deprecated",
"strum",
"tracing",
"windows 0.62.2",
]
[[package]] [[package]]
name = "komorebi-shortcuts" name = "komorebi-shortcuts"
version = "0.1.0" version = "0.1.0"

View File

@@ -5,6 +5,7 @@ members = [
"komorebi", "komorebi",
"komorebi-client", "komorebi-client",
"komorebi-gui", "komorebi-gui",
"komorebi-layouts",
"komorebic", "komorebic",
"komorebic-no-console", "komorebic-no-console",
"komorebi-bar", "komorebi-bar",

View File

@@ -0,0 +1,21 @@
[package]
name = "komorebi-layouts"
version = "0.1.40"
edition = "2024"
[dependencies]
clap = { workspace = true }
color-eyre = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
serde_yaml = { workspace = true }
strum = { workspace = true }
tracing = { workspace = true }
# Optional dependencies
schemars = { workspace = true, optional = true }
windows = { workspace = true, optional = true }
[features]
schemars = ["dep:schemars"]
win32 = ["dep:windows"]

View File

@@ -0,0 +1,28 @@
#![warn(clippy::all)]
#![allow(clippy::missing_errors_doc, clippy::use_self, clippy::doc_markdown)]
//! Layout system for the komorebi window manager.
//!
//! This crate provides the core layout algorithms and types for arranging windows
//! in various configurations. It includes optional Windows-specific functionality
//! behind the `win32` feature flag.
pub mod arrangement;
pub mod custom_layout;
pub mod cycle_direction;
pub mod default_layout;
pub mod direction;
pub mod layout;
pub mod operation_direction;
pub mod rect;
pub mod sizing;
pub use arrangement::*;
pub use custom_layout::*;
pub use cycle_direction::*;
pub use default_layout::*;
pub use direction::*;
pub use layout::*;
pub use operation_direction::*;
pub use rect::*;
pub use sizing::*;

View File

@@ -1,5 +1,7 @@
use serde::Deserialize; use serde::Deserialize;
use serde::Serialize; use serde::Serialize;
#[cfg(feature = "win32")]
use windows::Win32::Foundation::RECT; use windows::Win32::Foundation::RECT;
#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize, Eq, PartialEq)] #[derive(Debug, Default, Clone, Copy, Serialize, Deserialize, Eq, PartialEq)]
@@ -16,6 +18,7 @@ pub struct Rect {
pub bottom: i32, pub bottom: i32,
} }
#[cfg(feature = "win32")]
impl From<RECT> for Rect { impl From<RECT> for Rect {
fn from(rect: RECT) -> Self { fn from(rect: RECT) -> Self {
Self { Self {
@@ -27,6 +30,7 @@ impl From<RECT> for Rect {
} }
} }
#[cfg(feature = "win32")]
impl From<Rect> for RECT { impl From<Rect> for RECT {
fn from(rect: Rect) -> Self { fn from(rect: Rect) -> Self {
Self { Self {
@@ -96,6 +100,7 @@ impl Rect {
} }
} }
#[cfg(feature = "win32")]
#[must_use] #[must_use]
pub const fn rect(&self) -> RECT { pub const fn rect(&self) -> RECT {
RECT { RECT {

View File

@@ -0,0 +1,31 @@
use clap::ValueEnum;
use serde::Deserialize;
use serde::Serialize;
use strum::Display;
use strum::EnumString;
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ValueEnum)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
/// Sizing
pub enum Sizing {
/// Increase
Increase,
/// Decrease
Decrease,
}
impl Sizing {
#[must_use]
pub const fn adjust_by(&self, value: i32, adjustment: i32) -> i32 {
match self {
Self::Increase => value + adjustment,
Self::Decrease => {
if value > 0 && value - adjustment >= 0 {
value - adjustment
} else {
value
}
}
}
}
}

View File

@@ -8,6 +8,7 @@ edition = "2024"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
komorebi-layouts = { path = "../komorebi-layouts", features = ["win32"] }
komorebi-themes = { path = "../komorebi-themes" } komorebi-themes = { path = "../komorebi-themes" }
base64 = "0.22" base64 = "0.22"
@@ -63,4 +64,4 @@ uuid = { version = "1", features = ["v4"] }
[features] [features]
default = ["schemars"] default = ["schemars"]
deadlock_detection = ["parking_lot/deadlock_detection"] deadlock_detection = ["parking_lot/deadlock_detection"]
schemars = ["dep:schemars"] schemars = ["dep:schemars", "komorebi-layouts/schemars"]

View File

@@ -15,37 +15,42 @@ use strum::EnumString;
use crate::KomorebiTheme; use crate::KomorebiTheme;
use crate::animation::prefix::AnimationPrefix; use crate::animation::prefix::AnimationPrefix;
// Re-export everything from komorebi-layouts
pub use komorebi_layouts::Arrangement;
pub use komorebi_layouts::Axis;
pub use komorebi_layouts::Column;
pub use komorebi_layouts::ColumnSplit;
pub use komorebi_layouts::ColumnSplitWithCapacity;
pub use komorebi_layouts::ColumnWidth;
pub use komorebi_layouts::CustomLayout;
pub use komorebi_layouts::CycleDirection;
pub use komorebi_layouts::DEFAULT_RATIO;
pub use komorebi_layouts::DEFAULT_SECONDARY_RATIO;
pub use komorebi_layouts::DefaultLayout;
pub use komorebi_layouts::Direction;
pub use komorebi_layouts::GridLayoutOptions;
pub use komorebi_layouts::Layout;
pub use komorebi_layouts::LayoutOptions;
pub use komorebi_layouts::MAX_RATIO;
pub use komorebi_layouts::MAX_RATIOS;
pub use komorebi_layouts::MIN_RATIO;
pub use komorebi_layouts::OperationDirection;
pub use komorebi_layouts::Rect;
pub use komorebi_layouts::ScrollingLayoutOptions;
pub use komorebi_layouts::Sizing;
// Local modules and exports
pub use animation::AnimationStyle; pub use animation::AnimationStyle;
pub use arrangement::Arrangement;
pub use arrangement::Axis;
pub use custom_layout::Column;
pub use custom_layout::ColumnSplit;
pub use custom_layout::ColumnSplitWithCapacity;
pub use custom_layout::ColumnWidth;
pub use custom_layout::CustomLayout;
pub use cycle_direction::CycleDirection;
pub use default_layout::*;
pub use direction::Direction;
pub use layout::Layout;
pub use operation_direction::OperationDirection;
pub use pathext::PathExt; pub use pathext::PathExt;
pub use pathext::ResolvedPathBuf; pub use pathext::ResolvedPathBuf;
pub use pathext::replace_env_in_path; pub use pathext::replace_env_in_path;
pub use pathext::resolve_option_hashmap_usize_path; pub use pathext::resolve_option_hashmap_usize_path;
pub use rect::Rect;
pub mod animation; pub mod animation;
pub mod arrangement;
pub mod asc; pub mod asc;
pub mod config_generation; pub mod config_generation;
pub mod custom_layout;
pub mod cycle_direction;
pub mod default_layout;
pub mod direction;
pub mod layout;
pub mod operation_direction;
pub mod pathext; pub mod pathext;
pub mod rect;
// serde_as must be before derive // serde_as must be before derive
#[serde_with::serde_as] #[serde_with::serde_as]
@@ -545,32 +550,6 @@ pub enum OperationBehaviour {
NoOp, NoOp,
} }
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ValueEnum)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
/// Sizing
pub enum Sizing {
/// Increase
Increase,
/// Decrease
Decrease,
}
impl Sizing {
#[must_use]
pub const fn adjust_by(&self, value: i32, adjustment: i32) -> i32 {
match self {
Self::Increase => value + adjustment,
Self::Decrease => {
if value > 0 && value - adjustment >= 0 {
value - adjustment
} else {
value
}
}
}
}
}
#[derive( #[derive(
Clone, Copy, Debug, Default, Serialize, Deserialize, Display, EnumString, ValueEnum, PartialEq, Clone, Copy, Debug, Default, Serialize, Deserialize, Display, EnumString, ValueEnum, PartialEq,
)] )]

View File

@@ -60,9 +60,11 @@ use crate::core::Axis;
use crate::core::BorderImplementation; use crate::core::BorderImplementation;
use crate::core::FocusFollowsMouseImplementation; use crate::core::FocusFollowsMouseImplementation;
use crate::core::Layout; use crate::core::Layout;
use crate::core::LayoutOptions;
use crate::core::MoveBehaviour; use crate::core::MoveBehaviour;
use crate::core::OperationDirection; use crate::core::OperationDirection;
use crate::core::Rect; use crate::core::Rect;
use crate::core::ScrollingLayoutOptions;
use crate::core::Sizing; use crate::core::Sizing;
use crate::core::SocketMessage; use crate::core::SocketMessage;
use crate::core::StateQuery; use crate::core::StateQuery;
@@ -72,8 +74,6 @@ use crate::core::config_generation::IdWithIdentifier;
use crate::core::config_generation::MatchingRule; use crate::core::config_generation::MatchingRule;
use crate::core::config_generation::MatchingStrategy; use crate::core::config_generation::MatchingStrategy;
use crate::current_virtual_desktop; use crate::current_virtual_desktop;
use crate::default_layout::LayoutOptions;
use crate::default_layout::ScrollingLayoutOptions;
use crate::monitor::MonitorInformation; use crate::monitor::MonitorInformation;
use crate::notify_subscribers; use crate::notify_subscribers;
use crate::stackbar_manager; use crate::stackbar_manager;

View File

@@ -53,6 +53,7 @@ use crate::core::DefaultLayout;
use crate::core::FocusFollowsMouseImplementation; use crate::core::FocusFollowsMouseImplementation;
use crate::core::HidingBehaviour; use crate::core::HidingBehaviour;
use crate::core::Layout; use crate::core::Layout;
use crate::core::LayoutOptions;
use crate::core::MoveBehaviour; use crate::core::MoveBehaviour;
use crate::core::OperationBehaviour; use crate::core::OperationBehaviour;
use crate::core::Rect; use crate::core::Rect;
@@ -67,7 +68,6 @@ use crate::core::config_generation::ApplicationOptions;
use crate::core::config_generation::MatchingRule; use crate::core::config_generation::MatchingRule;
use crate::core::config_generation::MatchingStrategy; use crate::core::config_generation::MatchingStrategy;
use crate::current_virtual_desktop; use crate::current_virtual_desktop;
use crate::default_layout::LayoutOptions;
use crate::monitor; use crate::monitor;
use crate::monitor::Monitor; use crate::monitor::Monitor;
use crate::monitor_reconciliator; use crate::monitor_reconciliator;

View File

@@ -28,6 +28,7 @@ use crate::animation::AnimationEngine;
use crate::core::Arrangement; use crate::core::Arrangement;
use crate::core::Axis; use crate::core::Axis;
use crate::core::BorderImplementation; use crate::core::BorderImplementation;
use crate::core::CustomLayout;
use crate::core::CycleDirection; use crate::core::CycleDirection;
use crate::core::DefaultLayout; use crate::core::DefaultLayout;
use crate::core::FocusFollowsMouseImplementation; use crate::core::FocusFollowsMouseImplementation;
@@ -40,7 +41,6 @@ use crate::core::Sizing;
use crate::core::WindowContainerBehaviour; use crate::core::WindowContainerBehaviour;
use crate::core::WindowManagementBehaviour; use crate::core::WindowManagementBehaviour;
use crate::core::config_generation::MatchingRule; use crate::core::config_generation::MatchingRule;
use crate::core::custom_layout::CustomLayout;
use crate::CrossBoundaryBehaviour; use crate::CrossBoundaryBehaviour;
use crate::DATA_DIR; use crate::DATA_DIR;

View File

@@ -25,9 +25,9 @@ use crate::core::CustomLayout;
use crate::core::CycleDirection; use crate::core::CycleDirection;
use crate::core::DefaultLayout; use crate::core::DefaultLayout;
use crate::core::Layout; use crate::core::Layout;
use crate::core::LayoutOptions;
use crate::core::OperationDirection; use crate::core::OperationDirection;
use crate::core::Rect; use crate::core::Rect;
use crate::default_layout::LayoutOptions;
use crate::lockable_sequence::LockableSequence; use crate::lockable_sequence::LockableSequence;
use crate::ring::Ring; use crate::ring::Ring;
use crate::should_act; use crate::should_act;