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:
LGUG2Z
2021-08-19 17:18:22 -07:00
parent 6f7e87799b
commit 2e86b607b2
7 changed files with 59 additions and 107 deletions

View File

@@ -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,

View File

@@ -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)> {

View File

@@ -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)?;
}

View File

@@ -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 {

View File

@@ -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)
}
}

View File

@@ -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()?;

View File

@@ -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()?)?;
}