mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-04-21 08:11:30 +02:00
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:
@@ -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 => {}
|
||||||
|
|||||||
@@ -223,6 +223,8 @@ pub enum ApplicationIdentifier {
|
|||||||
Class,
|
Class,
|
||||||
#[serde(alias = "title")]
|
#[serde(alias = "title")]
|
||||||
Title,
|
Title,
|
||||||
|
#[serde(alias = "path")]
|
||||||
|
Path,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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,
|
||||||
®ex_identifiers,
|
®ex_identifiers,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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,
|
||||||
®ex_identifiers,
|
®ex_identifiers,
|
||||||
);
|
);
|
||||||
@@ -482,6 +492,7 @@ fn window_is_eligible(
|
|||||||
title,
|
title,
|
||||||
exe_name,
|
exe_name,
|
||||||
class,
|
class,
|
||||||
|
path,
|
||||||
&manage_identifiers,
|
&manage_identifiers,
|
||||||
®ex_identifiers,
|
®ex_identifiers,
|
||||||
);
|
);
|
||||||
@@ -495,6 +506,7 @@ fn window_is_eligible(
|
|||||||
title,
|
title,
|
||||||
exe_name,
|
exe_name,
|
||||||
class,
|
class,
|
||||||
|
path,
|
||||||
&layered_whitelist,
|
&layered_whitelist,
|
||||||
®ex_identifiers,
|
®ex_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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
®ex_identifiers,
|
®ex_identifiers,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -44,7 +44,8 @@
|
|||||||
"enum": [
|
"enum": [
|
||||||
"Exe",
|
"Exe",
|
||||||
"Class",
|
"Class",
|
||||||
"Title"
|
"Title",
|
||||||
|
"Path"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ApplicationOptions": {
|
"ApplicationOptions": {
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
Reference in New Issue
Block a user