mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-03-23 09:51:16 +01:00
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
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -813,6 +813,7 @@ dependencies = [
|
||||
"os_info",
|
||||
"parking_lot",
|
||||
"paste",
|
||||
"regex",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<Mutex<Vec<isize>>> = Arc::new(Mutex::new(vec![]));
|
||||
static ref LAYERED_WHITELIST: Arc<Mutex<Vec<String>>> =
|
||||
Arc::new(Mutex::new(vec!["steam.exe".to_string()]));
|
||||
static ref TRAY_AND_MULTI_WINDOW_IDENTIFIERS: Arc<Mutex<Vec<String>>> =
|
||||
static ref LAYERED_WHITELIST: Arc<Mutex<Vec<IdWithIdentifier>>> = 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<Mutex<Vec<IdWithIdentifier>>> =
|
||||
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<Mutex<Vec<String>>> = Arc::new(Mutex::new(vec![
|
||||
"firefox.exe".to_string(),
|
||||
"idea64.exe".to_string(),
|
||||
static ref OBJECT_NAME_CHANGE_ON_LAUNCH: Arc<Mutex<Vec<IdWithIdentifier>>> = 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<Mutex<HashMap<usize, Rect>>> =
|
||||
Arc::new(Mutex::new(HashMap::new()));
|
||||
static ref WORKSPACE_RULES: Arc<Mutex<HashMap<String, WorkspaceRule>>> =
|
||||
Arc::new(Mutex::new(HashMap::new()));
|
||||
static ref MANAGE_IDENTIFIERS: Arc<Mutex<Vec<String>>> = Arc::new(Mutex::new(vec![]));
|
||||
static ref REGEX_IDENTIFIERS: Arc<Mutex<HashMap<String, Regex>>> =
|
||||
Arc::new(Mutex::new(HashMap::new()));
|
||||
static ref MANAGE_IDENTIFIERS: Arc<Mutex<Vec<IdWithIdentifier>>> = Arc::new(Mutex::new(vec![]));
|
||||
static ref FLOAT_IDENTIFIERS: Arc<Mutex<Vec<IdWithIdentifier>>> = 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<Mutex<Vec<String>>> = Arc::new(Mutex::new(vec![
|
||||
"Chrome_RenderWidgetHostHWND".to_string(),
|
||||
]));
|
||||
static ref BORDER_OVERFLOW_IDENTIFIERS: Arc<Mutex<Vec<String>>> = Arc::new(Mutex::new(vec![]));
|
||||
static ref BORDER_OVERFLOW_IDENTIFIERS: Arc<Mutex<Vec<IdWithIdentifier>>> = Arc::new(Mutex::new(vec![]));
|
||||
static ref WSL2_UI_PROCESSES: Arc<Mutex<Vec<String>>> = Arc::new(Mutex::new(vec![
|
||||
"X410.exe".to_string(),
|
||||
"vcxsrv.exe".to_string(),
|
||||
|
||||
@@ -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 => {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 regex_identifiers = REGEX_IDENTIFIERS.lock();
|
||||
|
||||
{
|
||||
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 float_identifiers = FLOAT_IDENTIFIERS.lock();
|
||||
let should_float = should_act(
|
||||
title,
|
||||
exe_name,
|
||||
class,
|
||||
&float_identifiers,
|
||||
®ex_identifiers,
|
||||
);
|
||||
|
||||
let managed_override = {
|
||||
let manage_identifiers = MANAGE_IDENTIFIERS.lock();
|
||||
manage_identifiers.contains(exe_name)
|
||||
|| manage_identifiers.contains(class)
|
||||
|| manage_identifiers.contains(title)
|
||||
};
|
||||
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<String, Regex>,
|
||||
) -> 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
|
||||
}
|
||||
|
||||
@@ -95,11 +95,11 @@ pub struct State {
|
||||
pub has_pending_raise_op: bool,
|
||||
pub remove_titlebars: bool,
|
||||
pub float_identifiers: Vec<IdWithIdentifier>,
|
||||
pub manage_identifiers: Vec<String>,
|
||||
pub layered_whitelist: Vec<String>,
|
||||
pub tray_and_multi_window_identifiers: Vec<String>,
|
||||
pub border_overflow_identifiers: Vec<String>,
|
||||
pub name_change_on_launch_identifiers: Vec<String>,
|
||||
pub manage_identifiers: Vec<IdWithIdentifier>,
|
||||
pub layered_whitelist: Vec<IdWithIdentifier>,
|
||||
pub tray_and_multi_window_identifiers: Vec<IdWithIdentifier>,
|
||||
pub border_overflow_identifiers: Vec<IdWithIdentifier>,
|
||||
pub name_change_on_launch_identifiers: Vec<IdWithIdentifier>,
|
||||
pub monitor_index_preferences: HashMap<usize, Rect>,
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user