From 4e9b2948350e10e85c52b9b36d8984b56a59cb63 Mon Sep 17 00:00:00 2001 From: LGUG2Z Date: Thu, 19 Aug 2021 14:34:59 -0700 Subject: [PATCH] feat(wm): add additional manage rules Following on from 8ffe6f78b7c2a41d1bbe7768c595ca7bf5e41570, this commit introduces a command to add rules to forcibly manage windows that don't get picked up by the rough heuristics that are able to target most windows for management in Window.should_manage. Since there is again no overlap (or at least, no undesired overlap) between executable names and classes, I'll keep both class and exe names in a single lookup vec. re #16 --- README.md | 4 ++++ komorebi-core/src/lib.rs | 1 + komorebi/src/main.rs | 1 + komorebi/src/process_command.rs | 14 ++++++++++++++ komorebi/src/window.rs | 16 +++++++++------- komorebic/src/main.rs | 6 ++++++ 6 files changed, 35 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e61d8608..2f08c713 100644 --- a/README.md +++ b/README.md @@ -179,9 +179,12 @@ toggle-float Toggle floating mode for the focused window toggle-monocle Toggle monocle mode for the focused container toggle-maximize Toggle native maximization for the focused window restore-windows Restore all hidden windows (debugging command) +manage Force komorebi to manage the focused window +unmanage Unmanage a window that was forcibly managed reload-configuration Reload ~/komorebi.ahk (if it exists) watch-configuration Toggle the automatic reloading of ~/komorebi.ahk (if it exists) float-rule Add a rule to always float the specified application +manage-rule Add a rule to always manage the specified application workspace-rule Add a rule to associate an application with a workspace identify-tray-application Identify an application that closes to the system tray focus-follows-mouse Enable or disable focus follows mouse for the operating system @@ -209,6 +212,7 @@ help Print this message or the help of the given subcomm - [x] Equal-width, max-height column layout - [x] Floating rules based on exe name, window title and class - [x] Workspace rules based on exe name and window class +- [x] Additional manage rules based on exe name and window class - [x] Identify 'close/minimize to tray' applications by exe name and class - [x] Toggle floating windows - [x] Toggle monocle window diff --git a/komorebi-core/src/lib.rs b/komorebi-core/src/lib.rs index 6f785edd..c541fab2 100644 --- a/komorebi-core/src/lib.rs +++ b/komorebi-core/src/lib.rs @@ -61,6 +61,7 @@ pub enum SocketMessage { FloatExe(String), FloatTitle(String), WorkspaceRule(ApplicationIdentifier, String, usize, usize), + ManageRule(ApplicationIdentifier, String), IdentifyTrayApplication(ApplicationIdentifier, String), State, FocusFollowsMouse(bool), diff --git a/komorebi/src/main.rs b/komorebi/src/main.rs index a9c3c2c9..5d4dd7df 100644 --- a/komorebi/src/main.rs +++ b/komorebi/src/main.rs @@ -70,6 +70,7 @@ lazy_static! { ])); static ref WORKSPACE_RULES: Arc>> = Arc::new(Mutex::new(HashMap::new())); + static ref MANAGE_IDENTIFIERS: Arc>> = Arc::new(Mutex::new(vec![])); } fn setup() -> Result<(WorkerGuard, WorkerGuard)> { diff --git a/komorebi/src/process_command.rs b/komorebi/src/process_command.rs index 46146e99..c6eafa02 100644 --- a/komorebi/src/process_command.rs +++ b/komorebi/src/process_command.rs @@ -19,6 +19,7 @@ use crate::windows_api::WindowsApi; use crate::FLOAT_CLASSES; use crate::FLOAT_EXES; use crate::FLOAT_TITLES; +use crate::MANAGE_IDENTIFIERS; use crate::TRAY_AND_MULTI_WINDOW_CLASSES; use crate::TRAY_AND_MULTI_WINDOW_EXES; use crate::WORKSPACE_RULES; @@ -116,6 +117,19 @@ impl WindowManager { ApplicationIdentifier::Title => {} } } + SocketMessage::ManageRule(identifier, id) => match identifier { + ApplicationIdentifier::Exe | ApplicationIdentifier::Class => { + { + let mut manage_identifiers = MANAGE_IDENTIFIERS.lock(); + if !manage_identifiers.contains(&id) { + manage_identifiers.push(id); + } + } + + self.update_focused_workspace(false)?; + } + ApplicationIdentifier::Title => {} + }, SocketMessage::AdjustContainerPadding(sizing, adjustment) => { self.adjust_container_padding(sizing, adjustment)?; } diff --git a/komorebi/src/window.rs b/komorebi/src/window.rs index 5c30b940..cc88325a 100644 --- a/komorebi/src/window.rs +++ b/komorebi/src/window.rs @@ -20,6 +20,7 @@ use crate::FLOAT_EXES; use crate::FLOAT_TITLES; use crate::HIDDEN_HWNDS; use crate::LAYERED_EXE_WHITELIST; +use crate::MANAGE_IDENTIFIERS; #[derive(Debug, Clone, Copy)] pub struct Window { @@ -219,9 +220,9 @@ impl Window { #[tracing::instrument(fields(exe, title))] pub fn should_manage(self, event: Option) -> Result { - let classes = FLOAT_CLASSES.lock(); - let exes = FLOAT_EXES.lock(); - let titles = FLOAT_TITLES.lock(); + let float_classes = FLOAT_CLASSES.lock(); + let float_exes = FLOAT_EXES.lock(); + let float_titles = FLOAT_TITLES.lock(); if self.title().is_err() { return Ok(false); @@ -239,17 +240,17 @@ impl Window { (true, _) | // If not allowing cloaked windows, we need to ensure the window is not cloaked (false, false) => { - if let (Ok(title), Ok(exe_name)) = (self.title(), self.exe()) { - if titles.contains(&title) { + if let (Ok(title), Ok(exe_name), Ok(class)) = (self.title(), self.exe(), self.class()) { + if float_titles.contains(&title) { return Ok(false); } - if exes.contains(&exe_name) { + if float_exes.contains(&exe_name) { return Ok(false); } if let Ok(class) = self.class() { - if classes.contains(&class) { + if float_classes.contains(&class) { return Ok(false); } } @@ -267,6 +268,7 @@ impl Window { // allowing a specific layered window on the whitelist (like Steam), it should // pass this check && (allow_layered || !ex_style.contains(GwlExStyle::LAYERED)) + || MANAGE_IDENTIFIERS.lock().contains(&exe_name) || MANAGE_IDENTIFIERS.lock().contains(&class) { Ok(true) } else { diff --git a/komorebic/src/main.rs b/komorebic/src/main.rs index 2701688f..48ac32c0 100644 --- a/komorebic/src/main.rs +++ b/komorebic/src/main.rs @@ -281,6 +281,9 @@ enum SubCommand { /// Add a rule to always float the specified application #[clap(setting = AppSettings::ArgRequiredElseHelp)] FloatRule(ApplicationTarget), + /// Add a rule to always manage the specified application + #[clap(setting = AppSettings::ArgRequiredElseHelp)] + ManageRule(ApplicationTarget), /// Add a rule to associate an application with a workspace #[clap(setting = AppSettings::ArgRequiredElseHelp)] WorkspaceRule(WorkspaceRule), @@ -432,6 +435,9 @@ fn main() -> Result<()> { send_message(&*SocketMessage::FloatTitle(arg.id).as_bytes()?)?; } }, + SubCommand::ManageRule(arg) => { + send_message(&*SocketMessage::ManageRule(arg.identifier, arg.id).as_bytes()?)?; + } SubCommand::WorkspaceRule(arg) => { send_message( &*SocketMessage::WorkspaceRule(arg.identifier, arg.id, arg.monitor, arg.workspace)