Add: windows mvp - transparent bugs not fixed

This commit is contained in:
DaZuo0122
2026-02-12 22:58:33 +08:00
commit 61825f647d
147 changed files with 28498 additions and 0 deletions

View File

@@ -0,0 +1,252 @@
use sprimo_protocol::v1::CapabilityFlags;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum PlatformError {
#[error("operation unsupported on this platform")]
Unsupported,
#[error("platform operation failed: {0}")]
Message(String),
}
pub trait PlatformAdapter: Send + Sync {
fn capabilities(&self) -> CapabilityFlags;
fn attach_window_handle(&self, handle: isize) -> Result<(), PlatformError>;
fn set_click_through(&self, enabled: bool) -> Result<(), PlatformError>;
fn set_always_on_top(&self, enabled: bool) -> Result<(), PlatformError>;
fn set_visible(&self, visible: bool) -> Result<(), PlatformError>;
fn set_window_position(&self, x: f32, y: f32) -> Result<(), PlatformError>;
}
pub fn create_adapter() -> Box<dyn PlatformAdapter> {
#[cfg(target_os = "windows")]
{
return Box::new(windows::WindowsAdapter::default());
}
#[cfg(not(target_os = "windows"))]
{
Box::new(NoopAdapter::default())
}
}
#[derive(Debug, Default)]
pub struct NoopAdapter {
_private: (),
}
impl PlatformAdapter for NoopAdapter {
fn capabilities(&self) -> CapabilityFlags {
CapabilityFlags::default()
}
fn attach_window_handle(&self, _handle: isize) -> Result<(), PlatformError> {
Ok(())
}
fn set_click_through(&self, _enabled: bool) -> Result<(), PlatformError> {
Err(PlatformError::Unsupported)
}
fn set_always_on_top(&self, _enabled: bool) -> Result<(), PlatformError> {
Ok(())
}
fn set_visible(&self, _visible: bool) -> Result<(), PlatformError> {
Ok(())
}
fn set_window_position(&self, _x: f32, _y: f32) -> Result<(), PlatformError> {
Ok(())
}
}
#[cfg(target_os = "windows")]
#[allow(unsafe_code)]
mod windows {
use crate::{PlatformAdapter, PlatformError};
use sprimo_protocol::v1::CapabilityFlags;
use std::ffi::c_void;
use std::sync::Mutex;
use windows::Win32::Foundation::{COLORREF, GetLastError, HWND};
use windows::Win32::UI::WindowsAndMessaging::{
GetWindowLongPtrW, SetLayeredWindowAttributes, SetWindowLongPtrW, SetWindowPos,
ShowWindow, GWL_EXSTYLE, HWND_NOTOPMOST, HWND_TOPMOST, LWA_COLORKEY, SW_HIDE, SW_SHOW,
SWP_NOMOVE, SWP_NOSIZE, SWP_NOZORDER, WINDOW_EX_STYLE, WS_EX_LAYERED,
WS_EX_TRANSPARENT,
};
const COLOR_KEY_RGB: [u8; 3] = [255, 0, 255];
#[derive(Debug, Default)]
pub struct WindowsAdapter {
hwnd: Mutex<Option<isize>>,
}
impl WindowsAdapter {
fn enable_color_key_transparency(hwnd: HWND) -> Result<(), PlatformError> {
// SAFETY: `hwnd` comes from a real native window handle attached during startup.
let current_bits = unsafe { GetWindowLongPtrW(hwnd, GWL_EXSTYLE) };
let mut style = WINDOW_EX_STYLE(current_bits as u32);
style |= WS_EX_LAYERED;
// SAFETY: We pass the same valid window handle and write a computed style bitmask.
let previous = unsafe { SetWindowLongPtrW(hwnd, GWL_EXSTYLE, style.0 as isize) };
if previous == 0 {
// SAFETY: Calling `GetLastError` immediately after failed Win32 API is valid.
let code = unsafe { GetLastError().0 };
if code != 0 {
return Err(PlatformError::Message(format!(
"SetWindowLongPtrW(layered) failed: {}",
code
)));
}
}
let key = COLORREF(
u32::from(COLOR_KEY_RGB[0])
| (u32::from(COLOR_KEY_RGB[1]) << 8)
| (u32::from(COLOR_KEY_RGB[2]) << 16),
);
// SAFETY: `hwnd` is valid and colorkey transparency is configured on a layered window.
let result = unsafe { SetLayeredWindowAttributes(hwnd, key, 0, LWA_COLORKEY) };
if let Err(err) = result {
// SAFETY: Calling `GetLastError` immediately after failed Win32 API is valid.
let code = unsafe { GetLastError().0 };
return Err(PlatformError::Message(format!(
"SetLayeredWindowAttributes(colorkey) failed: {} ({})",
code, err
)));
}
Ok(())
}
fn apply_click_through_style(
hwnd: HWND,
click_through: Option<bool>,
) -> Result<(), PlatformError> {
// SAFETY: `hwnd` comes from a real native window handle attached during startup.
let current_bits = unsafe { GetWindowLongPtrW(hwnd, GWL_EXSTYLE) };
let mut style = WINDOW_EX_STYLE(current_bits as u32);
if let Some(enabled) = click_through {
if enabled {
style |= WS_EX_TRANSPARENT;
} else {
style &= !WS_EX_TRANSPARENT;
}
}
// SAFETY: We pass the same valid window handle and write a computed style bitmask.
let previous = unsafe { SetWindowLongPtrW(hwnd, GWL_EXSTYLE, style.0 as isize) };
if previous == 0 {
// SAFETY: Calling `GetLastError` immediately after failed Win32 API is valid.
let code = unsafe { GetLastError().0 };
if code != 0 {
return Err(PlatformError::Message(format!(
"SetWindowLongPtrW failed: {}",
code
)));
}
}
Ok(())
}
fn with_hwnd<F>(&self, callback: F) -> Result<(), PlatformError>
where
F: FnOnce(HWND) -> Result<(), PlatformError>,
{
let guard = self
.hwnd
.lock()
.map_err(|_| PlatformError::Message("window handle lock poisoned".to_string()))?;
let hwnd = guard.ok_or_else(|| {
PlatformError::Message("window handle not attached".to_string())
})?;
callback(HWND(hwnd as *mut c_void))
}
}
impl PlatformAdapter for WindowsAdapter {
fn capabilities(&self) -> CapabilityFlags {
CapabilityFlags {
supports_click_through: true,
supports_transparency: true,
supports_tray: false,
supports_global_hotkey: true,
supports_skip_taskbar: true,
}
}
fn attach_window_handle(&self, handle: isize) -> Result<(), PlatformError> {
{
let mut guard = self.hwnd.lock().map_err(|_| {
PlatformError::Message("window handle lock poisoned".to_string())
})?;
*guard = Some(handle);
}
self.with_hwnd(Self::enable_color_key_transparency)
}
fn set_click_through(&self, enabled: bool) -> Result<(), PlatformError> {
self.with_hwnd(|hwnd| Self::apply_click_through_style(hwnd, Some(enabled)))
}
fn set_always_on_top(&self, enabled: bool) -> Result<(), PlatformError> {
self.with_hwnd(|hwnd| {
let insert_after = if enabled { HWND_TOPMOST } else { HWND_NOTOPMOST };
// SAFETY: `hwnd` is valid and flags request only z-order update.
let result = unsafe {
SetWindowPos(hwnd, insert_after, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE)
};
if let Err(err) = result {
// SAFETY: Calling `GetLastError` immediately after failed Win32 API is valid.
let code = unsafe { GetLastError().0 };
return Err(PlatformError::Message(format!(
"SetWindowPos(topmost) failed: {} ({})",
code, err
)));
}
Ok(())
})
}
fn set_visible(&self, visible: bool) -> Result<(), PlatformError> {
self.with_hwnd(|hwnd| {
let command = if visible { SW_SHOW } else { SW_HIDE };
// SAFETY: `hwnd` is valid and `ShowWindow` is safe with these standard commands.
unsafe {
let _ = ShowWindow(hwnd, command);
}
Ok(())
})
}
fn set_window_position(&self, x: f32, y: f32) -> Result<(), PlatformError> {
self.with_hwnd(|hwnd| {
// SAFETY: `hwnd` is valid and this call updates only position.
let result = unsafe {
SetWindowPos(
hwnd,
HWND(std::ptr::null_mut()),
x.round() as i32,
y.round() as i32,
0,
0,
SWP_NOSIZE | SWP_NOZORDER,
)
};
if let Err(err) = result {
// SAFETY: Calling `GetLastError` immediately after failed Win32 API is valid.
let code = unsafe { GetLastError().0 };
return Err(PlatformError::Message(format!(
"SetWindowPos(move) failed: {} ({})",
code, err
)));
}
Ok(())
})
}
}
}