diff --git a/Cargo.lock b/Cargo.lock index be7a3d2e..a74e19cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1245,9 +1245,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ba9ab62b7d6497a8638dfda5e5c4fb3b2d5a7fca4118f2b96151c8ef1a437e" +checksum = "84f96e095c0c82419687c20ddf5cb3eadb61f4e1405923c9dc8e53a1adacbda8" dependencies = [ "cfg-if 1.0.0", "pin-project-lite", @@ -1319,9 +1319,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.2.23" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c42e73a9d277d4d2b6a88389a137ccf3c58599660b17e8f5fc39305e490669" +checksum = "fdd0568dbfe3baf7048b7908d2b32bca0d81cd56bec6d2a8f894b01d74f86be3" dependencies = [ "ansi_term", "chrono", @@ -1452,9 +1452,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef84dd25f4c69a271b1bba394532bf400523b43169de21dfc715e8f8e491053d" +checksum = "0a0b63f34b1cf0fcb7a2e387189936a7c9822123ef124a95da2b8a0b493bc69d" dependencies = [ "const-sha1", "windows_gen", @@ -1463,9 +1463,9 @@ dependencies = [ [[package]] name = "windows_gen" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac7bb21b8ff5e801232b72a6ff554b4cc0cef9ed9238188c3ca78fe3968a7e5d" +checksum = "7213e17fead412ec608804cbe190988db6f40b2a946ef58dd67fd9cdf39da144" dependencies = [ "windows_quote", "windows_reader", @@ -1473,9 +1473,9 @@ dependencies = [ [[package]] name = "windows_macros" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5566b8c51118769e4a9094a688bf1233a3f36aacbfc78f3b15817fe0b6e0442f" +checksum = "661a56e1edb9f9d466a9cb59c392edfad0d273b66bb20b1f5f4aea6db5ad35d6" dependencies = [ "syn", "windows_gen", @@ -1485,15 +1485,15 @@ dependencies = [ [[package]] name = "windows_quote" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4af8236a9493c38855f95cdd11b38b342512a5df4ee7473cffa828b5ebb0e39c" +checksum = "6d16ae0ecb5b0a365ff465ca9b9780e70986f951b4e06a95f87ac54a421d3767" [[package]] name = "windows_reader" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c8d5cf83fb08083438c5c46723e6206b2970da57ce314f80b57724439aaacab" +checksum = "c75040b326c26dda15a9c18970a7a15bf503dc22597d55dd559df16435f4a550" [[package]] name = "winput" diff --git a/bindings/Cargo.toml b/bindings/Cargo.toml index 64f28e6b..7071a7f7 100644 --- a/bindings/Cargo.toml +++ b/bindings/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -windows = "0.19" +windows = "0.20" [build-dependencies] -windows = "0.19" +windows = "0.20" diff --git a/bindings/src/lib.rs b/bindings/src/lib.rs index 79157607..511e4b65 100644 --- a/bindings/src/lib.rs +++ b/bindings/src/lib.rs @@ -1 +1,4 @@ +pub use windows::Handle; +pub use windows::Result; + ::windows::include_bindings!(); diff --git a/komorebi/src/windows_api.rs b/komorebi/src/windows_api.rs index 5d5fcfbd..6a88ea83 100644 --- a/komorebi/src/windows_api.rs +++ b/komorebi/src/windows_api.rs @@ -7,6 +7,8 @@ use color_eyre::eyre::anyhow; use color_eyre::eyre::Error; use color_eyre::Result; +use bindings::Handle; +use bindings::Result as WindowsCrateResult; use bindings::Windows::Win32::Foundation::BOOL; use bindings::Windows::Win32::Foundation::HANDLE; use bindings::Windows::Win32::Foundation::HWND; @@ -92,36 +94,6 @@ pub enum WindowsResult { Ok(T), } -impl From for WindowsResult<(), Error> { - fn from(return_value: BOOL) -> Self { - if return_value.as_bool() { - Self::Ok(()) - } else { - Self::Err(std::io::Error::last_os_error().into()) - } - } -} - -impl From for WindowsResult { - fn from(return_value: HWND) -> Self { - if return_value.is_null() { - Self::Err(std::io::Error::last_os_error().into()) - } else { - Self::Ok(return_value.0) - } - } -} - -impl From for WindowsResult { - fn from(return_value: HANDLE) -> Self { - if return_value.is_null() { - Self::Err(std::io::Error::last_os_error().into()) - } else { - Self::Ok(return_value) - } - } -} - macro_rules! impl_from_integer_for_windows_result { ( $( $integer_type:ty ),+ ) => { $( @@ -148,6 +120,40 @@ impl From> for Result { } } +pub trait ProcessWindowsCrateResult { + fn process(self) -> Result; +} + +macro_rules! impl_process_windows_crate_result { + ( $($input:ty => $deref:ty),+ $(,)? ) => ( + paste::paste! { + $( + impl ProcessWindowsCrateResult<$deref> for WindowsCrateResult<$input> { + fn process(self) -> Result<$deref> { + match self { + Ok(value) => Ok(value.0), + Err(error) => Err(error.into()), + } + } + } + )+ + } + ); +} + +impl_process_windows_crate_result!( + HWND => isize, +); + +impl ProcessWindowsCrateResult for WindowsCrateResult { + fn process(self) -> Result { + match self { + Ok(value) => Ok(value), + Err(error) => Err(error.into()), + } + } +} + pub struct WindowsApi; impl WindowsApi { @@ -155,14 +161,16 @@ impl WindowsApi { callback: MONITORENUMPROC, callback_data_address: isize, ) -> Result<()> { - Result::from(WindowsResult::from(unsafe { + unsafe { EnumDisplayMonitors( HDC(0), std::ptr::null_mut(), Option::from(callback), LPARAM(callback_data_address), ) - })) + } + .ok() + .process() } pub fn valid_hmonitors() -> Result> { @@ -184,9 +192,9 @@ impl WindowsApi { } pub fn enum_windows(callback: WNDENUMPROC, callback_data_address: isize) -> Result<()> { - Result::from(WindowsResult::from(unsafe { - EnumWindows(Option::from(callback), LPARAM(callback_data_address)) - })) + unsafe { EnumWindows(Option::from(callback), LPARAM(callback_data_address)) } + .ok() + .process() } pub fn load_workspace_information(monitors: &mut Ring) -> Result<()> { @@ -225,9 +233,9 @@ impl WindowsApi { } pub fn allow_set_foreground_window(process_id: u32) -> Result<()> { - Result::from(WindowsResult::from(unsafe { - AllowSetForegroundWindow(process_id) - })) + unsafe { AllowSetForegroundWindow(process_id) } + .ok() + .process() } pub fn monitor_from_window(hwnd: HWND) -> isize { @@ -250,7 +258,7 @@ impl WindowsApi { } pub fn set_window_pos(hwnd: HWND, layout: &Rect, position: HWND, flags: u32) -> Result<()> { - Result::from(WindowsResult::from(unsafe { + unsafe { SetWindowPos( hwnd, position, @@ -260,7 +268,9 @@ impl WindowsApi { layout.bottom, SET_WINDOW_POS_FLAGS(flags), ) - })) + } + .ok() + .process() } fn show_window(hwnd: HWND, command: SHOW_WINDOW_CMD) { @@ -282,39 +292,25 @@ impl WindowsApi { } pub fn foreground_window() -> Result { - Result::from(WindowsResult::from(unsafe { GetForegroundWindow() })) + unsafe { GetForegroundWindow() }.ok().process() } pub fn set_foreground_window(hwnd: HWND) -> Result<()> { - match WindowsResult::from(unsafe { SetForegroundWindow(hwnd) }) { - WindowsResult::Ok(_) => Ok(()), - WindowsResult::Err(error) => { - // TODO: Figure out the odd behaviour here, docs state that a zero value means - // TODO: that the window was not brought to the foreground, but this contradicts - // TODO: the behaviour that I have observed which resulted in this check - if error.to_string() == "The operation completed successfully. (os error 0)" { - Ok(()) - } else { - Err(error) - } - } - } + unsafe { SetForegroundWindow(hwnd) }.ok().process() } #[allow(dead_code)] pub fn top_window() -> Result { - Result::from(WindowsResult::from(unsafe { GetTopWindow(HWND::NULL).0 })) + unsafe { GetTopWindow(HWND::default()) }.ok().process() } pub fn desktop_window() -> Result { - Result::from(WindowsResult::from(unsafe { GetDesktopWindow() })) + unsafe { GetDesktopWindow() }.ok().process() } #[allow(dead_code)] pub fn next_window(hwnd: HWND) -> Result { - Result::from(WindowsResult::from(unsafe { - GetWindow(hwnd, GW_HWNDNEXT).0 - })) + unsafe { GetWindow(hwnd, GW_HWNDNEXT) }.ok().process() } #[allow(dead_code)] @@ -335,30 +331,24 @@ impl WindowsApi { pub fn window_rect(hwnd: HWND) -> Result { let mut rect = unsafe { std::mem::zeroed() }; - - Result::from(WindowsResult::from(unsafe { - GetWindowRect(hwnd, &mut rect) - }))?; + unsafe { GetWindowRect(hwnd, &mut rect) }.ok().process()?; Ok(Rect::from(rect)) } fn set_cursor_pos(x: i32, y: i32) -> Result<()> { - Result::from(WindowsResult::from(unsafe { SetCursorPos(x, y) })) + unsafe { SetCursorPos(x, y) }.ok().process() } pub fn cursor_pos() -> Result { - let mut cursor_pos: POINT = unsafe { std::mem::zeroed() }; - - Result::from(WindowsResult::from(unsafe { - GetCursorPos(&mut cursor_pos) - }))?; + let mut cursor_pos = POINT::default(); + unsafe { GetCursorPos(&mut cursor_pos) }.ok().process()?; Ok(cursor_pos) } pub fn window_from_point(point: POINT) -> Result { - Result::from(WindowsResult::from(unsafe { WindowFromPoint(point) })) + unsafe { WindowFromPoint(point) }.ok().process() } pub fn window_at_cursor_pos() -> Result { @@ -388,24 +378,13 @@ impl WindowsApi { } pub fn attach_thread_input(thread_id: u32, target_thread_id: u32, attach: bool) -> Result<()> { - Result::from(WindowsResult::from(unsafe { - AttachThreadInput(thread_id, target_thread_id, attach) - })) + unsafe { AttachThreadInput(thread_id, target_thread_id, attach) } + .ok() + .process() } pub fn set_focus(hwnd: HWND) -> Result<()> { - match WindowsResult::from(unsafe { SetFocus(hwnd) }) { - WindowsResult::Ok(_) => Ok(()), - WindowsResult::Err(error) => { - // If the window is not attached to the calling thread's message queue, the return value is NULL - // https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setfocus - if error.to_string() == "The operation completed successfully. (os error 0)" { - Ok(()) - } else { - Err(error) - } - } - } + unsafe { SetFocus(hwnd) }.ok().map(|_| ()).process() } #[allow(dead_code)] @@ -457,9 +436,9 @@ impl WindowsApi { inherit_handle: bool, process_id: u32, ) -> Result { - Result::from(WindowsResult::from(unsafe { - OpenProcess(access_rights, inherit_handle, process_id) - })) + unsafe { OpenProcess(access_rights, inherit_handle, process_id) } + .ok() + .process() } pub fn process_handle(process_id: u32) -> Result { @@ -471,14 +450,16 @@ impl WindowsApi { let mut path: Vec = vec![0; len as usize]; let text_ptr = path.as_mut_ptr(); - Result::from(WindowsResult::from(unsafe { + unsafe { QueryFullProcessImageNameW( handle, PROCESS_NAME_FORMAT(0), PWSTR(text_ptr), &mut len as *mut u32, ) - }))?; + } + .ok() + .process()?; Ok(String::from_utf16(&path[..len as usize])?) } @@ -553,9 +534,9 @@ impl WindowsApi { let mut monitor_info: MONITORINFO = unsafe { std::mem::zeroed() }; monitor_info.cbSize = u32::try_from(std::mem::size_of::())?; - Result::from(WindowsResult::from(unsafe { - GetMonitorInfoW(hmonitor, (&mut monitor_info as *mut MONITORINFO).cast()) - }))?; + unsafe { GetMonitorInfoW(hmonitor, (&mut monitor_info as *mut MONITORINFO).cast()) } + .ok() + .process()?; Ok(monitor_info) } @@ -577,9 +558,9 @@ impl WindowsApi { pv_param: *mut c_void, update_flags: SYSTEM_PARAMETERS_INFO_UPDATE_FLAGS, ) -> Result<()> { - Result::from(WindowsResult::from(unsafe { - SystemParametersInfoW(action, ui_param, pv_param, update_flags) - })) + unsafe { SystemParametersInfoW(action, ui_param, pv_param, update_flags) } + .ok() + .process() } #[allow(dead_code)]