This commit is contained in:
Junkui Zhang 2025-08-04 15:08:59 +08:00
parent 106aa0d9cc
commit 2261dcaa8e
2 changed files with 75 additions and 18 deletions

View file

@ -18,6 +18,7 @@ use windows::{
Win32::{
Foundation::*,
Graphics::{
DirectComposition::DCompositionWaitForCompositorClock,
Gdi::*,
Imaging::{CLSID_WICImagingFactory, IWICImagingFactory},
},
@ -32,7 +33,7 @@ use crate::*;
pub(crate) struct WindowsPlatform {
state: RefCell<WindowsPlatformState>,
raw_window_handles: RwLock<SmallVec<[HWND; 4]>>,
raw_window_handles: Arc<RwLock<SmallVec<[SafeHwnd; 4]>>>,
// The below members will never change throughout the entire lifecycle of the app.
icon: HICON,
main_receiver: flume::Receiver<Runnable>,
@ -109,7 +110,7 @@ impl WindowsPlatform {
};
let icon = load_icon().unwrap_or_default();
let state = RefCell::new(WindowsPlatformState::new());
let raw_window_handles = RwLock::new(SmallVec::new());
let raw_window_handles = Arc::new(RwLock::new(SmallVec::new()));
let windows_version = WindowsVersion::new().context("Error retrieve windows version")?;
Ok(Self {
@ -128,10 +129,27 @@ impl WindowsPlatform {
})
}
fn begin_vsync_thread(&self) {
let raw_window_handles = self.raw_window_handles.clone();
std::thread::spawn(move || {
loop {
unsafe {
DCompositionWaitForCompositorClock(None, INFINITE);
for handle in raw_window_handles.read().iter() {
RedrawWindow(Some(**handle), None, None, RDW_INVALIDATE)
.ok()
.log_err();
// PostMessageW(Some(**handle), WM_GPUI_FORCE_DRAW_WINDOW, WPARAM(0), LPARAM(0)).log_err();
}
}
}
});
}
fn redraw_all(&self) {
for handle in self.raw_window_handles.read().iter() {
unsafe {
RedrawWindow(Some(*handle), None, None, RDW_INVALIDATE | RDW_UPDATENOW)
RedrawWindow(Some(**handle), None, None, RDW_INVALIDATE | RDW_UPDATENOW)
.ok()
.log_err();
}
@ -142,8 +160,8 @@ impl WindowsPlatform {
self.raw_window_handles
.read()
.iter()
.find(|entry| *entry == &hwnd)
.and_then(|hwnd| try_get_window_inner(*hwnd))
.find(|entry| ***entry == hwnd)
.and_then(|hwnd| try_get_window_inner(**hwnd))
}
#[inline]
@ -152,7 +170,7 @@ impl WindowsPlatform {
.read()
.iter()
.for_each(|handle| unsafe {
PostMessageW(Some(*handle), message, wparam, lparam).log_err();
PostMessageW(Some(**handle), message, wparam, lparam).log_err();
});
}
@ -160,7 +178,7 @@ impl WindowsPlatform {
let mut lock = self.raw_window_handles.write();
let index = lock
.iter()
.position(|handle| *handle == target_window)
.position(|handle| **handle == target_window)
.unwrap();
lock.remove(index);
@ -223,7 +241,8 @@ impl WindowsPlatform {
fn handle_events(&self) -> bool {
let mut msg = MSG::default();
unsafe {
while PeekMessageW(&mut msg, None, 0, 0, PM_REMOVE).as_bool() {
// while PeekMessageW(&mut msg, None, 0, 0, PM_REMOVE).as_bool() {
while GetMessageW(&mut msg, None, 0, 0).as_bool() {
match msg.message {
WM_QUIT => return true,
WM_INPUTLANGCHANGE
@ -305,11 +324,17 @@ impl WindowsPlatform {
if active_window_hwnd.is_invalid() {
return None;
}
self.raw_window_handles
if self
.raw_window_handles
.read()
.iter()
.find(|&&hwnd| hwnd == active_window_hwnd)
.copied()
.find(|&&hwnd| *hwnd == active_window_hwnd)
.is_some()
{
Some(active_window_hwnd)
} else {
None
}
}
}
@ -340,12 +365,13 @@ impl Platform for WindowsPlatform {
fn run(&self, on_finish_launching: Box<dyn 'static + FnOnce()>) {
on_finish_launching();
loop {
if self.handle_events() {
break;
}
self.redraw_all();
self.begin_vsync_thread();
// loop {
if self.handle_events() {
// break;
}
// self.redraw_all();
// }
if let Some(ref mut callback) = self.state.borrow_mut().callbacks.quit {
callback();
@ -438,7 +464,7 @@ impl Platform for WindowsPlatform {
) -> Result<Box<dyn PlatformWindow>> {
let window = WindowsWindow::new(handle, options, self.generate_creation_info())?;
let handle = window.get_raw_handle();
self.raw_window_handles.write().push(handle);
self.raw_window_handles.write().push(handle.into());
Ok(Box::new(window))
}

View file

@ -1,6 +1,9 @@
use std::ops::Deref;
use windows::Win32::{Foundation::HANDLE, UI::WindowsAndMessaging::HCURSOR};
use windows::Win32::{
Foundation::{HANDLE, HWND},
UI::WindowsAndMessaging::HCURSOR,
};
#[derive(Debug, Clone, Copy)]
pub(crate) struct SafeHandle {
@ -45,3 +48,31 @@ impl Deref for SafeCursor {
&self.raw
}
}
#[derive(Clone, Copy)]
pub(crate) struct SafeHwnd {
raw: HWND,
}
unsafe impl Send for SafeHwnd {}
unsafe impl Sync for SafeHwnd {}
impl From<HWND> for SafeHwnd {
fn from(value: HWND) -> Self {
SafeHwnd { raw: value }
}
}
impl From<SafeHwnd> for HWND {
fn from(value: SafeHwnd) -> Self {
value.raw
}
}
impl Deref for SafeHwnd {
type Target = HWND;
fn deref(&self) -> &Self::Target {
&self.raw
}
}