Merge pull request #97 from BillyDM/master
send initial window resized event in x11
This commit is contained in:
commit
e7a6c661ef
|
@ -6,15 +6,16 @@ use winapi::um::winuser::{
|
||||||
AdjustWindowRectEx, CreateWindowExW, DefWindowProcW, DispatchMessageW,
|
AdjustWindowRectEx, CreateWindowExW, DefWindowProcW, DispatchMessageW,
|
||||||
GetMessageW, GetWindowLongPtrW, PostMessageW, RegisterClassW, SetTimer,
|
GetMessageW, GetWindowLongPtrW, PostMessageW, RegisterClassW, SetTimer,
|
||||||
SetWindowLongPtrW, TranslateMessage, UnregisterClassW, LoadCursorW,
|
SetWindowLongPtrW, TranslateMessage, UnregisterClassW, LoadCursorW,
|
||||||
DestroyWindow,
|
DestroyWindow, SetProcessDpiAwarenessContext, SetWindowPos,
|
||||||
|
GetDpiForWindow,
|
||||||
CS_OWNDC, GWLP_USERDATA, IDC_ARROW,
|
CS_OWNDC, GWLP_USERDATA, IDC_ARROW,
|
||||||
MSG, WM_CLOSE, WM_CREATE, WM_MOUSEMOVE, WM_SHOWWINDOW, WM_TIMER, WM_NCDESTROY,
|
MSG, WM_CLOSE, WM_CREATE, WM_MOUSEMOVE, WM_SHOWWINDOW, WM_TIMER, WM_NCDESTROY,
|
||||||
WNDCLASSW, WS_CAPTION, WS_CHILD, WS_CLIPSIBLINGS, WS_MAXIMIZEBOX, WS_MINIMIZEBOX,
|
WNDCLASSW, WS_CAPTION, WS_CHILD, WS_CLIPSIBLINGS, WS_MAXIMIZEBOX, WS_MINIMIZEBOX,
|
||||||
WS_POPUPWINDOW, WS_SIZEBOX, WS_VISIBLE, WM_DPICHANGED, WM_CHAR, WM_SYSCHAR, WM_KEYDOWN,
|
WS_POPUPWINDOW, WS_SIZEBOX, WS_VISIBLE, WM_DPICHANGED, WM_CHAR, WM_SYSCHAR, WM_KEYDOWN,
|
||||||
WM_SYSKEYDOWN, WM_KEYUP, WM_SYSKEYUP, WM_INPUTLANGCHANGE,
|
WM_SYSKEYDOWN, WM_KEYUP, WM_SYSKEYUP, WM_INPUTLANGCHANGE, WM_SIZE,
|
||||||
GET_XBUTTON_WPARAM, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP,
|
GET_XBUTTON_WPARAM, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP,
|
||||||
WM_RBUTTONDOWN, WM_RBUTTONUP, WM_XBUTTONDOWN, WM_XBUTTONUP, XBUTTON1, XBUTTON2,
|
WM_RBUTTONDOWN, WM_RBUTTONUP, WM_XBUTTONDOWN, WM_XBUTTONUP, XBUTTON1, XBUTTON2,
|
||||||
SetCapture, GetCapture, ReleaseCapture, IsWindow,
|
SetCapture, GetCapture, ReleaseCapture, IsWindow, SWP_NOZORDER, SWP_NOMOVE
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
@ -30,7 +31,7 @@ use raw_window_handle::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Event, MouseButton, MouseEvent, WindowEvent,
|
Event, MouseButton, MouseEvent, WindowEvent,
|
||||||
WindowHandler, WindowInfo, WindowOpenOptions, WindowScalePolicy, PhyPoint,
|
WindowHandler, WindowInfo, WindowOpenOptions, WindowScalePolicy, PhyPoint, PhySize
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::keyboard::KeyboardState;
|
use super::keyboard::KeyboardState;
|
||||||
|
@ -152,9 +153,6 @@ unsafe extern "system" fn wnd_proc(
|
||||||
// return 0;
|
// return 0;
|
||||||
return DefWindowProcW(hwnd, msg, wparam, lparam);
|
return DefWindowProcW(hwnd, msg, wparam, lparam);
|
||||||
}
|
}
|
||||||
WM_DPICHANGED => {
|
|
||||||
// TODO: Notify app of DPI change
|
|
||||||
},
|
|
||||||
WM_CHAR | WM_SYSCHAR | WM_KEYDOWN | WM_SYSKEYDOWN | WM_KEYUP
|
WM_CHAR | WM_SYSCHAR | WM_KEYDOWN | WM_SYSKEYDOWN | WM_KEYUP
|
||||||
| WM_SYSKEYUP | WM_INPUTLANGCHANGE => {
|
| WM_SYSKEYUP | WM_INPUTLANGCHANGE => {
|
||||||
let opt_event = (&*window_state_ptr).borrow_mut()
|
let opt_event = (&*window_state_ptr).borrow_mut()
|
||||||
|
@ -171,6 +169,70 @@ unsafe extern "system" fn wnd_proc(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
WM_SIZE => {
|
||||||
|
let width = (lparam & 0xFFFF) as u16 as u32;
|
||||||
|
let height = ((lparam >> 16) & 0xFFFF) as u16 as u32;
|
||||||
|
|
||||||
|
let mut window_state = (&*window_state_ptr).borrow_mut();
|
||||||
|
|
||||||
|
window_state.window_info = WindowInfo::from_physical_size(
|
||||||
|
PhySize { width, height },
|
||||||
|
window_state.window_info.scale(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let window_info = window_state.window_info;
|
||||||
|
|
||||||
|
window_state.handler.on_event(
|
||||||
|
&mut window,
|
||||||
|
Event::Window(WindowEvent::Resized(window_info)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
WM_DPICHANGED => {
|
||||||
|
// To avoid weirdness with the realtime borrow checker.
|
||||||
|
let new_rect = {
|
||||||
|
let mut window_state = (&*window_state_ptr).borrow_mut();
|
||||||
|
|
||||||
|
if let WindowScalePolicy::SystemScaleFactor = window_state.scale_policy {
|
||||||
|
let dpi = (wparam & 0xFFFF) as u16 as u32;
|
||||||
|
let scale_factor = dpi as f64 / 96.0;
|
||||||
|
|
||||||
|
window_state.window_info = WindowInfo::from_logical_size(
|
||||||
|
window_state.window_info.logical_size(),
|
||||||
|
scale_factor,
|
||||||
|
);
|
||||||
|
|
||||||
|
Some((
|
||||||
|
RECT {
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
// todo: check if usize fits into i32
|
||||||
|
right: window_state.window_info.physical_size().width as i32,
|
||||||
|
bottom: window_state.window_info.physical_size().height as i32,
|
||||||
|
},
|
||||||
|
window_state.dw_style,
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if let Some((mut new_rect, dw_style)) = new_rect {
|
||||||
|
// Convert this desired "client rectangle" size to the actual "window rectangle"
|
||||||
|
// size (Because of course you have to do that).
|
||||||
|
AdjustWindowRectEx(&mut new_rect, dw_style, 0, 0);
|
||||||
|
|
||||||
|
// Windows makes us resize the window manually. This will trigger another `WM_SIZE` event,
|
||||||
|
// which we can then send the user the new scale factor.
|
||||||
|
SetWindowPos(
|
||||||
|
hwnd,
|
||||||
|
hwnd,
|
||||||
|
new_rect.left as i32,
|
||||||
|
new_rect.top as i32,
|
||||||
|
new_rect.right - new_rect.left,
|
||||||
|
new_rect.bottom - new_rect.top,
|
||||||
|
SWP_NOZORDER | SWP_NOMOVE,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
WM_NCDESTROY => {
|
WM_NCDESTROY => {
|
||||||
let window_state = Box::from_raw(window_state_ptr);
|
let window_state = Box::from_raw(window_state_ptr);
|
||||||
unregister_wnd_class(window_state.borrow().window_class);
|
unregister_wnd_class(window_state.borrow().window_class);
|
||||||
|
@ -219,6 +281,8 @@ struct WindowState {
|
||||||
keyboard_state: KeyboardState,
|
keyboard_state: KeyboardState,
|
||||||
mouse_button_counter: usize,
|
mouse_button_counter: usize,
|
||||||
handler: Box<dyn WindowHandler>,
|
handler: Box<dyn WindowHandler>,
|
||||||
|
scale_policy: WindowScalePolicy,
|
||||||
|
dw_style: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Window {
|
pub struct Window {
|
||||||
|
@ -299,7 +363,7 @@ impl Window {
|
||||||
// todo: manage error ^
|
// todo: manage error ^
|
||||||
|
|
||||||
let scaling = match options.scale {
|
let scaling = match options.scale {
|
||||||
WindowScalePolicy::SystemScaleFactor => get_scaling().unwrap_or(1.0),
|
WindowScalePolicy::SystemScaleFactor => 1.0,
|
||||||
WindowScalePolicy::ScaleFactor(scale) => scale
|
WindowScalePolicy::ScaleFactor(scale) => scale
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -347,17 +411,69 @@ impl Window {
|
||||||
|
|
||||||
let handler = Box::new(build(&mut crate::Window::new(&mut Window { hwnd })));
|
let handler = Box::new(build(&mut crate::Window::new(&mut Window { hwnd })));
|
||||||
|
|
||||||
let window_state = Box::new(RefCell::new(WindowState {
|
let mut window_state = Box::new(RefCell::new(WindowState {
|
||||||
window_class,
|
window_class,
|
||||||
window_info,
|
window_info,
|
||||||
keyboard_state: KeyboardState::new(),
|
keyboard_state: KeyboardState::new(),
|
||||||
mouse_button_counter: 0,
|
mouse_button_counter: 0,
|
||||||
handler,
|
handler,
|
||||||
|
scale_policy: options.scale,
|
||||||
|
dw_style: flags,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// Only works on Windows 10 unfortunately.
|
||||||
|
SetProcessDpiAwarenessContext(
|
||||||
|
winapi::shared::windef::DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Now we can get the actual dpi of the window.
|
||||||
|
let new_rect = if let WindowScalePolicy::SystemScaleFactor = options.scale {
|
||||||
|
// Only works on Windows 10 unfortunately.
|
||||||
|
let dpi = GetDpiForWindow(hwnd);
|
||||||
|
let scale_factor = dpi as f64 / 96.0;
|
||||||
|
|
||||||
|
let mut window_state = window_state.get_mut();
|
||||||
|
if window_state.window_info.scale() != scale_factor {
|
||||||
|
window_state.window_info = WindowInfo::from_logical_size(
|
||||||
|
window_state.window_info.logical_size(),
|
||||||
|
scale_factor,
|
||||||
|
);
|
||||||
|
|
||||||
|
Some(RECT {
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
// todo: check if usize fits into i32
|
||||||
|
right: window_state.window_info.physical_size().width as i32,
|
||||||
|
bottom: window_state.window_info.physical_size().height as i32,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
SetWindowLongPtrW(hwnd, GWLP_USERDATA, Box::into_raw(window_state) as *const _ as _);
|
SetWindowLongPtrW(hwnd, GWLP_USERDATA, Box::into_raw(window_state) as *const _ as _);
|
||||||
SetTimer(hwnd, WIN_FRAME_TIMER, 15, None);
|
SetTimer(hwnd, WIN_FRAME_TIMER, 15, None);
|
||||||
|
|
||||||
|
if let Some(mut new_rect) = new_rect {
|
||||||
|
// Convert this desired"client rectangle" size to the actual "window rectangle"
|
||||||
|
// size (Because of course you have to do that).
|
||||||
|
AdjustWindowRectEx(&mut new_rect, flags, 0, 0);
|
||||||
|
|
||||||
|
// Windows makes us resize the window manually. This will trigger another `WM_SIZE` event,
|
||||||
|
// which we can then send the user the new scale factor.
|
||||||
|
SetWindowPos(
|
||||||
|
hwnd,
|
||||||
|
hwnd,
|
||||||
|
new_rect.left as i32,
|
||||||
|
new_rect.top as i32,
|
||||||
|
new_rect.right - new_rect.left,
|
||||||
|
new_rect.bottom - new_rect.top,
|
||||||
|
SWP_NOZORDER | SWP_NOMOVE,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
hwnd
|
hwnd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -370,9 +486,4 @@ unsafe impl HasRawWindowHandle for Window {
|
||||||
..WindowsHandle::empty()
|
..WindowsHandle::empty()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_scaling() -> Option<f64> {
|
|
||||||
// TODO: find system scaling
|
|
||||||
None
|
|
||||||
}
|
|
|
@ -200,6 +200,13 @@ impl Window {
|
||||||
|
|
||||||
let mut handler = build(&mut crate::Window::new(&mut window));
|
let mut handler = build(&mut crate::Window::new(&mut window));
|
||||||
|
|
||||||
|
// Send an initial window resized event so the user is alerted of
|
||||||
|
// the correct dpi scaling.
|
||||||
|
handler.on_event(
|
||||||
|
&mut crate::Window::new(&mut window),
|
||||||
|
Event::Window(WindowEvent::Resized(window_info))
|
||||||
|
);
|
||||||
|
|
||||||
let _ = tx.send(Ok(SendableRwh(window.raw_window_handle())));
|
let _ = tx.send(Ok(SendableRwh(window.raw_window_handle())));
|
||||||
|
|
||||||
window.run_event_loop(&mut handler);
|
window.run_event_loop(&mut handler);
|
||||||
|
|
Loading…
Reference in a new issue