Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions rio-window/src/platform_impl/windows/dark_mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ use std::{ffi::c_void, ptr};

use crate::utils::Lazy;
use windows_sys::core::PCSTR;
use windows_sys::w;
use windows_sys::Win32::Foundation::{BOOL, HWND, NTSTATUS, S_OK};
use windows_sys::Win32::System::LibraryLoader::{GetProcAddress, LoadLibraryA};
use windows_sys::Win32::System::LibraryLoader::{GetProcAddress, LoadLibraryW};
use windows_sys::Win32::System::SystemInformation::OSVERSIONINFOW;
use windows_sys::Win32::UI::Accessibility::{HCF_HIGHCONTRASTON, HIGHCONTRASTA};
use windows_sys::Win32::UI::Accessibility::{HCF_HIGHCONTRASTON, HIGHCONTRASTW};
use windows_sys::Win32::UI::Controls::SetWindowTheme;
use windows_sys::Win32::UI::WindowsAndMessaging::{
SystemParametersInfoA, SPI_GETHIGHCONTRAST,
SystemParametersInfoW, SPI_GETHIGHCONTRAST,
};

use crate::window::Theme;
Expand Down Expand Up @@ -146,7 +147,7 @@ fn should_apps_use_dark_mode() -> bool {
return None;
}

let module = LoadLibraryA("uxtheme.dll\0".as_ptr());
let module = LoadLibraryW(w!("uxtheme.dll"));

if module.is_null() {
return None;
Expand All @@ -163,14 +164,14 @@ fn should_apps_use_dark_mode() -> bool {
}

fn is_high_contrast() -> bool {
let mut hc = HIGHCONTRASTA {
let mut hc = HIGHCONTRASTW {
cbSize: 0,
dwFlags: 0,
lpszDefaultScheme: ptr::null_mut(),
};

let ok = unsafe {
SystemParametersInfoA(
SystemParametersInfoW(
SPI_GETHIGHCONTRAST,
std::mem::size_of_val(&hc) as _,
&mut hc as *mut _ as _,
Expand Down
36 changes: 23 additions & 13 deletions rio-window/src/platform_impl/windows/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ use std::{mem, panic, ptr};

use crate::utils::Lazy;

use windows_sys::core::PCWSTR;
use windows_sys::w;
use windows_sys::Win32::Foundation::{
GetLastError, FALSE, HANDLE, HWND, LPARAM, LRESULT, POINT, RECT, WAIT_FAILED, WPARAM,
};
Expand Down Expand Up @@ -50,7 +52,7 @@ use windows_sys::Win32::UI::Input::{
use windows_sys::Win32::UI::WindowsAndMessaging::{
CreateWindowExW, DefWindowProcW, DestroyWindow, DispatchMessageW, GetClientRect,
GetCursorPos, GetMenu, LoadCursorW, MsgWaitForMultipleObjectsEx, PeekMessageW,
PostMessageW, RegisterClassExW, RegisterWindowMessageA, SetCursor, SetWindowPos,
PostMessageW, RegisterClassExW, RegisterWindowMessageW, SetCursor, SetWindowPos,
TranslateMessage, CREATESTRUCTW, GIDC_ARRIVAL, GIDC_REMOVAL, GWL_STYLE, GWL_USERDATA,
HTCAPTION, HTCLIENT, MINMAXINFO, MNC_CLOSE, MSG, MWMO_INPUTAVAILABLE,
NCCALCSIZE_PARAMS, PM_REMOVE, PT_PEN, PT_TOUCH, QS_ALLINPUT, RI_MOUSE_HWHEEL,
Expand Down Expand Up @@ -898,15 +900,15 @@ pub struct LazyMessageId {
id: AtomicU32,

/// The name of the message.
name: &'static str,
name: PCWSTR,
}

/// An invalid custom window ID.
const INVALID_ID: u32 = 0x0;

impl LazyMessageId {
/// Create a new `LazyId`.
const fn new(name: &'static str) -> Self {
const fn new(name: PCWSTR) -> Self {
Self {
id: AtomicU32::new(INVALID_ID),
name,
Expand All @@ -923,15 +925,20 @@ impl LazyMessageId {
}

// Register the message.
// SAFETY: We are sure that the pointer is a valid C string ending with '\0'.
assert!(self.name.ends_with('\0'));
let new_id = unsafe { RegisterWindowMessageA(self.name.as_ptr()) };
// assert!(self.name.ends_with('\0'));
let new_id = unsafe { RegisterWindowMessageW(self.name) };

assert_ne!(
new_id,
0,
"RegisterWindowMessageA returned zero for '{}': {}",
self.name,
"RegisterWindowMessageW returned zero for '{}': {}",
unsafe {
let mut len = 0;
while *self.name.add(len) != 0 {
len += 1;
}
String::from_utf16_lossy(std::slice::from_raw_parts(self.name, len))
},
std::io::Error::last_os_error()
);

Expand All @@ -944,27 +951,30 @@ impl LazyMessageId {
new_id
}
}
// SAFETY: PCWSTR is read-only in this context
unsafe impl Sync for LazyMessageId {}

// Message sent by the `EventLoopProxy` when we want to wake up the thread.
// WPARAM and LPARAM are unused.
static USER_EVENT_MSG_ID: LazyMessageId = LazyMessageId::new("Winit::WakeupMsg\0");
static USER_EVENT_MSG_ID: LazyMessageId = LazyMessageId::new(w!("Winit::WakeupMsg"));
// Message sent when we want to execute a closure in the thread.
// WPARAM contains a Box<Box<dyn FnMut()>> that must be retrieved with `Box::from_raw`,
// and LPARAM is unused.
static EXEC_MSG_ID: LazyMessageId = LazyMessageId::new("Winit::ExecMsg\0");
static EXEC_MSG_ID: LazyMessageId = LazyMessageId::new(w!("Winit::ExecMsg"));
// Message sent by a `Window` when it wants to be destroyed by the main thread.
// WPARAM and LPARAM are unused.
pub(crate) static DESTROY_MSG_ID: LazyMessageId =
LazyMessageId::new("Winit::DestroyMsg\0");
LazyMessageId::new(w!("Winit::DestroyMsg"));
// WPARAM is a bool specifying the `WindowFlags::MARKER_RETAIN_STATE_ON_SIZE` flag. See the
// documentation in the `window_state` module for more information.
pub(crate) static SET_RETAIN_STATE_ON_SIZE_MSG_ID: LazyMessageId =
LazyMessageId::new("Winit::SetRetainMaximized\0");
LazyMessageId::new(w!("Winit::SetRetainMaximized"));
static THREAD_EVENT_TARGET_WINDOW_CLASS: Lazy<Vec<u16>> =
Lazy::new(|| util::encode_wide("Winit Thread Event Target"));
/// When the taskbar is created, it registers a message with the "TaskbarCreated" string and then
/// broadcasts this message to all top-level windows <https://docs.microsoft.com/en-us/windows/win32/shell/taskbar#taskbar-creation-notification>
pub(crate) static TASKBAR_CREATED: LazyMessageId = LazyMessageId::new("TaskbarCreated\0");
pub(crate) static TASKBAR_CREATED: LazyMessageId =
LazyMessageId::new(w!("TaskbarCreated"));

fn create_event_target_window() -> HWND {
use windows_sys::Win32::UI::WindowsAndMessaging::{CS_HREDRAW, CS_VREDRAW};
Expand Down
13 changes: 8 additions & 5 deletions rio-window/src/platform_impl/windows/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::utils::Lazy;
use windows_sys::core::{HRESULT, PCWSTR};
use windows_sys::Win32::Foundation::{BOOL, HANDLE, HMODULE, HWND, RECT};
use windows_sys::Win32::Graphics::Gdi::{ClientToScreen, HMONITOR};
use windows_sys::Win32::System::LibraryLoader::{GetProcAddress, LoadLibraryA};
use windows_sys::Win32::System::LibraryLoader::{GetProcAddress, LoadLibraryW};
use windows_sys::Win32::System::SystemServices::IMAGE_DOS_HEADER;
use windows_sys::Win32::UI::HiDpi::{
DPI_AWARENESS_CONTEXT, MONITOR_DPI_TYPE, PROCESS_DPI_AWARENESS,
Expand Down Expand Up @@ -193,12 +193,15 @@ pub(crate) fn to_windows_cursor(cursor: CursorIcon) -> PCWSTR {
// may not be available on all Windows platforms supported by winit.
//
// `library` and `function` must be zero-terminated.
pub(super) fn get_function_impl(library: &str, function: &str) -> Option<*const c_void> {
assert_eq!(library.chars().last(), Some('\0'));
pub(super) fn get_function_impl(
library: PCWSTR,
function: &str,
) -> Option<*const c_void> {
// assert_eq!(library.chars().last(), Some('\0'));
assert_eq!(function.chars().last(), Some('\0'));

// Library names we will use are ASCII so we can use the A version to avoid string conversion.
let module = unsafe { LoadLibraryA(library.as_ptr()) };
let module = unsafe { LoadLibraryW(library) };
if module.is_null() {
return None;
}
Expand All @@ -210,7 +213,7 @@ pub(super) fn get_function_impl(library: &str, function: &str) -> Option<*const
macro_rules! get_function {
($lib:expr, $func:ident) => {
crate::platform_impl::platform::util::get_function_impl(
concat!($lib, '\0'),
::windows_sys::w!($lib),
concat!(stringify!($func), '\0'),
)
.map(|f| unsafe { std::mem::transmute::<*const _, $func>(f) })
Expand Down
Loading