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",
"ed25519-dalek",
"hotwatch",
"komorebi-layouts",
"komorebi-themes",
"lazy_static",
"miow",
@@ -3231,6 +3232,21 @@ dependencies = [
"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]]
name = "komorebi-shortcuts"
version = "0.1.0"

View File

@@ -5,6 +5,7 @@ members = [
"komorebi",
"komorebi-client",
"komorebi-gui",
"komorebi-layouts",
"komorebic",
"komorebic-no-console",
"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::Serialize;
#[cfg(feature = "win32")]
use windows::Win32::Foundation::RECT;
#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize, Eq, PartialEq)]
@@ -16,6 +18,7 @@ pub struct Rect {
pub bottom: i32,
}
#[cfg(feature = "win32")]
impl From<RECT> for Rect {
fn from(rect: RECT) -> Self {
Self {
@@ -27,6 +30,7 @@ impl From<RECT> for Rect {
}
}
#[cfg(feature = "win32")]
impl From<Rect> for RECT {
fn from(rect: Rect) -> Self {
Self {
@@ -96,6 +100,7 @@ impl Rect {
}
}
#[cfg(feature = "win32")]
#[must_use]
pub const fn rect(&self) -> 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
[dependencies]
komorebi-layouts = { path = "../komorebi-layouts", features = ["win32"] }
komorebi-themes = { path = "../komorebi-themes" }
base64 = "0.22"
@@ -63,4 +64,4 @@ uuid = { version = "1", features = ["v4"] }
[features]
default = ["schemars"]
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::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 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::ResolvedPathBuf;
pub use pathext::replace_env_in_path;
pub use pathext::resolve_option_hashmap_usize_path;
pub use rect::Rect;
pub mod animation;
pub mod arrangement;
pub mod asc;
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 rect;
// serde_as must be before derive
#[serde_with::serde_as]
@@ -545,32 +550,6 @@ pub enum OperationBehaviour {
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(
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::FocusFollowsMouseImplementation;
use crate::core::Layout;
use crate::core::LayoutOptions;
use crate::core::MoveBehaviour;
use crate::core::OperationDirection;
use crate::core::Rect;
use crate::core::ScrollingLayoutOptions;
use crate::core::Sizing;
use crate::core::SocketMessage;
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::MatchingStrategy;
use crate::current_virtual_desktop;
use crate::default_layout::LayoutOptions;
use crate::default_layout::ScrollingLayoutOptions;
use crate::monitor::MonitorInformation;
use crate::notify_subscribers;
use crate::stackbar_manager;

View File

@@ -53,6 +53,7 @@ use crate::core::DefaultLayout;
use crate::core::FocusFollowsMouseImplementation;
use crate::core::HidingBehaviour;
use crate::core::Layout;
use crate::core::LayoutOptions;
use crate::core::MoveBehaviour;
use crate::core::OperationBehaviour;
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::MatchingStrategy;
use crate::current_virtual_desktop;
use crate::default_layout::LayoutOptions;
use crate::monitor;
use crate::monitor::Monitor;
use crate::monitor_reconciliator;

View File

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

View File

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