windows: Use a message-only window for WindowsPlatform (#37313)

Previously, we were using `PostThreadMessage` to pass messages to
`WindowsPlatform`. This PR switches to an approach similar to `winit`
which using a hidden window as the message window (I guess that’s why
winit uses a hidden window?). The difference is that this PR creates it
as a message-only window.

Thanks to @reflectronic for the original PR #37255, this implementation
just fits better with the current code style.


Release Notes:

- N/A

---------

Co-authored-by: reflectronic <john-tur@outlook.com>
This commit is contained in:
张小白
2025-09-02 22:32:24 +08:00
committed by GitHub
co-authored by reflectronic
parent f06c18765f
commit 2eb7ac97e0
4 changed files with 275 additions and 154 deletions
+10 -7
View File
@@ -14,34 +14,37 @@ use windows::{
},
Win32::{
Foundation::{LPARAM, WPARAM},
UI::WindowsAndMessaging::PostThreadMessageW,
UI::WindowsAndMessaging::PostMessageW,
},
};
use crate::{PlatformDispatcher, TaskLabel, WM_GPUI_TASK_DISPATCHED_ON_MAIN_THREAD};
use crate::{
HWND, PlatformDispatcher, SafeHwnd, TaskLabel, WM_GPUI_TASK_DISPATCHED_ON_MAIN_THREAD,
};
pub(crate) struct WindowsDispatcher {
main_sender: Sender<Runnable>,
parker: Mutex<Parker>,
main_thread_id: ThreadId,
main_thread_id_win32: u32,
platform_window_handle: SafeHwnd,
validation_number: usize,
}
impl WindowsDispatcher {
pub(crate) fn new(
main_sender: Sender<Runnable>,
main_thread_id_win32: u32,
platform_window_handle: HWND,
validation_number: usize,
) -> Self {
let parker = Mutex::new(Parker::new());
let main_thread_id = current().id();
let platform_window_handle = platform_window_handle.into();
WindowsDispatcher {
main_sender,
parker,
main_thread_id,
main_thread_id_win32,
platform_window_handle,
validation_number,
}
}
@@ -84,8 +87,8 @@ impl PlatformDispatcher for WindowsDispatcher {
fn dispatch_on_main_thread(&self, runnable: Runnable) {
match self.main_sender.send(runnable) {
Ok(_) => unsafe {
PostThreadMessageW(
self.main_thread_id_win32,
PostMessageW(
Some(self.platform_window_handle.as_raw()),
WM_GPUI_TASK_DISPATCHED_ON_MAIN_THREAD,
WPARAM(self.validation_number),
LPARAM(0),
+12 -7
View File
@@ -24,6 +24,7 @@ pub(crate) const WM_GPUI_CLOSE_ONE_WINDOW: u32 = WM_USER + 2;
pub(crate) const WM_GPUI_TASK_DISPATCHED_ON_MAIN_THREAD: u32 = WM_USER + 3;
pub(crate) const WM_GPUI_DOCK_MENU_ACTION: u32 = WM_USER + 4;
pub(crate) const WM_GPUI_FORCE_UPDATE_WINDOW: u32 = WM_USER + 5;
pub(crate) const WM_GPUI_KEYBOARD_LAYOUT_CHANGED: u32 = WM_USER + 6;
const SIZE_MOVE_LOOP_TIMER_ID: usize = 1;
const AUTO_HIDE_TASKBAR_THICKNESS_PX: i32 = 1;
@@ -99,7 +100,7 @@ impl WindowsWindowInner {
WM_IME_COMPOSITION => self.handle_ime_composition(handle, lparam),
WM_SETCURSOR => self.handle_set_cursor(handle, lparam),
WM_SETTINGCHANGE => self.handle_system_settings_changed(handle, wparam, lparam),
WM_INPUTLANGCHANGE => self.handle_input_language_changed(lparam),
WM_INPUTLANGCHANGE => self.handle_input_language_changed(),
WM_SHOWWINDOW => self.handle_window_visibility_changed(handle, wparam),
WM_GPUI_CURSOR_STYLE_CHANGED => self.handle_cursor_changed(lparam),
WM_GPUI_FORCE_UPDATE_WINDOW => self.draw_window(handle, true),
@@ -264,8 +265,8 @@ impl WindowsWindowInner {
callback();
}
unsafe {
PostThreadMessageW(
self.main_thread_id_win32,
PostMessageW(
Some(self.platform_window_handle),
WM_GPUI_CLOSE_ONE_WINDOW,
WPARAM(self.validation_number),
LPARAM(handle.0 as isize),
@@ -1146,11 +1147,15 @@ impl WindowsWindowInner {
Some(0)
}
fn handle_input_language_changed(&self, lparam: LPARAM) -> Option<isize> {
let thread = self.main_thread_id_win32;
let validation = self.validation_number;
fn handle_input_language_changed(&self) -> Option<isize> {
unsafe {
PostThreadMessageW(thread, WM_INPUTLANGCHANGE, WPARAM(validation), lparam).log_err();
PostMessageW(
Some(self.platform_window_handle),
WM_GPUI_KEYBOARD_LAYOUT_CHANGED,
WPARAM(self.validation_number),
LPARAM(0),
)
.log_err();
}
Some(0)
}
+248 -135
View File
@@ -2,7 +2,7 @@ use std::{
cell::RefCell,
ffi::OsStr,
path::{Path, PathBuf},
rc::Rc,
rc::{Rc, Weak},
sync::Arc,
};
@@ -19,7 +19,7 @@ use windows::{
Foundation::*,
Graphics::Gdi::*,
Security::Credentials::*,
System::{Com::*, LibraryLoader::*, Ole::*, SystemInformation::*, Threading::*},
System::{Com::*, LibraryLoader::*, Ole::*, SystemInformation::*},
UI::{Input::KeyboardAndMouse::*, Shell::*, WindowsAndMessaging::*},
},
core::*,
@@ -28,21 +28,27 @@ use windows::{
use crate::*;
pub(crate) struct WindowsPlatform {
state: RefCell<WindowsPlatformState>,
inner: Rc<WindowsPlatformInner>,
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>,
background_executor: BackgroundExecutor,
foreground_executor: ForegroundExecutor,
text_system: Arc<DirectWriteTextSystem>,
windows_version: WindowsVersion,
drop_target_helper: IDropTargetHelper,
validation_number: usize,
main_thread_id_win32: u32,
handle: HWND,
disable_direct_composition: bool,
}
struct WindowsPlatformInner {
state: RefCell<WindowsPlatformState>,
raw_window_handles: std::sync::Weak<RwLock<SmallVec<[SafeHwnd; 4]>>>,
// The below members will never change throughout the entire lifecycle of the app.
validation_number: usize,
main_receiver: flume::Receiver<Runnable>,
}
pub(crate) struct WindowsPlatformState {
callbacks: PlatformCallbacks,
menus: Vec<OwnedMenu>,
@@ -83,11 +89,36 @@ impl WindowsPlatform {
OleInitialize(None).context("unable to initialize Windows OLE")?;
}
let (main_sender, main_receiver) = flume::unbounded::<Runnable>();
let main_thread_id_win32 = unsafe { GetCurrentThreadId() };
let validation_number = rand::random::<usize>();
let raw_window_handles = Arc::new(RwLock::new(SmallVec::new()));
register_platform_window_class();
let mut context = PlatformWindowCreateContext {
inner: None,
raw_window_handles: Arc::downgrade(&raw_window_handles),
validation_number,
main_receiver: Some(main_receiver),
};
let result = unsafe {
CreateWindowExW(
WINDOW_EX_STYLE(0),
PLATFORM_WINDOW_CLASS_NAME,
None,
WINDOW_STYLE(0),
0,
0,
0,
0,
Some(HWND_MESSAGE),
None,
None,
Some(&context as *const _ as *const _),
)
};
let inner = context.inner.take().unwrap()?;
let handle = result?;
let dispatcher = Arc::new(WindowsDispatcher::new(
main_sender,
main_thread_id_win32,
handle,
validation_number,
));
let disable_direct_composition = std::env::var(DISABLE_DIRECT_COMPOSITION)
@@ -105,23 +136,19 @@ impl WindowsPlatform {
.context("Error creating drop target helper.")?
};
let icon = load_icon().unwrap_or_default();
let state = RefCell::new(WindowsPlatformState::new());
let raw_window_handles = Arc::new(RwLock::new(SmallVec::new()));
let windows_version = WindowsVersion::new().context("Error retrieve windows version")?;
Ok(Self {
state,
inner,
handle,
raw_window_handles,
icon,
main_receiver,
background_executor,
foreground_executor,
text_system,
disable_direct_composition,
windows_version,
drop_target_helper,
validation_number,
main_thread_id_win32,
})
}
@@ -143,119 +170,20 @@ impl WindowsPlatform {
});
}
fn close_one_window(&self, target_window: HWND) -> bool {
let mut lock = self.raw_window_handles.write();
let index = lock
.iter()
.position(|handle| handle.as_raw() == target_window)
.unwrap();
lock.remove(index);
lock.is_empty()
}
#[inline]
fn run_foreground_task(&self) {
for runnable in self.main_receiver.drain() {
runnable.run();
}
}
fn generate_creation_info(&self) -> WindowCreationInfo {
WindowCreationInfo {
icon: self.icon,
executor: self.foreground_executor.clone(),
current_cursor: self.state.borrow().current_cursor,
current_cursor: self.inner.state.borrow().current_cursor,
windows_version: self.windows_version,
drop_target_helper: self.drop_target_helper.clone(),
validation_number: self.validation_number,
main_receiver: self.main_receiver.clone(),
main_thread_id_win32: self.main_thread_id_win32,
validation_number: self.inner.validation_number,
main_receiver: self.inner.main_receiver.clone(),
platform_window_handle: self.handle,
disable_direct_composition: self.disable_direct_composition,
}
}
fn handle_dock_action_event(&self, action_idx: usize) {
let mut lock = self.state.borrow_mut();
if let Some(mut callback) = lock.callbacks.app_menu_action.take() {
let Some(action) = lock
.jump_list
.dock_menus
.get(action_idx)
.map(|dock_menu| dock_menu.action.boxed_clone())
else {
lock.callbacks.app_menu_action = Some(callback);
log::error!("Dock menu for index {action_idx} not found");
return;
};
drop(lock);
callback(&*action);
self.state.borrow_mut().callbacks.app_menu_action = Some(callback);
}
}
fn handle_input_lang_change(&self) {
let mut lock = self.state.borrow_mut();
if let Some(mut callback) = lock.callbacks.keyboard_layout_change.take() {
drop(lock);
callback();
self.state
.borrow_mut()
.callbacks
.keyboard_layout_change
.get_or_insert(callback);
}
}
// Returns if the app should quit.
fn handle_events(&self) {
let mut msg = MSG::default();
unsafe {
while GetMessageW(&mut msg, None, 0, 0).as_bool() {
match msg.message {
WM_QUIT => return,
WM_INPUTLANGCHANGE
| WM_GPUI_CLOSE_ONE_WINDOW
| WM_GPUI_TASK_DISPATCHED_ON_MAIN_THREAD
| WM_GPUI_DOCK_MENU_ACTION => {
if self.handle_gpui_events(msg.message, msg.wParam, msg.lParam, &msg) {
return;
}
}
_ => {
DispatchMessageW(&msg);
}
}
}
}
}
// Returns true if the app should quit.
fn handle_gpui_events(
&self,
message: u32,
wparam: WPARAM,
lparam: LPARAM,
msg: *const MSG,
) -> bool {
if wparam.0 != self.validation_number {
unsafe { DispatchMessageW(msg) };
return false;
}
match message {
WM_GPUI_CLOSE_ONE_WINDOW => {
if self.close_one_window(HWND(lparam.0 as _)) {
return true;
}
}
WM_GPUI_TASK_DISPATCHED_ON_MAIN_THREAD => self.run_foreground_task(),
WM_GPUI_DOCK_MENU_ACTION => self.handle_dock_action_event(lparam.0 as _),
WM_INPUTLANGCHANGE => self.handle_input_lang_change(),
_ => unreachable!(),
}
false
}
fn set_dock_menus(&self, menus: Vec<MenuItem>) {
let mut actions = Vec::new();
menus.into_iter().for_each(|menu| {
@@ -263,7 +191,7 @@ impl WindowsPlatform {
actions.push(dock_menu);
}
});
let mut lock = self.state.borrow_mut();
let mut lock = self.inner.state.borrow_mut();
lock.jump_list.dock_menus = actions;
update_jump_list(&lock.jump_list).log_err();
}
@@ -279,7 +207,7 @@ impl WindowsPlatform {
actions.push(dock_menu);
}
});
let mut lock = self.state.borrow_mut();
let mut lock = self.inner.state.borrow_mut();
lock.jump_list.dock_menus = actions;
lock.jump_list.recent_workspaces = entries;
update_jump_list(&lock.jump_list)
@@ -346,15 +274,25 @@ impl Platform for WindowsPlatform {
}
fn on_keyboard_layout_change(&self, callback: Box<dyn FnMut()>) {
self.state.borrow_mut().callbacks.keyboard_layout_change = Some(callback);
self.inner
.state
.borrow_mut()
.callbacks
.keyboard_layout_change = Some(callback);
}
fn run(&self, on_finish_launching: Box<dyn 'static + FnOnce()>) {
on_finish_launching();
self.begin_vsync_thread();
self.handle_events();
if let Some(ref mut callback) = self.state.borrow_mut().callbacks.quit {
let mut msg = MSG::default();
unsafe {
while GetMessageW(&mut msg, None, 0, 0).as_bool() {
DispatchMessageW(&msg);
}
}
if let Some(ref mut callback) = self.inner.state.borrow_mut().callbacks.quit {
callback();
}
}
@@ -469,7 +407,7 @@ impl Platform for WindowsPlatform {
}
fn on_open_urls(&self, callback: Box<dyn FnMut(Vec<String>)>) {
self.state.borrow_mut().callbacks.open_urls = Some(callback);
self.inner.state.borrow_mut().callbacks.open_urls = Some(callback);
}
fn prompt_for_paths(
@@ -539,19 +477,19 @@ impl Platform for WindowsPlatform {
}
fn on_quit(&self, callback: Box<dyn FnMut()>) {
self.state.borrow_mut().callbacks.quit = Some(callback);
self.inner.state.borrow_mut().callbacks.quit = Some(callback);
}
fn on_reopen(&self, callback: Box<dyn FnMut()>) {
self.state.borrow_mut().callbacks.reopen = Some(callback);
self.inner.state.borrow_mut().callbacks.reopen = Some(callback);
}
fn set_menus(&self, menus: Vec<Menu>, _keymap: &Keymap) {
self.state.borrow_mut().menus = menus.into_iter().map(|menu| menu.owned()).collect();
self.inner.state.borrow_mut().menus = menus.into_iter().map(|menu| menu.owned()).collect();
}
fn get_menus(&self) -> Option<Vec<OwnedMenu>> {
Some(self.state.borrow().menus.clone())
Some(self.inner.state.borrow().menus.clone())
}
fn set_dock_menu(&self, menus: Vec<MenuItem>, _keymap: &Keymap) {
@@ -559,15 +497,19 @@ impl Platform for WindowsPlatform {
}
fn on_app_menu_action(&self, callback: Box<dyn FnMut(&dyn Action)>) {
self.state.borrow_mut().callbacks.app_menu_action = Some(callback);
self.inner.state.borrow_mut().callbacks.app_menu_action = Some(callback);
}
fn on_will_open_app_menu(&self, callback: Box<dyn FnMut()>) {
self.state.borrow_mut().callbacks.will_open_app_menu = Some(callback);
self.inner.state.borrow_mut().callbacks.will_open_app_menu = Some(callback);
}
fn on_validate_app_menu_command(&self, callback: Box<dyn FnMut(&dyn Action) -> bool>) {
self.state.borrow_mut().callbacks.validate_app_menu_command = Some(callback);
self.inner
.state
.borrow_mut()
.callbacks
.validate_app_menu_command = Some(callback);
}
fn app_path(&self) -> Result<PathBuf> {
@@ -581,7 +523,7 @@ impl Platform for WindowsPlatform {
fn set_cursor_style(&self, style: CursorStyle) {
let hcursor = load_cursor(style);
let mut lock = self.state.borrow_mut();
let mut lock = self.inner.state.borrow_mut();
if lock.current_cursor.map(|c| c.0) != hcursor.map(|c| c.0) {
self.post_message(
WM_GPUI_CURSOR_STYLE_CHANGED,
@@ -684,10 +626,10 @@ impl Platform for WindowsPlatform {
fn perform_dock_menu_action(&self, action: usize) {
unsafe {
PostThreadMessageW(
self.main_thread_id_win32,
PostMessageW(
Some(self.handle),
WM_GPUI_DOCK_MENU_ACTION,
WPARAM(self.validation_number),
WPARAM(self.inner.validation_number),
LPARAM(action as isize),
)
.log_err();
@@ -703,9 +645,118 @@ impl Platform for WindowsPlatform {
}
}
impl WindowsPlatformInner {
fn new(context: &mut PlatformWindowCreateContext) -> Result<Rc<Self>> {
let state = RefCell::new(WindowsPlatformState::new());
Ok(Rc::new(Self {
state,
raw_window_handles: context.raw_window_handles.clone(),
validation_number: context.validation_number,
main_receiver: context.main_receiver.take().unwrap(),
}))
}
fn handle_msg(
self: &Rc<Self>,
handle: HWND,
msg: u32,
wparam: WPARAM,
lparam: LPARAM,
) -> LRESULT {
let handled = match msg {
WM_GPUI_CLOSE_ONE_WINDOW
| WM_GPUI_TASK_DISPATCHED_ON_MAIN_THREAD
| WM_GPUI_DOCK_MENU_ACTION
| WM_GPUI_KEYBOARD_LAYOUT_CHANGED => self.handle_gpui_events(msg, wparam, lparam),
_ => None,
};
if let Some(result) = handled {
LRESULT(result)
} else {
unsafe { DefWindowProcW(handle, msg, wparam, lparam) }
}
}
fn handle_gpui_events(&self, message: u32, wparam: WPARAM, lparam: LPARAM) -> Option<isize> {
if wparam.0 != self.validation_number {
log::error!("Wrong validation number while processing message: {message}");
return None;
}
match message {
WM_GPUI_CLOSE_ONE_WINDOW => {
if self.close_one_window(HWND(lparam.0 as _)) {
unsafe { PostQuitMessage(0) };
}
Some(0)
}
WM_GPUI_TASK_DISPATCHED_ON_MAIN_THREAD => self.run_foreground_task(),
WM_GPUI_DOCK_MENU_ACTION => self.handle_dock_action_event(lparam.0 as _),
WM_GPUI_KEYBOARD_LAYOUT_CHANGED => self.handle_keyboard_layout_change(),
_ => unreachable!(),
}
}
fn close_one_window(&self, target_window: HWND) -> bool {
let Some(all_windows) = self.raw_window_handles.upgrade() else {
log::error!("Failed to upgrade raw window handles");
return false;
};
let mut lock = all_windows.write();
let index = lock
.iter()
.position(|handle| handle.as_raw() == target_window)
.unwrap();
lock.remove(index);
lock.is_empty()
}
#[inline]
fn run_foreground_task(&self) -> Option<isize> {
for runnable in self.main_receiver.drain() {
runnable.run();
}
Some(0)
}
fn handle_dock_action_event(&self, action_idx: usize) -> Option<isize> {
let mut lock = self.state.borrow_mut();
let mut callback = lock.callbacks.app_menu_action.take()?;
let Some(action) = lock
.jump_list
.dock_menus
.get(action_idx)
.map(|dock_menu| dock_menu.action.boxed_clone())
else {
lock.callbacks.app_menu_action = Some(callback);
log::error!("Dock menu for index {action_idx} not found");
return Some(1);
};
drop(lock);
callback(&*action);
self.state.borrow_mut().callbacks.app_menu_action = Some(callback);
Some(0)
}
fn handle_keyboard_layout_change(&self) -> Option<isize> {
let mut callback = self
.state
.borrow_mut()
.callbacks
.keyboard_layout_change
.take()?;
callback();
self.state.borrow_mut().callbacks.keyboard_layout_change = Some(callback);
Some(0)
}
}
impl Drop for WindowsPlatform {
fn drop(&mut self) {
unsafe {
DestroyWindow(self.handle)
.context("Destroying platform window")
.log_err();
OleUninitialize();
}
}
@@ -719,10 +770,17 @@ pub(crate) struct WindowCreationInfo {
pub(crate) drop_target_helper: IDropTargetHelper,
pub(crate) validation_number: usize,
pub(crate) main_receiver: flume::Receiver<Runnable>,
pub(crate) main_thread_id_win32: u32,
pub(crate) platform_window_handle: HWND,
pub(crate) disable_direct_composition: bool,
}
struct PlatformWindowCreateContext {
inner: Option<Result<Rc<WindowsPlatformInner>>>,
raw_window_handles: std::sync::Weak<RwLock<SmallVec<[SafeHwnd; 4]>>>,
validation_number: usize,
main_receiver: Option<flume::Receiver<Runnable>>,
}
fn open_target(target: impl AsRef<OsStr>) -> Result<()> {
let target = target.as_ref();
let ret = unsafe {
@@ -893,6 +951,61 @@ fn should_auto_hide_scrollbars() -> Result<bool> {
Ok(ui_settings.AutoHideScrollBars()?)
}
const PLATFORM_WINDOW_CLASS_NAME: PCWSTR = w!("Zed::PlatformWindow");
fn register_platform_window_class() {
let wc = WNDCLASSW {
lpfnWndProc: Some(window_procedure),
lpszClassName: PCWSTR(PLATFORM_WINDOW_CLASS_NAME.as_ptr()),
..Default::default()
};
unsafe { RegisterClassW(&wc) };
}
unsafe extern "system" fn window_procedure(
hwnd: HWND,
msg: u32,
wparam: WPARAM,
lparam: LPARAM,
) -> LRESULT {
if msg == WM_NCCREATE {
let params = lparam.0 as *const CREATESTRUCTW;
let params = unsafe { &*params };
let creation_context = params.lpCreateParams as *mut PlatformWindowCreateContext;
let creation_context = unsafe { &mut *creation_context };
return match WindowsPlatformInner::new(creation_context) {
Ok(inner) => {
let weak = Box::new(Rc::downgrade(&inner));
unsafe { set_window_long(hwnd, GWLP_USERDATA, Box::into_raw(weak) as isize) };
creation_context.inner = Some(Ok(inner));
unsafe { DefWindowProcW(hwnd, msg, wparam, lparam) }
}
Err(error) => {
creation_context.inner = Some(Err(error));
LRESULT(0)
}
};
}
let ptr = unsafe { get_window_long(hwnd, GWLP_USERDATA) } as *mut Weak<WindowsPlatformInner>;
if ptr.is_null() {
return unsafe { DefWindowProcW(hwnd, msg, wparam, lparam) };
}
let inner = unsafe { &*ptr };
let result = if let Some(inner) = inner.upgrade() {
inner.handle_msg(hwnd, msg, wparam, lparam)
} else {
unsafe { DefWindowProcW(hwnd, msg, wparam, lparam) }
};
if msg == WM_NCDESTROY {
unsafe { set_window_long(hwnd, GWLP_USERDATA, 0) };
unsafe { drop(Box::from_raw(ptr)) };
}
result
}
#[cfg(test)]
mod tests {
use crate::{ClipboardItem, read_from_clipboard, write_to_clipboard};
+5 -5
View File
@@ -73,7 +73,7 @@ pub(crate) struct WindowsWindowInner {
pub(crate) windows_version: WindowsVersion,
pub(crate) validation_number: usize,
pub(crate) main_receiver: flume::Receiver<Runnable>,
pub(crate) main_thread_id_win32: u32,
pub(crate) platform_window_handle: HWND,
}
impl WindowsWindowState {
@@ -228,7 +228,7 @@ impl WindowsWindowInner {
windows_version: context.windows_version,
validation_number: context.validation_number,
main_receiver: context.main_receiver.clone(),
main_thread_id_win32: context.main_thread_id_win32,
platform_window_handle: context.platform_window_handle,
}))
}
@@ -342,7 +342,7 @@ struct WindowCreateContext {
drop_target_helper: IDropTargetHelper,
validation_number: usize,
main_receiver: flume::Receiver<Runnable>,
main_thread_id_win32: u32,
platform_window_handle: HWND,
appearance: WindowAppearance,
disable_direct_composition: bool,
}
@@ -361,7 +361,7 @@ impl WindowsWindow {
drop_target_helper,
validation_number,
main_receiver,
main_thread_id_win32,
platform_window_handle,
disable_direct_composition,
} = creation_info;
register_window_class(icon);
@@ -419,7 +419,7 @@ impl WindowsWindow {
drop_target_helper,
validation_number,
main_receiver,
main_thread_id_win32,
platform_window_handle,
appearance,
disable_direct_composition,
};