mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-03-29 13:41:56 +02:00
Not a huge fan of these updates in the windows-rs crate which swap the isize values which were previously wrapped in various handles with *mut core::ffi:c_void pointers. In order to at least keep this codebase sane, all of the wrapper functions exposed in WindowsApi now take isize wherever they previously took HWND, HMONITOR, HINSTANCE etc. Going forward any pub fn in WindowsApi should prefer isize over Windows handles which wrap c_void pointers.
104 lines
3.1 KiB
Rust
104 lines
3.1 KiB
Rust
// This code is largely taken verbatim from this repository: https://github.com/Ciantic/AltTabAccessor
|
|
// which the author Jari Pennanen (Ciantic) has kindly made available with the MIT license, available
|
|
// in full here: https://github.com/Ciantic/AltTabAccessor/blob/main/LICENSE.txt
|
|
|
|
mod interfaces;
|
|
|
|
use interfaces::CLSID_ImmersiveShell;
|
|
use interfaces::IApplicationViewCollection;
|
|
use interfaces::IServiceProvider;
|
|
|
|
use std::ffi::c_void;
|
|
|
|
use windows::Win32::Foundation::HWND;
|
|
use windows::Win32::System::Com::CoCreateInstance;
|
|
use windows::Win32::System::Com::CoInitializeEx;
|
|
use windows::Win32::System::Com::CoUninitialize;
|
|
use windows::Win32::System::Com::CLSCTX_ALL;
|
|
use windows::Win32::System::Com::COINIT_APARTMENTTHREADED;
|
|
use windows_core::Interface;
|
|
|
|
struct ComInit();
|
|
|
|
impl ComInit {
|
|
pub fn new() -> Self {
|
|
unsafe {
|
|
// Notice: Only COINIT_APARTMENTTHREADED works correctly!
|
|
//
|
|
// Not COINIT_MULTITHREADED or CoIncrementMTAUsage, they cause a seldom crashes in threading tests.
|
|
CoInitializeEx(None, COINIT_APARTMENTTHREADED).unwrap();
|
|
}
|
|
Self()
|
|
}
|
|
}
|
|
|
|
impl Drop for ComInit {
|
|
fn drop(&mut self) {
|
|
unsafe {
|
|
CoUninitialize();
|
|
}
|
|
}
|
|
}
|
|
|
|
thread_local! {
|
|
static COM_INIT: ComInit = ComInit::new();
|
|
}
|
|
|
|
fn get_iservice_provider() -> IServiceProvider {
|
|
COM_INIT.with(|_| unsafe { CoCreateInstance(&CLSID_ImmersiveShell, None, CLSCTX_ALL).unwrap() })
|
|
}
|
|
|
|
fn get_iapplication_view_collection(provider: &IServiceProvider) -> IApplicationViewCollection {
|
|
COM_INIT.with(|_| {
|
|
let mut obj = std::ptr::null_mut::<c_void>();
|
|
unsafe {
|
|
provider
|
|
.query_service(
|
|
&IApplicationViewCollection::IID,
|
|
&IApplicationViewCollection::IID,
|
|
&mut obj,
|
|
)
|
|
.unwrap();
|
|
}
|
|
|
|
assert!(!obj.is_null());
|
|
|
|
unsafe { IApplicationViewCollection::from_raw(obj) }
|
|
})
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn SetCloak(hwnd: HWND, cloak_type: u32, flags: i32) {
|
|
COM_INIT.with(|_| {
|
|
let provider = get_iservice_provider();
|
|
let view_collection = get_iapplication_view_collection(&provider);
|
|
let mut view = None;
|
|
unsafe {
|
|
if view_collection.get_view_for_hwnd(hwnd, &mut view).is_err() {
|
|
tracing::error!(
|
|
"could not get view for hwnd {} due to os error: {}",
|
|
hwnd.0 as isize,
|
|
std::io::Error::last_os_error()
|
|
);
|
|
}
|
|
};
|
|
|
|
view.map_or_else(
|
|
|| {
|
|
tracing::error!("no view was found for {}", hwnd.0 as isize);
|
|
},
|
|
|view| {
|
|
unsafe {
|
|
if view.set_cloak(cloak_type, flags).is_err() {
|
|
tracing::error!(
|
|
"could not change the cloaking status for hwnd {} due to os error: {}",
|
|
hwnd.0 as isize,
|
|
std::io::Error::last_os_error()
|
|
);
|
|
}
|
|
};
|
|
},
|
|
);
|
|
});
|
|
}
|