Skip to content

Commit

Permalink
feat(config): allow colours in both rgb and hex
Browse files Browse the repository at this point in the history
This commit introduces the ability for users to specify colours in the
static config file in either RGB or Hex format.

This is done by introducing a new enum, Colour, which provides variants
wrapping the internal Rgb type, and the HexColour type from the
hex_colour crate. HexColour itself is wrapped in a new struct, Hex, in
order to allow the implementation of the JsonSchema trait.

A number of From<T> implementations have been done in order to make
working with the Colour enum more ergonomic.

Ultimately, the core representation for colours in komorebi remains the
Rgb struct, any and Hex-specified colours will be converted to this Rgb
type before being converted to u32 to pass them on to various Win32 API
calls.
  • Loading branch information
LGUG2Z committed Feb 25, 2024
1 parent 608ec03 commit e7d928a
Show file tree
Hide file tree
Showing 7 changed files with 245 additions and 124 deletions.
18 changes: 18 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 7 additions & 6 deletions komorebi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ komorebi-core = { path = "../komorebi-core" }

bitflags = "2"
clap = { version = "4", features = ["derive"] }
color-eyre = { workspace = true }
crossbeam-channel = "0.5"
crossbeam-utils = "0.8"
ctrlc = "3"
dirs = { workspace = true }
getset = "0.1"
hex_color = { version = "3", features = ["serde"] }
hotwatch = "0.4"
lazy_static = "1"
miow = "0.5"
Expand All @@ -38,14 +41,12 @@ tracing-appender = "0.2"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
uds_windows = "1"
which = "5"
widestring = "1"
windows = { workspace = true }
windows-implement = { workspace = true }
windows-interface = { workspace = true }
winput = "0.2"
winreg = "0.52"
windows-interface = { workspace = true }
windows-implement = { workspace = true }
windows = { workspace = true }
color-eyre = { workspace = true }
dirs = { workspace = true }
widestring = "1"

[features]
deadlock_detection = []
103 changes: 103 additions & 0 deletions komorebi/src/colour.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
use hex_color::HexColor;
use schemars::gen::SchemaGenerator;
use schemars::schema::InstanceType;
use schemars::schema::Schema;
use schemars::schema::SchemaObject;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;

#[derive(Debug, Copy, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(untagged)]
pub enum Colour {
/// Colour represented as RGB
Rgb(Rgb),
/// Colour represented as Hex
Hex(Hex),
}

impl From<Rgb> for Colour {
fn from(value: Rgb) -> Self {
Self::Rgb(value)
}
}

impl From<u32> for Colour {
fn from(value: u32) -> Self {
Self::Rgb(Rgb::from(value))
}
}

#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
pub struct Hex(HexColor);

impl JsonSchema for Hex {
fn schema_name() -> String {
String::from("Hex")
}

fn json_schema(_: &mut SchemaGenerator) -> Schema {
SchemaObject {
instance_type: Some(InstanceType::String.into()),
..Default::default()
}
.into()
}
}

impl From<Colour> for u32 {
fn from(value: Colour) -> Self {
match value {
Colour::Rgb(val) => val.into(),
Colour::Hex(val) => (Rgb::from(val)).into(),
}
}
}

#[derive(Debug, Copy, Clone, Serialize, Deserialize, JsonSchema)]
pub struct Rgb {
/// Red
pub r: u32,
/// Green
pub g: u32,
/// Blue
pub b: u32,
}

impl Rgb {
pub fn new(r: u32, g: u32, b: u32) -> Self {
Self { r, g, b }
}
}

impl From<Hex> for Rgb {
fn from(value: Hex) -> Self {
value.0.into()
}
}

impl From<HexColor> for Rgb {
fn from(value: HexColor) -> Self {
Self {
r: value.r as u32,
g: value.g as u32,
b: value.b as u32,
}
}
}

impl From<Rgb> for u32 {
fn from(value: Rgb) -> Self {
value.r | (value.g << 8) | (value.b << 16)
}
}

impl From<u32> for Rgb {
fn from(value: u32) -> Self {
Self {
r: value & 0xff,
g: value >> 8 & 0xff,
b: value >> 16 & 0xff,
}
}
}
1 change: 1 addition & 0 deletions komorebi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pub mod border;
pub mod com;
#[macro_use]
pub mod ring;
pub mod colour;
pub mod container;
pub mod hidden;
pub mod monitor;
Expand Down
9 changes: 5 additions & 4 deletions komorebi/src/process_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ use komorebi_core::WindowContainerBehaviour;
use komorebi_core::WindowKind;

use crate::border::Border;
use crate::colour::Rgb;
use crate::current_virtual_desktop;
use crate::notify_subscribers;
use crate::static_config::StaticConfig;
Expand Down Expand Up @@ -1234,14 +1235,14 @@ impl WindowManager {
SocketMessage::ActiveWindowBorderColour(kind, r, g, b) => {
match kind {
WindowKind::Single => {
BORDER_COLOUR_SINGLE.store(r | (g << 8) | (b << 16), Ordering::SeqCst);
BORDER_COLOUR_CURRENT.store(r | (g << 8) | (b << 16), Ordering::SeqCst);
BORDER_COLOUR_SINGLE.store(Rgb::new(r, g, b).into(), Ordering::SeqCst);
BORDER_COLOUR_CURRENT.store(Rgb::new(r, g, b).into(), Ordering::SeqCst);
}
WindowKind::Stack => {
BORDER_COLOUR_STACK.store(r | (g << 8) | (b << 16), Ordering::SeqCst);
BORDER_COLOUR_STACK.store(Rgb::new(r, g, b).into(), Ordering::SeqCst);
}
WindowKind::Monocle => {
BORDER_COLOUR_MONOCLE.store(r | (g << 8) | (b << 16), Ordering::SeqCst);
BORDER_COLOUR_MONOCLE.store(Rgb::new(r, g, b).into(), Ordering::SeqCst);
}
}

Expand Down
54 changes: 12 additions & 42 deletions komorebi/src/static_config.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::border::Border;
use crate::colour::Colour;
use crate::current_virtual_desktop;
use crate::monitor::Monitor;
use crate::ring::Ring;
Expand Down Expand Up @@ -28,6 +29,7 @@ use crate::OBJECT_NAME_CHANGE_ON_LAUNCH;
use crate::REGEX_IDENTIFIERS;
use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS;
use crate::WORKSPACE_RULES;

use color_eyre::Result;
use crossbeam_channel::Receiver;
use hotwatch::notify::DebouncedEvent;
Expand Down Expand Up @@ -62,34 +64,14 @@ use std::sync::Arc;
use uds_windows::UnixListener;
use uds_windows::UnixStream;

#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct Rgb {
/// Red
pub r: u32,
/// Green
pub g: u32,
/// Blue
pub b: u32,
}

impl From<u32> for Rgb {
fn from(value: u32) -> Self {
Self {
r: value & 0xff,
g: value >> 8 & 0xff,
b: value >> 16 & 0xff,
}
}
}

#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ActiveWindowBorderColours {
/// Border colour when the container contains a single window
pub single: Rgb,
pub single: Colour,
/// Border colour when the container contains multiple windows
pub stack: Rgb,
pub stack: Colour,
/// Border colour when the container is in monocle mode
pub monocle: Rgb,
pub monocle: Colour,
}

#[derive(Debug, Serialize, Deserialize, JsonSchema)]
Expand Down Expand Up @@ -377,13 +359,13 @@ impl From<&WindowManager> for StaticConfig {
None
} else {
Option::from(ActiveWindowBorderColours {
single: Rgb::from(BORDER_COLOUR_SINGLE.load(Ordering::SeqCst)),
stack: Rgb::from(if BORDER_COLOUR_STACK.load(Ordering::SeqCst) == 0 {
single: Colour::from(BORDER_COLOUR_SINGLE.load(Ordering::SeqCst)),
stack: Colour::from(if BORDER_COLOUR_STACK.load(Ordering::SeqCst) == 0 {
BORDER_COLOUR_SINGLE.load(Ordering::SeqCst)
} else {
BORDER_COLOUR_STACK.load(Ordering::SeqCst)
}),
monocle: Rgb::from(if BORDER_COLOUR_MONOCLE.load(Ordering::SeqCst) == 0 {
monocle: Colour::from(if BORDER_COLOUR_MONOCLE.load(Ordering::SeqCst) == 0 {
BORDER_COLOUR_SINGLE.load(Ordering::SeqCst)
} else {
BORDER_COLOUR_MONOCLE.load(Ordering::SeqCst)
Expand Down Expand Up @@ -487,22 +469,10 @@ impl StaticConfig {
);

if let Some(colours) = &self.active_window_border_colours {
BORDER_COLOUR_SINGLE.store(
colours.single.r | (colours.single.g << 8) | (colours.single.b << 16),
Ordering::SeqCst,
);
BORDER_COLOUR_CURRENT.store(
colours.single.r | (colours.single.g << 8) | (colours.single.b << 16),
Ordering::SeqCst,
);
BORDER_COLOUR_STACK.store(
colours.stack.r | (colours.stack.g << 8) | (colours.stack.b << 16),
Ordering::SeqCst,
);
BORDER_COLOUR_MONOCLE.store(
colours.monocle.r | (colours.monocle.g << 8) | (colours.monocle.b << 16),
Ordering::SeqCst,
);
BORDER_COLOUR_SINGLE.store(u32::from(colours.single), Ordering::SeqCst);
BORDER_COLOUR_CURRENT.store(u32::from(colours.single), Ordering::SeqCst);
BORDER_COLOUR_STACK.store(u32::from(colours.stack), Ordering::SeqCst);
BORDER_COLOUR_MONOCLE.store(u32::from(colours.monocle), Ordering::SeqCst);
}

let mut float_identifiers = FLOAT_IDENTIFIERS.lock();
Expand Down
Loading

0 comments on commit e7d928a

Please sign in to comment.