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) {
if self.identifier.matching_strategy.is_none() {
match self.identifier.kind {
ApplicationIdentifier::Exe => {
ApplicationIdentifier::Exe | ApplicationIdentifier::Path => {
self.identifier.matching_strategy = Option::from(MatchingStrategy::Equals);
}
ApplicationIdentifier::Class | ApplicationIdentifier::Title => {}

View File

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

View File

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

View File

@@ -185,6 +185,7 @@ impl WindowManager {
let title = &window.title()?;
let exe_name = &window.exe()?;
let class = &window.class()?;
let path = &window.path()?;
// 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.
@@ -193,6 +194,7 @@ impl WindowManager {
title,
exe_name,
class,
path,
&tray_and_multi_window_identifiers,
&regex_identifiers,
);

View File

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

View File

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

View File

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