Format everything and add rustfmt to travis (#951)
* Format everything and add rustfmt to travis * Remove extern crate winit from examples and add force_multiline_blocks * Format the code properly * Fix inconsistent period in PULL_REQUEST_TEMPLATE.md * Only run rustfmt on nightly * Travis fixings
This commit is contained in:
parent
b1b5aefc4b
commit
e2c84725de
109 changed files with 4787 additions and 3679 deletions
|
|
@ -1,45 +1,43 @@
|
|||
#![allow(non_snake_case, unused_unsafe)]
|
||||
|
||||
use std::mem;
|
||||
use std::os::raw::c_void;
|
||||
use std::sync::{Once, ONCE_INIT};
|
||||
use std::{
|
||||
mem,
|
||||
os::raw::c_void,
|
||||
sync::{Once, ONCE_INIT},
|
||||
};
|
||||
|
||||
use winapi::shared::minwindef::{BOOL, UINT, FALSE};
|
||||
use winapi::shared::windef::{
|
||||
DPI_AWARENESS_CONTEXT,
|
||||
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE,
|
||||
HMONITOR,
|
||||
HWND,
|
||||
use winapi::{
|
||||
shared::{
|
||||
minwindef::{BOOL, FALSE, UINT},
|
||||
windef::{DPI_AWARENESS_CONTEXT, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE, HMONITOR, HWND},
|
||||
winerror::S_OK,
|
||||
},
|
||||
um::{
|
||||
libloaderapi::{GetProcAddress, LoadLibraryA},
|
||||
shellscalingapi::{
|
||||
MDT_EFFECTIVE_DPI, MONITOR_DPI_TYPE, PROCESS_DPI_AWARENESS,
|
||||
PROCESS_PER_MONITOR_DPI_AWARE,
|
||||
},
|
||||
wingdi::{GetDeviceCaps, LOGPIXELSX},
|
||||
winnt::{HRESULT, LPCSTR},
|
||||
winuser::{self, MONITOR_DEFAULTTONEAREST},
|
||||
},
|
||||
};
|
||||
use winapi::shared::winerror::S_OK;
|
||||
use winapi::um::libloaderapi::{GetProcAddress, LoadLibraryA};
|
||||
use winapi::um::shellscalingapi::{
|
||||
MDT_EFFECTIVE_DPI,
|
||||
MONITOR_DPI_TYPE,
|
||||
PROCESS_DPI_AWARENESS,
|
||||
PROCESS_PER_MONITOR_DPI_AWARE,
|
||||
};
|
||||
use winapi::um::wingdi::{GetDeviceCaps, LOGPIXELSX};
|
||||
use winapi::um::winnt::{HRESULT, LPCSTR};
|
||||
use winapi::um::winuser::{self, MONITOR_DEFAULTTONEAREST};
|
||||
|
||||
const DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2: DPI_AWARENESS_CONTEXT = -4isize as _;
|
||||
|
||||
type SetProcessDPIAware = unsafe extern "system" fn () -> BOOL;
|
||||
type SetProcessDpiAwareness = unsafe extern "system" fn (
|
||||
value: PROCESS_DPI_AWARENESS,
|
||||
) -> HRESULT;
|
||||
type SetProcessDpiAwarenessContext = unsafe extern "system" fn (
|
||||
value: DPI_AWARENESS_CONTEXT,
|
||||
) -> BOOL;
|
||||
type GetDpiForWindow = unsafe extern "system" fn (hwnd: HWND) -> UINT;
|
||||
type GetDpiForMonitor = unsafe extern "system" fn (
|
||||
type SetProcessDPIAware = unsafe extern "system" fn() -> BOOL;
|
||||
type SetProcessDpiAwareness = unsafe extern "system" fn(value: PROCESS_DPI_AWARENESS) -> HRESULT;
|
||||
type SetProcessDpiAwarenessContext =
|
||||
unsafe extern "system" fn(value: DPI_AWARENESS_CONTEXT) -> BOOL;
|
||||
type GetDpiForWindow = unsafe extern "system" fn(hwnd: HWND) -> UINT;
|
||||
type GetDpiForMonitor = unsafe extern "system" fn(
|
||||
hmonitor: HMONITOR,
|
||||
dpi_type: MONITOR_DPI_TYPE,
|
||||
dpi_x: *mut UINT,
|
||||
dpi_y: *mut UINT,
|
||||
) -> HRESULT;
|
||||
type EnableNonClientDpiScaling = unsafe extern "system" fn (hwnd: HWND) -> BOOL;
|
||||
type EnableNonClientDpiScaling = unsafe extern "system" fn(hwnd: HWND) -> BOOL;
|
||||
|
||||
// Helper function to dynamically load function pointer.
|
||||
// `library` and `function` must be zero-terminated.
|
||||
|
|
@ -65,53 +63,48 @@ macro_rules! get_function {
|
|||
($lib:expr, $func:ident) => {
|
||||
get_function_impl(concat!($lib, '\0'), concat!(stringify!($func), '\0'))
|
||||
.map(|f| unsafe { mem::transmute::<*const _, $func>(f) })
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref GET_DPI_FOR_WINDOW: Option<GetDpiForWindow> = get_function!(
|
||||
"user32.dll",
|
||||
GetDpiForWindow
|
||||
);
|
||||
static ref GET_DPI_FOR_MONITOR: Option<GetDpiForMonitor> = get_function!(
|
||||
"shcore.dll",
|
||||
GetDpiForMonitor
|
||||
);
|
||||
static ref ENABLE_NON_CLIENT_DPI_SCALING: Option<EnableNonClientDpiScaling> = get_function!(
|
||||
"user32.dll",
|
||||
EnableNonClientDpiScaling
|
||||
);
|
||||
static ref GET_DPI_FOR_WINDOW: Option<GetDpiForWindow> =
|
||||
get_function!("user32.dll", GetDpiForWindow);
|
||||
static ref GET_DPI_FOR_MONITOR: Option<GetDpiForMonitor> =
|
||||
get_function!("shcore.dll", GetDpiForMonitor);
|
||||
static ref ENABLE_NON_CLIENT_DPI_SCALING: Option<EnableNonClientDpiScaling> =
|
||||
get_function!("user32.dll", EnableNonClientDpiScaling);
|
||||
}
|
||||
|
||||
pub fn become_dpi_aware(enable: bool) {
|
||||
if !enable { return; }
|
||||
if !enable {
|
||||
return;
|
||||
}
|
||||
static ENABLE_DPI_AWARENESS: Once = ONCE_INIT;
|
||||
ENABLE_DPI_AWARENESS.call_once(|| { unsafe {
|
||||
if let Some(SetProcessDpiAwarenessContext) = get_function!(
|
||||
"user32.dll",
|
||||
SetProcessDpiAwarenessContext
|
||||
) {
|
||||
// We are on Windows 10 Anniversary Update (1607) or later.
|
||||
if SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)
|
||||
== FALSE {
|
||||
// V2 only works with Windows 10 Creators Update (1703). Try using the older
|
||||
// V1 if we can't set V2.
|
||||
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE);
|
||||
ENABLE_DPI_AWARENESS.call_once(|| {
|
||||
unsafe {
|
||||
if let Some(SetProcessDpiAwarenessContext) =
|
||||
get_function!("user32.dll", SetProcessDpiAwarenessContext)
|
||||
{
|
||||
// We are on Windows 10 Anniversary Update (1607) or later.
|
||||
if SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)
|
||||
== FALSE
|
||||
{
|
||||
// V2 only works with Windows 10 Creators Update (1703). Try using the older
|
||||
// V1 if we can't set V2.
|
||||
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE);
|
||||
}
|
||||
} else if let Some(SetProcessDpiAwareness) =
|
||||
get_function!("shcore.dll", SetProcessDpiAwareness)
|
||||
{
|
||||
// We are on Windows 8.1 or later.
|
||||
SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
|
||||
} else if let Some(SetProcessDPIAware) = get_function!("user32.dll", SetProcessDPIAware)
|
||||
{
|
||||
// We are on Vista or later.
|
||||
SetProcessDPIAware();
|
||||
}
|
||||
} else if let Some(SetProcessDpiAwareness) = get_function!(
|
||||
"shcore.dll",
|
||||
SetProcessDpiAwareness
|
||||
) {
|
||||
// We are on Windows 8.1 or later.
|
||||
SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
|
||||
} else if let Some(SetProcessDPIAware) = get_function!(
|
||||
"user32.dll",
|
||||
SetProcessDPIAware
|
||||
) {
|
||||
// We are on Vista or later.
|
||||
SetProcessDPIAware();
|
||||
}
|
||||
} });
|
||||
});
|
||||
}
|
||||
|
||||
pub fn enable_non_client_dpi_scaling(hwnd: HWND) {
|
||||
|
|
@ -132,7 +125,7 @@ pub fn get_monitor_dpi(hmonitor: HMONITOR) -> Option<u32> {
|
|||
// MSDN says that "the values of *dpiX and *dpiY are identical. You only need to
|
||||
// record one of the values to determine the DPI and respond appropriately".
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/dn280510(v=vs.85).aspx
|
||||
return Some(dpi_x as u32)
|
||||
return Some(dpi_x as u32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,31 @@
|
|||
use std::ffi::OsString;
|
||||
use std::os::windows::ffi::OsStringExt;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::{mem, ptr};
|
||||
use std::{
|
||||
ffi::OsString,
|
||||
mem,
|
||||
os::windows::ffi::OsStringExt,
|
||||
path::PathBuf,
|
||||
ptr,
|
||||
sync::atomic::{AtomicUsize, Ordering},
|
||||
};
|
||||
|
||||
use winapi::ctypes::c_void;
|
||||
use winapi::shared::guiddef::REFIID;
|
||||
use winapi::shared::minwindef::{DWORD, MAX_PATH, UINT, ULONG};
|
||||
use winapi::shared::windef::{HWND, POINTL};
|
||||
use winapi::shared::winerror::S_OK;
|
||||
use winapi::um::objidl::IDataObject;
|
||||
use winapi::um::oleidl::{DROPEFFECT_COPY, DROPEFFECT_NONE, IDropTarget, IDropTargetVtbl};
|
||||
use winapi::um::winnt::HRESULT;
|
||||
use winapi::um::{shellapi, unknwnbase};
|
||||
use winapi::{
|
||||
ctypes::c_void,
|
||||
shared::{
|
||||
guiddef::REFIID,
|
||||
minwindef::{DWORD, MAX_PATH, UINT, ULONG},
|
||||
windef::{HWND, POINTL},
|
||||
winerror::S_OK,
|
||||
},
|
||||
um::{
|
||||
objidl::IDataObject,
|
||||
oleidl::{IDropTarget, IDropTargetVtbl, DROPEFFECT_COPY, DROPEFFECT_NONE},
|
||||
shellapi, unknwnbase,
|
||||
winnt::HRESULT,
|
||||
},
|
||||
};
|
||||
|
||||
use crate::platform_impl::platform::WindowId;
|
||||
|
||||
use crate::event::Event;
|
||||
use crate::window::WindowId as SuperWindowId;
|
||||
use crate::{event::Event, window::WindowId as SuperWindowId};
|
||||
|
||||
#[repr(C)]
|
||||
pub struct FileDropHandlerData {
|
||||
|
|
@ -26,7 +34,7 @@ pub struct FileDropHandlerData {
|
|||
window: HWND,
|
||||
send_event: Box<dyn Fn(Event<()>)>,
|
||||
cursor_effect: DWORD,
|
||||
hovered_is_valid: bool, // If the currently hovered item is not valid there must not be any `HoveredFileCancelled` emitted
|
||||
hovered_is_valid: bool, /* If the currently hovered item is not valid there must not be any `HoveredFileCancelled` emitted */
|
||||
}
|
||||
|
||||
pub struct FileDropHandler {
|
||||
|
|
@ -155,16 +163,25 @@ impl FileDropHandler {
|
|||
&mut *(this as *mut _)
|
||||
}
|
||||
|
||||
unsafe fn iterate_filenames<F>(data_obj: *const IDataObject, callback: F) -> Option<shellapi::HDROP>
|
||||
unsafe fn iterate_filenames<F>(
|
||||
data_obj: *const IDataObject,
|
||||
callback: F,
|
||||
) -> Option<shellapi::HDROP>
|
||||
where
|
||||
F: Fn(PathBuf),
|
||||
{
|
||||
use winapi::ctypes::wchar_t;
|
||||
use winapi::shared::winerror::{SUCCEEDED, DV_E_FORMATETC};
|
||||
use winapi::shared::wtypes::{CLIPFORMAT, DVASPECT_CONTENT};
|
||||
use winapi::um::objidl::{FORMATETC, TYMED_HGLOBAL};
|
||||
use winapi::um::shellapi::DragQueryFileW;
|
||||
use winapi::um::winuser::CF_HDROP;
|
||||
use winapi::{
|
||||
ctypes::wchar_t,
|
||||
shared::{
|
||||
winerror::{DV_E_FORMATETC, SUCCEEDED},
|
||||
wtypes::{CLIPFORMAT, DVASPECT_CONTENT},
|
||||
},
|
||||
um::{
|
||||
objidl::{FORMATETC, TYMED_HGLOBAL},
|
||||
shellapi::DragQueryFileW,
|
||||
winuser::CF_HDROP,
|
||||
},
|
||||
};
|
||||
|
||||
let mut drop_format = FORMATETC {
|
||||
cfFormat: CF_HDROP as CLIPFORMAT,
|
||||
|
|
|
|||
|
|
@ -1,16 +1,19 @@
|
|||
use std::{char, ptr};
|
||||
use std::os::raw::c_int;
|
||||
use std::sync::atomic::{AtomicBool, AtomicPtr, Ordering};
|
||||
use std::{
|
||||
char,
|
||||
os::raw::c_int,
|
||||
ptr,
|
||||
sync::atomic::{AtomicBool, AtomicPtr, Ordering},
|
||||
};
|
||||
|
||||
use crate::event::{ScanCode, ModifiersState, VirtualKeyCode};
|
||||
use crate::event::{ModifiersState, ScanCode, VirtualKeyCode};
|
||||
|
||||
use winapi::shared::minwindef::{WPARAM, LPARAM, UINT, HKL, HKL__};
|
||||
use winapi::um::winuser;
|
||||
use winapi::{
|
||||
shared::minwindef::{HKL, HKL__, LPARAM, UINT, WPARAM},
|
||||
um::winuser,
|
||||
};
|
||||
|
||||
fn key_pressed(vkey: c_int) -> bool {
|
||||
unsafe {
|
||||
(winuser::GetKeyState(vkey) & (1 << 15)) == (1 << 15)
|
||||
}
|
||||
unsafe { (winuser::GetKeyState(vkey) & (1 << 15)) == (1 << 15) }
|
||||
}
|
||||
|
||||
pub fn get_key_mods() -> ModifiersState {
|
||||
|
|
@ -26,9 +29,19 @@ pub fn get_key_mods() -> ModifiersState {
|
|||
|
||||
unsafe fn get_char(keyboard_state: &[u8; 256], v_key: u32, hkl: HKL) -> Option<char> {
|
||||
let mut unicode_bytes = [0u16; 5];
|
||||
let len = winuser::ToUnicodeEx(v_key, 0, keyboard_state.as_ptr(), unicode_bytes.as_mut_ptr(), unicode_bytes.len() as _, 0, hkl);
|
||||
let len = winuser::ToUnicodeEx(
|
||||
v_key,
|
||||
0,
|
||||
keyboard_state.as_ptr(),
|
||||
unicode_bytes.as_mut_ptr(),
|
||||
unicode_bytes.len() as _,
|
||||
0,
|
||||
hkl,
|
||||
);
|
||||
if len >= 1 {
|
||||
char::decode_utf16(unicode_bytes.into_iter().cloned()).next().and_then(|c| c.ok())
|
||||
char::decode_utf16(unicode_bytes.into_iter().cloned())
|
||||
.next()
|
||||
.and_then(|c| c.ok())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
@ -239,7 +252,7 @@ pub fn vkey_to_winit_vkey(vkey: c_int) -> Option<VirtualKeyCode> {
|
|||
winuser::VK_OEM_5 => map_text_keys(vkey),
|
||||
winuser::VK_OEM_6 => map_text_keys(vkey),
|
||||
winuser::VK_OEM_7 => map_text_keys(vkey),
|
||||
/*winuser::VK_OEM_8 => Some(VirtualKeyCode::Oem_8), */
|
||||
/* winuser::VK_OEM_8 => Some(VirtualKeyCode::Oem_8), */
|
||||
winuser::VK_OEM_102 => Some(VirtualKeyCode::OEM102),
|
||||
/*winuser::VK_PROCESSKEY => Some(VirtualKeyCode::Processkey),
|
||||
winuser::VK_PACKET => Some(VirtualKeyCode::Packet),
|
||||
|
|
@ -252,49 +265,61 @@ pub fn vkey_to_winit_vkey(vkey: c_int) -> Option<VirtualKeyCode> {
|
|||
winuser::VK_NONAME => Some(VirtualKeyCode::Noname),
|
||||
winuser::VK_PA1 => Some(VirtualKeyCode::Pa1),
|
||||
winuser::VK_OEM_CLEAR => Some(VirtualKeyCode::Oem_clear),*/
|
||||
_ => None
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_extended_keys(vkey: c_int, mut scancode: UINT, extended: bool) -> Option<(c_int, UINT)> {
|
||||
pub fn handle_extended_keys(
|
||||
vkey: c_int,
|
||||
mut scancode: UINT,
|
||||
extended: bool,
|
||||
) -> Option<(c_int, UINT)> {
|
||||
// Welcome to hell https://blog.molecular-matters.com/2011/09/05/properly-handling-keyboard-input/
|
||||
let vkey = match vkey {
|
||||
winuser::VK_SHIFT => unsafe { winuser::MapVirtualKeyA(
|
||||
scancode,
|
||||
winuser::MAPVK_VSC_TO_VK_EX,
|
||||
) as _ },
|
||||
winuser::VK_CONTROL => if extended {
|
||||
winuser::VK_RCONTROL
|
||||
} else {
|
||||
winuser::VK_LCONTROL
|
||||
winuser::VK_SHIFT => unsafe {
|
||||
winuser::MapVirtualKeyA(scancode, winuser::MAPVK_VSC_TO_VK_EX) as _
|
||||
},
|
||||
winuser::VK_MENU => if extended {
|
||||
winuser::VK_RMENU
|
||||
} else {
|
||||
winuser::VK_LMENU
|
||||
winuser::VK_CONTROL => {
|
||||
if extended {
|
||||
winuser::VK_RCONTROL
|
||||
} else {
|
||||
winuser::VK_LCONTROL
|
||||
}
|
||||
},
|
||||
_ => match scancode {
|
||||
// This is only triggered when using raw input. Without this check, we get two events whenever VK_PAUSE is
|
||||
// pressed, the first one having scancode 0x1D but vkey VK_PAUSE...
|
||||
0x1D if vkey == winuser::VK_PAUSE => return None,
|
||||
// ...and the second having scancode 0x45 but an unmatched vkey!
|
||||
0x45 => winuser::VK_PAUSE,
|
||||
// VK_PAUSE and VK_SCROLL have the same scancode when using modifiers, alongside incorrect vkey values.
|
||||
0x46 => {
|
||||
if extended {
|
||||
scancode = 0x45;
|
||||
winuser::VK_PAUSE
|
||||
} else {
|
||||
winuser::VK_SCROLL
|
||||
}
|
||||
},
|
||||
_ => vkey,
|
||||
winuser::VK_MENU => {
|
||||
if extended {
|
||||
winuser::VK_RMENU
|
||||
} else {
|
||||
winuser::VK_LMENU
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
match scancode {
|
||||
// This is only triggered when using raw input. Without this check, we get two events whenever VK_PAUSE is
|
||||
// pressed, the first one having scancode 0x1D but vkey VK_PAUSE...
|
||||
0x1D if vkey == winuser::VK_PAUSE => return None,
|
||||
// ...and the second having scancode 0x45 but an unmatched vkey!
|
||||
0x45 => winuser::VK_PAUSE,
|
||||
// VK_PAUSE and VK_SCROLL have the same scancode when using modifiers, alongside incorrect vkey values.
|
||||
0x46 => {
|
||||
if extended {
|
||||
scancode = 0x45;
|
||||
winuser::VK_PAUSE
|
||||
} else {
|
||||
winuser::VK_SCROLL
|
||||
}
|
||||
},
|
||||
_ => vkey,
|
||||
}
|
||||
},
|
||||
};
|
||||
Some((vkey, scancode))
|
||||
}
|
||||
|
||||
pub fn process_key_params(wparam: WPARAM, lparam: LPARAM) -> Option<(ScanCode, Option<VirtualKeyCode>)> {
|
||||
pub fn process_key_params(
|
||||
wparam: WPARAM,
|
||||
lparam: LPARAM,
|
||||
) -> Option<(ScanCode, Option<VirtualKeyCode>)> {
|
||||
let scancode = ((lparam >> 16) & 0xff) as UINT;
|
||||
let extended = (lparam & 0x01000000) != 0;
|
||||
handle_extended_keys(wparam as _, scancode, extended)
|
||||
|
|
@ -304,7 +329,9 @@ pub fn process_key_params(wparam: WPARAM, lparam: LPARAM) -> Option<(ScanCode, O
|
|||
// This is needed as windows doesn't properly distinguish
|
||||
// some virtual key codes for different keyboard layouts
|
||||
fn map_text_keys(win_virtual_key: i32) -> Option<VirtualKeyCode> {
|
||||
let char_key = unsafe { winuser::MapVirtualKeyA(win_virtual_key as u32, winuser::MAPVK_VK_TO_CHAR) } & 0x7FFF;
|
||||
let char_key =
|
||||
unsafe { winuser::MapVirtualKeyA(win_virtual_key as u32, winuser::MAPVK_VK_TO_CHAR) }
|
||||
& 0x7FFF;
|
||||
match char::from_u32(char_key) {
|
||||
Some(';') => Some(VirtualKeyCode::Semicolon),
|
||||
Some('/') => Some(VirtualKeyCode::Slash),
|
||||
|
|
@ -313,6 +340,6 @@ fn map_text_keys(win_virtual_key: i32) -> Option<VirtualKeyCode> {
|
|||
Some(']') => Some(VirtualKeyCode::RBracket),
|
||||
Some('\'') => Some(VirtualKeyCode::Apostrophe),
|
||||
Some('\\') => Some(VirtualKeyCode::Backslash),
|
||||
_ => None
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,13 +1,15 @@
|
|||
use std::{mem, ptr, io};
|
||||
use std::os::windows::ffi::OsStrExt;
|
||||
use std::path::Path;
|
||||
use std::{io, mem, os::windows::ffi::OsStrExt, path::Path, ptr};
|
||||
|
||||
use winapi::ctypes::{c_int, wchar_t};
|
||||
use winapi::shared::minwindef::{BYTE, LPARAM, WPARAM};
|
||||
use winapi::shared::windef::{HICON, HWND};
|
||||
use winapi::um::winuser;
|
||||
use winapi::{
|
||||
ctypes::{c_int, wchar_t},
|
||||
shared::{
|
||||
minwindef::{BYTE, LPARAM, WPARAM},
|
||||
windef::{HICON, HWND},
|
||||
},
|
||||
um::winuser,
|
||||
};
|
||||
|
||||
use crate::icon::{Pixel, PIXEL_SIZE, Icon};
|
||||
use crate::icon::{Icon, Pixel, PIXEL_SIZE};
|
||||
|
||||
impl Pixel {
|
||||
fn to_bgra(&mut self) {
|
||||
|
|
@ -103,11 +105,6 @@ impl Drop for WinIcon {
|
|||
|
||||
pub fn unset_for_window(hwnd: HWND, icon_type: IconType) {
|
||||
unsafe {
|
||||
winuser::SendMessageW(
|
||||
hwnd,
|
||||
winuser::WM_SETICON,
|
||||
icon_type as WPARAM,
|
||||
0 as LPARAM,
|
||||
);
|
||||
winuser::SendMessageW(hwnd, winuser::WM_SETICON, icon_type as WPARAM, 0 as LPARAM);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
#![cfg(target_os = "windows")]
|
||||
|
||||
use winapi;
|
||||
use winapi::shared::windef::HWND;
|
||||
use winapi::{self, shared::windef::HWND};
|
||||
|
||||
pub use self::event_loop::{EventLoop, EventLoopWindowTarget, EventLoopProxy};
|
||||
pub use self::monitor::MonitorHandle;
|
||||
pub use self::window::Window;
|
||||
pub use self::{
|
||||
event_loop::{EventLoop, EventLoopProxy, EventLoopWindowTarget},
|
||||
monitor::MonitorHandle,
|
||||
window::Window,
|
||||
};
|
||||
|
||||
use crate::window::Icon;
|
||||
use crate::event::DeviceId as RootDeviceId;
|
||||
use crate::{event::DeviceId as RootDeviceId, window::Icon};
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct PlatformSpecificWindowBuilderAttributes {
|
||||
|
|
|
|||
|
|
@ -1,16 +1,25 @@
|
|||
use winapi::shared::minwindef::{BOOL, DWORD, LPARAM, TRUE, WORD};
|
||||
use winapi::shared::windef::{HDC, HMONITOR, HWND, LPRECT, POINT};
|
||||
use winapi::um::winnt::LONG;
|
||||
use winapi::um::{wingdi, winuser};
|
||||
use winapi::{
|
||||
shared::{
|
||||
minwindef::{BOOL, DWORD, LPARAM, TRUE, WORD},
|
||||
windef::{HDC, HMONITOR, HWND, LPRECT, POINT},
|
||||
},
|
||||
um::{wingdi, winnt::LONG, winuser},
|
||||
};
|
||||
|
||||
use std::collections::{HashSet, VecDeque};
|
||||
use std::{io, mem, ptr};
|
||||
use std::{
|
||||
collections::{HashSet, VecDeque},
|
||||
io, mem, ptr,
|
||||
};
|
||||
|
||||
use super::{util, EventLoop};
|
||||
use crate::dpi::{PhysicalPosition, PhysicalSize};
|
||||
use crate::monitor::VideoMode;
|
||||
use crate::platform_impl::platform::dpi::{dpi_to_scale_factor, get_monitor_dpi};
|
||||
use crate::platform_impl::platform::window::Window;
|
||||
use crate::{
|
||||
dpi::{PhysicalPosition, PhysicalSize},
|
||||
monitor::VideoMode,
|
||||
platform_impl::platform::{
|
||||
dpi::{dpi_to_scale_factor, get_monitor_dpi},
|
||||
window::Window,
|
||||
},
|
||||
};
|
||||
|
||||
/// Win32 implementation of the main `MonitorHandle` object.
|
||||
#[derive(Derivative)]
|
||||
|
|
@ -69,16 +78,12 @@ pub fn available_monitors() -> VecDeque<MonitorHandle> {
|
|||
|
||||
pub fn primary_monitor() -> MonitorHandle {
|
||||
const ORIGIN: POINT = POINT { x: 0, y: 0 };
|
||||
let hmonitor = unsafe {
|
||||
winuser::MonitorFromPoint(ORIGIN, winuser::MONITOR_DEFAULTTOPRIMARY)
|
||||
};
|
||||
let hmonitor = unsafe { winuser::MonitorFromPoint(ORIGIN, winuser::MONITOR_DEFAULTTOPRIMARY) };
|
||||
MonitorHandle::from_hmonitor(hmonitor)
|
||||
}
|
||||
|
||||
pub fn current_monitor(hwnd: HWND) -> MonitorHandle {
|
||||
let hmonitor = unsafe {
|
||||
winuser::MonitorFromWindow(hwnd, winuser::MONITOR_DEFAULTTONEAREST)
|
||||
};
|
||||
let hmonitor = unsafe { winuser::MonitorFromWindow(hwnd, winuser::MONITOR_DEFAULTTONEAREST) };
|
||||
MonitorHandle::from_hmonitor(hmonitor)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,49 +1,35 @@
|
|||
use std::mem::{self, size_of};
|
||||
use std::ptr;
|
||||
|
||||
use winapi::ctypes::wchar_t;
|
||||
use winapi::shared::minwindef::{UINT, USHORT, TRUE};
|
||||
use winapi::shared::hidusage::{
|
||||
HID_USAGE_PAGE_GENERIC,
|
||||
HID_USAGE_GENERIC_MOUSE,
|
||||
HID_USAGE_GENERIC_KEYBOARD,
|
||||
};
|
||||
use winapi::shared::windef::HWND;
|
||||
use winapi::um::winnt::HANDLE;
|
||||
use winapi::um::winuser::{
|
||||
self,
|
||||
RAWINPUTDEVICELIST,
|
||||
RID_DEVICE_INFO,
|
||||
RID_DEVICE_INFO_MOUSE,
|
||||
RID_DEVICE_INFO_KEYBOARD,
|
||||
RID_DEVICE_INFO_HID,
|
||||
RIM_TYPEMOUSE,
|
||||
RIM_TYPEKEYBOARD,
|
||||
RIM_TYPEHID,
|
||||
RIDI_DEVICEINFO,
|
||||
RIDI_DEVICENAME,
|
||||
RAWINPUTDEVICE,
|
||||
RIDEV_DEVNOTIFY,
|
||||
RIDEV_INPUTSINK,
|
||||
HRAWINPUT,
|
||||
RAWINPUT,
|
||||
RAWINPUTHEADER,
|
||||
RID_INPUT,
|
||||
use std::{
|
||||
mem::{self, size_of},
|
||||
ptr,
|
||||
};
|
||||
|
||||
use crate::platform_impl::platform::util;
|
||||
use crate::event::ElementState;
|
||||
use winapi::{
|
||||
ctypes::wchar_t,
|
||||
shared::{
|
||||
hidusage::{HID_USAGE_GENERIC_KEYBOARD, HID_USAGE_GENERIC_MOUSE, HID_USAGE_PAGE_GENERIC},
|
||||
minwindef::{TRUE, UINT, USHORT},
|
||||
windef::HWND,
|
||||
},
|
||||
um::{
|
||||
winnt::HANDLE,
|
||||
winuser::{
|
||||
self, HRAWINPUT, RAWINPUT, RAWINPUTDEVICE, RAWINPUTDEVICELIST, RAWINPUTHEADER,
|
||||
RIDEV_DEVNOTIFY, RIDEV_INPUTSINK, RIDI_DEVICEINFO, RIDI_DEVICENAME, RID_DEVICE_INFO,
|
||||
RID_DEVICE_INFO_HID, RID_DEVICE_INFO_KEYBOARD, RID_DEVICE_INFO_MOUSE, RID_INPUT,
|
||||
RIM_TYPEHID, RIM_TYPEKEYBOARD, RIM_TYPEMOUSE,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
use crate::{event::ElementState, platform_impl::platform::util};
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_raw_input_device_list() -> Option<Vec<RAWINPUTDEVICELIST>> {
|
||||
let list_size = size_of::<RAWINPUTDEVICELIST>() as UINT;
|
||||
|
||||
let mut num_devices = 0;
|
||||
let status = unsafe { winuser::GetRawInputDeviceList(
|
||||
ptr::null_mut(),
|
||||
&mut num_devices,
|
||||
list_size,
|
||||
) };
|
||||
let status =
|
||||
unsafe { winuser::GetRawInputDeviceList(ptr::null_mut(), &mut num_devices, list_size) };
|
||||
|
||||
if status == UINT::max_value() {
|
||||
return None;
|
||||
|
|
@ -51,11 +37,9 @@ pub fn get_raw_input_device_list() -> Option<Vec<RAWINPUTDEVICELIST>> {
|
|||
|
||||
let mut buffer = Vec::with_capacity(num_devices as _);
|
||||
|
||||
let num_stored = unsafe { winuser::GetRawInputDeviceList(
|
||||
buffer.as_ptr() as _,
|
||||
&mut num_devices,
|
||||
list_size,
|
||||
) };
|
||||
let num_stored = unsafe {
|
||||
winuser::GetRawInputDeviceList(buffer.as_ptr() as _, &mut num_devices, list_size)
|
||||
};
|
||||
|
||||
if num_stored == UINT::max_value() {
|
||||
return None;
|
||||
|
|
@ -96,12 +80,14 @@ pub fn get_raw_input_device_info(handle: HANDLE) -> Option<RawDeviceInfo> {
|
|||
info.cbSize = info_size;
|
||||
|
||||
let mut minimum_size = 0;
|
||||
let status = unsafe { winuser::GetRawInputDeviceInfoW(
|
||||
handle,
|
||||
RIDI_DEVICEINFO,
|
||||
&mut info as *mut _ as _,
|
||||
&mut minimum_size,
|
||||
) };
|
||||
let status = unsafe {
|
||||
winuser::GetRawInputDeviceInfoW(
|
||||
handle,
|
||||
RIDI_DEVICEINFO,
|
||||
&mut info as *mut _ as _,
|
||||
&mut minimum_size,
|
||||
)
|
||||
};
|
||||
|
||||
if status == UINT::max_value() || status == 0 {
|
||||
return None;
|
||||
|
|
@ -114,12 +100,9 @@ pub fn get_raw_input_device_info(handle: HANDLE) -> Option<RawDeviceInfo> {
|
|||
|
||||
pub fn get_raw_input_device_name(handle: HANDLE) -> Option<String> {
|
||||
let mut minimum_size = 0;
|
||||
let status = unsafe { winuser::GetRawInputDeviceInfoW(
|
||||
handle,
|
||||
RIDI_DEVICENAME,
|
||||
ptr::null_mut(),
|
||||
&mut minimum_size,
|
||||
) };
|
||||
let status = unsafe {
|
||||
winuser::GetRawInputDeviceInfoW(handle, RIDI_DEVICENAME, ptr::null_mut(), &mut minimum_size)
|
||||
};
|
||||
|
||||
if status != 0 {
|
||||
return None;
|
||||
|
|
@ -127,12 +110,14 @@ pub fn get_raw_input_device_name(handle: HANDLE) -> Option<String> {
|
|||
|
||||
let mut name: Vec<wchar_t> = Vec::with_capacity(minimum_size as _);
|
||||
|
||||
let status = unsafe { winuser::GetRawInputDeviceInfoW(
|
||||
handle,
|
||||
RIDI_DEVICENAME,
|
||||
name.as_ptr() as _,
|
||||
&mut minimum_size,
|
||||
) };
|
||||
let status = unsafe {
|
||||
winuser::GetRawInputDeviceInfoW(
|
||||
handle,
|
||||
RIDI_DEVICENAME,
|
||||
name.as_ptr() as _,
|
||||
&mut minimum_size,
|
||||
)
|
||||
};
|
||||
|
||||
if status == UINT::max_value() || status == 0 {
|
||||
return None;
|
||||
|
|
@ -148,11 +133,9 @@ pub fn get_raw_input_device_name(handle: HANDLE) -> Option<String> {
|
|||
pub fn register_raw_input_devices(devices: &[RAWINPUTDEVICE]) -> bool {
|
||||
let device_size = size_of::<RAWINPUTDEVICE>() as UINT;
|
||||
|
||||
let success = unsafe { winuser::RegisterRawInputDevices(
|
||||
devices.as_ptr() as _,
|
||||
devices.len() as _,
|
||||
device_size,
|
||||
) };
|
||||
let success = unsafe {
|
||||
winuser::RegisterRawInputDevices(devices.as_ptr() as _, devices.len() as _, device_size)
|
||||
};
|
||||
|
||||
success == TRUE
|
||||
}
|
||||
|
|
@ -185,13 +168,15 @@ pub fn get_raw_input_data(handle: HRAWINPUT) -> Option<RAWINPUT> {
|
|||
let mut data_size = size_of::<RAWINPUT>() as UINT;
|
||||
let header_size = size_of::<RAWINPUTHEADER>() as UINT;
|
||||
|
||||
let status = unsafe { winuser::GetRawInputData(
|
||||
handle,
|
||||
RID_INPUT,
|
||||
&mut data as *mut _ as _,
|
||||
&mut data_size,
|
||||
header_size,
|
||||
) };
|
||||
let status = unsafe {
|
||||
winuser::GetRawInputData(
|
||||
handle,
|
||||
RID_INPUT,
|
||||
&mut data as *mut _ as _,
|
||||
&mut data_size,
|
||||
header_size,
|
||||
)
|
||||
};
|
||||
|
||||
if status == UINT::max_value() || status == 0 {
|
||||
return None;
|
||||
|
|
@ -200,10 +185,11 @@ pub fn get_raw_input_data(handle: HRAWINPUT) -> Option<RAWINPUT> {
|
|||
Some(data)
|
||||
}
|
||||
|
||||
|
||||
fn button_flags_to_element_state(button_flags: USHORT, down_flag: USHORT, up_flag: USHORT)
|
||||
-> Option<ElementState>
|
||||
{
|
||||
fn button_flags_to_element_state(
|
||||
button_flags: USHORT,
|
||||
down_flag: USHORT,
|
||||
up_flag: USHORT,
|
||||
) -> Option<ElementState> {
|
||||
// We assume the same button won't be simultaneously pressed and released.
|
||||
if util::has_flag(button_flags, down_flag) {
|
||||
Some(ElementState::Pressed)
|
||||
|
|
|
|||
|
|
@ -1,17 +1,23 @@
|
|||
use std::{mem, ptr, slice, io};
|
||||
use std::ops::BitAnd;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::{
|
||||
io, mem,
|
||||
ops::BitAnd,
|
||||
ptr, slice,
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
};
|
||||
|
||||
use crate::window::CursorIcon;
|
||||
use winapi::ctypes::wchar_t;
|
||||
use winapi::shared::minwindef::{BOOL, DWORD};
|
||||
use winapi::shared::windef::{HWND, POINT, RECT};
|
||||
use winapi::um::winbase::lstrlenW;
|
||||
use winapi::um::winuser;
|
||||
use winapi::{
|
||||
ctypes::wchar_t,
|
||||
shared::{
|
||||
minwindef::{BOOL, DWORD},
|
||||
windef::{HWND, POINT, RECT},
|
||||
},
|
||||
um::{winbase::lstrlenW, winuser},
|
||||
};
|
||||
|
||||
pub fn has_flag<T>(bitset: T, flag: T) -> bool
|
||||
where T:
|
||||
Copy + PartialEq + BitAnd<T, Output = T>
|
||||
where
|
||||
T: Copy + PartialEq + BitAnd<T, Output = T>,
|
||||
{
|
||||
bitset & flag == flag
|
||||
}
|
||||
|
|
@ -75,32 +81,42 @@ pub fn adjust_window_rect(hwnd: HWND, rect: RECT) -> Option<RECT> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn adjust_window_rect_with_styles(hwnd: HWND, style: DWORD, style_ex: DWORD, rect: RECT) -> Option<RECT> {
|
||||
unsafe { status_map(|r| {
|
||||
*r = rect;
|
||||
pub fn adjust_window_rect_with_styles(
|
||||
hwnd: HWND,
|
||||
style: DWORD,
|
||||
style_ex: DWORD,
|
||||
rect: RECT,
|
||||
) -> Option<RECT> {
|
||||
unsafe {
|
||||
status_map(|r| {
|
||||
*r = rect;
|
||||
|
||||
let b_menu = !winuser::GetMenu(hwnd).is_null() as BOOL;
|
||||
winuser::AdjustWindowRectEx(r, style as _ , b_menu, style_ex as _)
|
||||
}) }
|
||||
let b_menu = !winuser::GetMenu(hwnd).is_null() as BOOL;
|
||||
winuser::AdjustWindowRectEx(r, style as _, b_menu, style_ex as _)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_cursor_hidden(hidden: bool) {
|
||||
static HIDDEN: AtomicBool = AtomicBool::new(false);
|
||||
let changed = HIDDEN.swap(hidden, Ordering::SeqCst) ^ hidden;
|
||||
if changed {
|
||||
unsafe{ winuser::ShowCursor(!hidden as BOOL) };
|
||||
unsafe { winuser::ShowCursor(!hidden as BOOL) };
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_cursor_clip(rect: Option<RECT>) -> Result<(), io::Error> {
|
||||
unsafe {
|
||||
let rect_ptr = rect.as_ref().map(|r| r as *const RECT).unwrap_or(ptr::null());
|
||||
let rect_ptr = rect
|
||||
.as_ref()
|
||||
.map(|r| r as *const RECT)
|
||||
.unwrap_or(ptr::null());
|
||||
win_to_err(|| winuser::ClipCursor(rect_ptr))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_focused(window: HWND) -> bool {
|
||||
window == unsafe{ winuser::GetActiveWindow() }
|
||||
window == unsafe { winuser::GetActiveWindow() }
|
||||
}
|
||||
|
||||
impl CursorIcon {
|
||||
|
|
@ -111,16 +127,23 @@ impl CursorIcon {
|
|||
CursorIcon::Crosshair => winuser::IDC_CROSS,
|
||||
CursorIcon::Text | CursorIcon::VerticalText => winuser::IDC_IBEAM,
|
||||
CursorIcon::NotAllowed | CursorIcon::NoDrop => winuser::IDC_NO,
|
||||
CursorIcon::Grab | CursorIcon::Grabbing |
|
||||
CursorIcon::Move | CursorIcon::AllScroll => winuser::IDC_SIZEALL,
|
||||
CursorIcon::EResize | CursorIcon::WResize |
|
||||
CursorIcon::EwResize | CursorIcon::ColResize => winuser::IDC_SIZEWE,
|
||||
CursorIcon::NResize | CursorIcon::SResize |
|
||||
CursorIcon::NsResize | CursorIcon::RowResize => winuser::IDC_SIZENS,
|
||||
CursorIcon::NeResize | CursorIcon::SwResize |
|
||||
CursorIcon::NeswResize => winuser::IDC_SIZENESW,
|
||||
CursorIcon::NwResize | CursorIcon::SeResize |
|
||||
CursorIcon::NwseResize => winuser::IDC_SIZENWSE,
|
||||
CursorIcon::Grab | CursorIcon::Grabbing | CursorIcon::Move | CursorIcon::AllScroll => {
|
||||
winuser::IDC_SIZEALL
|
||||
},
|
||||
CursorIcon::EResize
|
||||
| CursorIcon::WResize
|
||||
| CursorIcon::EwResize
|
||||
| CursorIcon::ColResize => winuser::IDC_SIZEWE,
|
||||
CursorIcon::NResize
|
||||
| CursorIcon::SResize
|
||||
| CursorIcon::NsResize
|
||||
| CursorIcon::RowResize => winuser::IDC_SIZENS,
|
||||
CursorIcon::NeResize | CursorIcon::SwResize | CursorIcon::NeswResize => {
|
||||
winuser::IDC_SIZENESW
|
||||
},
|
||||
CursorIcon::NwResize | CursorIcon::SeResize | CursorIcon::NwseResize => {
|
||||
winuser::IDC_SIZENWSE
|
||||
},
|
||||
CursorIcon::Wait => winuser::IDC_WAIT,
|
||||
CursorIcon::Progress => winuser::IDC_APPSTARTING,
|
||||
CursorIcon::Help => winuser::IDC_HELP,
|
||||
|
|
|
|||
|
|
@ -1,37 +1,52 @@
|
|||
#![cfg(target_os = "windows")]
|
||||
|
||||
use std::{io, mem, ptr};
|
||||
use std::cell::Cell;
|
||||
use std::ffi::OsStr;
|
||||
use std::os::windows::ffi::OsStrExt;
|
||||
use std::sync::Arc;
|
||||
use std::sync::mpsc::channel;
|
||||
use parking_lot::Mutex;
|
||||
use std::{
|
||||
cell::Cell,
|
||||
ffi::OsStr,
|
||||
io, mem,
|
||||
os::windows::ffi::OsStrExt,
|
||||
ptr,
|
||||
sync::{mpsc::channel, Arc},
|
||||
};
|
||||
|
||||
use winapi::ctypes::c_int;
|
||||
use winapi::shared::minwindef::{DWORD, LPARAM, UINT, WORD, WPARAM};
|
||||
use winapi::shared::windef::{HWND, POINT, RECT};
|
||||
use winapi::um::{combaseapi, dwmapi, libloaderapi, ole2, winuser};
|
||||
use winapi::um::objbase::COINIT_APARTMENTTHREADED;
|
||||
use winapi::um::shobjidl_core::{CLSID_TaskbarList, ITaskbarList2};
|
||||
use winapi::um::wingdi::{CreateRectRgn, DeleteObject};
|
||||
use winapi::um::oleidl::LPDROPTARGET;
|
||||
use winapi::um::winnt::{LONG, LPCWSTR};
|
||||
use winapi::{
|
||||
ctypes::c_int,
|
||||
shared::{
|
||||
minwindef::{DWORD, LPARAM, UINT, WORD, WPARAM},
|
||||
windef::{HWND, POINT, RECT},
|
||||
},
|
||||
um::{
|
||||
combaseapi, dwmapi, libloaderapi,
|
||||
objbase::COINIT_APARTMENTTHREADED,
|
||||
ole2,
|
||||
oleidl::LPDROPTARGET,
|
||||
shobjidl_core::{CLSID_TaskbarList, ITaskbarList2},
|
||||
wingdi::{CreateRectRgn, DeleteObject},
|
||||
winnt::{LONG, LPCWSTR},
|
||||
winuser,
|
||||
},
|
||||
};
|
||||
|
||||
use crate::window::{Icon, CursorIcon, WindowAttributes};
|
||||
use crate::error::{ExternalError, NotSupportedError, OsError as RootOsError};
|
||||
use crate::dpi::{LogicalPosition, LogicalSize, PhysicalSize};
|
||||
use crate::monitor::MonitorHandle as RootMonitorHandle;
|
||||
use crate::platform_impl::platform::{
|
||||
{PlatformSpecificWindowBuilderAttributes, WindowId},
|
||||
dpi::{dpi_to_scale_factor, hwnd_dpi},
|
||||
drop_handler::FileDropHandler,
|
||||
event_loop::{self, EventLoopWindowTarget, DESTROY_MSG_ID, INITIAL_DPI_MSG_ID, REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID},
|
||||
icon::{self, IconType, WinIcon},
|
||||
monitor,
|
||||
raw_input::register_all_mice_and_keyboards_for_raw_input,
|
||||
util,
|
||||
window_state::{CursorFlags, SavedWindow, WindowFlags, WindowState},
|
||||
use crate::{
|
||||
dpi::{LogicalPosition, LogicalSize, PhysicalSize},
|
||||
error::{ExternalError, NotSupportedError, OsError as RootOsError},
|
||||
monitor::MonitorHandle as RootMonitorHandle,
|
||||
platform_impl::platform::{
|
||||
dpi::{dpi_to_scale_factor, hwnd_dpi},
|
||||
drop_handler::FileDropHandler,
|
||||
event_loop::{
|
||||
self, EventLoopWindowTarget, DESTROY_MSG_ID, INITIAL_DPI_MSG_ID,
|
||||
REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID,
|
||||
},
|
||||
icon::{self, IconType, WinIcon},
|
||||
monitor,
|
||||
raw_input::register_all_mice_and_keyboards_for_raw_input,
|
||||
util,
|
||||
window_state::{CursorFlags, SavedWindow, WindowFlags, WindowState},
|
||||
PlatformSpecificWindowBuilderAttributes, WindowId,
|
||||
},
|
||||
window::{CursorIcon, Icon, WindowAttributes},
|
||||
};
|
||||
|
||||
/// The Win32 implementation of the main `Window` object.
|
||||
|
|
@ -73,11 +88,19 @@ impl Window {
|
|||
let file_drop_runner = event_loop.runner_shared.clone();
|
||||
let file_drop_handler = FileDropHandler::new(
|
||||
win.window.0,
|
||||
Box::new(move |event| if let Ok(e) = event.map_nonuser_event() {file_drop_runner.send_event(e)})
|
||||
Box::new(move |event| {
|
||||
if let Ok(e) = event.map_nonuser_event() {
|
||||
file_drop_runner.send_event(e)
|
||||
}
|
||||
}),
|
||||
);
|
||||
let handler_interface_ptr = &mut (*file_drop_handler.data).interface as LPDROPTARGET;
|
||||
let handler_interface_ptr =
|
||||
&mut (*file_drop_handler.data).interface as LPDROPTARGET;
|
||||
|
||||
assert_eq!(ole2::RegisterDragDrop(win.window.0, handler_interface_ptr), S_OK);
|
||||
assert_eq!(
|
||||
ole2::RegisterDragDrop(win.window.0, handler_interface_ptr),
|
||||
S_OK
|
||||
);
|
||||
file_drop_handler
|
||||
};
|
||||
|
||||
|
|
@ -106,8 +129,12 @@ impl Window {
|
|||
#[inline]
|
||||
pub fn set_visible(&self, visible: bool) {
|
||||
match visible {
|
||||
true => unsafe { winuser::ShowWindow(self.window.0, winuser::SW_SHOW); },
|
||||
false => unsafe { winuser::ShowWindow(self.window.0, winuser::SW_HIDE); },
|
||||
true => unsafe {
|
||||
winuser::ShowWindow(self.window.0, winuser::SW_SHOW);
|
||||
},
|
||||
false => unsafe {
|
||||
winuser::ShowWindow(self.window.0, winuser::SW_HIDE);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -119,7 +146,7 @@ impl Window {
|
|||
self.window.0,
|
||||
ptr::null(),
|
||||
ptr::null_mut(),
|
||||
winuser::RDW_INTERNALPAINT
|
||||
winuser::RDW_INTERNALPAINT,
|
||||
);
|
||||
} else {
|
||||
winuser::PostMessageW(self.window.0, *REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID, 0, 0);
|
||||
|
|
@ -137,7 +164,10 @@ impl Window {
|
|||
pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||
let physical_position = self.outer_position_physical();
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
Ok(LogicalPosition::from_physical(physical_position, dpi_factor))
|
||||
Ok(LogicalPosition::from_physical(
|
||||
physical_position,
|
||||
dpi_factor,
|
||||
))
|
||||
}
|
||||
|
||||
pub(crate) fn inner_position_physical(&self) -> (i32, i32) {
|
||||
|
|
@ -152,7 +182,10 @@ impl Window {
|
|||
pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||
let physical_position = self.inner_position_physical();
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
Ok(LogicalPosition::from_physical(physical_position, dpi_factor))
|
||||
Ok(LogicalPosition::from_physical(
|
||||
physical_position,
|
||||
dpi_factor,
|
||||
))
|
||||
}
|
||||
|
||||
pub(crate) fn set_position_physical(&self, x: i32, y: i32) {
|
||||
|
|
@ -197,10 +230,12 @@ impl Window {
|
|||
|
||||
pub(crate) fn outer_size_physical(&self) -> (u32, u32) {
|
||||
util::get_window_rect(self.window.0)
|
||||
.map(|rect| (
|
||||
(rect.right - rect.left) as u32,
|
||||
(rect.bottom - rect.top) as u32,
|
||||
))
|
||||
.map(|rect| {
|
||||
(
|
||||
(rect.right - rect.left) as u32,
|
||||
(rect.bottom - rect.top) as u32,
|
||||
)
|
||||
})
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
|
|
@ -220,8 +255,9 @@ impl Window {
|
|||
left: 0,
|
||||
bottom: y as LONG,
|
||||
right: x as LONG,
|
||||
}
|
||||
).expect("adjust_window_rect failed");
|
||||
},
|
||||
)
|
||||
.expect("adjust_window_rect failed");
|
||||
|
||||
let outer_x = (rect.right - rect.left).abs() as c_int;
|
||||
let outer_y = (rect.top - rect.bottom).abs() as c_int;
|
||||
|
|
@ -233,9 +269,9 @@ impl Window {
|
|||
outer_x,
|
||||
outer_y,
|
||||
winuser::SWP_ASYNCWINDOWPOS
|
||||
| winuser::SWP_NOZORDER
|
||||
| winuser::SWP_NOREPOSITION
|
||||
| winuser::SWP_NOMOVE,
|
||||
| winuser::SWP_NOZORDER
|
||||
| winuser::SWP_NOREPOSITION
|
||||
| winuser::SWP_NOMOVE,
|
||||
);
|
||||
winuser::UpdateWindow(self.window.0);
|
||||
}
|
||||
|
|
@ -286,12 +322,9 @@ impl Window {
|
|||
let window_state = Arc::clone(&self.window_state);
|
||||
|
||||
self.thread_executor.execute_in_thread(move || {
|
||||
WindowState::set_window_flags(
|
||||
window_state.lock(),
|
||||
window.0,
|
||||
None,
|
||||
|f| f.set(WindowFlags::RESIZABLE, resizable),
|
||||
);
|
||||
WindowState::set_window_flags(window_state.lock(), window.0, None, |f| {
|
||||
f.set(WindowFlags::RESIZABLE, resizable)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -305,10 +338,7 @@ impl Window {
|
|||
pub fn set_cursor_icon(&self, cursor: CursorIcon) {
|
||||
self.window_state.lock().mouse.cursor = cursor;
|
||||
self.thread_executor.execute_in_thread(move || unsafe {
|
||||
let cursor = winuser::LoadCursorW(
|
||||
ptr::null_mut(),
|
||||
cursor.to_windows_cursor(),
|
||||
);
|
||||
let cursor = winuser::LoadCursorW(ptr::null_mut(), cursor.to_windows_cursor());
|
||||
winuser::SetCursor(cursor);
|
||||
});
|
||||
}
|
||||
|
|
@ -320,7 +350,9 @@ impl Window {
|
|||
let (tx, rx) = channel();
|
||||
|
||||
self.thread_executor.execute_in_thread(move || {
|
||||
let result = window_state.lock().mouse
|
||||
let result = window_state
|
||||
.lock()
|
||||
.mouse
|
||||
.set_cursor_flags(window.0, |f| f.set(CursorFlags::GRABBED, grab))
|
||||
.map_err(|e| ExternalError::Os(os_error!(e)));
|
||||
let _ = tx.send(result);
|
||||
|
|
@ -335,7 +367,9 @@ impl Window {
|
|||
let (tx, rx) = channel();
|
||||
|
||||
self.thread_executor.execute_in_thread(move || {
|
||||
let result = window_state.lock().mouse
|
||||
let result = window_state
|
||||
.lock()
|
||||
.mouse
|
||||
.set_cursor_flags(window.0, |f| f.set(CursorFlags::HIDDEN, !visible))
|
||||
.map_err(|e| e.to_string());
|
||||
let _ = tx.send(result);
|
||||
|
|
@ -362,7 +396,10 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_position(&self, logical_position: LogicalPosition) -> Result<(), ExternalError> {
|
||||
pub fn set_cursor_position(
|
||||
&self,
|
||||
logical_position: LogicalPosition,
|
||||
) -> Result<(), ExternalError> {
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
let (x, y) = logical_position.to_physical(dpi_factor).into();
|
||||
self.set_cursor_position_physical(x, y)
|
||||
|
|
@ -379,12 +416,9 @@ impl Window {
|
|||
let window_state = Arc::clone(&self.window_state);
|
||||
|
||||
self.thread_executor.execute_in_thread(move || {
|
||||
WindowState::set_window_flags(
|
||||
window_state.lock(),
|
||||
window.0,
|
||||
None,
|
||||
|f| f.set(WindowFlags::MAXIMIZED, maximized),
|
||||
);
|
||||
WindowState::set_window_flags(window_state.lock(), window.0, None, |f| {
|
||||
f.set(WindowFlags::MAXIMIZED, maximized)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -409,10 +443,11 @@ impl Window {
|
|||
self.thread_executor.execute_in_thread(move || {
|
||||
let mut window_state_lock = window_state.lock();
|
||||
|
||||
let client_rect = util::get_client_rect(window.0).expect("get client rect failed!");
|
||||
let client_rect =
|
||||
util::get_client_rect(window.0).expect("get client rect failed!");
|
||||
window_state_lock.saved_window = Some(SavedWindow {
|
||||
client_rect,
|
||||
dpi_factor: window_state_lock.dpi_factor
|
||||
dpi_factor: window_state_lock.dpi_factor,
|
||||
});
|
||||
|
||||
window_state_lock.fullscreen = monitor.take();
|
||||
|
|
@ -424,31 +459,35 @@ impl Window {
|
|||
top: y,
|
||||
right: x + width as c_int,
|
||||
bottom: y + height as c_int,
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
mark_fullscreen(window.0, true);
|
||||
});
|
||||
}
|
||||
},
|
||||
&None => {
|
||||
self.thread_executor.execute_in_thread(move || {
|
||||
let mut window_state_lock = window_state.lock();
|
||||
window_state_lock.fullscreen = None;
|
||||
|
||||
if let Some(SavedWindow{client_rect, dpi_factor}) = window_state_lock.saved_window {
|
||||
if let Some(SavedWindow {
|
||||
client_rect,
|
||||
dpi_factor,
|
||||
}) = window_state_lock.saved_window
|
||||
{
|
||||
window_state_lock.dpi_factor = dpi_factor;
|
||||
window_state_lock.saved_window = None;
|
||||
|
||||
WindowState::refresh_window_state(
|
||||
window_state_lock,
|
||||
window.0,
|
||||
Some(client_rect)
|
||||
Some(client_rect),
|
||||
);
|
||||
}
|
||||
|
||||
mark_fullscreen(window.0, false);
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -460,12 +499,9 @@ impl Window {
|
|||
|
||||
self.thread_executor.execute_in_thread(move || {
|
||||
let client_rect = util::get_client_rect(window.0).expect("get client rect failed!");
|
||||
WindowState::set_window_flags(
|
||||
window_state.lock(),
|
||||
window.0,
|
||||
Some(client_rect),
|
||||
|f| f.set(WindowFlags::DECORATIONS, decorations),
|
||||
);
|
||||
WindowState::set_window_flags(window_state.lock(), window.0, Some(client_rect), |f| {
|
||||
f.set(WindowFlags::DECORATIONS, decorations)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -475,12 +511,9 @@ impl Window {
|
|||
let window_state = Arc::clone(&self.window_state);
|
||||
|
||||
self.thread_executor.execute_in_thread(move || {
|
||||
WindowState::set_window_flags(
|
||||
window_state.lock(),
|
||||
window.0,
|
||||
None,
|
||||
|f| f.set(WindowFlags::ALWAYS_ON_TOP, always_on_top),
|
||||
);
|
||||
WindowState::set_window_flags(window_state.lock(), window.0, None, |f| {
|
||||
f.set(WindowFlags::ALWAYS_ON_TOP, always_on_top)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -573,9 +606,7 @@ unsafe fn init<T: 'static>(
|
|||
.collect::<Vec<_>>();
|
||||
|
||||
let window_icon = {
|
||||
let icon = attributes.window_icon
|
||||
.take()
|
||||
.map(WinIcon::from_icon);
|
||||
let icon = attributes.window_icon.take().map(WinIcon::from_icon);
|
||||
if let Some(icon) = icon {
|
||||
Some(icon.map_err(|e| os_error!(e))?)
|
||||
} else {
|
||||
|
|
@ -583,9 +614,7 @@ unsafe fn init<T: 'static>(
|
|||
}
|
||||
};
|
||||
let taskbar_icon = {
|
||||
let icon = attributes.window_icon
|
||||
.take()
|
||||
.map(WinIcon::from_icon);
|
||||
let icon = attributes.window_icon.take().map(WinIcon::from_icon);
|
||||
if let Some(icon) = icon {
|
||||
Some(icon.map_err(|e| os_error!(e))?)
|
||||
} else {
|
||||
|
|
@ -607,7 +636,10 @@ unsafe fn init<T: 'static>(
|
|||
}
|
||||
dpi_factor
|
||||
} else {
|
||||
return Err(os_error!(io::Error::new(io::ErrorKind::NotFound, "No monitors were detected.")));
|
||||
return Err(os_error!(io::Error::new(
|
||||
io::ErrorKind::NotFound,
|
||||
"No monitors were detected."
|
||||
)));
|
||||
};
|
||||
dpi_factor.unwrap_or_else(|| {
|
||||
util::get_cursor_pos()
|
||||
|
|
@ -631,7 +663,10 @@ unsafe fn init<T: 'static>(
|
|||
let mut window_flags = WindowFlags::empty();
|
||||
window_flags.set(WindowFlags::DECORATIONS, attributes.decorations);
|
||||
window_flags.set(WindowFlags::ALWAYS_ON_TOP, attributes.always_on_top);
|
||||
window_flags.set(WindowFlags::NO_BACK_BUFFER, pl_attribs.no_redirection_bitmap);
|
||||
window_flags.set(
|
||||
WindowFlags::NO_BACK_BUFFER,
|
||||
pl_attribs.no_redirection_bitmap,
|
||||
);
|
||||
window_flags.set(WindowFlags::TRANSPARENT, attributes.transparent);
|
||||
// WindowFlags::VISIBLE and MAXIMIZED are set down below after the window has been configured.
|
||||
window_flags.set(WindowFlags::RESIZABLE, attributes.resizable);
|
||||
|
|
@ -646,8 +681,10 @@ unsafe fn init<T: 'static>(
|
|||
class_name.as_ptr(),
|
||||
title.as_ptr() as LPCWSTR,
|
||||
style,
|
||||
winuser::CW_USEDEFAULT, winuser::CW_USEDEFAULT,
|
||||
winuser::CW_USEDEFAULT, winuser::CW_USEDEFAULT,
|
||||
winuser::CW_USEDEFAULT,
|
||||
winuser::CW_USEDEFAULT,
|
||||
winuser::CW_USEDEFAULT,
|
||||
winuser::CW_USEDEFAULT,
|
||||
pl_attribs.parent.unwrap_or(ptr::null_mut()),
|
||||
ptr::null_mut(),
|
||||
libloaderapi::GetModuleHandleW(ptr::null()),
|
||||
|
|
@ -666,9 +703,9 @@ unsafe fn init<T: 'static>(
|
|||
|
||||
// Register for touch events if applicable
|
||||
{
|
||||
let digitizer = winuser::GetSystemMetrics( winuser::SM_DIGITIZER ) as u32;
|
||||
let digitizer = winuser::GetSystemMetrics(winuser::SM_DIGITIZER) as u32;
|
||||
if digitizer & winuser::NID_READY != 0 {
|
||||
winuser::RegisterTouchWindow( real_window.0, winuser::TWF_WANTPALM );
|
||||
winuser::RegisterTouchWindow(real_window.0, winuser::TWF_WANTPALM);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -712,7 +749,12 @@ unsafe fn init<T: 'static>(
|
|||
// The color key can be any value except for black (0x0).
|
||||
let color_key = 0x0030c100;
|
||||
|
||||
winuser::SetLayeredWindowAttributes(real_window.0, color_key, opacity, winuser::LWA_ALPHA);
|
||||
winuser::SetLayeredWindowAttributes(
|
||||
real_window.0,
|
||||
color_key,
|
||||
opacity,
|
||||
winuser::LWA_ALPHA,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -720,19 +762,11 @@ unsafe fn init<T: 'static>(
|
|||
window_flags.set(WindowFlags::MAXIMIZED, attributes.maximized);
|
||||
|
||||
let window_state = {
|
||||
let window_state = WindowState::new(
|
||||
&attributes,
|
||||
window_icon,
|
||||
taskbar_icon,
|
||||
dpi_factor,
|
||||
);
|
||||
let window_state = WindowState::new(&attributes, window_icon, taskbar_icon, dpi_factor);
|
||||
let window_state = Arc::new(Mutex::new(window_state));
|
||||
WindowState::set_window_flags(
|
||||
window_state.lock(),
|
||||
real_window.0,
|
||||
None,
|
||||
|f| *f = window_flags,
|
||||
);
|
||||
WindowState::set_window_flags(window_state.lock(), real_window.0, None, |f| {
|
||||
*f = window_flags
|
||||
});
|
||||
window_state
|
||||
};
|
||||
|
||||
|
|
@ -803,7 +837,7 @@ impl Drop for ComInitialized {
|
|||
}
|
||||
}
|
||||
|
||||
thread_local!{
|
||||
thread_local! {
|
||||
static COM_INITIALIZED: ComInitialized = {
|
||||
unsafe {
|
||||
combaseapi::CoInitializeEx(ptr::null_mut(), COINIT_APARTMENTTHREADED);
|
||||
|
|
@ -833,8 +867,7 @@ unsafe fn mark_fullscreen(handle: HWND, fullscreen: bool) {
|
|||
let mut task_bar_list = task_bar_list_ptr.get();
|
||||
|
||||
if task_bar_list == ptr::null_mut() {
|
||||
use winapi::shared::winerror::S_OK;
|
||||
use winapi::Interface;
|
||||
use winapi::{shared::winerror::S_OK, Interface};
|
||||
|
||||
let hr = combaseapi::CoCreateInstance(
|
||||
&CLSID_TaskbarList,
|
||||
|
|
|
|||
|
|
@ -1,13 +1,18 @@
|
|||
use crate::monitor::MonitorHandle;
|
||||
use crate::window::{CursorIcon, WindowAttributes};
|
||||
use std::{io, ptr};
|
||||
use crate::{
|
||||
dpi::LogicalSize,
|
||||
monitor::MonitorHandle,
|
||||
platform_impl::platform::{event_loop, icon::WinIcon, util},
|
||||
window::{CursorIcon, WindowAttributes},
|
||||
};
|
||||
use parking_lot::MutexGuard;
|
||||
use crate::dpi::LogicalSize;
|
||||
use crate::platform_impl::platform::{util, event_loop};
|
||||
use crate::platform_impl::platform::icon::WinIcon;
|
||||
use winapi::shared::windef::{RECT, HWND};
|
||||
use winapi::shared::minwindef::DWORD;
|
||||
use winapi::um::winuser;
|
||||
use std::{io, ptr};
|
||||
use winapi::{
|
||||
shared::{
|
||||
minwindef::DWORD,
|
||||
windef::{HWND, RECT},
|
||||
},
|
||||
um::winuser,
|
||||
};
|
||||
|
||||
/// Contains information about states and the window that the callback is going to use.
|
||||
#[derive(Clone)]
|
||||
|
|
@ -86,7 +91,7 @@ impl WindowState {
|
|||
attributes: &WindowAttributes,
|
||||
window_icon: Option<WinIcon>,
|
||||
taskbar_icon: Option<WinIcon>,
|
||||
dpi_factor: f64
|
||||
dpi_factor: f64,
|
||||
) -> WindowState {
|
||||
WindowState {
|
||||
mouse: MouseProperties {
|
||||
|
|
@ -105,7 +110,7 @@ impl WindowState {
|
|||
dpi_factor,
|
||||
|
||||
fullscreen: None,
|
||||
window_flags: WindowFlags::empty()
|
||||
window_flags: WindowFlags::empty(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -113,26 +118,37 @@ impl WindowState {
|
|||
self.window_flags
|
||||
}
|
||||
|
||||
pub fn set_window_flags<F>(mut this: MutexGuard<'_, Self>, window: HWND, set_client_rect: Option<RECT>, f: F)
|
||||
where F: FnOnce(&mut WindowFlags)
|
||||
pub fn set_window_flags<F>(
|
||||
mut this: MutexGuard<'_, Self>,
|
||||
window: HWND,
|
||||
set_client_rect: Option<RECT>,
|
||||
f: F,
|
||||
) where
|
||||
F: FnOnce(&mut WindowFlags),
|
||||
{
|
||||
let old_flags = this.window_flags;
|
||||
f(&mut this.window_flags);
|
||||
|
||||
let is_fullscreen = this.fullscreen.is_some();
|
||||
this.window_flags.set(WindowFlags::MARKER_FULLSCREEN, is_fullscreen);
|
||||
this.window_flags
|
||||
.set(WindowFlags::MARKER_FULLSCREEN, is_fullscreen);
|
||||
let new_flags = this.window_flags;
|
||||
|
||||
drop(this);
|
||||
old_flags.apply_diff(window, new_flags, set_client_rect);
|
||||
}
|
||||
|
||||
pub fn refresh_window_state(this: MutexGuard<'_, Self>, window: HWND, set_client_rect: Option<RECT>) {
|
||||
pub fn refresh_window_state(
|
||||
this: MutexGuard<'_, Self>,
|
||||
window: HWND,
|
||||
set_client_rect: Option<RECT>,
|
||||
) {
|
||||
Self::set_window_flags(this, window, set_client_rect, |_| ());
|
||||
}
|
||||
|
||||
pub fn set_window_flags_in_place<F>(&mut self, f: F)
|
||||
where F: FnOnce(&mut WindowFlags)
|
||||
where
|
||||
F: FnOnce(&mut WindowFlags),
|
||||
{
|
||||
f(&mut self.window_flags);
|
||||
}
|
||||
|
|
@ -144,7 +160,8 @@ impl MouseProperties {
|
|||
}
|
||||
|
||||
pub fn set_cursor_flags<F>(&mut self, window: HWND, f: F) -> Result<(), io::Error>
|
||||
where F: FnOnce(&mut CursorFlags)
|
||||
where
|
||||
F: FnOnce(&mut CursorFlags),
|
||||
{
|
||||
let old_flags = self.cursor_flags;
|
||||
f(&mut self.cursor_flags);
|
||||
|
|
@ -153,7 +170,7 @@ impl MouseProperties {
|
|||
Err(e) => {
|
||||
self.cursor_flags = old_flags;
|
||||
return Err(e);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
@ -229,8 +246,8 @@ impl WindowFlags {
|
|||
window,
|
||||
match new.contains(WindowFlags::VISIBLE) {
|
||||
true => winuser::SW_SHOW,
|
||||
false => winuser::SW_HIDE
|
||||
}
|
||||
false => winuser::SW_HIDE,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -239,10 +256,13 @@ impl WindowFlags {
|
|||
winuser::SetWindowPos(
|
||||
window,
|
||||
match new.contains(WindowFlags::ALWAYS_ON_TOP) {
|
||||
true => winuser::HWND_TOPMOST,
|
||||
true => winuser::HWND_TOPMOST,
|
||||
false => winuser::HWND_NOTOPMOST,
|
||||
},
|
||||
0, 0, 0, 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
winuser::SWP_ASYNCWINDOWPOS | winuser::SWP_NOMOVE | winuser::SWP_NOSIZE,
|
||||
);
|
||||
winuser::UpdateWindow(window);
|
||||
|
|
@ -255,8 +275,8 @@ impl WindowFlags {
|
|||
window,
|
||||
match new.contains(WindowFlags::MAXIMIZED) {
|
||||
true => winuser::SW_MAXIMIZE,
|
||||
false => winuser::SW_RESTORE
|
||||
}
|
||||
false => winuser::SW_RESTORE,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -270,7 +290,9 @@ impl WindowFlags {
|
|||
winuser::SetWindowLongW(window, winuser::GWL_STYLE, style as _);
|
||||
winuser::SetWindowLongW(window, winuser::GWL_EXSTYLE, style_ex as _);
|
||||
|
||||
match set_client_rect.and_then(|r| util::adjust_window_rect_with_styles(window, style, style_ex, r)) {
|
||||
match set_client_rect
|
||||
.and_then(|r| util::adjust_window_rect_with_styles(window, style, style_ex, r))
|
||||
{
|
||||
Some(client_rect) => {
|
||||
let (x, y, w, h) = (
|
||||
client_rect.left,
|
||||
|
|
@ -281,9 +303,11 @@ impl WindowFlags {
|
|||
winuser::SetWindowPos(
|
||||
window,
|
||||
ptr::null_mut(),
|
||||
x, y, w, h,
|
||||
winuser::SWP_NOZORDER
|
||||
| winuser::SWP_FRAMECHANGED,
|
||||
x,
|
||||
y,
|
||||
w,
|
||||
h,
|
||||
winuser::SWP_NOZORDER | winuser::SWP_FRAMECHANGED,
|
||||
);
|
||||
},
|
||||
None => {
|
||||
|
|
@ -291,13 +315,16 @@ impl WindowFlags {
|
|||
winuser::SetWindowPos(
|
||||
window,
|
||||
ptr::null_mut(),
|
||||
0, 0, 0, 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
winuser::SWP_NOZORDER
|
||||
| winuser::SWP_NOMOVE
|
||||
| winuser::SWP_NOSIZE
|
||||
| winuser::SWP_FRAMECHANGED,
|
||||
| winuser::SWP_NOMOVE
|
||||
| winuser::SWP_NOSIZE
|
||||
| winuser::SWP_FRAMECHANGED,
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
winuser::SendMessageW(window, *event_loop::SET_RETAIN_STATE_ON_SIZE_MSG_ID, 0, 0);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue