diff --git a/komorebi-core/src/lib.rs b/komorebi-core/src/lib.rs index 9c6d6d0f..93618fb2 100644 --- a/komorebi-core/src/lib.rs +++ b/komorebi-core/src/lib.rs @@ -51,6 +51,8 @@ pub enum SocketMessage { SendContainerToWorkspaceNumber(usize), SendContainerToMonitorWorkspaceNumber(usize, usize), MoveWorkspaceToMonitorNumber(usize), + Close, + Minimize, Promote, PromoteFocus, ToggleFloat, diff --git a/komorebi/src/process_command.rs b/komorebi/src/process_command.rs index 416df9ea..dd00fed5 100644 --- a/komorebi/src/process_command.rs +++ b/komorebi/src/process_command.rs @@ -177,6 +177,8 @@ impl WindowManager { SocketMessage::CycleStack(direction) => { self.cycle_container_window_in_direction(direction)?; } + SocketMessage::Close => self.focused_window()?.close(), + SocketMessage::Minimize => self.focused_window()?.minimize(), SocketMessage::ToggleFloat => self.toggle_float()?, SocketMessage::ToggleMonocle => self.toggle_monocle()?, SocketMessage::ToggleMaximize => self.toggle_maximize()?, diff --git a/komorebi/src/window.rs b/komorebi/src/window.rs index 9ef1be7c..48cf1f3b 100644 --- a/komorebi/src/window.rs +++ b/komorebi/src/window.rs @@ -151,6 +151,14 @@ impl Window { } } + pub fn minimize(self) { + WindowsApi::minimize_window(self.hwnd()); + } + + pub fn close(self) { + WindowsApi::close_window(self.hwnd()); + } + pub fn restore(self) { let mut programmatically_hidden_hwnds = HIDDEN_HWNDS.lock(); if let Some(idx) = programmatically_hidden_hwnds diff --git a/komorebi/src/windows_api.rs b/komorebi/src/windows_api.rs index 961a01bc..3529d779 100644 --- a/komorebi/src/windows_api.rs +++ b/komorebi/src/windows_api.rs @@ -16,6 +16,7 @@ use windows::Win32::Foundation::HINSTANCE; use windows::Win32::Foundation::HWND; use windows::Win32::Foundation::LPARAM; use windows::Win32::Foundation::POINT; +use windows::Win32::Foundation::WPARAM; use windows::Win32::Graphics::Dwm::DwmGetWindowAttribute; use windows::Win32::Graphics::Dwm::DwmSetWindowAttribute; use windows::Win32::Graphics::Dwm::DWMWA_CLOAKED; @@ -68,6 +69,7 @@ use windows::Win32::UI::WindowsAndMessaging::GetWindowThreadProcessId; use windows::Win32::UI::WindowsAndMessaging::IsIconic; use windows::Win32::UI::WindowsAndMessaging::IsWindow; use windows::Win32::UI::WindowsAndMessaging::IsWindowVisible; +use windows::Win32::UI::WindowsAndMessaging::PostMessageW; use windows::Win32::UI::WindowsAndMessaging::RealGetWindowClassW; use windows::Win32::UI::WindowsAndMessaging::RegisterClassA; use windows::Win32::UI::WindowsAndMessaging::SetCursorPos; @@ -99,6 +101,7 @@ use windows::Win32::UI::WindowsAndMessaging::SW_SHOWNOACTIVATE; use windows::Win32::UI::WindowsAndMessaging::SYSTEM_PARAMETERS_INFO_ACTION; use windows::Win32::UI::WindowsAndMessaging::SYSTEM_PARAMETERS_INFO_UPDATE_FLAGS; use windows::Win32::UI::WindowsAndMessaging::WINDOW_LONG_PTR_INDEX; +use windows::Win32::UI::WindowsAndMessaging::WM_CLOSE; use windows::Win32::UI::WindowsAndMessaging::WNDCLASSA; use windows::Win32::UI::WindowsAndMessaging::WNDENUMPROC; use windows::Win32::UI::WindowsAndMessaging::WS_EX_LAYERED; @@ -336,6 +339,10 @@ impl WindowsApi { Self::show_window(hwnd, SW_MINIMIZE); } + pub fn close_window(hwnd: HWND) { + unsafe { PostMessageW(hwnd, WM_CLOSE, WPARAM(0), LPARAM(0)) }; + } + pub fn hide_window(hwnd: HWND) { Self::show_window(hwnd, SW_HIDE); } diff --git a/komorebic/src/main.rs b/komorebic/src/main.rs index 0a833b71..8728c81e 100644 --- a/komorebic/src/main.rs +++ b/komorebic/src/main.rs @@ -517,6 +517,10 @@ enum SubCommand { /// Move the focused window in the specified direction #[clap(arg_required_else_help = true)] Move(Move), + /// Minimize the focused window + Minimize, + /// Close the focused window + Close, /// Change focus to the window in the specified cycle direction #[clap(arg_required_else_help = true)] CycleFocus(CycleFocus), @@ -775,6 +779,12 @@ fn main() -> Result<()> { SubCommand::Focus(arg) => { send_message(&SocketMessage::FocusWindow(arg.operation_direction).as_bytes()?)?; } + SubCommand::Close => { + send_message(&SocketMessage::Close.as_bytes()?)?; + } + SubCommand::Minimize => { + send_message(&SocketMessage::Minimize.as_bytes()?)?; + } SubCommand::Promote => { send_message(&SocketMessage::Promote.as_bytes()?)?; }