Move Windows backend to winit-win32

This commit is contained in:
Mads Marquart 2025-05-25 05:13:25 +02:00 committed by GitHub
parent b1f8d778a1
commit 3b986f5583
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
26 changed files with 299 additions and 280 deletions

5
.github/CODEOWNERS vendored
View file

@ -21,9 +21,8 @@
/src/platform/web.rs @daxpedda /src/platform/web.rs @daxpedda
/src/platform_impl/web @daxpedda /src/platform_impl/web @daxpedda
# Windows # Windows (Win32)
/src/platform/windows.rs @notgull /winit-win32 @notgull
/src/platform_impl/windows @notgull
# Orbital (Redox OS) # Orbital (Redox OS)
/winit-orbital @jackpot51 /winit-orbital @jackpot51

View file

@ -190,6 +190,10 @@ jobs:
if: contains(matrix.platform.target, 'redox') if: contains(matrix.platform.target, 'redox')
run: cargo test -p winit-orbital run: cargo test -p winit-orbital
- name: Test winit Win32
if: contains(matrix.platform.target, 'windows')
run: cargo $CMD test -p winit-win32 --target=${{ matrix.platform.target }}
# Test only on Linux x86_64, so we avoid spending unnecessary CI hours. # Test only on Linux x86_64, so we avoid spending unnecessary CI hours.
- name: Test dpi crate - name: Test dpi crate
if: > if: >

View file

@ -15,6 +15,7 @@ winit = { path = "." }
winit-android = { version = "0.0.0", path = "winit-android" } winit-android = { version = "0.0.0", path = "winit-android" }
winit-core = { version = "0.0.0", path = "winit-core" } winit-core = { version = "0.0.0", path = "winit-core" }
winit-orbital = { version = "0.0.0", path = "winit-orbital" } winit-orbital = { version = "0.0.0", path = "winit-orbital" }
winit-win32 = { version = "0.0.0", path = "winit-win32" }
# Core dependencies. # Core dependencies.
bitflags = "2" bitflags = "2"
@ -339,36 +340,8 @@ objc2-ui-kit = { workspace = true, features = [
"UIWindow", "UIWindow",
] } ] }
# Windows
[target.'cfg(target_os = "windows")'.dependencies] [target.'cfg(target_os = "windows")'.dependencies]
unicode-segmentation.workspace = true winit-win32.workspace = true
windows-sys = { workspace = true, features = [
"Win32_Devices_HumanInterfaceDevice",
"Win32_Foundation",
"Win32_Globalization",
"Win32_Graphics_Dwm",
"Win32_Graphics_Gdi",
"Win32_Media",
"Win32_System_Com_StructuredStorage",
"Win32_System_Com",
"Win32_System_LibraryLoader",
"Win32_System_Ole",
"Win32_Security",
"Win32_System_SystemInformation",
"Win32_System_SystemServices",
"Win32_System_Threading",
"Win32_System_WindowsProgramming",
"Win32_UI_Accessibility",
"Win32_UI_Controls",
"Win32_UI_HiDpi",
"Win32_UI_Input_Ime",
"Win32_UI_Input_KeyboardAndMouse",
"Win32_UI_Input_Pointer",
"Win32_UI_Input_Touch",
"Win32_UI_Shell",
"Win32_UI_TextServices",
"Win32_UI_WindowsAndMessaging",
] }
# Linux # Linux
[target.'cfg(all(unix, not(any(target_os = "redox", target_family = "wasm", target_os = "android", target_vendor = "apple"))))'.dependencies] [target.'cfg(all(unix, not(any(target_os = "redox", target_family = "wasm", target_os = "android", target_vendor = "apple"))))'.dependencies]

View file

@ -348,6 +348,30 @@ impl winit_android::EventLoopBuilderExtAndroid for EventLoopBuilder {
} }
} }
#[cfg(windows_platform)]
impl winit_win32::EventLoopBuilderExtWindows for EventLoopBuilder {
#[inline]
fn with_any_thread(&mut self, any_thread: bool) -> &mut Self {
self.platform_specific.any_thread = any_thread;
self
}
#[inline]
fn with_dpi_aware(&mut self, dpi_aware: bool) -> &mut Self {
self.platform_specific.dpi_aware = dpi_aware;
self
}
#[inline]
fn with_msg_hook<F>(&mut self, callback: F) -> &mut Self
where
F: FnMut(*const core::ffi::c_void) -> bool + 'static,
{
self.platform_specific.msg_hook = Some(Box::new(callback));
self
}
}
/// ```compile_error /// ```compile_error
/// use winit::event_loop::run_on_demand::EventLoopExtRunOnDemand; /// use winit::event_loop::run_on_demand::EventLoopExtRunOnDemand;
/// use winit::event_loop::EventLoop; /// use winit::event_loop::EventLoop;

View file

@ -17,7 +17,7 @@ pub mod wayland;
#[cfg(web_platform)] #[cfg(web_platform)]
pub mod web; pub mod web;
#[cfg(windows_platform)] #[cfg(windows_platform)]
pub mod windows; pub use winit_win32 as windows;
#[cfg(x11_platform)] #[cfg(x11_platform)]
pub mod x11; pub mod x11;

View file

@ -9,7 +9,7 @@ pub(crate) use winit_orbital as platform;
#[cfg(web_platform)] #[cfg(web_platform)]
mod web; mod web;
#[cfg(windows_platform)] #[cfg(windows_platform)]
mod windows; pub(crate) use winit_win32 as platform;
#[cfg(target_vendor = "apple")] #[cfg(target_vendor = "apple")]
use self::apple as platform; use self::apple as platform;
@ -19,8 +19,6 @@ use self::linux as platform;
pub use self::platform::*; pub use self::platform::*;
#[cfg(web_platform)] #[cfg(web_platform)]
use self::web as platform; use self::web as platform;
#[cfg(windows_platform)]
use self::windows as platform;
#[cfg(all( #[cfg(all(
not(ios_platform), not(ios_platform),

View file

@ -1,82 +0,0 @@
use windows_sys::Win32::Foundation::HWND;
use windows_sys::Win32::UI::WindowsAndMessaging::WINDOW_LONG_PTR_INDEX;
use winit_core::event::DeviceId;
pub(crate) use self::event_loop::{EventLoop, PlatformSpecificEventLoopAttributes};
pub(crate) use self::icon::{RaiiIcon, SelectedCursor};
pub(crate) use self::keyboard::{physicalkey_to_scancode, scancode_to_physicalkey};
pub(crate) use self::monitor::MonitorHandle;
pub(crate) use self::window::Window;
fn wrap_device_id(id: u32) -> DeviceId {
DeviceId::from_raw(id as i64)
}
#[inline(always)]
const fn get_xbutton_wparam(x: u32) -> u16 {
hiword(x)
}
#[inline(always)]
const fn get_x_lparam(x: u32) -> i16 {
loword(x) as _
}
#[inline(always)]
const fn get_y_lparam(x: u32) -> i16 {
hiword(x) as _
}
#[inline(always)]
pub(crate) const fn primarylangid(lgid: u16) -> u16 {
lgid & 0x3ff
}
#[inline(always)]
pub(crate) const fn loword(x: u32) -> u16 {
(x & 0xffff) as u16
}
#[inline(always)]
const fn hiword(x: u32) -> u16 {
((x >> 16) & 0xffff) as u16
}
#[inline(always)]
unsafe fn get_window_long(hwnd: HWND, nindex: WINDOW_LONG_PTR_INDEX) -> isize {
#[cfg(target_pointer_width = "64")]
return unsafe { windows_sys::Win32::UI::WindowsAndMessaging::GetWindowLongPtrW(hwnd, nindex) };
#[cfg(target_pointer_width = "32")]
return unsafe {
windows_sys::Win32::UI::WindowsAndMessaging::GetWindowLongW(hwnd, nindex) as isize
};
}
#[inline(always)]
unsafe fn set_window_long(hwnd: HWND, nindex: WINDOW_LONG_PTR_INDEX, dwnewlong: isize) -> isize {
#[cfg(target_pointer_width = "64")]
return unsafe {
windows_sys::Win32::UI::WindowsAndMessaging::SetWindowLongPtrW(hwnd, nindex, dwnewlong)
};
#[cfg(target_pointer_width = "32")]
return unsafe {
windows_sys::Win32::UI::WindowsAndMessaging::SetWindowLongW(hwnd, nindex, dwnewlong as i32)
as isize
};
}
#[macro_use]
mod util;
mod dark_mode;
mod definitions;
mod dpi;
mod drop_handler;
mod event_loop;
mod icon;
mod ime;
mod keyboard;
mod keyboard_layout;
mod monitor;
pub(crate) mod raw_input;
mod window;
mod window_state;

59
winit-win32/Cargo.toml Normal file
View file

@ -0,0 +1,59 @@
[package]
description = "Winit's Win32/Windows backend"
documentation = "https://docs.rs/winit-win32"
edition.workspace = true
license.workspace = true
name = "winit-win32"
repository.workspace = true
rust-version.workspace = true
version = "0.0.0"
[features]
serde = ["dep:serde", "bitflags/serde", "smol_str/serde", "dpi/serde", "winit-core/serde"]
[dependencies]
bitflags.workspace = true
cursor-icon.workspace = true
dpi.workspace = true
rwh_06.workspace = true
serde = { workspace = true, optional = true }
smol_str.workspace = true
tracing.workspace = true
winit-core.workspace = true
# Platform-specific
unicode-segmentation.workspace = true
windows-sys = { workspace = true, features = [
"Win32_Devices_HumanInterfaceDevice",
"Win32_Foundation",
"Win32_Globalization",
"Win32_Graphics_Dwm",
"Win32_Graphics_Gdi",
"Win32_Media",
"Win32_System_Com_StructuredStorage",
"Win32_System_Com",
"Win32_System_LibraryLoader",
"Win32_System_Ole",
"Win32_Security",
"Win32_System_SystemInformation",
"Win32_System_SystemServices",
"Win32_System_Threading",
"Win32_System_WindowsProgramming",
"Win32_UI_Accessibility",
"Win32_UI_Controls",
"Win32_UI_HiDpi",
"Win32_UI_Input_Ime",
"Win32_UI_Input_KeyboardAndMouse",
"Win32_UI_Input_Pointer",
"Win32_UI_Input_Touch",
"Win32_UI_Shell",
"Win32_UI_TextServices",
"Win32_UI_WindowsAndMessaging",
] }
[dev-dependencies]
winit.workspace = true
[package.metadata.docs.rs]
all-features = true
targets = ["x86_64-pc-windows-msvc"]

1
winit-win32/README.md Symbolic link
View file

@ -0,0 +1 @@
../README.md

View file

@ -12,7 +12,7 @@ use windows_sys::Win32::UI::HiDpi::{
}; };
use windows_sys::Win32::UI::WindowsAndMessaging::IsProcessDPIAware; use windows_sys::Win32::UI::WindowsAndMessaging::IsProcessDPIAware;
use crate::platform_impl::platform::util::{ use crate::util::{
ENABLE_NON_CLIENT_DPI_SCALING, GET_DPI_FOR_MONITOR, GET_DPI_FOR_WINDOW, SET_PROCESS_DPI_AWARE, ENABLE_NON_CLIENT_DPI_SCALING, GET_DPI_FOR_MONITOR, GET_DPI_FOR_WINDOW, SET_PROCESS_DPI_AWARE,
SET_PROCESS_DPI_AWARENESS, SET_PROCESS_DPI_AWARENESS_CONTEXT, SET_PROCESS_DPI_AWARENESS, SET_PROCESS_DPI_AWARENESS_CONTEXT,
}; };

View file

@ -14,7 +14,7 @@ use windows_sys::Win32::System::Ole::{CF_HDROP, DROPEFFECT_COPY, DROPEFFECT_NONE
use windows_sys::Win32::UI::Shell::{DragFinish, DragQueryFileW, HDROP}; use windows_sys::Win32::UI::Shell::{DragFinish, DragQueryFileW, HDROP};
use winit_core::event::WindowEvent; use winit_core::event::WindowEvent;
use crate::platform_impl::platform::definitions::{ use crate::definitions::{
IDataObject, IDataObjectVtbl, IDropTarget, IDropTargetVtbl, IUnknown, IUnknownVtbl, IDataObject, IDataObjectVtbl, IDropTarget, IDropTargetVtbl, IUnknown, IUnknownVtbl,
}; };

View file

@ -79,20 +79,18 @@ use winit_core::window::{Theme, Window as CoreWindow, WindowAttributes, WindowId
pub(super) use self::runner::{Event, EventLoopRunner}; pub(super) use self::runner::{Event, EventLoopRunner};
use super::window::set_skip_taskbar; use super::window::set_skip_taskbar;
use super::SelectedCursor; use super::SelectedCursor;
use crate::platform_impl::platform::dark_mode::try_theme; use crate::dark_mode::try_theme;
use crate::platform_impl::platform::dpi::{become_dpi_aware, dpi_to_scale_factor}; use crate::dpi::{become_dpi_aware, dpi_to_scale_factor};
use crate::platform_impl::platform::drop_handler::FileDropHandler; use crate::drop_handler::FileDropHandler;
use crate::platform_impl::platform::icon::WinCursor; use crate::icon::WinCursor;
use crate::platform_impl::platform::ime::ImeContext; use crate::ime::ImeContext;
use crate::platform_impl::platform::keyboard::KeyEventBuilder; use crate::keyboard::KeyEventBuilder;
use crate::platform_impl::platform::keyboard_layout::LAYOUT_CACHE; use crate::keyboard_layout::LAYOUT_CACHE;
use crate::platform_impl::platform::monitor::{self, MonitorHandle}; use crate::monitor::{self, MonitorHandle};
use crate::platform_impl::platform::window::InitData; use crate::util::wrap_device_id;
use crate::platform_impl::platform::window_state::{ use crate::window::{InitData, Window};
CursorFlags, ImeState, WindowFlags, WindowState, use crate::window_state::{CursorFlags, ImeState, WindowFlags, WindowState};
}; use crate::{raw_input, util};
use crate::platform_impl::platform::{raw_input, util, wrap_device_id};
use crate::platform_impl::Window;
pub(crate) struct WindowData { pub(crate) struct WindowData {
pub window_state: Arc<Mutex<WindowState>>, pub window_state: Arc<Mutex<WindowState>>,
@ -150,10 +148,10 @@ impl fmt::Debug for EventLoop {
} }
} }
pub(crate) struct PlatformSpecificEventLoopAttributes { pub struct PlatformSpecificEventLoopAttributes {
pub(crate) any_thread: bool, pub any_thread: bool,
pub(crate) dpi_aware: bool, pub dpi_aware: bool,
pub(crate) msg_hook: Option<Box<dyn FnMut(*const c_void) -> bool + 'static>>, pub msg_hook: Option<Box<dyn FnMut(*const c_void) -> bool + 'static>>,
} }
impl fmt::Debug for PlatformSpecificEventLoopAttributes { impl fmt::Debug for PlatformSpecificEventLoopAttributes {
@ -194,7 +192,7 @@ impl std::hash::Hash for PlatformSpecificEventLoopAttributes {
} }
impl EventLoop { impl EventLoop {
pub(crate) fn new( pub fn new(
attributes: &mut PlatformSpecificEventLoopAttributes, attributes: &mut PlatformSpecificEventLoopAttributes,
) -> Result<Self, EventLoopError> { ) -> Result<Self, EventLoopError> {
let thread_id = unsafe { GetCurrentThreadId() }; let thread_id = unsafe { GetCurrentThreadId() };
@ -880,7 +878,7 @@ fn create_event_target_window() -> HWND {
ptr::null(), ptr::null(),
); );
super::set_window_long( util::set_window_long(
window, window,
GWL_STYLE, GWL_STYLE,
// The window technically has to be visible to receive WM_PAINT messages (which are // The window technically has to be visible to receive WM_PAINT messages (which are
@ -899,7 +897,7 @@ fn insert_event_target_window_data(
let userdata = ThreadMsgTargetData { event_loop_runner }; let userdata = ThreadMsgTargetData { event_loop_runner };
let input_ptr = Box::into_raw(Box::new(userdata)); let input_ptr = Box::into_raw(Box::new(userdata));
unsafe { super::set_window_long(thread_msg_target, GWL_USERDATA, input_ptr as isize) }; unsafe { util::set_window_long(thread_msg_target, GWL_USERDATA, input_ptr as isize) };
} }
/// Capture mouse input, allowing `window` to receive mouse events when the cursor is outside of /// Capture mouse input, allowing `window` to receive mouse events when the cursor is outside of
@ -977,7 +975,7 @@ pub(super) unsafe extern "system" fn public_window_callback(
wparam: WPARAM, wparam: WPARAM,
lparam: LPARAM, lparam: LPARAM,
) -> LRESULT { ) -> LRESULT {
let userdata = unsafe { super::get_window_long(window, GWL_USERDATA) }; let userdata = unsafe { util::get_window_long(window, GWL_USERDATA) };
let userdata_ptr = match (userdata, msg) { let userdata_ptr = match (userdata, msg) {
(0, WM_NCCREATE) => { (0, WM_NCCREATE) => {
@ -986,7 +984,7 @@ pub(super) unsafe extern "system" fn public_window_callback(
let result = match unsafe { initdata.on_nccreate(window) } { let result = match unsafe { initdata.on_nccreate(window) } {
Some(userdata) => unsafe { Some(userdata) => unsafe {
super::set_window_long(window, GWL_USERDATA, userdata as _); util::set_window_long(window, GWL_USERDATA, userdata as _);
DefWindowProcW(window, msg, wparam, lparam) DefWindowProcW(window, msg, wparam, lparam)
}, },
None => -1, // failed to create the window None => -1, // failed to create the window
@ -1176,7 +1174,7 @@ unsafe fn public_window_callback_inner(
}, },
WM_NCDESTROY => { WM_NCDESTROY => {
unsafe { super::set_window_long(window, GWL_USERDATA, 0) }; unsafe { util::set_window_long(window, GWL_USERDATA, 0) };
userdata.userdata_removed.set(true); userdata.userdata_removed.set(true);
result = ProcResult::Value(0); result = ProcResult::Value(0);
}, },
@ -1301,8 +1299,8 @@ unsafe fn public_window_callback_inner(
WM_SIZE => { WM_SIZE => {
use winit_core::event::WindowEvent::SurfaceResized; use winit_core::event::WindowEvent::SurfaceResized;
let w = super::loword(lparam as u32) as u32; let w = util::loword(lparam as u32) as u32;
let h = super::hiword(lparam as u32) as u32; let h = util::hiword(lparam as u32) as u32;
let physical_size = PhysicalSize::new(w, h); let physical_size = PhysicalSize::new(w, h);
@ -1533,8 +1531,8 @@ unsafe fn public_window_callback_inner(
use winit_core::event::WindowEvent::{PointerEntered, PointerLeft, PointerMoved}; use winit_core::event::WindowEvent::{PointerEntered, PointerLeft, PointerMoved};
use winit_core::event::{PointerKind, PointerSource}; use winit_core::event::{PointerKind, PointerSource};
let x = super::get_x_lparam(lparam as u32) as i32; let x = util::get_x_lparam(lparam as u32) as i32;
let y = super::get_y_lparam(lparam as u32) as i32; let y = util::get_y_lparam(lparam as u32) as i32;
let position = PhysicalPosition::new(x as f64, y as f64); let position = PhysicalPosition::new(x as f64, y as f64);
let cursor_moved; let cursor_moved;
@ -1681,8 +1679,8 @@ unsafe fn public_window_callback_inner(
update_modifiers(window, userdata); update_modifiers(window, userdata);
let x = super::get_x_lparam(lparam as u32) as i32; let x = util::get_x_lparam(lparam as u32) as i32;
let y = super::get_y_lparam(lparam as u32) as i32; let y = util::get_y_lparam(lparam as u32) as i32;
let position = PhysicalPosition::new(x as f64, y as f64); let position = PhysicalPosition::new(x as f64, y as f64);
userdata.send_window_event(window, PointerButton { userdata.send_window_event(window, PointerButton {
@ -1704,8 +1702,8 @@ unsafe fn public_window_callback_inner(
update_modifiers(window, userdata); update_modifiers(window, userdata);
let x = super::get_x_lparam(lparam as u32) as i32; let x = util::get_x_lparam(lparam as u32) as i32;
let y = super::get_y_lparam(lparam as u32) as i32; let y = util::get_y_lparam(lparam as u32) as i32;
let position = PhysicalPosition::new(x as f64, y as f64); let position = PhysicalPosition::new(x as f64, y as f64);
userdata.send_window_event(window, PointerButton { userdata.send_window_event(window, PointerButton {
@ -1727,8 +1725,8 @@ unsafe fn public_window_callback_inner(
update_modifiers(window, userdata); update_modifiers(window, userdata);
let x = super::get_x_lparam(lparam as u32) as i32; let x = util::get_x_lparam(lparam as u32) as i32;
let y = super::get_y_lparam(lparam as u32) as i32; let y = util::get_y_lparam(lparam as u32) as i32;
let position = PhysicalPosition::new(x as f64, y as f64); let position = PhysicalPosition::new(x as f64, y as f64);
userdata.send_window_event(window, PointerButton { userdata.send_window_event(window, PointerButton {
@ -1750,8 +1748,8 @@ unsafe fn public_window_callback_inner(
update_modifiers(window, userdata); update_modifiers(window, userdata);
let x = super::get_x_lparam(lparam as u32) as i32; let x = util::get_x_lparam(lparam as u32) as i32;
let y = super::get_y_lparam(lparam as u32) as i32; let y = util::get_y_lparam(lparam as u32) as i32;
let position = PhysicalPosition::new(x as f64, y as f64); let position = PhysicalPosition::new(x as f64, y as f64);
userdata.send_window_event(window, PointerButton { userdata.send_window_event(window, PointerButton {
@ -1773,8 +1771,8 @@ unsafe fn public_window_callback_inner(
update_modifiers(window, userdata); update_modifiers(window, userdata);
let x = super::get_x_lparam(lparam as u32) as i32; let x = util::get_x_lparam(lparam as u32) as i32;
let y = super::get_y_lparam(lparam as u32) as i32; let y = util::get_y_lparam(lparam as u32) as i32;
let position = PhysicalPosition::new(x as f64, y as f64); let position = PhysicalPosition::new(x as f64, y as f64);
userdata.send_window_event(window, PointerButton { userdata.send_window_event(window, PointerButton {
@ -1796,8 +1794,8 @@ unsafe fn public_window_callback_inner(
update_modifiers(window, userdata); update_modifiers(window, userdata);
let x = super::get_x_lparam(lparam as u32) as i32; let x = util::get_x_lparam(lparam as u32) as i32;
let y = super::get_y_lparam(lparam as u32) as i32; let y = util::get_y_lparam(lparam as u32) as i32;
let position = PhysicalPosition::new(x as f64, y as f64); let position = PhysicalPosition::new(x as f64, y as f64);
userdata.send_window_event(window, PointerButton { userdata.send_window_event(window, PointerButton {
@ -1814,14 +1812,14 @@ unsafe fn public_window_callback_inner(
use winit_core::event::ElementState::Pressed; use winit_core::event::ElementState::Pressed;
use winit_core::event::MouseButton::{Back, Forward, Other}; use winit_core::event::MouseButton::{Back, Forward, Other};
use winit_core::event::WindowEvent::PointerButton; use winit_core::event::WindowEvent::PointerButton;
let xbutton = super::get_xbutton_wparam(wparam as u32); let xbutton = util::get_xbutton_wparam(wparam as u32);
unsafe { capture_mouse(window, &mut userdata.window_state_lock()) }; unsafe { capture_mouse(window, &mut userdata.window_state_lock()) };
update_modifiers(window, userdata); update_modifiers(window, userdata);
let x = super::get_x_lparam(lparam as u32) as i32; let x = util::get_x_lparam(lparam as u32) as i32;
let y = super::get_y_lparam(lparam as u32) as i32; let y = util::get_y_lparam(lparam as u32) as i32;
let position = PhysicalPosition::new(x as f64, y as f64); let position = PhysicalPosition::new(x as f64, y as f64);
userdata.send_window_event(window, PointerButton { userdata.send_window_event(window, PointerButton {
@ -1843,14 +1841,14 @@ unsafe fn public_window_callback_inner(
use winit_core::event::ElementState::Released; use winit_core::event::ElementState::Released;
use winit_core::event::MouseButton::{Back, Forward, Other}; use winit_core::event::MouseButton::{Back, Forward, Other};
use winit_core::event::WindowEvent::PointerButton; use winit_core::event::WindowEvent::PointerButton;
let xbutton = super::get_xbutton_wparam(wparam as u32); let xbutton = util::get_xbutton_wparam(wparam as u32);
unsafe { release_mouse(userdata.window_state_lock()) }; unsafe { release_mouse(userdata.window_state_lock()) };
update_modifiers(window, userdata); update_modifiers(window, userdata);
let x = super::get_x_lparam(lparam as u32) as i32; let x = util::get_x_lparam(lparam as u32) as i32;
let y = super::get_y_lparam(lparam as u32) as i32; let y = util::get_y_lparam(lparam as u32) as i32;
let position = PhysicalPosition::new(x as f64, y as f64); let position = PhysicalPosition::new(x as f64, y as f64);
userdata.send_window_event(window, PointerButton { userdata.send_window_event(window, PointerButton {
@ -1884,7 +1882,7 @@ unsafe fn public_window_callback_inner(
use winit_core::event::ElementState::{Pressed, Released}; use winit_core::event::ElementState::{Pressed, Released};
use winit_core::event::{PointerKind, PointerSource}; use winit_core::event::{PointerKind, PointerSource};
let pcount = super::loword(wparam as u32) as usize; let pcount = util::loword(wparam as u32) as usize;
let mut inputs = Vec::with_capacity(pcount); let mut inputs = Vec::with_capacity(pcount);
let htouch = lparam as *mut _; let htouch = lparam as *mut _;
if unsafe { if unsafe {
@ -1967,7 +1965,7 @@ unsafe fn public_window_callback_inner(
*util::SKIP_POINTER_FRAME_MESSAGES, *util::SKIP_POINTER_FRAME_MESSAGES,
*util::GET_POINTER_DEVICE_RECTS, *util::GET_POINTER_DEVICE_RECTS,
) { ) {
let pointer_id = super::loword(wparam as u32) as u32; let pointer_id = util::loword(wparam as u32) as u32;
let mut entries_count = 0u32; let mut entries_count = 0u32;
let mut pointers_count = 0u32; let mut pointers_count = 0u32;
if unsafe { if unsafe {
@ -2165,7 +2163,7 @@ unsafe fn public_window_callback_inner(
// The return value for the preceding `WM_NCHITTEST` message is conveniently // The return value for the preceding `WM_NCHITTEST` message is conveniently
// provided through the low-order word of lParam. We use that here since // provided through the low-order word of lParam. We use that here since
// `WM_MOUSEMOVE` seems to come after `WM_SETCURSOR` for a given cursor movement. // `WM_MOUSEMOVE` seems to come after `WM_SETCURSOR` for a given cursor movement.
let in_client_area = super::loword(lparam as u32) as u32 == HTCLIENT; let in_client_area = util::loword(lparam as u32) as u32 == HTCLIENT;
if in_client_area { if in_client_area {
Some(window_state.mouse.selected_cursor.clone()) Some(window_state.mouse.selected_cursor.clone())
} else { } else {
@ -2221,7 +2219,7 @@ unsafe fn public_window_callback_inner(
// "you only need to use either the X-axis or the Y-axis value when scaling your // "you only need to use either the X-axis or the Y-axis value when scaling your
// application since they are the same". // application since they are the same".
// https://msdn.microsoft.com/en-us/library/windows/desktop/dn312083(v=vs.85).aspx // https://msdn.microsoft.com/en-us/library/windows/desktop/dn312083(v=vs.85).aspx
let new_dpi_x = super::loword(wparam as u32) as u32; let new_dpi_x = util::loword(wparam as u32) as u32;
let new_scale_factor = dpi_to_scale_factor(new_dpi_x); let new_scale_factor = dpi_to_scale_factor(new_dpi_x);
let old_scale_factor: f64; let old_scale_factor: f64;
@ -2474,7 +2472,7 @@ unsafe extern "system" fn thread_event_target_callback(
lparam: LPARAM, lparam: LPARAM,
) -> LRESULT { ) -> LRESULT {
let userdata_ptr = let userdata_ptr =
unsafe { super::get_window_long(window, GWL_USERDATA) } as *mut ThreadMsgTargetData; unsafe { util::get_window_long(window, GWL_USERDATA) } as *mut ThreadMsgTargetData;
if userdata_ptr.is_null() { if userdata_ptr.is_null() {
// `userdata_ptr` will always be null for the first `WM_GETMINMAXINFO`, as well as // `userdata_ptr` will always be null for the first `WM_GETMINMAXINFO`, as well as
// `WM_NCCREATE` and `WM_CREATE`. // `WM_NCCREATE` and `WM_CREATE`.
@ -2493,7 +2491,7 @@ unsafe extern "system" fn thread_event_target_callback(
// the git blame and history would be preserved. // the git blame and history would be preserved.
let callback = || match msg { let callback = || match msg {
WM_NCDESTROY => { WM_NCDESTROY => {
unsafe { super::set_window_long(window, GWL_USERDATA, 0) }; unsafe { util::set_window_long(window, GWL_USERDATA, 0) };
userdata_removed = true; userdata_removed = true;
0 0
}, },

View file

@ -14,8 +14,8 @@ use winit_core::event_loop::ActiveEventLoop as RootActiveEventLoop;
use winit_core::window::WindowId; use winit_core::window::WindowId;
use super::{ActiveEventLoop, ControlFlow, EventLoopThreadExecutor}; use super::{ActiveEventLoop, ControlFlow, EventLoopThreadExecutor};
use crate::platform_impl::platform::event_loop::{WindowData, GWL_USERDATA}; use crate::event_loop::{WindowData, GWL_USERDATA};
use crate::platform_impl::platform::get_window_long; use crate::util::get_window_long;
type EventHandler = Cell<Option<&'static mut (dyn ApplicationHandler + 'static)>>; type EventHandler = Cell<Option<&'static mut (dyn ApplicationHandler + 'static)>>;

View file

@ -18,7 +18,7 @@ use winit_core::error::RequestError;
use winit_core::icon::*; use winit_core::icon::*;
use super::util; use super::util;
use crate::platform::windows::WinIcon; use crate::WinIcon;
pub(crate) const PIXEL_SIZE: usize = mem::size_of::<Pixel>(); pub(crate) const PIXEL_SIZE: usize = mem::size_of::<Pixel>();

View file

@ -12,7 +12,7 @@ use windows_sys::Win32::UI::Input::Ime::{
}; };
use windows_sys::Win32::UI::WindowsAndMessaging::{GetSystemMetrics, SM_IMMENABLED}; use windows_sys::Win32::UI::WindowsAndMessaging::{GetSystemMetrics, SM_IMMENABLED};
use crate::platform::windows::HWND; use crate::HWND;
pub struct ImeContext { pub struct ImeContext {
hwnd: HWND, hwnd: HWND,

View file

@ -29,11 +29,9 @@ use winit_core::keyboard::{
Key, KeyCode, KeyLocation, NamedKey, NativeKey, NativeKeyCode, PhysicalKey, Key, KeyCode, KeyLocation, NamedKey, NativeKey, NativeKeyCode, PhysicalKey,
}; };
use crate::platform_impl::platform::event_loop::ProcResult; use crate::event_loop::ProcResult;
use crate::platform_impl::platform::keyboard_layout::{ use crate::keyboard_layout::{Layout, LayoutCache, WindowsModifiers, LAYOUT_CACHE};
Layout, LayoutCache, WindowsModifiers, LAYOUT_CACHE, use crate::util::{loword, primarylangid};
};
use crate::platform_impl::platform::{loword, primarylangid};
pub type ExScancode = u16; pub type ExScancode = u16;
@ -900,7 +898,7 @@ fn get_location(scancode: ExScancode, hkl: HKL) -> KeyLocation {
} }
} }
pub(crate) fn physicalkey_to_scancode(physical_key: PhysicalKey) -> Option<u32> { pub fn physicalkey_to_scancode(physical_key: PhysicalKey) -> Option<u32> {
// See `scancode_to_physicalkey` for more info // See `scancode_to_physicalkey` for more info
let hkl = unsafe { GetKeyboardLayout(0) }; let hkl = unsafe { GetKeyboardLayout(0) };
@ -1096,7 +1094,7 @@ pub(crate) fn physicalkey_to_scancode(physical_key: PhysicalKey) -> Option<u32>
} }
} }
pub(crate) fn scancode_to_physicalkey(scancode: u32) -> PhysicalKey { pub fn scancode_to_physicalkey(scancode: u32) -> PhysicalKey {
// See: https://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html // See: https://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html
// and: https://www.w3.org/TR/uievents-code/ // and: https://www.w3.org/TR/uievents-code/
// and: The widget/NativeKeyToDOMCodeName.h file in the firefox source // and: The widget/NativeKeyToDOMCodeName.h file in the firefox source

View file

@ -42,7 +42,8 @@ use windows_sys::Win32::UI::Input::KeyboardAndMouse::{
}; };
use winit_core::keyboard::{Key, KeyCode, ModifiersState, NamedKey, NativeKey, PhysicalKey}; use winit_core::keyboard::{Key, KeyCode, ModifiersState, NamedKey, NativeKey, PhysicalKey};
use crate::platform_impl::{loword, primarylangid, scancode_to_physicalkey}; use crate::keyboard::scancode_to_physicalkey;
use crate::util::{loword, primarylangid};
pub(crate) static LAYOUT_CACHE: LazyLock<Mutex<LayoutCache>> = pub(crate) static LAYOUT_CACHE: LazyLock<Mutex<LayoutCache>> =
LazyLock::new(|| Mutex::new(LayoutCache::default())); LazyLock::new(|| Mutex::new(LayoutCache::default()));

View file

@ -1,25 +1,44 @@
//! # Windows //! # Winit Win32 / Windows backend
//! //!
//! The supported OS version is Windows 7 or higher, though Windows 10 is //! The supported OS version is Windows 7 or higher, though Windows 10 is
//! tested regularly. //! tested regularly.
#![cfg(target_os = "windows")] // FIXME(madsmtm): Allow compiling on all platforms.
#[macro_use]
mod util;
mod dark_mode;
mod definitions;
mod dpi;
mod drop_handler;
mod event_loop;
mod icon;
mod ime;
mod keyboard;
mod keyboard_layout;
mod monitor;
mod raw_input;
mod window;
mod window_state;
use std::borrow::Borrow; use std::borrow::Borrow;
use std::ffi::c_void; use std::ffi::c_void;
use std::ops::Deref; use std::ops::Deref;
use std::path::Path; use std::path::Path;
use std::sync::Arc; use std::sync::Arc;
use ::dpi::PhysicalSize;
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[cfg(windows_platform)]
use windows_sys::Win32::Foundation::HANDLE; use windows_sys::Win32::Foundation::HANDLE;
use winit_core::window::PlatformWindowAttributes; use winit_core::event::DeviceId;
use winit_core::icon::{BadIcon, Icon};
use winit_core::window::{PlatformWindowAttributes, Window as CoreWindow};
use crate::dpi::PhysicalSize; pub use self::event_loop::{EventLoop, PlatformSpecificEventLoopAttributes};
use crate::event::DeviceId; use self::icon::{RaiiIcon, SelectedCursor};
use crate::event_loop::EventLoopBuilder; pub use self::keyboard::{physicalkey_to_scancode, scancode_to_physicalkey};
use crate::icon::{BadIcon, Icon}; pub use self::monitor::{MonitorHandle, VideoModeHandle};
use crate::platform_impl::RaiiIcon; pub use self::window::Window;
use crate::window::Window;
/// Window Handle type used by Win32 API /// Window Handle type used by Win32 API
pub type HWND = *mut c_void; pub type HWND = *mut c_void;
@ -121,24 +140,24 @@ pub enum CornerPreference {
/// ///
/// See [`WindowBorrowExtWindows::any_thread`] for more information. /// See [`WindowBorrowExtWindows::any_thread`] for more information.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct AnyThread<W: Window>(W); pub struct AnyThread<W: CoreWindow>(W);
impl<W: Window> AnyThread<W> { impl<W: CoreWindow> AnyThread<W> {
/// Get a reference to the inner window. /// Get a reference to the inner window.
#[inline] #[inline]
pub fn get_ref(&self) -> &dyn Window { pub fn get_ref(&self) -> &dyn CoreWindow {
&self.0 &self.0
} }
} }
impl<W: Window> Deref for AnyThread<W> { impl<W: CoreWindow> Deref for AnyThread<W> {
type Target = W; type Target = W;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
&self.0 &self.0
} }
} }
impl<W: Window> rwh_06::HasWindowHandle for AnyThread<W> { impl<W: CoreWindow> rwh_06::HasWindowHandle for AnyThread<W> {
fn window_handle(&self) -> Result<rwh_06::WindowHandle<'_>, rwh_06::HandleError> { fn window_handle(&self) -> Result<rwh_06::WindowHandle<'_>, rwh_06::HandleError> {
// SAFETY: The top level user has asserted this is only used safely. // SAFETY: The top level user has asserted this is only used safely.
unsafe { self.get_ref().window_handle_any_thread() } unsafe { self.get_ref().window_handle_any_thread() }
@ -213,29 +232,6 @@ pub trait EventLoopBuilderExtWindows {
F: FnMut(*const c_void) -> bool + 'static; F: FnMut(*const c_void) -> bool + 'static;
} }
impl EventLoopBuilderExtWindows for EventLoopBuilder {
#[inline]
fn with_any_thread(&mut self, any_thread: bool) -> &mut Self {
self.platform_specific.any_thread = any_thread;
self
}
#[inline]
fn with_dpi_aware(&mut self, dpi_aware: bool) -> &mut Self {
self.platform_specific.dpi_aware = dpi_aware;
self
}
#[inline]
fn with_msg_hook<F>(&mut self, callback: F) -> &mut Self
where
F: FnMut(*const c_void) -> bool + 'static,
{
self.platform_specific.msg_hook = Some(Box::new(callback));
self
}
}
/// Additional methods on `Window` that are specific to Windows. /// Additional methods on `Window` that are specific to Windows.
pub trait WindowExtWindows { pub trait WindowExtWindows {
/// Enables or disables mouse and keyboard input to the specified window. /// Enables or disables mouse and keyboard input to the specified window.
@ -344,40 +340,40 @@ pub trait WindowExtWindows {
) -> Result<rwh_06::WindowHandle<'_>, rwh_06::HandleError>; ) -> Result<rwh_06::WindowHandle<'_>, rwh_06::HandleError>;
} }
impl WindowExtWindows for dyn Window + '_ { impl WindowExtWindows for dyn CoreWindow + '_ {
#[inline] #[inline]
fn set_enable(&self, enabled: bool) { fn set_enable(&self, enabled: bool) {
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap(); let window = self.cast_ref::<Window>().unwrap();
window.set_enable(enabled) window.set_enable(enabled)
} }
#[inline] #[inline]
fn set_taskbar_icon(&self, taskbar_icon: Option<Icon>) { fn set_taskbar_icon(&self, taskbar_icon: Option<Icon>) {
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap(); let window = self.cast_ref::<Window>().unwrap();
window.set_taskbar_icon(taskbar_icon) window.set_taskbar_icon(taskbar_icon)
} }
#[inline] #[inline]
fn set_skip_taskbar(&self, skip: bool) { fn set_skip_taskbar(&self, skip: bool) {
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap(); let window = self.cast_ref::<Window>().unwrap();
window.set_skip_taskbar(skip) window.set_skip_taskbar(skip)
} }
#[inline] #[inline]
fn set_undecorated_shadow(&self, shadow: bool) { fn set_undecorated_shadow(&self, shadow: bool) {
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap(); let window = self.cast_ref::<Window>().unwrap();
window.set_undecorated_shadow(shadow) window.set_undecorated_shadow(shadow)
} }
#[inline] #[inline]
fn set_system_backdrop(&self, backdrop_type: BackdropType) { fn set_system_backdrop(&self, backdrop_type: BackdropType) {
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap(); let window = self.cast_ref::<Window>().unwrap();
window.set_system_backdrop(backdrop_type) window.set_system_backdrop(backdrop_type)
} }
#[inline] #[inline]
fn set_border_color(&self, color: Option<Color>) { fn set_border_color(&self, color: Option<Color>) {
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap(); let window = self.cast_ref::<Window>().unwrap();
window.set_border_color(color.unwrap_or(Color::NONE)) window.set_border_color(color.unwrap_or(Color::NONE))
} }
@ -386,26 +382,26 @@ impl WindowExtWindows for dyn Window + '_ {
// The windows docs don't mention NONE as a valid options but it works in practice and is // The windows docs don't mention NONE as a valid options but it works in practice and is
// useful to circumvent the Windows option "Show accent color on title bars and // useful to circumvent the Windows option "Show accent color on title bars and
// window borders" // window borders"
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap(); let window = self.cast_ref::<Window>().unwrap();
window.set_title_background_color(color.unwrap_or(Color::NONE)) window.set_title_background_color(color.unwrap_or(Color::NONE))
} }
#[inline] #[inline]
fn set_title_text_color(&self, color: Color) { fn set_title_text_color(&self, color: Color) {
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap(); let window = self.cast_ref::<Window>().unwrap();
window.set_title_text_color(color) window.set_title_text_color(color)
} }
#[inline] #[inline]
fn set_corner_preference(&self, preference: CornerPreference) { fn set_corner_preference(&self, preference: CornerPreference) {
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap(); let window = self.cast_ref::<Window>().unwrap();
window.set_corner_preference(preference) window.set_corner_preference(preference)
} }
unsafe fn window_handle_any_thread( unsafe fn window_handle_any_thread(
&self, &self,
) -> Result<rwh_06::WindowHandle<'_>, rwh_06::HandleError> { ) -> Result<rwh_06::WindowHandle<'_>, rwh_06::HandleError> {
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap(); let window = self.cast_ref::<Window>().unwrap();
unsafe { unsafe {
let handle = window.rwh_06_no_thread_check()?; let handle = window.rwh_06_no_thread_check()?;
@ -418,7 +414,7 @@ impl WindowExtWindows for dyn Window + '_ {
/// Additional methods for anything that dereference to [`Window`]. /// Additional methods for anything that dereference to [`Window`].
/// ///
/// [`Window`]: crate::window::Window /// [`Window`]: crate::window::Window
pub trait WindowBorrowExtWindows: Borrow<dyn Window> + Sized { pub trait WindowBorrowExtWindows: Borrow<dyn CoreWindow> + Sized {
/// Create an object that allows accessing the inner window handle in a thread-unsafe way. /// Create an object that allows accessing the inner window handle in a thread-unsafe way.
/// ///
/// It is possible to call [`window_handle_any_thread`] to get around Windows's thread /// It is possible to call [`window_handle_any_thread`] to get around Windows's thread
@ -439,13 +435,13 @@ pub trait WindowBorrowExtWindows: Borrow<dyn Window> + Sized {
/// [`window_handle_any_thread`]: WindowExtWindows::window_handle_any_thread /// [`window_handle_any_thread`]: WindowExtWindows::window_handle_any_thread
unsafe fn any_thread(self) -> AnyThread<Self> unsafe fn any_thread(self) -> AnyThread<Self>
where where
Self: Window, Self: CoreWindow,
{ {
AnyThread(self) AnyThread(self)
} }
} }
impl<W: Borrow<dyn Window> + Sized> WindowBorrowExtWindows for W {} impl<W: Borrow<dyn CoreWindow> + Sized> WindowBorrowExtWindows for W {}
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct WindowAttributesWindows { pub struct WindowAttributesWindows {
@ -503,7 +499,7 @@ impl WindowAttributesWindows {
/// ///
/// For more information, see <https://docs.microsoft.com/en-us/windows/win32/winmsg/window-features#owned-windows> /// For more information, see <https://docs.microsoft.com/en-us/windows/win32/winmsg/window-features#owned-windows>
/// ///
/// [`WindowAttributes::with_parent_window`]: crate::window::WindowAttributes::with_parent_window /// [`WindowAttributes::with_parent_window`]: winit_core::window::WindowAttributes::with_parent_window
pub fn with_owner_window(mut self, parent: HWND) -> Self { pub fn with_owner_window(mut self, parent: HWND) -> Self {
self.owner = Some(parent); self.owner = Some(parent);
self self
@ -518,13 +514,8 @@ impl WindowAttributesWindows {
/// Note: Dark mode cannot be supported for win32 menus, it's simply not possible to change how /// Note: Dark mode cannot be supported for win32 menus, it's simply not possible to change how
/// the menus look. If you use this, it is recommended that you combine it with /// the menus look. If you use this, it is recommended that you combine it with
/// `with_theme(Some(Theme::Light))` to avoid a jarring effect. /// `with_theme(Some(Theme::Light))` to avoid a jarring effect.
#[rustfmt::skip]
/// ///
#[cfg_attr( /// [`CreateMenu`]: windows_sys::Win32::UI::WindowsAndMessaging::CreateMenu"
windows_platform,
doc = "[`CreateMenu`]: windows_sys::Win32::UI::WindowsAndMessaging::CreateMenu"
)]
#[cfg_attr(not(windows_platform), doc = "[`CreateMenu`]: #only-available-on-windows")]
pub fn with_menu(mut self, menu: HMENU) -> Self { pub fn with_menu(mut self, menu: HMENU) -> Self {
self.menu = Some(menu); self.menu = Some(menu);
self self
@ -635,12 +626,11 @@ pub trait DeviceIdExtWindows {
fn persistent_identifier(&self) -> Option<String>; fn persistent_identifier(&self) -> Option<String>;
} }
#[cfg(windows_platform)]
impl DeviceIdExtWindows for DeviceId { impl DeviceIdExtWindows for DeviceId {
fn persistent_identifier(&self) -> Option<String> { fn persistent_identifier(&self) -> Option<String> {
let raw_id = self.into_raw(); let raw_id = self.into_raw();
if raw_id != 0 { if raw_id != 0 {
crate::platform_impl::raw_input::get_raw_input_device_name(raw_id as HANDLE) raw_input::get_raw_input_device_name(raw_id as HANDLE)
} else { } else {
None None
} }

View file

@ -11,7 +11,7 @@ use winapi::{
um::winuser, um::winuser,
}; };
use crate::platform_impl::platform::{event_loop::ProcResult, keyboard::next_kbd_msg}; use crate::{event_loop::ProcResult, keyboard::next_kbd_msg};
pub struct MinimalIme { pub struct MinimalIme {
// True if we're currently receiving messages belonging to a finished IME session. // True if we're currently receiving messages belonging to a finished IME session.

View file

@ -14,8 +14,8 @@ use windows_sys::Win32::Graphics::Gdi::{
use winit_core::monitor::{MonitorHandleProvider, VideoMode}; use winit_core::monitor::{MonitorHandleProvider, VideoMode};
use super::util::decode_wide; use super::util::decode_wide;
use crate::platform_impl::platform::dpi::{dpi_to_scale_factor, get_monitor_dpi}; use crate::dpi::{dpi_to_scale_factor, get_monitor_dpi};
use crate::platform_impl::platform::util::has_flag; use crate::util::has_flag;
#[derive(Clone)] #[derive(Clone)]
pub struct VideoModeHandle { pub struct VideoModeHandle {

View file

@ -25,7 +25,7 @@ use winit_core::event_loop::DeviceEvents;
use winit_core::keyboard::{KeyCode, PhysicalKey}; use winit_core::keyboard::{KeyCode, PhysicalKey};
use super::scancode_to_physicalkey; use super::scancode_to_physicalkey;
use crate::platform_impl::platform::util; use crate::util;
#[allow(dead_code)] #[allow(dead_code)]
pub fn get_raw_input_device_list() -> Option<Vec<RAWINPUTDEVICELIST>> { pub fn get_raw_input_device_list() -> Option<Vec<RAWINPUTDEVICELIST>> {

View file

@ -21,9 +21,16 @@ use windows_sys::Win32::UI::WindowsAndMessaging::{
GetWindowRect, IsIconic, ShowCursor, IDC_APPSTARTING, IDC_ARROW, IDC_CROSS, IDC_HAND, IDC_HELP, GetWindowRect, IsIconic, ShowCursor, IDC_APPSTARTING, IDC_ARROW, IDC_CROSS, IDC_HAND, IDC_HELP,
IDC_IBEAM, IDC_NO, IDC_SIZEALL, IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE, IDC_SIZEWE, IDC_WAIT, IDC_IBEAM, IDC_NO, IDC_SIZEALL, IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE, IDC_SIZEWE, IDC_WAIT,
SM_CXVIRTUALSCREEN, SM_CYVIRTUALSCREEN, SM_XVIRTUALSCREEN, SM_YVIRTUALSCREEN, SW_MAXIMIZE, SM_CXVIRTUALSCREEN, SM_CYVIRTUALSCREEN, SM_XVIRTUALSCREEN, SM_YVIRTUALSCREEN, SW_MAXIMIZE,
WINDOWPLACEMENT, WINDOWPLACEMENT, WINDOW_LONG_PTR_INDEX,
}; };
use winit_core::cursor::CursorIcon; use winit_core::cursor::CursorIcon;
use winit_core::event::DeviceId;
macro_rules! os_error {
($error:expr) => {{
winit_core::error::OsError::new(line!(), file!(), $error)
}};
}
pub fn encode_wide(string: impl AsRef<OsStr>) -> Vec<u16> { pub fn encode_wide(string: impl AsRef<OsStr>) -> Vec<u16> {
string.as_ref().encode_wide().chain(once(0)).collect() string.as_ref().encode_wide().chain(once(0)).collect()
@ -204,11 +211,8 @@ pub(super) fn get_function_impl(library: &str, function: &str) -> Option<*const
macro_rules! get_function { macro_rules! get_function {
($lib:expr, $func:ident) => { ($lib:expr, $func:ident) => {
crate::platform_impl::platform::util::get_function_impl( crate::util::get_function_impl(concat!($lib, '\0'), concat!(stringify!($func), '\0'))
concat!($lib, '\0'), .map(|f| unsafe { std::mem::transmute::<*const _, $func>(f) })
concat!(stringify!($func), '\0'),
)
.map(|f| unsafe { std::mem::transmute::<*const _, $func>(f) })
}; };
} }
@ -273,3 +277,64 @@ pub(crate) static GET_POINTER_DEVICE_RECTS: LazyLock<Option<GetPointerDeviceRect
LazyLock::new(|| get_function!("user32.dll", GetPointerDeviceRects)); LazyLock::new(|| get_function!("user32.dll", GetPointerDeviceRects));
pub(crate) static GET_POINTER_TOUCH_INFO: LazyLock<Option<GetPointerTouchInfo>> = pub(crate) static GET_POINTER_TOUCH_INFO: LazyLock<Option<GetPointerTouchInfo>> =
LazyLock::new(|| get_function!("user32.dll", GetPointerTouchInfo)); LazyLock::new(|| get_function!("user32.dll", GetPointerTouchInfo));
pub(crate) fn wrap_device_id(id: u32) -> DeviceId {
DeviceId::from_raw(id as i64)
}
#[inline(always)]
pub(crate) const fn get_xbutton_wparam(x: u32) -> u16 {
hiword(x)
}
#[inline(always)]
pub(crate) const fn get_x_lparam(x: u32) -> i16 {
loword(x) as _
}
#[inline(always)]
pub(crate) const fn get_y_lparam(x: u32) -> i16 {
hiword(x) as _
}
#[inline(always)]
pub(crate) const fn primarylangid(lgid: u16) -> u16 {
lgid & 0x3ff
}
#[inline(always)]
pub(crate) const fn loword(x: u32) -> u16 {
(x & 0xffff) as u16
}
#[inline(always)]
pub(crate) const fn hiword(x: u32) -> u16 {
((x >> 16) & 0xffff) as u16
}
#[inline(always)]
pub(crate) unsafe fn get_window_long(hwnd: HWND, nindex: WINDOW_LONG_PTR_INDEX) -> isize {
#[cfg(target_pointer_width = "64")]
return unsafe { windows_sys::Win32::UI::WindowsAndMessaging::GetWindowLongPtrW(hwnd, nindex) };
#[cfg(target_pointer_width = "32")]
return unsafe {
windows_sys::Win32::UI::WindowsAndMessaging::GetWindowLongW(hwnd, nindex) as isize
};
}
#[inline(always)]
pub(crate) unsafe fn set_window_long(
hwnd: HWND,
nindex: WINDOW_LONG_PTR_INDEX,
dwnewlong: isize,
) -> isize {
#[cfg(target_pointer_width = "64")]
return unsafe {
windows_sys::Win32::UI::WindowsAndMessaging::SetWindowLongPtrW(hwnd, nindex, dwnewlong)
};
#[cfg(target_pointer_width = "32")]
return unsafe {
windows_sys::Win32::UI::WindowsAndMessaging::SetWindowLongW(hwnd, nindex, dwnewlong as i32)
as isize
};
}

View file

@ -1,5 +1,3 @@
#![cfg(windows_platform)]
use std::borrow::Cow; use std::borrow::Cow;
use std::cell::Cell; use std::cell::Cell;
use std::ffi::c_void; use std::ffi::c_void;
@ -57,29 +55,22 @@ use winit_core::window::{
WindowAttributes, WindowButtons, WindowId, WindowLevel, WindowAttributes, WindowButtons, WindowId, WindowLevel,
}; };
use super::icon::WinCursor; use crate::dark_mode::try_theme;
use super::MonitorHandle; use crate::definitions::{
use crate::platform::windows::{
BackdropType, Color, CornerPreference, WinIcon, WindowAttributesWindows,
};
use crate::platform_impl::platform::dark_mode::try_theme;
use crate::platform_impl::platform::definitions::{
CLSID_TaskbarList, IID_ITaskbarList, IID_ITaskbarList2, ITaskbarList, ITaskbarList2, CLSID_TaskbarList, IID_ITaskbarList, IID_ITaskbarList2, ITaskbarList, ITaskbarList2,
}; };
use crate::platform_impl::platform::dpi::{ use crate::dpi::{dpi_to_scale_factor, enable_non_client_dpi_scaling, hwnd_dpi};
dpi_to_scale_factor, enable_non_client_dpi_scaling, hwnd_dpi, use crate::drop_handler::FileDropHandler;
use crate::event_loop::{self, ActiveEventLoop, Event, EventLoopRunner, DESTROY_MSG_ID};
use crate::icon::{IconType, WinCursor};
use crate::ime::ImeContext;
use crate::keyboard::KeyEventBuilder;
use crate::monitor::MonitorHandle;
use crate::window_state::{CursorFlags, SavedWindow, WindowFlags, WindowState};
use crate::{
monitor, util, BackdropType, Color, CornerPreference, SelectedCursor, WinIcon,
WindowAttributesWindows,
}; };
use crate::platform_impl::platform::drop_handler::FileDropHandler;
use crate::platform_impl::platform::event_loop::{
self, ActiveEventLoop, Event, EventLoopRunner, DESTROY_MSG_ID,
};
use crate::platform_impl::platform::icon::IconType;
use crate::platform_impl::platform::ime::ImeContext;
use crate::platform_impl::platform::keyboard::KeyEventBuilder;
use crate::platform_impl::platform::window_state::{
CursorFlags, SavedWindow, WindowFlags, WindowState,
};
use crate::platform_impl::platform::{monitor, util, SelectedCursor};
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
#[repr(transparent)] #[repr(transparent)]
@ -98,7 +89,7 @@ impl SyncWindowHandle {
/// The Win32 implementation of the main `Window` object. /// The Win32 implementation of the main `Window` object.
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct Window { pub struct Window {
/// Main handle for the window. /// Main handle for the window.
window: SyncWindowHandle, window: SyncWindowHandle,
@ -130,14 +121,14 @@ impl Window {
self.window.hwnd() self.window.hwnd()
} }
pub unsafe fn rwh_06_no_thread_check( pub(crate) unsafe fn rwh_06_no_thread_check(
&self, &self,
) -> Result<rwh_06::RawWindowHandle, rwh_06::HandleError> { ) -> Result<rwh_06::RawWindowHandle, rwh_06::HandleError> {
let mut window_handle = rwh_06::Win32WindowHandle::new(unsafe { let mut window_handle = rwh_06::Win32WindowHandle::new(unsafe {
// SAFETY: Handle will never be zero. // SAFETY: Handle will never be zero.
std::num::NonZeroIsize::new_unchecked(self.window.hwnd() as isize) std::num::NonZeroIsize::new_unchecked(self.window.hwnd() as isize)
}); });
let hinstance = unsafe { super::get_window_long(self.hwnd(), GWLP_HINSTANCE) }; let hinstance = unsafe { util::get_window_long(self.hwnd(), GWLP_HINSTANCE) };
window_handle.hinstance = std::num::NonZeroIsize::new(hinstance); window_handle.hinstance = std::num::NonZeroIsize::new(hinstance);
Ok(rwh_06::RawWindowHandle::Win32(window_handle)) Ok(rwh_06::RawWindowHandle::Win32(window_handle))
} }

View file

@ -21,7 +21,7 @@ use winit_core::keyboard::ModifiersState;
use winit_core::monitor::Fullscreen; use winit_core::monitor::Fullscreen;
use winit_core::window::{Theme, WindowAttributes}; use winit_core::window::{Theme, WindowAttributes};
use crate::platform_impl::platform::{event_loop, util, SelectedCursor}; use crate::{event_loop, util, SelectedCursor};
/// Contains information about states and the window that the callback is going to use. /// Contains information about states and the window that the callback is going to use.
#[derive(Debug)] #[derive(Debug)]