mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2025-01-23 18:36:34 +11:00
macOS: Resizable without decorations (#553)
* macOS: Resizable without decorations * Fix style mask regressions
This commit is contained in:
parent
2cc8fa1eac
commit
8891cfd85e
3 changed files with 60 additions and 23 deletions
|
@ -2,13 +2,14 @@
|
||||||
|
|
||||||
- On X11, the `Moved` event is no longer sent when the window is resized without changing position.
|
- On X11, the `Moved` event is no longer sent when the window is resized without changing position.
|
||||||
- `MouseCursor` and `CursorState` now implement `Default`.
|
- `MouseCursor` and `CursorState` now implement `Default`.
|
||||||
- `WindowBuilder::with_resizable` implemented for Windows & X11.
|
- `WindowBuilder::with_resizable` implemented for Windows, X11, and macOS.
|
||||||
- On X11, if the monitor's width or height in millimeters is reported as 0, the DPI is now 1.0 instead of +inf.
|
- On X11, if the monitor's width or height in millimeters is reported as 0, the DPI is now 1.0 instead of +inf.
|
||||||
- On X11, the environment variable `WINIT_HIDPI_FACTOR` has been added for overriding DPI factor.
|
- On X11, the environment variable `WINIT_HIDPI_FACTOR` has been added for overriding DPI factor.
|
||||||
- On X11, enabling transparency no longer causes the window contents to flicker when resizing.
|
- On X11, enabling transparency no longer causes the window contents to flicker when resizing.
|
||||||
- On X11, `with_override_redirect` now actually enables override redirect.
|
- On X11, `with_override_redirect` now actually enables override redirect.
|
||||||
- macOS now generates `VirtualKeyCode::LAlt` and `VirtualKeyCode::RAlt` instead of `None` for both.
|
- macOS now generates `VirtualKeyCode::LAlt` and `VirtualKeyCode::RAlt` instead of `None` for both.
|
||||||
- On macOS, `VirtualKeyCode::RWin` and `VirtualKeyCode::LWin` are no longer switched.
|
- On macOS, `VirtualKeyCode::RWin` and `VirtualKeyCode::LWin` are no longer switched.
|
||||||
|
- On macOS, windows without decorations can once again be resized.
|
||||||
|
|
||||||
# Version 0.15.0 (2018-05-22)
|
# Version 0.15.0 (2018-05-22)
|
||||||
|
|
||||||
|
|
|
@ -58,14 +58,16 @@ impl DelegateState {
|
||||||
// resizable temporality
|
// resizable temporality
|
||||||
let curr_mask = self.window.styleMask();
|
let curr_mask = self.window.styleMask();
|
||||||
|
|
||||||
if !curr_mask.contains(NSWindowStyleMask::NSTitledWindowMask) {
|
let required = NSWindowStyleMask::NSTitledWindowMask | NSWindowStyleMask::NSResizableWindowMask;
|
||||||
util::set_style_mask(*self.window, *self.view, NSWindowStyleMask::NSResizableWindowMask);
|
let needs_temp_mask = !curr_mask.contains(required);
|
||||||
|
if needs_temp_mask {
|
||||||
|
util::set_style_mask(*self.window, *self.view, required);
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_zoomed: BOOL = msg_send![*self.window, isZoomed];
|
let is_zoomed: BOOL = msg_send![*self.window, isZoomed];
|
||||||
|
|
||||||
// Roll back temp styles
|
// Roll back temp styles
|
||||||
if !curr_mask.contains(NSWindowStyleMask::NSTitledWindowMask) {
|
if needs_temp_mask {
|
||||||
util::set_style_mask(*self.window, *self.view, curr_mask);
|
util::set_style_mask(*self.window, *self.view, curr_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,13 +78,20 @@ impl DelegateState {
|
||||||
fn restore_state_from_fullscreen(&mut self) {
|
fn restore_state_from_fullscreen(&mut self) {
|
||||||
let maximized = unsafe {
|
let maximized = unsafe {
|
||||||
let mut win_attribs = self.win_attribs.borrow_mut();
|
let mut win_attribs = self.win_attribs.borrow_mut();
|
||||||
|
|
||||||
win_attribs.fullscreen = None;
|
win_attribs.fullscreen = None;
|
||||||
let save_style_opt = self.save_style_mask.take();
|
|
||||||
|
|
||||||
if let Some(save_style) = save_style_opt {
|
let mask = {
|
||||||
util::set_style_mask(*self.window, *self.view, save_style);
|
let base_mask = self.save_style_mask
|
||||||
|
.take()
|
||||||
|
.unwrap_or_else(|| self.window.styleMask());
|
||||||
|
if win_attribs.resizable {
|
||||||
|
base_mask | NSWindowStyleMask::NSResizableWindowMask
|
||||||
|
} else {
|
||||||
|
base_mask & !NSWindowStyleMask::NSResizableWindowMask
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
util::set_style_mask(*self.window, *self.view, mask);
|
||||||
|
|
||||||
win_attribs.maximized
|
win_attribs.maximized
|
||||||
};
|
};
|
||||||
|
@ -107,16 +116,17 @@ impl DelegateState {
|
||||||
let mut win_attribs = self.win_attribs.borrow_mut();
|
let mut win_attribs = self.win_attribs.borrow_mut();
|
||||||
win_attribs.maximized = maximized;
|
win_attribs.maximized = maximized;
|
||||||
|
|
||||||
|
let curr_mask = unsafe { self.window.styleMask() };
|
||||||
if win_attribs.fullscreen.is_some() {
|
if win_attribs.fullscreen.is_some() {
|
||||||
// Handle it in window_did_exit_fullscreen
|
// Handle it in window_did_exit_fullscreen
|
||||||
return;
|
return;
|
||||||
} else if win_attribs.decorations {
|
} else if curr_mask.contains(NSWindowStyleMask::NSResizableWindowMask) {
|
||||||
// Just use the native zoom if not borderless
|
// Just use the native zoom if resizable
|
||||||
unsafe {
|
unsafe {
|
||||||
self.window.zoom_(nil);
|
self.window.zoom_(nil);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// if it is borderless, we set the frame directly
|
// if it's not resizable, we set the frame directly
|
||||||
unsafe {
|
unsafe {
|
||||||
let new_rect = if maximized {
|
let new_rect = if maximized {
|
||||||
let screen = NSScreen::mainScreen(nil);
|
let screen = NSScreen::mainScreen(nil);
|
||||||
|
@ -558,7 +568,7 @@ impl WindowExt for Window2 {
|
||||||
impl Window2 {
|
impl Window2 {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
shared: Weak<Shared>,
|
shared: Weak<Shared>,
|
||||||
win_attribs: WindowAttributes,
|
mut win_attribs: WindowAttributes,
|
||||||
pl_attribs: PlatformSpecificWindowBuilderAttributes,
|
pl_attribs: PlatformSpecificWindowBuilderAttributes,
|
||||||
) -> Result<Window2, CreationError> {
|
) -> Result<Window2, CreationError> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -566,6 +576,10 @@ impl Window2 {
|
||||||
panic!("Windows can only be created on the main thread on macOS");
|
panic!("Windows can only be created on the main thread on macOS");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Might as well save some RAM...
|
||||||
|
win_attribs.window_icon.take();
|
||||||
|
|
||||||
let autoreleasepool = unsafe {
|
let autoreleasepool = unsafe {
|
||||||
NSAutoreleasePool::new(nil)
|
NSAutoreleasePool::new(nil)
|
||||||
};
|
};
|
||||||
|
@ -721,9 +735,10 @@ impl Window2 {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut masks = if !attrs.decorations && !screen.is_some() {
|
let mut masks = if !attrs.decorations && !screen.is_some() {
|
||||||
// unresizable Window2 without a titlebar or borders
|
// Resizable Window2 without a titlebar or borders
|
||||||
// if decorations is set to false, ignore pl_attrs
|
// if decorations is set to false, ignore pl_attrs
|
||||||
NSWindowStyleMask::NSBorderlessWindowMask
|
NSWindowStyleMask::NSBorderlessWindowMask
|
||||||
|
| NSWindowStyleMask::NSResizableWindowMask
|
||||||
} else if pl_attrs.titlebar_hidden {
|
} else if pl_attrs.titlebar_hidden {
|
||||||
// if the titlebar is hidden, ignore other pl_attrs
|
// if the titlebar is hidden, ignore other pl_attrs
|
||||||
NSWindowStyleMask::NSBorderlessWindowMask |
|
NSWindowStyleMask::NSBorderlessWindowMask |
|
||||||
|
@ -736,8 +751,12 @@ impl Window2 {
|
||||||
NSWindowStyleMask::NSTitledWindowMask
|
NSWindowStyleMask::NSTitledWindowMask
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if !attrs.resizable {
|
||||||
|
masks &= !NSWindowStyleMask::NSResizableWindowMask;
|
||||||
|
}
|
||||||
|
|
||||||
if pl_attrs.fullsize_content_view {
|
if pl_attrs.fullsize_content_view {
|
||||||
masks = masks | NSWindowStyleMask::NSFullSizeContentViewWindowMask;
|
masks |= NSWindowStyleMask::NSFullSizeContentViewWindowMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
let winit_window = Window2::class();
|
let winit_window = Window2::class();
|
||||||
|
@ -900,6 +919,21 @@ impl Window2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_resizable(&self, resizable: bool) {
|
||||||
|
let mut win_attribs = self.delegate.state.win_attribs.borrow_mut();
|
||||||
|
win_attribs.resizable = resizable;
|
||||||
|
if win_attribs.fullscreen.is_none() {
|
||||||
|
let mut mask = unsafe { self.window.styleMask() };
|
||||||
|
if resizable {
|
||||||
|
mask |= NSWindowStyleMask::NSResizableWindowMask;
|
||||||
|
} else {
|
||||||
|
mask &= !NSWindowStyleMask::NSResizableWindowMask;
|
||||||
|
}
|
||||||
|
unsafe { util::set_style_mask(*self.window, *self.view, mask) };
|
||||||
|
} // Otherwise, we don't change the mask until we exit fullscreen.
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn platform_display(&self) -> *mut libc::c_void {
|
pub fn platform_display(&self) -> *mut libc::c_void {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
|
@ -1028,11 +1062,9 @@ impl Window2 {
|
||||||
// It will clean up at window_did_exit_fullscreen.
|
// It will clean up at window_did_exit_fullscreen.
|
||||||
if current.is_none() {
|
if current.is_none() {
|
||||||
let curr_mask = state.window.styleMask();
|
let curr_mask = state.window.styleMask();
|
||||||
|
let required = NSWindowStyleMask::NSTitledWindowMask | NSWindowStyleMask::NSResizableWindowMask;
|
||||||
if !curr_mask.contains(NSWindowStyleMask::NSTitledWindowMask) {
|
if !curr_mask.contains(required) {
|
||||||
let mask = NSWindowStyleMask::NSTitledWindowMask
|
util::set_style_mask(*self.window, *self.view, required);
|
||||||
| NSWindowStyleMask::NSResizableWindowMask;
|
|
||||||
util::set_style_mask(*self.window, *self.view, mask);
|
|
||||||
state.save_style_mask.set(Some(curr_mask));
|
state.save_style_mask.set(Some(curr_mask));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1059,14 +1091,18 @@ impl Window2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let new_mask = if decorations {
|
let mut new_mask = if decorations {
|
||||||
NSWindowStyleMask::NSClosableWindowMask
|
NSWindowStyleMask::NSClosableWindowMask
|
||||||
| NSWindowStyleMask::NSMiniaturizableWindowMask
|
| NSWindowStyleMask::NSMiniaturizableWindowMask
|
||||||
| NSWindowStyleMask::NSResizableWindowMask
|
| NSWindowStyleMask::NSResizableWindowMask
|
||||||
| NSWindowStyleMask::NSTitledWindowMask
|
| NSWindowStyleMask::NSTitledWindowMask
|
||||||
} else {
|
} else {
|
||||||
NSWindowStyleMask::NSBorderlessWindowMask
|
NSWindowStyleMask::NSBorderlessWindowMask
|
||||||
|
| NSWindowStyleMask::NSResizableWindowMask
|
||||||
};
|
};
|
||||||
|
if !win_attribs.resizable {
|
||||||
|
new_mask &= !NSWindowStyleMask::NSResizableWindowMask;
|
||||||
|
}
|
||||||
util::set_style_mask(*state.window, *state.view, new_mask);
|
util::set_style_mask(*state.window, *state.view, new_mask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ impl WindowBuilder {
|
||||||
///
|
///
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
/// This only has an effect on Windows & X11.
|
/// This only has an effect on Windows, X11, and macOS.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn with_resizable(mut self, resizable: bool) -> WindowBuilder {
|
pub fn with_resizable(mut self, resizable: bool) -> WindowBuilder {
|
||||||
self.window.resizable = resizable;
|
self.window.resizable = resizable;
|
||||||
|
|
Loading…
Add table
Reference in a new issue