mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-04-25 10:08:33 +02:00
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:
10
README.md
10
README.md
@@ -166,9 +166,9 @@ komorebic.exe identify-tray-application exe Discord.exe
|
|||||||
|
|
||||||
#### Focus Follows Mouse
|
#### Focus Follows Mouse
|
||||||
|
|
||||||
Komorebi supports two focus-follows-mouse implementations; the native Windows X-Mouse implementation, which treats 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`
|
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
|
implementation, which only considers windows managed by `komorebi` as valid targets to switch focus to when moving the
|
||||||
mouse.
|
mouse.
|
||||||
|
|
||||||
When calling any of the `komorebic` commands related to focus-follows-mouse functionality, the `komorebi`
|
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 floating windows
|
||||||
- [x] Toggle monocle window
|
- [x] Toggle monocle window
|
||||||
- [x] Toggle native maximization
|
- [x] Toggle native maximization
|
||||||
- [x] Toggle X-Mouse (Native Windows) focus follows mouse
|
- [x] Toggle Xmouse/Windows focus follows mouse implementation
|
||||||
- [x] Toggle custom Komorebi focus follows mouse (desktop and system tray-aware)
|
- [x] Toggle Komorebi focus follows mouse implementation (desktop and system tray-aware)
|
||||||
- [x] Toggle automatic tiling
|
- [x] Toggle automatic tiling
|
||||||
- [x] Pause all window management
|
- [x] Pause all window management
|
||||||
- [x] Load configuration on startup
|
- [x] Load configuration on startup
|
||||||
|
|||||||
@@ -223,6 +223,7 @@ impl WindowManager {
|
|||||||
self.focus_follows_mouse = Option::from(implementation);
|
self.focus_follows_mouse = Option::from(implementation);
|
||||||
} else {
|
} else {
|
||||||
self.focus_follows_mouse = None;
|
self.focus_follows_mouse = None;
|
||||||
|
self.has_pending_raise_op = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FocusFollowsMouseImplementation::Windows => {
|
FocusFollowsMouseImplementation::Windows => {
|
||||||
@@ -250,12 +251,15 @@ impl WindowManager {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
match self.focus_follows_mouse {
|
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) => {
|
Some(FocusFollowsMouseImplementation::Komorebi) => {
|
||||||
self.focus_follows_mouse = None;
|
self.focus_follows_mouse = None;
|
||||||
}
|
}
|
||||||
Some(FocusFollowsMouseImplementation::Windows) => {
|
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 {
|
} else {
|
||||||
match self.focus_follows_mouse {
|
match self.focus_follows_mouse {
|
||||||
None => {
|
None => {
|
||||||
self.focus_follows_mouse = {
|
WindowsApi::enable_focus_follows_mouse()?;
|
||||||
WindowsApi::enable_focus_follows_mouse()?;
|
self.focus_follows_mouse = Option::from(implementation);
|
||||||
Option::from(implementation)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Some(FocusFollowsMouseImplementation::Windows) => {
|
Some(FocusFollowsMouseImplementation::Windows) => {
|
||||||
WindowsApi::disable_focus_follows_mouse()?;
|
WindowsApi::disable_focus_follows_mouse()?;
|
||||||
self.focus_follows_mouse = None;
|
self.focus_follows_mouse = None;
|
||||||
}
|
}
|
||||||
Some(FocusFollowsMouseImplementation::Komorebi) => {
|
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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ pub struct State {
|
|||||||
pub monitors: Ring<Monitor>,
|
pub monitors: Ring<Monitor>,
|
||||||
pub is_paused: bool,
|
pub is_paused: bool,
|
||||||
pub focus_follows_mouse: Option<FocusFollowsMouseImplementation>,
|
pub focus_follows_mouse: Option<FocusFollowsMouseImplementation>,
|
||||||
|
pub has_pending_raise_op: bool,
|
||||||
pub float_identifiers: Vec<String>,
|
pub float_identifiers: Vec<String>,
|
||||||
pub manage_identifiers: Vec<String>,
|
pub manage_identifiers: Vec<String>,
|
||||||
pub layered_exe_whitelist: Vec<String>,
|
pub layered_exe_whitelist: Vec<String>,
|
||||||
@@ -69,7 +70,8 @@ impl From<&mut WindowManager> for State {
|
|||||||
Self {
|
Self {
|
||||||
monitors: wm.monitors.clone(),
|
monitors: wm.monitors.clone(),
|
||||||
is_paused: wm.is_paused,
|
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(),
|
float_identifiers: FLOAT_IDENTIFIERS.lock().clone(),
|
||||||
manage_identifiers: MANAGE_IDENTIFIERS.lock().clone(),
|
manage_identifiers: MANAGE_IDENTIFIERS.lock().clone(),
|
||||||
layered_exe_whitelist: LAYERED_EXE_WHITELIST.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 });
|
let event = WindowManagerEvent::Raise(Window { hwnd });
|
||||||
self.has_pending_raise_op = true;
|
self.has_pending_raise_op = true;
|
||||||
Ok(WINEVENT_CALLBACK_CHANNEL.lock().0.send(event)?)
|
Ok(WINEVENT_CALLBACK_CHANNEL.lock().0.send(event)?)
|
||||||
|
|||||||
Reference in New Issue
Block a user