Files
komorebi/komorebi/src/window_manager_event.rs
LGUG2Z b048e7c3aa feat(rules): implement all matching strategies
This commit ensures that matching strategies can be used wherever
IdWithIdentifier is used, and that they are respected for users opting
to use the static configuration file format.

Some thought and planning needs to go into how this can be backported to
dynamic configurations via the CLI without breaking existing user
configurations.

re #60
2023-10-06 12:14:58 -07:00

160 lines
5.9 KiB
Rust

use std::fmt::Display;
use std::fmt::Formatter;
use schemars::JsonSchema;
use serde::Serialize;
use crate::window::should_act;
use crate::window::Window;
use crate::winevent::WinEvent;
use crate::OBJECT_NAME_CHANGE_ON_LAUNCH;
use crate::REGEX_IDENTIFIERS;
#[derive(Debug, Copy, Clone, Serialize, JsonSchema)]
#[serde(tag = "type", content = "content")]
pub enum WindowManagerEvent {
Destroy(WinEvent, Window),
FocusChange(WinEvent, Window),
Hide(WinEvent, Window),
Cloak(WinEvent, Window),
Minimize(WinEvent, Window),
Show(WinEvent, Window),
Uncloak(WinEvent, Window),
MoveResizeStart(WinEvent, Window),
MoveResizeEnd(WinEvent, Window),
MouseCapture(WinEvent, Window),
Manage(Window),
Unmanage(Window),
Raise(Window),
DisplayChange(Window),
}
impl Display for WindowManagerEvent {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Self::Manage(window) => {
write!(f, "Manage (Window: {window})")
}
Self::Unmanage(window) => {
write!(f, "Unmanage (Window: {window})")
}
Self::Destroy(winevent, window) => {
write!(f, "Destroy (WinEvent: {winevent}, Window: {window})")
}
Self::FocusChange(winevent, window) => {
write!(f, "FocusChange (WinEvent: {winevent}, Window: {window})",)
}
Self::Hide(winevent, window) => {
write!(f, "Hide (WinEvent: {winevent}, Window: {window})")
}
Self::Cloak(winevent, window) => {
write!(f, "Cloak (WinEvent: {winevent}, Window: {window})")
}
Self::Minimize(winevent, window) => {
write!(f, "Minimize (WinEvent: {winevent}, Window: {window})")
}
Self::Show(winevent, window) => {
write!(f, "Show (WinEvent: {winevent}, Window: {window})")
}
Self::Uncloak(winevent, window) => {
write!(f, "Uncloak (WinEvent: {winevent}, Window: {window})")
}
Self::MoveResizeStart(winevent, window) => {
write!(
f,
"MoveResizeStart (WinEvent: {winevent}, Window: {window})",
)
}
Self::MoveResizeEnd(winevent, window) => {
write!(f, "MoveResizeEnd (WinEvent: {winevent}, Window: {window})",)
}
Self::MouseCapture(winevent, window) => {
write!(f, "MouseCapture (WinEvent: {winevent}, Window: {window})",)
}
Self::Raise(window) => {
write!(f, "Raise (Window: {window})")
}
Self::DisplayChange(window) => {
write!(f, "DisplayChange (Window: {window})")
}
}
}
}
impl WindowManagerEvent {
pub const fn window(self) -> Window {
match self {
Self::Destroy(_, window)
| Self::FocusChange(_, window)
| Self::Hide(_, window)
| Self::Cloak(_, window)
| Self::Minimize(_, window)
| Self::Show(_, window)
| Self::Uncloak(_, window)
| Self::MoveResizeStart(_, window)
| Self::MoveResizeEnd(_, window)
| Self::MouseCapture(_, window)
| Self::Raise(window)
| Self::Manage(window)
| Self::DisplayChange(window)
| Self::Unmanage(window) => window,
}
}
pub fn from_win_event(winevent: WinEvent, window: Window) -> Option<Self> {
match winevent {
WinEvent::ObjectDestroy => Option::from(Self::Destroy(winevent, window)),
WinEvent::ObjectHide => Option::from(Self::Hide(winevent, window)),
WinEvent::ObjectCloaked => Option::from(Self::Cloak(winevent, window)),
WinEvent::SystemMinimizeStart => Option::from(Self::Minimize(winevent, window)),
WinEvent::ObjectShow | WinEvent::SystemMinimizeEnd => {
Option::from(Self::Show(winevent, window))
}
WinEvent::ObjectUncloaked => Option::from(Self::Uncloak(winevent, window)),
WinEvent::ObjectFocus | WinEvent::SystemForeground => {
Option::from(Self::FocusChange(winevent, window))
}
WinEvent::SystemMoveSizeStart => Option::from(Self::MoveResizeStart(winevent, window)),
WinEvent::SystemMoveSizeEnd => Option::from(Self::MoveResizeEnd(winevent, window)),
WinEvent::SystemCaptureStart | WinEvent::SystemCaptureEnd => {
Option::from(Self::MouseCapture(winevent, window))
}
WinEvent::ObjectNameChange => {
// Some apps like Firefox don't send ObjectCreate or ObjectShow on launch
// This spams the message queue, but I don't know what else to do. On launch
// it only sends the following WinEvents :/
//
// [yatta\src\windows_event.rs:110] event = 32780 ObjectNameChange
// [yatta\src\windows_event.rs:110] event = 32779 ObjectLocationChange
let object_name_change_on_launch = OBJECT_NAME_CHANGE_ON_LAUNCH.lock();
let regex_identifiers = REGEX_IDENTIFIERS.lock();
let title = &window.title().ok()?;
let exe_name = &window.exe().ok()?;
let class = &window.class().ok()?;
let should_trigger = should_act(
title,
exe_name,
class,
&object_name_change_on_launch,
&regex_identifiers,
);
if should_trigger {
Option::from(Self::Show(winevent, window))
} else {
None
}
}
_ => None,
}
}
}