diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 0e1955f..f288e7c 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -19,8 +19,14 @@ jobs: include: - target: x86_64-pc-windows-msvc os: windows-latest + platform: windows-64 - target: i686-pc-windows-msvc os: windows-latest + platform: windows-32 + use-cross: true + - target: aarch64-pc-windows-msvc + os: windows-latest + platform: windows-arm use-cross: true runs-on: ${{matrix.os}} @@ -78,13 +84,14 @@ jobs: id: package env: target: ${{ matrix.target }} + platform: ${{ matrix.platform }} version: ${{ steps.check-tag.outputs.version }} run: | set -euxo pipefail bin=${GITHUB_REPOSITORY##*/} dist_dir=`pwd`/dist - name=$bin-$version-$target + name=$bin-$version-$platform executable=target/$target/release/$bin if [[ "$RUNNER_OS" == "Windows" ]]; then diff --git a/Cargo.lock b/Cargo.lock index e912e00..fecec23 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -378,7 +378,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "window-switcher" -version = "1.3.3" +version = "1.4.0-rc1" dependencies = [ "anyhow", "embed-resource", diff --git a/Cargo.toml b/Cargo.toml index 42a22e8..71a8356 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "window-switcher" -version = "1.3.3" +version = "1.4.0-rc1" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/utils/window.rs b/src/utils/window.rs index 128e377..39cf967 100644 --- a/src/utils/window.rs +++ b/src/utils/window.rs @@ -171,7 +171,7 @@ pub fn get_module_icon(hwnd: HWND) -> Option { pub fn get_window_user_data(hwnd: HWND) -> i32 { unsafe { windows::Win32::UI::WindowsAndMessaging::GetWindowLongW(hwnd, GWL_USERDATA) } } -#[cfg(target_arch = "x86_64")] +#[cfg(not(target_arch = "x86"))] pub fn get_window_user_data(hwnd: HWND) -> isize { unsafe { windows::Win32::UI::WindowsAndMessaging::GetWindowLongPtrW(hwnd, GWL_USERDATA) } } @@ -181,7 +181,7 @@ pub fn set_window_user_data(hwnd: HWND, ptr: i32) -> i32 { unsafe { windows::Win32::UI::WindowsAndMessaging::SetWindowLongW(hwnd, GWL_USERDATA, ptr) } } -#[cfg(target_arch = "x86_64")] +#[cfg(not(target_arch = "x86"))] pub fn set_window_user_data(hwnd: HWND, ptr: isize) -> isize { unsafe { windows::Win32::UI::WindowsAndMessaging::SetWindowLongPtrW(hwnd, GWL_USERDATA, ptr) } } @@ -190,7 +190,7 @@ pub fn set_window_user_data(hwnd: HWND, ptr: isize) -> isize { pub fn get_class_icon(hwnd: HWND) -> u32 { unsafe { windows::Win32::UI::WindowsAndMessaging::GetClassLongW(hwnd, GCL_HICON) } } -#[cfg(target_arch = "x86_64")] +#[cfg(not(target_arch = "x86"))] pub fn get_class_icon(hwnd: HWND) -> usize { unsafe { windows::Win32::UI::WindowsAndMessaging::GetClassLongPtrW(hwnd, GCL_HICON) } } diff --git a/tools/inspect-windows/src/main.rs b/tools/inspect-windows/src/main.rs index 9ddc111..51fd0ec 100644 --- a/tools/inspect-windows/src/main.rs +++ b/tools/inspect-windows/src/main.rs @@ -1,13 +1,55 @@ -use anyhow::{anyhow, Result}; +use anyhow::{Context, Result}; use window_switcher::utils::*; use windows::Win32::Foundation::{BOOL, HWND, LPARAM}; use windows::Win32::UI::WindowsAndMessaging::{EnumWindows, GetWindow, GW_OWNER}; fn main() -> Result<()> { + let output = collect_windows_info()? + .iter() + .map(|v| v.stringify()) + .collect::>() + .join("\n"); + println!("{output}"); + Ok(()) +} + +#[derive(Debug)] +struct WindowInfo { + hwnd: HWND, + title: String, + owner_hwnd: HWND, + owner_title: String, + size: (usize, usize), + is_visible: bool, + is_cloaked: bool, + is_iconic: bool, + is_topmost: bool, +} + +impl WindowInfo { + pub fn stringify(&self) -> String { + let size = format!("{}x{}", self.size.0, self.size.1); + format!( + "visible:{}cloacked{}iconic{}topmost:{} {:>10} {:>10}:{} {}:{}", + pretty_bool(self.is_visible), + pretty_bool(self.is_cloaked), + pretty_bool(self.is_iconic), + pretty_bool(self.is_topmost), + size, + self.hwnd.0, + self.title, + self.owner_hwnd.0, + self.owner_title + ) + } +} + +fn collect_windows_info() -> anyhow::Result> { let mut hwnds: Vec = Default::default(); unsafe { EnumWindows(Some(enum_window), LPARAM(&mut hwnds as *mut _ as isize)) } - .map_err(|e| anyhow!("Fail to get windows {}", e))?; + .with_context(|| "Fail to enum windows".to_string())?; + let mut output = vec![]; for hwnd in hwnds { let title = get_window_title(hwnd); let is_cloaked = is_cloaked_window(hwnd); @@ -21,21 +63,20 @@ fn main() -> Result<()> { } else { "".into() }; - let size = format!("{width}x{height}"); - println!( - "visible:{}cloacked{}iconic{}topmost:{} {:>10} {:>10}:{} {}:{}", - pretty_bool(is_visible), - pretty_bool(is_cloaked), - pretty_bool(is_iconic), - pretty_bool(is_topmost), - size, - hwnd.0, + let window_info = WindowInfo { + hwnd, title, - owner_hwnd.0, - owner_title - ); + owner_hwnd, + owner_title, + size: (width as usize, height as usize), + is_visible, + is_cloaked, + is_iconic, + is_topmost, + }; + output.push(window_info); } - Ok(()) + Ok(output) } fn pretty_bool(value: bool) -> String { @@ -51,3 +92,8 @@ extern "system" fn enum_window(hwnd: HWND, lparam: LPARAM) -> BOOL { windows.push(hwnd); BOOL(1) } + +#[test] +fn test_collect_windows_info() { + collect_windows_info().unwrap(); +}