Skip to content

Commit

Permalink
feat(win32): set foregroundlocktimeout explicitly
Browse files Browse the repository at this point in the history
After another round of deep diving to find a workaround to all of the
mechanisms within Windows that prevent a process from changing the
focused window, I came across this gist which I saw setting
SPI_SETFOREGROUNDLOCKTIMEOUT to 0:
https://gist.github.com/EBNull/1419093

This tentatively seems like it works and it removes the need for the
alt_focus_hack setting.

However, according to this StackOverflow discussion, it seems like on
Win10+ changes to ForegroundLockTimeout in the registry are no longer
respected and changes made via SPI_SETFOREGROUNDLOCKTIMEOUT are not
persisted:
https://stackoverflow.com/questions/73735129/setforegroundwindow-relationship-between-the-foregroundlocktimeout-registry-val

Therefore on starting, komorebi will now check the value with
SPI_GETFOREGROUNDLOCKTIMEOUT and if it is not 0, it will be set to 0.

Logging has been added to inform the user of the changes that are
happening.
  • Loading branch information
LGUG2Z committed Dec 2, 2023
1 parent 8afad72 commit e04ba0e
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
2 changes: 2 additions & 0 deletions komorebi/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,8 @@ fn main() -> Result<()> {
// File logging worker guard has to have an assignment in the main fn to work
let (_guard, _color_guard) = setup()?;

WindowsApi::foreground_lock_timeout()?;

#[cfg(feature = "deadlock_detection")]
detect_deadlocks();

Expand Down
38 changes: 38 additions & 0 deletions komorebi/src/windows_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ use windows::Win32::UI::WindowsAndMessaging::SET_WINDOW_POS_FLAGS;
use windows::Win32::UI::WindowsAndMessaging::SHOW_WINDOW_CMD;
use windows::Win32::UI::WindowsAndMessaging::SPIF_SENDCHANGE;
use windows::Win32::UI::WindowsAndMessaging::SPI_GETACTIVEWINDOWTRACKING;
use windows::Win32::UI::WindowsAndMessaging::SPI_GETFOREGROUNDLOCKTIMEOUT;
use windows::Win32::UI::WindowsAndMessaging::SPI_SETACTIVEWINDOWTRACKING;
use windows::Win32::UI::WindowsAndMessaging::SPI_SETFOREGROUNDLOCKTIMEOUT;
use windows::Win32::UI::WindowsAndMessaging::SW_HIDE;
use windows::Win32::UI::WindowsAndMessaging::SW_MAXIMIZE;
use windows::Win32::UI::WindowsAndMessaging::SW_MINIMIZE;
Expand Down Expand Up @@ -679,6 +681,42 @@ impl WindowsApi {
.process()
}

#[tracing::instrument]
pub fn foreground_lock_timeout() -> Result<()> {
let mut value: u32 = 0;

Self::system_parameters_info_w(
SPI_GETFOREGROUNDLOCKTIMEOUT,
0,
std::ptr::addr_of_mut!(value).cast(),
SPIF_SENDCHANGE,
)?;

tracing::info!("current value of ForegroundLockTimeout is {value}");

if value != 0 {
tracing::info!("updating value of ForegroundLockTimeout to {value} in order to enable keyboard-driven focus updating");

Self::system_parameters_info_w(
SPI_SETFOREGROUNDLOCKTIMEOUT,
0,
0 as *mut c_void,
SPIF_SENDCHANGE,
)?;

Self::system_parameters_info_w(
SPI_GETFOREGROUNDLOCKTIMEOUT,
0,
std::ptr::addr_of_mut!(value).cast(),
SPIF_SENDCHANGE,
)?;

tracing::info!("updated value of ForegroundLockTimeout is now {value}");
}

Ok(())
}

#[allow(dead_code)]
pub fn focus_follows_mouse() -> Result<bool> {
let mut is_enabled: BOOL = unsafe { std::mem::zeroed() };
Expand Down

0 comments on commit e04ba0e

Please sign in to comment.