diff --git a/README.md b/README.md index a2ea4359..2de67762 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/komorebi/src/process_command.rs b/komorebi/src/process_command.rs index dbdb36c2..50c321df 100644 --- a/komorebi/src/process_command.rs +++ b/komorebi/src/process_command.rs @@ -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"); } } } diff --git a/komorebi/src/window_manager.rs b/komorebi/src/window_manager.rs index a9319684..40a1046f 100644 --- a/komorebi/src/window_manager.rs +++ b/komorebi/src/window_manager.rs @@ -56,6 +56,7 @@ pub struct State { pub monitors: Ring, pub is_paused: bool, pub focus_follows_mouse: Option, + pub has_pending_raise_op: bool, pub float_identifiers: Vec, pub manage_identifiers: Vec, pub layered_exe_whitelist: Vec, @@ -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)?)