refactor(bar-core): move the komorebi widget config types and KomorebiLayout into the core

The seven Komorebi*Config structs (komorebi.rs) and the KomorebiLayout enum
with its hand-written Deserialize and Display (komorebi_layout.rs) are data:
they move to crates/komorebi-bar-core/src/widgets/komorebi_config.rs, which
needs komorebi-layouts (DefaultLayout; schemars forwarded) and color-eyre
in the core: two lines in each Cargo.lock. The two shells re-export them.
The inherent impl of KomorebiLayout (is_default, on_click, show_icon, show,
the egui painting) cannot stay an inherent impl of a foreign type: it
becomes the extension trait `KomorebiLayoutExt` in each shell with the same
bodies; komorebi.rs imports the trait. Because the types are no longer in
the shell file, the two komorebi_layout.rs differ no more than the Windows
one; the macOS widget files keep their own komorebi.rs runtime.

Verified: schema harness macOS and Windows byte-identical (3,774 / 9,091
lines); native bar-core tests 3+5; Windows clippy -D warnings --locked
clean; macOS fake-CC check --locked 0 errors (core files touched first). I
reverted a stray `cargo fmt --all` that had reformatted unrelated files.
Not run: the bars.
This commit is contained in:
LGUG2Z committed 2026-10-31 10:47:01 -07:00
1 parent cb8fc00afb
commit c2e6b01f89
9 files changed
+228 -313

No files matched your search

Generated
+2
View File
@@ -3445,10 +3445,12 @@ version = "0.1.42"
dependencies = [
"chrono",
"chrono-tz",
"color-eyre",
"eframe",
"egui-phosphor",
"image 0.25.10",
"komorebi-config",
"komorebi-layouts",
"komorebi-protocol",
"lazy_static",
"reqwest",
+3 -1
View File
@@ -13,8 +13,10 @@ lazy_static = { workspace = true }
image = "0.25"
komorebi-config = { path = "../komorebi-config", default-features = false }
reqwest = { version = "0.12", features = ["blocking"] }
komorebi-layouts = { path = "../../komorebi-layouts" }
komorebi-protocol = { path = "../komorebi-protocol", default-features = false }
serde = { workspace = true }
color-eyre = { workspace = true }
serde_json = { workspace = true, features = ["preserve_order"] }
starship-battery = "0.11"
sysinfo = { workspace = true }
@@ -25,4 +27,4 @@ schemars = { workspace = true, optional = true }
[features]
default = ["schemars"]
schemars = ["dep:schemars", "komorebi-config/schemars", "komorebi-protocol/schemars"]
schemars = ["dep:schemars", "komorebi-config/schemars", "komorebi-layouts/schemars", "komorebi-protocol/schemars"]
@@ -0,0 +1,158 @@
//! The configuration of the komorebi widgets (workspaces, layout, focused container, ...) and
//! the layout kind the layout widget shows: data only, shared by both bars.
use crate::config::DisplayFormat;
use crate::config::WorkspacesDisplayFormat;
use color_eyre::eyre;
use serde::Deserialize;
use serde::Deserializer;
use serde::Serialize;
use serde::de::Error;
use serde_json::from_str;
use std::collections::BTreeMap;
use std::fmt::Display;
use std::fmt::Formatter;
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
/// Komorebi widget configuration
pub struct KomorebiConfig {
/// Configure the Workspaces widget
pub workspaces: Option<KomorebiWorkspacesConfig>,
/// Configure the Layout widget
pub layout: Option<KomorebiLayoutConfig>,
/// Configure the Workspace Layer widget
pub workspace_layer: Option<KomorebiWorkspaceLayerConfig>,
/// Configure the Focused Container widget
#[serde(alias = "focused_window")]
pub focused_container: Option<KomorebiFocusedContainerConfig>,
/// Configure the Locked Container widget
pub locked_container: Option<KomorebiLockedContainerConfig>,
/// Configure the Configuration Switcher widget
pub configuration_switcher: Option<KomorebiConfigurationSwitcherConfig>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
/// Komorebi widget workspaces configuration
pub struct KomorebiWorkspacesConfig {
/// Enable the Komorebi Workspaces widget
pub enable: bool,
/// Hide workspaces without any windows
pub hide_empty_workspaces: bool,
/// Display format of the workspace
pub display: Option<WorkspacesDisplayFormat>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
/// Komorebi widget layout configuration
pub struct KomorebiLayoutConfig {
/// Enable the Komorebi Layout widget
pub enable: bool,
/// List of layout options
pub options: Option<Vec<KomorebiLayout>>,
/// Display format of the current layout
pub display: Option<DisplayFormat>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
/// Komorebi widget workspace layer configuration
pub struct KomorebiWorkspaceLayerConfig {
/// Enable the Komorebi Workspace Layer widget
pub enable: bool,
/// Display format of the current layer
pub display: Option<DisplayFormat>,
/// Show the widget event if the layer is Tiling
pub show_when_tiling: Option<bool>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
/// Komorebi widget focused container configuration
pub struct KomorebiFocusedContainerConfig {
/// Enable the Komorebi Focused Container widget
pub enable: bool,
/// DEPRECATED: use `display` instead (Show the icon of the currently focused container)
#[deprecated(note = "Use `display` instead")]
pub show_icon: Option<bool>,
/// Display format of the currently focused container
pub display: Option<DisplayFormat>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
/// Komorebi widget locked container configuration
pub struct KomorebiLockedContainerConfig {
/// Enable the Komorebi Locked Container widget
pub enable: bool,
/// Display format of the current locked state
pub display: Option<DisplayFormat>,
/// Show the widget event if the layer is unlocked
pub show_when_unlocked: Option<bool>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
/// Komorebi widget configuration switcher configuration
pub struct KomorebiConfigurationSwitcherConfig {
/// Enable the Komorebi Configurations widget
pub enable: bool,
/// A map of display friendly name => path to configuration.json
pub configurations: BTreeMap<String, String>,
}
#[derive(Copy, Clone, Debug, Serialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[serde(untagged)]
/// Komorebi layout kind
pub enum KomorebiLayout {
/// Predefined layout
#[cfg_attr(feature = "schemars", schemars(title = "Default"))]
Default(komorebi_layouts::DefaultLayout),
/// Monocle mode
Monocle,
/// Floating layer
Floating,
/// Paused
Paused,
/// Custom layout
Custom,
}
impl<'de> Deserialize<'de> for KomorebiLayout {
fn deserialize<D>(deserializer: D) -> eyre::Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s: String = String::deserialize(deserializer)?;
// Attempt to deserialize the string as a DefaultLayout
if let Ok(default_layout) = from_str::<komorebi_layouts::DefaultLayout>(&format!("\"{s}\""))
{
return Ok(KomorebiLayout::Default(default_layout));
}
// Handle other cases
match s.as_str() {
"Monocle" => Ok(KomorebiLayout::Monocle),
"Floating" => Ok(KomorebiLayout::Floating),
"Paused" => Ok(KomorebiLayout::Paused),
"Custom" => Ok(KomorebiLayout::Custom),
_ => Err(Error::custom(format!("Invalid layout: {s}"))),
}
}
}
impl Display for KomorebiLayout {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
KomorebiLayout::Default(layout) => write!(f, "{layout}"),
KomorebiLayout::Monocle => write!(f, "Monocle"),
KomorebiLayout::Floating => write!(f, "Floating"),
KomorebiLayout::Paused => write!(f, "Paused"),
KomorebiLayout::Custom => write!(f, "Custom"),
}
}
}
@@ -3,6 +3,7 @@ pub mod battery;
pub mod cpu;
pub mod date;
pub mod icons;
pub mod komorebi_config;
pub mod memory;
pub mod platform_config;
pub mod storage;
+9 -94
View File
@@ -7,7 +7,7 @@ use crate::config::WorkspacesDisplayFormat;
use crate::render::RenderConfig;
use crate::selected_frame::SelectableFrame;
use crate::ui::CustomUi;
use crate::widgets::komorebi_layout::KomorebiLayout;
use crate::widgets::komorebi_layout::KomorebiLayoutExt;
use crate::widgets::widget::BarWidget;
use eframe::egui::Align;
use eframe::egui::Color32;
@@ -28,6 +28,14 @@ use eframe::egui::Ui;
use eframe::egui::Vec2;
use eframe::egui::text::LayoutJob;
use eframe::egui::vec2;
pub use komorebi_bar_core::widgets::komorebi_config::KomorebiConfig;
pub use komorebi_bar_core::widgets::komorebi_config::KomorebiConfigurationSwitcherConfig;
pub use komorebi_bar_core::widgets::komorebi_config::KomorebiFocusedContainerConfig;
pub use komorebi_bar_core::widgets::komorebi_config::KomorebiLayout;
pub use komorebi_bar_core::widgets::komorebi_config::KomorebiLayoutConfig;
pub use komorebi_bar_core::widgets::komorebi_config::KomorebiLockedContainerConfig;
pub use komorebi_bar_core::widgets::komorebi_config::KomorebiWorkspaceLayerConfig;
pub use komorebi_bar_core::widgets::komorebi_config::KomorebiWorkspacesConfig;
use komorebi_client::Container;
use komorebi_client::PathExt;
use komorebi_client::Rect;
@@ -37,106 +45,13 @@ use komorebi_client::State;
use komorebi_client::Window;
use komorebi_client::Workspace;
use komorebi_client::WorkspaceLayer;
use serde::Deserialize;
use serde::Serialize;
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::io::Result as IoResult;
use std::path::Path;
use std::rc::Rc;
use std::sync::atomic::Ordering;
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
/// Komorebi widget configuration
pub struct KomorebiConfig {
/// Configure the Workspaces widget
pub workspaces: Option<KomorebiWorkspacesConfig>,
/// Configure the Layout widget
pub layout: Option<KomorebiLayoutConfig>,
/// Configure the Workspace Layer widget
pub workspace_layer: Option<KomorebiWorkspaceLayerConfig>,
/// Configure the Focused Container widget
#[serde(alias = "focused_window")]
pub focused_container: Option<KomorebiFocusedContainerConfig>,
/// Configure the Locked Container widget
pub locked_container: Option<KomorebiLockedContainerConfig>,
/// Configure the Configuration Switcher widget
pub configuration_switcher: Option<KomorebiConfigurationSwitcherConfig>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
/// Komorebi widget workspaces configuration
pub struct KomorebiWorkspacesConfig {
/// Enable the Komorebi Workspaces widget
pub enable: bool,
/// Hide workspaces without any windows
pub hide_empty_workspaces: bool,
/// Display format of the workspace
pub display: Option<WorkspacesDisplayFormat>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
/// Komorebi widget layout configuration
pub struct KomorebiLayoutConfig {
/// Enable the Komorebi Layout widget
pub enable: bool,
/// List of layout options
pub options: Option<Vec<KomorebiLayout>>,
/// Display format of the current layout
pub display: Option<DisplayFormat>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
/// Komorebi widget workspace layer configuration
pub struct KomorebiWorkspaceLayerConfig {
/// Enable the Komorebi Workspace Layer widget
pub enable: bool,
/// Display format of the current layer
pub display: Option<DisplayFormat>,
/// Show the widget event if the layer is Tiling
pub show_when_tiling: Option<bool>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
/// Komorebi widget focused container configuration
pub struct KomorebiFocusedContainerConfig {
/// Enable the Komorebi Focused Container widget
pub enable: bool,
/// DEPRECATED: use `display` instead (Show the icon of the currently focused container)
#[deprecated(note = "Use `display` instead")]
pub show_icon: Option<bool>,
/// Display format of the currently focused container
pub display: Option<DisplayFormat>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
/// Komorebi widget locked container configuration
pub struct KomorebiLockedContainerConfig {
/// Enable the Komorebi Locked Container widget
pub enable: bool,
/// Display format of the current locked state
pub display: Option<DisplayFormat>,
/// Show the widget event if the layer is unlocked
pub show_when_unlocked: Option<bool>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
/// Komorebi widget configuration switcher configuration
pub struct KomorebiConfigurationSwitcherConfig {
/// Enable the Komorebi Configurations widget
pub enable: bool,
/// A map of display friendly name => path to configuration.json
pub configurations: BTreeMap<String, String>,
}
impl From<&KomorebiConfig> for Komorebi {
fn from(cfg: &KomorebiConfig) -> Self {
let configuration_switcher = cfg.configuration_switcher.clone().map(|mut cs| {
+22 -62
View File
@@ -2,7 +2,6 @@ use crate::config::DisplayFormat;
use crate::render::RenderConfig;
use crate::selected_frame::SelectableFrame;
use crate::widgets::komorebi::KomorebiLayoutConfig;
use color_eyre::eyre;
use eframe::egui::Context;
use eframe::egui::CornerRadius;
use eframe::egui::FontId;
@@ -14,70 +13,31 @@ use eframe::egui::StrokeKind;
use eframe::egui::Ui;
use eframe::egui::Vec2;
use eframe::egui::vec2;
pub use komorebi_bar_core::widgets::komorebi_config::KomorebiLayout;
use komorebi_client::SocketMessage;
use serde::Deserialize;
use serde::Deserializer;
use serde::Serialize;
use serde::de::Error;
use serde_json::from_str;
use std::fmt::Display;
use std::fmt::Formatter;
#[derive(Copy, Clone, Debug, Serialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[serde(untagged)]
/// Komorebi layout kind
pub enum KomorebiLayout {
/// Predefined layout
#[cfg_attr(feature = "schemars", schemars(title = "Default"))]
Default(komorebi_client::DefaultLayout),
/// Monocle mode
Monocle,
/// Floating layer
Floating,
/// Paused
Paused,
/// Custom layout
Custom,
/// What the layout widget does with a layout kind (the kind itself lives in the core).
pub trait KomorebiLayoutExt {
fn is_default(&mut self) -> bool;
fn on_click(
&mut self,
show_options: &bool,
monitor_idx: usize,
workspace_idx: Option<usize>,
) -> bool;
fn on_click_option(&mut self, monitor_idx: usize, workspace_idx: Option<usize>);
fn show_icon(&mut self, is_selected: bool, font_id: FontId, ctx: &Context, ui: &mut Ui);
fn show(
&mut self,
ctx: &Context,
ui: &mut Ui,
render_config: &mut RenderConfig,
layout_config: &KomorebiLayoutConfig,
workspace_idx: Option<usize>,
);
}
impl<'de> Deserialize<'de> for KomorebiLayout {
fn deserialize<D>(deserializer: D) -> eyre::Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s: String = String::deserialize(deserializer)?;
// Attempt to deserialize the string as a DefaultLayout
if let Ok(default_layout) = from_str::<komorebi_client::DefaultLayout>(&format!("\"{s}\""))
{
return Ok(KomorebiLayout::Default(default_layout));
}
// Handle other cases
match s.as_str() {
"Monocle" => Ok(KomorebiLayout::Monocle),
"Floating" => Ok(KomorebiLayout::Floating),
"Paused" => Ok(KomorebiLayout::Paused),
"Custom" => Ok(KomorebiLayout::Custom),
_ => Err(Error::custom(format!("Invalid layout: {s}"))),
}
}
}
impl Display for KomorebiLayout {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
KomorebiLayout::Default(layout) => write!(f, "{layout}"),
KomorebiLayout::Monocle => write!(f, "Monocle"),
KomorebiLayout::Floating => write!(f, "Floating"),
KomorebiLayout::Paused => write!(f, "Paused"),
KomorebiLayout::Custom => write!(f, "Custom"),
}
}
}
impl KomorebiLayout {
impl KomorebiLayoutExt for KomorebiLayout {
fn is_default(&mut self) -> bool {
matches!(self, KomorebiLayout::Default(_))
}
@@ -242,7 +202,7 @@ impl KomorebiLayout {
}
}
pub fn show(
fn show(
&mut self,
ctx: &Context,
ui: &mut Ui,
+2
View File
@@ -3253,10 +3253,12 @@ version = "0.1.42"
dependencies = [
"chrono",
"chrono-tz",
"color-eyre",
"eframe",
"egui-phosphor",
"image 0.25.10",
"komorebi-config",
"komorebi-layouts",
"komorebi-protocol",
"lazy_static",
"reqwest",
@@ -7,7 +7,15 @@ use crate::config::WorkspacesDisplayFormat;
use crate::render::RenderConfig;
use crate::selected_frame::SelectableFrame;
use crate::ui::CustomUi;
use crate::widgets::komorebi_layout::KomorebiLayout;
pub use komorebi_bar_core::widgets::komorebi_config::KomorebiConfig;
pub use komorebi_bar_core::widgets::komorebi_config::KomorebiConfigurationSwitcherConfig;
pub use komorebi_bar_core::widgets::komorebi_config::KomorebiFocusedContainerConfig;
pub use komorebi_bar_core::widgets::komorebi_config::KomorebiLayoutConfig;
pub use komorebi_bar_core::widgets::komorebi_config::KomorebiLockedContainerConfig;
pub use komorebi_bar_core::widgets::komorebi_config::KomorebiWorkspaceLayerConfig;
pub use komorebi_bar_core::widgets::komorebi_config::KomorebiWorkspacesConfig;
pub use komorebi_bar_core::widgets::komorebi_config::KomorebiLayout;
use crate::widgets::komorebi_layout::KomorebiLayoutExt;
use crate::widgets::widget::BarWidget;
use eframe::egui::Align;
use eframe::egui::Color32;
@@ -40,10 +48,7 @@ use komorebi_client::State;
use komorebi_client::Window;
use komorebi_client::Workspace;
use komorebi_client::WorkspaceLayer;
use serde::Deserialize;
use serde::Serialize;
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::fs::File;
use std::io::BufReader;
@@ -52,96 +57,6 @@ use std::path::Path;
use std::rc::Rc;
use std::sync::atomic::Ordering;
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
/// Komorebi widget configuration
pub struct KomorebiConfig {
/// Configure the Workspaces widget
pub workspaces: Option<KomorebiWorkspacesConfig>,
/// Configure the Layout widget
pub layout: Option<KomorebiLayoutConfig>,
/// Configure the Workspace Layer widget
pub workspace_layer: Option<KomorebiWorkspaceLayerConfig>,
/// Configure the Focused Container widget
#[serde(alias = "focused_window")]
pub focused_container: Option<KomorebiFocusedContainerConfig>,
/// Configure the Locked Container widget
pub locked_container: Option<KomorebiLockedContainerConfig>,
/// Configure the Configuration Switcher widget
pub configuration_switcher: Option<KomorebiConfigurationSwitcherConfig>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
/// Komorebi widget workspaces configuration
pub struct KomorebiWorkspacesConfig {
/// Enable the Komorebi Workspaces widget
pub enable: bool,
/// Hide workspaces without any windows
pub hide_empty_workspaces: bool,
/// Display format of the workspace
pub display: Option<WorkspacesDisplayFormat>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
/// Komorebi widget layout configuration
pub struct KomorebiLayoutConfig {
/// Enable the Komorebi Layout widget
pub enable: bool,
/// List of layout options
pub options: Option<Vec<KomorebiLayout>>,
/// Display format of the current layout
pub display: Option<DisplayFormat>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
/// Komorebi widget workspace layer configuration
pub struct KomorebiWorkspaceLayerConfig {
/// Enable the Komorebi Workspace Layer widget
pub enable: bool,
/// Display format of the current layer
pub display: Option<DisplayFormat>,
/// Show the widget event if the layer is Tiling
pub show_when_tiling: Option<bool>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
/// Komorebi widget focused container configuration
pub struct KomorebiFocusedContainerConfig {
/// Enable the Komorebi Focused Container widget
pub enable: bool,
/// DEPRECATED: use `display` instead (Show the icon of the currently focused container)
#[deprecated(note = "Use `display` instead")]
pub show_icon: Option<bool>,
/// Display format of the currently focused container
pub display: Option<DisplayFormat>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
/// Komorebi widget locked container configuration
pub struct KomorebiLockedContainerConfig {
/// Enable the Komorebi Locked Container widget
pub enable: bool,
/// Display format of the current locked state
pub display: Option<DisplayFormat>,
/// Show the widget event if the layer is unlocked
pub show_when_unlocked: Option<bool>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
/// Komorebi widget configuration switcher configuration
pub struct KomorebiConfigurationSwitcherConfig {
/// Enable the Komorebi Configurations widget
pub enable: bool,
/// A map of display friendly name => path to configuration.json
pub configurations: BTreeMap<String, String>,
}
impl From<&KomorebiConfig> for Komorebi {
fn from(cfg: &KomorebiConfig) -> Self {
let configuration_switcher = cfg.configuration_switcher.clone().map(|mut cs| {
@@ -2,7 +2,7 @@ use crate::config::DisplayFormat;
use crate::render::RenderConfig;
use crate::selected_frame::SelectableFrame;
use crate::widgets::komorebi::KomorebiLayoutConfig;
use color_eyre::eyre;
pub use komorebi_bar_core::widgets::komorebi_config::KomorebiLayout;
use eframe::egui::Context;
use eframe::egui::CornerRadius;
use eframe::egui::FontId;
@@ -15,69 +15,29 @@ use eframe::egui::Ui;
use eframe::egui::Vec2;
use eframe::egui::vec2;
use komorebi_client::SocketMessage;
use serde::Deserialize;
use serde::Deserializer;
use serde::Serialize;
use serde::de::Error;
use serde_json::from_str;
use std::fmt::Display;
use std::fmt::Formatter;
#[derive(Copy, Clone, Debug, Serialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[serde(untagged)]
/// Komorebi layout kind
pub enum KomorebiLayout {
/// Predefined layout
#[cfg_attr(feature = "schemars", schemars(title = "Default"))]
Default(komorebi_client::DefaultLayout),
/// Monocle mode
Monocle,
/// Floating layer
Floating,
/// Paused
Paused,
/// Custom layout
Custom,
/// What the layout widget does with a layout kind (the kind itself lives in the core).
pub trait KomorebiLayoutExt {
fn is_default(&mut self) -> bool;
fn on_click(
&mut self,
show_options: &bool,
monitor_idx: usize,
workspace_idx: Option<usize>,
) -> bool;
fn on_click_option(&mut self, monitor_idx: usize, workspace_idx: Option<usize>);
fn show_icon(&mut self, is_selected: bool, font_id: FontId, ctx: &Context, ui: &mut Ui);
fn show(
&mut self,
ctx: &Context,
ui: &mut Ui,
render_config: &mut RenderConfig,
layout_config: &KomorebiLayoutConfig,
workspace_idx: Option<usize>,
);
}
impl<'de> Deserialize<'de> for KomorebiLayout {
fn deserialize<D>(deserializer: D) -> eyre::Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s: String = String::deserialize(deserializer)?;
// Attempt to deserialize the string as a DefaultLayout
if let Ok(default_layout) = from_str::<komorebi_client::DefaultLayout>(&format!("\"{s}\""))
{
return Ok(KomorebiLayout::Default(default_layout));
}
// Handle other cases
match s.as_str() {
"Monocle" => Ok(KomorebiLayout::Monocle),
"Floating" => Ok(KomorebiLayout::Floating),
"Paused" => Ok(KomorebiLayout::Paused),
"Custom" => Ok(KomorebiLayout::Custom),
_ => Err(Error::custom(format!("Invalid layout: {s}"))),
}
}
}
impl Display for KomorebiLayout {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
KomorebiLayout::Default(layout) => write!(f, "{layout}"),
KomorebiLayout::Monocle => write!(f, "Monocle"),
KomorebiLayout::Floating => write!(f, "Floating"),
KomorebiLayout::Paused => write!(f, "Paused"),
KomorebiLayout::Custom => write!(f, "Custom"),
}
}
}
impl KomorebiLayout {
impl KomorebiLayoutExt for KomorebiLayout {
fn is_default(&mut self) -> bool {
matches!(self, KomorebiLayout::Default(_))
}
@@ -242,7 +202,7 @@ impl KomorebiLayout {
}
}
pub fn show(
fn show(
&mut self,
ctx: &Context,
ui: &mut Ui,