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::{ Win32::{
Foundation::*, Foundation::*,
Graphics::{ Graphics::{
DirectComposition::DCompositionWaitForCompositorClock,
Gdi::*, Gdi::*,
Imaging::{CLSID_WICImagingFactory, IWICImagingFactory}, Imaging::{CLSID_WICImagingFactory, IWICImagingFactory},
}, },
@ -32,7 +33,7 @@ use crate::*;
pub(crate) struct WindowsPlatform { pub(crate) struct WindowsPlatform {
state: RefCell<WindowsPlatformState>, 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. // The below members will never change throughout the entire lifecycle of the app.
icon: HICON, icon: HICON,
main_receiver: flume::Receiver<Runnable>, main_receiver: flume::Receiver<Runnable>,
@ -109,7 +110,7 @@ impl WindowsPlatform {
}; };
let icon = load_icon().unwrap_or_default(); let icon = load_icon().unwrap_or_default();
let state = RefCell::new(WindowsPlatformState::new()); 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")?; let windows_version = WindowsVersion::new().context("Error retrieve windows version")?;
Ok(Self { 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) { fn redraw_all(&self) {
for handle in self.raw_window_handles.read().iter() { for handle in self.raw_window_handles.read().iter() {
unsafe { unsafe {
RedrawWindow(Some(*handle), None, None, RDW_INVALIDATE | RDW_UPDATENOW) RedrawWindow(Some(**handle), None, None, RDW_INVALIDATE | RDW_UPDATENOW)
.ok() .ok()
.log_err(); .log_err();
} }
@ -142,8 +160,8 @@ impl WindowsPlatform {
self.raw_window_handles self.raw_window_handles
.read() .read()
.iter() .iter()
.find(|entry| *entry == &hwnd) .find(|entry| ***entry == hwnd)
.and_then(|hwnd| try_get_window_inner(*hwnd)) .and_then(|hwnd| try_get_window_inner(**hwnd))
} }
#[inline] #[inline]
@ -152,7 +170,7 @@ impl WindowsPlatform {
.read() .read()
.iter() .iter()
.for_each(|handle| unsafe { .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 mut lock = self.raw_window_handles.write();
let index = lock let index = lock
.iter() .iter()
.position(|handle| *handle == target_window) .position(|handle| **handle == target_window)
.unwrap(); .unwrap();
lock.remove(index); lock.remove(index);
@ -223,7 +241,8 @@ impl WindowsPlatform {
fn handle_events(&self) -> bool { fn handle_events(&self) -> bool {
let mut msg = MSG::default(); let mut msg = MSG::default();
unsafe { 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 { match msg.message {
WM_QUIT => return true, WM_QUIT => return true,
WM_INPUTLANGCHANGE WM_INPUTLANGCHANGE
@ -305,11 +324,17 @@ impl WindowsPlatform {
if active_window_hwnd.is_invalid() { if active_window_hwnd.is_invalid() {
return None; return None;
} }
self.raw_window_handles if self
.raw_window_handles
.read() .read()
.iter() .iter()
.find(|&&hwnd| hwnd == active_window_hwnd) .find(|&&hwnd| *hwnd == active_window_hwnd)
.copied() .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()>) { fn run(&self, on_finish_launching: Box<dyn 'static + FnOnce()>) {
on_finish_launching(); on_finish_launching();
loop { self.begin_vsync_thread();
// loop {
if self.handle_events() { if self.handle_events() {
break; // break;
}
self.redraw_all();
} }
// self.redraw_all();
// }
if let Some(ref mut callback) = self.state.borrow_mut().callbacks.quit { if let Some(ref mut callback) = self.state.borrow_mut().callbacks.quit {
callback(); callback();
@ -438,7 +464,7 @@ impl Platform for WindowsPlatform {
) -> Result<Box<dyn PlatformWindow>> { ) -> Result<Box<dyn PlatformWindow>> {
let window = WindowsWindow::new(handle, options, self.generate_creation_info())?; let window = WindowsWindow::new(handle, options, self.generate_creation_info())?;
let handle = window.get_raw_handle(); 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)) Ok(Box::new(window))
} }

View file

@ -1,6 +1,9 @@
use std::ops::Deref; 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)] #[derive(Debug, Clone, Copy)]
pub(crate) struct SafeHandle { pub(crate) struct SafeHandle {
@ -45,3 +48,31 @@ impl Deref for SafeCursor {
&self.raw &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
}
}