@@ -5,10 +5,10 @@ use std::sync::atomic::{AtomicBool, Ordering};
55use std:: sync:: Arc ;
66
77use cocoa:: appkit:: {
8- NSApp , NSApplication , NSApplicationActivationPolicyRegular , NSBackingStoreBuffered , NSWindow ,
9- NSWindowStyleMask ,
8+ NSApp , NSApplication , NSApplicationActivationPolicyRegular , NSBackingStoreBuffered , NSView ,
9+ NSWindow , NSWindowStyleMask ,
1010} ;
11- use cocoa:: base:: { id, nil, NO } ;
11+ use cocoa:: base:: { id, nil, NO , YES } ;
1212use cocoa:: foundation:: { NSAutoreleasePool , NSPoint , NSRect , NSSize , NSString } ;
1313use core_foundation:: runloop:: {
1414 CFRunLoop , CFRunLoopTimer , CFRunLoopTimerContext , __CFRunLoopTimer, kCFRunLoopDefaultMode,
@@ -20,7 +20,7 @@ use objc::{msg_send, runtime::Object, sel, sel_impl};
2020use raw_window_handle:: { AppKitHandle , HasRawWindowHandle , RawWindowHandle } ;
2121
2222use crate :: {
23- Event , EventStatus , WindowEvent , WindowHandler , WindowInfo , WindowOpenOptions ,
23+ Event , EventStatus , Size , WindowEvent , WindowHandler , WindowInfo , WindowOpenOptions ,
2424 WindowScalePolicy ,
2525} ;
2626
@@ -124,6 +124,13 @@ impl Window {
124124 {
125125 let pool = unsafe { NSAutoreleasePool :: new ( nil) } ;
126126
127+ let scaling = match options. scale {
128+ WindowScalePolicy :: ScaleFactor ( scale) => scale,
129+ WindowScalePolicy :: SystemScaleFactor => 1.0 ,
130+ } ;
131+
132+ let window_info = WindowInfo :: from_logical_size ( options. size , scaling) ;
133+
127134 let handle = if let RawWindowHandle :: AppKit ( handle) = parent. raw_window_handle ( ) {
128135 handle
129136 } else {
@@ -144,7 +151,7 @@ impl Window {
144151 . map ( |gl_config| Self :: create_gl_context ( None , ns_view, gl_config) ) ,
145152 } ;
146153
147- let window_handle = Self :: init ( true , window, build) ;
154+ let window_handle = Self :: init ( true , window, window_info , build) ;
148155
149156 unsafe {
150157 let _: id = msg_send ! [ handle. ns_view as * mut Object , addSubview: ns_view] ;
@@ -164,6 +171,13 @@ impl Window {
164171 {
165172 let pool = unsafe { NSAutoreleasePool :: new ( nil) } ;
166173
174+ let scaling = match options. scale {
175+ WindowScalePolicy :: ScaleFactor ( scale) => scale,
176+ WindowScalePolicy :: SystemScaleFactor => 1.0 ,
177+ } ;
178+
179+ let window_info = WindowInfo :: from_logical_size ( options. size , scaling) ;
180+
167181 let ns_view = unsafe { create_view ( & options) } ;
168182
169183 let window = Window {
@@ -178,7 +192,7 @@ impl Window {
178192 . map ( |gl_config| Self :: create_gl_context ( None , ns_view, gl_config) ) ,
179193 } ;
180194
181- let window_handle = Self :: init ( true , window, build) ;
195+ let window_handle = Self :: init ( true , window, window_info , build) ;
182196
183197 unsafe {
184198 let ( ) = msg_send ! [ pool, drain] ;
@@ -215,10 +229,7 @@ impl Window {
215229
216230 let rect = NSRect :: new (
217231 NSPoint :: new ( 0.0 , 0.0 ) ,
218- NSSize :: new (
219- window_info. logical_size ( ) . width as f64 ,
220- window_info. logical_size ( ) . height as f64 ,
221- ) ,
232+ NSSize :: new ( window_info. logical_size ( ) . width , window_info. logical_size ( ) . height ) ,
222233 ) ;
223234
224235 let ns_window = unsafe {
@@ -254,7 +265,7 @@ impl Window {
254265 . map ( |gl_config| Self :: create_gl_context ( Some ( ns_window) , ns_view, gl_config) ) ,
255266 } ;
256267
257- let _ = Self :: init ( false , window, build) ;
268+ let _ = Self :: init ( false , window, window_info , build) ;
258269
259270 unsafe {
260271 ns_window. setContentView_ ( ns_view) ;
@@ -266,7 +277,9 @@ impl Window {
266277 }
267278 }
268279
269- fn init < H , B > ( parented : bool , mut window : Window , build : B ) -> WindowHandle
280+ fn init < H , B > (
281+ parented : bool , mut window : Window , window_info : WindowInfo , build : B ,
282+ ) -> WindowHandle
270283 where
271284 H : WindowHandler + ' static ,
272285 B : FnOnce ( & mut crate :: Window ) -> H ,
@@ -285,6 +298,7 @@ impl Window {
285298 keyboard_state : KeyboardState :: new ( ) ,
286299 frame_timer : None ,
287300 retain_count_after_build,
301+ window_info,
288302 _parent_handle : parent_handle,
289303 } ) ) ;
290304
@@ -302,6 +316,28 @@ impl Window {
302316 self . close_requested = true ;
303317 }
304318
319+ pub fn resize ( & mut self , size : Size ) {
320+ // NOTE: macOS gives you a personal rave if you pass in fractional pixels here. Even though
321+ // the size is in fractional pixels.
322+ let size = NSSize :: new ( size. width . round ( ) , size. height . round ( ) ) ;
323+
324+ unsafe { NSView :: setFrameSize ( self . ns_view , size) } ;
325+ unsafe {
326+ let _: ( ) = msg_send ! [ self . ns_view, setNeedsDisplay: YES ] ;
327+ }
328+
329+ // When using OpenGL the `NSOpenGLView` needs to be resized separately? Why? Because macOS.
330+ #[ cfg( feature = "opengl" ) ]
331+ if let Some ( gl_context) = & self . gl_context {
332+ gl_context. resize ( size) ;
333+ }
334+
335+ // If this is a standalone window then we'll also need to resize the window itself
336+ if let Some ( ns_window) = self . ns_window {
337+ unsafe { NSWindow :: setContentSize_ ( ns_window, size) } ;
338+ }
339+ }
340+
305341 #[ cfg( feature = "opengl" ) ]
306342 pub fn gl_context ( & self ) -> Option < & GlContext > {
307343 self . gl_context . as_ref ( )
@@ -325,6 +361,8 @@ pub(super) struct WindowState {
325361 frame_timer : Option < CFRunLoopTimer > ,
326362 _parent_handle : Option < ParentHandle > ,
327363 pub retain_count_after_build : usize ,
364+ /// The last known window info for this window.
365+ pub window_info : WindowInfo ,
328366}
329367
330368impl WindowState {
0 commit comments