Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@

- On X11, the `Moved` event is no longer sent when the window is resized without changing position.
- `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, 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, `with_override_redirect` now actually enables override redirect.
- 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, windows without decorations can once again be resized.

# Version 0.15.0 (2018-05-22)

Expand Down
78 changes: 57 additions & 21 deletions src/platform/macos/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,16 @@ impl DelegateState {
// resizable temporality
let curr_mask = self.window.styleMask();

if !curr_mask.contains(NSWindowStyleMask::NSTitledWindowMask) {
util::set_style_mask(*self.window, *self.view, NSWindowStyleMask::NSResizableWindowMask);
let required = NSWindowStyleMask::NSTitledWindowMask | 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];

// Roll back temp styles
if !curr_mask.contains(NSWindowStyleMask::NSTitledWindowMask) {
if needs_temp_mask {
util::set_style_mask(*self.window, *self.view, curr_mask);
}

Expand All @@ -76,13 +78,20 @@ impl DelegateState {
fn restore_state_from_fullscreen(&mut self) {
let maximized = unsafe {
let mut win_attribs = self.win_attribs.borrow_mut();

win_attribs.fullscreen = None;
let save_style_opt = self.save_style_mask.take();

if let Some(save_style) = save_style_opt {
util::set_style_mask(*self.window, *self.view, save_style);
}
let mask = {
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
};
Expand All @@ -107,16 +116,17 @@ impl DelegateState {
let mut win_attribs = self.win_attribs.borrow_mut();
win_attribs.maximized = maximized;

let curr_mask = unsafe { self.window.styleMask() };
if win_attribs.fullscreen.is_some() {
// Handle it in window_did_exit_fullscreen
return;
} else if win_attribs.decorations {
// Just use the native zoom if not borderless
} else if curr_mask.contains(NSWindowStyleMask::NSResizableWindowMask) {
// Just use the native zoom if resizable
unsafe {
self.window.zoom_(nil);
}
} else {
// if it is borderless, we set the frame directly
// if it's not resizable, we set the frame directly
unsafe {
let new_rect = if maximized {
let screen = NSScreen::mainScreen(nil);
Expand Down Expand Up @@ -558,14 +568,18 @@ impl WindowExt for Window2 {
impl Window2 {
pub fn new(
shared: Weak<Shared>,
win_attribs: WindowAttributes,
mut win_attribs: WindowAttributes,
pl_attribs: PlatformSpecificWindowBuilderAttributes,
) -> Result<Window2, CreationError> {
unsafe {
if !msg_send![cocoa::base::class("NSThread"), isMainThread] {
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 {
NSAutoreleasePool::new(nil)
};
Expand Down Expand Up @@ -721,9 +735,10 @@ impl Window2 {
};

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
NSWindowStyleMask::NSBorderlessWindowMask
| NSWindowStyleMask::NSResizableWindowMask
} else if pl_attrs.titlebar_hidden {
// if the titlebar is hidden, ignore other pl_attrs
NSWindowStyleMask::NSBorderlessWindowMask |
Expand All @@ -736,8 +751,12 @@ impl Window2 {
NSWindowStyleMask::NSTitledWindowMask
};

if !attrs.resizable {
masks &= !NSWindowStyleMask::NSResizableWindowMask;
}

if pl_attrs.fullsize_content_view {
masks = masks | NSWindowStyleMask::NSFullSizeContentViewWindowMask;
masks |= NSWindowStyleMask::NSFullSizeContentViewWindowMask;
}

let winit_window = Window2::class();
Expand Down Expand Up @@ -779,7 +798,7 @@ impl Window2 {
if attrs.always_on_top {
let _: () = msg_send![*window, setLevel:ffi::NSWindowLevel::NSFloatingWindowLevel];
}

if let Some((x, y)) = pl_attrs.resize_increments {
if x >= 1 && y >= 1 {
let size = NSSize::new(x as _, y as _);
Expand Down Expand Up @@ -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]
pub fn platform_display(&self) -> *mut libc::c_void {
unimplemented!()
Expand Down Expand Up @@ -1028,11 +1062,9 @@ impl Window2 {
// It will clean up at window_did_exit_fullscreen.
if current.is_none() {
let curr_mask = state.window.styleMask();

if !curr_mask.contains(NSWindowStyleMask::NSTitledWindowMask) {
let mask = NSWindowStyleMask::NSTitledWindowMask
| NSWindowStyleMask::NSResizableWindowMask;
util::set_style_mask(*self.window, *self.view, mask);
let required = NSWindowStyleMask::NSTitledWindowMask | NSWindowStyleMask::NSResizableWindowMask;
if !curr_mask.contains(required) {
util::set_style_mask(*self.window, *self.view, required);
state.save_style_mask.set(Some(curr_mask));
}
}
Expand All @@ -1059,14 +1091,18 @@ impl Window2 {
}

unsafe {
let new_mask = if decorations {
let mut new_mask = if decorations {
NSWindowStyleMask::NSClosableWindowMask
| NSWindowStyleMask::NSMiniaturizableWindowMask
| NSWindowStyleMask::NSResizableWindowMask
| NSWindowStyleMask::NSTitledWindowMask
} else {
NSWindowStyleMask::NSBorderlessWindowMask
| NSWindowStyleMask::NSResizableWindowMask
};
if !win_attribs.resizable {
new_mask &= !NSWindowStyleMask::NSResizableWindowMask;
}
util::set_style_mask(*state.window, *state.view, new_mask);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl WindowBuilder {
///
/// ## Platform-specific
///
/// This only has an effect on Windows & X11.
/// This only has an effect on Windows, X11, and macOS.
#[inline]
pub fn with_resizable(mut self, resizable: bool) -> WindowBuilder {
self.window.resizable = resizable;
Expand Down