Skip to content

Commit

Permalink
feat(wm): add cmd to id layered apps
Browse files Browse the repository at this point in the history
Users on Discord noted that Microsoft Office applications were not being
handled correctly by the wm. After some investigation it was clear that
this was because the application windows had WS_EX_LAYERED set.

This had only been seen once before with Steam, and so a whitelist for
layered applications was previously added to the codebase with steam.exe
hard-coded, but this had not been exposed via the cli.

This commit adds a command to allow users to specify layered
applications which should be managed, and also renames the whitelist to
reflect that classes can also be used to identify applications on the
whitelist.

A section has been added to the README to guide Microsoft Office users
to guide Microsoft Office users in configuring komorebi to correctly
handle Office applications with Word given as an example.

This commit also renames the identify-border-overflow command to
identify-border-overflow-application for consistency, while retaining
the previous command as an alias to maintain compatibility with existing
user configurations.

It should be noted however, that those like me who are using the
generated komorebic AHK library, will have to update any AHK function
calls to use IdentifyBorderOverflowApplication().

resolve #124
  • Loading branch information
LGUG2Z committed Mar 30, 2022
1 parent 532adc9 commit 4686d5e
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 70 deletions.
79 changes: 25 additions & 54 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,24 @@ komorebic.exe identify-tray-application exe Discord.exe
# komorebic.exe identify-tray-application title [TITLE]
```

#### Microsoft Office Applications

Microsoft Office applications such as Word and Excel require certain configuration options to be set in order to be
managed correctly. Below is an example of configuring Microsoft Word to be managed correctly by _komorebi_.

```powershell
# This only needs to be added once
komorebic.exe float-rule class _WwB
# Repeat these for other office applications such as EXCEL.EXE etc
# Note that the capitalised EXE is important here- double check the
# exact case for the name and the file extension in Task Manager or
# the AHK Window Spy
komorebic.exe identify-layered-application exe WINWORD.EXE
komorebic.exe identify-border-overflow-application exe WINWORD.EXE
```

#### Focus Follows Mouse

`komorebi` supports two focus-follows-mouse implementations; the native Windows Xmouse implementation, which treats the
Expand Down Expand Up @@ -409,7 +427,8 @@ manage-rule Add a rule to always manage the speci
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
identify-layered-application Identify an application that has WS_EX_LAYERED, but should still be managed
identify-border-overflow-application 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
Expand Down
3 changes: 2 additions & 1 deletion komorebi-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ pub enum SocketMessage {
ManageRule(ApplicationIdentifier, String),
IdentifyObjectNameChangeApplication(ApplicationIdentifier, String),
IdentifyTrayApplication(ApplicationIdentifier, String),
IdentifyBorderOverflow(ApplicationIdentifier, String),
IdentifyLayeredApplication(ApplicationIdentifier, String),
IdentifyBorderOverflowApplication(ApplicationIdentifier, String),
State,
Query(StateQuery),
FocusFollowsMouse(FocusFollowsMouseImplementation, bool),
Expand Down
2 changes: 1 addition & 1 deletion komorebi/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ mod workspace;

lazy_static! {
static ref HIDDEN_HWNDS: Arc<Mutex<Vec<isize>>> = Arc::new(Mutex::new(vec![]));
static ref LAYERED_EXE_WHITELIST: Arc<Mutex<Vec<String>>> =
static ref LAYERED_WHITELIST: Arc<Mutex<Vec<String>>> =
Arc::new(Mutex::new(vec!["steam.exe".to_string()]));
static ref TRAY_AND_MULTI_WINDOW_IDENTIFIERS: Arc<Mutex<Vec<String>>> =
Arc::new(Mutex::new(vec![
Expand Down
9 changes: 8 additions & 1 deletion komorebi/src/process_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ use crate::CUSTOM_FFM;
use crate::FLOAT_IDENTIFIERS;
use crate::HIDING_BEHAVIOUR;
use crate::HOME_DIR;
use crate::LAYERED_WHITELIST;
use crate::MANAGE_IDENTIFIERS;
use crate::OBJECT_NAME_CHANGE_ON_LAUNCH;
use crate::SUBSCRIPTION_PIPES;
Expand Down Expand Up @@ -550,7 +551,7 @@ impl WindowManager {
SocketMessage::WatchConfiguration(enable) => {
self.watch_configuration(enable)?;
}
SocketMessage::IdentifyBorderOverflow(_, id) => {
SocketMessage::IdentifyBorderOverflowApplication(_, id) => {
let mut identifiers = BORDER_OVERFLOW_IDENTIFIERS.lock();
if !identifiers.contains(&id) {
identifiers.push(id);
Expand All @@ -568,6 +569,12 @@ impl WindowManager {
identifiers.push(id);
}
}
SocketMessage::IdentifyLayeredApplication(_, id) => {
let mut identifiers = LAYERED_WHITELIST.lock();
if !identifiers.contains(&id) {
identifiers.push(id);
}
}
SocketMessage::ManageFocusedWindow => {
self.manage_focused_window()?;
}
Expand Down
6 changes: 3 additions & 3 deletions komorebi/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::BORDER_OVERFLOW_IDENTIFIERS;
use crate::FLOAT_IDENTIFIERS;
use crate::HIDDEN_HWNDS;
use crate::HIDING_BEHAVIOUR;
use crate::LAYERED_EXE_WHITELIST;
use crate::LAYERED_WHITELIST;
use crate::MANAGE_IDENTIFIERS;
use crate::WSL2_UI_PROCESSES;

Expand Down Expand Up @@ -295,8 +295,8 @@ impl Window {
};

let allow_layered = {
let layered_exe_whitelist = LAYERED_EXE_WHITELIST.lock();
layered_exe_whitelist.contains(&exe_name)
let layered_whitelist = LAYERED_WHITELIST.lock();
layered_whitelist.contains(&exe_name) || layered_whitelist.contains(&class)
};

let allow_wsl2_gui = {
Expand Down
6 changes: 3 additions & 3 deletions komorebi/src/window_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ use crate::workspace::Workspace;
use crate::BORDER_OVERFLOW_IDENTIFIERS;
use crate::FLOAT_IDENTIFIERS;
use crate::HOME_DIR;
use crate::LAYERED_EXE_WHITELIST;
use crate::LAYERED_WHITELIST;
use crate::MANAGE_IDENTIFIERS;
use crate::OBJECT_NAME_CHANGE_ON_LAUNCH;
use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS;
Expand Down Expand Up @@ -77,7 +77,7 @@ pub struct State {
pub has_pending_raise_op: bool,
pub float_identifiers: Vec<String>,
pub manage_identifiers: Vec<String>,
pub layered_exe_whitelist: Vec<String>,
pub layered_whitelist: Vec<String>,
pub tray_and_multi_window_identifiers: Vec<String>,
pub border_overflow_identifiers: Vec<String>,
pub name_change_on_launch_identifiers: Vec<String>,
Expand All @@ -103,7 +103,7 @@ impl From<&WindowManager> for State {
has_pending_raise_op: wm.has_pending_raise_op,
float_identifiers: FLOAT_IDENTIFIERS.lock().clone(),
manage_identifiers: MANAGE_IDENTIFIERS.lock().clone(),
layered_exe_whitelist: LAYERED_EXE_WHITELIST.lock().clone(),
layered_whitelist: LAYERED_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(),
Expand Down
8 changes: 6 additions & 2 deletions komorebic.lib.sample.ahk
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,12 @@ IdentifyTrayApplication(identifier, id) {
Run, komorebic.exe identify-tray-application %identifier% %id%, , Hide
}

IdentifyBorderOverflow(identifier, id) {
Run, komorebic.exe identify-border-overflow %identifier% %id%, , Hide
IdentifyLayeredApplication(identifier, id) {
Run, komorebic.exe identify-layered-application %identifier% %id%, , Hide
}

IdentifyBorderOverflowApplication(identifier, id) {
Run, komorebic.exe identify-border-overflow-application %identifier% %id%, , Hide
}

FocusFollowsMouse(boolean_state, implementation) {
Expand Down
20 changes: 16 additions & 4 deletions komorebic/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,8 +352,9 @@ gen_application_target_subcommand_args! {
FloatRule,
ManageRule,
IdentifyTrayApplication,
IdentifyLayeredApplication,
IdentifyObjectNameChangeApplication,
IdentifyBorderOverflow,
IdentifyBorderOverflowApplication,
}

#[derive(Parser, AhkFunction)]
Expand Down Expand Up @@ -620,9 +621,13 @@ enum SubCommand {
/// Identify an application that closes to the system tray
#[clap(arg_required_else_help = true)]
IdentifyTrayApplication(IdentifyTrayApplication),
/// Identify an application that has WS_EX_LAYERED, but should still be managed
#[clap(arg_required_else_help = true)]
IdentifyLayeredApplication(IdentifyLayeredApplication),
/// Identify an application that has overflowing borders
#[clap(arg_required_else_help = true)]
IdentifyBorderOverflow(IdentifyBorderOverflow),
#[clap(alias = "identify-border-overflow")]
IdentifyBorderOverflowApplication(IdentifyBorderOverflowApplication),
/// Enable or disable focus follows mouse for the operating system
#[clap(arg_required_else_help = true)]
FocusFollowsMouse(FocusFollowsMouse),
Expand Down Expand Up @@ -1079,9 +1084,16 @@ fn main() -> Result<()> {
.as_bytes()?,
)?;
}
SubCommand::IdentifyBorderOverflow(target) => {
SubCommand::IdentifyLayeredApplication(target) => {
send_message(
&*SocketMessage::IdentifyLayeredApplication(target.identifier, target.id)
.as_bytes()?,
)?;
}
SubCommand::IdentifyBorderOverflowApplication(target) => {
send_message(
&*SocketMessage::IdentifyBorderOverflow(target.identifier, target.id).as_bytes()?,
&*SocketMessage::IdentifyBorderOverflowApplication(target.identifier, target.id)
.as_bytes()?,
)?;
}
SubCommand::Manage => {
Expand Down

0 comments on commit 4686d5e

Please sign in to comment.