From b048e7c3aa0d4f9075fd725e39a80ab7687a18e7 Mon Sep 17 00:00:00 2001 From: LGUG2Z Date: Fri, 6 Oct 2023 12:14:55 -0700 Subject: [PATCH] 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 --- Cargo.lock | 1 + komorebi.generated.ahk | 74 ++++++++- komorebi.generated.ps1 | 74 ++++++++- komorebi/Cargo.toml | 1 + komorebi/src/border.rs | 23 ++- komorebi/src/main.rs | 68 ++++++-- komorebi/src/process_command.rs | 89 ++++++++-- komorebi/src/process_event.rs | 21 ++- komorebi/src/static_config.rs | 182 ++++++++++++++++---- komorebi/src/window.rs | 239 +++++++++++++++++++-------- komorebi/src/window_manager.rs | 10 +- komorebi/src/window_manager_event.rs | 20 ++- 12 files changed, 654 insertions(+), 148 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2f13512b4..00bd202df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -813,6 +813,7 @@ dependencies = [ "os_info", "parking_lot", "paste", + "regex", "schemars", "serde", "serde_json", diff --git a/komorebi.generated.ahk b/komorebi.generated.ahk index 79ca7717d..aeb8fcbc7 100644 --- a/komorebi.generated.ahk +++ b/komorebi.generated.ahk @@ -27,6 +27,10 @@ RunWait('komorebic.exe identify-tray-application exe "Akiflow.exe"', , "Hide") ; Android Studio RunWait('komorebic.exe identify-object-name-change-application exe "studio64.exe"', , "Hide") +; Anki +; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line +RunWait('komorebic.exe identify-tray-application exe "anki.exe"', , "Hide") + ; ArmCord RunWait('komorebic.exe identify-border-overflow-application exe "ArmCord.exe"', , "Hide") ; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line @@ -36,6 +40,7 @@ RunWait('komorebic.exe identify-tray-application exe "ArmCord.exe"', , "Hide") ; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line RunWait('komorebic.exe identify-tray-application exe "AutoHotkeyU64.exe"', , "Hide") RunWait('komorebic.exe float-rule title "Window Spy"', , "Hide") +RunWait('komorebic.exe float-rule exe "AutoHotkeyUX.exe"', , "Hide") ; Beeper RunWait('komorebic.exe identify-border-overflow-application exe "Beeper.exe"', , "Hide") @@ -52,6 +57,19 @@ RunWait('komorebic.exe float-rule exe "Bloxstrap.exe"', , "Hide") ; Calculator RunWait('komorebic.exe float-rule title "Calculator"', , "Hide") +; Clash Verge +RunWait('komorebic.exe identify-border-overflow-application exe "Clash Verge.exe"', , "Hide") +; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line +RunWait('komorebic.exe identify-tray-application exe "Clash Verge.exe"', , "Hide") + +; Clementine +; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line +RunWait('komorebic.exe identify-tray-application exe "clementine.exe"', , "Hide") + +; CopyQ +; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line +RunWait('komorebic.exe identify-tray-application exe "copyq.exe"', , "Hide") + ; Credential Manager UI Host ; Targets the Windows popup prompting you for a PIN instead of a password on 1Password etc. RunWait('komorebic.exe float-rule exe "CredentialUIBroker.exe"', , "Hide") @@ -91,6 +109,9 @@ RunWait('komorebic.exe identify-border-overflow-application exe "DiscordPTB.exe" ; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line RunWait('komorebic.exe identify-tray-application exe "DiscordPTB.exe"', , "Hide") +; Docker Desktop +RunWait('komorebic.exe identify-border-overflow-application exe "Docker Desktop.exe"', , "Hide") + ; Dropbox RunWait('komorebic.exe float-rule exe "Dropbox.exe"', , "Hide") @@ -123,6 +144,13 @@ RunWait('komorebic.exe identify-border-overflow-application exe "EpicGamesLaunch ; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line RunWait('komorebic.exe identify-tray-application exe "EpicGamesLauncher.exe"', , "Hide") +; Everything +; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line +RunWait('komorebic.exe identify-tray-application exe "Everything.exe"', , "Hide") + +; Figma +RunWait('komorebic.exe identify-border-overflow-application exe "Figma.exe"', , "Hide") + ; Flow Launcher RunWait('komorebic.exe identify-border-overflow-application exe "Flow.Launcher.exe"', , "Hide") @@ -143,11 +171,17 @@ RunWait('komorebic.exe identify-border-overflow-application exe "GodotManager.ex RunWait('komorebic.exe manage-rule exe "GodotManager.exe"', , "Hide") RunWait('komorebic.exe identify-object-name-change-application exe "GodotManager.exe"', , "Hide") +; Golden Dict +; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line +RunWait('komorebic.exe identify-tray-application exe "GoldenDict.exe"', , "Hide") + ; Google Chrome ; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line RunWait('komorebic.exe identify-tray-application exe "chrome.exe"', , "Hide") ; Google Drive +; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line +RunWait('komorebic.exe identify-tray-application exe "GoogleDriveFS.exe"', , "Hide") RunWait('komorebic.exe float-rule exe "GoogleDriveFS.exe"', , "Hide") ; Houdoku @@ -256,6 +290,10 @@ RunWait('komorebic.exe identify-border-overflow-application exe "NVIDIA GeForce ; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line RunWait('komorebic.exe identify-tray-application exe "NZXT CAM.exe"', , "Hide") +; NetEase Cloud Music +; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line +RunWait('komorebic.exe identify-tray-application exe "cloudmusic.exe"', , "Hide") + ; NiceHash Miner RunWait('komorebic.exe identify-border-overflow-application exe "nhm_app.exe"', , "Hide") RunWait('komorebic.exe manage-rule exe "nhm_app.exe"', , "Hide") @@ -288,6 +326,10 @@ RunWait('komorebic.exe manage-rule exe "Obsidian.exe"', , "Hide") ; OneDrive RunWait('komorebic.exe float-rule class "OneDriveReactNativeWin32WindowClass"', , "Hide") +; OneQuick +; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line +RunWait('komorebic.exe identify-tray-application exe "OneQuick.exe"', , "Hide") + ; OpenRGB ; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line RunWait('komorebic.exe identify-tray-application exe "OpenRGB.exe"', , "Hide") @@ -295,6 +337,13 @@ RunWait('komorebic.exe identify-tray-application exe "OpenRGB.exe"', , "Hide") ; Paradox Launcher RunWait('komorebic.exe float-rule exe "Paradox Launcher.exe"', , "Hide") +; Playnite +RunWait('komorebic.exe identify-border-overflow-application exe "Playnite.DesktopApp.exe"', , "Hide") +; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line +RunWait('komorebic.exe identify-tray-application exe "Playnite.DesktopApp.exe"', , "Hide") +; Target fullscreen app +RunWait('komorebic.exe float-rule exe "Playnite.FullscreenApp.exe"', , "Hide") + ; Plexamp RunWait('komorebic.exe identify-border-overflow-application exe "Plexamp.exe"', , "Hide") @@ -321,6 +370,13 @@ RunWait('komorebic.exe identify-object-name-change-application exe "pycharm64.ex ; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line RunWait('komorebic.exe identify-tray-application exe "pycharm64.exe"', , "Hide") +; QQ +; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line +RunWait('komorebic.exe identify-tray-application exe "QQ.exe"', , "Hide") +RunWait('komorebic.exe float-rule title "图片查看器"', , "Hide") +RunWait('komorebic.exe float-rule title "群聊的聊天记录"', , "Hide") +RunWait('komorebic.exe float-rule title "语音通话"', , "Hide") + ; QtScrcpy ; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line RunWait('komorebic.exe identify-tray-application exe "QtScrcpy.exe"', , "Hide") @@ -348,6 +404,15 @@ RunWait('komorebic.exe identify-border-overflow-application exe "RoundedTB.exe"' ; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line RunWait('komorebic.exe identify-tray-application exe "RoundedTB.exe"', , "Hide") +; RustRover +RunWait('komorebic.exe identify-object-name-change-application exe "rustrover64.exe"', , "Hide") +; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line +RunWait('komorebic.exe identify-tray-application exe "rustrover64.exe"', , "Hide") + +; Sandboxie Plus +; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line +RunWait('komorebic.exe identify-tray-application exe "SandMan.exe"', , "Hide") + ; ShareX RunWait('komorebic.exe identify-border-overflow-application exe "ShareX.exe"', , "Hide") ; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line @@ -358,7 +423,7 @@ RunWait('komorebic.exe float-rule exe "sideloadly.exe"', , "Hide") ; Signal ; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line -RunWait('komorebic.exe identify-tray-application exe "signal.exe"', , "Hide") +RunWait('komorebic.exe identify-tray-application exe "Signal.exe"', , "Hide") ; SiriKali ; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line @@ -484,6 +549,10 @@ RunWait('komorebic.exe float-rule title "Control Panel"', , "Hide") ; Windows Installer RunWait('komorebic.exe float-rule exe "msiexec.exe"', , "Hide") +; Windows Subsystem for Android +; Targets splash/startup screen +RunWait('komorebic.exe float-rule class "android(splash)"', , "Hide") + ; WingetUI ; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line RunWait('komorebic.exe identify-tray-application exe "WingetUI.exe"', , "Hide") @@ -503,6 +572,9 @@ RunWait('komorebic.exe identify-tray-application exe "xampp-control.exe"', , "Hi ; Zoom RunWait('komorebic.exe float-rule exe "Zoom.exe"', , "Hide") +; mpv +RunWait('komorebic.exe identify-object-name-change-application class "mpv"', , "Hide") + ; mpv.net RunWait('komorebic.exe identify-object-name-change-application exe "mpvnet.exe"', , "Hide") diff --git a/komorebi.generated.ps1 b/komorebi.generated.ps1 index b3046c46e..8787a5c4b 100644 --- a/komorebi.generated.ps1 +++ b/komorebi.generated.ps1 @@ -27,6 +27,10 @@ komorebic.exe identify-tray-application exe "Akiflow.exe" # Android Studio komorebic.exe identify-object-name-change-application exe "studio64.exe" +# Anki +# If you have disabled minimize/close to tray for this application, you can delete/comment out the next line +komorebic.exe identify-tray-application exe "anki.exe" + # ArmCord komorebic.exe identify-border-overflow-application exe "ArmCord.exe" # If you have disabled minimize/close to tray for this application, you can delete/comment out the next line @@ -36,6 +40,7 @@ komorebic.exe identify-tray-application exe "ArmCord.exe" # If you have disabled minimize/close to tray for this application, you can delete/comment out the next line komorebic.exe identify-tray-application exe "AutoHotkeyU64.exe" komorebic.exe float-rule title "Window Spy" +komorebic.exe float-rule exe "AutoHotkeyUX.exe" # Beeper komorebic.exe identify-border-overflow-application exe "Beeper.exe" @@ -52,6 +57,19 @@ komorebic.exe float-rule exe "Bloxstrap.exe" # Calculator komorebic.exe float-rule title "Calculator" +# Clash Verge +komorebic.exe identify-border-overflow-application exe "Clash Verge.exe" +# If you have disabled minimize/close to tray for this application, you can delete/comment out the next line +komorebic.exe identify-tray-application exe "Clash Verge.exe" + +# Clementine +# If you have disabled minimize/close to tray for this application, you can delete/comment out the next line +komorebic.exe identify-tray-application exe "clementine.exe" + +# CopyQ +# If you have disabled minimize/close to tray for this application, you can delete/comment out the next line +komorebic.exe identify-tray-application exe "copyq.exe" + # Credential Manager UI Host # Targets the Windows popup prompting you for a PIN instead of a password on 1Password etc. komorebic.exe float-rule exe "CredentialUIBroker.exe" @@ -91,6 +109,9 @@ komorebic.exe identify-border-overflow-application exe "DiscordPTB.exe" # If you have disabled minimize/close to tray for this application, you can delete/comment out the next line komorebic.exe identify-tray-application exe "DiscordPTB.exe" +# Docker Desktop +komorebic.exe identify-border-overflow-application exe "Docker Desktop.exe" + # Dropbox komorebic.exe float-rule exe "Dropbox.exe" @@ -123,6 +144,13 @@ komorebic.exe identify-border-overflow-application exe "EpicGamesLauncher.exe" # If you have disabled minimize/close to tray for this application, you can delete/comment out the next line komorebic.exe identify-tray-application exe "EpicGamesLauncher.exe" +# Everything +# If you have disabled minimize/close to tray for this application, you can delete/comment out the next line +komorebic.exe identify-tray-application exe "Everything.exe" + +# Figma +komorebic.exe identify-border-overflow-application exe "Figma.exe" + # Flow Launcher komorebic.exe identify-border-overflow-application exe "Flow.Launcher.exe" @@ -143,11 +171,17 @@ komorebic.exe identify-border-overflow-application exe "GodotManager.exe" komorebic.exe manage-rule exe "GodotManager.exe" komorebic.exe identify-object-name-change-application exe "GodotManager.exe" +# Golden Dict +# If you have disabled minimize/close to tray for this application, you can delete/comment out the next line +komorebic.exe identify-tray-application exe "GoldenDict.exe" + # Google Chrome # If you have disabled minimize/close to tray for this application, you can delete/comment out the next line komorebic.exe identify-tray-application exe "chrome.exe" # Google Drive +# If you have disabled minimize/close to tray for this application, you can delete/comment out the next line +komorebic.exe identify-tray-application exe "GoogleDriveFS.exe" komorebic.exe float-rule exe "GoogleDriveFS.exe" # Houdoku @@ -256,6 +290,10 @@ komorebic.exe identify-border-overflow-application exe "NVIDIA GeForce Experienc # If you have disabled minimize/close to tray for this application, you can delete/comment out the next line komorebic.exe identify-tray-application exe "NZXT CAM.exe" +# NetEase Cloud Music +# If you have disabled minimize/close to tray for this application, you can delete/comment out the next line +komorebic.exe identify-tray-application exe "cloudmusic.exe" + # NiceHash Miner komorebic.exe identify-border-overflow-application exe "nhm_app.exe" komorebic.exe manage-rule exe "nhm_app.exe" @@ -288,6 +326,10 @@ komorebic.exe manage-rule exe "Obsidian.exe" # OneDrive komorebic.exe float-rule class "OneDriveReactNativeWin32WindowClass" +# OneQuick +# If you have disabled minimize/close to tray for this application, you can delete/comment out the next line +komorebic.exe identify-tray-application exe "OneQuick.exe" + # OpenRGB # If you have disabled minimize/close to tray for this application, you can delete/comment out the next line komorebic.exe identify-tray-application exe "OpenRGB.exe" @@ -295,6 +337,13 @@ komorebic.exe identify-tray-application exe "OpenRGB.exe" # Paradox Launcher komorebic.exe float-rule exe "Paradox Launcher.exe" +# Playnite +komorebic.exe identify-border-overflow-application exe "Playnite.DesktopApp.exe" +# If you have disabled minimize/close to tray for this application, you can delete/comment out the next line +komorebic.exe identify-tray-application exe "Playnite.DesktopApp.exe" +# Target fullscreen app +komorebic.exe float-rule exe "Playnite.FullscreenApp.exe" + # Plexamp komorebic.exe identify-border-overflow-application exe "Plexamp.exe" @@ -321,6 +370,13 @@ komorebic.exe identify-object-name-change-application exe "pycharm64.exe" # If you have disabled minimize/close to tray for this application, you can delete/comment out the next line komorebic.exe identify-tray-application exe "pycharm64.exe" +# QQ +# If you have disabled minimize/close to tray for this application, you can delete/comment out the next line +komorebic.exe identify-tray-application exe "QQ.exe" +komorebic.exe float-rule title "图片查看器" +komorebic.exe float-rule title "群聊的聊天记录" +komorebic.exe float-rule title "语音通话" + # QtScrcpy # If you have disabled minimize/close to tray for this application, you can delete/comment out the next line komorebic.exe identify-tray-application exe "QtScrcpy.exe" @@ -348,6 +404,15 @@ komorebic.exe identify-border-overflow-application exe "RoundedTB.exe" # If you have disabled minimize/close to tray for this application, you can delete/comment out the next line komorebic.exe identify-tray-application exe "RoundedTB.exe" +# RustRover +komorebic.exe identify-object-name-change-application exe "rustrover64.exe" +# If you have disabled minimize/close to tray for this application, you can delete/comment out the next line +komorebic.exe identify-tray-application exe "rustrover64.exe" + +# Sandboxie Plus +# If you have disabled minimize/close to tray for this application, you can delete/comment out the next line +komorebic.exe identify-tray-application exe "SandMan.exe" + # ShareX komorebic.exe identify-border-overflow-application exe "ShareX.exe" # If you have disabled minimize/close to tray for this application, you can delete/comment out the next line @@ -358,7 +423,7 @@ komorebic.exe float-rule exe "sideloadly.exe" # Signal # If you have disabled minimize/close to tray for this application, you can delete/comment out the next line -komorebic.exe identify-tray-application exe "signal.exe" +komorebic.exe identify-tray-application exe "Signal.exe" # SiriKali # If you have disabled minimize/close to tray for this application, you can delete/comment out the next line @@ -484,6 +549,10 @@ komorebic.exe float-rule title "Control Panel" # Windows Installer komorebic.exe float-rule exe "msiexec.exe" +# Windows Subsystem for Android +# Targets splash/startup screen +komorebic.exe float-rule class "android(splash)" + # WingetUI # If you have disabled minimize/close to tray for this application, you can delete/comment out the next line komorebic.exe identify-tray-application exe "WingetUI.exe" @@ -503,6 +572,9 @@ komorebic.exe identify-tray-application exe "xampp-control.exe" # Zoom komorebic.exe float-rule exe "Zoom.exe" +# mpv +komorebic.exe identify-object-name-change-application class "mpv" + # mpv.net komorebic.exe identify-object-name-change-application exe "mpvnet.exe" diff --git a/komorebi/Cargo.toml b/komorebi/Cargo.toml index 08162b4f1..206bf4168 100644 --- a/komorebi/Cargo.toml +++ b/komorebi/Cargo.toml @@ -29,6 +29,7 @@ net2 = "0.2" os_info = "3.7" parking_lot = { version = "0.12", features = ["deadlock_detection"] } paste = "1" +regex = "1" schemars = "0.8" serde = { version = "1", features = ["derive"] } serde_json = "1" diff --git a/komorebi/src/border.rs b/komorebi/src/border.rs index f39bd5c68..466cf8ca4 100644 --- a/komorebi/src/border.rs +++ b/komorebi/src/border.rs @@ -14,6 +14,7 @@ use windows::Win32::UI::WindowsAndMessaging::WNDCLASSA; use komorebi_core::Rect; +use crate::window::should_act; use crate::window::Window; use crate::windows_callbacks; use crate::WindowsApi; @@ -21,6 +22,7 @@ use crate::BORDER_HWND; use crate::BORDER_OFFSET; use crate::BORDER_OVERFLOW_IDENTIFIERS; use crate::BORDER_RECT; +use crate::REGEX_IDENTIFIERS; use crate::TRANSPARENCY_COLOUR; use crate::WINDOWS_11; @@ -108,19 +110,24 @@ impl Border { Self::create("komorebi-border-window")?; } - let mut should_expand_border = false; - let mut rect = WindowsApi::window_rect(window.hwnd())?; rect.top -= invisible_borders.bottom; rect.bottom += invisible_borders.bottom; let border_overflows = BORDER_OVERFLOW_IDENTIFIERS.lock(); - if border_overflows.contains(&window.title()?) - || border_overflows.contains(&window.exe()?) - || border_overflows.contains(&window.class()?) - { - should_expand_border = true; - } + let regex_identifiers = REGEX_IDENTIFIERS.lock(); + + let title = &window.title()?; + let exe_name = &window.exe()?; + let class = &window.class()?; + + let should_expand_border = should_act( + title, + exe_name, + class, + &border_overflows, + ®ex_identifiers, + ); if should_expand_border { rect.left -= invisible_borders.left; diff --git a/komorebi/src/main.rs b/komorebi/src/main.rs index 964645774..5f402c694 100644 --- a/komorebi/src/main.rs +++ b/komorebi/src/main.rs @@ -32,6 +32,7 @@ use os_info::Version; #[cfg(feature = "deadlock_detection")] use parking_lot::deadlock; use parking_lot::Mutex; +use regex::Regex; use schemars::JsonSchema; use serde::Serialize; use sysinfo::Process; @@ -89,26 +90,65 @@ type WorkspaceRule = (usize, usize, bool); lazy_static! { static ref HIDDEN_HWNDS: Arc>> = Arc::new(Mutex::new(vec![])); - static ref LAYERED_WHITELIST: Arc>> = - Arc::new(Mutex::new(vec!["steam.exe".to_string()])); - static ref TRAY_AND_MULTI_WINDOW_IDENTIFIERS: Arc>> = + static ref LAYERED_WHITELIST: Arc>> = Arc::new(Mutex::new(vec![ + IdWithIdentifier { + kind: ApplicationIdentifier::Exe, + id: String::from("steam.exe"), + matching_strategy: Option::from(MatchingStrategy::Equals), + }, + ])); + static ref TRAY_AND_MULTI_WINDOW_IDENTIFIERS: Arc>> = Arc::new(Mutex::new(vec![ - "explorer.exe".to_string(), - "firefox.exe".to_string(), - "chrome.exe".to_string(), - "idea64.exe".to_string(), - "ApplicationFrameHost.exe".to_string(), - "steam.exe".to_string(), + IdWithIdentifier { + kind: ApplicationIdentifier::Exe, + id: String::from("explorer.exe"), + matching_strategy: Option::from(MatchingStrategy::Equals), + }, + IdWithIdentifier { + kind: ApplicationIdentifier::Exe, + id: String::from("firefox.exe"), + matching_strategy: Option::from(MatchingStrategy::Equals), + }, + IdWithIdentifier { + kind: ApplicationIdentifier::Exe, + id: String::from("chrome.exe"), + matching_strategy: Option::from(MatchingStrategy::Equals), + }, + IdWithIdentifier { + kind: ApplicationIdentifier::Exe, + id: String::from("idea64.exe"), + matching_strategy: Option::from(MatchingStrategy::Equals), + }, + IdWithIdentifier { + kind: ApplicationIdentifier::Exe, + id: String::from("ApplicationFrameHost.exe"), + matching_strategy: Option::from(MatchingStrategy::Equals), + }, + IdWithIdentifier { + kind: ApplicationIdentifier::Exe, + id: String::from("steam.exe"), + matching_strategy: Option::from(MatchingStrategy::Equals), + } ])); - static ref OBJECT_NAME_CHANGE_ON_LAUNCH: Arc>> = Arc::new(Mutex::new(vec![ - "firefox.exe".to_string(), - "idea64.exe".to_string(), + static ref OBJECT_NAME_CHANGE_ON_LAUNCH: Arc>> = Arc::new(Mutex::new(vec![ + IdWithIdentifier { + kind: ApplicationIdentifier::Exe, + id: String::from("firefox.exe"), + matching_strategy: Option::from(MatchingStrategy::Equals), + }, + IdWithIdentifier { + kind: ApplicationIdentifier::Exe, + id: String::from("idea64.exe"), + matching_strategy: Option::from(MatchingStrategy::Equals), + }, ])); static ref MONITOR_INDEX_PREFERENCES: Arc>> = Arc::new(Mutex::new(HashMap::new())); static ref WORKSPACE_RULES: Arc>> = Arc::new(Mutex::new(HashMap::new())); - static ref MANAGE_IDENTIFIERS: Arc>> = Arc::new(Mutex::new(vec![])); + static ref REGEX_IDENTIFIERS: Arc>> = + Arc::new(Mutex::new(HashMap::new())); + static ref MANAGE_IDENTIFIERS: Arc>> = Arc::new(Mutex::new(vec![])); static ref FLOAT_IDENTIFIERS: Arc>> = Arc::new(Mutex::new(vec![ // mstsc.exe creates these on Windows 11 when a WSL process is launched // https://github.com/LGUG2Z/komorebi/issues/74 @@ -126,7 +166,7 @@ lazy_static! { static ref PERMAIGNORE_CLASSES: Arc>> = Arc::new(Mutex::new(vec![ "Chrome_RenderWidgetHostHWND".to_string(), ])); - static ref BORDER_OVERFLOW_IDENTIFIERS: Arc>> = Arc::new(Mutex::new(vec![])); + static ref BORDER_OVERFLOW_IDENTIFIERS: Arc>> = Arc::new(Mutex::new(vec![])); static ref WSL2_UI_PROCESSES: Arc>> = Arc::new(Mutex::new(vec![ "X410.exe".to_string(), "vcxsrv.exe".to_string(), diff --git a/komorebi/src/process_command.rs b/komorebi/src/process_command.rs index 6738c46e1..1a0539b1c 100644 --- a/komorebi/src/process_command.rs +++ b/komorebi/src/process_command.rs @@ -240,10 +240,22 @@ impl WindowManager { self.handle_definitive_workspace_rules(id, monitor_idx, workspace_idx)?; } } - SocketMessage::ManageRule(_, ref id) => { + SocketMessage::ManageRule(identifier, ref id) => { let mut manage_identifiers = MANAGE_IDENTIFIERS.lock(); - if !manage_identifiers.contains(id) { - manage_identifiers.push(id.to_string()); + + let mut should_push = true; + for m in &*manage_identifiers { + if m.id.eq(id) { + should_push = false; + } + } + + if should_push { + manage_identifiers.push(IdWithIdentifier { + kind: identifier, + id: id.clone(), + matching_strategy: Option::from(MatchingStrategy::Legacy), + }); } } SocketMessage::FloatRule(identifier, ref id) => { @@ -904,28 +916,75 @@ impl WindowManager { SocketMessage::WatchConfiguration(enable) => { self.watch_configuration(enable)?; } - SocketMessage::IdentifyBorderOverflowApplication(_, ref id) => { + SocketMessage::IdentifyBorderOverflowApplication(identifier, ref id) => { let mut identifiers = BORDER_OVERFLOW_IDENTIFIERS.lock(); - if !identifiers.contains(id) { - identifiers.push(id.to_string()); + + let mut should_push = true; + for i in &*identifiers { + if i.id.eq(id) { + should_push = false; + } + } + + if should_push { + identifiers.push(IdWithIdentifier { + kind: identifier, + id: id.clone(), + matching_strategy: Option::from(MatchingStrategy::Legacy), + }); } } - SocketMessage::IdentifyObjectNameChangeApplication(_, ref id) => { + SocketMessage::IdentifyObjectNameChangeApplication(identifier, ref id) => { let mut identifiers = OBJECT_NAME_CHANGE_ON_LAUNCH.lock(); - if !identifiers.contains(id) { - identifiers.push(id.to_string()); + + let mut should_push = true; + for i in &*identifiers { + if i.id.eq(id) { + should_push = false; + } + } + + if should_push { + identifiers.push(IdWithIdentifier { + kind: identifier, + id: id.clone(), + matching_strategy: Option::from(MatchingStrategy::Legacy), + }); } } - SocketMessage::IdentifyTrayApplication(_, ref id) => { + SocketMessage::IdentifyTrayApplication(identifier, ref id) => { let mut identifiers = TRAY_AND_MULTI_WINDOW_IDENTIFIERS.lock(); - if !identifiers.contains(id) { - identifiers.push(id.to_string()); + let mut should_push = true; + for i in &*identifiers { + if i.id.eq(id) { + should_push = false; + } + } + + if should_push { + identifiers.push(IdWithIdentifier { + kind: identifier, + id: id.clone(), + matching_strategy: Option::from(MatchingStrategy::Legacy), + }); } } - SocketMessage::IdentifyLayeredApplication(_, ref id) => { + SocketMessage::IdentifyLayeredApplication(identifier, ref id) => { let mut identifiers = LAYERED_WHITELIST.lock(); - if !identifiers.contains(id) { - identifiers.push(id.to_string()); + + let mut should_push = true; + for i in &*identifiers { + if i.id.eq(id) { + should_push = false; + } + } + + if should_push { + identifiers.push(IdWithIdentifier { + kind: identifier, + id: id.clone(), + matching_strategy: Option::from(MatchingStrategy::Legacy), + }); } } SocketMessage::ManageFocusedWindow => { diff --git a/komorebi/src/process_event.rs b/komorebi/src/process_event.rs index 522cbb631..f3ac58d71 100644 --- a/komorebi/src/process_event.rs +++ b/komorebi/src/process_event.rs @@ -15,6 +15,7 @@ use komorebi_core::WindowContainerBehaviour; use crate::border::Border; use crate::current_virtual_desktop; use crate::notify_subscribers; +use crate::window::should_act; use crate::window_manager::WindowManager; use crate::window_manager_event::WindowManagerEvent; use crate::windows_api::WindowsApi; @@ -29,6 +30,7 @@ use crate::BORDER_HIDDEN; use crate::BORDER_HWND; use crate::DATA_DIR; use crate::HIDDEN_HWNDS; +use crate::REGEX_IDENTIFIERS; use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS; #[tracing::instrument] @@ -179,15 +181,26 @@ impl WindowManager { { let tray_and_multi_window_identifiers = TRAY_AND_MULTI_WINDOW_IDENTIFIERS.lock(); + let regex_identifiers = REGEX_IDENTIFIERS.lock(); + + let title = &window.title()?; + let exe_name = &window.exe()?; + let class = &window.class()?; // We don't want to purge windows that have been deliberately hidden by us, eg. when // they are not on the top of a container stack. let programmatically_hidden_hwnds = HIDDEN_HWNDS.lock(); + let should_act = should_act( + title, + exe_name, + class, + &tray_and_multi_window_identifiers, + ®ex_identifiers, + ); - if ((!window.is_window() - || tray_and_multi_window_identifiers.contains(&window.exe()?)) - || tray_and_multi_window_identifiers.contains(&window.class()?)) - && !programmatically_hidden_hwnds.contains(&window.hwnd) + if !window.is_window() + || should_act + || !programmatically_hidden_hwnds.contains(&window.hwnd) { hide = true; } diff --git a/komorebi/src/static_config.rs b/komorebi/src/static_config.rs index 13bc869cf..b21a28e25 100644 --- a/komorebi/src/static_config.rs +++ b/komorebi/src/static_config.rs @@ -24,6 +24,7 @@ use crate::LAYERED_WHITELIST; use crate::MANAGE_IDENTIFIERS; use crate::MONITOR_INDEX_PREFERENCES; use crate::OBJECT_NAME_CHANGE_ON_LAUNCH; +use crate::REGEX_IDENTIFIERS; use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS; use crate::WORKSPACE_RULES; use color_eyre::Result; @@ -46,6 +47,7 @@ use komorebi_core::Rect; use komorebi_core::SocketMessage; use komorebi_core::WindowContainerBehaviour; use parking_lot::Mutex; +use regex::Regex; use schemars::JsonSchema; use serde::Deserialize; use serde::Serialize; @@ -504,6 +506,7 @@ impl StaticConfig { } let mut float_identifiers = FLOAT_IDENTIFIERS.lock(); + let mut regex_identifiers = REGEX_IDENTIFIERS.lock(); let mut manage_identifiers = MANAGE_IDENTIFIERS.lock(); let mut tray_and_multi_window_identifiers = TRAY_AND_MULTI_WINDOW_IDENTIFIERS.lock(); let mut border_overflow_identifiers = BORDER_OVERFLOW_IDENTIFIERS.lock(); @@ -518,46 +521,96 @@ impl StaticConfig { if !float_identifiers.contains(identifier) { float_identifiers.push(identifier.clone()); + + if matches!(identifier.matching_strategy, Some(MatchingStrategy::Regex)) { + let re = Regex::new(&identifier.id)?; + regex_identifiers.insert(identifier.id.clone(), re); + } } } } - if let Some(float) = &self.manage_rules { - for identifier in float { - if !manage_identifiers.contains(&identifier.id) { - manage_identifiers.push(identifier.id.clone()); + if let Some(manage) = &mut self.manage_rules { + for identifier in manage { + if identifier.matching_strategy.is_none() { + identifier.matching_strategy = Option::from(MatchingStrategy::Legacy); + } + + if !manage_identifiers.contains(identifier) { + manage_identifiers.push(identifier.clone()); + + if matches!(identifier.matching_strategy, Some(MatchingStrategy::Regex)) { + let re = Regex::new(&identifier.id)?; + regex_identifiers.insert(identifier.id.clone(), re); + } } } } - if let Some(identifiers) = &self.object_name_change_applications { + if let Some(identifiers) = &mut self.object_name_change_applications { for identifier in identifiers { - if !object_name_change_identifiers.contains(&identifier.id) { - object_name_change_identifiers.push(identifier.id.clone()); + if identifier.matching_strategy.is_none() { + identifier.matching_strategy = Option::from(MatchingStrategy::Legacy); + } + + if !object_name_change_identifiers.contains(identifier) { + object_name_change_identifiers.push(identifier.clone()); + + if matches!(identifier.matching_strategy, Some(MatchingStrategy::Regex)) { + let re = Regex::new(&identifier.id)?; + regex_identifiers.insert(identifier.id.clone(), re); + } } } } - if let Some(identifiers) = &self.layered_applications { + if let Some(identifiers) = &mut self.layered_applications { for identifier in identifiers { - if !layered_identifiers.contains(&identifier.id) { - layered_identifiers.push(identifier.id.clone()); + if identifier.matching_strategy.is_none() { + identifier.matching_strategy = Option::from(MatchingStrategy::Legacy); + } + + if !border_overflow_identifiers.contains(identifier) { + border_overflow_identifiers.push(identifier.clone()); + + if matches!(identifier.matching_strategy, Some(MatchingStrategy::Regex)) { + let re = Regex::new(&identifier.id)?; + regex_identifiers.insert(identifier.id.clone(), re); + } } } } - if let Some(identifiers) = &self.border_overflow_applications { + if let Some(identifiers) = &mut self.border_overflow_applications { for identifier in identifiers { - if !border_overflow_identifiers.contains(&identifier.id) { - border_overflow_identifiers.push(identifier.id.clone()); + if identifier.matching_strategy.is_none() { + identifier.matching_strategy = Option::from(MatchingStrategy::Legacy); + } + + if !border_overflow_identifiers.contains(identifier) { + border_overflow_identifiers.push(identifier.clone()); + + if matches!(identifier.matching_strategy, Some(MatchingStrategy::Regex)) { + let re = Regex::new(&identifier.id)?; + regex_identifiers.insert(identifier.id.clone(), re); + } } } } - if let Some(identifiers) = &self.tray_and_multi_window_applications { + if let Some(identifiers) = &mut self.tray_and_multi_window_applications { for identifier in identifiers { - if !tray_and_multi_window_identifiers.contains(&identifier.id) { - tray_and_multi_window_identifiers.push(identifier.id.clone()); + if identifier.matching_strategy.is_none() { + identifier.matching_strategy = Option::from(MatchingStrategy::Legacy); + } + + if !tray_and_multi_window_identifiers.contains(identifier) { + tray_and_multi_window_identifiers.push(identifier.clone()); + + if matches!(identifier.matching_strategy, Some(MatchingStrategy::Regex)) { + let re = Regex::new(&identifier.id)?; + regex_identifiers.insert(identifier.id.clone(), re); + } } } } @@ -572,7 +625,7 @@ impl StaticConfig { let content = std::fs::read_to_string(stringified)?; let asc = ApplicationConfigurationGenerator::load(&content)?; - for entry in asc { + for mut entry in asc { if let Some(float) = entry.float_identifiers { for f in float { let mut without_comment: IdWithIdentifier = f.into(); @@ -583,6 +636,14 @@ impl StaticConfig { if !float_identifiers.contains(&without_comment) { float_identifiers.push(without_comment.clone()); + + if matches!( + without_comment.matching_strategy, + Some(MatchingStrategy::Regex) + ) { + let re = Regex::new(&without_comment.id)?; + regex_identifiers.insert(without_comment.id.clone(), re); + } } } } @@ -590,31 +651,94 @@ impl StaticConfig { for o in options { match o { ApplicationOptions::ObjectNameChange => { - if !object_name_change_identifiers.contains(&entry.identifier.id) { - object_name_change_identifiers - .push(entry.identifier.id.clone()); + if entry.identifier.matching_strategy.is_none() { + entry.identifier.matching_strategy = + Option::from(MatchingStrategy::Legacy); + } + + if !object_name_change_identifiers.contains(&entry.identifier) { + object_name_change_identifiers.push(entry.identifier.clone()); + + if matches!( + entry.identifier.matching_strategy, + Some(MatchingStrategy::Regex) + ) { + let re = Regex::new(&entry.identifier.id)?; + regex_identifiers.insert(entry.identifier.id.clone(), re); + } } } ApplicationOptions::Layered => { - if !layered_identifiers.contains(&entry.identifier.id) { - layered_identifiers.push(entry.identifier.id.clone()); + if entry.identifier.matching_strategy.is_none() { + entry.identifier.matching_strategy = + Option::from(MatchingStrategy::Legacy); + } + + if !layered_identifiers.contains(&entry.identifier) { + layered_identifiers.push(entry.identifier.clone()); + + if matches!( + entry.identifier.matching_strategy, + Some(MatchingStrategy::Regex) + ) { + let re = Regex::new(&entry.identifier.id)?; + regex_identifiers.insert(entry.identifier.id.clone(), re); + } } } ApplicationOptions::BorderOverflow => { - if !border_overflow_identifiers.contains(&entry.identifier.id) { - border_overflow_identifiers.push(entry.identifier.id.clone()); + if entry.identifier.matching_strategy.is_none() { + entry.identifier.matching_strategy = + Option::from(MatchingStrategy::Legacy); + } + + if !border_overflow_identifiers.contains(&entry.identifier) { + border_overflow_identifiers.push(entry.identifier.clone()); + + if matches!( + entry.identifier.matching_strategy, + Some(MatchingStrategy::Regex) + ) { + let re = Regex::new(&entry.identifier.id)?; + regex_identifiers.insert(entry.identifier.id.clone(), re); + } } } ApplicationOptions::TrayAndMultiWindow => { - if !tray_and_multi_window_identifiers.contains(&entry.identifier.id) - { + if entry.identifier.matching_strategy.is_none() { + entry.identifier.matching_strategy = + Option::from(MatchingStrategy::Legacy); + } + + if !tray_and_multi_window_identifiers.contains(&entry.identifier) { tray_and_multi_window_identifiers - .push(entry.identifier.id.clone()); + .push(entry.identifier.clone()); + + if matches!( + entry.identifier.matching_strategy, + Some(MatchingStrategy::Regex) + ) { + let re = Regex::new(&entry.identifier.id)?; + regex_identifiers.insert(entry.identifier.id.clone(), re); + } } } ApplicationOptions::Force => { - if !manage_identifiers.contains(&entry.identifier.id) { - manage_identifiers.push(entry.identifier.id.clone()); + if entry.identifier.matching_strategy.is_none() { + entry.identifier.matching_strategy = + Option::from(MatchingStrategy::Legacy); + } + + if !manage_identifiers.contains(&entry.identifier) { + manage_identifiers.push(entry.identifier.clone()); + + if matches!( + entry.identifier.matching_strategy, + Some(MatchingStrategy::Regex) + ) { + let re = Regex::new(&entry.identifier.id)?; + regex_identifiers.insert(entry.identifier.id.clone(), re); + } } } } diff --git a/komorebi/src/window.rs b/komorebi/src/window.rs index 26918321e..b08760efe 100644 --- a/komorebi/src/window.rs +++ b/komorebi/src/window.rs @@ -1,4 +1,5 @@ use crate::com::SetCloak; +use std::collections::HashMap; use std::convert::TryFrom; use std::fmt::Display; use std::fmt::Formatter; @@ -7,7 +8,9 @@ use std::sync::atomic::Ordering; use color_eyre::eyre::anyhow; use color_eyre::Result; +use komorebi_core::config_generation::IdWithIdentifier; use komorebi_core::config_generation::MatchingStrategy; +use regex::Regex; use schemars::JsonSchema; use serde::ser::Error; use serde::ser::SerializeStruct; @@ -35,6 +38,7 @@ 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; #[derive(Debug, Clone, Copy, JsonSchema)] @@ -126,15 +130,21 @@ impl Window { top: bool, ) -> Result<()> { let mut rect = *layout; - let mut should_remove_border = true; let border_overflows = BORDER_OVERFLOW_IDENTIFIERS.lock(); - if border_overflows.contains(&self.title()?) - || border_overflows.contains(&self.exe()?) - || border_overflows.contains(&self.class()?) - { - should_remove_border = false; - } + let regex_identifiers = REGEX_IDENTIFIERS.lock(); + + let title = &self.title()?; + let class = &self.class()?; + let exe_name = &self.exe()?; + + let should_remove_border = should_act( + title, + exe_name, + class, + &border_overflows, + ®ex_identifiers, + ); if should_remove_border { // Remove the invisible borders @@ -471,71 +481,38 @@ fn window_is_eligible( } } - let mut should_float = false; - - { - let float_identifiers = FLOAT_IDENTIFIERS.lock(); - for identifier in float_identifiers.iter() { - match identifier.matching_strategy { - None => { - panic!("there is no matching strategy identified for this rule"); - } - Some(MatchingStrategy::Equals) => match identifier.kind { - ApplicationIdentifier::Title => { - if title.eq(&identifier.id) { - should_float = true; - } - } - ApplicationIdentifier::Class => { - if class.eq(&identifier.id) { - should_float = true; - } - } - ApplicationIdentifier::Exe => { - if exe_name.eq(&identifier.id) { - should_float = true; - } - } - }, - Some(MatchingStrategy::Legacy) => match identifier.kind { - ApplicationIdentifier::Title => { - if title.starts_with(&identifier.id) || title.ends_with(&identifier.id) { - should_float = true; - } - } - ApplicationIdentifier::Class => { - if class.starts_with(&identifier.id) || class.ends_with(&identifier.id) { - should_float = true; - } - } - ApplicationIdentifier::Exe => { - if exe_name.eq(&identifier.id) { - should_float = true; - } - } - }, - _ => unimplemented!(), - } - } - }; - - let managed_override = { - let manage_identifiers = MANAGE_IDENTIFIERS.lock(); - manage_identifiers.contains(exe_name) - || manage_identifiers.contains(class) - || manage_identifiers.contains(title) - }; + let regex_identifiers = REGEX_IDENTIFIERS.lock(); + + let float_identifiers = FLOAT_IDENTIFIERS.lock(); + let should_float = should_act( + title, + exe_name, + class, + &float_identifiers, + ®ex_identifiers, + ); + + let manage_identifiers = MANAGE_IDENTIFIERS.lock(); + let managed_override = should_act( + title, + exe_name, + class, + &manage_identifiers, + ®ex_identifiers, + ); if should_float && !managed_override { return false; } - let allow_layered = { - let layered_whitelist = LAYERED_WHITELIST.lock(); - layered_whitelist.contains(exe_name) - || layered_whitelist.contains(class) - || layered_whitelist.contains(title) - }; + let layered_whitelist = LAYERED_WHITELIST.lock(); + let allow_layered = should_act( + title, + exe_name, + class, + &layered_whitelist, + ®ex_identifiers, + ); // TODO: might need this for transparency // let allow_layered = true; @@ -566,3 +543,131 @@ fn window_is_eligible( false } + +#[allow(clippy::cognitive_complexity, clippy::too_many_lines)] +pub fn should_act( + title: &str, + exe_name: &str, + class: &str, + identifiers: &[IdWithIdentifier], + regex_identifiers: &HashMap, +) -> bool { + let mut should_act = false; + for identifier in identifiers { + match identifier.matching_strategy { + None => { + panic!("there is no matching strategy identified for this rule"); + } + Some(MatchingStrategy::Legacy) => match identifier.kind { + ApplicationIdentifier::Title => { + if title.starts_with(&identifier.id) || title.ends_with(&identifier.id) { + should_act = true; + } + } + ApplicationIdentifier::Class => { + if class.starts_with(&identifier.id) || class.ends_with(&identifier.id) { + should_act = true; + } + } + ApplicationIdentifier::Exe => { + if exe_name.eq(&identifier.id) { + should_act = true; + } + } + }, + Some(MatchingStrategy::Equals) => match identifier.kind { + ApplicationIdentifier::Title => { + if title.eq(&identifier.id) { + should_act = true; + } + } + ApplicationIdentifier::Class => { + if class.eq(&identifier.id) { + should_act = true; + } + } + ApplicationIdentifier::Exe => { + if exe_name.eq(&identifier.id) { + should_act = true; + } + } + }, + Some(MatchingStrategy::StartsWith) => match identifier.kind { + ApplicationIdentifier::Title => { + if title.starts_with(&identifier.id) { + should_act = true; + } + } + ApplicationIdentifier::Class => { + if class.starts_with(&identifier.id) { + should_act = true; + } + } + ApplicationIdentifier::Exe => { + if exe_name.starts_with(&identifier.id) { + should_act = true; + } + } + }, + Some(MatchingStrategy::EndsWith) => match identifier.kind { + ApplicationIdentifier::Title => { + if title.ends_with(&identifier.id) { + should_act = true; + } + } + ApplicationIdentifier::Class => { + if class.ends_with(&identifier.id) { + should_act = true; + } + } + ApplicationIdentifier::Exe => { + if exe_name.ends_with(&identifier.id) { + should_act = true; + } + } + }, + Some(MatchingStrategy::Contains) => match identifier.kind { + ApplicationIdentifier::Title => { + if title.contains(&identifier.id) { + should_act = true; + } + } + ApplicationIdentifier::Class => { + if class.contains(&identifier.id) { + should_act = true; + } + } + ApplicationIdentifier::Exe => { + if exe_name.contains(&identifier.id) { + should_act = true; + } + } + }, + Some(MatchingStrategy::Regex) => match identifier.kind { + ApplicationIdentifier::Title => { + if let Some(re) = regex_identifiers.get(&identifier.id) { + if re.is_match(title) { + should_act = true; + } + } + } + ApplicationIdentifier::Class => { + if let Some(re) = regex_identifiers.get(&identifier.id) { + if re.is_match(class) { + should_act = true; + } + } + } + ApplicationIdentifier::Exe => { + if let Some(re) = regex_identifiers.get(&identifier.id) { + if re.is_match(exe_name) { + should_act = true; + } + } + } + }, + } + } + + should_act +} diff --git a/komorebi/src/window_manager.rs b/komorebi/src/window_manager.rs index 3ca48817f..87af1eb88 100644 --- a/komorebi/src/window_manager.rs +++ b/komorebi/src/window_manager.rs @@ -95,11 +95,11 @@ pub struct State { pub has_pending_raise_op: bool, pub remove_titlebars: bool, pub float_identifiers: Vec, - pub manage_identifiers: Vec, - pub layered_whitelist: Vec, - pub tray_and_multi_window_identifiers: Vec, - pub border_overflow_identifiers: Vec, - pub name_change_on_launch_identifiers: Vec, + pub manage_identifiers: Vec, + pub layered_whitelist: Vec, + pub tray_and_multi_window_identifiers: Vec, + pub border_overflow_identifiers: Vec, + pub name_change_on_launch_identifiers: Vec, pub monitor_index_preferences: HashMap, } diff --git a/komorebi/src/window_manager_event.rs b/komorebi/src/window_manager_event.rs index af9cdbe41..ae6d19bd1 100644 --- a/komorebi/src/window_manager_event.rs +++ b/komorebi/src/window_manager_event.rs @@ -4,9 +4,11 @@ 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")] @@ -131,11 +133,21 @@ impl WindowManagerEvent { // [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(); - if object_name_change_on_launch.contains(&window.exe().ok()?) - || object_name_change_on_launch.contains(&window.class().ok()?) - || object_name_change_on_launch.contains(&window.title().ok()?) - { + 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, + ®ex_identifiers, + ); + + if should_trigger { Option::from(Self::Show(winevent, window)) } else { None