Files
komorebi/komorebi-core/src/lib.rs
LGUG2Z 1eba8aa01d feat(wm): add workspace rules
This feature allows users to specify which monitor/workspace an
application's window, identified either by executable name or window
class name, should be assigned to.

A new fn, WindowManager.enforce_workspace_rules, is called whenever a
new rule is added, and periodically whenever an event is processed by
komorebi (just after orphan windows are repead, before the matching and
processing of the specific event).

Both class and exe identifiers are stored in the same HashMap for the
sake of simplicity, as I couldn't think of any situations where there
might be a clash between the two identifiers.

Did some light refactoring of window_manager.rs to make the new()
constructor a static method on the WindowManager struct.

Also fixed a bug in Workspace.new_container_for_window where the focused
index was not getting set correctly when the workspace had no
containers.
2021-08-19 08:19:34 -07:00

114 lines
2.9 KiB
Rust

use std::str::FromStr;
use clap::ArgEnum;
use color_eyre::Result;
use serde::Deserialize;
use serde::Serialize;
use strum::Display;
use strum::EnumString;
pub use cycle_direction::CycleDirection;
pub use layout::Layout;
pub use layout::LayoutFlip;
pub use operation_direction::OperationDirection;
pub use rect::Rect;
pub mod cycle_direction;
pub mod layout;
pub mod operation_direction;
pub mod rect;
#[derive(Clone, Debug, Serialize, Deserialize, Display)]
pub enum SocketMessage {
// Window / Container Commands
FocusWindow(OperationDirection),
MoveWindow(OperationDirection),
StackWindow(OperationDirection),
ResizeWindow(OperationDirection, Sizing),
UnstackWindow,
CycleStack(CycleDirection),
MoveContainerToMonitorNumber(usize),
MoveContainerToWorkspaceNumber(usize),
Promote,
ToggleFloat,
ToggleMonocle,
ToggleMaximize,
// Current Workspace Commands
AdjustContainerPadding(Sizing, i32),
AdjustWorkspacePadding(Sizing, i32),
ChangeLayout(Layout),
FlipLayout(LayoutFlip),
// Monitor and Workspace Commands
EnsureWorkspaces(usize, usize),
NewWorkspace,
ToggleTiling,
Stop,
TogglePause,
Retile,
FocusMonitorNumber(usize),
FocusWorkspaceNumber(usize),
ContainerPadding(usize, usize, i32),
WorkspacePadding(usize, usize, i32),
WorkspaceTiling(usize, usize, bool),
WorkspaceName(usize, usize, String),
WorkspaceLayout(usize, usize, Layout),
// Configuration
ReloadConfiguration,
WatchConfiguration(bool),
FloatClass(String),
FloatExe(String),
FloatTitle(String),
WorkspaceRule(ApplicationIdentifier, String, usize, usize),
IdentifyTrayApplication(ApplicationIdentifier, String),
State,
FocusFollowsMouse(bool),
}
impl SocketMessage {
pub fn as_bytes(&self) -> Result<Vec<u8>> {
Ok(serde_json::to_string(self)?.as_bytes().to_vec())
}
pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
Ok(serde_json::from_slice(bytes)?)
}
}
impl FromStr for SocketMessage {
type Err = serde_json::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
serde_json::from_str(s)
}
}
#[derive(Clone, Debug, Serialize, Deserialize, Display, EnumString, ArgEnum)]
#[strum(serialize_all = "snake_case")]
pub enum ApplicationIdentifier {
Exe,
Class,
Title,
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ArgEnum)]
#[strum(serialize_all = "snake_case")]
pub enum Sizing {
Increase,
Decrease,
}
impl Sizing {
pub fn adjust_by(&self, value: i32, adjustment: i32) -> i32 {
match self {
Sizing::Increase => value + adjustment,
Sizing::Decrease => {
if value > 0 && value - adjustment >= 0 {
value - adjustment
} else {
value
}
}
}
}
}