mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-07-10 07:02:44 +02:00
feat(wm): add additional manage rules
Following on from 8ffe6f78b7, this commit
introduces a command to add rules to forcibly manage windows that don't
get picked up by the rough heuristics that are able to target most
windows for management in Window.should_manage.
Since there is again no overlap (or at least, no undesired overlap)
between executable names and classes, I'll keep both class and exe names
in a single lookup vec.
re #16
This commit is contained in:
@@ -179,9 +179,12 @@ toggle-float Toggle floating mode for the focused window
|
|||||||
toggle-monocle Toggle monocle mode for the focused container
|
toggle-monocle Toggle monocle mode for the focused container
|
||||||
toggle-maximize Toggle native maximization for the focused window
|
toggle-maximize Toggle native maximization for the focused window
|
||||||
restore-windows Restore all hidden windows (debugging command)
|
restore-windows Restore all hidden windows (debugging command)
|
||||||
|
manage Force komorebi to manage the focused window
|
||||||
|
unmanage Unmanage a window that was forcibly managed
|
||||||
reload-configuration Reload ~/komorebi.ahk (if it exists)
|
reload-configuration Reload ~/komorebi.ahk (if it exists)
|
||||||
watch-configuration Toggle the automatic reloading of ~/komorebi.ahk (if it exists)
|
watch-configuration Toggle the automatic reloading of ~/komorebi.ahk (if it exists)
|
||||||
float-rule Add a rule to always float the specified application
|
float-rule Add a rule to always float the specified application
|
||||||
|
manage-rule Add a rule to always manage the specified application
|
||||||
workspace-rule Add a rule to associate an application with a workspace
|
workspace-rule Add a rule to associate an application with a workspace
|
||||||
identify-tray-application Identify an application that closes to the system tray
|
identify-tray-application Identify an application that closes to the system tray
|
||||||
focus-follows-mouse Enable or disable focus follows mouse for the operating system
|
focus-follows-mouse Enable or disable focus follows mouse for the operating system
|
||||||
@@ -209,6 +212,7 @@ help Print this message or the help of the given subcomm
|
|||||||
- [x] Equal-width, max-height column layout
|
- [x] Equal-width, max-height column layout
|
||||||
- [x] Floating rules based on exe name, window title and class
|
- [x] Floating rules based on exe name, window title and class
|
||||||
- [x] Workspace rules based on exe name and window class
|
- [x] Workspace rules based on exe name and window class
|
||||||
|
- [x] Additional manage rules based on exe name and window class
|
||||||
- [x] Identify 'close/minimize to tray' applications by exe name and class
|
- [x] Identify 'close/minimize to tray' applications by exe name and class
|
||||||
- [x] Toggle floating windows
|
- [x] Toggle floating windows
|
||||||
- [x] Toggle monocle window
|
- [x] Toggle monocle window
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ pub enum SocketMessage {
|
|||||||
FloatExe(String),
|
FloatExe(String),
|
||||||
FloatTitle(String),
|
FloatTitle(String),
|
||||||
WorkspaceRule(ApplicationIdentifier, String, usize, usize),
|
WorkspaceRule(ApplicationIdentifier, String, usize, usize),
|
||||||
|
ManageRule(ApplicationIdentifier, String),
|
||||||
IdentifyTrayApplication(ApplicationIdentifier, String),
|
IdentifyTrayApplication(ApplicationIdentifier, String),
|
||||||
State,
|
State,
|
||||||
FocusFollowsMouse(bool),
|
FocusFollowsMouse(bool),
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ lazy_static! {
|
|||||||
]));
|
]));
|
||||||
static ref WORKSPACE_RULES: Arc<Mutex<HashMap<String, (usize, usize)>>> =
|
static ref WORKSPACE_RULES: Arc<Mutex<HashMap<String, (usize, usize)>>> =
|
||||||
Arc::new(Mutex::new(HashMap::new()));
|
Arc::new(Mutex::new(HashMap::new()));
|
||||||
|
static ref MANAGE_IDENTIFIERS: Arc<Mutex<Vec<String>>> = Arc::new(Mutex::new(vec![]));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup() -> Result<(WorkerGuard, WorkerGuard)> {
|
fn setup() -> Result<(WorkerGuard, WorkerGuard)> {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ use crate::windows_api::WindowsApi;
|
|||||||
use crate::FLOAT_CLASSES;
|
use crate::FLOAT_CLASSES;
|
||||||
use crate::FLOAT_EXES;
|
use crate::FLOAT_EXES;
|
||||||
use crate::FLOAT_TITLES;
|
use crate::FLOAT_TITLES;
|
||||||
|
use crate::MANAGE_IDENTIFIERS;
|
||||||
use crate::TRAY_AND_MULTI_WINDOW_CLASSES;
|
use crate::TRAY_AND_MULTI_WINDOW_CLASSES;
|
||||||
use crate::TRAY_AND_MULTI_WINDOW_EXES;
|
use crate::TRAY_AND_MULTI_WINDOW_EXES;
|
||||||
use crate::WORKSPACE_RULES;
|
use crate::WORKSPACE_RULES;
|
||||||
@@ -116,6 +117,19 @@ impl WindowManager {
|
|||||||
ApplicationIdentifier::Title => {}
|
ApplicationIdentifier::Title => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.update_focused_workspace(false)?;
|
||||||
|
}
|
||||||
|
ApplicationIdentifier::Title => {}
|
||||||
|
},
|
||||||
SocketMessage::AdjustContainerPadding(sizing, adjustment) => {
|
SocketMessage::AdjustContainerPadding(sizing, adjustment) => {
|
||||||
self.adjust_container_padding(sizing, adjustment)?;
|
self.adjust_container_padding(sizing, adjustment)?;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ use crate::FLOAT_EXES;
|
|||||||
use crate::FLOAT_TITLES;
|
use crate::FLOAT_TITLES;
|
||||||
use crate::HIDDEN_HWNDS;
|
use crate::HIDDEN_HWNDS;
|
||||||
use crate::LAYERED_EXE_WHITELIST;
|
use crate::LAYERED_EXE_WHITELIST;
|
||||||
|
use crate::MANAGE_IDENTIFIERS;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct Window {
|
pub struct Window {
|
||||||
@@ -219,9 +220,9 @@ impl Window {
|
|||||||
|
|
||||||
#[tracing::instrument(fields(exe, title))]
|
#[tracing::instrument(fields(exe, title))]
|
||||||
pub fn should_manage(self, event: Option<WindowManagerEvent>) -> Result<bool> {
|
pub fn should_manage(self, event: Option<WindowManagerEvent>) -> Result<bool> {
|
||||||
let classes = FLOAT_CLASSES.lock();
|
let float_classes = FLOAT_CLASSES.lock();
|
||||||
let exes = FLOAT_EXES.lock();
|
let float_exes = FLOAT_EXES.lock();
|
||||||
let titles = FLOAT_TITLES.lock();
|
let float_titles = FLOAT_TITLES.lock();
|
||||||
|
|
||||||
if self.title().is_err() {
|
if self.title().is_err() {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
@@ -239,17 +240,17 @@ impl Window {
|
|||||||
(true, _) |
|
(true, _) |
|
||||||
// If not allowing cloaked windows, we need to ensure the window is not cloaked
|
// If not allowing cloaked windows, we need to ensure the window is not cloaked
|
||||||
(false, false) => {
|
(false, false) => {
|
||||||
if let (Ok(title), Ok(exe_name)) = (self.title(), self.exe()) {
|
if let (Ok(title), Ok(exe_name), Ok(class)) = (self.title(), self.exe(), self.class()) {
|
||||||
if titles.contains(&title) {
|
if float_titles.contains(&title) {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if exes.contains(&exe_name) {
|
if float_exes.contains(&exe_name) {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(class) = self.class() {
|
if let Ok(class) = self.class() {
|
||||||
if classes.contains(&class) {
|
if float_classes.contains(&class) {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -267,6 +268,7 @@ impl Window {
|
|||||||
// allowing a specific layered window on the whitelist (like Steam), it should
|
// allowing a specific layered window on the whitelist (like Steam), it should
|
||||||
// pass this check
|
// pass this check
|
||||||
&& (allow_layered || !ex_style.contains(GwlExStyle::LAYERED))
|
&& (allow_layered || !ex_style.contains(GwlExStyle::LAYERED))
|
||||||
|
|| MANAGE_IDENTIFIERS.lock().contains(&exe_name) || MANAGE_IDENTIFIERS.lock().contains(&class)
|
||||||
{
|
{
|
||||||
Ok(true)
|
Ok(true)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -281,6 +281,9 @@ enum SubCommand {
|
|||||||
/// Add a rule to always float the specified application
|
/// Add a rule to always float the specified application
|
||||||
#[clap(setting = AppSettings::ArgRequiredElseHelp)]
|
#[clap(setting = AppSettings::ArgRequiredElseHelp)]
|
||||||
FloatRule(ApplicationTarget),
|
FloatRule(ApplicationTarget),
|
||||||
|
/// Add a rule to always manage the specified application
|
||||||
|
#[clap(setting = AppSettings::ArgRequiredElseHelp)]
|
||||||
|
ManageRule(ApplicationTarget),
|
||||||
/// Add a rule to associate an application with a workspace
|
/// Add a rule to associate an application with a workspace
|
||||||
#[clap(setting = AppSettings::ArgRequiredElseHelp)]
|
#[clap(setting = AppSettings::ArgRequiredElseHelp)]
|
||||||
WorkspaceRule(WorkspaceRule),
|
WorkspaceRule(WorkspaceRule),
|
||||||
@@ -432,6 +435,9 @@ fn main() -> Result<()> {
|
|||||||
send_message(&*SocketMessage::FloatTitle(arg.id).as_bytes()?)?;
|
send_message(&*SocketMessage::FloatTitle(arg.id).as_bytes()?)?;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
SubCommand::ManageRule(arg) => {
|
||||||
|
send_message(&*SocketMessage::ManageRule(arg.identifier, arg.id).as_bytes()?)?;
|
||||||
|
}
|
||||||
SubCommand::WorkspaceRule(arg) => {
|
SubCommand::WorkspaceRule(arg) => {
|
||||||
send_message(
|
send_message(
|
||||||
&*SocketMessage::WorkspaceRule(arg.identifier, arg.id, arg.monitor, arg.workspace)
|
&*SocketMessage::WorkspaceRule(arg.identifier, arg.id, arg.monitor, arg.workspace)
|
||||||
|
|||||||
Reference in New Issue
Block a user