mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-04-25 10:08:33 +02:00
feat(wm): separate floating and ignored apps
This commit is contained in:
@@ -49,6 +49,8 @@ lazy_static! {
|
|||||||
pub static ref MONOCLE: AtomicU32 =
|
pub static ref MONOCLE: AtomicU32 =
|
||||||
AtomicU32::new(u32::from(Colour::Rgb(Rgb::new(255, 51, 153))));
|
AtomicU32::new(u32::from(Colour::Rgb(Rgb::new(255, 51, 153))));
|
||||||
pub static ref STACK: AtomicU32 = AtomicU32::new(u32::from(Colour::Rgb(Rgb::new(0, 165, 66))));
|
pub static ref STACK: AtomicU32 = AtomicU32::new(u32::from(Colour::Rgb(Rgb::new(0, 165, 66))));
|
||||||
|
pub static ref FLOATING: AtomicU32 =
|
||||||
|
AtomicU32::new(u32::from(Colour::Rgb(Rgb::new(245, 245, 165))));
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
@@ -57,7 +59,7 @@ lazy_static! {
|
|||||||
static ref FOCUS_STATE: Mutex<HashMap<isize, WindowKind>> = Mutex::new(HashMap::new());
|
static ref FOCUS_STATE: Mutex<HashMap<isize, WindowKind>> = Mutex::new(HashMap::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Notification;
|
pub struct Notification(pub Option<isize>);
|
||||||
|
|
||||||
static CHANNEL: OnceLock<(Sender<Notification>, Receiver<Notification>)> = OnceLock::new();
|
static CHANNEL: OnceLock<(Sender<Notification>, Receiver<Notification>)> = OnceLock::new();
|
||||||
|
|
||||||
@@ -73,8 +75,8 @@ fn event_rx() -> Receiver<Notification> {
|
|||||||
channel().1.clone()
|
channel().1.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_notification() {
|
pub fn send_notification(hwnd: Option<isize>) {
|
||||||
if event_tx().try_send(Notification).is_err() {
|
if event_tx().try_send(Notification(hwnd)).is_err() {
|
||||||
tracing::warn!("channel is full; dropping notification")
|
tracing::warn!("channel is full; dropping notification")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,6 +120,7 @@ fn window_kind_colour(focus_kind: WindowKind) -> u32 {
|
|||||||
WindowKind::Single => FOCUSED.load(Ordering::SeqCst),
|
WindowKind::Single => FOCUSED.load(Ordering::SeqCst),
|
||||||
WindowKind::Stack => STACK.load(Ordering::SeqCst),
|
WindowKind::Stack => STACK.load(Ordering::SeqCst),
|
||||||
WindowKind::Monocle => MONOCLE.load(Ordering::SeqCst),
|
WindowKind::Monocle => MONOCLE.load(Ordering::SeqCst),
|
||||||
|
WindowKind::Floating => FLOATING.load(Ordering::SeqCst),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,19 +142,29 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
|||||||
|
|
||||||
BORDER_TEMPORARILY_DISABLED.store(false, Ordering::SeqCst);
|
BORDER_TEMPORARILY_DISABLED.store(false, Ordering::SeqCst);
|
||||||
let receiver = event_rx();
|
let receiver = event_rx();
|
||||||
event_tx().send(Notification)?;
|
event_tx().send(Notification(None))?;
|
||||||
|
|
||||||
let mut previous_snapshot = Ring::default();
|
let mut previous_snapshot = Ring::default();
|
||||||
let mut previous_pending_move_op = None;
|
let mut previous_pending_move_op = None;
|
||||||
let mut previous_is_paused = false;
|
let mut previous_is_paused = false;
|
||||||
|
let mut previous_notification: Option<Notification> = None;
|
||||||
|
|
||||||
'receiver: for _ in receiver {
|
'receiver: for notification in receiver {
|
||||||
// Check the wm state every time we receive a notification
|
// Check the wm state every time we receive a notification
|
||||||
let state = wm.lock();
|
let state = wm.lock();
|
||||||
let is_paused = state.is_paused;
|
let is_paused = state.is_paused;
|
||||||
let focused_monitor_idx = state.focused_monitor_idx();
|
let focused_monitor_idx = state.focused_monitor_idx();
|
||||||
|
let focused_workspace_idx =
|
||||||
|
state.monitors.elements()[focused_monitor_idx].focused_workspace_idx();
|
||||||
let monitors = state.monitors.clone();
|
let monitors = state.monitors.clone();
|
||||||
let pending_move_op = state.pending_move_op;
|
let pending_move_op = state.pending_move_op;
|
||||||
|
let floating_window_hwnds = state.monitors.elements()[focused_monitor_idx].workspaces()
|
||||||
|
[focused_workspace_idx]
|
||||||
|
.floating_windows()
|
||||||
|
.iter()
|
||||||
|
.map(|w| w.hwnd)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
drop(state);
|
drop(state);
|
||||||
|
|
||||||
match IMPLEMENTATION.load() {
|
match IMPLEMENTATION.load() {
|
||||||
@@ -220,6 +233,21 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
|||||||
should_process_notification = true;
|
should_process_notification = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// when we switch focus to a floating window
|
||||||
|
if !should_process_notification
|
||||||
|
&& floating_window_hwnds.contains(¬ification.0.unwrap_or_default())
|
||||||
|
{
|
||||||
|
should_process_notification = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !should_process_notification {
|
||||||
|
if let Some(ref previous) = previous_notification {
|
||||||
|
if previous.0.unwrap_or_default() != notification.0.unwrap_or_default() {
|
||||||
|
should_process_notification = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !should_process_notification {
|
if !should_process_notification {
|
||||||
tracing::trace!("monitor state matches latest snapshot, skipping notification");
|
tracing::trace!("monitor state matches latest snapshot, skipping notification");
|
||||||
continue 'receiver;
|
continue 'receiver;
|
||||||
@@ -446,6 +474,68 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
|||||||
|
|
||||||
border.update(&rect, should_invalidate)?;
|
border.update(&rect, should_invalidate)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let restore_z_order = Z_ORDER.load();
|
||||||
|
Z_ORDER.store(ZOrder::TopMost);
|
||||||
|
|
||||||
|
'windows: for window in ws.floating_windows() {
|
||||||
|
let border = match borders.entry(window.hwnd.to_string()) {
|
||||||
|
Entry::Occupied(entry) => entry.into_mut(),
|
||||||
|
Entry::Vacant(entry) => {
|
||||||
|
if let Ok(border) = Border::create(&window.hwnd.to_string())
|
||||||
|
{
|
||||||
|
entry.insert(border)
|
||||||
|
} else {
|
||||||
|
continue 'monitors;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
borders_monitors.insert(window.hwnd.to_string(), monitor_idx);
|
||||||
|
|
||||||
|
let mut should_destroy = false;
|
||||||
|
|
||||||
|
if let Some(notification_hwnd) = notification.0 {
|
||||||
|
if notification_hwnd != window.hwnd {
|
||||||
|
should_destroy = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if WindowsApi::foreground_window().unwrap_or_default()
|
||||||
|
!= window.hwnd
|
||||||
|
{
|
||||||
|
should_destroy = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if should_destroy {
|
||||||
|
border.destroy()?;
|
||||||
|
borders.remove(&window.hwnd.to_string());
|
||||||
|
borders_monitors.remove(&window.hwnd.to_string());
|
||||||
|
continue 'windows;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unused_assignments)]
|
||||||
|
let mut last_focus_state = None;
|
||||||
|
let new_focus_state = WindowKind::Floating;
|
||||||
|
{
|
||||||
|
let mut focus_state = FOCUS_STATE.lock();
|
||||||
|
last_focus_state =
|
||||||
|
focus_state.insert(border.hwnd, new_focus_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
let rect = WindowsApi::window_rect(window.hwnd)?;
|
||||||
|
|
||||||
|
let should_invalidate = match last_focus_state {
|
||||||
|
None => true,
|
||||||
|
Some(last_focus_state) => last_focus_state != new_focus_state,
|
||||||
|
};
|
||||||
|
|
||||||
|
border.update(&rect, should_invalidate)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Z_ORDER.store(restore_z_order);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -454,6 +544,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
|||||||
previous_snapshot = monitors;
|
previous_snapshot = monitors;
|
||||||
previous_pending_move_op = pending_move_op;
|
previous_pending_move_op = pending_move_op;
|
||||||
previous_is_paused = is_paused;
|
previous_is_paused = is_paused;
|
||||||
|
previous_notification = Some(notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -294,6 +294,7 @@ pub enum WindowKind {
|
|||||||
Stack,
|
Stack,
|
||||||
Monocle,
|
Monocle,
|
||||||
Unfocused,
|
Unfocused,
|
||||||
|
Floating,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
|
|||||||
@@ -158,6 +158,7 @@ lazy_static! {
|
|||||||
matching_strategy: Option::from(MatchingStrategy::Equals),
|
matching_strategy: Option::from(MatchingStrategy::Equals),
|
||||||
})
|
})
|
||||||
]));
|
]));
|
||||||
|
static ref FLOATING_APPLICATIONS: Arc<Mutex<Vec<MatchingRule>>> = Arc::new(Mutex::new(Vec::new()));
|
||||||
static ref PERMAIGNORE_CLASSES: Arc<Mutex<Vec<String>>> = Arc::new(Mutex::new(vec![
|
static ref PERMAIGNORE_CLASSES: Arc<Mutex<Vec<String>>> = Arc::new(Mutex::new(vec![
|
||||||
"Chrome_RenderWidgetHostHWND".to_string(),
|
"Chrome_RenderWidgetHostHWND".to_string(),
|
||||||
]));
|
]));
|
||||||
@@ -224,7 +225,6 @@ lazy_static! {
|
|||||||
|
|
||||||
static ref WINDOWS_BY_BAR_HWNDS: Arc<Mutex<HashMap<isize, VecDeque<isize>>>> =
|
static ref WINDOWS_BY_BAR_HWNDS: Arc<Mutex<HashMap<isize, VecDeque<isize>>>> =
|
||||||
Arc::new(Mutex::new(HashMap::new()));
|
Arc::new(Mutex::new(HashMap::new()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static DEFAULT_WORKSPACE_PADDING: AtomicI32 = AtomicI32::new(10);
|
pub static DEFAULT_WORKSPACE_PADDING: AtomicI32 = AtomicI32::new(10);
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
|||||||
if should_update {
|
if should_update {
|
||||||
tracing::info!("updated work area for {}", monitor.device_id());
|
tracing::info!("updated work area for {}", monitor.device_id());
|
||||||
monitor.update_focused_workspace(offset)?;
|
monitor.update_focused_workspace(offset)?;
|
||||||
border_manager::send_notification();
|
border_manager::send_notification(None);
|
||||||
} else {
|
} else {
|
||||||
tracing::debug!(
|
tracing::debug!(
|
||||||
"work areas match, reconciliation not required for {}",
|
"work areas match, reconciliation not required for {}",
|
||||||
@@ -219,7 +219,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
|||||||
);
|
);
|
||||||
|
|
||||||
monitor.update_focused_workspace(offset)?;
|
monitor.update_focused_workspace(offset)?;
|
||||||
border_manager::send_notification();
|
border_manager::send_notification(None);
|
||||||
} else {
|
} else {
|
||||||
tracing::debug!(
|
tracing::debug!(
|
||||||
"resolutions match, reconciliation not required for {}",
|
"resolutions match, reconciliation not required for {}",
|
||||||
@@ -406,7 +406,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
|||||||
// Second retile to fix DPI/resolution related jank
|
// Second retile to fix DPI/resolution related jank
|
||||||
wm.retile_all(true)?;
|
wm.retile_all(true)?;
|
||||||
// Border updates to fix DPI/resolution related jank
|
// Border updates to fix DPI/resolution related jank
|
||||||
border_manager::send_notification();
|
border_manager::send_notification(None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1395,7 +1395,7 @@ impl WindowManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
border_manager::send_notification();
|
border_manager::send_notification(None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SocketMessage::BorderColour(kind, r, g, b) => match kind {
|
SocketMessage::BorderColour(kind, r, g, b) => match kind {
|
||||||
@@ -1411,6 +1411,9 @@ impl WindowManager {
|
|||||||
WindowKind::Unfocused => {
|
WindowKind::Unfocused => {
|
||||||
border_manager::UNFOCUSED.store(Rgb::new(r, g, b).into(), Ordering::SeqCst);
|
border_manager::UNFOCUSED.store(Rgb::new(r, g, b).into(), Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
WindowKind::Floating => {
|
||||||
|
border_manager::FLOATING.store(Rgb::new(r, g, b).into(), Ordering::SeqCst);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
SocketMessage::BorderStyle(style) => {
|
SocketMessage::BorderStyle(style) => {
|
||||||
STYLE.store(style);
|
STYLE.store(style);
|
||||||
@@ -1540,7 +1543,7 @@ impl WindowManager {
|
|||||||
};
|
};
|
||||||
|
|
||||||
notify_subscribers(&serde_json::to_string(¬ification)?)?;
|
notify_subscribers(&serde_json::to_string(¬ification)?)?;
|
||||||
border_manager::send_notification();
|
border_manager::send_notification(None);
|
||||||
transparency_manager::send_notification();
|
transparency_manager::send_notification();
|
||||||
stackbar_manager::send_notification();
|
stackbar_manager::send_notification();
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ use crate::workspace_reconciliator::ALT_TAB_HWND_INSTANT;
|
|||||||
use crate::Notification;
|
use crate::Notification;
|
||||||
use crate::NotificationEvent;
|
use crate::NotificationEvent;
|
||||||
use crate::DATA_DIR;
|
use crate::DATA_DIR;
|
||||||
|
use crate::FLOATING_APPLICATIONS;
|
||||||
use crate::HIDDEN_HWNDS;
|
use crate::HIDDEN_HWNDS;
|
||||||
use crate::REGEX_IDENTIFIERS;
|
use crate::REGEX_IDENTIFIERS;
|
||||||
use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS;
|
use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS;
|
||||||
@@ -336,19 +337,44 @@ impl WindowManager {
|
|||||||
let monocle_container = workspace.monocle_container().clone();
|
let monocle_container = workspace.monocle_container().clone();
|
||||||
|
|
||||||
if !workspace_contains_window && !needs_reconciliation {
|
if !workspace_contains_window && !needs_reconciliation {
|
||||||
match behaviour {
|
let floating_applications = FLOATING_APPLICATIONS.lock();
|
||||||
WindowContainerBehaviour::Create => {
|
let regex_identifiers = REGEX_IDENTIFIERS.lock();
|
||||||
workspace.new_container_for_window(window);
|
let mut should_float = false;
|
||||||
self.update_focused_workspace(false, false)?;
|
|
||||||
}
|
|
||||||
WindowContainerBehaviour::Append => {
|
|
||||||
workspace
|
|
||||||
.focused_container_mut()
|
|
||||||
.ok_or_else(|| anyhow!("there is no focused container"))?
|
|
||||||
.add_window(window);
|
|
||||||
self.update_focused_workspace(true, false)?;
|
|
||||||
|
|
||||||
stackbar_manager::send_notification();
|
if !floating_applications.is_empty() {
|
||||||
|
if let (Ok(title), Ok(exe_name), Ok(class), Ok(path)) =
|
||||||
|
(window.title(), window.exe(), window.class(), window.path())
|
||||||
|
{
|
||||||
|
should_float = should_act(
|
||||||
|
&title,
|
||||||
|
&exe_name,
|
||||||
|
&class,
|
||||||
|
&path,
|
||||||
|
&floating_applications,
|
||||||
|
®ex_identifiers,
|
||||||
|
)
|
||||||
|
.is_some();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if should_float && !matches!(event, WindowManagerEvent::Manage(_)) {
|
||||||
|
workspace.floating_windows_mut().push(window);
|
||||||
|
self.update_focused_workspace(false, true)?;
|
||||||
|
} else {
|
||||||
|
match behaviour {
|
||||||
|
WindowContainerBehaviour::Create => {
|
||||||
|
workspace.new_container_for_window(window);
|
||||||
|
self.update_focused_workspace(false, false)?;
|
||||||
|
}
|
||||||
|
WindowContainerBehaviour::Append => {
|
||||||
|
workspace
|
||||||
|
.focused_container_mut()
|
||||||
|
.ok_or_else(|| anyhow!("there is no focused container"))?
|
||||||
|
.add_window(window);
|
||||||
|
self.update_focused_workspace(true, false)?;
|
||||||
|
|
||||||
|
stackbar_manager::send_notification();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -642,7 +668,7 @@ impl WindowManager {
|
|||||||
};
|
};
|
||||||
|
|
||||||
notify_subscribers(&serde_json::to_string(¬ification)?)?;
|
notify_subscribers(&serde_json::to_string(¬ification)?)?;
|
||||||
border_manager::send_notification();
|
border_manager::send_notification(Some(event.hwnd()));
|
||||||
transparency_manager::send_notification();
|
transparency_manager::send_notification();
|
||||||
stackbar_manager::send_notification();
|
stackbar_manager::send_notification();
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ pub fn find_orphans(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result<()> {
|
|||||||
let reaped_orphans = workspace.reap_orphans()?;
|
let reaped_orphans = workspace.reap_orphans()?;
|
||||||
if reaped_orphans.0 > 0 || reaped_orphans.1 > 0 {
|
if reaped_orphans.0 > 0 || reaped_orphans.1 > 0 {
|
||||||
workspace.update(&work_area, offset, window_based_work_area_offset)?;
|
workspace.update(&work_area, offset, window_based_work_area_offset)?;
|
||||||
border_manager::send_notification();
|
border_manager::send_notification(None);
|
||||||
tracing::info!(
|
tracing::info!(
|
||||||
"reaped {} orphan window(s) and {} orphaned container(s) on monitor: {}, workspace: {}",
|
"reaped {} orphan window(s) and {} orphaned container(s) on monitor: {}, workspace: {}",
|
||||||
reaped_orphans.0,
|
reaped_orphans.0,
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ use crate::DATA_DIR;
|
|||||||
use crate::DEFAULT_CONTAINER_PADDING;
|
use crate::DEFAULT_CONTAINER_PADDING;
|
||||||
use crate::DEFAULT_WORKSPACE_PADDING;
|
use crate::DEFAULT_WORKSPACE_PADDING;
|
||||||
use crate::DISPLAY_INDEX_PREFERENCES;
|
use crate::DISPLAY_INDEX_PREFERENCES;
|
||||||
|
use crate::FLOATING_APPLICATIONS;
|
||||||
use crate::FLOAT_IDENTIFIERS;
|
use crate::FLOAT_IDENTIFIERS;
|
||||||
use crate::HIDING_BEHAVIOUR;
|
use crate::HIDING_BEHAVIOUR;
|
||||||
use crate::LAYERED_WHITELIST;
|
use crate::LAYERED_WHITELIST;
|
||||||
@@ -304,10 +305,14 @@ pub struct StaticConfig {
|
|||||||
pub global_work_area_offset: Option<Rect>,
|
pub global_work_area_offset: Option<Rect>,
|
||||||
/// Individual window floating rules
|
/// Individual window floating rules
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub float_rules: Option<Vec<MatchingRule>>,
|
#[serde(alias = "float_rules")]
|
||||||
|
pub ignore_rules: Option<Vec<MatchingRule>>,
|
||||||
/// Individual window force-manage rules
|
/// Individual window force-manage rules
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub manage_rules: Option<Vec<MatchingRule>>,
|
pub manage_rules: Option<Vec<MatchingRule>>,
|
||||||
|
/// Identify applications which should be managed as floating windows
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub floating_applications: Option<Vec<MatchingRule>>,
|
||||||
/// Identify border overflow applications
|
/// Identify border overflow applications
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub border_overflow_applications: Option<Vec<MatchingRule>>,
|
pub border_overflow_applications: Option<Vec<MatchingRule>>,
|
||||||
@@ -371,6 +376,8 @@ pub enum KomorebiTheme {
|
|||||||
stack_border: Option<komorebi_themes::CatppuccinValue>,
|
stack_border: Option<komorebi_themes::CatppuccinValue>,
|
||||||
/// Border colour when the container is in monocle mode (default: Pink)
|
/// Border colour when the container is in monocle mode (default: Pink)
|
||||||
monocle_border: Option<komorebi_themes::CatppuccinValue>,
|
monocle_border: Option<komorebi_themes::CatppuccinValue>,
|
||||||
|
/// Border colour when the window is floating (default: Yellow)
|
||||||
|
floating_border: Option<komorebi_themes::CatppuccinValue>,
|
||||||
/// Border colour when the container is unfocused (default: Base)
|
/// Border colour when the container is unfocused (default: Base)
|
||||||
unfocused_border: Option<komorebi_themes::CatppuccinValue>,
|
unfocused_border: Option<komorebi_themes::CatppuccinValue>,
|
||||||
/// Stackbar focused tab text colour (default: Green)
|
/// Stackbar focused tab text colour (default: Green)
|
||||||
@@ -392,6 +399,8 @@ pub enum KomorebiTheme {
|
|||||||
stack_border: Option<komorebi_themes::Base16Value>,
|
stack_border: Option<komorebi_themes::Base16Value>,
|
||||||
/// Border colour when the container is in monocle mode (default: Base0F)
|
/// Border colour when the container is in monocle mode (default: Base0F)
|
||||||
monocle_border: Option<komorebi_themes::Base16Value>,
|
monocle_border: Option<komorebi_themes::Base16Value>,
|
||||||
|
/// Border colour when the window is floating (default: Base09)
|
||||||
|
floating_border: Option<komorebi_themes::Base16Value>,
|
||||||
/// Border colour when the container is unfocused (default: Base01)
|
/// Border colour when the container is unfocused (default: Base01)
|
||||||
unfocused_border: Option<komorebi_themes::Base16Value>,
|
unfocused_border: Option<komorebi_themes::Base16Value>,
|
||||||
/// Stackbar focused tab text colour (default: Base0B)
|
/// Stackbar focused tab text colour (default: Base0B)
|
||||||
@@ -545,7 +554,8 @@ impl From<&WindowManager> for StaticConfig {
|
|||||||
monitors: Option::from(monitors),
|
monitors: Option::from(monitors),
|
||||||
window_hiding_behaviour: Option::from(*HIDING_BEHAVIOUR.lock()),
|
window_hiding_behaviour: Option::from(*HIDING_BEHAVIOUR.lock()),
|
||||||
global_work_area_offset: value.work_area_offset,
|
global_work_area_offset: value.work_area_offset,
|
||||||
float_rules: None,
|
ignore_rules: None,
|
||||||
|
floating_applications: None,
|
||||||
manage_rules: None,
|
manage_rules: None,
|
||||||
border_overflow_applications: None,
|
border_overflow_applications: None,
|
||||||
tray_and_multi_window_applications: None,
|
tray_and_multi_window_applications: None,
|
||||||
@@ -654,7 +664,7 @@ impl StaticConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
border_manager::send_notification();
|
border_manager::send_notification(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
transparency_manager::TRANSPARENCY_ENABLED
|
transparency_manager::TRANSPARENCY_ENABLED
|
||||||
@@ -670,11 +680,16 @@ impl StaticConfig {
|
|||||||
let mut layered_identifiers = LAYERED_WHITELIST.lock();
|
let mut layered_identifiers = LAYERED_WHITELIST.lock();
|
||||||
let mut transparency_blacklist = TRANSPARENCY_BLACKLIST.lock();
|
let mut transparency_blacklist = TRANSPARENCY_BLACKLIST.lock();
|
||||||
let mut slow_application_identifiers = SLOW_APPLICATION_IDENTIFIERS.lock();
|
let mut slow_application_identifiers = SLOW_APPLICATION_IDENTIFIERS.lock();
|
||||||
|
let mut floating_applications = FLOATING_APPLICATIONS.lock();
|
||||||
|
|
||||||
if let Some(rules) = &mut self.float_rules {
|
if let Some(rules) = &mut self.ignore_rules {
|
||||||
populate_rules(rules, &mut float_identifiers, &mut regex_identifiers)?;
|
populate_rules(rules, &mut float_identifiers, &mut regex_identifiers)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(rules) = &mut self.floating_applications {
|
||||||
|
populate_rules(rules, &mut floating_applications, &mut regex_identifiers)?;
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(rules) = &mut self.manage_rules {
|
if let Some(rules) = &mut self.manage_rules {
|
||||||
populate_rules(rules, &mut manage_identifiers, &mut regex_identifiers)?;
|
populate_rules(rules, &mut manage_identifiers, &mut regex_identifiers)?;
|
||||||
}
|
}
|
||||||
@@ -752,6 +767,7 @@ impl StaticConfig {
|
|||||||
single_border,
|
single_border,
|
||||||
stack_border,
|
stack_border,
|
||||||
monocle_border,
|
monocle_border,
|
||||||
|
floating_border,
|
||||||
unfocused_border,
|
unfocused_border,
|
||||||
stackbar_focused_text,
|
stackbar_focused_text,
|
||||||
stackbar_unfocused_text,
|
stackbar_unfocused_text,
|
||||||
@@ -762,6 +778,7 @@ impl StaticConfig {
|
|||||||
single_border,
|
single_border,
|
||||||
stack_border,
|
stack_border,
|
||||||
monocle_border,
|
monocle_border,
|
||||||
|
floating_border,
|
||||||
unfocused_border,
|
unfocused_border,
|
||||||
stackbar_focused_text,
|
stackbar_focused_text,
|
||||||
stackbar_unfocused_text,
|
stackbar_unfocused_text,
|
||||||
@@ -780,6 +797,10 @@ impl StaticConfig {
|
|||||||
.unwrap_or(komorebi_themes::CatppuccinValue::Pink)
|
.unwrap_or(komorebi_themes::CatppuccinValue::Pink)
|
||||||
.color32(name.as_theme());
|
.color32(name.as_theme());
|
||||||
|
|
||||||
|
let floating_border = floating_border
|
||||||
|
.unwrap_or(komorebi_themes::CatppuccinValue::Yellow)
|
||||||
|
.color32(name.as_theme());
|
||||||
|
|
||||||
let unfocused_border = unfocused_border
|
let unfocused_border = unfocused_border
|
||||||
.unwrap_or(komorebi_themes::CatppuccinValue::Base)
|
.unwrap_or(komorebi_themes::CatppuccinValue::Base)
|
||||||
.color32(name.as_theme());
|
.color32(name.as_theme());
|
||||||
@@ -800,6 +821,7 @@ impl StaticConfig {
|
|||||||
single_border,
|
single_border,
|
||||||
stack_border,
|
stack_border,
|
||||||
monocle_border,
|
monocle_border,
|
||||||
|
floating_border,
|
||||||
unfocused_border,
|
unfocused_border,
|
||||||
stackbar_focused_text,
|
stackbar_focused_text,
|
||||||
stackbar_unfocused_text,
|
stackbar_unfocused_text,
|
||||||
@@ -811,6 +833,7 @@ impl StaticConfig {
|
|||||||
single_border,
|
single_border,
|
||||||
stack_border,
|
stack_border,
|
||||||
monocle_border,
|
monocle_border,
|
||||||
|
floating_border,
|
||||||
unfocused_border,
|
unfocused_border,
|
||||||
stackbar_focused_text,
|
stackbar_focused_text,
|
||||||
stackbar_unfocused_text,
|
stackbar_unfocused_text,
|
||||||
@@ -833,6 +856,10 @@ impl StaticConfig {
|
|||||||
.unwrap_or(komorebi_themes::Base16Value::Base01)
|
.unwrap_or(komorebi_themes::Base16Value::Base01)
|
||||||
.color32(*name);
|
.color32(*name);
|
||||||
|
|
||||||
|
let floating_border = floating_border
|
||||||
|
.unwrap_or(komorebi_themes::Base16Value::Base09)
|
||||||
|
.color32(*name);
|
||||||
|
|
||||||
let stackbar_focused_text = stackbar_focused_text
|
let stackbar_focused_text = stackbar_focused_text
|
||||||
.unwrap_or(komorebi_themes::Base16Value::Base0B)
|
.unwrap_or(komorebi_themes::Base16Value::Base0B)
|
||||||
.color32(*name);
|
.color32(*name);
|
||||||
@@ -849,6 +876,7 @@ impl StaticConfig {
|
|||||||
single_border,
|
single_border,
|
||||||
stack_border,
|
stack_border,
|
||||||
monocle_border,
|
monocle_border,
|
||||||
|
floating_border,
|
||||||
unfocused_border,
|
unfocused_border,
|
||||||
stackbar_focused_text,
|
stackbar_focused_text,
|
||||||
stackbar_unfocused_text,
|
stackbar_unfocused_text,
|
||||||
@@ -861,6 +889,8 @@ impl StaticConfig {
|
|||||||
border_manager::MONOCLE
|
border_manager::MONOCLE
|
||||||
.store(u32::from(Colour::from(monocle_border)), Ordering::SeqCst);
|
.store(u32::from(Colour::from(monocle_border)), Ordering::SeqCst);
|
||||||
border_manager::STACK.store(u32::from(Colour::from(stack_border)), Ordering::SeqCst);
|
border_manager::STACK.store(u32::from(Colour::from(stack_border)), Ordering::SeqCst);
|
||||||
|
border_manager::FLOATING
|
||||||
|
.store(u32::from(Colour::from(floating_border)), Ordering::SeqCst);
|
||||||
border_manager::UNFOCUSED
|
border_manager::UNFOCUSED
|
||||||
.store(u32::from(Colour::from(unfocused_border)), Ordering::SeqCst);
|
.store(u32::from(Colour::from(unfocused_border)), Ordering::SeqCst);
|
||||||
|
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ impl Window {
|
|||||||
let mut animation = self.animation;
|
let mut animation = self.animation;
|
||||||
|
|
||||||
border_manager::BORDER_TEMPORARILY_DISABLED.store(true, Ordering::SeqCst);
|
border_manager::BORDER_TEMPORARILY_DISABLED.store(true, Ordering::SeqCst);
|
||||||
border_manager::send_notification();
|
border_manager::send_notification(Some(self.hwnd));
|
||||||
|
|
||||||
stackbar_manager::STACKBAR_TEMPORARILY_DISABLED.store(true, Ordering::SeqCst);
|
stackbar_manager::STACKBAR_TEMPORARILY_DISABLED.store(true, Ordering::SeqCst);
|
||||||
stackbar_manager::send_notification();
|
stackbar_manager::send_notification();
|
||||||
@@ -203,7 +203,7 @@ impl Window {
|
|||||||
stackbar_manager::STACKBAR_TEMPORARILY_DISABLED
|
stackbar_manager::STACKBAR_TEMPORARILY_DISABLED
|
||||||
.store(false, Ordering::SeqCst);
|
.store(false, Ordering::SeqCst);
|
||||||
|
|
||||||
border_manager::send_notification();
|
border_manager::send_notification(Some(hwnd));
|
||||||
stackbar_manager::send_notification();
|
stackbar_manager::send_notification();
|
||||||
transparency_manager::send_notification();
|
transparency_manager::send_notification();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
|||||||
// Unblock the border manager
|
// Unblock the border manager
|
||||||
ALT_TAB_HWND.store(None);
|
ALT_TAB_HWND.store(None);
|
||||||
// Send a notification to the border manager to update the borders
|
// Send a notification to the border manager to update the borders
|
||||||
border_manager::send_notification();
|
border_manager::send_notification(None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user