mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-07-15 17:42:43 +02:00
feat(transparency): add ignore rules to config
This commit adds transparency_ignore_rules to the komorebi.json static
configuration format. Windows that match any rules given in this list
will not have transparency applied when they are unfocused.
For example, to ensure that a browser window is not made transparent
when the focused tab is a YouTube video:
```json
"transparency_ignore_rules": [
{
"kind": "Title",
"id": "YouTube",
"matching_strategy": "Contains"
}
]
```
This commit is contained in:
@@ -50,5 +50,8 @@ schemagen:
|
|||||||
cargo run --package komorebic -- application-specific-configuration-schema > schema.asc.json
|
cargo run --package komorebic -- application-specific-configuration-schema > schema.asc.json
|
||||||
cargo run --package komorebi-bar -- --schema > schema.bar.json
|
cargo run --package komorebi-bar -- --schema > schema.bar.json
|
||||||
generate-schema-doc .\schema.json --config template_name=js_offline --config minify=false .\static-config-docs\
|
generate-schema-doc .\schema.json --config template_name=js_offline --config minify=false .\static-config-docs\
|
||||||
|
|
||||||
generate-schema-doc .\schema.bar.json --config template_name=js_offline --config minify=false .\bar-config-docs\
|
generate-schema-doc .\schema.bar.json --config template_name=js_offline --config minify=false .\bar-config-docs\
|
||||||
|
|
||||||
|
rm -Force .\bar-config-docs\schema.html
|
||||||
mv .\bar-config-docs\schema.bar.html .\bar-config-docs\schema.html
|
mv .\bar-config-docs\schema.bar.html .\bar-config-docs\schema.html
|
||||||
|
|||||||
@@ -130,6 +130,7 @@ lazy_static! {
|
|||||||
matching_strategy: Option::from(MatchingStrategy::Equals),
|
matching_strategy: Option::from(MatchingStrategy::Equals),
|
||||||
}),
|
}),
|
||||||
]));
|
]));
|
||||||
|
static ref TRANSPARENCY_BLACKLIST: Arc<Mutex<Vec<MatchingRule>>> = Arc::new(Mutex::new(Vec::new()));
|
||||||
static ref MONITOR_INDEX_PREFERENCES: Arc<Mutex<HashMap<usize, Rect>>> =
|
static ref MONITOR_INDEX_PREFERENCES: Arc<Mutex<HashMap<usize, Rect>>> =
|
||||||
Arc::new(Mutex::new(HashMap::new()));
|
Arc::new(Mutex::new(HashMap::new()));
|
||||||
static ref DISPLAY_INDEX_PREFERENCES: Arc<Mutex<HashMap<usize, String>>> =
|
static ref DISPLAY_INDEX_PREFERENCES: Arc<Mutex<HashMap<usize, String>>> =
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ use crate::MANAGE_IDENTIFIERS;
|
|||||||
use crate::MONITOR_INDEX_PREFERENCES;
|
use crate::MONITOR_INDEX_PREFERENCES;
|
||||||
use crate::OBJECT_NAME_CHANGE_ON_LAUNCH;
|
use crate::OBJECT_NAME_CHANGE_ON_LAUNCH;
|
||||||
use crate::REGEX_IDENTIFIERS;
|
use crate::REGEX_IDENTIFIERS;
|
||||||
|
use crate::TRANSPARENCY_BLACKLIST;
|
||||||
use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS;
|
use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS;
|
||||||
use crate::WINDOWS_11;
|
use crate::WINDOWS_11;
|
||||||
use crate::WORKSPACE_RULES;
|
use crate::WORKSPACE_RULES;
|
||||||
@@ -313,6 +314,9 @@ pub struct StaticConfig {
|
|||||||
/// Alpha value for unfocused window transparency [[0-255]] (default: 200)
|
/// Alpha value for unfocused window transparency [[0-255]] (default: 200)
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub transparency_alpha: Option<u8>,
|
pub transparency_alpha: Option<u8>,
|
||||||
|
/// Individual window transparency ignore rules
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub transparency_ignore_rules: Option<Vec<MatchingRule>>,
|
||||||
/// Global default workspace padding (default: 10)
|
/// Global default workspace padding (default: 10)
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub default_workspace_padding: Option<i32>,
|
pub default_workspace_padding: Option<i32>,
|
||||||
@@ -637,6 +641,7 @@ impl From<&WindowManager> for StaticConfig {
|
|||||||
transparency_alpha: Option::from(
|
transparency_alpha: Option::from(
|
||||||
transparency_manager::TRANSPARENCY_ALPHA.load(Ordering::SeqCst),
|
transparency_manager::TRANSPARENCY_ALPHA.load(Ordering::SeqCst),
|
||||||
),
|
),
|
||||||
|
transparency_ignore_rules: None,
|
||||||
border_style: Option::from(STYLE.load()),
|
border_style: Option::from(STYLE.load()),
|
||||||
border_z_order: Option::from(Z_ORDER.load()),
|
border_z_order: Option::from(Z_ORDER.load()),
|
||||||
border_implementation: Option::from(IMPLEMENTATION.load()),
|
border_implementation: Option::from(IMPLEMENTATION.load()),
|
||||||
@@ -767,6 +772,7 @@ impl StaticConfig {
|
|||||||
let mut tray_and_multi_window_identifiers = TRAY_AND_MULTI_WINDOW_IDENTIFIERS.lock();
|
let mut tray_and_multi_window_identifiers = TRAY_AND_MULTI_WINDOW_IDENTIFIERS.lock();
|
||||||
let mut object_name_change_identifiers = OBJECT_NAME_CHANGE_ON_LAUNCH.lock();
|
let mut object_name_change_identifiers = OBJECT_NAME_CHANGE_ON_LAUNCH.lock();
|
||||||
let mut layered_identifiers = LAYERED_WHITELIST.lock();
|
let mut layered_identifiers = LAYERED_WHITELIST.lock();
|
||||||
|
let mut transparency_blacklist = TRANSPARENCY_BLACKLIST.lock();
|
||||||
|
|
||||||
if let Some(rules) = &mut self.float_rules {
|
if let Some(rules) = &mut self.float_rules {
|
||||||
populate_rules(rules, &mut float_identifiers, &mut regex_identifiers)?;
|
populate_rules(rules, &mut float_identifiers, &mut regex_identifiers)?;
|
||||||
@@ -796,6 +802,10 @@ impl StaticConfig {
|
|||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(rules) = &mut self.transparency_ignore_rules {
|
||||||
|
populate_rules(rules, &mut transparency_blacklist, &mut regex_identifiers)?;
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(stackbar) = &self.stackbar {
|
if let Some(stackbar) = &self.stackbar {
|
||||||
if let Some(height) = &stackbar.height {
|
if let Some(height) = &stackbar.height {
|
||||||
STACKBAR_TAB_HEIGHT.store(*height, Ordering::SeqCst);
|
STACKBAR_TAB_HEIGHT.store(*height, Ordering::SeqCst);
|
||||||
|
|||||||
@@ -9,9 +9,12 @@ use std::sync::atomic::AtomicU8;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::OnceLock;
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
|
use crate::should_act;
|
||||||
use crate::Window;
|
use crate::Window;
|
||||||
use crate::WindowManager;
|
use crate::WindowManager;
|
||||||
use crate::WindowsApi;
|
use crate::WindowsApi;
|
||||||
|
use crate::REGEX_IDENTIFIERS;
|
||||||
|
use crate::TRANSPARENCY_BLACKLIST;
|
||||||
|
|
||||||
pub static TRANSPARENCY_ENABLED: AtomicBool = AtomicBool::new(false);
|
pub static TRANSPARENCY_ENABLED: AtomicBool = AtomicBool::new(false);
|
||||||
pub static TRANSPARENCY_ALPHA: AtomicU8 = AtomicU8::new(200);
|
pub static TRANSPARENCY_ALPHA: AtomicU8 = AtomicU8::new(200);
|
||||||
@@ -133,6 +136,9 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
|||||||
continue 'monitors;
|
continue 'monitors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let transparency_blacklist = TRANSPARENCY_BLACKLIST.lock();
|
||||||
|
let regex_identifiers = REGEX_IDENTIFIERS.lock();
|
||||||
|
|
||||||
for (idx, c) in ws.containers().iter().enumerate() {
|
for (idx, c) in ws.containers().iter().enumerate() {
|
||||||
// Update the transparency for all containers on this workspace
|
// Update the transparency for all containers on this workspace
|
||||||
|
|
||||||
@@ -143,15 +149,37 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
|||||||
let focused_window_idx = c.focused_window_idx();
|
let focused_window_idx = c.focused_window_idx();
|
||||||
for (window_idx, window) in c.windows().iter().enumerate() {
|
for (window_idx, window) in c.windows().iter().enumerate() {
|
||||||
if window_idx == focused_window_idx {
|
if window_idx == focused_window_idx {
|
||||||
match window.transparent() {
|
let mut should_make_transparent = true;
|
||||||
Err(error) => {
|
if !transparency_blacklist.is_empty() {
|
||||||
let hwnd = foreground_hwnd;
|
if let (Ok(title), Ok(exe_name), Ok(class), Ok(path)) = (
|
||||||
tracing::error!(
|
window.title(),
|
||||||
"failed to make unfocused window {hwnd} transparent: {error}"
|
window.exe(),
|
||||||
)
|
window.class(),
|
||||||
|
window.path(),
|
||||||
|
) {
|
||||||
|
let is_blacklisted = should_act(
|
||||||
|
&title,
|
||||||
|
&exe_name,
|
||||||
|
&class,
|
||||||
|
&path,
|
||||||
|
&transparency_blacklist,
|
||||||
|
®ex_identifiers,
|
||||||
|
)
|
||||||
|
.is_some();
|
||||||
|
|
||||||
|
should_make_transparent = !is_blacklisted;
|
||||||
}
|
}
|
||||||
Ok(..) => {
|
}
|
||||||
known_hwnds.lock().push(window.hwnd);
|
|
||||||
|
if should_make_transparent {
|
||||||
|
match window.transparent() {
|
||||||
|
Err(error) => {
|
||||||
|
let hwnd = foreground_hwnd;
|
||||||
|
tracing::error!("failed to make unfocused window {hwnd} transparent: {error}" )
|
||||||
|
}
|
||||||
|
Ok(..) => {
|
||||||
|
known_hwnds.lock().push(window.hwnd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
"title": "KomobarConfig",
|
"title": "KomobarConfig",
|
||||||
"description": "The `komorebi.bar.json` configuration file reference for `v0.1.29`",
|
"description": "The `komorebi.bar.json` configuration file reference for `v0.1.30`",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
"left_widgets",
|
"left_widgets",
|
||||||
|
|||||||
+84
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
"title": "StaticConfig",
|
"title": "StaticConfig",
|
||||||
"description": "The `komorebi.json` static configuration file reference for `v0.1.29`",
|
"description": "The `komorebi.json` static configuration file reference for `v0.1.30`",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"animation": {
|
"animation": {
|
||||||
@@ -2076,6 +2076,89 @@
|
|||||||
"format": "uint8",
|
"format": "uint8",
|
||||||
"minimum": 0.0
|
"minimum": 0.0
|
||||||
},
|
},
|
||||||
|
"transparency_ignore_rules": {
|
||||||
|
"description": "Individual window transparency ignore rules",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"kind"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"kind": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Exe",
|
||||||
|
"Class",
|
||||||
|
"Title",
|
||||||
|
"Path"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"matching_strategy": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Legacy",
|
||||||
|
"Equals",
|
||||||
|
"StartsWith",
|
||||||
|
"EndsWith",
|
||||||
|
"Contains",
|
||||||
|
"Regex",
|
||||||
|
"DoesNotEndWith",
|
||||||
|
"DoesNotStartWith",
|
||||||
|
"DoesNotEqual",
|
||||||
|
"DoesNotContain"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"kind"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"kind": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Exe",
|
||||||
|
"Class",
|
||||||
|
"Title",
|
||||||
|
"Path"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"matching_strategy": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Legacy",
|
||||||
|
"Equals",
|
||||||
|
"StartsWith",
|
||||||
|
"EndsWith",
|
||||||
|
"Contains",
|
||||||
|
"Regex",
|
||||||
|
"DoesNotEndWith",
|
||||||
|
"DoesNotStartWith",
|
||||||
|
"DoesNotEqual",
|
||||||
|
"DoesNotContain"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"tray_and_multi_window_applications": {
|
"tray_and_multi_window_applications": {
|
||||||
"description": "Identify tray and multi-window applications",
|
"description": "Identify tray and multi-window applications",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
|
|||||||
Reference in New Issue
Block a user