From 2261dcaa8ed4f7ad35667539cacb7a242188e4df Mon Sep 17 00:00:00 2001 From: Junkui Zhang <364772080@qq.com> Date: Mon, 4 Aug 2025 15:08:59 +0800 Subject: [PATCH] init --- crates/gpui/src/platform/windows/platform.rs | 60 ++++++++++++++------ crates/gpui/src/platform/windows/wrapper.rs | 33 ++++++++++- 2 files changed, 75 insertions(+), 18 deletions(-) diff --git a/crates/gpui/src/platform/windows/platform.rs b/crates/gpui/src/platform/windows/platform.rs index 8433e29c6d73f9b6a26d444dbb90b97140f5d57f..a1d052496a351600ee9040b84cac42ce74bc0e59 100644 --- a/crates/gpui/src/platform/windows/platform.rs +++ b/crates/gpui/src/platform/windows/platform.rs @@ -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, - raw_window_handles: RwLock>, + raw_window_handles: Arc>>, // The below members will never change throughout the entire lifecycle of the app. icon: HICON, main_receiver: flume::Receiver, @@ -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) { 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> { 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)) } diff --git a/crates/gpui/src/platform/windows/wrapper.rs b/crates/gpui/src/platform/windows/wrapper.rs index 6015dffdab299754d9469684ead08a9d5c95d4c6..9d9df3a79678a1b05cf8f95e9c1fec66a2de64da 100644 --- a/crates/gpui/src/platform/windows/wrapper.rs +++ b/crates/gpui/src/platform/windows/wrapper.rs @@ -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 for SafeHwnd { + fn from(value: HWND) -> Self { + SafeHwnd { raw: value } + } +} + +impl From for HWND { + fn from(value: SafeHwnd) -> Self { + value.raw + } +} + +impl Deref for SafeHwnd { + type Target = HWND; + + fn deref(&self) -> &Self::Target { + &self.raw + } +}