From 31b8be1481d045d4cb550690f1ad4f0e40e05c07 Mon Sep 17 00:00:00 2001 From: LGUG2Z Date: Mon, 28 Mar 2022 10:01:38 -0700 Subject: [PATCH] feat(wm): add cmd to id apps with odd launch event A user on the Discord noted that PyCharm windows were not being managed as expected when initially launched. After some digging this seems to be the same issue that was addressed for IntelliJ and Firefox early on in development, where these applications send EVENT_OBJECT_NAMECHANGE on launch instead of the regular event when drawing a new window. The OBJECT_NAME_CHANGE_ON_LAUNCH vec was not previously exposed via komorebic to allow users to identify other applications that exhibit the same behaviour. This commit adds a command to allow users to specify further applications in their configuration files. --- Cargo.lock | 36 +++---- README.md | 146 ++++++++++++++------------- komorebi-core/src/lib.rs | 1 + komorebi/src/process_command.rs | 7 ++ komorebi/src/window_manager.rs | 4 + komorebi/src/window_manager_event.rs | 5 +- komorebic.lib.sample.ahk | 4 + komorebic/src/main.rs | 10 ++ 8 files changed, 122 insertions(+), 91 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ac311318..ed330bb4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -322,9 +322,9 @@ checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" [[package]] name = "getrandom" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77" +checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" dependencies = [ "cfg-if 1.0.0", "libc", @@ -544,9 +544,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.14" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" dependencies = [ "cfg-if 1.0.0", ] @@ -742,9 +742,9 @@ dependencies = [ [[package]] name = "owo-colors" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20448fd678ec04e6ea15bbe0476874af65e98a01515d667aa49f1434dc44ebf4" +checksum = "5e72e30578e0d0993c8ae20823dd9cff2bc5517d2f586a8aef462a581e8a03eb" [[package]] name = "parking_lot" @@ -774,9 +774,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5" +checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc" [[package]] name = "petgraph" @@ -841,9 +841,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4af2ec4714533fcdf07e886f17025ace8b997b9ce51204ee69b6da831c3da57" +checksum = "632d02bff7f874a36f33ea8bb416cd484b90cc66c1194b1a1110d067a7013f58" dependencies = [ "proc-macro2", ] @@ -942,9 +942,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8380fe0152551244f0747b1bf41737e0f8a74f97a14ccefd1148187271634f3c" +checksum = "8ae183fc1b06c149f0c1793e1eb447c8b04bfe46d48e9e48bfb8d2d7ed64ecf0" dependencies = [ "bitflags", ] @@ -1155,9 +1155,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.89" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea297be220d52398dcc07ce15a209fce436d361735ac1db700cab3b6cdfb9f54" +checksum = "704df27628939572cd88d33f171cd6f896f4eaca85252c6e0a72d8d8287ee86f" dependencies = [ "proc-macro2", "quote", @@ -1259,9 +1259,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.7" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "004cbc98f30fa233c61a38bc77e96a9106e65c88f2d3bef182ae952027e5753d" +checksum = "c2702e08a7a860f005826c6815dcac101b19b5eb330c27fe4a5928fec1d20ddd" dependencies = [ "itoa", "libc", @@ -1398,9 +1398,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "which" -version = "4.2.4" +version = "4.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a5a7e487e921cf220206864a94a89b6c6905bfc19f1057fa26a4cb360e5c1d2" +checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" dependencies = [ "either", "lazy_static", diff --git a/README.md b/README.md index 5c67fbae..1c16ec8a 100644 --- a/README.md +++ b/README.md @@ -315,78 +315,80 @@ keybindings with. You can run `komorebic.exe --help` to get a full exp each command. ``` -start Start komorebi.exe as a background process -stop Stop the komorebi.exe process and restore all hidden windows -state Show a JSON representation of the current window manager state -query Query the current window manager state -subscribe Subscribe to komorebi events -unsubscribe Unsubscribe from komorebi events -log Tail komorebi.exe's process logs (cancel with Ctrl-C) -quick-save-resize Quicksave the current resize layout dimensions -quick-load-resize Load the last quicksaved resize layout dimensions -save-resize Save the current resize layout dimensions to a file -load-resize Load the resize layout dimensions from a file -focus Change focus to the window in the specified direction -move Move the focused window in the specified direction -cycle-focus Change focus to the window in the specified cycle direction -cycle-move Move the focused window in the specified cycle direction -stack Stack the focused window in the specified direction -resize-edge Resize the focused window in the specified direction -resize-axis Resize the focused window or primary column along the specified axis -unstack Unstack the focused window -cycle-stack Cycle the focused stack in the specified cycle direction -move-to-monitor Move the focused window to the specified monitor -move-to-workspace Move the focused window to the specified workspace -send-to-monitor Send the focused window to the specified monitor -send-to-workspace Send the focused window to the specified workspace -send-to-monitor-workspace Send the focused window to the specified monitor workspace -focus-monitor Focus the specified monitor -focus-workspace Focus the specified workspace on the focused monitor -focus-monitor-workspace Focus the specified workspace on the target monitor -cycle-monitor Focus the monitor in the given cycle direction -cycle-workspace Focus the workspace in the given cycle direction -move-workspace-to-monitor Move the focused workspace to the specified monitor -new-workspace Create and append a new workspace on the focused monitor -resize-delta Set the resize delta (used by resize-edge and resize-axis) -invisible-borders Set the invisible border dimensions around each window -work-area-offset Set offsets to exclude parts of the work area from tiling -adjust-container-padding Adjust container padding on the focused workspace -adjust-workspace-padding Adjust workspace padding on the focused workspace -change-layout Set the layout on the focused workspace -load-custom-layout Load a custom layout from file for the focused workspace -flip-layout Flip the layout on the focused workspace (BSP only) -promote Promote the focused window to the top of the tree -retile Force the retiling of all managed windows -ensure-workspaces Create at least this many workspaces for the specified monitor -container-padding Set the container padding for the specified workspace -workspace-padding Set the workspace padding for the specified workspace -workspace-layout Set the layout for the specified workspace -workspace-custom-layout Set a custom layout for the specified workspace -workspace-tiling Enable or disable window tiling for the specified workspace -workspace-name Set the workspace name for the specified workspace -toggle-window-container-behaviour Toggle the behaviour for new windows (stacking or dynamic tiling) -toggle-pause Toggle window tiling on the focused workspace -toggle-tiling Toggle window tiling on the focused workspace -toggle-float Toggle floating mode for the focused window -toggle-monocle Toggle monocle mode for the focused container -toggle-maximize Toggle native maximization for the focused window -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) -watch-configuration Enable or disable watching of ~/komorebi.ahk (if it exists) -window-hiding-behaviour Set the window behaviour when switching workspaces / cycling stacks -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 -identify-tray-application Identify an application that closes to the system tray -identify-border-overflow Identify an application that has overflowing borders -focus-follows-mouse Enable or disable focus follows mouse for the operating system -toggle-focus-follows-mouse Toggle focus follows mouse for the operating system -mouse-follows-focus Enable or disable mouse follows focus on all workspaces -toggle-mouse-follows-focus Toggle mouse follows focus on all workspaces -ahk-library Generate a library of AutoHotKey helper functions -help Print this message or the help of the given subcommand(s) +start Start komorebi.exe as a background process +stop Stop the komorebi.exe process and restore all hidden windows +state Show a JSON representation of the current window manager state +query Query the current window manager state +subscribe Subscribe to komorebi events +unsubscribe Unsubscribe from komorebi events +log Tail komorebi.exe's process logs (cancel with Ctrl-C) +quick-save-resize Quicksave the current resize layout dimensions +quick-load-resize Load the last quicksaved resize layout dimensions +save-resize Save the current resize layout dimensions to a file +load-resize Load the resize layout dimensions from a file +focus Change focus to the window in the specified direction +move Move the focused window in the specified direction +cycle-focus Change focus to the window in the specified cycle direction +cycle-move Move the focused window in the specified cycle direction +stack Stack the focused window in the specified direction +resize-edge Resize the focused window in the specified direction +resize-axis Resize the focused window or primary column along the specified axis +unstack Unstack the focused window +cycle-stack Cycle the focused stack in the specified cycle direction +move-to-monitor Move the focused window to the specified monitor +move-to-workspace Move the focused window to the specified workspace +send-to-monitor Send the focused window to the specified monitor +send-to-workspace Send the focused window to the specified workspace +send-to-monitor-workspace Send the focused window to the specified monitor workspace +focus-monitor Focus the specified monitor +focus-workspace Focus the specified workspace on the focused monitor +focus-monitor-workspace Focus the specified workspace on the target monitor +cycle-monitor Focus the monitor in the given cycle direction +cycle-workspace Focus the workspace in the given cycle direction +move-workspace-to-monitor Move the focused workspace to the specified monitor +new-workspace Create and append a new workspace on the focused monitor +resize-delta Set the resize delta (used by resize-edge and resize-axis) +invisible-borders Set the invisible border dimensions around each window +work-area-offset Set offsets to exclude parts of the work area from tiling +adjust-container-padding Adjust container padding on the focused workspace +adjust-workspace-padding Adjust workspace padding on the focused workspace +change-layout Set the layout on the focused workspace +load-custom-layout Load a custom layout from file for the focused workspace +flip-layout Flip the layout on the focused workspace (BSP only) +promote Promote the focused window to the top of the tree +retile Force the retiling of all managed windows +ensure-workspaces Create at least this many workspaces for the specified monitor +container-padding Set the container padding for the specified workspace +workspace-padding Set the workspace padding for the specified workspace +workspace-layout Set the layout for the specified workspace +workspace-custom-layout Set a custom layout for the specified workspace +workspace-tiling Enable or disable window tiling for the specified workspace +workspace-name Set the workspace name for the specified workspace +toggle-window-container-behaviour Toggle the behaviour for new windows (stacking or dynamic tiling) +toggle-pause Toggle window tiling on the focused workspace +toggle-tiling Toggle window tiling on the focused workspace +toggle-float Toggle floating mode for the focused window +toggle-monocle Toggle monocle mode for the focused container +toggle-maximize Toggle native maximization for the focused window +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) +watch-configuration Enable or disable watching of ~/komorebi.ahk (if it exists) +window-hiding-behaviour Set the window behaviour when switching workspaces / cycling stacks +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 +identify-object-name-change-application Identify an application that sends EVENT_OBJECT_NAMECHANGE on launch +identify-tray-application Identify an application that closes to the system tray +identify-border-overflow Identify an application that has overflowing borders +focus-follows-mouse Enable or disable focus follows mouse for the operating system +toggle-focus-follows-mouse Toggle focus follows mouse for the operating system +mouse-follows-focus Enable or disable mouse follows focus on all workspaces +toggle-mouse-follows-focus Toggle mouse follows focus on all workspaces +ahk-library Generate a library of AutoHotKey helper functions +notification-schema Generate a JSON Schema of subscription notifications +help Print this message or the help of the given subcommand(s) ``` ### AutoHotKey Helper Library for `komorebic` diff --git a/komorebi-core/src/lib.rs b/komorebi-core/src/lib.rs index d7548666..d694369e 100644 --- a/komorebi-core/src/lib.rs +++ b/komorebi-core/src/lib.rs @@ -95,6 +95,7 @@ pub enum SocketMessage { WorkspaceRule(ApplicationIdentifier, String, usize, usize), FloatRule(ApplicationIdentifier, String), ManageRule(ApplicationIdentifier, String), + IdentifyObjectNameChangeApplication(ApplicationIdentifier, String), IdentifyTrayApplication(ApplicationIdentifier, String), IdentifyBorderOverflow(ApplicationIdentifier, String), State, diff --git a/komorebi/src/process_command.rs b/komorebi/src/process_command.rs index fb5506b2..2a80b19a 100644 --- a/komorebi/src/process_command.rs +++ b/komorebi/src/process_command.rs @@ -40,6 +40,7 @@ use crate::FLOAT_IDENTIFIERS; use crate::HIDING_BEHAVIOUR; use crate::HOME_DIR; use crate::MANAGE_IDENTIFIERS; +use crate::OBJECT_NAME_CHANGE_ON_LAUNCH; use crate::SUBSCRIPTION_PIPES; use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS; use crate::WORKSPACE_RULES; @@ -526,6 +527,12 @@ impl WindowManager { identifiers.push(id); } } + SocketMessage::IdentifyObjectNameChangeApplication(_, id) => { + let mut identifiers = OBJECT_NAME_CHANGE_ON_LAUNCH.lock(); + if !identifiers.contains(&id) { + identifiers.push(id); + } + } SocketMessage::IdentifyTrayApplication(_, id) => { let mut identifiers = TRAY_AND_MULTI_WINDOW_IDENTIFIERS.lock(); if !identifiers.contains(&id) { diff --git a/komorebi/src/window_manager.rs b/komorebi/src/window_manager.rs index 0025aaf2..68d61321 100644 --- a/komorebi/src/window_manager.rs +++ b/komorebi/src/window_manager.rs @@ -42,6 +42,7 @@ use crate::FLOAT_IDENTIFIERS; use crate::HOME_DIR; use crate::LAYERED_EXE_WHITELIST; use crate::MANAGE_IDENTIFIERS; +use crate::OBJECT_NAME_CHANGE_ON_LAUNCH; use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS; use crate::WORKSPACE_RULES; @@ -79,6 +80,7 @@ pub struct State { pub layered_exe_whitelist: Vec, pub tray_and_multi_window_identifiers: Vec, pub border_overflow_identifiers: Vec, + pub name_change_on_launch_identifiers: Vec, } impl AsRef for WindowManager { @@ -104,6 +106,7 @@ impl From<&WindowManager> for State { layered_exe_whitelist: LAYERED_EXE_WHITELIST.lock().clone(), tray_and_multi_window_identifiers: TRAY_AND_MULTI_WINDOW_IDENTIFIERS.lock().clone(), border_overflow_identifiers: BORDER_OVERFLOW_IDENTIFIERS.lock().clone(), + name_change_on_launch_identifiers: OBJECT_NAME_CHANGE_ON_LAUNCH.lock().clone(), } } } @@ -310,6 +313,7 @@ impl WindowManager { should_update = true; } + if reference.size() != monitor.size() { monitor.set_size(Rect { left: reference.size().left, diff --git a/komorebi/src/window_manager_event.rs b/komorebi/src/window_manager_event.rs index c6061361..95477037 100644 --- a/komorebi/src/window_manager_event.rs +++ b/komorebi/src/window_manager_event.rs @@ -138,7 +138,10 @@ impl WindowManagerEvent { let object_name_change_on_launch = OBJECT_NAME_CHANGE_ON_LAUNCH.lock(); - if object_name_change_on_launch.contains(&window.exe().ok()?) { + if object_name_change_on_launch.contains(&window.exe().ok()?) + || object_name_change_on_launch.contains(&window.class().ok()?) + || object_name_change_on_launch.contains(&window.title().ok()?) + { Option::from(Self::Show(winevent, window)) } else { None diff --git a/komorebic.lib.sample.ahk b/komorebic.lib.sample.ahk index e97d065b..7510e7d1 100644 --- a/komorebic.lib.sample.ahk +++ b/komorebic.lib.sample.ahk @@ -256,6 +256,10 @@ WorkspaceRule(identifier, id, monitor, workspace) { Run, komorebic.exe workspace-rule %identifier% %id% %monitor% %workspace%, , Hide } +IdentifyObjectNameChangeApplication(identifier, id) { + Run, komorebic.exe identify-object-name-change-application %identifier% %id%, , Hide +} + IdentifyTrayApplication(identifier, id) { Run, komorebic.exe identify-tray-application %identifier% %id%, , Hide } diff --git a/komorebic/src/main.rs b/komorebic/src/main.rs index 863d496d..9d53ee8d 100644 --- a/komorebic/src/main.rs +++ b/komorebic/src/main.rs @@ -314,6 +314,7 @@ gen_application_target_subcommand_args! { FloatRule, ManageRule, IdentifyTrayApplication, + IdentifyObjectNameChangeApplication, IdentifyBorderOverflow, } @@ -566,6 +567,9 @@ enum SubCommand { /// Add a rule to associate an application with a workspace #[clap(arg_required_else_help = true)] WorkspaceRule(WorkspaceRule), + /// Identify an application that sends EVENT_OBJECT_NAMECHANGE on launch + #[clap(arg_required_else_help = true)] + IdentifyObjectNameChangeApplication(IdentifyObjectNameChangeApplication), /// Identify an application that closes to the system tray #[clap(arg_required_else_help = true)] IdentifyTrayApplication(IdentifyTrayApplication), @@ -988,6 +992,12 @@ fn main() -> Result<()> { &*SocketMessage::WatchConfiguration(arg.boolean_state.into()).as_bytes()?, )?; } + SubCommand::IdentifyObjectNameChangeApplication(target) => { + send_message( + &*SocketMessage::IdentifyObjectNameChangeApplication(target.identifier, target.id) + .as_bytes()?, + )?; + } SubCommand::IdentifyTrayApplication(target) => { send_message( &*SocketMessage::IdentifyTrayApplication(target.identifier, target.id)