From df7571b369a6bc502e2abfb5aefcac4e60e94063 Mon Sep 17 00:00:00 2001 From: Osspial Date: Sat, 5 Oct 2019 16:23:30 -0400 Subject: [PATCH] Improve interaction between fullscreen windows and monitor-switching keyboard shortcuts (#1171) * Update to 1.38.0 formatting * Improve fullscreen window monitor switching on Windows * Format --- CHANGELOG.md | 2 ++ src/platform_impl/windows/event_loop.rs | 48 ++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index efbf56e8..ae7eb7ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,8 @@ resulting in `Window::fullscreen` returning the old state in `Resized` events instead of reflecting the new fullscreen state - On X11, fix use-after-free during window creation +- On Windows, disable monitor change keyboard shortcut while in exclusive fullscreen. +- On Windows, ensure that changing a borderless fullscreen window's monitor via keyboard shortcuts keeps the window fullscreen on the new monitor. # 0.20.0 Alpha 3 (2019-08-14) diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 94f7255e..b9a0846a 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -54,13 +54,14 @@ use crate::{ }, drop_handler::FileDropHandler, event::{self, handle_extended_keys, process_key_params, vkey_to_winit_vkey}, + monitor, raw_input::{get_raw_input_data, get_raw_mouse_button_state}, util, window::adjust_size, window_state::{CursorFlags, WindowFlags, WindowState}, wrap_device_id, WindowId, DEVICE_ID, }, - window::WindowId as RootWindowId, + window::{Fullscreen, WindowId as RootWindowId}, }; type GetPointerFrameInfoHistory = unsafe extern "system" fn( @@ -982,6 +983,51 @@ unsafe extern "system" fn public_window_callback( commctrl::DefSubclassProc(window, msg, wparam, lparam) } + winuser::WM_WINDOWPOSCHANGING => { + let mut window_state = subclass_input.window_state.lock(); + if let Some(ref mut fullscreen) = window_state.fullscreen { + let window_pos = &mut *(lparam as *mut winuser::WINDOWPOS); + let new_rect = RECT { + left: window_pos.x, + top: window_pos.y, + right: window_pos.x + window_pos.cx, + bottom: window_pos.y + window_pos.cy, + }; + let new_monitor = + winuser::MonitorFromRect(&new_rect, winuser::MONITOR_DEFAULTTONULL); + match fullscreen { + Fullscreen::Borderless(ref mut fullscreen_monitor) => { + if new_monitor != fullscreen_monitor.inner.hmonitor() + && new_monitor != ptr::null_mut() + { + if let Ok(new_monitor_info) = monitor::get_monitor_info(new_monitor) { + let new_monitor_rect = new_monitor_info.rcMonitor; + window_pos.x = new_monitor_rect.left; + window_pos.y = new_monitor_rect.top; + window_pos.cx = new_monitor_rect.right - new_monitor_rect.left; + window_pos.cy = new_monitor_rect.bottom - new_monitor_rect.top; + } + *fullscreen_monitor = crate::monitor::MonitorHandle { + inner: monitor::MonitorHandle::new(new_monitor), + }; + } + } + Fullscreen::Exclusive(ref video_mode) => { + let old_monitor = video_mode.video_mode.monitor.hmonitor(); + if let Ok(old_monitor_info) = monitor::get_monitor_info(old_monitor) { + let old_monitor_rect = old_monitor_info.rcMonitor; + window_pos.x = old_monitor_rect.left; + window_pos.y = old_monitor_rect.top; + window_pos.cx = old_monitor_rect.right - old_monitor_rect.left; + window_pos.cy = old_monitor_rect.bottom - old_monitor_rect.top; + } + } + } + } + + 0 + } + // WM_MOVE supplies client area positions, so we send Moved here instead. winuser::WM_WINDOWPOSCHANGED => { use crate::event::WindowEvent::Moved;