@@ -32,8 +32,7 @@ use crate::wrappers::win32::{
3232 WindowStyle ,
3333} ;
3434use crate :: {
35- Event , MouseButton , MouseEvent , ScrollDelta , WindowEvent , WindowOpenOptions , WindowScalePolicy ,
36- WindowSize ,
35+ Event , MouseButton , MouseEvent , ScrollDelta , WindowEvent , WindowOpenOptions , WindowSize ,
3736} ;
3837
3938#[ allow( non_snake_case) ]
@@ -65,6 +64,26 @@ impl WindowHandle {
6564 pub fn is_open ( & self ) -> bool {
6665 self . state . is_alive . get ( )
6766 }
67+
68+ pub fn size ( & self ) -> WindowSize {
69+ self . state . size ( )
70+ }
71+
72+ pub fn resize ( & self , new_size : Size ) -> Result < ( ) > {
73+ let Some ( hwnd) = self . hwnd . get ( ) else { return Ok ( ( ) ) } ;
74+ let new_size = new_size. to_physical ( self . state . scale_factor ( ) ) ;
75+ hwnd. resize_and_activate ( new_size, self . state . current_dpi . get ( ) , & self . state . user32 ) ?;
76+
77+ if self . state . current_size . get ( ) == new_size {
78+ Ok ( ( ) )
79+ } else {
80+ Err ( Error :: ResizeFailed )
81+ }
82+ }
83+
84+ pub fn suggest_scale_factor ( & self , _scale_factor : f64 ) -> Result < ( ) > {
85+ todo ! ( )
86+ }
6887}
6988
7089impl Drop for WindowHandle {
@@ -106,22 +125,19 @@ impl WindowImpl for BaseviewWindow {
106125 // Now we can get the actual dpi of the window.
107126 let dpi = window. get_dpi ( & self . window_state . user32 ) ?;
108127
109- if dpi != window_state. current_dpi . get ( ) {
110- window_state. current_dpi . set ( dpi) ;
111-
112- // If the user's requested initial size was in system-scaled logical pixels
113- if let WindowScalePolicy :: SystemScaleFactor = self . window_state . scale_policy {
114- // We cannot create a window in "logical" pixels, and we can't DPI-scale to physical pixels because we
115- // have no way to know where the window will end up.
116- // So, at window creation, we assume a DPI=96, and if it ends up wrong, we resize the window
117- // to the actual logical size the user desired.
118- let new_size = self . initial_size . to_physical ( dpi. scale_factor ( ) ) ;
119-
120- // Preemptively update so a synchronous WM_SIZE from SetWindowPos below
121- // doesn't also emit Resized.
122- window_state. current_size . set ( new_size) ;
123- window. resize_and_activate ( new_size, dpi, & window_state. user32 ) ?;
124- }
128+ if dpi != window_state. shared . current_dpi . get ( ) {
129+ window_state. shared . current_dpi . set ( dpi) ;
130+
131+ // We cannot create a window in "logical" pixels, and we can't DPI-scale to physical pixels because we
132+ // have no way to know where the window will end up.
133+ // So, at window creation, we assume a DPI=96, and if it ends up wrong, we resize the window
134+ // to the actual logical size the user desired.
135+ let new_size = self . initial_size . to_physical ( dpi. scale_factor ( ) ) ;
136+
137+ // Preemptively update so a synchronous WM_SIZE from SetWindowPos below
138+ // doesn't also emit Resized.
139+ window_state. shared . current_size . set ( new_size) ;
140+ window. resize_and_activate ( new_size, dpi, & window_state. user32 ) ?;
125141 }
126142
127143 let drop_target = ComObject :: new ( DropTarget :: new ( Rc :: downgrade ( window_state) , window) ) ;
@@ -330,24 +346,26 @@ unsafe fn wnd_proc_inner(
330346 let height = ( ( lparam >> 16 ) & 0xFFFF ) as u16 as u32 ;
331347
332348 let new_size = PhysicalSize { width, height } ;
333- let current_size = window_state. current_size . get ( ) ;
349+ let current_size = window_state. shared . current_size . get ( ) ;
334350
335351 // Only send the event if anything changed
336352 if current_size == new_size {
337353 return None ;
338354 }
339355
340- let previous = window_state. current_size . replace ( new_size) ;
341- let new_size = WindowSize :: from_physical ( new_size, window_state. scale_factor ( ) ) ;
356+ let previous = window_state. shared . current_size . replace ( new_size) ;
357+ let new_size = WindowSize :: from_physical ( new_size, window_state. shared . scale_factor ( ) ) ;
342358
343359 let handler = window_state. handler . get ( ) ?;
344360 if let Err ( e) = handler. resized ( new_size) {
345361 warn ! ( "Window Handler failed to resize: {}" , e) ;
346- window_state. current_size . set ( previous) ;
362+ window_state. shared . current_size . set ( previous) ;
347363
348364 if let Err ( e) = window_state. resize ( previous. into ( ) ) {
349365 warn ! ( "Failed to resize back to previous window size: {}" , e) ;
350366 }
367+
368+ return Some ( -1 ) ;
351369 }
352370
353371 None
@@ -363,11 +381,11 @@ unsafe fn wnd_proc_inner(
363381
364382 let new_size = suggested_rect. size ( ) ;
365383
366- let changed = window_state. current_size . get ( ) != new_size
367- || window_state. current_dpi . get ( ) != dpi;
384+ let changed = window_state. shared . current_size . get ( ) != new_size
385+ || window_state. shared . current_dpi . get ( ) != dpi;
368386
369- window_state. current_dpi . replace ( dpi) ;
370- let previous_size = window_state. current_size . replace ( new_size) ;
387+ window_state. shared . current_dpi . replace ( dpi) ;
388+ let previous_size = window_state. shared . current_size . replace ( new_size) ;
371389
372390 // Windows makes us resize the window manually. This however will not send a WM_SIZE event,
373391 // hence why we are notifying the window handler manually below.
@@ -379,7 +397,7 @@ unsafe fn wnd_proc_inner(
379397
380398 if let Err ( e) = handler. resized ( new_size) {
381399 warn ! ( "Window Handler failed to resize: {}" , e) ;
382- window_state. current_size . set ( previous_size) ;
400+ window_state. shared . current_size . set ( previous_size) ;
383401
384402 if let Err ( e) = window_state. resize ( previous_size. into ( ) ) {
385403 warn ! ( "Failed to resize back to previous window size: {}" , e) ;
@@ -422,10 +440,7 @@ impl WindowHandle {
422440 let extended_user_32 = ExtendedUser32 :: load ( ) ?;
423441 let title = HSTRING :: from ( options. title ) ;
424442
425- let scaling_factor = match options. scale {
426- WindowScalePolicy :: SystemScaleFactor => 1.0 ,
427- WindowScalePolicy :: ScaleFactor ( scale) => scale,
428- } ;
443+ let scaling_factor = 1.0 ;
429444
430445 let window_size = options. size . to_physical ( scaling_factor) ;
431446
@@ -435,20 +450,21 @@ impl WindowHandle {
435450 WindowStyle :: embedded ( )
436451 } ;
437452 let dpi_ctx = DpiAwarenessContext :: new ( & extended_user_32) ?;
438-
439- let rect = dpi_ctx. client_area_to_nc_area ( window_size. into ( ) , style, Dpi :: default ( ) ) ?;
453+ let shared_state = WindowSharedState :: new ( window_size, extended_user_32. clone ( ) ) ;
440454
441455 let initializer = {
442456 let extended_user_32 = extended_user_32. clone ( ) ;
457+ let shared_state = shared_state. clone ( ) ;
443458
444459 move |hwnd : HWnd | {
445460 let window_state =
446- Rc :: new ( WindowState :: new ( hwnd, window_size , options . scale , extended_user_32 ) ) ;
461+ Rc :: new ( WindowState :: new ( hwnd, extended_user_32 , shared_state . clone ( ) ) ) ;
447462
448463 BaseviewWindow {
449464 window_state,
450465 initial_size : options. size ,
451466 handler_builder : Cell :: new ( Some ( build) ) ,
467+ shared_state,
452468
453469 _drop_target : None . into ( ) ,
454470 _keyboard_hook : None . into ( ) ,
@@ -460,6 +476,7 @@ impl WindowHandle {
460476 } ;
461477
462478 let parent = options. parent . map ( |p| p. handle ) ;
479+ let rect = dpi_ctx. client_area_to_nc_area ( window_size. into ( ) , style, Dpi :: default ( ) ) ?;
463480
464481 let window = create_window ( & title, style, rect. size ( ) , parent, & dpi_ctx, initializer) ?;
465482
@@ -472,7 +489,7 @@ impl WindowHandle {
472489
473490 window. show_and_activate ( ) ;
474491
475- Ok ( WindowHandle { hwnd : Some ( window) . into ( ) , is_open : Rc :: clone ( & is_open ) } )
492+ Ok ( WindowHandle { hwnd : Some ( window) . into ( ) , state : shared_state } )
476493 }
477494}
478495
0 commit comments