mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-24 06:11:30 +11:00
Windows: Preserve minimized/maximized state in fullscreen (#1784)
This commit is contained in:
parent
6db308f1e9
commit
39573d65d0
13
CHANGELOG.md
13
CHANGELOG.md
|
@ -1,19 +1,24 @@
|
||||||
|
# Unreleased
|
||||||
|
|
||||||
|
- On Windows, fix fullscreen not preserving minimized/maximized state.
|
||||||
|
|
||||||
# 0.24.0 (2020-12-09)
|
# 0.24.0 (2020-12-09)
|
||||||
|
|
||||||
- On Windows, fix applications not exiting gracefully due to thread_event_target_callback accessing corrupted memory.
|
- On Windows, fix applications not exiting gracefully due to thread_event_target_callback accessing corrupted memory.
|
||||||
- On Windows, implement `Window::set_ime_position`.
|
- On Windows, implement `Window::set_ime_position`.
|
||||||
- **Breaking:** On Windows, Renamed `WindowBuilderExtWindows`'s `is_dark_mode` to `theme`.
|
- **Breaking:** On Windows, Renamed `WindowBuilderExtWindows`'s `is_dark_mode` to `theme`.
|
||||||
|
- **Breaking:** On Windows, renamed `WindowBuilderExtWindows::is_dark_mode` to `theme`.
|
||||||
- On Windows, add `WindowBuilderExtWindows::with_theme` to set a preferred theme.
|
- On Windows, add `WindowBuilderExtWindows::with_theme` to set a preferred theme.
|
||||||
- On Windows, fix bug causing message boxes to appear delayed.
|
- On Windows, fix bug causing message boxes to appear delayed.
|
||||||
- On Android, calling `WindowEvent::Focused` now works properly instead of always returning false.
|
- On Android, calling `WindowEvent::Focused` now works properly instead of always returning false.
|
||||||
- On Windows, fix alt-tab behaviour by removing borderless fullscreen "always on top" flag.
|
- On Windows, fix Alt-Tab behaviour by removing borderless fullscreen "always on top" flag.
|
||||||
- On Windows, fix bug preventing windows with transparency enabled from having fully-opaque regions.
|
- On Windows, fix bug preventing windows with transparency enabled from having fully-opaque regions.
|
||||||
- **Breaking:** On Windows, include prefix byte in scancodes.
|
- **Breaking:** On Windows, include prefix byte in scancodes.
|
||||||
- On Wayland, fix window not being resizeable when using `with_min_inner_size` in `WindowBuilder`.
|
- On Wayland, fix window not being resizeable when using `WindowBuilder::with_min_inner_size`.
|
||||||
- On Unix, fix cross-compiling to wasm32 without enabling X11 or Wayland.
|
- On Unix, fix cross-compiling to wasm32 without enabling X11 or Wayland.
|
||||||
- On Windows, fix use after free crash during window destruction.
|
- On Windows, fix use-after-free crash during window destruction.
|
||||||
- On Web, fix `WindowEvent::ReceivedCharacter` never being sent on key input.
|
- On Web, fix `WindowEvent::ReceivedCharacter` never being sent on key input.
|
||||||
- On macOS, fix compilation when targeting aarch64
|
- On macOS, fix compilation when targeting aarch64.
|
||||||
- On X11, fix `Window::request_redraw` not waking the event loop.
|
- On X11, fix `Window::request_redraw` not waking the event loop.
|
||||||
- On Wayland, the keypad arrow keys are now recognized.
|
- On Wayland, the keypad arrow keys are now recognized.
|
||||||
- **Breaking** Rename `desktop::EventLoopExtDesktop` to `run_return::EventLoopExtRunReturn`.
|
- **Breaking** Rename `desktop::EventLoopExtDesktop` to `run_return::EventLoopExtRunReturn`.
|
||||||
|
|
|
@ -403,20 +403,6 @@ impl Window {
|
||||||
drop(window_state_lock);
|
drop(window_state_lock);
|
||||||
|
|
||||||
self.thread_executor.execute_in_thread(move || {
|
self.thread_executor.execute_in_thread(move || {
|
||||||
let mut window_state_lock = window_state.lock();
|
|
||||||
|
|
||||||
// Save window bounds before entering fullscreen
|
|
||||||
match (&old_fullscreen, &fullscreen) {
|
|
||||||
(&None, &Some(_)) => {
|
|
||||||
let client_rect = util::get_client_rect(window.0).unwrap();
|
|
||||||
window_state_lock.saved_window = Some(SavedWindow {
|
|
||||||
client_rect,
|
|
||||||
scale_factor: window_state_lock.scale_factor,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change video mode if we're transitioning to or from exclusive
|
// Change video mode if we're transitioning to or from exclusive
|
||||||
// fullscreen
|
// fullscreen
|
||||||
match (&old_fullscreen, &fullscreen) {
|
match (&old_fullscreen, &fullscreen) {
|
||||||
|
@ -490,7 +476,7 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update window style
|
// Update window style
|
||||||
WindowState::set_window_flags(window_state_lock, window.0, |f| {
|
WindowState::set_window_flags(window_state.lock(), window.0, |f| {
|
||||||
f.set(
|
f.set(
|
||||||
WindowFlags::MARKER_EXCLUSIVE_FULLSCREEN,
|
WindowFlags::MARKER_EXCLUSIVE_FULLSCREEN,
|
||||||
matches!(fullscreen, Some(Fullscreen::Exclusive(_))),
|
matches!(fullscreen, Some(Fullscreen::Exclusive(_))),
|
||||||
|
@ -504,6 +490,15 @@ impl Window {
|
||||||
// Update window bounds
|
// Update window bounds
|
||||||
match &fullscreen {
|
match &fullscreen {
|
||||||
Some(fullscreen) => {
|
Some(fullscreen) => {
|
||||||
|
// Save window bounds before entering fullscreen
|
||||||
|
let placement = unsafe {
|
||||||
|
let mut placement = mem::zeroed();
|
||||||
|
winuser::GetWindowPlacement(window.0, &mut placement);
|
||||||
|
placement
|
||||||
|
};
|
||||||
|
|
||||||
|
window_state.lock().saved_window = Some(SavedWindow { placement });
|
||||||
|
|
||||||
let monitor = match &fullscreen {
|
let monitor = match &fullscreen {
|
||||||
Fullscreen::Exclusive(video_mode) => video_mode.monitor(),
|
Fullscreen::Exclusive(video_mode) => video_mode.monitor(),
|
||||||
Fullscreen::Borderless(Some(monitor)) => monitor.clone(),
|
Fullscreen::Borderless(Some(monitor)) => monitor.clone(),
|
||||||
|
@ -530,27 +525,10 @@ impl Window {
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let mut window_state_lock = window_state.lock();
|
let mut window_state_lock = window_state.lock();
|
||||||
if let Some(SavedWindow {
|
if let Some(SavedWindow { placement }) = window_state_lock.saved_window.take() {
|
||||||
client_rect,
|
|
||||||
scale_factor,
|
|
||||||
}) = window_state_lock.saved_window.take()
|
|
||||||
{
|
|
||||||
window_state_lock.scale_factor = scale_factor;
|
|
||||||
drop(window_state_lock);
|
drop(window_state_lock);
|
||||||
let client_rect = util::adjust_window_rect(window.0, client_rect).unwrap();
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
winuser::SetWindowPos(
|
winuser::SetWindowPlacement(window.0, &placement);
|
||||||
window.0,
|
|
||||||
ptr::null_mut(),
|
|
||||||
client_rect.left,
|
|
||||||
client_rect.top,
|
|
||||||
client_rect.right - client_rect.left,
|
|
||||||
client_rect.bottom - client_rect.top,
|
|
||||||
winuser::SWP_ASYNCWINDOWPOS
|
|
||||||
| winuser::SWP_NOZORDER
|
|
||||||
| winuser::SWP_NOACTIVATE,
|
|
||||||
);
|
|
||||||
winuser::InvalidateRgn(window.0, ptr::null_mut(), 0);
|
winuser::InvalidateRgn(window.0, ptr::null_mut(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,8 +39,7 @@ pub struct WindowState {
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct SavedWindow {
|
pub struct SavedWindow {
|
||||||
pub client_rect: RECT,
|
pub placement: winuser::WINDOWPLACEMENT,
|
||||||
pub scale_factor: f64,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -86,11 +85,6 @@ bitflags! {
|
||||||
|
|
||||||
const MINIMIZED = 1 << 12;
|
const MINIMIZED = 1 << 12;
|
||||||
|
|
||||||
const FULLSCREEN_AND_MASK = !(
|
|
||||||
WindowFlags::DECORATIONS.bits |
|
|
||||||
WindowFlags::RESIZABLE.bits |
|
|
||||||
WindowFlags::MAXIMIZED.bits
|
|
||||||
);
|
|
||||||
const EXCLUSIVE_FULLSCREEN_OR_MASK = WindowFlags::ALWAYS_ON_TOP.bits;
|
const EXCLUSIVE_FULLSCREEN_OR_MASK = WindowFlags::ALWAYS_ON_TOP.bits;
|
||||||
const NO_DECORATIONS_AND_MASK = !WindowFlags::RESIZABLE.bits;
|
const NO_DECORATIONS_AND_MASK = !WindowFlags::RESIZABLE.bits;
|
||||||
const INVISIBLE_AND_MASK = !WindowFlags::MAXIMIZED.bits;
|
const INVISIBLE_AND_MASK = !WindowFlags::MAXIMIZED.bits;
|
||||||
|
@ -181,10 +175,7 @@ impl MouseProperties {
|
||||||
impl WindowFlags {
|
impl WindowFlags {
|
||||||
fn mask(mut self) -> WindowFlags {
|
fn mask(mut self) -> WindowFlags {
|
||||||
if self.contains(WindowFlags::MARKER_EXCLUSIVE_FULLSCREEN) {
|
if self.contains(WindowFlags::MARKER_EXCLUSIVE_FULLSCREEN) {
|
||||||
self &= WindowFlags::FULLSCREEN_AND_MASK;
|
|
||||||
self |= WindowFlags::EXCLUSIVE_FULLSCREEN_OR_MASK;
|
self |= WindowFlags::EXCLUSIVE_FULLSCREEN_OR_MASK;
|
||||||
} else if self.contains(WindowFlags::MARKER_BORDERLESS_FULLSCREEN) {
|
|
||||||
self &= WindowFlags::FULLSCREEN_AND_MASK;
|
|
||||||
}
|
}
|
||||||
if !self.contains(WindowFlags::VISIBLE) {
|
if !self.contains(WindowFlags::VISIBLE) {
|
||||||
self &= WindowFlags::INVISIBLE_AND_MASK;
|
self &= WindowFlags::INVISIBLE_AND_MASK;
|
||||||
|
@ -235,6 +226,12 @@ impl WindowFlags {
|
||||||
style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_SYSMENU;
|
style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_SYSMENU;
|
||||||
style_ex |= WS_EX_ACCEPTFILES;
|
style_ex |= WS_EX_ACCEPTFILES;
|
||||||
|
|
||||||
|
if self.intersects(
|
||||||
|
WindowFlags::MARKER_EXCLUSIVE_FULLSCREEN | WindowFlags::MARKER_BORDERLESS_FULLSCREEN,
|
||||||
|
) {
|
||||||
|
style &= !WS_OVERLAPPEDWINDOW;
|
||||||
|
}
|
||||||
|
|
||||||
(style, style_ex)
|
(style, style_ex)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue