diff --git a/komorebi-core/src/lib.rs b/komorebi-core/src/lib.rs index ee3e1e77..d3fbbe5e 100644 --- a/komorebi-core/src/lib.rs +++ b/komorebi-core/src/lib.rs @@ -53,6 +53,7 @@ pub enum SocketMessage { CycleSendContainerToWorkspace(CycleDirection), SendContainerToMonitorWorkspaceNumber(usize, usize), MoveWorkspaceToMonitorNumber(usize), + ForceFocus, Close, Minimize, Promote, diff --git a/komorebi/src/process_command.rs b/komorebi/src/process_command.rs index 4f74afaa..9c831a83 100644 --- a/komorebi/src/process_command.rs +++ b/komorebi/src/process_command.rs @@ -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()?, diff --git a/komorebi/src/windows_api.rs b/komorebi/src/windows_api.rs index 1e840f0b..a4a1713c 100644 --- a/komorebi/src/windows_api.rs +++ b/komorebi/src/windows_api.rs @@ -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::() as i32) + } + } } diff --git a/komorebic.lib.ahk b/komorebic.lib.ahk index 46e068ab..fceed6b0 100644 --- a/komorebic.lib.ahk +++ b/komorebic.lib.ahk @@ -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 } diff --git a/komorebic/src/main.rs b/komorebic/src/main.rs index c79591a7..102810ae 100644 --- a/komorebic/src/main.rs +++ b/komorebic/src/main.rs @@ -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()?)?; }