mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-04-25 10:08:33 +02:00
refactor(wm): improve data consistency + scoping
Just a little bit of clean up to make sure that the float rule data structures match the same emerging pattern as the data structures for other kinds of rules. Also some refactoring of Window.should_manage to ensure stricter scoping where locks are gained on global static variables.
This commit is contained in:
@@ -57,10 +57,8 @@ pub enum SocketMessage {
|
||||
// Configuration
|
||||
ReloadConfiguration,
|
||||
WatchConfiguration(bool),
|
||||
FloatClass(String),
|
||||
FloatExe(String),
|
||||
FloatTitle(String),
|
||||
WorkspaceRule(ApplicationIdentifier, String, usize, usize),
|
||||
FloatRule(ApplicationIdentifier, String),
|
||||
ManageRule(ApplicationIdentifier, String),
|
||||
IdentifyTrayApplication(ApplicationIdentifier, String),
|
||||
State,
|
||||
|
||||
@@ -48,9 +48,6 @@ mod winevent_listener;
|
||||
mod workspace;
|
||||
|
||||
lazy_static! {
|
||||
static ref FLOAT_CLASSES: Arc<Mutex<Vec<String>>> = Arc::new(Mutex::new(vec![]));
|
||||
static ref FLOAT_EXES: Arc<Mutex<Vec<String>>> = Arc::new(Mutex::new(vec![]));
|
||||
static ref FLOAT_TITLES: Arc<Mutex<Vec<String>>> = Arc::new(Mutex::new(vec![]));
|
||||
static ref HIDDEN_HWNDS: Arc<Mutex<Vec<isize>>> = Arc::new(Mutex::new(vec![]));
|
||||
static ref LAYERED_EXE_WHITELIST: Arc<Mutex<Vec<String>>> =
|
||||
Arc::new(Mutex::new(vec!["steam.exe".to_string()]));
|
||||
@@ -71,6 +68,7 @@ lazy_static! {
|
||||
static ref WORKSPACE_RULES: Arc<Mutex<HashMap<String, (usize, usize)>>> =
|
||||
Arc::new(Mutex::new(HashMap::new()));
|
||||
static ref MANAGE_IDENTIFIERS: Arc<Mutex<Vec<String>>> = Arc::new(Mutex::new(vec![]));
|
||||
static ref FLOAT_IDENTIFIERS: Arc<Mutex<Vec<String>>> = Arc::new(Mutex::new(vec![]));
|
||||
}
|
||||
|
||||
fn setup() -> Result<(WorkerGuard, WorkerGuard)> {
|
||||
|
||||
@@ -16,9 +16,7 @@ use komorebi_core::SocketMessage;
|
||||
use crate::window_manager;
|
||||
use crate::window_manager::WindowManager;
|
||||
use crate::windows_api::WindowsApi;
|
||||
use crate::FLOAT_CLASSES;
|
||||
use crate::FLOAT_EXES;
|
||||
use crate::FLOAT_TITLES;
|
||||
use crate::FLOAT_IDENTIFIERS;
|
||||
use crate::MANAGE_IDENTIFIERS;
|
||||
use crate::TRAY_AND_MULTI_WINDOW_CLASSES;
|
||||
use crate::TRAY_AND_MULTI_WINDOW_EXES;
|
||||
@@ -52,18 +50,7 @@ pub fn listen_for_commands(wm: Arc<Mutex<WindowManager>>) {
|
||||
impl WindowManager {
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub fn process_command(&mut self, message: SocketMessage) -> Result<()> {
|
||||
let virtual_desktop_id = winvd::helpers::get_current_desktop_number().ok();
|
||||
if let (Some(id), Some(virtual_desktop_id)) = (virtual_desktop_id, self.virtual_desktop_id)
|
||||
{
|
||||
if id != virtual_desktop_id {
|
||||
tracing::warn!(
|
||||
"ignoring events while not on virtual desktop {:?}",
|
||||
virtual_desktop_id
|
||||
);
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
self.validate_virtual_desktop_id();
|
||||
|
||||
match message {
|
||||
SocketMessage::Promote => self.promote_container_to_front()?,
|
||||
@@ -87,24 +74,6 @@ impl WindowManager {
|
||||
SocketMessage::WorkspacePadding(monitor_idx, workspace_idx, size) => {
|
||||
self.set_workspace_padding(monitor_idx, workspace_idx, size)?;
|
||||
}
|
||||
SocketMessage::FloatClass(target) => {
|
||||
let mut float_classes = FLOAT_CLASSES.lock();
|
||||
if !float_classes.contains(&target) {
|
||||
float_classes.push(target);
|
||||
}
|
||||
}
|
||||
SocketMessage::FloatExe(target) => {
|
||||
let mut float_exes = FLOAT_EXES.lock();
|
||||
if !float_exes.contains(&target) {
|
||||
float_exes.push(target);
|
||||
}
|
||||
}
|
||||
SocketMessage::FloatTitle(target) => {
|
||||
let mut float_titles = FLOAT_TITLES.lock();
|
||||
if !float_titles.contains(&target) {
|
||||
float_titles.push(target);
|
||||
}
|
||||
}
|
||||
SocketMessage::WorkspaceRule(identifier, id, monitor_idx, workspace_idx) => {
|
||||
match identifier {
|
||||
ApplicationIdentifier::Exe | ApplicationIdentifier::Class => {
|
||||
@@ -120,17 +89,19 @@ impl WindowManager {
|
||||
}
|
||||
SocketMessage::ManageRule(identifier, id) => match identifier {
|
||||
ApplicationIdentifier::Exe | ApplicationIdentifier::Class => {
|
||||
{
|
||||
let mut manage_identifiers = MANAGE_IDENTIFIERS.lock();
|
||||
if !manage_identifiers.contains(&id) {
|
||||
manage_identifiers.push(id);
|
||||
}
|
||||
let mut manage_identifiers = MANAGE_IDENTIFIERS.lock();
|
||||
if !manage_identifiers.contains(&id) {
|
||||
manage_identifiers.push(id);
|
||||
}
|
||||
|
||||
self.update_focused_workspace(false)?;
|
||||
}
|
||||
ApplicationIdentifier::Title => {}
|
||||
},
|
||||
SocketMessage::FloatRule(_, id) => {
|
||||
let mut float_identifiers = FLOAT_IDENTIFIERS.lock();
|
||||
if !float_identifiers.contains(&id) {
|
||||
float_identifiers.push(id);
|
||||
}
|
||||
}
|
||||
SocketMessage::AdjustContainerPadding(sizing, adjustment) => {
|
||||
self.adjust_container_padding(sizing, adjustment)?;
|
||||
}
|
||||
|
||||
@@ -48,18 +48,7 @@ impl WindowManager {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let virtual_desktop_id = winvd::helpers::get_current_desktop_number().ok();
|
||||
if let (Some(id), Some(virtual_desktop_id)) = (virtual_desktop_id, self.virtual_desktop_id)
|
||||
{
|
||||
if id != virtual_desktop_id {
|
||||
tracing::warn!(
|
||||
"ignoring events while not on virtual desktop {:?}",
|
||||
virtual_desktop_id
|
||||
);
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
self.validate_virtual_desktop_id();
|
||||
|
||||
// Make sure we have the most recently focused monitor from any event
|
||||
match event {
|
||||
|
||||
@@ -15,9 +15,7 @@ use crate::styles::GwlExStyle;
|
||||
use crate::styles::GwlStyle;
|
||||
use crate::window_manager_event::WindowManagerEvent;
|
||||
use crate::windows_api::WindowsApi;
|
||||
use crate::FLOAT_CLASSES;
|
||||
use crate::FLOAT_EXES;
|
||||
use crate::FLOAT_TITLES;
|
||||
use crate::FLOAT_IDENTIFIERS;
|
||||
use crate::HIDDEN_HWNDS;
|
||||
use crate::LAYERED_EXE_WHITELIST;
|
||||
use crate::MANAGE_IDENTIFIERS;
|
||||
@@ -220,10 +218,6 @@ impl Window {
|
||||
|
||||
#[tracing::instrument(fields(exe, title))]
|
||||
pub fn should_manage(self, event: Option<WindowManagerEvent>) -> Result<bool> {
|
||||
let float_classes = FLOAT_CLASSES.lock();
|
||||
let float_exes = FLOAT_EXES.lock();
|
||||
let float_titles = FLOAT_TITLES.lock();
|
||||
|
||||
if self.title().is_err() {
|
||||
return Ok(false);
|
||||
}
|
||||
@@ -241,21 +235,24 @@ impl Window {
|
||||
// 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()) {
|
||||
if float_titles.contains(&title) {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
if float_exes.contains(&exe_name) {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
if let Ok(class) = self.class() {
|
||||
if float_classes.contains(&class) {
|
||||
{
|
||||
let float_identifiers = FLOAT_IDENTIFIERS.lock();
|
||||
if float_identifiers.contains(&title)
|
||||
|| float_identifiers.contains(&exe_name)
|
||||
|| float_identifiers.contains(&class) {
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
|
||||
let allow_layered = LAYERED_EXE_WHITELIST.lock().contains(&exe_name);
|
||||
let managed_override = {
|
||||
let manage_identifiers = MANAGE_IDENTIFIERS.lock();
|
||||
manage_identifiers.contains(&exe_name) || manage_identifiers.contains(&class)
|
||||
};
|
||||
|
||||
let allow_layered = {
|
||||
let layered_exe_whitelist = LAYERED_EXE_WHITELIST.lock();
|
||||
layered_exe_whitelist.contains(&exe_name)
|
||||
};
|
||||
|
||||
let style = self.style()?;
|
||||
let ex_style = self.ex_style()?;
|
||||
@@ -268,21 +265,17 @@ impl Window {
|
||||
// allowing a specific layered window on the whitelist (like Steam), it should
|
||||
// pass this check
|
||||
&& (allow_layered || !ex_style.contains(GwlExStyle::LAYERED))
|
||||
|| MANAGE_IDENTIFIERS.lock().contains(&exe_name) || MANAGE_IDENTIFIERS.lock().contains(&class)
|
||||
|| managed_override
|
||||
{
|
||||
Ok(true)
|
||||
} else {
|
||||
if event.is_some() {
|
||||
tracing::debug!("ignoring (exe: {}, title: {})", exe_name, title);
|
||||
}
|
||||
|
||||
Ok(false)
|
||||
return Ok(true)
|
||||
} else if event.is_some() {
|
||||
tracing::debug!("ignoring (exe: {}, title: {})", exe_name, title);
|
||||
}
|
||||
} else {
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
_ => Ok(false),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,10 +30,9 @@ use crate::window_manager_event::WindowManagerEvent;
|
||||
use crate::windows_api::WindowsApi;
|
||||
use crate::winevent_listener::WINEVENT_CALLBACK_CHANNEL;
|
||||
use crate::workspace::Workspace;
|
||||
use crate::FLOAT_CLASSES;
|
||||
use crate::FLOAT_EXES;
|
||||
use crate::FLOAT_TITLES;
|
||||
use crate::FLOAT_IDENTIFIERS;
|
||||
use crate::LAYERED_EXE_WHITELIST;
|
||||
use crate::MANAGE_IDENTIFIERS;
|
||||
use crate::TRAY_AND_MULTI_WINDOW_CLASSES;
|
||||
use crate::TRAY_AND_MULTI_WINDOW_EXES;
|
||||
use crate::WORKSPACE_RULES;
|
||||
@@ -52,9 +51,8 @@ pub struct WindowManager {
|
||||
pub struct State {
|
||||
pub monitors: Ring<Monitor>,
|
||||
pub is_paused: bool,
|
||||
pub float_classes: Vec<String>,
|
||||
pub float_exes: Vec<String>,
|
||||
pub float_titles: Vec<String>,
|
||||
pub float_identifiers: Vec<String>,
|
||||
pub manage_identifiers: Vec<String>,
|
||||
pub layered_exe_whitelist: Vec<String>,
|
||||
pub tray_and_multi_window_exes: Vec<String>,
|
||||
pub tray_and_multi_window_classes: Vec<String>,
|
||||
@@ -66,9 +64,8 @@ impl From<&mut WindowManager> for State {
|
||||
Self {
|
||||
monitors: wm.monitors.clone(),
|
||||
is_paused: wm.is_paused,
|
||||
float_classes: FLOAT_CLASSES.lock().clone(),
|
||||
float_exes: FLOAT_EXES.lock().clone(),
|
||||
float_titles: FLOAT_TITLES.lock().clone(),
|
||||
float_identifiers: FLOAT_IDENTIFIERS.lock().clone(),
|
||||
manage_identifiers: MANAGE_IDENTIFIERS.lock().clone(),
|
||||
layered_exe_whitelist: LAYERED_EXE_WHITELIST.lock().clone(),
|
||||
tray_and_multi_window_exes: TRAY_AND_MULTI_WINDOW_EXES.lock().clone(),
|
||||
tray_and_multi_window_classes: TRAY_AND_MULTI_WINDOW_CLASSES.lock().clone(),
|
||||
@@ -334,6 +331,20 @@ impl WindowManager {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub fn validate_virtual_desktop_id(&self) {
|
||||
let virtual_desktop_id = winvd::helpers::get_current_desktop_number().ok();
|
||||
if let (Some(id), Some(virtual_desktop_id)) = (virtual_desktop_id, self.virtual_desktop_id)
|
||||
{
|
||||
if id != virtual_desktop_id {
|
||||
tracing::warn!(
|
||||
"ignoring events while not on virtual desktop {}",
|
||||
virtual_desktop_id
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub fn manage_focused_window(&mut self) -> Result<()> {
|
||||
let hwnd = WindowsApi::foreground_window()?;
|
||||
|
||||
@@ -424,17 +424,9 @@ fn main() -> Result<()> {
|
||||
SubCommand::Stop => {
|
||||
send_message(&*SocketMessage::Stop.as_bytes()?)?;
|
||||
}
|
||||
SubCommand::FloatRule(arg) => match arg.identifier {
|
||||
ApplicationIdentifier::Exe => {
|
||||
send_message(&*SocketMessage::FloatExe(arg.id).as_bytes()?)?;
|
||||
}
|
||||
ApplicationIdentifier::Class => {
|
||||
send_message(&*SocketMessage::FloatClass(arg.id).as_bytes()?)?;
|
||||
}
|
||||
ApplicationIdentifier::Title => {
|
||||
send_message(&*SocketMessage::FloatTitle(arg.id).as_bytes()?)?;
|
||||
}
|
||||
},
|
||||
SubCommand::FloatRule(arg) => {
|
||||
send_message(&*SocketMessage::FloatRule(arg.identifier, arg.id).as_bytes()?)?;
|
||||
}
|
||||
SubCommand::ManageRule(arg) => {
|
||||
send_message(&*SocketMessage::ManageRule(arg.identifier, arg.id).as_bytes()?)?;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user