fix(ffm): raise when switching focus from anywhere

Previously, when switching focus from unmanaged windows such as the
taskbar and the system tray, komorebi would still recognise its last
known focused window as the currently focused window although that would
not be strictly true, making the ffm functionality stop working until
focus was set to a known window specifically either via a click or an
alt-tab.

This commit fixes that by always also comparing against what the OS has
registered as the current foreground window.

There is another little fix here to reset the pending raise op tracker
whenever ffm is toggled or disabled in the event that it ever gets
stuck.
This commit is contained in:
LGUG2Z
2021-09-05 22:45:57 -07:00
parent 2b7c51b87b
commit 368d41e3e0
3 changed files with 24 additions and 14 deletions

View File

@@ -166,9 +166,9 @@ komorebic.exe identify-tray-application exe Discord.exe
#### Focus Follows Mouse
Komorebi supports two focus-follows-mouse implementations; the native Windows X-Mouse implementation, which treats the
desktop, the task bar and the system tray as windows and switches focus to them eagerly, and a custom `komorebi`
implementation which only considers windows managed by `komorebi` as valid targets to switch focus to when moving the
`komorebi` supports two focus-follows-mouse implementations; the native Windows Xmouse implementation, which treats the
desktop, the task bar, and the system tray as windows and switches focus to them eagerly, and a custom `komorebi`
implementation, which only considers windows managed by `komorebi` as valid targets to switch focus to when moving the
mouse.
When calling any of the `komorebic` commands related to focus-follows-mouse functionality, the `komorebi`
@@ -278,8 +278,8 @@ used [is available here](komorebi.sample.with.lib.ahk).
- [x] Toggle floating windows
- [x] Toggle monocle window
- [x] Toggle native maximization
- [x] Toggle X-Mouse (Native Windows) focus follows mouse
- [x] Toggle custom Komorebi focus follows mouse (desktop and system tray-aware)
- [x] Toggle Xmouse/Windows focus follows mouse implementation
- [x] Toggle Komorebi focus follows mouse implementation (desktop and system tray-aware)
- [x] Toggle automatic tiling
- [x] Pause all window management
- [x] Load configuration on startup

View File

@@ -223,6 +223,7 @@ impl WindowManager {
self.focus_follows_mouse = Option::from(implementation);
} else {
self.focus_follows_mouse = None;
self.has_pending_raise_op = false;
}
}
FocusFollowsMouseImplementation::Windows => {
@@ -250,12 +251,15 @@ impl WindowManager {
);
} else {
match self.focus_follows_mouse {
None => self.focus_follows_mouse = Option::from(implementation),
None => {
self.focus_follows_mouse = Option::from(implementation);
self.has_pending_raise_op = false;
}
Some(FocusFollowsMouseImplementation::Komorebi) => {
self.focus_follows_mouse = None;
}
Some(FocusFollowsMouseImplementation::Windows) => {
tracing::warn!("ignoring command that could mix different focus follow mouse implementations");
tracing::warn!("ignoring command that could mix different focus follows mouse implementations");
}
}
}
@@ -270,17 +274,15 @@ impl WindowManager {
} else {
match self.focus_follows_mouse {
None => {
self.focus_follows_mouse = {
WindowsApi::enable_focus_follows_mouse()?;
Option::from(implementation)
}
WindowsApi::enable_focus_follows_mouse()?;
self.focus_follows_mouse = Option::from(implementation);
}
Some(FocusFollowsMouseImplementation::Windows) => {
WindowsApi::disable_focus_follows_mouse()?;
self.focus_follows_mouse = None;
}
Some(FocusFollowsMouseImplementation::Komorebi) => {
tracing::warn!("ignoring command that could mix different focus follow mouse implementations");
tracing::warn!("ignoring command that could mix different focus follows mouse implementations");
}
}
}

View File

@@ -56,6 +56,7 @@ pub struct State {
pub monitors: Ring<Monitor>,
pub is_paused: bool,
pub focus_follows_mouse: Option<FocusFollowsMouseImplementation>,
pub has_pending_raise_op: bool,
pub float_identifiers: Vec<String>,
pub manage_identifiers: Vec<String>,
pub layered_exe_whitelist: Vec<String>,
@@ -69,7 +70,8 @@ impl From<&mut WindowManager> for State {
Self {
monitors: wm.monitors.clone(),
is_paused: wm.is_paused,
focus_follows_mouse: None,
focus_follows_mouse: wm.focus_follows_mouse.clone(),
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(),
@@ -398,7 +400,13 @@ impl WindowManager {
}
}
if known_hwnd && self.focused_window()?.hwnd != hwnd {
if known_hwnd
&& self.focused_window()?.hwnd != hwnd
// Sometimes we need this check, because the focus may have been given by a click
// to a non-window such as the taskbar or system tray, and komorebi doesn't know that
// the focused window of the workspace is not actually focused by the OS at that point
&& WindowsApi::foreground_window()? != hwnd
{
let event = WindowManagerEvent::Raise(Window { hwnd });
self.has_pending_raise_op = true;
Ok(WINEVENT_CALLBACK_CHANNEL.lock().0.send(event)?)