feat(wm): add path variant to application identifiers

This commit add a new way to match applications
through its paths, allowing to match a bunch
of applications that share a parent folder.
This commit is contained in:
eythaann
2024-02-28 06:25:51 -05:00
committed by جاد
parent b32bce8713
commit 2bceff4edc
8 changed files with 68 additions and 4 deletions

View File

@@ -102,7 +102,7 @@ impl ApplicationConfiguration {
pub fn populate_default_matching_strategies(&mut self) { pub fn populate_default_matching_strategies(&mut self) {
if self.identifier.matching_strategy.is_none() { if self.identifier.matching_strategy.is_none() {
match self.identifier.kind { match self.identifier.kind {
ApplicationIdentifier::Exe => { ApplicationIdentifier::Exe | ApplicationIdentifier::Path => {
self.identifier.matching_strategy = Option::from(MatchingStrategy::Equals); self.identifier.matching_strategy = Option::from(MatchingStrategy::Equals);
} }
ApplicationIdentifier::Class | ApplicationIdentifier::Title => {} ApplicationIdentifier::Class | ApplicationIdentifier::Title => {}

View File

@@ -223,6 +223,8 @@ pub enum ApplicationIdentifier {
Class, Class,
#[serde(alias = "title")] #[serde(alias = "title")]
Title, Title,
#[serde(alias = "path")]
Path,
} }
#[derive( #[derive(

View File

@@ -315,6 +315,11 @@ impl WindowManager {
{ {
for window in container.windows() { for window in container.windows() {
match identifier { match identifier {
ApplicationIdentifier::Path => {
if window.path()? == *id {
hwnds_to_purge.push((i, window.hwnd));
}
}
ApplicationIdentifier::Exe => { ApplicationIdentifier::Exe => {
if window.exe()? == *id { if window.exe()? == *id {
hwnds_to_purge.push((i, window.hwnd)); hwnds_to_purge.push((i, window.hwnd));

View File

@@ -185,6 +185,7 @@ impl WindowManager {
let title = &window.title()?; let title = &window.title()?;
let exe_name = &window.exe()?; let exe_name = &window.exe()?;
let class = &window.class()?; let class = &window.class()?;
let path = &window.path()?;
// We don't want to purge windows that have been deliberately hidden by us, eg. when // 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. // they are not on the top of a container stack.
@@ -193,6 +194,7 @@ impl WindowManager {
title, title,
exe_name, exe_name,
class, class,
path,
&tray_and_multi_window_identifiers, &tray_and_multi_window_identifiers,
&regex_identifiers, &regex_identifiers,
); );

View File

@@ -377,6 +377,14 @@ impl Window {
WindowsApi::window_text_w(self.hwnd()) WindowsApi::window_text_w(self.hwnd())
} }
pub fn path(self) -> Result<String> {
let (process_id, _) = WindowsApi::window_thread_process_id(self.hwnd());
let handle = WindowsApi::process_handle(process_id)?;
let path = WindowsApi::exe_path(handle);
WindowsApi::close_process(handle)?;
path
}
pub fn exe(self) -> Result<String> { pub fn exe(self) -> Result<String> {
let (process_id, _) = WindowsApi::window_thread_process_id(self.hwnd()); let (process_id, _) = WindowsApi::window_thread_process_id(self.hwnd());
let handle = WindowsApi::process_handle(process_id)?; let handle = WindowsApi::process_handle(process_id)?;
@@ -440,8 +448,8 @@ impl Window {
(true, _) | (true, _) |
// If not allowing cloaked windows, we need to ensure the window is not cloaked // If not allowing cloaked windows, we need to ensure the window is not cloaked
(false, false) => { (false, false) => {
if let (Ok(title), Ok(exe_name), Ok(class)) = (self.title(), self.exe(), self.class()) { if let (Ok(title), Ok(exe_name), Ok(class), Ok(path)) = (self.title(), self.exe(), self.class(), self.path()) {
return Ok(window_is_eligible(&title, &exe_name, &class, &self.style()?, &self.ex_style()?, event)); return Ok(window_is_eligible(&title, &exe_name, &class, &path, &self.style()?, &self.ex_style()?, event));
} }
} }
_ => {} _ => {}
@@ -455,6 +463,7 @@ fn window_is_eligible(
title: &String, title: &String,
exe_name: &String, exe_name: &String,
class: &String, class: &String,
path: &String,
style: &WindowStyle, style: &WindowStyle,
ex_style: &ExtendedWindowStyle, ex_style: &ExtendedWindowStyle,
event: Option<WindowManagerEvent>, event: Option<WindowManagerEvent>,
@@ -473,6 +482,7 @@ fn window_is_eligible(
title, title,
exe_name, exe_name,
class, class,
path,
&float_identifiers, &float_identifiers,
&regex_identifiers, &regex_identifiers,
); );
@@ -482,6 +492,7 @@ fn window_is_eligible(
title, title,
exe_name, exe_name,
class, class,
path,
&manage_identifiers, &manage_identifiers,
&regex_identifiers, &regex_identifiers,
); );
@@ -495,6 +506,7 @@ fn window_is_eligible(
title, title,
exe_name, exe_name,
class, class,
path,
&layered_whitelist, &layered_whitelist,
&regex_identifiers, &regex_identifiers,
); );
@@ -534,6 +546,7 @@ pub fn should_act(
title: &str, title: &str,
exe_name: &str, exe_name: &str,
class: &str, class: &str,
path: &str,
identifiers: &[IdWithIdentifier], identifiers: &[IdWithIdentifier],
regex_identifiers: &HashMap<String, Regex>, regex_identifiers: &HashMap<String, Regex>,
) -> bool { ) -> bool {
@@ -559,6 +572,11 @@ pub fn should_act(
should_act = true; should_act = true;
} }
} }
ApplicationIdentifier::Path => {
if path.eq(&identifier.id) {
should_act = true;
}
}
}, },
Some(MatchingStrategy::Equals) => match identifier.kind { Some(MatchingStrategy::Equals) => match identifier.kind {
ApplicationIdentifier::Title => { ApplicationIdentifier::Title => {
@@ -576,6 +594,11 @@ pub fn should_act(
should_act = true; should_act = true;
} }
} }
ApplicationIdentifier::Path => {
if path.eq(&identifier.id) {
should_act = true;
}
}
}, },
Some(MatchingStrategy::StartsWith) => match identifier.kind { Some(MatchingStrategy::StartsWith) => match identifier.kind {
ApplicationIdentifier::Title => { ApplicationIdentifier::Title => {
@@ -593,6 +616,11 @@ pub fn should_act(
should_act = true; should_act = true;
} }
} }
ApplicationIdentifier::Path => {
if path.starts_with(&identifier.id) {
should_act = true;
}
}
}, },
Some(MatchingStrategy::EndsWith) => match identifier.kind { Some(MatchingStrategy::EndsWith) => match identifier.kind {
ApplicationIdentifier::Title => { ApplicationIdentifier::Title => {
@@ -610,6 +638,11 @@ pub fn should_act(
should_act = true; should_act = true;
} }
} }
ApplicationIdentifier::Path => {
if path.ends_with(&identifier.id) {
should_act = true;
}
}
}, },
Some(MatchingStrategy::Contains) => match identifier.kind { Some(MatchingStrategy::Contains) => match identifier.kind {
ApplicationIdentifier::Title => { ApplicationIdentifier::Title => {
@@ -627,6 +660,11 @@ pub fn should_act(
should_act = true; should_act = true;
} }
} }
ApplicationIdentifier::Path => {
if path.contains(&identifier.id) {
should_act = true;
}
}
}, },
Some(MatchingStrategy::Regex) => match identifier.kind { Some(MatchingStrategy::Regex) => match identifier.kind {
ApplicationIdentifier::Title => { ApplicationIdentifier::Title => {
@@ -650,6 +688,13 @@ pub fn should_act(
} }
} }
} }
ApplicationIdentifier::Path => {
if let Some(re) = regex_identifiers.get(&identifier.id) {
if re.is_match(path) {
should_act = true;
}
}
}
}, },
} }
} }

View File

@@ -139,11 +139,13 @@ impl WindowManagerEvent {
let title = &window.title().ok()?; let title = &window.title().ok()?;
let exe_name = &window.exe().ok()?; let exe_name = &window.exe().ok()?;
let class = &window.class().ok()?; let class = &window.class().ok()?;
let path = &window.path().ok()?;
let should_trigger = should_act( let should_trigger = should_act(
title, title,
exe_name, exe_name,
class, class,
path,
&object_name_change_on_launch, &object_name_change_on_launch,
&regex_identifiers, &regex_identifiers,
); );

View File

@@ -44,7 +44,8 @@
"enum": [ "enum": [
"Exe", "Exe",
"Class", "Class",
"Title" "Title",
"Path"
] ]
}, },
"ApplicationOptions": { "ApplicationOptions": {

View File

@@ -163,6 +163,7 @@
"kind": { "kind": {
"type": "string", "type": "string",
"enum": [ "enum": [
"Path",
"Exe", "Exe",
"Class", "Class",
"Title" "Title"
@@ -234,6 +235,7 @@
"kind": { "kind": {
"type": "string", "type": "string",
"enum": [ "enum": [
"Path",
"Exe", "Exe",
"Class", "Class",
"Title" "Title"
@@ -352,6 +354,7 @@
"kind": { "kind": {
"type": "string", "type": "string",
"enum": [ "enum": [
"Path",
"Exe", "Exe",
"Class", "Class",
"Title" "Title"
@@ -387,6 +390,7 @@
"kind": { "kind": {
"type": "string", "type": "string",
"enum": [ "enum": [
"Path",
"Exe", "Exe",
"Class", "Class",
"Title" "Title"
@@ -523,6 +527,7 @@
"kind": { "kind": {
"type": "string", "type": "string",
"enum": [ "enum": [
"Path",
"Exe", "Exe",
"Class", "Class",
"Title" "Title"
@@ -594,6 +599,7 @@
"kind": { "kind": {
"type": "string", "type": "string",
"enum": [ "enum": [
"Path",
"Exe", "Exe",
"Class", "Class",
"Title" "Title"
@@ -639,6 +645,7 @@
"kind": { "kind": {
"type": "string", "type": "string",
"enum": [ "enum": [
"Path",
"Exe", "Exe",
"Class", "Class",
"Title" "Title"