Skip to content

Commit

Permalink
Added optional parent exclusions
Browse files Browse the repository at this point in the history
  • Loading branch information
mbwilding committed Dec 12, 2023
1 parent 06f58fa commit 69cabbb
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 15 deletions.
10 changes: 9 additions & 1 deletion common/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,13 @@ pub struct AppConfig {
#[serde(skip_serializing_if = "Option::is_none")]
pub process: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub parent: Option<String>,
pub parent: Option<Parent>,
}

#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct Parent {
#[serde(skip_serializing_if = "Option::is_none")]
pub process: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub excludes: Option<Vec<String>>,
}
55 changes: 49 additions & 6 deletions common/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::app::{AppConfig, AppDetails};
use crate::app::{AppConfig, AppDetails, Parent};
use crate::serial;
use serde::{Deserialize, Serialize};
use std::fs::File;
Expand Down Expand Up @@ -134,18 +134,23 @@ impl Config {
app_details
.process
.as_ref()
.and_then(|x| self.match_property(x, |mapping| &mapping.process))
.and_then(|x| self.match_property_opt_string(x, |mapping| &mapping.process))
}

pub fn check_window(&self, app_details: &AppDetails) -> Option<u8> {
app_details
.window
.as_ref()
.and_then(|x| self.match_property(x, |mapping| &mapping.window))
.and_then(|x| self.match_property_opt_string(x, |mapping| &mapping.window))
}

pub fn check_parent(&self, app_details: &AppDetails) -> Option<u8> {
if let Some(process) = &app_details.process {
if self.is_process_excluded(process) {
debug!("Process was excluded from parent process: {:?}", process);
return None;
}

let mut sys = System::new();
sys.refresh_processes();

Expand All @@ -161,6 +166,24 @@ impl Config {
None
}

fn is_process_excluded(&self, process: &str) -> bool {
self.mappings.as_ref().map_or(false, |mappings| {
mappings.iter().any(|mapping| {
if let Some(parent) = &mapping.parent {
if let Some(excludes) = &parent.excludes {
return excludes.iter().any(|excluded_process| {
excluded_process
.to_lowercase()
.contains(&process.to_lowercase())
});
}
}

false
})
})
}

fn check_parent_recursively<F>(
&self,
proc: &Process,
Expand All @@ -169,13 +192,15 @@ impl Config {
level: usize,
) -> Option<u8>
where
F: Fn(&AppConfig) -> &Option<String> + Copy,
F: Fn(&AppConfig) -> &Option<Parent> + Copy,
{
// Recursive call with the parent process
if let Some(parent_pid) = proc.parent() {
if let Some(parent_proc) = sys.processes().get(&parent_pid) {
debug!("Parent: {:?}, Level: {}", parent_proc.name(), level);
if let Some(layer) = self.match_property(parent_proc.name(), mapping_property) {
if let Some(layer) =
self.match_property_opt_parent(parent_proc.name(), mapping_property)
{
return Some(layer);
}
return self.check_parent_recursively(
Expand All @@ -190,7 +215,25 @@ impl Config {
None
}

fn match_property<T, F>(&self, app_property: T, mapping_property: F) -> Option<u8>
fn match_property_opt_parent<T, F>(&self, app_property: T, mapping_property: F) -> Option<u8>
where
T: AsRef<str>,
F: Fn(&AppConfig) -> &Option<Parent>,
{
let app_prop = app_property.as_ref().to_lowercase();

self.mappings.as_ref()?.iter().find_map(|mapping| {
mapping_property(mapping)
.as_ref()?
.process
.as_ref()?
.to_lowercase()
.contains(&app_prop)
.then_some(mapping.layer)
})
}

fn match_property_opt_string<T, F>(&self, app_property: T, mapping_property: F) -> Option<u8>
where
T: AsRef<str>,
F: Fn(&AppConfig) -> &Option<String>,
Expand Down
2 changes: 1 addition & 1 deletion common/src/layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ fn layer_change(config: &Config, layer: u8) {
let command = format!("layer.moveTo {:?}\n", &layer - 1);

if port.write_all(command.as_bytes()).is_ok() {
info!("Layer: {}", layer);
info!("Changed layer: {}", layer);
} else {
error!("Failed to write to serial port: {:?}", &config.comm_port);
}
Expand Down
29 changes: 22 additions & 7 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,34 @@ base_layer: 1

# The mappings, each mapping has a layer and a choice of `window`, `process`, and `parent`, ordered in respect to performance.
# The settings aren't mutually exclusive nor are the layers.
# All setting's values are case insensitive.

# `window` is part of the title of the window, case insensitive.
# `process` is part of the name of the process, case insensitive.
# `parent` is part of the name of any parent process, case insensitive.
# `window` is part of the title of the window.
# `process` is part of the name of the process.
# `parent` has a `process` and an optional `excludes` (array) section.
mappings:
- layer: 5
window: "Blender"
process: "blender.exe"
# Using `window` only.
- layer: 5
window: "Maya"
# Using `process` only.
- layer: 2
process: "some_thing.exe"
# Using `window` and `process` together.
- layer: 3
window: "Parsec"
process: "parsecd.exe"
# Using `parent` only.
- layer: 4
parent:
process: "EpicGamesLauncher.exe"
# Using `parent` only, with excludes.
- layer: 4
parent: "steam.exe"
parent:
process: "steam.exe"
excludes:
- "blender.exe"
- "Quake_x64_steam.exe"
- "bg3.exe"
- "bg3_dx11.exe"

```

0 comments on commit 69cabbb

Please sign in to comment.