feat(wm): add force-focus command

On rare occasions and usually with Firefox, the desired application will
fail to be focused with the regular focus commands. This commit
introduces a new command, force-focus, which can be used to simulate a
left-click on a window that has failed to take focus, since this is what
I have to do to work around the issue anyway.
This commit is contained in:
LGUG2Z
2022-12-15 17:08:23 -08:00
parent ca09b9b300
commit 613d69a737
5 changed files with 56 additions and 0 deletions

View File

@@ -53,6 +53,7 @@ pub enum SocketMessage {
CycleSendContainerToWorkspace(CycleDirection),
SendContainerToMonitorWorkspaceNumber(usize, usize),
MoveWorkspaceToMonitorNumber(usize),
ForceFocus,
Close,
Minimize,
Promote,

View File

@@ -179,6 +179,9 @@ impl WindowManager {
SocketMessage::CycleStack(direction) => {
self.cycle_container_window_in_direction(direction)?;
}
SocketMessage::ForceFocus => {
WindowsApi::left_click();
}
SocketMessage::Close => self.focused_window()?.close()?,
SocketMessage::Minimize => self.focused_window()?.minimize(),
SocketMessage::ToggleFloat => self.toggle_float()?,

View File

@@ -52,7 +52,14 @@ use windows::Win32::System::Threading::PROCESS_NAME_WIN32;
use windows::Win32::System::Threading::PROCESS_QUERY_INFORMATION;
use windows::Win32::UI::HiDpi::SetProcessDpiAwarenessContext;
use windows::Win32::UI::HiDpi::DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2;
use windows::Win32::UI::Input::KeyboardAndMouse::SendInput;
use windows::Win32::UI::Input::KeyboardAndMouse::SetFocus;
use windows::Win32::UI::Input::KeyboardAndMouse::INPUT;
use windows::Win32::UI::Input::KeyboardAndMouse::INPUT_0;
use windows::Win32::UI::Input::KeyboardAndMouse::INPUT_MOUSE;
use windows::Win32::UI::Input::KeyboardAndMouse::MOUSEEVENTF_LEFTDOWN;
use windows::Win32::UI::Input::KeyboardAndMouse::MOUSEEVENTF_LEFTUP;
use windows::Win32::UI::Input::KeyboardAndMouse::MOUSEINPUT;
use windows::Win32::UI::Shell::Common::DEVICE_SCALE_FACTOR;
use windows::Win32::UI::Shell::GetScaleFactorForMonitor;
use windows::Win32::UI::WindowsAndMessaging::AllowSetForegroundWindow;
@@ -789,4 +796,40 @@ impl WindowsApi {
.ok()
.process()
}
pub fn left_click() -> u32 {
let inputs = [
INPUT {
r#type: INPUT_MOUSE,
Anonymous: INPUT_0 {
mi: MOUSEINPUT {
dx: 0,
dy: 0,
mouseData: 0,
dwFlags: MOUSEEVENTF_LEFTDOWN,
time: 0,
dwExtraInfo: 0,
},
},
},
INPUT {
r#type: INPUT_MOUSE,
Anonymous: INPUT_0 {
mi: MOUSEINPUT {
dx: 0,
dy: 0,
mouseData: 0,
dwFlags: MOUSEEVENTF_LEFTUP,
time: 0,
dwExtraInfo: 0,
},
},
},
];
#[allow(clippy::cast_possible_wrap, clippy::cast_possible_truncation)]
unsafe {
SendInput(&inputs, std::mem::size_of::<INPUT>() as i32)
}
}
}

View File

@@ -60,6 +60,10 @@ Close() {
RunWait, komorebic.exe close, , Hide
}
ForceFocus() {
RunWait, komorebic.exe force-focus, , Hide
}
CycleFocus(cycle_direction) {
RunWait, komorebic.exe cycle-focus %cycle_direction%, , Hide
}

View File

@@ -557,6 +557,8 @@ enum SubCommand {
Minimize,
/// Close the focused window
Close,
/// Forcibly focus the window at the cursor with a left mouse click
ForceFocus,
/// Change focus to the window in the specified cycle direction
#[clap(arg_required_else_help = true)]
CycleFocus(CycleFocus),
@@ -831,6 +833,9 @@ fn main() -> Result<()> {
SubCommand::Focus(arg) => {
send_message(&SocketMessage::FocusWindow(arg.operation_direction).as_bytes()?)?;
}
SubCommand::ForceFocus => {
send_message(&SocketMessage::ForceFocus.as_bytes()?)?;
}
SubCommand::Close => {
send_message(&SocketMessage::Close.as_bytes()?)?;
}