Compare commits

..

24 Commits

Author SHA1 Message Date
alex-ds13
89d67507c7 fix(reaper): avoid deadlocks at startup
Previously the reaper at startup would lock it's own `HWNDS_CACHE` and
then try to lock the WM to get its `known_hwnds`.

However if there was an event in the meantime, process_event would lock
the WM first and then it would try to lock the reaper's `HWNDS_CACHE` to
update it.  This would deadlock since that would be locked by the reaper
waiting for the WM lock to be released.

This commit now makes it so we pass the `known_hwnds` to the reaper as
an argument at startup and it also rearranges the order of loading the
listeners.

Now komorebi first loads all the manager-type listeners, and only
afterwards does it load the commands and events listeners.

After some testing this seems to be the best order that doesn't cause
any issues at all!

There were some other issues that I've noticed before when starting
komorebi while having other 3rd parties trying to subscribe to it (like
komorebi-bar and YASB), which would make those subscribers lock the
`process_command` thread. This doesn't seem to be happening on my tests
anymore with this new order.
2025-03-02 18:28:07 -08:00
alex-ds13
83538be46e perf(reaper): switch to channel notifications
This commit changes the way the reaper works.

First this commit changed the `known_hwnds` held by the `WindowManager`
to be a HashMap of window handles (isize) to a pair of monitor_idx,
workspace_idx (usize, usize).

This commit then changes the reaper to have a cache of hwnds which is
updated by the `WindowManager` when they change. The reaper has a thread
that is continuously checking this cache to see if there is any window
handle that no longer exists. When it finds them, the thread sends a
notification to a channel which is then received by the reaper on
another thread that actually does the work on the `WindowManager` by
removing said windows.

This means that the reaper no longer tries to access and lock the
`WindowManager` every second like it used to, but instead it only does
it when it actually needs, when a window actually needs to be reaped.
This means that we can make the thread that checks for orphan windows
run much more frequently since it won't influence the rest of komorebi.

Since now the `known_hwnds` have the monitor/workspace index pair of the
window, we can simply get that info from the map and immediately access
that monitor/workspace or use that index info.
2025-03-02 18:28:07 -08:00
Csaba
8f98cc6be5 feat(bar): add icons to workspace-layer widget
This commits adds the ability to set icons for the `workspace-layer` with
the `DisplayFormat` and a setting to specify if it should `show_when_tiling`
or not.

collab with @alex-ds13
2025-03-02 15:39:49 -08:00
LGUG2Z
06d469f1da fix(wm): preserve resize dimensions on offset toggle
This commit ensures that the resize dimensions will be reserved for
other monitors and workspaces when the
toggle-window-based-work-area-offset command is used.
2025-03-02 14:43:13 -08:00
Csaba
1115db65e7 fix(bar): always add stroke on selected_frame
This commit fixes a breaking change on the selected_frame that was
introduced by eframe version 0.31.

In this version, the stroke is drawn on the inside of a Frame instead it
being drawn on the outside like before.

This now means that a stroke needs to be added on all the states of the
Frame in order to avoid all the elements to be moving around on hover.
2025-03-02 14:43:13 -08:00
LGUG2Z
a785d7b7b1 docs(readme): add active individual commercial use licenses count 2025-03-02 14:43:13 -08:00
LGUG2Z
01a417605c chore(deps): bump eframe to 0.31 2025-03-02 14:43:13 -08:00
alex-ds13
6e7f42be87 fix(wm): allow stacking in all dirs, improve stack border rendering
Previously the stacking logic would sometimes change the focused
container without actually changing focus to said container.

This resulted in the stack showing up with an unfocused border even
though we had focus on one windows belonging to the stack (just not the
right one).

Also before it wasn't possible to stack windows on some directions
when we were already on a stack.

This commit fixes both issues.
2025-03-02 14:43:13 -08:00
alex-ds13
64d856169b fix(borders): address memory leaks
This commit fixes multiple issues with the borders which were resulting
in multiple borders being created and not completely destroyed which
meant that the amount of borders in memory kept increasing indefinitely
the more we used komorebi. To do so this commit does the following:

- Clear all the maps on `destroy_all_borders`.

- Create function `remove_border` which should always be used when we
  want to remove a border since this function destroys the border window
  and removes all its related data and clones from all the maps.

- Create function `remove_borders` which should always be used when we
  want to remove multiple borders or filter the current existing
  borders. It takes in a `condition` function that takes a ref to the
  border's container id and a ref to the border and should return a
  bool. This function is then applied to each existing border and if it
  evaluates to true it will call `remove_border` on it.

- Apply these new functions on all the code that was previously manually
  removing borders.

- When a container is a stack, we now check it's unfocused windows, in
  case they had borders attached to them we remove them, otherwise these
  borders would persist and be drawn below other borders.

- We now check if a container's border was previously tracking a different
  window, if it was we destroy that border and remove it's hwnd from the
  `FOCUS_STATE` and then we check if its `tracking_hwnd` still points to
  the same border and remove it if it does (if it doesn't that means
  that a new border was already attached to that window so we don't
  remove it).

  We don't call `remove_border` here since we don't want to actually
  remove the border but instead we replace it with a new one tracking
  the correct window. (I've tried updating the `tracking_hwnd` instead
  of destroying the border and creating a new one but that didn't work
  since it still kept tracking the previous window...).
2025-03-02 14:43:13 -08:00
alex-ds13
67cb5d044a feat(wm): move all windows on ws layer toggle
This commit makes it so when you toggle between workspace layers it
moves all windows of that layer to the top of the z-order.

So if you move to `Floating` layer, then all floating windows are moved
to the top, and if you go back to the `Tiling` layer, all tiled
containers are moved to the top.
2025-03-02 14:43:13 -08:00
LGUG2Z
4a19336974 chore(deps): bump shadow-rs from 0.38 to 1 2025-03-02 14:43:13 -08:00
Csaba
3a1e73918d fix(bar): use accent color for active widget components
This commit makes sure that the accent color is used on certain bar
components, such as active workspace, selected layout and focused
window.

This will now make these components stand out even more for a better
visual indication.

fix #1288
2025-03-02 14:43:13 -08:00
LGUG2Z
60ed10e6e6 chore(deps): bump win32-display-data 2025-03-02 14:43:13 -08:00
Csaba
2e90a3a75d feat(bar): add opts to show all icons on workspace widget
This commit adds 3 new display options on the komorebi workspace widget
to show all icons.
2025-03-02 14:43:13 -08:00
LGUG2Z
0289b02d97 chore(just): add wpm target 2025-03-02 14:43:13 -08:00
alex-ds13
d351e910e5 fix(wm): prevent floating focus change event infinite loops
This commit stops the `FocusChange` event from focusing a floating
window when it is the one emitting said `FocusChange` event, since it's
not needed and is the cause of some flicker bugs reported!

If that floating window was the one emitting the `FocusChange` event
then it means it is already the foreground window, and there is no
reason for us to focus the window again (since that will create an
infinite loop of events).

When the window emitting this event is not floating we don't try to
focus the window, we simply set the focus index for the container of
that window and the focused index for the window of that container.

Except in one case, which is if the workspace has a monocle container,
then it does focus a window, it focuses the monocle window to make sure
the monocle keeps showing in front of everything and doesn't let
anything come in front of it.
2025-03-02 14:43:13 -08:00
alex-ds13
c25750b691 fix(bar): apply work area offset on monitor reconnect
This commit makes sure the bar applies the the `work_area_offset`
correctly after a monitor reconnects; if it is the first time a monitor
is connecting, the cached offset won't exist yet.
2025-03-02 14:43:12 -08:00
alex-ds13
c37a0aa8a6 fix(wm): properly load monitor on first connect
This commit fixes an issue where if you started komorebi without a
monitor connected, and then connected it later, it wasn't properly
loading the data returned from `win32-display-data`.
2025-03-02 14:43:12 -08:00
LGUG2Z
fc0da2c1d3 refactor(bar): add extend_enum! macro
This commit adds an extend_enum! macro and some unit tests to provide
an ergonomic way to specialize configs for specific (sub)widgets.

The macro takes the name of the existing enum, the desired name of the
new, extended enum, and a list of variants which should be added to the
extended enum.

The macro will add new variants to a new enum definition first, before
wrapping the existing enum in an Existing variant and tagging it with
the `#[serde(untagged)]` annotation.

From is also implemented for ergonomic from/into calls between shared
variants of the existing and extended enums.
2025-03-02 14:43:12 -08:00
alex-ds13
47f4f47d3f feat(wm): add padding per monitor
This commit adds the ability to set container and workspace padding per
monitor.

To do so (and to simplify any future need of changing some value per
monitor), and have it pass through to each workspace a new field was added
to `Workspace` called `globals` which has a new struct called
`WorkspaceGlobals`.

`WorkspaceGlobals` includes any global values that might be needed by
the workspace.

This field is updated by the monitor for all its workspaces whenever the
config is loaded or reloaded. It is also updated on `RetileAll` and on
the function `update_focused_workspace`.

This should make sure that every time a workspace needs to use it's
`update` function, it has all the `globals` up to date!

This also means that now the `update` function from workspaces doesn't
take any argument at all, reducing all the need to get all the
`work_area`, `work_area_offset`, `window_based_work_area_offset` or
`window_based_work_area_offset_limit` simplifying the callers of this
function quite a bit.

Lastly this commit has also (sort of accidentaly) fixed an existing bug
with the `move_workspace_to_monitor` function.

This was previous removing the workspace from a monitor, but wasn't
changing it's `focused_workspace_idx`, meaning that komorebi would get
all messed up after that command. For example, the `border_manager`
would get stuck and the komorebi-bar would crash.

Now, the `remove_focused_workspace` function also focuses the previous
workspace (which in turn will create a new workspace in case the removed
workspace was the last workspace).
2025-03-02 14:43:11 -08:00
alex-ds13
0f59820419 fix(wm): hide/restore floating windows on monocle toggle 2025-03-02 14:42:04 -08:00
alex-ds13
ba1ef22204 fix(wm): take layer into account on ws restore
Previously if a workspace had any floating windows it would always focus
the first one when restoring. Now it only focus the floating window if
the workspace layer is `Floating`.
2025-03-02 14:42:04 -08:00
LGUG2Z
f7c9712706 feat(wm): add tiling and floating ws layers
This commit introduces an implementation of workspace layers to
komorebi.

Workspace layers change the kinds of windows that certain commands
operate on. This implementation features two variants,
WorkspaceLayer::Tiling and WorkspaceLayer::Floating.

The default behaviour until now has been WorkspaceLayer::Tiling.

When the user sets WorkspaceLayer::Floating, either through the
'toggle-workspace-layer' command or the new bar widget, the 'move',
'focus', 'cycle-focus' and 'resize-axis' commands will operate on
floating windows, if the currently focused window is a floating window.

As I don't have 'cycle-focus' bound to anything, 'focus up' and 'focus
down' double as incrementing and decrementing cycle focus commands,
iterating focus through the floating windows assigned to a workspace.

Floating windows in komorebi belong to specific workspaces, therefore
commands such as 'move' and 'resize-axis' will restrict movement and
resizing to the bounds of their workspace's work area (or more
accurately, the work area of the monitor that the workspace belongs to,
as floating windows are never constrained by workspace-specific work
area restrictions).
2025-03-02 14:42:04 -08:00
LGUG2Z
01a832027d build(cargo): add custom build profiles 2025-03-02 14:42:04 -08:00
51 changed files with 467 additions and 378 deletions

View File

@@ -71,4 +71,17 @@ features = [
"Win32_System_WindowsProgramming",
"Media",
"Media_Control"
]
]
[profile.dev-jeezy]
inherits = "dev"
debug = false
opt-level = 1
[profile.dev-jeezy.package."*"]
opt-level = 3
[profile.release-jeezy]
inherits = "release"
incremental = true
codegen-units = 256

View File

@@ -19,31 +19,22 @@ install-targets *targets:
"{{ targets }}" -split ' ' | ForEach-Object { just install-target $_ }
install-target target:
cargo +stable install --path {{ target }} --locked --no-default-features
install-targets-with-jsonschema *targets:
"{{ targets }}" -split ' ' | ForEach-Object { just install-target-with-jsonschema $_ }
install-target-with-jsonschema target:
cargo +stable install --path {{ target }} --locked
install:
just install-targets komorebic komorebic-no-console komorebi komorebi-bar komorebi-gui
install-with-jsonschema:
just install-targets-with-jsonschema komorebic komorebic-no-console komorebi komorebi-bar komorebi-gui
build-targets *targets:
"{{ targets }}" -split ' ' | ForEach-Object { just build-target $_ }
build-target target:
cargo +stable build --package {{ target }} --locked --release --no-default-features
cargo +stable build --package {{ target }} --locked --profile release-jeezy
build:
just build-targets komorebic komorebic-no-console komorebi komorebi-bar komorebi-gui
copy-target target:
cp .\target\release\{{ target }}.exe $Env:USERPROFILE\.cargo\bin
cp .\target\release-jeezy\{{ target }}.exe $Env:USERPROFILE\.cargo\bin
copy-targets *targets:
"{{ targets }}" -split ' ' | ForEach-Object { just copy-target $_ }
@@ -55,7 +46,7 @@ copy:
just copy-targets komorebic komorebic-no-console komorebi komorebi-bar komorebi-gui
run target:
cargo +stable run --bin {{ target }} --locked --no-default-features
cargo +stable run --bin {{ target }} --locked
warn target $RUST_LOG="warn":
just run {{ target }}
@@ -70,7 +61,7 @@ trace target $RUST_LOG="trace":
just run {{ target }}
deadlock $RUST_LOG="trace":
cargo +stable run --bin komorebi --locked --no-default-features --features deadlock_detection
cargo +stable run --bin komorebi --locked --features deadlock_detection
docgen:
cargo run --package komorebic -- docgen

View File

@@ -26,7 +26,7 @@ num-derive = "0.4"
num-traits = "0.2"
random_word = { version = "0.4", features = ["en"] }
reqwest = { version = "0.12", features = ["blocking"] }
schemars = { workspace = true, optional = true }
schemars = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
starship-battery = "0.10"
@@ -35,8 +35,4 @@ tracing = { workspace = true }
tracing-subscriber = { workspace = true }
windows = { workspace = true }
windows-core = { workspace = true }
windows-icons = { git = "https://github.com/LGUG2Z/windows-icons", rev = "d67cc9920aa9b4883393e411fb4fa2ddd4c498b5" }
[features]
default = ["schemars"]
schemars = ["dep:schemars"]
windows-icons = { git = "https://github.com/LGUG2Z/windows-icons", rev = "d67cc9920aa9b4883393e411fb4fa2ddd4c498b5" }

View File

@@ -8,6 +8,7 @@ use eframe::egui::Context;
use eframe::egui::Label;
use eframe::egui::TextFormat;
use eframe::egui::Ui;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use starship_battery::units::ratio::percent;
@@ -17,8 +18,7 @@ use std::process::Command;
use std::time::Duration;
use std::time::Instant;
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct BatteryConfig {
/// Enable the Battery widget
pub enable: bool,

View File

@@ -6,13 +6,13 @@ use eframe::egui::TextBuffer;
use eframe::egui::Vec2;
use komorebi_client::KomorebiTheme;
use komorebi_client::Rect;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use std::collections::HashMap;
use std::path::PathBuf;
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
/// The `komorebi.bar.json` configuration file reference for `v0.1.35`
pub struct KomobarConfig {
/// Bar height (default: 50)
@@ -136,8 +136,7 @@ impl KomobarConfig {
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct PositionConfig {
/// The desired starting position of the bar (0,0 = top left of the screen)
#[serde(alias = "position")]
@@ -147,15 +146,13 @@ pub struct PositionConfig {
pub end: Option<Position>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct FrameConfig {
/// Margin inside the painted frame
pub inner_margin: Position,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
#[serde(untagged)]
pub enum MonitorConfigOrIndex {
/// The monitor index where you want the bar to show
@@ -164,8 +161,7 @@ pub enum MonitorConfigOrIndex {
MonitorConfig(MonitorConfig),
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct MonitorConfig {
/// Komorebi monitor index of the monitor on which to render the bar
pub index: usize,
@@ -176,8 +172,7 @@ pub struct MonitorConfig {
pub type Padding = SpacingKind;
pub type Margin = SpacingKind;
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
#[serde(untagged)]
// WARNING: To any developer messing with this code in the future: The order here matters!
// `Grouped` needs to come last, otherwise serde might mistaken an `IndividualSpacingConfig` for a
@@ -228,23 +223,20 @@ impl SpacingKind {
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct GroupedSpacingConfig {
pub vertical: Option<GroupedSpacingOptions>,
pub horizontal: Option<GroupedSpacingOptions>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
#[serde(untagged)]
pub enum GroupedSpacingOptions {
Symmetrical(f32),
Split(f32, f32),
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct IndividualSpacingConfig {
pub top: f32,
pub bottom: f32,
@@ -346,8 +338,7 @@ impl KomobarConfig {
}
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct Position {
/// X coordinate
pub x: f32,
@@ -373,8 +364,7 @@ impl From<Position> for Pos2 {
}
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "palette")]
pub enum KomobarTheme {
/// A theme from catppuccin-egui
@@ -410,8 +400,7 @@ impl From<KomorebiTheme> for KomobarTheme {
}
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub enum LabelPrefix {
/// Show no prefix
None,
@@ -423,8 +412,7 @@ pub enum LabelPrefix {
IconAndText,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
pub enum DisplayFormat {
/// Show only icon
Icon,
@@ -440,8 +428,7 @@ pub enum DisplayFormat {
macro_rules! extend_enum {
($existing_enum:ident, $new_enum:ident, { $($(#[$meta:meta])* $variant:ident),* $(,)? }) => {
#[derive(Copy, Clone, Debug, serde::Serialize, serde::Deserialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Copy, Clone, Debug, serde::Serialize, serde::Deserialize, schemars::JsonSchema, PartialEq)]
pub enum $new_enum {
// Add new variants
$(
@@ -473,11 +460,12 @@ extend_enum!(DisplayFormat, WorkspacesDisplayFormat, {
#[cfg(test)]
mod tests {
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use serde_json::json;
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq)]
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
pub enum OriginalDisplayFormat {
/// Show None Of The Things
NoneOfTheThings,

View File

@@ -8,6 +8,7 @@ use eframe::egui::Context;
use eframe::egui::Label;
use eframe::egui::TextFormat;
use eframe::egui::Ui;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use std::process::Command;
@@ -16,8 +17,7 @@ use std::time::Instant;
use sysinfo::RefreshKind;
use sysinfo::System;
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct CpuConfig {
/// Enable the Cpu widget
pub enable: bool,

View File

@@ -9,12 +9,12 @@ use eframe::egui::Label;
use eframe::egui::TextFormat;
use eframe::egui::Ui;
use eframe::egui::WidgetText;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
/// Custom format with additive modifiers for integer format specifiers
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct CustomModifiers {
/// Custom format (https://docs.rs/chrono/latest/chrono/format/strftime/index.html)
format: String,
@@ -55,8 +55,7 @@ impl CustomModifiers {
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct DateConfig {
/// Enable the Date widget
pub enable: bool,
@@ -76,8 +75,7 @@ impl From<DateConfig> for Date {
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub enum DateFormat {
/// Month/Date/Year format (09/08/24)
MonthDateYear,

View File

@@ -8,6 +8,7 @@ use eframe::egui::Label;
use eframe::egui::TextFormat;
use eframe::egui::Ui;
use eframe::egui::WidgetText;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use std::time::Duration;
@@ -22,8 +23,7 @@ use windows::Win32::UI::WindowsAndMessaging::GetWindowThreadProcessId;
const DEFAULT_DATA_REFRESH_INTERVAL: u64 = 1;
const ERROR_TEXT: &str = "Error";
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct KeyboardConfig {
/// Enable the Input widget
pub enable: bool,

View File

@@ -37,6 +37,7 @@ use komorebi_client::SocketMessage;
use komorebi_client::Window;
use komorebi_client::Workspace;
use komorebi_client::WorkspaceLayer;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use std::cell::RefCell;
@@ -46,8 +47,7 @@ use std::path::PathBuf;
use std::rc::Rc;
use std::sync::atomic::Ordering;
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct KomorebiConfig {
/// Configure the Workspaces widget
pub workspaces: Option<KomorebiWorkspacesConfig>,
@@ -61,8 +61,7 @@ pub struct KomorebiConfig {
pub configuration_switcher: Option<KomorebiConfigurationSwitcherConfig>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct KomorebiWorkspacesConfig {
/// Enable the Komorebi Workspaces widget
pub enable: bool,
@@ -72,8 +71,7 @@ pub struct KomorebiWorkspacesConfig {
pub display: Option<WorkspacesDisplayFormat>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct KomorebiLayoutConfig {
/// Enable the Komorebi Layout widget
pub enable: bool,
@@ -83,8 +81,7 @@ pub struct KomorebiLayoutConfig {
pub display: Option<DisplayFormat>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct KomorebiWorkspaceLayerConfig {
/// Enable the Komorebi Workspace Layer widget
pub enable: bool,
@@ -94,8 +91,7 @@ pub struct KomorebiWorkspaceLayerConfig {
pub show_when_tiling: Option<bool>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct KomorebiFocusedWindowConfig {
/// Enable the Komorebi Focused Window widget
pub enable: bool,
@@ -105,8 +101,7 @@ pub struct KomorebiFocusedWindowConfig {
pub display: Option<DisplayFormat>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct KomorebiConfigurationSwitcherConfig {
/// Enable the Komorebi Configurations widget
pub enable: bool,

View File

@@ -14,6 +14,7 @@ use eframe::egui::StrokeKind;
use eframe::egui::Ui;
use eframe::egui::Vec2;
use komorebi_client::SocketMessage;
use schemars::JsonSchema;
use serde::de::Error;
use serde::Deserialize;
use serde::Deserializer;
@@ -22,8 +23,7 @@ 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))]
#[derive(Copy, Clone, Debug, Serialize, JsonSchema, PartialEq)]
#[serde(untagged)]
pub enum KomorebiLayout {
Default(komorebi_client::DefaultLayout),

View File

@@ -30,6 +30,7 @@ use hotwatch::Hotwatch;
use image::RgbaImage;
use komorebi_client::SocketMessage;
use komorebi_client::SubscribeOptions;
use schemars::gen::SchemaSettings;
use std::collections::HashMap;
use std::io::BufReader;
use std::io::Read;
@@ -124,9 +125,8 @@ fn main() -> color_eyre::Result<()> {
let opts: Opts = Opts::parse();
#[cfg(feature = "schemars")]
if opts.schema {
let settings = schemars::gen::SchemaSettings::default().with(|s| {
let settings = SchemaSettings::default().with(|s| {
s.option_nullable = false;
s.option_add_null_type = false;
s.inline_subschemas = true;

View File

@@ -10,13 +10,13 @@ use eframe::egui::Label;
use eframe::egui::TextFormat;
use eframe::egui::Ui;
use eframe::egui::Vec2;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use std::sync::atomic::Ordering;
use windows::Media::Control::GlobalSystemMediaTransportControlsSessionManager;
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct MediaConfig {
/// Enable the Media widget
pub enable: bool,

View File

@@ -8,6 +8,7 @@ use eframe::egui::Context;
use eframe::egui::Label;
use eframe::egui::TextFormat;
use eframe::egui::Ui;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use std::process::Command;
@@ -16,8 +17,7 @@ use std::time::Instant;
use sysinfo::RefreshKind;
use sysinfo::System;
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct MemoryConfig {
/// Enable the Memory widget
pub enable: bool,

View File

@@ -9,6 +9,7 @@ use eframe::egui::Label;
use eframe::egui::TextFormat;
use eframe::egui::Ui;
use num_derive::FromPrimitive;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use std::fmt;
@@ -17,8 +18,7 @@ use std::time::Duration;
use std::time::Instant;
use sysinfo::Networks;
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct NetworkConfig {
/// Enable the Network widget
pub enable: bool,

View File

@@ -11,6 +11,7 @@ use eframe::egui::Margin;
use eframe::egui::Shadow;
use eframe::egui::TextStyle;
use eframe::egui::Ui;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use std::sync::atomic::AtomicUsize;
@@ -19,8 +20,7 @@ use std::sync::Arc;
static SHOW_KOMOREBI_LAYOUT_OPTIONS: AtomicUsize = AtomicUsize::new(0);
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "kind")]
pub enum Grouping {
/// No grouping is applied
@@ -339,8 +339,7 @@ impl RenderConfig {
}
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct GroupingConfig {
/// Styles for the grouping
pub style: Option<GroupingStyle>,
@@ -350,8 +349,7 @@ pub struct GroupingConfig {
pub rounding: Option<RoundingConfig>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub enum GroupingStyle {
#[serde(alias = "CtByte")]
Default,
@@ -371,8 +369,7 @@ pub enum GroupingStyle {
DefaultWithGlowB0O1S2,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
#[serde(untagged)]
pub enum RoundingConfig {
/// All 4 corners are the same

View File

@@ -8,6 +8,7 @@ use eframe::egui::Context;
use eframe::egui::Label;
use eframe::egui::TextFormat;
use eframe::egui::Ui;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use std::process::Command;
@@ -15,8 +16,7 @@ use std::time::Duration;
use std::time::Instant;
use sysinfo::Disks;
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct StorageConfig {
/// Enable the Storage widget
pub enable: bool,

View File

@@ -14,11 +14,11 @@ use eframe::egui::TextFormat;
use eframe::egui::Ui;
use eframe::egui::Vec2;
use eframe::epaint::StrokeKind;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct TimeConfig {
/// Enable the Time widget
pub enable: bool,
@@ -38,8 +38,7 @@ impl From<TimeConfig> for Time {
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub enum TimeFormat {
/// Twelve-hour format (with seconds)
TwelveHour,

View File

@@ -8,14 +8,14 @@ use eframe::egui::Context;
use eframe::egui::Label;
use eframe::egui::TextFormat;
use eframe::egui::Ui;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use std::process::Command;
use std::time::Duration;
use std::time::Instant;
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct UpdateConfig {
/// Enable the Update widget
pub enable: bool,

View File

@@ -23,6 +23,7 @@ use crate::update::Update;
use crate::update::UpdateConfig;
use eframe::egui::Context;
use eframe::egui::Ui;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
@@ -30,8 +31,7 @@ pub trait BarWidget {
fn render(&mut self, ctx: &Context, ui: &mut Ui, config: &mut RenderConfig);
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub enum WidgetConfig {
Battery(BatteryConfig),
Cpu(CpuConfig),

View File

@@ -29,7 +29,7 @@ os_info = "3.10"
parking_lot = "0.12"
paste = { workspace = true }
regex = "1"
schemars = { workspace = true, optional = true }
schemars = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
serde_yaml = { workspace = true }
@@ -57,6 +57,4 @@ shadow-rs = { workspace = true }
reqwest = { version = "0.12", features = ["blocking"] }
[features]
default = ["schemars"]
deadlock_detection = ["parking_lot/deadlock_detection"]
schemars = ["dep:schemars"]

View File

@@ -1,5 +1,7 @@
use color_eyre::Result;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use std::sync::atomic::Ordering;
@@ -11,8 +13,7 @@ use super::ANIMATION_DURATION_GLOBAL;
use super::ANIMATION_FPS;
use super::ANIMATION_MANAGER;
#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize, JsonSchema, PartialEq)]
pub struct AnimationEngine;
impl AnimationEngine {

View File

@@ -18,12 +18,11 @@ pub mod prefix;
pub mod render_dispatcher;
pub use render_dispatcher::RenderDispatcher;
pub mod style;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
#[serde(untagged)]
pub enum PerAnimationPrefixConfig<T> {
Prefix(HashMap<AnimationPrefix, T>),

View File

@@ -1,14 +1,24 @@
use clap::ValueEnum;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use strum::Display;
use strum::EnumString;
#[derive(
Copy, Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Display, EnumString, ValueEnum,
Copy,
Clone,
Debug,
Hash,
PartialEq,
Eq,
Serialize,
Deserialize,
Display,
EnumString,
ValueEnum,
JsonSchema,
)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[strum(serialize_all = "snake_case")]
#[serde(rename_all = "snake_case")]
pub enum AnimationPrefix {

View File

@@ -19,6 +19,7 @@ use crossbeam_utils::atomic::AtomicCell;
use crossbeam_utils::atomic::AtomicConsume;
use lazy_static::lazy_static;
use parking_lot::Mutex;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use std::collections::hash_map::Entry;
@@ -697,8 +698,7 @@ fn remove_border(
Ok(())
}
#[derive(Debug, Copy, Clone, Display, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Debug, Copy, Clone, Display, Serialize, Deserialize, JsonSchema, PartialEq)]
pub enum ZOrder {
Top,
NoTopMost,

View File

@@ -1,19 +1,14 @@
use hex_color::HexColor;
use komorebi_themes::Color32;
#[cfg(feature = "schemars")]
use schemars::gen::SchemaGenerator;
#[cfg(feature = "schemars")]
use schemars::schema::InstanceType;
#[cfg(feature = "schemars")]
use schemars::schema::Schema;
#[cfg(feature = "schemars")]
use schemars::schema::SchemaObject;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Debug, Copy, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
#[serde(untagged)]
pub enum Colour {
/// Colour represented as RGB
@@ -59,8 +54,7 @@ impl From<Colour> for Color32 {
#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq)]
pub struct Hex(HexColor);
#[cfg(feature = "schemars")]
impl schemars::JsonSchema for Hex {
impl JsonSchema for Hex {
fn schema_name() -> String {
String::from("Hex")
}
@@ -84,8 +78,7 @@ impl From<Colour> for u32 {
}
}
#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Debug, Copy, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
pub struct Rgb {
/// Red
pub r: u32,

View File

@@ -2,14 +2,14 @@ use std::collections::VecDeque;
use getset::Getters;
use nanoid::nanoid;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use crate::ring::Ring;
use crate::window::Window;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Getters)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Getters, JsonSchema)]
pub struct Container {
#[getset(get = "pub")]
id: String,

View File

@@ -1,12 +1,22 @@
use clap::ValueEnum;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use strum::Display;
use strum::EnumString;
#[derive(Copy, Clone, Debug, Serialize, Deserialize, Display, EnumString, ValueEnum, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(
Copy,
Clone,
Debug,
Serialize,
Deserialize,
Display,
EnumString,
ValueEnum,
JsonSchema,
PartialEq,
)]
pub enum AnimationStyle {
Linear,
EaseInSine,

View File

@@ -1,6 +1,7 @@
use std::num::NonZeroUsize;
use clap::ValueEnum;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use strum::Display;
@@ -602,8 +603,18 @@ impl Arrangement for CustomLayout {
}
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ValueEnum, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(
Clone,
Copy,
Debug,
Serialize,
Deserialize,
Display,
EnumString,
ValueEnum,
JsonSchema,
PartialEq,
)]
pub enum Axis {
Horizontal,
Vertical,

View File

@@ -2,6 +2,7 @@ use crate::config_generation::ApplicationConfiguration;
use crate::config_generation::ApplicationOptions;
use crate::config_generation::MatchingRule;
use color_eyre::Result;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use std::collections::BTreeMap;
@@ -9,12 +10,10 @@ use std::ops::Deref;
use std::ops::DerefMut;
use std::path::PathBuf;
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct ApplicationSpecificConfiguration(pub BTreeMap<String, AscApplicationRulesOrSchema>);
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
#[serde(untagged)]
pub enum AscApplicationRulesOrSchema {
AscApplicationRules(AscApplicationRules),
@@ -47,8 +46,7 @@ impl ApplicationSpecificConfiguration {
}
/// Rules that determine how an application is handled
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct AscApplicationRules {
/// Rules to ignore specific windows
#[serde(skip_serializing_if = "Option::is_none")]

View File

@@ -1,5 +1,6 @@
use clap::ValueEnum;
use color_eyre::Result;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use strum::Display;
@@ -7,8 +8,9 @@ use strum::EnumString;
use super::ApplicationIdentifier;
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ValueEnum)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(
Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ValueEnum, JsonSchema,
)]
#[strum(serialize_all = "snake_case")]
#[serde(rename_all = "snake_case")]
pub enum ApplicationOptions {
@@ -50,16 +52,14 @@ impl ApplicationOptions {
}
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
#[serde(untagged)]
pub enum MatchingRule {
Simple(IdWithIdentifier),
Composite(Vec<IdWithIdentifier>),
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct WorkspaceMatchingRule {
pub monitor_index: usize,
pub workspace_index: usize,
@@ -67,8 +67,7 @@ pub struct WorkspaceMatchingRule {
pub initial_only: bool,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct IdWithIdentifier {
pub kind: ApplicationIdentifier,
pub id: String,
@@ -76,8 +75,7 @@ pub struct IdWithIdentifier {
pub matching_strategy: Option<MatchingStrategy>,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Display)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Display, JsonSchema)]
pub enum MatchingStrategy {
Legacy,
Equals,
@@ -91,8 +89,7 @@ pub enum MatchingStrategy {
DoesNotContain,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct IdWithIdentifierAndComment {
pub kind: ApplicationIdentifier,
pub id: String,
@@ -112,8 +109,7 @@ impl From<IdWithIdentifierAndComment> for IdWithIdentifier {
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct ApplicationConfiguration {
pub name: String,
pub identifier: IdWithIdentifier,
@@ -137,8 +133,7 @@ impl ApplicationConfiguration {
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct ApplicationConfigurationGenerator;
impl ApplicationConfigurationGenerator {

View File

@@ -8,13 +8,13 @@ use std::path::Path;
use color_eyre::eyre::anyhow;
use color_eyre::eyre::bail;
use color_eyre::Result;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use super::Rect;
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
pub struct CustomLayout(Vec<Column>);
impl Deref for CustomLayout {
@@ -250,8 +250,7 @@ impl CustomLayout {
}
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
#[serde(tag = "column", content = "configuration")]
pub enum Column {
Primary(Option<ColumnWidth>),
@@ -259,21 +258,18 @@ pub enum Column {
Tertiary(ColumnSplit),
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
pub enum ColumnWidth {
WidthPercentage(f32),
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
pub enum ColumnSplit {
Horizontal,
Vertical,
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
pub enum ColumnSplitWithCapacity {
Horizontal(usize),
Vertical(usize),

View File

@@ -1,13 +1,15 @@
use std::num::NonZeroUsize;
use clap::ValueEnum;
use schemars::JsonSchema;
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))]
#[derive(
Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ValueEnum, JsonSchema,
)]
pub enum CycleDirection {
Previous,
Next,

View File

@@ -1,4 +1,5 @@
use clap::ValueEnum;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use strum::Display;
@@ -9,9 +10,18 @@ use super::Rect;
use super::Sizing;
#[derive(
Clone, Copy, Debug, Serialize, Deserialize, Eq, PartialEq, Display, EnumString, ValueEnum,
Clone,
Copy,
Debug,
Serialize,
Deserialize,
Eq,
PartialEq,
Display,
EnumString,
ValueEnum,
JsonSchema,
)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum DefaultLayout {
BSP,
Columns,

View File

@@ -1,3 +1,4 @@
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
@@ -6,8 +7,7 @@ use super::CustomLayout;
use super::DefaultLayout;
use super::Direction;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
pub enum Layout {
Default(DefaultLayout),
Custom(CustomLayout),

View File

@@ -8,6 +8,7 @@ use std::str::FromStr;
use clap::ValueEnum;
use color_eyre::eyre::anyhow;
use color_eyre::Result;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use strum::Display;
@@ -44,8 +45,7 @@ pub mod operation_direction;
pub mod pathext;
pub mod rect;
#[derive(Clone, Debug, Serialize, Deserialize, Display)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, Display, JsonSchema)]
#[serde(tag = "type", content = "content")]
pub enum SocketMessage {
// Window / Container Commands
@@ -241,23 +241,24 @@ impl FromStr for SocketMessage {
}
}
#[derive(Default, Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Default, Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct SubscribeOptions {
/// Only emit notifications when the window manager state has changed
pub filter_state_changes: bool,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Display, Serialize, Deserialize, ValueEnum)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(
Debug, Copy, Clone, Eq, PartialEq, Display, Serialize, Deserialize, JsonSchema, ValueEnum,
)]
pub enum StackbarMode {
Always,
Never,
OnStack,
}
#[derive(Debug, Copy, Default, Clone, Eq, PartialEq, Display, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(
Debug, Copy, Default, Clone, Eq, PartialEq, Display, Serialize, Deserialize, JsonSchema,
)]
pub enum StackbarLabel {
#[default]
Process,
@@ -265,9 +266,18 @@ pub enum StackbarLabel {
}
#[derive(
Default, Copy, Clone, Debug, Eq, PartialEq, Display, Serialize, Deserialize, ValueEnum,
Default,
Copy,
Clone,
Debug,
Eq,
PartialEq,
Display,
Serialize,
Deserialize,
JsonSchema,
ValueEnum,
)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum BorderStyle {
#[default]
/// Use the system border style
@@ -279,9 +289,18 @@ pub enum BorderStyle {
}
#[derive(
Default, Copy, Clone, Debug, Eq, PartialEq, Display, Serialize, Deserialize, ValueEnum,
Default,
Copy,
Clone,
Debug,
Eq,
PartialEq,
Display,
Serialize,
Deserialize,
JsonSchema,
ValueEnum,
)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum BorderImplementation {
#[default]
/// Use the adjustable komorebi border implementation
@@ -291,9 +310,19 @@ pub enum BorderImplementation {
}
#[derive(
Copy, Clone, Debug, Serialize, Deserialize, Display, EnumString, ValueEnum, PartialEq, Eq, Hash,
Copy,
Clone,
Debug,
Serialize,
Deserialize,
Display,
EnumString,
ValueEnum,
JsonSchema,
PartialEq,
Eq,
Hash,
)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum WindowKind {
Single,
Stack,
@@ -302,8 +331,9 @@ pub enum WindowKind {
Floating,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, Display, EnumString, ValueEnum)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(
Copy, Clone, Debug, Serialize, Deserialize, Display, EnumString, ValueEnum, JsonSchema,
)]
pub enum StateQuery {
FocusedMonitorIndex,
FocusedWorkspaceIndex,
@@ -313,9 +343,18 @@ pub enum StateQuery {
}
#[derive(
Copy, Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Display, EnumString, ValueEnum,
Copy,
Clone,
Debug,
Eq,
PartialEq,
Serialize,
Deserialize,
Display,
EnumString,
ValueEnum,
JsonSchema,
)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum ApplicationIdentifier {
#[serde(alias = "exe")]
Exe,
@@ -327,8 +366,18 @@ pub enum ApplicationIdentifier {
Path,
}
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Display, EnumString, ValueEnum)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(
Copy,
Clone,
Debug,
PartialEq,
Serialize,
Deserialize,
Display,
EnumString,
ValueEnum,
JsonSchema,
)]
pub enum FocusFollowsMouseImplementation {
/// A custom FFM implementation (slightly more CPU-intensive)
Komorebi,
@@ -336,8 +385,7 @@ pub enum FocusFollowsMouseImplementation {
Windows,
}
#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq)]
pub struct WindowManagementBehaviour {
/// The current WindowContainerBehaviour to be used
pub current_behaviour: WindowContainerBehaviour,
@@ -348,9 +396,18 @@ pub struct WindowManagementBehaviour {
}
#[derive(
Clone, Copy, Debug, Default, Serialize, Deserialize, Display, EnumString, ValueEnum, PartialEq,
Clone,
Copy,
Debug,
Default,
Serialize,
Deserialize,
Display,
EnumString,
ValueEnum,
JsonSchema,
PartialEq,
)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum WindowContainerBehaviour {
/// Create a new container for each new window
#[default]
@@ -359,8 +416,18 @@ pub enum WindowContainerBehaviour {
Append,
}
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize, Display, EnumString, ValueEnum)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(
Clone,
Copy,
Debug,
PartialEq,
Serialize,
Deserialize,
Display,
EnumString,
ValueEnum,
JsonSchema,
)]
pub enum MoveBehaviour {
/// Swap the window container with the window container at the edge of the adjacent monitor
Swap,
@@ -370,8 +437,18 @@ pub enum MoveBehaviour {
NoOp,
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ValueEnum, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(
Clone,
Copy,
Debug,
Serialize,
Deserialize,
Display,
EnumString,
ValueEnum,
JsonSchema,
PartialEq,
)]
pub enum CrossBoundaryBehaviour {
/// Attempt to perform actions across a workspace boundary
Workspace,
@@ -379,8 +456,18 @@ pub enum CrossBoundaryBehaviour {
Monitor,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, Display, EnumString, ValueEnum, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(
Copy,
Clone,
Debug,
Serialize,
Deserialize,
Display,
EnumString,
ValueEnum,
JsonSchema,
PartialEq,
)]
pub enum HidingBehaviour {
/// Use the SW_HIDE flag to hide windows when switching workspaces (has issues with Electron apps)
Hide,
@@ -390,8 +477,18 @@ pub enum HidingBehaviour {
Cloak,
}
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize, Display, EnumString, ValueEnum)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(
Clone,
Copy,
Debug,
PartialEq,
Serialize,
Deserialize,
Display,
EnumString,
ValueEnum,
JsonSchema,
)]
pub enum OperationBehaviour {
/// Process komorebic commands on temporarily unmanaged/floated windows
Op,
@@ -399,8 +496,9 @@ pub enum OperationBehaviour {
NoOp,
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ValueEnum)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(
Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ValueEnum, JsonSchema,
)]
pub enum Sizing {
Increase,
Decrease,

View File

@@ -1,6 +1,7 @@
use std::num::NonZeroUsize;
use clap::ValueEnum;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use strum::Display;
@@ -9,8 +10,9 @@ use strum::EnumString;
use super::direction::Direction;
use super::Axis;
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ValueEnum)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(
Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ValueEnum, JsonSchema,
)]
pub enum OperationDirection {
Left,
Right,

View File

@@ -1,9 +1,9 @@
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use windows::Win32::Foundation::RECT;
#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize, Eq, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize, Eq, PartialEq, JsonSchema)]
pub struct Rect {
/// The left point in a Win32 Rect
pub left: i32,

View File

@@ -66,6 +66,7 @@ use color_eyre::Result;
use os_info::Version;
use parking_lot::Mutex;
use regex::Regex;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use uds_windows::UnixStream;
@@ -279,8 +280,7 @@ pub fn current_virtual_desktop() -> Option<Vec<u8>> {
current
}
#[derive(Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
#[serde(untagged)]
pub enum NotificationEvent {
WindowManager(WindowManagerEvent),
@@ -288,8 +288,7 @@ pub enum NotificationEvent {
Monitor(MonitorNotification),
}
#[derive(Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct Notification {
pub event: NotificationEvent,
pub state: State,

View File

@@ -9,6 +9,7 @@ use getset::CopyGetters;
use getset::Getters;
use getset::MutGetters;
use getset::Setters;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
@@ -25,9 +26,17 @@ use crate::DEFAULT_CONTAINER_PADDING;
use crate::DEFAULT_WORKSPACE_PADDING;
#[derive(
Debug, Clone, Serialize, Deserialize, Getters, CopyGetters, MutGetters, Setters, PartialEq,
Debug,
Clone,
Serialize,
Deserialize,
Getters,
CopyGetters,
MutGetters,
Setters,
JsonSchema,
PartialEq,
)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct Monitor {
#[getset(get_copy = "pub", set = "pub")]
pub id: isize,

View File

@@ -17,6 +17,7 @@ use crossbeam_channel::Receiver;
use crossbeam_channel::Sender;
use crossbeam_utils::atomic::AtomicConsume;
use parking_lot::Mutex;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use std::collections::HashMap;
@@ -27,8 +28,7 @@ use std::sync::OnceLock;
pub mod hidden;
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Debug, Copy, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "type", content = "content")]
pub enum MonitorNotification {
ResolutionScalingChanged,

View File

@@ -1,8 +1,3 @@
use color_eyre::eyre::anyhow;
use color_eyre::Result;
use miow::pipe::connect;
use net2::TcpStreamExt;
use parking_lot::Mutex;
use std::collections::HashMap;
use std::fs::File;
use std::fs::OpenOptions;
@@ -16,11 +11,20 @@ use std::str::FromStr;
use std::sync::atomic::Ordering;
use std::sync::Arc;
use std::time::Duration;
use color_eyre::eyre::anyhow;
use color_eyre::Result;
use miow::pipe::connect;
use net2::TcpStreamExt;
use parking_lot::Mutex;
use schemars::gen::SchemaSettings;
use schemars::schema_for;
use uds_windows::UnixStream;
use crate::animation::ANIMATION_DURATION_PER_ANIMATION;
use crate::animation::ANIMATION_ENABLED_PER_ANIMATION;
use crate::animation::ANIMATION_STYLE_PER_ANIMATION;
use crate::core::config_generation::ApplicationConfiguration;
use crate::core::config_generation::IdWithIdentifier;
use crate::core::config_generation::MatchingRule;
use crate::core::config_generation::MatchingStrategy;
@@ -1824,49 +1828,35 @@ impl WindowManager {
*STACKBAR_FONT_FAMILY.lock() = font_family.clone();
}
SocketMessage::ApplicationSpecificConfigurationSchema => {
#[cfg(feature = "schemars")]
{
let asc = schemars::schema_for!(
Vec<crate::core::config_generation::ApplicationConfiguration>
);
let schema = serde_json::to_string_pretty(&asc)?;
let asc = schema_for!(Vec<ApplicationConfiguration>);
let schema = serde_json::to_string_pretty(&asc)?;
reply.write_all(schema.as_bytes())?;
}
reply.write_all(schema.as_bytes())?;
}
SocketMessage::NotificationSchema => {
#[cfg(feature = "schemars")]
{
let notification = schemars::schema_for!(Notification);
let schema = serde_json::to_string_pretty(&notification)?;
let notification = schema_for!(Notification);
let schema = serde_json::to_string_pretty(&notification)?;
reply.write_all(schema.as_bytes())?;
}
reply.write_all(schema.as_bytes())?;
}
SocketMessage::SocketSchema => {
#[cfg(feature = "schemars")]
{
let socket_message = schemars::schema_for!(SocketMessage);
let schema = serde_json::to_string_pretty(&socket_message)?;
let socket_message = schema_for!(SocketMessage);
let schema = serde_json::to_string_pretty(&socket_message)?;
reply.write_all(schema.as_bytes())?;
}
reply.write_all(schema.as_bytes())?;
}
SocketMessage::StaticConfigSchema => {
#[cfg(feature = "schemars")]
{
let settings = schemars::gen::SchemaSettings::default().with(|s| {
s.option_nullable = false;
s.option_add_null_type = false;
s.inline_subschemas = true;
});
let settings = SchemaSettings::default().with(|s| {
s.option_nullable = false;
s.option_add_null_type = false;
s.inline_subschemas = true;
});
let gen = settings.into_generator();
let socket_message = gen.into_root_schema_for::<StaticConfig>();
let schema = serde_json::to_string_pretty(&socket_message)?;
let gen = settings.into_generator();
let socket_message = gen.into_root_schema_for::<StaticConfig>();
let schema = serde_json::to_string_pretty(&socket_message)?;
reply.write_all(schema.as_bytes())?;
}
reply.write_all(schema.as_bytes())?;
}
SocketMessage::GenerateStaticConfig => {
let config = serde_json::to_string_pretty(&StaticConfig::from(&*self))?;

View File

@@ -79,7 +79,6 @@ fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result<()>
for (hwnd, (m_idx, w_idx)) in orphan_hwnds.iter() {
if let Some(monitor) = wm.monitors_mut().get_mut(*m_idx) {
let focused_workspace_idx = monitor.focused_workspace_idx();
if let Some(workspace) = monitor.workspaces_mut().get_mut(*w_idx) {
// Remove orphan window
if let Err(error) = workspace.remove_window(*hwnd) {

View File

@@ -1,10 +1,10 @@
use std::collections::VecDeque;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
pub struct Ring<T> {
elements: VecDeque<T>,
focused: usize,

View File

@@ -7,35 +7,14 @@ use crate::animation::ANIMATION_FPS;
use crate::animation::ANIMATION_STYLE_GLOBAL;
use crate::animation::ANIMATION_STYLE_PER_ANIMATION;
use crate::animation::DEFAULT_ANIMATION_FPS;
use crate::asc::ApplicationSpecificConfiguration;
use crate::asc::AscApplicationRulesOrSchema;
use crate::border_manager;
use crate::border_manager::ZOrder;
use crate::border_manager::IMPLEMENTATION;
use crate::border_manager::STYLE;
use crate::colour::Colour;
use crate::config_generation::WorkspaceMatchingRule;
use crate::core::config_generation::ApplicationConfiguration;
use crate::core::config_generation::ApplicationConfigurationGenerator;
use crate::core::config_generation::ApplicationOptions;
use crate::core::config_generation::MatchingRule;
use crate::core::config_generation::MatchingStrategy;
use crate::core::resolve_home_path;
use crate::core::AnimationStyle;
use crate::core::BorderImplementation;
use crate::core::BorderStyle;
use crate::core::DefaultLayout;
use crate::core::FocusFollowsMouseImplementation;
use crate::core::HidingBehaviour;
use crate::core::Layout;
use crate::core::MoveBehaviour;
use crate::core::OperationBehaviour;
use crate::core::Rect;
use crate::core::SocketMessage;
use crate::core::StackbarLabel;
use crate::core::StackbarMode;
use crate::core::WindowContainerBehaviour;
use crate::core::WindowManagementBehaviour;
use crate::current_virtual_desktop;
use crate::monitor;
use crate::monitor::Monitor;
@@ -82,12 +61,35 @@ use crate::TRANSPARENCY_BLACKLIST;
use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS;
use crate::WINDOWS_11;
use crate::WORKSPACE_MATCHING_RULES;
use crate::asc::ApplicationSpecificConfiguration;
use crate::asc::AscApplicationRulesOrSchema;
use crate::config_generation::WorkspaceMatchingRule;
use crate::core::config_generation::ApplicationConfiguration;
use crate::core::config_generation::ApplicationConfigurationGenerator;
use crate::core::config_generation::ApplicationOptions;
use crate::core::config_generation::MatchingRule;
use crate::core::config_generation::MatchingStrategy;
use crate::core::resolve_home_path;
use crate::core::AnimationStyle;
use crate::core::BorderStyle;
use crate::core::DefaultLayout;
use crate::core::FocusFollowsMouseImplementation;
use crate::core::HidingBehaviour;
use crate::core::Layout;
use crate::core::MoveBehaviour;
use crate::core::OperationBehaviour;
use crate::core::Rect;
use crate::core::SocketMessage;
use crate::core::WindowContainerBehaviour;
use crate::core::WindowManagementBehaviour;
use color_eyre::Result;
use crossbeam_channel::Receiver;
use hotwatch::EventKind;
use hotwatch::Hotwatch;
use parking_lot::Mutex;
use regex::Regex;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use std::collections::HashMap;
@@ -100,8 +102,7 @@ use std::sync::Arc;
use uds_windows::UnixListener;
use uds_windows::UnixStream;
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
pub struct BorderColours {
/// Border colour when the container contains a single window
#[serde(skip_serializing_if = "Option::is_none")]
@@ -120,8 +121,7 @@ pub struct BorderColours {
pub unfocused: Option<Colour>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
pub struct WorkspaceConfig {
/// Name
pub name: String,
@@ -243,8 +243,7 @@ impl From<&Workspace> for WorkspaceConfig {
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
pub struct MonitorConfig {
/// Workspace configurations
pub workspaces: Vec<WorkspaceConfig>,
@@ -302,8 +301,7 @@ impl From<&Monitor> for MonitorConfig {
}
}
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq)]
/// The `komorebi.json` static configuration file reference for `v0.1.35`
pub struct StaticConfig {
/// DEPRECATED from v0.1.22: no longer required
@@ -451,8 +449,7 @@ pub struct StaticConfig {
pub floating_window_aspect_ratio: Option<AspectRatio>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
pub struct AnimationsConfig {
/// Enable or disable animations (default: false)
pub enabled: PerAnimationPrefixConfig<bool>,
@@ -467,8 +464,7 @@ pub struct AnimationsConfig {
pub fps: Option<u64>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
#[serde(tag = "palette")]
pub enum KomorebiTheme {
/// A theme from catppuccin-egui
@@ -618,8 +614,7 @@ impl StaticConfig {
}
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
pub struct TabsConfig {
/// Width of a stackbar tab
#[serde(skip_serializing_if = "Option::is_none")]
@@ -641,8 +636,7 @@ pub struct TabsConfig {
pub font_size: Option<i32>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
pub struct StackbarConfig {
/// Stackbar height
#[serde(skip_serializing_if = "Option::is_none")]

View File

@@ -11,42 +11,13 @@ use crate::animation::ANIMATION_MANAGER;
use crate::animation::ANIMATION_STYLE_GLOBAL;
use crate::animation::ANIMATION_STYLE_PER_ANIMATION;
use crate::com::SetCloak;
use crate::core::config_generation::IdWithIdentifier;
use crate::core::config_generation::MatchingRule;
use crate::core::config_generation::MatchingStrategy;
use crate::core::ApplicationIdentifier;
use crate::core::HidingBehaviour;
use crate::core::Rect;
use crate::focus_manager;
use crate::stackbar_manager;
use crate::styles::ExtendedWindowStyle;
use crate::styles::WindowStyle;
use crate::transparency_manager;
use crate::window_manager_event::WindowManagerEvent;
use crate::windows_api;
use crate::windows_api::WindowsApi;
use crate::AnimationStyle;
use crate::FLOATING_APPLICATIONS;
use crate::FLOATING_WINDOW_TOGGLE_ASPECT_RATIO;
use crate::HIDDEN_HWNDS;
use crate::HIDING_BEHAVIOUR;
use crate::IGNORE_IDENTIFIERS;
use crate::LAYERED_WHITELIST;
use crate::MANAGE_IDENTIFIERS;
use crate::NO_TITLEBAR;
use crate::PERMAIGNORE_CLASSES;
use crate::REGEX_IDENTIFIERS;
use crate::SLOW_APPLICATION_COMPENSATION_TIME;
use crate::SLOW_APPLICATION_IDENTIFIERS;
use crate::WSL2_UI_PROCESSES;
use color_eyre::eyre;
use color_eyre::Result;
use crossbeam_utils::atomic::AtomicConsume;
use regex::Regex;
use serde::ser::SerializeStruct;
use serde::Deserialize;
use serde::Serialize;
use serde::Serializer;
use std::collections::HashMap;
use std::convert::TryFrom;
use std::fmt::Display;
@@ -56,15 +27,47 @@ use std::sync::atomic::AtomicI32;
use std::sync::atomic::Ordering;
use std::thread;
use std::time::Duration;
use crate::core::config_generation::IdWithIdentifier;
use crate::core::config_generation::MatchingRule;
use crate::core::config_generation::MatchingStrategy;
use color_eyre::eyre;
use color_eyre::Result;
use crossbeam_utils::atomic::AtomicConsume;
use regex::Regex;
use schemars::JsonSchema;
use serde::ser::SerializeStruct;
use serde::Deserialize;
use serde::Serialize;
use serde::Serializer;
use strum::Display;
use strum::EnumString;
use windows::Win32::Foundation::HWND;
use crate::core::ApplicationIdentifier;
use crate::core::HidingBehaviour;
use crate::core::Rect;
use crate::styles::ExtendedWindowStyle;
use crate::styles::WindowStyle;
use crate::transparency_manager;
use crate::window_manager_event::WindowManagerEvent;
use crate::windows_api::WindowsApi;
use crate::FLOATING_APPLICATIONS;
use crate::HIDDEN_HWNDS;
use crate::HIDING_BEHAVIOUR;
use crate::IGNORE_IDENTIFIERS;
use crate::LAYERED_WHITELIST;
use crate::MANAGE_IDENTIFIERS;
use crate::NO_TITLEBAR;
use crate::PERMAIGNORE_CLASSES;
use crate::REGEX_IDENTIFIERS;
use crate::WSL2_UI_PROCESSES;
pub static MINIMUM_WIDTH: AtomicI32 = AtomicI32::new(0);
pub static MINIMUM_HEIGHT: AtomicI32 = AtomicI32::new(0);
#[derive(Debug, Default, Clone, Copy, Deserialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Debug, Default, Clone, Copy, Deserialize, JsonSchema, PartialEq)]
pub struct Window {
pub hwnd: isize,
}
@@ -84,8 +87,7 @@ impl From<HWND> for Window {
}
#[allow(clippy::module_name_repetitions)]
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Debug, Clone, Serialize, JsonSchema)]
pub struct WindowDetails {
pub title: String,
pub exe: String,
@@ -297,8 +299,9 @@ impl RenderDispatcher for TransparencyRenderDispatcher {
}
}
#[derive(Copy, Clone, Debug, Display, EnumString, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(
Copy, Clone, Debug, Display, EnumString, Serialize, Deserialize, JsonSchema, PartialEq,
)]
#[serde(untagged)]
pub enum AspectRatio {
/// A predefined aspect ratio
@@ -313,8 +316,9 @@ impl Default for AspectRatio {
}
}
#[derive(Copy, Clone, Debug, Default, Display, EnumString, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(
Copy, Clone, Debug, Default, Display, EnumString, Serialize, Deserialize, JsonSchema, PartialEq,
)]
pub enum PredefinedAspectRatio {
/// 21:9
Ultrawide,

View File

@@ -19,6 +19,7 @@ use hotwatch::notify::ErrorKind as NotifyErrorKind;
use hotwatch::EventKind;
use hotwatch::Hotwatch;
use parking_lot::Mutex;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use uds_windows::UnixListener;
@@ -125,8 +126,7 @@ pub struct WindowManager {
}
#[allow(clippy::struct_excessive_bools)]
#[derive(Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct State {
pub monitors: Ring<Monitor>,
pub monitor_usr_idx_map: HashMap<usize, usize>,
@@ -191,8 +191,7 @@ impl State {
}
#[allow(clippy::struct_excessive_bools)]
#[derive(Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GlobalState {
pub border_enabled: bool,
pub border_colours: BorderColours,

View File

@@ -1,6 +1,7 @@
use std::fmt::Display;
use std::fmt::Formatter;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
@@ -11,8 +12,7 @@ use crate::OBJECT_NAME_CHANGE_ON_LAUNCH;
use crate::OBJECT_NAME_CHANGE_TITLE_IGNORE_LIST;
use crate::REGEX_IDENTIFIERS;
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Debug, Copy, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "type", content = "content")]
pub enum WindowManagerEvent {
Destroy(WinEvent, Window),

View File

@@ -1,5 +1,6 @@
#![allow(clippy::use_self)]
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use strum::Display;
@@ -88,8 +89,7 @@ use windows::Win32::UI::WindowsAndMessaging::EVENT_UIA_EVENTID_START;
use windows::Win32::UI::WindowsAndMessaging::EVENT_UIA_PROPID_END;
use windows::Win32::UI::WindowsAndMessaging::EVENT_UIA_PROPID_START;
#[derive(Clone, Copy, PartialEq, Eq, Debug, Serialize, Deserialize, Display)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Copy, PartialEq, Eq, Debug, Serialize, Deserialize, Display, JsonSchema)]
#[repr(u32)]
#[allow(dead_code)]
pub enum WinEvent {

View File

@@ -10,6 +10,7 @@ use getset::CopyGetters;
use getset::Getters;
use getset::MutGetters;
use getset::Setters;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
@@ -42,9 +43,17 @@ use crate::REMOVE_TITLEBARS;
#[allow(clippy::struct_field_names)]
#[derive(
Debug, Clone, Serialize, Deserialize, Getters, CopyGetters, MutGetters, Setters, PartialEq,
Debug,
Clone,
Serialize,
Deserialize,
Getters,
CopyGetters,
MutGetters,
Setters,
JsonSchema,
PartialEq,
)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct Workspace {
#[getset(get = "pub", set = "pub")]
pub name: Option<String>,
@@ -94,8 +103,7 @@ pub struct Workspace {
pub workspace_config: Option<WorkspaceConfig>,
}
#[derive(Debug, Default, Copy, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Debug, Default, Copy, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
pub enum WorkspaceLayer {
#[default]
Tiling,
@@ -161,9 +169,9 @@ pub enum WorkspaceWindowLocation {
CopyGetters,
MutGetters,
Setters,
JsonSchema,
PartialEq,
)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
/// Settings setup either by the parent monitor or by the `WindowManager`
pub struct WorkspaceGlobals {
pub container_padding: Option<i32>,

View File

@@ -21,7 +21,7 @@ miette = { version = "7", features = ["fancy"] }
paste = { workspace = true }
powershell_script = "1.0"
reqwest = { version = "0.12", features = ["blocking"] }
schemars = { workspace = true, optional = true }
schemars = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
shadow-rs = { workspace = true }
@@ -34,9 +34,5 @@ windows = { workspace = true }
reqwest = { version = "0.12", features = ["blocking"] }
shadow-rs = { workspace = true }
[features]
default = ["schemars"]
schemars = ["dep:schemars"]
[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(FALSE)'] }

View File

@@ -26,12 +26,15 @@ use komorebi_client::resolve_home_path;
use komorebi_client::send_message;
use komorebi_client::send_query;
use komorebi_client::ApplicationSpecificConfiguration;
use komorebi_client::Notification;
use lazy_static::lazy_static;
use miette::NamedSource;
use miette::Report;
use miette::SourceOffset;
use miette::SourceSpan;
use paste::paste;
use schemars::gen::SchemaSettings;
use schemars::schema_for;
use serde::Deserialize;
use sysinfo::ProcessesToUpdate;
use which::which;
@@ -2970,43 +2973,31 @@ if (Get-Command Get-CimInstance -ErrorAction SilentlyContinue) {
);
}
SubCommand::ApplicationSpecificConfigurationSchema => {
#[cfg(feature = "schemars")]
{
let asc = schemars::schema_for!(ApplicationSpecificConfiguration);
let schema = serde_json::to_string_pretty(&asc)?;
println!("{schema}");
}
let asc = schema_for!(ApplicationSpecificConfiguration);
let schema = serde_json::to_string_pretty(&asc)?;
println!("{schema}");
}
SubCommand::NotificationSchema => {
#[cfg(feature = "schemars")]
{
let notification = schemars::schema_for!(komorebi_client::Notification);
let schema = serde_json::to_string_pretty(&notification)?;
println!("{schema}");
}
let notification = schema_for!(Notification);
let schema = serde_json::to_string_pretty(&notification)?;
println!("{schema}");
}
SubCommand::SocketSchema => {
#[cfg(feature = "schemars")]
{
let socket_message = schemars::schema_for!(SocketMessage);
let schema = serde_json::to_string_pretty(&socket_message)?;
println!("{schema}");
}
let socket_message = schema_for!(SocketMessage);
let schema = serde_json::to_string_pretty(&socket_message)?;
println!("{schema}");
}
SubCommand::StaticConfigSchema => {
#[cfg(feature = "schemars")]
{
let settings = schemars::gen::SchemaSettings::default().with(|s| {
s.option_nullable = false;
s.option_add_null_type = false;
s.inline_subschemas = true;
});
let settings = SchemaSettings::default().with(|s| {
s.option_nullable = false;
s.option_add_null_type = false;
s.inline_subschemas = true;
});
let gen = settings.into_generator();
let socket_message = gen.into_root_schema_for::<StaticConfig>();
let schema = serde_json::to_string_pretty(&socket_message)?;
println!("{schema}");
}
let gen = settings.into_generator();
let socket_message = gen.into_root_schema_for::<StaticConfig>();
let schema = serde_json::to_string_pretty(&socket_message)?;
println!("{schema}");
}
SubCommand::GenerateStaticConfig => {
print_query(&SocketMessage::GenerateStaticConfig);