Windows: Add #[deny(unsafe_op_in_unsafe_fn)] (#3070)

This commit is contained in:
Mads Marquart 2023-09-29 16:07:44 +02:00 committed by GitHub
parent cb58c49a90
commit b2b4564a5f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 339 additions and 289 deletions

View file

@ -78,36 +78,36 @@ pub fn dpi_to_scale_factor(dpi: u32) -> f64 {
} }
pub unsafe fn hwnd_dpi(hwnd: HWND) -> u32 { pub unsafe fn hwnd_dpi(hwnd: HWND) -> u32 {
let hdc = GetDC(hwnd); let hdc = unsafe { GetDC(hwnd) };
if hdc == 0 { if hdc == 0 {
panic!("[winit] `GetDC` returned null!"); panic!("[winit] `GetDC` returned null!");
} }
if let Some(GetDpiForWindow) = *GET_DPI_FOR_WINDOW { if let Some(GetDpiForWindow) = *GET_DPI_FOR_WINDOW {
// We are on Windows 10 Anniversary Update (1607) or later. // We are on Windows 10 Anniversary Update (1607) or later.
match GetDpiForWindow(hwnd) { match unsafe { GetDpiForWindow(hwnd) } {
0 => BASE_DPI, // 0 is returned if hwnd is invalid 0 => BASE_DPI, // 0 is returned if hwnd is invalid
dpi => dpi, dpi => dpi,
} }
} else if let Some(GetDpiForMonitor) = *GET_DPI_FOR_MONITOR { } else if let Some(GetDpiForMonitor) = *GET_DPI_FOR_MONITOR {
// We are on Windows 8.1 or later. // We are on Windows 8.1 or later.
let monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); let monitor = unsafe { MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST) };
if monitor == 0 { if monitor == 0 {
return BASE_DPI; return BASE_DPI;
} }
let mut dpi_x = 0; let mut dpi_x = 0;
let mut dpi_y = 0; let mut dpi_y = 0;
if GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &mut dpi_x, &mut dpi_y) == S_OK { if unsafe { GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &mut dpi_x, &mut dpi_y) } == S_OK {
dpi_x dpi_x
} else { } else {
BASE_DPI BASE_DPI
} }
} else { } else {
// We are on Vista or later. // We are on Vista or later.
if IsProcessDPIAware() != false.into() { if unsafe { IsProcessDPIAware() } != false.into() {
// If the process is DPI aware, then scaling must be handled by the application using // If the process is DPI aware, then scaling must be handled by the application using
// this DPI value. // this DPI value.
GetDeviceCaps(hdc, LOGPIXELSX) as u32 unsafe { GetDeviceCaps(hdc, LOGPIXELSX) as u32 }
} else { } else {
// If the process is DPI unaware, then scaling is performed by the OS; we thus return // If the process is DPI unaware, then scaling is performed by the OS; we thus return
// 96 (scale factor 1.0) to prevent the window from being re-scaled by both the // 96 (scale factor 1.0) to prevent the window from being re-scaled by both the

View file

@ -69,17 +69,17 @@ impl FileDropHandler {
} }
pub unsafe extern "system" fn AddRef(this: *mut IUnknown) -> u32 { pub unsafe extern "system" fn AddRef(this: *mut IUnknown) -> u32 {
let drop_handler_data = Self::from_interface(this); let drop_handler_data = unsafe { Self::from_interface(this) };
let count = drop_handler_data.refcount.fetch_add(1, Ordering::Release) + 1; let count = drop_handler_data.refcount.fetch_add(1, Ordering::Release) + 1;
count as u32 count as u32
} }
pub unsafe extern "system" fn Release(this: *mut IUnknown) -> u32 { pub unsafe extern "system" fn Release(this: *mut IUnknown) -> u32 {
let drop_handler = Self::from_interface(this); let drop_handler = unsafe { Self::from_interface(this) };
let count = drop_handler.refcount.fetch_sub(1, Ordering::Release) - 1; let count = drop_handler.refcount.fetch_sub(1, Ordering::Release) - 1;
if count == 0 { if count == 0 {
// Destroy the underlying data // Destroy the underlying data
drop(Box::from_raw(drop_handler as *mut FileDropHandlerData)); drop(unsafe { Box::from_raw(drop_handler as *mut FileDropHandlerData) });
} }
count as u32 count as u32
} }
@ -92,20 +92,24 @@ impl FileDropHandler {
pdwEffect: *mut u32, pdwEffect: *mut u32,
) -> HRESULT { ) -> HRESULT {
use crate::event::WindowEvent::HoveredFile; use crate::event::WindowEvent::HoveredFile;
let drop_handler = Self::from_interface(this); let drop_handler = unsafe { Self::from_interface(this) };
let hdrop = Self::iterate_filenames(pDataObj, |filename| { let hdrop = unsafe {
drop_handler.send_event(Event::WindowEvent { Self::iterate_filenames(pDataObj, |filename| {
window_id: RootWindowId(WindowId(drop_handler.window)), drop_handler.send_event(Event::WindowEvent {
event: HoveredFile(filename), window_id: RootWindowId(WindowId(drop_handler.window)),
}); event: HoveredFile(filename),
}); });
})
};
drop_handler.hovered_is_valid = hdrop.is_some(); drop_handler.hovered_is_valid = hdrop.is_some();
drop_handler.cursor_effect = if drop_handler.hovered_is_valid { drop_handler.cursor_effect = if drop_handler.hovered_is_valid {
DROPEFFECT_COPY DROPEFFECT_COPY
} else { } else {
DROPEFFECT_NONE DROPEFFECT_NONE
}; };
*pdwEffect = drop_handler.cursor_effect; unsafe {
*pdwEffect = drop_handler.cursor_effect;
}
S_OK S_OK
} }
@ -116,15 +120,17 @@ impl FileDropHandler {
_pt: *const POINTL, _pt: *const POINTL,
pdwEffect: *mut u32, pdwEffect: *mut u32,
) -> HRESULT { ) -> HRESULT {
let drop_handler = Self::from_interface(this); let drop_handler = unsafe { Self::from_interface(this) };
*pdwEffect = drop_handler.cursor_effect; unsafe {
*pdwEffect = drop_handler.cursor_effect;
}
S_OK S_OK
} }
pub unsafe extern "system" fn DragLeave(this: *mut IDropTarget) -> HRESULT { pub unsafe extern "system" fn DragLeave(this: *mut IDropTarget) -> HRESULT {
use crate::event::WindowEvent::HoveredFileCancelled; use crate::event::WindowEvent::HoveredFileCancelled;
let drop_handler = Self::from_interface(this); let drop_handler = unsafe { Self::from_interface(this) };
if drop_handler.hovered_is_valid { if drop_handler.hovered_is_valid {
drop_handler.send_event(Event::WindowEvent { drop_handler.send_event(Event::WindowEvent {
window_id: RootWindowId(WindowId(drop_handler.window)), window_id: RootWindowId(WindowId(drop_handler.window)),
@ -143,22 +149,24 @@ impl FileDropHandler {
_pdwEffect: *mut u32, _pdwEffect: *mut u32,
) -> HRESULT { ) -> HRESULT {
use crate::event::WindowEvent::DroppedFile; use crate::event::WindowEvent::DroppedFile;
let drop_handler = Self::from_interface(this); let drop_handler = unsafe { Self::from_interface(this) };
let hdrop = Self::iterate_filenames(pDataObj, |filename| { let hdrop = unsafe {
drop_handler.send_event(Event::WindowEvent { Self::iterate_filenames(pDataObj, |filename| {
window_id: RootWindowId(WindowId(drop_handler.window)), drop_handler.send_event(Event::WindowEvent {
event: DroppedFile(filename), window_id: RootWindowId(WindowId(drop_handler.window)),
}); event: DroppedFile(filename),
}); });
})
};
if let Some(hdrop) = hdrop { if let Some(hdrop) = hdrop {
DragFinish(hdrop); unsafe { DragFinish(hdrop) };
} }
S_OK S_OK
} }
unsafe fn from_interface<'a, InterfaceT>(this: *mut InterfaceT) -> &'a mut FileDropHandlerData { unsafe fn from_interface<'a, InterfaceT>(this: *mut InterfaceT) -> &'a mut FileDropHandlerData {
&mut *(this as *mut _) unsafe { &mut *(this as *mut _) }
} }
unsafe fn iterate_filenames<F>(data_obj: *const IDataObject, callback: F) -> Option<HDROP> unsafe fn iterate_filenames<F>(data_obj: *const IDataObject, callback: F) -> Option<HDROP>
@ -173,26 +181,29 @@ impl FileDropHandler {
tymed: TYMED_HGLOBAL as u32, tymed: TYMED_HGLOBAL as u32,
}; };
let mut medium = std::mem::zeroed(); let mut medium = unsafe { std::mem::zeroed() };
let get_data_fn = (*(*data_obj).cast::<IDataObjectVtbl>()).GetData; let get_data_fn = unsafe { (*(*data_obj).cast::<IDataObjectVtbl>()).GetData };
let get_data_result = get_data_fn(data_obj as *mut _, &drop_format, &mut medium); let get_data_result = unsafe { get_data_fn(data_obj as *mut _, &drop_format, &mut medium) };
if get_data_result >= 0 { if get_data_result >= 0 {
let hdrop = medium.Anonymous.hGlobal; let hdrop = unsafe { medium.Anonymous.hGlobal };
// The second parameter (0xFFFFFFFF) instructs the function to return the item count // The second parameter (0xFFFFFFFF) instructs the function to return the item count
let item_count = DragQueryFileW(hdrop, 0xFFFFFFFF, ptr::null_mut(), 0); let item_count = unsafe { DragQueryFileW(hdrop, 0xFFFFFFFF, ptr::null_mut(), 0) };
for i in 0..item_count { for i in 0..item_count {
// Get the length of the path string NOT including the terminating null character. // Get the length of the path string NOT including the terminating null character.
// Previously, this was using a fixed size array of MAX_PATH length, but the // Previously, this was using a fixed size array of MAX_PATH length, but the
// Windows API allows longer paths under certain circumstances. // Windows API allows longer paths under certain circumstances.
let character_count = DragQueryFileW(hdrop, i, ptr::null_mut(), 0) as usize; let character_count =
unsafe { DragQueryFileW(hdrop, i, ptr::null_mut(), 0) as usize };
let str_len = character_count + 1; let str_len = character_count + 1;
// Fill path_buf with the null-terminated file name // Fill path_buf with the null-terminated file name
let mut path_buf = Vec::with_capacity(str_len); let mut path_buf = Vec::with_capacity(str_len);
DragQueryFileW(hdrop, i, path_buf.as_mut_ptr(), str_len as u32); unsafe {
path_buf.set_len(str_len); DragQueryFileW(hdrop, i, path_buf.as_mut_ptr(), str_len as u32);
path_buf.set_len(str_len);
}
callback(OsString::from_wide(&path_buf[0..character_count]).into()); callback(OsString::from_wide(&path_buf[0..character_count]).into());
} }

View file

@ -145,7 +145,7 @@ pub(crate) struct WindowData<T: 'static> {
} }
impl<T> WindowData<T> { impl<T> WindowData<T> {
unsafe fn send_event(&self, event: Event<T>) { fn send_event(&self, event: Event<T>) {
self.event_loop_runner.send_event(event); self.event_loop_runner.send_event(event);
} }
@ -160,7 +160,7 @@ struct ThreadMsgTargetData<T: 'static> {
} }
impl<T> ThreadMsgTargetData<T> { impl<T> ThreadMsgTargetData<T> {
unsafe fn send_event(&self, event: Event<T>) { fn send_event(&self, event: Event<T>) {
self.event_loop_runner.send_event(event); self.event_loop_runner.send_event(event);
} }
} }
@ -596,7 +596,7 @@ fn main_thread_id() -> u32 {
#[link_section = ".CRT$XCU"] #[link_section = ".CRT$XCU"]
static INIT_MAIN_THREAD_ID: unsafe fn() = { static INIT_MAIN_THREAD_ID: unsafe fn() = {
unsafe fn initer() { unsafe fn initer() {
MAIN_THREAD_ID = GetCurrentThreadId(); unsafe { MAIN_THREAD_ID = GetCurrentThreadId() };
} }
initer initer
}; };
@ -884,7 +884,7 @@ fn insert_event_target_window_data<T>(
/// the window. /// the window.
unsafe fn capture_mouse(window: HWND, window_state: &mut WindowState) { unsafe fn capture_mouse(window: HWND, window_state: &mut WindowState) {
window_state.mouse.capture_count += 1; window_state.mouse.capture_count += 1;
SetCapture(window); unsafe { SetCapture(window) };
} }
/// Release mouse input, stopping windows on this thread from receiving mouse input when the cursor /// Release mouse input, stopping windows on this thread from receiving mouse input when the cursor
@ -894,7 +894,7 @@ unsafe fn release_mouse(mut window_state: MutexGuard<'_, WindowState>) {
if window_state.mouse.capture_count == 0 { if window_state.mouse.capture_count == 0 {
// ReleaseCapture() causes a WM_CAPTURECHANGED where we lock the window_state. // ReleaseCapture() causes a WM_CAPTURECHANGED where we lock the window_state.
drop(window_state); drop(window_state);
ReleaseCapture(); unsafe { ReleaseCapture() };
} }
} }
@ -922,12 +922,10 @@ fn update_modifiers<T>(window: HWND, userdata: &WindowData<T>) {
// Drop lock // Drop lock
drop(window_state); drop(window_state);
unsafe { userdata.send_event(Event::WindowEvent {
userdata.send_event(Event::WindowEvent { window_id: RootWindowId(WindowId(window)),
window_id: RootWindowId(WindowId(window)), event: ModifiersChanged(modifiers.into()),
event: ModifiersChanged(modifiers.into()), });
});
}
} }
} }
@ -970,18 +968,18 @@ pub(super) unsafe extern "system" fn public_window_callback<T: 'static>(
wparam: WPARAM, wparam: WPARAM,
lparam: LPARAM, lparam: LPARAM,
) -> LRESULT { ) -> LRESULT {
let userdata = super::get_window_long(window, GWL_USERDATA); let userdata = unsafe { super::get_window_long(window, GWL_USERDATA) };
let userdata_ptr = match (userdata, msg) { let userdata_ptr = match (userdata, msg) {
(0, WM_NCCREATE) => { (0, WM_NCCREATE) => {
let createstruct = &mut *(lparam as *mut CREATESTRUCTW); let createstruct = unsafe { &mut *(lparam as *mut CREATESTRUCTW) };
let initdata = &mut *(createstruct.lpCreateParams as *mut InitData<'_, T>); let initdata = unsafe { &mut *(createstruct.lpCreateParams as *mut InitData<'_, T>) };
let result = match initdata.on_nccreate(window) { let result = match unsafe { initdata.on_nccreate(window) } {
Some(userdata) => { Some(userdata) => unsafe {
super::set_window_long(window, GWL_USERDATA, userdata as _); super::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
}; };
@ -990,24 +988,24 @@ pub(super) unsafe extern "system" fn public_window_callback<T: 'static>(
// Getting here should quite frankly be impossible, // Getting here should quite frankly be impossible,
// but we'll make window creation fail here just in case. // but we'll make window creation fail here just in case.
(0, WM_CREATE) => return -1, (0, WM_CREATE) => return -1,
(_, WM_CREATE) => { (_, WM_CREATE) => unsafe {
let createstruct = &mut *(lparam as *mut CREATESTRUCTW); let createstruct = &mut *(lparam as *mut CREATESTRUCTW);
let initdata = createstruct.lpCreateParams; let initdata = createstruct.lpCreateParams;
let initdata = &mut *(initdata as *mut InitData<'_, T>); let initdata = &mut *(initdata as *mut InitData<'_, T>);
initdata.on_create(); initdata.on_create();
return DefWindowProcW(window, msg, wparam, lparam); return DefWindowProcW(window, msg, wparam, lparam);
} },
(0, _) => return DefWindowProcW(window, msg, wparam, lparam), (0, _) => return unsafe { DefWindowProcW(window, msg, wparam, lparam) },
_ => userdata as *mut WindowData<T>, _ => userdata as *mut WindowData<T>,
}; };
let (result, userdata_removed, recurse_depth) = { let (result, userdata_removed, recurse_depth) = {
let userdata = &*(userdata_ptr); let userdata = unsafe { &*(userdata_ptr) };
userdata.recurse_depth.set(userdata.recurse_depth.get() + 1); userdata.recurse_depth.set(userdata.recurse_depth.get() + 1);
let result = public_window_callback_inner(window, msg, wparam, lparam, userdata); let result = unsafe { public_window_callback_inner(window, msg, wparam, lparam, userdata) };
let userdata_removed = userdata.userdata_removed.get(); let userdata_removed = userdata.userdata_removed.get();
let recurse_depth = userdata.recurse_depth.get() - 1; let recurse_depth = userdata.recurse_depth.get() - 1;
@ -1017,7 +1015,7 @@ pub(super) unsafe extern "system" fn public_window_callback<T: 'static>(
}; };
if userdata_removed && recurse_depth == 0 { if userdata_removed && recurse_depth == 0 {
drop(Box::from_raw(userdata_ptr)); drop(unsafe { Box::from_raw(userdata_ptr) });
} }
result result
@ -1078,7 +1076,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
return; return;
} }
let params = &mut *(lparam as *mut NCCALCSIZE_PARAMS); let params = unsafe { &mut *(lparam as *mut NCCALCSIZE_PARAMS) };
if util::is_maximized(window) { if util::is_maximized(window) {
// Limit the window size when maximized to the current monitor. // Limit the window size when maximized to the current monitor.
@ -1087,7 +1085,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
// Use `MonitorFromRect` instead of `MonitorFromWindow` to select // Use `MonitorFromRect` instead of `MonitorFromWindow` to select
// the correct monitor here. // the correct monitor here.
// See https://github.com/MicrosoftEdge/WebView2Feedback/issues/2549 // See https://github.com/MicrosoftEdge/WebView2Feedback/issues/2549
let monitor = MonitorFromRect(&params.rgrc[0], MONITOR_DEFAULTTONULL); let monitor = unsafe { MonitorFromRect(&params.rgrc[0], MONITOR_DEFAULTTONULL) };
if let Ok(monitor_info) = monitor::get_monitor_info(monitor) { if let Ok(monitor_info) = monitor::get_monitor_info(monitor) {
params.rgrc[0] = monitor_info.monitorInfo.rcWork; params.rgrc[0] = monitor_info.monitorInfo.rcWork;
} }
@ -1121,7 +1119,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
let mut state = userdata.window_state_lock(); let mut state = userdata.window_state_lock();
if state.dragging { if state.dragging {
state.dragging = false; state.dragging = false;
PostMessageW(window, WM_LBUTTONUP, 0, lparam); unsafe { PostMessageW(window, WM_LBUTTONUP, 0, lparam) };
} }
state.set_window_flags_in_place(|f| f.remove(WindowFlags::MARKER_IN_SIZE_MOVE)); state.set_window_flags_in_place(|f| f.remove(WindowFlags::MARKER_IN_SIZE_MOVE));
@ -1130,7 +1128,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
WM_NCLBUTTONDOWN => { WM_NCLBUTTONDOWN => {
if wparam == HTCAPTION as _ { if wparam == HTCAPTION as _ {
PostMessageW(window, WM_MOUSEMOVE, 0, lparam); unsafe { PostMessageW(window, WM_MOUSEMOVE, 0, lparam) };
} }
result = ProcResult::DefWindowProc(wparam); result = ProcResult::DefWindowProc(wparam);
} }
@ -1146,7 +1144,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
WM_DESTROY => { WM_DESTROY => {
use crate::event::WindowEvent::Destroyed; use crate::event::WindowEvent::Destroyed;
RevokeDragDrop(window); unsafe { RevokeDragDrop(window) };
userdata.send_event(Event::WindowEvent { userdata.send_event(Event::WindowEvent {
window_id: RootWindowId(WindowId(window)), window_id: RootWindowId(WindowId(window)),
event: Destroyed, event: Destroyed,
@ -1155,7 +1153,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
} }
WM_NCDESTROY => { WM_NCDESTROY => {
super::set_window_long(window, GWL_USERDATA, 0); unsafe { super::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);
} }
@ -1164,7 +1162,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
if userdata.event_loop_runner.should_buffer() { if userdata.event_loop_runner.should_buffer() {
// this branch can happen in response to `UpdateWindow`, if win32 decides to // this branch can happen in response to `UpdateWindow`, if win32 decides to
// redraw the window outside the normal flow of the event loop. // redraw the window outside the normal flow of the event loop.
RedrawWindow(window, ptr::null(), 0, RDW_INTERNALPAINT); unsafe { RedrawWindow(window, ptr::null(), 0, RDW_INTERNALPAINT) };
} else { } else {
userdata.send_event(Event::WindowEvent { userdata.send_event(Event::WindowEvent {
window_id: RootWindowId(WindowId(window)), window_id: RootWindowId(WindowId(window)),
@ -1177,7 +1175,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
WM_WINDOWPOSCHANGING => { WM_WINDOWPOSCHANGING => {
let mut window_state = userdata.window_state_lock(); let mut window_state = userdata.window_state_lock();
if let Some(ref mut fullscreen) = window_state.fullscreen { if let Some(ref mut fullscreen) = window_state.fullscreen {
let window_pos = &mut *(lparam as *mut WINDOWPOS); let window_pos = unsafe { &mut *(lparam as *mut WINDOWPOS) };
let new_rect = RECT { let new_rect = RECT {
left: window_pos.x, left: window_pos.x,
top: window_pos.y, top: window_pos.y,
@ -1215,7 +1213,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
}; };
if let Some(new_rect) = new_rect { if let Some(new_rect) = new_rect {
let new_monitor = MonitorFromRect(&new_rect, MONITOR_DEFAULTTONULL); let new_monitor = unsafe { MonitorFromRect(&new_rect, MONITOR_DEFAULTTONULL) };
match fullscreen { match fullscreen {
Fullscreen::Borderless(ref mut fullscreen_monitor) => { Fullscreen::Borderless(ref mut fullscreen_monitor) => {
if new_monitor != 0 if new_monitor != 0
@ -1257,8 +1255,9 @@ unsafe fn public_window_callback_inner<T: 'static>(
use crate::event::WindowEvent::Moved; use crate::event::WindowEvent::Moved;
let windowpos = lparam as *const WINDOWPOS; let windowpos = lparam as *const WINDOWPOS;
if (*windowpos).flags & SWP_NOMOVE != SWP_NOMOVE { if unsafe { (*windowpos).flags & SWP_NOMOVE != SWP_NOMOVE } {
let physical_position = PhysicalPosition::new((*windowpos).x, (*windowpos).y); let physical_position =
unsafe { PhysicalPosition::new((*windowpos).x, (*windowpos).y) };
userdata.send_event(Event::WindowEvent { userdata.send_event(Event::WindowEvent {
window_id: RootWindowId(WindowId(window)), window_id: RootWindowId(WindowId(window)),
event: Moved(physical_position), event: Moved(physical_position),
@ -1321,7 +1320,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
// Windows Hangul IME sends WM_IME_COMPOSITION after WM_IME_ENDCOMPOSITION, so // Windows Hangul IME sends WM_IME_COMPOSITION after WM_IME_ENDCOMPOSITION, so
// check whether composing. // check whether composing.
if ime_allowed_and_composing { if ime_allowed_and_composing {
let ime_context = ImeContext::current(window); let ime_context = unsafe { ImeContext::current(window) };
if lparam == 0 { if lparam == 0 {
userdata.send_event(Event::WindowEvent { userdata.send_event(Event::WindowEvent {
@ -1333,7 +1332,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
// Google Japanese Input and ATOK have both flags, so // Google Japanese Input and ATOK have both flags, so
// first, receive composing result if exist. // first, receive composing result if exist.
if (lparam as u32 & GCS_RESULTSTR) != 0 { if (lparam as u32 & GCS_RESULTSTR) != 0 {
if let Some(text) = ime_context.get_composed_text() { if let Some(text) = unsafe { ime_context.get_composed_text() } {
userdata.window_state_lock().ime_state = ImeState::Enabled; userdata.window_state_lock().ime_state = ImeState::Enabled;
userdata.send_event(Event::WindowEvent { userdata.send_event(Event::WindowEvent {
@ -1349,7 +1348,9 @@ unsafe fn public_window_callback_inner<T: 'static>(
// Next, receive preedit range for next composing if exist. // Next, receive preedit range for next composing if exist.
if (lparam as u32 & GCS_COMPSTR) != 0 { if (lparam as u32 & GCS_COMPSTR) != 0 {
if let Some((text, first, last)) = ime_context.get_composing_text_and_cursor() { if let Some((text, first, last)) =
unsafe { ime_context.get_composing_text_and_cursor() }
{
userdata.window_state_lock().ime_state = ImeState::Preedit; userdata.window_state_lock().ime_state = ImeState::Preedit;
let cursor_range = first.map(|f| (f, last.unwrap_or(f))); let cursor_range = first.map(|f| (f, last.unwrap_or(f)));
@ -1374,8 +1375,8 @@ unsafe fn public_window_callback_inner<T: 'static>(
if userdata.window_state_lock().ime_state == ImeState::Preedit { if userdata.window_state_lock().ime_state == ImeState::Preedit {
// Windows Hangul IME sends WM_IME_COMPOSITION after WM_IME_ENDCOMPOSITION, so // Windows Hangul IME sends WM_IME_COMPOSITION after WM_IME_ENDCOMPOSITION, so
// trying receiving composing result and commit if exists. // trying receiving composing result and commit if exists.
let ime_context = ImeContext::current(window); let ime_context = unsafe { ImeContext::current(window) };
if let Some(text) = ime_context.get_composed_text() { if let Some(text) = unsafe { ime_context.get_composed_text() } {
userdata.send_event(Event::WindowEvent { userdata.send_event(Event::WindowEvent {
window_id: RootWindowId(WindowId(window)), window_id: RootWindowId(WindowId(window)),
event: WindowEvent::Ime(Ime::Preedit(String::new(), None)), event: WindowEvent::Ime(Ime::Preedit(String::new(), None)),
@ -1448,12 +1449,14 @@ unsafe fn public_window_callback_inner<T: 'static>(
}); });
// Calling TrackMouseEvent in order to receive mouse leave events. // Calling TrackMouseEvent in order to receive mouse leave events.
TrackMouseEvent(&mut TRACKMOUSEEVENT { unsafe {
cbSize: mem::size_of::<TRACKMOUSEEVENT>() as u32, TrackMouseEvent(&mut TRACKMOUSEEVENT {
dwFlags: TME_LEAVE, cbSize: mem::size_of::<TRACKMOUSEEVENT>() as u32,
hwndTrack: window, dwFlags: TME_LEAVE,
dwHoverTime: HOVER_DEFAULT, hwndTrack: window,
}); dwHoverTime: HOVER_DEFAULT,
})
};
} }
let x = super::get_x_lparam(lparam as u32) as f64; let x = super::get_x_lparam(lparam as u32) as f64;
@ -1551,7 +1554,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
} }
WM_KEYUP | WM_SYSKEYUP => { WM_KEYUP | WM_SYSKEYUP => {
if msg == WM_SYSKEYUP && GetMenu(window) != 0 { if msg == WM_SYSKEYUP && unsafe { GetMenu(window) != 0 } {
// let Windows handle event if the window has a native menu, a modal event loop // let Windows handle event if the window has a native menu, a modal event loop
// is started here on Alt key up. // is started here on Alt key up.
result = ProcResult::DefWindowProc(wparam); result = ProcResult::DefWindowProc(wparam);
@ -1561,7 +1564,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
WM_LBUTTONDOWN => { WM_LBUTTONDOWN => {
use crate::event::{ElementState::Pressed, MouseButton::Left, WindowEvent::MouseInput}; use crate::event::{ElementState::Pressed, MouseButton::Left, WindowEvent::MouseInput};
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);
@ -1581,7 +1584,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
ElementState::Released, MouseButton::Left, WindowEvent::MouseInput, ElementState::Released, MouseButton::Left, WindowEvent::MouseInput,
}; };
release_mouse(userdata.window_state_lock()); unsafe { release_mouse(userdata.window_state_lock()) };
update_modifiers(window, userdata); update_modifiers(window, userdata);
@ -1601,7 +1604,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
ElementState::Pressed, MouseButton::Right, WindowEvent::MouseInput, ElementState::Pressed, MouseButton::Right, WindowEvent::MouseInput,
}; };
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);
@ -1621,7 +1624,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
ElementState::Released, MouseButton::Right, WindowEvent::MouseInput, ElementState::Released, MouseButton::Right, WindowEvent::MouseInput,
}; };
release_mouse(userdata.window_state_lock()); unsafe { release_mouse(userdata.window_state_lock()) };
update_modifiers(window, userdata); update_modifiers(window, userdata);
@ -1641,7 +1644,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
ElementState::Pressed, MouseButton::Middle, WindowEvent::MouseInput, ElementState::Pressed, MouseButton::Middle, WindowEvent::MouseInput,
}; };
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);
@ -1661,7 +1664,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
ElementState::Released, MouseButton::Middle, WindowEvent::MouseInput, ElementState::Released, MouseButton::Middle, WindowEvent::MouseInput,
}; };
release_mouse(userdata.window_state_lock()); unsafe { release_mouse(userdata.window_state_lock()) };
update_modifiers(window, userdata); update_modifiers(window, userdata);
@ -1683,7 +1686,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
}; };
let xbutton = super::get_xbutton_wparam(wparam as u32); let xbutton = super::get_xbutton_wparam(wparam as u32);
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);
@ -1709,7 +1712,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
}; };
let xbutton = super::get_xbutton_wparam(wparam as u32); let xbutton = super::get_xbutton_wparam(wparam as u32);
release_mouse(userdata.window_state_lock()); unsafe { release_mouse(userdata.window_state_lock()) };
update_modifiers(window, userdata); update_modifiers(window, userdata);
@ -1743,21 +1746,22 @@ unsafe fn public_window_callback_inner<T: 'static>(
let pcount = super::loword(wparam as u32) as usize; let pcount = super::loword(wparam as u32) as usize;
let mut inputs = Vec::with_capacity(pcount); let mut inputs = Vec::with_capacity(pcount);
let htouch = lparam; let htouch = lparam;
if GetTouchInputInfo( if unsafe {
htouch, GetTouchInputInfo(
pcount as u32, htouch,
inputs.as_mut_ptr(), pcount as u32,
mem::size_of::<TOUCHINPUT>() as i32, inputs.as_mut_ptr(),
) > 0 mem::size_of::<TOUCHINPUT>() as i32,
{ ) > 0
inputs.set_len(pcount); } {
unsafe { inputs.set_len(pcount) };
for input in &inputs { for input in &inputs {
let mut location = POINT { let mut location = POINT {
x: input.x / 100, x: input.x / 100,
y: input.y / 100, y: input.y / 100,
}; };
if ScreenToClient(window, &mut location) == false.into() { if unsafe { ScreenToClient(window, &mut location) } == false.into() {
continue; continue;
} }
@ -1784,7 +1788,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
}); });
} }
} }
CloseTouchInputHandle(htouch); unsafe { CloseTouchInputHandle(htouch) };
result = ProcResult::Value(0); result = ProcResult::Value(0);
} }
@ -1801,12 +1805,14 @@ unsafe fn public_window_callback_inner<T: 'static>(
let pointer_id = super::loword(wparam as u32) as u32; let pointer_id = super::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 GetPointerFrameInfoHistory( if unsafe {
pointer_id, GetPointerFrameInfoHistory(
&mut entries_count, pointer_id,
&mut pointers_count, &mut entries_count,
ptr::null_mut(), &mut pointers_count,
) == false.into() ptr::null_mut(),
)
} == false.into()
{ {
result = ProcResult::Value(0); result = ProcResult::Value(0);
return; return;
@ -1814,17 +1820,19 @@ unsafe fn public_window_callback_inner<T: 'static>(
let pointer_info_count = (entries_count * pointers_count) as usize; let pointer_info_count = (entries_count * pointers_count) as usize;
let mut pointer_infos = Vec::with_capacity(pointer_info_count); let mut pointer_infos = Vec::with_capacity(pointer_info_count);
if GetPointerFrameInfoHistory( if unsafe {
pointer_id, GetPointerFrameInfoHistory(
&mut entries_count, pointer_id,
&mut pointers_count, &mut entries_count,
pointer_infos.as_mut_ptr(), &mut pointers_count,
) == false.into() pointer_infos.as_mut_ptr(),
)
} == false.into()
{ {
result = ProcResult::Value(0); result = ProcResult::Value(0);
return; return;
} }
pointer_infos.set_len(pointer_info_count); unsafe { pointer_infos.set_len(pointer_info_count) };
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getpointerframeinfohistory // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getpointerframeinfohistory
// The information retrieved appears in reverse chronological order, with the most recent entry in the first // The information retrieved appears in reverse chronological order, with the most recent entry in the first
@ -1833,17 +1841,19 @@ unsafe fn public_window_callback_inner<T: 'static>(
let mut device_rect = mem::MaybeUninit::uninit(); let mut device_rect = mem::MaybeUninit::uninit();
let mut display_rect = mem::MaybeUninit::uninit(); let mut display_rect = mem::MaybeUninit::uninit();
if GetPointerDeviceRects( if unsafe {
pointer_info.sourceDevice, GetPointerDeviceRects(
device_rect.as_mut_ptr(), pointer_info.sourceDevice,
display_rect.as_mut_ptr(), device_rect.as_mut_ptr(),
) == false.into() display_rect.as_mut_ptr(),
)
} == false.into()
{ {
continue; continue;
} }
let device_rect = device_rect.assume_init(); let device_rect = unsafe { device_rect.assume_init() };
let display_rect = display_rect.assume_init(); let display_rect = unsafe { display_rect.assume_init() };
// For the most precise himetric to pixel conversion we calculate the ratio between the resolution // For the most precise himetric to pixel conversion we calculate the ratio between the resolution
// of the display device (pixel) and the touch device (himetric). // of the display device (pixel) and the touch device (himetric).
@ -1865,7 +1875,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
y: y.floor() as i32, y: y.floor() as i32,
}; };
if ScreenToClient(window, &mut location) == false.into() { if unsafe { ScreenToClient(window, &mut location) } == false.into() {
continue; continue;
} }
@ -1873,28 +1883,29 @@ unsafe fn public_window_callback_inner<T: 'static>(
PT_TOUCH => { PT_TOUCH => {
let mut touch_info = mem::MaybeUninit::uninit(); let mut touch_info = mem::MaybeUninit::uninit();
GET_POINTER_TOUCH_INFO.and_then(|GetPointerTouchInfo| { GET_POINTER_TOUCH_INFO.and_then(|GetPointerTouchInfo| {
match GetPointerTouchInfo( match unsafe {
pointer_info.pointerId, GetPointerTouchInfo(
touch_info.as_mut_ptr(), pointer_info.pointerId,
) { touch_info.as_mut_ptr(),
)
} {
0 => None, 0 => None,
_ => normalize_pointer_pressure( _ => normalize_pointer_pressure(unsafe {
touch_info.assume_init().pressure, touch_info.assume_init().pressure
), }),
} }
}) })
} }
PT_PEN => { PT_PEN => {
let mut pen_info = mem::MaybeUninit::uninit(); let mut pen_info = mem::MaybeUninit::uninit();
GET_POINTER_PEN_INFO.and_then(|GetPointerPenInfo| { GET_POINTER_PEN_INFO.and_then(|GetPointerPenInfo| {
match GetPointerPenInfo( match unsafe {
pointer_info.pointerId, GetPointerPenInfo(pointer_info.pointerId, pen_info.as_mut_ptr())
pen_info.as_mut_ptr(), } {
) {
0 => None, 0 => None,
_ => { _ => normalize_pointer_pressure(unsafe {
normalize_pointer_pressure(pen_info.assume_init().pressure) pen_info.assume_init().pressure
} }),
} }
}) })
} }
@ -1925,7 +1936,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
}); });
} }
SkipPointerFrameMessages(pointer_id); unsafe { SkipPointerFrameMessages(pointer_id) };
} }
result = ProcResult::Value(0); result = ProcResult::Value(0);
} }
@ -1935,9 +1946,9 @@ unsafe fn public_window_callback_inner<T: 'static>(
let active_focus_changed = userdata.window_state_lock().set_active(is_active); let active_focus_changed = userdata.window_state_lock().set_active(is_active);
if active_focus_changed { if active_focus_changed {
if is_active { if is_active {
gain_active_focus(window, userdata); unsafe { gain_active_focus(window, userdata) };
} else { } else {
lose_active_focus(window, userdata); unsafe { lose_active_focus(window, userdata) };
} }
} }
result = ProcResult::DefWindowProc(wparam); result = ProcResult::DefWindowProc(wparam);
@ -1946,7 +1957,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
WM_SETFOCUS => { WM_SETFOCUS => {
let active_focus_changed = userdata.window_state_lock().set_focused(true); let active_focus_changed = userdata.window_state_lock().set_focused(true);
if active_focus_changed { if active_focus_changed {
gain_active_focus(window, userdata); unsafe { gain_active_focus(window, userdata) };
} }
result = ProcResult::Value(0); result = ProcResult::Value(0);
} }
@ -1954,7 +1965,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
WM_KILLFOCUS => { WM_KILLFOCUS => {
let active_focus_changed = userdata.window_state_lock().set_focused(false); let active_focus_changed = userdata.window_state_lock().set_focused(false);
if active_focus_changed { if active_focus_changed {
lose_active_focus(window, userdata); unsafe { lose_active_focus(window, userdata) };
} }
result = ProcResult::Value(0); result = ProcResult::Value(0);
} }
@ -1975,8 +1986,8 @@ unsafe fn public_window_callback_inner<T: 'static>(
match set_cursor_to { match set_cursor_to {
Some(cursor) => { Some(cursor) => {
let cursor = LoadCursorW(0, util::to_windows_cursor(cursor)); let cursor = unsafe { LoadCursorW(0, util::to_windows_cursor(cursor)) };
SetCursor(cursor); unsafe { SetCursor(cursor) };
result = ProcResult::Value(0); result = ProcResult::Value(0);
} }
None => result = ProcResult::DefWindowProc(wparam), None => result = ProcResult::DefWindowProc(wparam),
@ -1994,18 +2005,22 @@ unsafe fn public_window_callback_inner<T: 'static>(
let min_size = min_size.to_physical(window_state.scale_factor); let min_size = min_size.to_physical(window_state.scale_factor);
let (width, height): (u32, u32) = let (width, height): (u32, u32) =
window_flags.adjust_size(window, min_size).into(); window_flags.adjust_size(window, min_size).into();
(*mmi).ptMinTrackSize = POINT { unsafe {
x: width as i32, (*mmi).ptMinTrackSize = POINT {
y: height as i32, x: width as i32,
y: height as i32,
}
}; };
} }
if let Some(max_size) = window_state.max_size { if let Some(max_size) = window_state.max_size {
let max_size = max_size.to_physical(window_state.scale_factor); let max_size = max_size.to_physical(window_state.scale_factor);
let (width, height): (u32, u32) = let (width, height): (u32, u32) =
window_flags.adjust_size(window, max_size).into(); window_flags.adjust_size(window, max_size).into();
(*mmi).ptMaxTrackSize = POINT { unsafe {
x: width as i32, (*mmi).ptMaxTrackSize = POINT {
y: height as i32, x: width as i32,
y: height as i32,
}
}; };
} }
} }
@ -2043,7 +2058,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
}; };
// New size as suggested by Windows. // New size as suggested by Windows.
let suggested_rect = *(lparam as *const RECT); let suggested_rect = unsafe { *(lparam as *const RECT) };
// The window rect provided is the window's outer size, not it's inner size. However, // The window rect provided is the window's outer size, not it's inner size. However,
// win32 doesn't provide an `UnadjustWindowRectEx` function to get the client rect from // win32 doesn't provide an `UnadjustWindowRectEx` function to get the client rect from
@ -2132,8 +2147,8 @@ unsafe fn public_window_callback_inner<T: 'static>(
if dragging_window { if dragging_window {
let bias = { let bias = {
let cursor_pos = { let cursor_pos = {
let mut pos = mem::zeroed(); let mut pos = unsafe { mem::zeroed() };
GetCursorPos(&mut pos); unsafe { GetCursorPos(&mut pos) };
pos pos
}; };
let suggested_cursor_horizontal_ratio = (cursor_pos.x - suggested_rect.left) let suggested_cursor_horizontal_ratio = (cursor_pos.x - suggested_rect.left)
@ -2152,18 +2167,18 @@ unsafe fn public_window_callback_inner<T: 'static>(
// Check to see if the new window rect is on the monitor with the new DPI factor. // Check to see if the new window rect is on the monitor with the new DPI factor.
// If it isn't, offset the window so that it is. // If it isn't, offset the window so that it is.
let new_dpi_monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONULL); let new_dpi_monitor = unsafe { MonitorFromWindow(window, MONITOR_DEFAULTTONULL) };
let conservative_rect_monitor = let conservative_rect_monitor =
MonitorFromRect(&conservative_rect, MONITOR_DEFAULTTONULL); unsafe { MonitorFromRect(&conservative_rect, MONITOR_DEFAULTTONULL) };
new_outer_rect = if conservative_rect_monitor == new_dpi_monitor { new_outer_rect = if conservative_rect_monitor == new_dpi_monitor {
conservative_rect conservative_rect
} else { } else {
let get_monitor_rect = |monitor| { let get_monitor_rect = |monitor| {
let mut monitor_info = MONITORINFO { let mut monitor_info = MONITORINFO {
cbSize: mem::size_of::<MONITORINFO>() as _, cbSize: mem::size_of::<MONITORINFO>() as _,
..mem::zeroed() ..unsafe { mem::zeroed() }
}; };
GetMonitorInfoW(monitor, &mut monitor_info); unsafe { GetMonitorInfoW(monitor, &mut monitor_info) };
monitor_info.rcMonitor monitor_info.rcMonitor
}; };
let wrong_monitor = conservative_rect_monitor; let wrong_monitor = conservative_rect_monitor;
@ -2200,7 +2215,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
conservative_rect.top += delta_nudge_to_dpi_monitor.1; conservative_rect.top += delta_nudge_to_dpi_monitor.1;
conservative_rect.bottom += delta_nudge_to_dpi_monitor.1; conservative_rect.bottom += delta_nudge_to_dpi_monitor.1;
if MonitorFromRect(&conservative_rect, MONITOR_DEFAULTTONULL) if unsafe { MonitorFromRect(&conservative_rect, MONITOR_DEFAULTTONULL) }
== new_dpi_monitor == new_dpi_monitor
{ {
break; break;
@ -2211,15 +2226,17 @@ unsafe fn public_window_callback_inner<T: 'static>(
}; };
} }
SetWindowPos( unsafe {
window, SetWindowPos(
0, window,
new_outer_rect.left, 0,
new_outer_rect.top, new_outer_rect.left,
new_outer_rect.right - new_outer_rect.left, new_outer_rect.top,
new_outer_rect.bottom - new_outer_rect.top, new_outer_rect.right - new_outer_rect.left,
SWP_NOZORDER | SWP_NOACTIVATE, new_outer_rect.bottom - new_outer_rect.top,
); SWP_NOZORDER | SWP_NOACTIVATE,
)
};
result = ProcResult::Value(0); result = ProcResult::Value(0);
} }
@ -2247,7 +2264,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
_ => { _ => {
if msg == DESTROY_MSG_ID.get() { if msg == DESTROY_MSG_ID.get() {
DestroyWindow(window); unsafe { DestroyWindow(window) };
result = ProcResult::Value(0); result = ProcResult::Value(0);
} else if msg == SET_RETAIN_STATE_ON_SIZE_MSG_ID.get() { } else if msg == SET_RETAIN_STATE_ON_SIZE_MSG_ID.get() {
let mut window_state = userdata.window_state_lock(); let mut window_state = userdata.window_state_lock();
@ -2257,7 +2274,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
result = ProcResult::Value(0); result = ProcResult::Value(0);
} else if msg == TASKBAR_CREATED.get() { } else if msg == TASKBAR_CREATED.get() {
let window_state = userdata.window_state_lock(); let window_state = userdata.window_state_lock();
set_skip_taskbar(window, window_state.skip_taskbar); unsafe { set_skip_taskbar(window, window_state.skip_taskbar) };
result = ProcResult::DefWindowProc(wparam); result = ProcResult::DefWindowProc(wparam);
} else { } else {
result = ProcResult::DefWindowProc(wparam); result = ProcResult::DefWindowProc(wparam);
@ -2271,7 +2288,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
.unwrap_or_else(|| result = ProcResult::Value(-1)); .unwrap_or_else(|| result = ProcResult::Value(-1));
match result { match result {
ProcResult::DefWindowProc(wparam) => DefWindowProcW(window, msg, wparam, lparam), ProcResult::DefWindowProc(wparam) => unsafe { DefWindowProcW(window, msg, wparam, lparam) },
ProcResult::Value(val) => val, ProcResult::Value(val) => val,
} }
} }
@ -2282,16 +2299,17 @@ unsafe extern "system" fn thread_event_target_callback<T: 'static>(
wparam: WPARAM, wparam: WPARAM,
lparam: LPARAM, lparam: LPARAM,
) -> LRESULT { ) -> LRESULT {
let userdata_ptr = super::get_window_long(window, GWL_USERDATA) as *mut ThreadMsgTargetData<T>; let userdata_ptr =
unsafe { super::get_window_long(window, GWL_USERDATA) } as *mut ThreadMsgTargetData<T>;
if userdata_ptr.is_null() { if userdata_ptr.is_null() {
// `userdata_ptr` will always be null for the first `WM_GETMINMAXINFO`, as well as `WM_NCCREATE` and // `userdata_ptr` will always be null for the first `WM_GETMINMAXINFO`, as well as `WM_NCCREATE` and
// `WM_CREATE`. // `WM_CREATE`.
return DefWindowProcW(window, msg, wparam, lparam); return unsafe { DefWindowProcW(window, msg, wparam, lparam) };
} }
let userdata = Box::from_raw(userdata_ptr); let userdata = unsafe { Box::from_raw(userdata_ptr) };
if msg != WM_PAINT { if msg != WM_PAINT {
RedrawWindow(window, ptr::null(), 0, RDW_INTERNALPAINT); unsafe { RedrawWindow(window, ptr::null(), 0, RDW_INTERNALPAINT) };
} }
let mut userdata_removed = false; let mut userdata_removed = false;
@ -2301,15 +2319,15 @@ unsafe extern "system" fn thread_event_target_callback<T: 'static>(
// 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 => {
super::set_window_long(window, GWL_USERDATA, 0); unsafe { super::set_window_long(window, GWL_USERDATA, 0) };
userdata_removed = true; userdata_removed = true;
0 0
} }
WM_PAINT => { WM_PAINT => unsafe {
ValidateRect(window, ptr::null()); ValidateRect(window, ptr::null());
// Default WM_PAINT behaviour. This makes sure modals and popups are shown immediatly when opening them. // Default WM_PAINT behaviour. This makes sure modals and popups are shown immediatly when opening them.
DefWindowProcW(window, msg, wparam, lparam) DefWindowProcW(window, msg, wparam, lparam)
} },
WM_INPUT_DEVICE_CHANGE => { WM_INPUT_DEVICE_CHANGE => {
let event = match wparam as u32 { let event = match wparam as u32 {
@ -2328,10 +2346,10 @@ unsafe extern "system" fn thread_event_target_callback<T: 'static>(
WM_INPUT => { WM_INPUT => {
if let Some(data) = raw_input::get_raw_input_data(lparam as _) { if let Some(data) = raw_input::get_raw_input_data(lparam as _) {
handle_raw_input(&userdata, data); unsafe { handle_raw_input(&userdata, data) };
} }
DefWindowProcW(window, msg, wparam, lparam) unsafe { DefWindowProcW(window, msg, wparam, lparam) }
} }
_ if msg == USER_EVENT_MSG_ID.get() => { _ if msg == USER_EVENT_MSG_ID.get() => {
@ -2341,11 +2359,11 @@ unsafe extern "system" fn thread_event_target_callback<T: 'static>(
0 0
} }
_ if msg == EXEC_MSG_ID.get() => { _ if msg == EXEC_MSG_ID.get() => {
let mut function: ThreadExecFn = Box::from_raw(wparam as *mut _); let mut function: ThreadExecFn = unsafe { Box::from_raw(wparam as *mut _) };
function(); function();
0 0
} }
_ => DefWindowProcW(window, msg, wparam, lparam), _ => unsafe { DefWindowProcW(window, msg, wparam, lparam) },
}; };
let result = userdata let result = userdata
@ -2370,7 +2388,7 @@ unsafe fn handle_raw_input<T: 'static>(userdata: &ThreadMsgTargetData<T>, data:
let device_id = wrap_device_id(data.header.hDevice as _); let device_id = wrap_device_id(data.header.hDevice as _);
if data.header.dwType == RIM_TYPEMOUSE { if data.header.dwType == RIM_TYPEMOUSE {
let mouse = data.data.mouse; let mouse = unsafe { data.data.mouse };
if util::has_flag(mouse.usFlags as u32, MOUSE_MOVE_RELATIVE) { if util::has_flag(mouse.usFlags as u32, MOUSE_MOVE_RELATIVE) {
let x = mouse.lLastX as f64; let x = mouse.lLastX as f64;
@ -2398,10 +2416,10 @@ unsafe fn handle_raw_input<T: 'static>(userdata: &ThreadMsgTargetData<T>, data:
} }
} }
let button_flags = mouse.Anonymous.Anonymous.usButtonFlags; let button_flags = unsafe { mouse.Anonymous.Anonymous.usButtonFlags };
if util::has_flag(button_flags as u32, RI_MOUSE_WHEEL) { if util::has_flag(button_flags as u32, RI_MOUSE_WHEEL) {
let button_data = mouse.Anonymous.Anonymous.usButtonData; let button_data = unsafe { mouse.Anonymous.Anonymous.usButtonData };
// We must cast to i16 first, becaues `usButtonData` must be interpreted as signed. // We must cast to i16 first, becaues `usButtonData` must be interpreted as signed.
let delta = button_data as i16 as f32 / WHEEL_DELTA as f32; let delta = button_data as i16 as f32 / WHEEL_DELTA as f32;
userdata.send_event(Event::DeviceEvent { userdata.send_event(Event::DeviceEvent {
@ -2427,7 +2445,7 @@ unsafe fn handle_raw_input<T: 'static>(userdata: &ThreadMsgTargetData<T>, data:
} }
} }
} else if data.header.dwType == RIM_TYPEKEYBOARD { } else if data.header.dwType == RIM_TYPEKEYBOARD {
let keyboard = data.data.keyboard; let keyboard = unsafe { data.data.keyboard };
let pressed = keyboard.Message == WM_KEYDOWN || keyboard.Message == WM_SYSKEYDOWN; let pressed = keyboard.Message == WM_KEYDOWN || keyboard.Message == WM_SYSKEYDOWN;
let released = keyboard.Message == WM_KEYUP || keyboard.Message == WM_SYSKEYUP; let released = keyboard.Message == WM_KEYUP || keyboard.Message == WM_SYSKEYUP;
@ -2449,7 +2467,7 @@ unsafe fn handle_raw_input<T: 'static>(userdata: &ThreadMsgTargetData<T>, data:
let scancode = if keyboard.MakeCode == 0 { let scancode = if keyboard.MakeCode == 0 {
// In some cases (often with media keys) the device reports a scancode of 0 but a // In some cases (often with media keys) the device reports a scancode of 0 but a
// valid virtual key. In these cases we obtain the scancode from the virtual key. // valid virtual key. In these cases we obtain the scancode from the virtual key.
MapVirtualKeyW(keyboard.VKey as u32, MAPVK_VK_TO_VSC_EX) as u16 unsafe { MapVirtualKeyW(keyboard.VKey as u32, MAPVK_VK_TO_VSC_EX) as u16 }
} else { } else {
keyboard.MakeCode | extension keyboard.MakeCode | extension
}; };

View file

@ -96,10 +96,12 @@ impl<T> EventLoopRunner<T> {
where where
F: FnMut(Event<T>), F: FnMut(Event<T>),
{ {
let old_event_handler = self.event_handler.replace(mem::transmute::< // Erase closure lifetime.
Option<Box<dyn FnMut(Event<T>)>>, // SAFETY: Caller upholds that the lifetime of the closure is upheld.
Option<Box<dyn FnMut(Event<T>)>>, let f = unsafe {
>(Some(Box::new(f)))); mem::transmute::<Box<dyn FnMut(Event<T>)>, Box<dyn FnMut(Event<T>)>>(Box::new(f))
};
let old_event_handler = self.event_handler.replace(Some(f));
assert!(old_event_handler.is_none()); assert!(old_event_handler.is_none());
} }

View file

@ -30,15 +30,15 @@ pub struct ImeContext {
impl ImeContext { impl ImeContext {
pub unsafe fn current(hwnd: HWND) -> Self { pub unsafe fn current(hwnd: HWND) -> Self {
let himc = ImmGetContext(hwnd); let himc = unsafe { ImmGetContext(hwnd) };
ImeContext { hwnd, himc } ImeContext { hwnd, himc }
} }
pub unsafe fn get_composing_text_and_cursor( pub unsafe fn get_composing_text_and_cursor(
&self, &self,
) -> Option<(String, Option<usize>, Option<usize>)> { ) -> Option<(String, Option<usize>, Option<usize>)> {
let text = self.get_composition_string(GCS_COMPSTR)?; let text = unsafe { self.get_composition_string(GCS_COMPSTR) }?;
let attrs = self.get_composition_data(GCS_COMPATTR).unwrap_or_default(); let attrs = unsafe { self.get_composition_data(GCS_COMPATTR) }.unwrap_or_default();
let mut first = None; let mut first = None;
let mut last = None; let mut last = None;
@ -61,7 +61,7 @@ impl ImeContext {
last = Some(text.len()); last = Some(text.len());
} else if first.is_none() { } else if first.is_none() {
// IME haven't split words and select any clause yet, so trying to retrieve normal cursor. // IME haven't split words and select any clause yet, so trying to retrieve normal cursor.
let cursor = self.get_composition_cursor(&text); let cursor = unsafe { self.get_composition_cursor(&text) };
first = cursor; first = cursor;
last = cursor; last = cursor;
} }
@ -70,17 +70,17 @@ impl ImeContext {
} }
pub unsafe fn get_composed_text(&self) -> Option<String> { pub unsafe fn get_composed_text(&self) -> Option<String> {
self.get_composition_string(GCS_RESULTSTR) unsafe { self.get_composition_string(GCS_RESULTSTR) }
} }
unsafe fn get_composition_cursor(&self, text: &str) -> Option<usize> { unsafe fn get_composition_cursor(&self, text: &str) -> Option<usize> {
let cursor = ImmGetCompositionStringW(self.himc, GCS_CURSORPOS, null_mut(), 0); let cursor = unsafe { ImmGetCompositionStringW(self.himc, GCS_CURSORPOS, null_mut(), 0) };
(cursor >= 0).then(|| text.chars().take(cursor as _).map(|c| c.len_utf8()).sum()) (cursor >= 0).then(|| text.chars().take(cursor as _).map(|c| c.len_utf8()).sum())
} }
unsafe fn get_composition_string(&self, gcs_mode: u32) -> Option<String> { unsafe fn get_composition_string(&self, gcs_mode: u32) -> Option<String> {
let data = self.get_composition_data(gcs_mode)?; let data = unsafe { self.get_composition_data(gcs_mode) }?;
let (prefix, shorts, suffix) = data.align_to::<u16>(); let (prefix, shorts, suffix) = unsafe { data.align_to::<u16>() };
if prefix.is_empty() && suffix.is_empty() { if prefix.is_empty() && suffix.is_empty() {
OsString::from_wide(shorts).into_string().ok() OsString::from_wide(shorts).into_string().ok()
} else { } else {
@ -89,30 +89,32 @@ impl ImeContext {
} }
unsafe fn get_composition_data(&self, gcs_mode: u32) -> Option<Vec<u8>> { unsafe fn get_composition_data(&self, gcs_mode: u32) -> Option<Vec<u8>> {
let size = match ImmGetCompositionStringW(self.himc, gcs_mode, null_mut(), 0) { let size = match unsafe { ImmGetCompositionStringW(self.himc, gcs_mode, null_mut(), 0) } {
0 => return Some(Vec::new()), 0 => return Some(Vec::new()),
size if size < 0 => return None, size if size < 0 => return None,
size => size, size => size,
}; };
let mut buf = Vec::<u8>::with_capacity(size as _); let mut buf = Vec::<u8>::with_capacity(size as _);
let size = ImmGetCompositionStringW( let size = unsafe {
self.himc, ImmGetCompositionStringW(
gcs_mode, self.himc,
buf.as_mut_ptr() as *mut c_void, gcs_mode,
size as _, buf.as_mut_ptr() as *mut c_void,
); size as _,
)
};
if size < 0 { if size < 0 {
None None
} else { } else {
buf.set_len(size as _); unsafe { buf.set_len(size as _) };
Some(buf) Some(buf)
} }
} }
pub unsafe fn set_ime_cursor_area(&self, spot: Position, size: Size, scale_factor: f64) { pub unsafe fn set_ime_cursor_area(&self, spot: Position, size: Size, scale_factor: f64) {
if !ImeContext::system_has_ime() { if !unsafe { ImeContext::system_has_ime() } {
return; return;
} }
@ -131,23 +133,23 @@ impl ImeContext {
rcArea: rc_area, rcArea: rc_area,
}; };
ImmSetCandidateWindow(self.himc, &candidate_form); unsafe { ImmSetCandidateWindow(self.himc, &candidate_form) };
} }
pub unsafe fn set_ime_allowed(hwnd: HWND, allowed: bool) { pub unsafe fn set_ime_allowed(hwnd: HWND, allowed: bool) {
if !ImeContext::system_has_ime() { if !unsafe { ImeContext::system_has_ime() } {
return; return;
} }
if allowed { if allowed {
ImmAssociateContextEx(hwnd, 0, IACE_DEFAULT); unsafe { ImmAssociateContextEx(hwnd, 0, IACE_DEFAULT) };
} else { } else {
ImmAssociateContextEx(hwnd, 0, IACE_CHILDREN); unsafe { ImmAssociateContextEx(hwnd, 0, IACE_CHILDREN) };
} }
} }
unsafe fn system_has_ime() -> bool { unsafe fn system_has_ime() -> bool {
GetSystemMetrics(SM_IMMENABLED) != 0 unsafe { GetSystemMetrics(SM_IMMENABLED) != 0 }
} }
} }

View file

@ -1,4 +1,5 @@
#![cfg(windows_platform)] #![cfg(windows_platform)]
#![deny(unsafe_op_in_unsafe_fn)]
use smol_str::SmolStr; use smol_str::SmolStr;
use windows_sys::Win32::{ use windows_sys::Win32::{
@ -154,21 +155,24 @@ const fn hiword(x: u32) -> u16 {
#[inline(always)] #[inline(always)]
unsafe fn get_window_long(hwnd: HWND, nindex: WINDOW_LONG_PTR_INDEX) -> isize { unsafe fn get_window_long(hwnd: HWND, nindex: WINDOW_LONG_PTR_INDEX) -> isize {
#[cfg(target_pointer_width = "64")] #[cfg(target_pointer_width = "64")]
return windows_sys::Win32::UI::WindowsAndMessaging::GetWindowLongPtrW(hwnd, nindex); return unsafe { windows_sys::Win32::UI::WindowsAndMessaging::GetWindowLongPtrW(hwnd, nindex) };
#[cfg(target_pointer_width = "32")] #[cfg(target_pointer_width = "32")]
return windows_sys::Win32::UI::WindowsAndMessaging::GetWindowLongW(hwnd, nindex) as isize; return unsafe {
windows_sys::Win32::UI::WindowsAndMessaging::GetWindowLongW(hwnd, nindex) as isize
};
} }
#[inline(always)] #[inline(always)]
unsafe fn set_window_long(hwnd: HWND, nindex: WINDOW_LONG_PTR_INDEX, dwnewlong: isize) -> isize { unsafe fn set_window_long(hwnd: HWND, nindex: WINDOW_LONG_PTR_INDEX, dwnewlong: isize) -> isize {
#[cfg(target_pointer_width = "64")] #[cfg(target_pointer_width = "64")]
return windows_sys::Win32::UI::WindowsAndMessaging::SetWindowLongPtrW(hwnd, nindex, dwnewlong); return unsafe {
windows_sys::Win32::UI::WindowsAndMessaging::SetWindowLongPtrW(hwnd, nindex, dwnewlong)
};
#[cfg(target_pointer_width = "32")] #[cfg(target_pointer_width = "32")]
return windows_sys::Win32::UI::WindowsAndMessaging::SetWindowLongW( return unsafe {
hwnd, windows_sys::Win32::UI::WindowsAndMessaging::SetWindowLongW(hwnd, nindex, dwnewlong as i32)
nindex, as isize
dwnewlong as i32, };
) as isize;
} }
#[macro_use] #[macro_use]

View file

@ -101,7 +101,7 @@ unsafe extern "system" fn monitor_enum_proc(
data: LPARAM, data: LPARAM,
) -> BOOL { ) -> BOOL {
let monitors = data as *mut VecDeque<MonitorHandle>; let monitors = data as *mut VecDeque<MonitorHandle>;
(*monitors).push_back(MonitorHandle::new(hmonitor)); unsafe { (*monitors).push_back(MonitorHandle::new(hmonitor)) };
true.into() // continue enumeration true.into() // continue enumeration
} }

View file

@ -424,24 +424,26 @@ impl Window {
unsafe fn handle_os_dragging(&self, wparam: WPARAM) { unsafe fn handle_os_dragging(&self, wparam: WPARAM) {
let points = { let points = {
let mut pos = mem::zeroed(); let mut pos = unsafe { mem::zeroed() };
GetCursorPos(&mut pos); unsafe { GetCursorPos(&mut pos) };
pos pos
}; };
let points = POINTS { let points = POINTS {
x: points.x as i16, x: points.x as i16,
y: points.y as i16, y: points.y as i16,
}; };
ReleaseCapture(); unsafe { ReleaseCapture() };
self.window_state_lock().dragging = true; self.window_state_lock().dragging = true;
PostMessageW( unsafe {
self.hwnd(), PostMessageW(
WM_NCLBUTTONDOWN, self.hwnd(),
wparam, WM_NCLBUTTONDOWN,
&points as *const _ as LPARAM, wparam,
); &points as *const _ as LPARAM,
)
};
} }
#[inline] #[inline]
@ -925,13 +927,13 @@ impl<'a, T: 'static> InitData<'a, T> {
unsafe fn create_window(&self, window: HWND) -> Window { unsafe fn create_window(&self, window: HWND) -> Window {
// Register for touch events if applicable // Register for touch events if applicable
{ {
let digitizer = GetSystemMetrics(SM_DIGITIZER) as u32; let digitizer = unsafe { GetSystemMetrics(SM_DIGITIZER) as u32 };
if digitizer & NID_READY != 0 { if digitizer & NID_READY != 0 {
RegisterTouchWindow(window, TWF_WANTPALM); unsafe { RegisterTouchWindow(window, TWF_WANTPALM) };
} }
} }
let dpi = hwnd_dpi(window); let dpi = unsafe { hwnd_dpi(window) };
let scale_factor = dpi_to_scale_factor(dpi); let scale_factor = dpi_to_scale_factor(dpi);
// If the system theme is dark, we need to set the window theme now // If the system theme is dark, we need to set the window theme now
@ -955,7 +957,7 @@ impl<'a, T: 'static> InitData<'a, T> {
enable_non_client_dpi_scaling(window); enable_non_client_dpi_scaling(window);
ImeContext::set_ime_allowed(window, false); unsafe { ImeContext::set_ime_allowed(window, false) };
Window { Window {
window: WindowWrapper(window), window: WindowWrapper(window),
@ -966,7 +968,7 @@ impl<'a, T: 'static> InitData<'a, T> {
unsafe fn create_window_data(&self, win: &Window) -> event_loop::WindowData<T> { unsafe fn create_window_data(&self, win: &Window) -> event_loop::WindowData<T> {
let file_drop_handler = if self.pl_attribs.drag_and_drop { let file_drop_handler = if self.pl_attribs.drag_and_drop {
let ole_init_result = OleInitialize(ptr::null_mut()); let ole_init_result = unsafe { OleInitialize(ptr::null_mut()) };
// It is ok if the initialize result is `S_FALSE` because it might happen that // It is ok if the initialize result is `S_FALSE` because it might happen that
// multiple windows are created on the same thread. // multiple windows are created on the same thread.
if ole_init_result == OLE_E_WRONGCOMPOBJ { if ole_init_result == OLE_E_WRONGCOMPOBJ {
@ -990,9 +992,12 @@ impl<'a, T: 'static> InitData<'a, T> {
); );
let handler_interface_ptr = let handler_interface_ptr =
&mut (*file_drop_handler.data).interface as *mut _ as *mut c_void; unsafe { &mut (*file_drop_handler.data).interface as *mut _ as *mut c_void };
assert_eq!(RegisterDragDrop(win.window.0, handler_interface_ptr), S_OK); assert_eq!(
unsafe { RegisterDragDrop(win.window.0, handler_interface_ptr) },
S_OK
);
Some(file_drop_handler) Some(file_drop_handler)
} else { } else {
None None
@ -1013,8 +1018,8 @@ impl<'a, T: 'static> InitData<'a, T> {
pub unsafe fn on_nccreate(&mut self, window: HWND) -> Option<isize> { pub unsafe fn on_nccreate(&mut self, window: HWND) -> Option<isize> {
let runner = self.event_loop.runner_shared.clone(); let runner = self.event_loop.runner_shared.clone();
let result = runner.catch_unwind(|| { let result = runner.catch_unwind(|| {
let window = self.create_window(window); let window = unsafe { self.create_window(window) };
let window_data = self.create_window_data(&window); let window_data = unsafe { self.create_window_data(&window) };
(window, window_data) (window, window_data)
}); });
@ -1031,7 +1036,7 @@ impl<'a, T: 'static> InitData<'a, T> {
// making the window transparent // making the window transparent
if self.attributes.transparent && !self.pl_attribs.no_redirection_bitmap { if self.attributes.transparent && !self.pl_attribs.no_redirection_bitmap {
// Empty region for the blur effect, so the window is fully transparent // Empty region for the blur effect, so the window is fully transparent
let region = CreateRectRgn(0, 0, -1, -1); let region = unsafe { CreateRectRgn(0, 0, -1, -1) };
let bb = DWM_BLURBEHIND { let bb = DWM_BLURBEHIND {
dwFlags: DWM_BB_ENABLE | DWM_BB_BLURREGION, dwFlags: DWM_BB_ENABLE | DWM_BB_BLURREGION,
@ -1039,14 +1044,14 @@ impl<'a, T: 'static> InitData<'a, T> {
hRgnBlur: region, hRgnBlur: region,
fTransitionOnMaximized: false.into(), fTransitionOnMaximized: false.into(),
}; };
let hr = DwmEnableBlurBehindWindow(win.hwnd(), &bb); let hr = unsafe { DwmEnableBlurBehindWindow(win.hwnd(), &bb) };
if hr < 0 { if hr < 0 {
warn!( warn!(
"Setting transparent window is failed. HRESULT Code: 0x{:X}", "Setting transparent window is failed. HRESULT Code: 0x{:X}",
hr hr
); );
} }
DeleteObject(region); unsafe { DeleteObject(region) };
} }
win.set_skip_taskbar(self.pl_attribs.skip_taskbar); win.set_skip_taskbar(self.pl_attribs.skip_taskbar);
@ -1067,7 +1072,7 @@ impl<'a, T: 'static> InitData<'a, T> {
if attributes.fullscreen.is_some() { if attributes.fullscreen.is_some() {
win.set_fullscreen(attributes.fullscreen.map(Into::into)); win.set_fullscreen(attributes.fullscreen.map(Into::into));
force_window_active(win.window.0); unsafe { force_window_active(win.window.0) };
} else { } else {
let size = attributes let size = attributes
.inner_size .inner_size
@ -1112,7 +1117,7 @@ where
let title = util::encode_wide(&attributes.title); let title = util::encode_wide(&attributes.title);
let class_name = util::encode_wide(&pl_attribs.class_name); let class_name = util::encode_wide(&pl_attribs.class_name);
register_window_class::<T>(&class_name); unsafe { register_window_class::<T>(&class_name) };
let mut window_flags = WindowFlags::empty(); let mut window_flags = WindowFlags::empty();
window_flags.set(WindowFlags::MARKER_DECORATIONS, attributes.decorations); window_flags.set(WindowFlags::MARKER_DECORATIONS, attributes.decorations);
@ -1170,20 +1175,22 @@ where
}; };
let (style, ex_style) = window_flags.to_window_styles(); let (style, ex_style) = window_flags.to_window_styles();
let handle = CreateWindowExW( let handle = unsafe {
ex_style, CreateWindowExW(
class_name.as_ptr(), ex_style,
title.as_ptr(), class_name.as_ptr(),
style, title.as_ptr(),
CW_USEDEFAULT, style,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
parent.unwrap_or(0), CW_USEDEFAULT,
pl_attribs.menu.unwrap_or(0), parent.unwrap_or(0),
util::get_instance_handle(), pl_attribs.menu.unwrap_or(0),
&mut initdata as *mut _ as *mut _, util::get_instance_handle(),
); &mut initdata as *mut _ as *mut _,
)
};
// If the window creation in `InitData` panicked, then should resume panicking here // If the window creation in `InitData` panicked, then should resume panicking here
if let Err(panic_error) = event_loop.runner_shared.take_panic_error() { if let Err(panic_error) = event_loop.runner_shared.take_panic_error() {
@ -1219,7 +1226,7 @@ unsafe fn register_window_class<T: 'static>(class_name: &[u16]) {
// an error, and because errors here are detected during CreateWindowEx anyway. // an error, and because errors here are detected during CreateWindowEx anyway.
// Also since there is no weird element in the struct, there is no reason for this // Also since there is no weird element in the struct, there is no reason for this
// call to fail. // call to fail.
RegisterClassExW(&class); unsafe { RegisterClassExW(&class) };
} }
struct ComInitialized(*mut ()); struct ComInitialized(*mut ());
@ -1260,20 +1267,22 @@ unsafe fn taskbar_mark_fullscreen(handle: HWND, fullscreen: bool) {
let mut task_bar_list2 = task_bar_list2_ptr.get(); let mut task_bar_list2 = task_bar_list2_ptr.get();
if task_bar_list2.is_null() { if task_bar_list2.is_null() {
let hr = CoCreateInstance( let hr = unsafe {
&CLSID_TaskbarList, CoCreateInstance(
ptr::null_mut(), &CLSID_TaskbarList,
CLSCTX_ALL, ptr::null_mut(),
&IID_ITaskbarList2, CLSCTX_ALL,
&mut task_bar_list2 as *mut _ as *mut _, &IID_ITaskbarList2,
); &mut task_bar_list2 as *mut _ as *mut _,
)
};
if hr != S_OK { if hr != S_OK {
// In visual studio retrieving the taskbar list fails // In visual studio retrieving the taskbar list fails
return; return;
} }
let hr_init = (*(*task_bar_list2).lpVtbl).parent.HrInit; let hr_init = unsafe { (*(*task_bar_list2).lpVtbl).parent.HrInit };
if hr_init(task_bar_list2.cast()) != S_OK { if unsafe { hr_init(task_bar_list2.cast()) } != S_OK {
// In some old windows, the taskbar object could not be created, we just ignore it // In some old windows, the taskbar object could not be created, we just ignore it
return; return;
} }
@ -1281,8 +1290,8 @@ unsafe fn taskbar_mark_fullscreen(handle: HWND, fullscreen: bool) {
} }
task_bar_list2 = task_bar_list2_ptr.get(); task_bar_list2 = task_bar_list2_ptr.get();
let mark_fullscreen_window = (*(*task_bar_list2).lpVtbl).MarkFullscreenWindow; let mark_fullscreen_window = unsafe { (*(*task_bar_list2).lpVtbl).MarkFullscreenWindow };
mark_fullscreen_window(task_bar_list2, handle, fullscreen.into()); unsafe { mark_fullscreen_window(task_bar_list2, handle, fullscreen.into()) };
}) })
} }
@ -1292,20 +1301,22 @@ pub(crate) unsafe fn set_skip_taskbar(hwnd: HWND, skip: bool) {
let mut task_bar_list = task_bar_list_ptr.get(); let mut task_bar_list = task_bar_list_ptr.get();
if task_bar_list.is_null() { if task_bar_list.is_null() {
let hr = CoCreateInstance( let hr = unsafe {
&CLSID_TaskbarList, CoCreateInstance(
ptr::null_mut(), &CLSID_TaskbarList,
CLSCTX_ALL, ptr::null_mut(),
&IID_ITaskbarList, CLSCTX_ALL,
&mut task_bar_list as *mut _ as *mut _, &IID_ITaskbarList,
); &mut task_bar_list as *mut _ as *mut _,
)
};
if hr != S_OK { if hr != S_OK {
// In visual studio retrieving the taskbar list fails // In visual studio retrieving the taskbar list fails
return; return;
} }
let hr_init = (*(*task_bar_list).lpVtbl).HrInit; let hr_init = unsafe { (*(*task_bar_list).lpVtbl).HrInit };
if hr_init(task_bar_list.cast()) != S_OK { if unsafe { hr_init(task_bar_list.cast()) } != S_OK {
// In some old windows, the taskbar object could not be created, we just ignore it // In some old windows, the taskbar object could not be created, we just ignore it
return; return;
} }
@ -1314,11 +1325,11 @@ pub(crate) unsafe fn set_skip_taskbar(hwnd: HWND, skip: bool) {
task_bar_list = task_bar_list_ptr.get(); task_bar_list = task_bar_list_ptr.get();
if skip { if skip {
let delete_tab = (*(*task_bar_list).lpVtbl).DeleteTab; let delete_tab = unsafe { (*(*task_bar_list).lpVtbl).DeleteTab };
delete_tab(task_bar_list, hwnd); unsafe { delete_tab(task_bar_list, hwnd) };
} else { } else {
let add_tab = (*(*task_bar_list).lpVtbl).AddTab; let add_tab = unsafe { (*(*task_bar_list).lpVtbl).AddTab };
add_tab(task_bar_list, hwnd); unsafe { add_tab(task_bar_list, hwnd) };
} }
}); });
} }
@ -1328,7 +1339,7 @@ unsafe fn force_window_active(handle: HWND) {
// This is a little hack which can "steal" the foreground window permission // This is a little hack which can "steal" the foreground window permission
// We only call this function in the window creation, so it should be fine. // We only call this function in the window creation, so it should be fine.
// See : https://stackoverflow.com/questions/10740346/setforegroundwindow-only-working-while-visual-studio-is-open // See : https://stackoverflow.com/questions/10740346/setforegroundwindow-only-working-while-visual-studio-is-open
let alt_sc = MapVirtualKeyW(VK_MENU as u32, MAPVK_VK_TO_VSC); let alt_sc = unsafe { MapVirtualKeyW(VK_MENU as u32, MAPVK_VK_TO_VSC) };
let inputs = [ let inputs = [
INPUT { INPUT {
@ -1358,11 +1369,13 @@ unsafe fn force_window_active(handle: HWND) {
]; ];
// Simulate a key press and release // Simulate a key press and release
SendInput( unsafe {
inputs.len() as u32, SendInput(
inputs.as_ptr(), inputs.len() as u32,
mem::size_of::<INPUT>() as i32, inputs.as_ptr(),
); mem::size_of::<INPUT>() as i32,
)
};
SetForegroundWindow(handle); unsafe { SetForegroundWindow(handle) };
} }