@@ -81,8 +81,36 @@ impl WindowHandle {
8181 }
8282 }
8383
84- pub fn suggest_scale_factor ( & self , _scale_factor : f64 ) -> Result < ( ) > {
85- todo ! ( )
84+ pub fn suggest_scale_factor ( & self , scale_factor : f64 ) -> Result < ( ) > {
85+ let Some ( hwnd) = self . hwnd . get ( ) else { return Ok ( ( ) ) } ;
86+
87+ let current_scale_factor = self . state . scale_factor ( ) ;
88+ self . state . fallback_scale_factor . set ( Some ( scale_factor) ) ;
89+
90+ if self . state . current_dpi . get ( ) . is_some ( ) {
91+ return Ok ( ( ) ) ;
92+ }
93+
94+ let current_size = self . state . current_size . get ( ) ;
95+ let new_size = self
96+ . state
97+ . current_size
98+ . get ( )
99+ . to_logical :: < f64 > ( current_scale_factor)
100+ . to_physical ( self . state . scale_factor ( ) ) ;
101+
102+ // This call doesn't meaningfully change the scaling factor, ignore the result
103+ if current_size == new_size {
104+ return Ok ( ( ) ) ;
105+ }
106+
107+ hwnd. resize_and_activate ( new_size, None , & self . state . user32 ) ?;
108+
109+ if self . state . current_size . get ( ) == new_size {
110+ Ok ( ( ) )
111+ } else {
112+ Err ( Error :: ResizeFailed )
113+ }
86114 }
87115}
88116
@@ -125,19 +153,21 @@ impl WindowImpl for BaseviewWindow {
125153 // Now we can get the actual dpi of the window.
126154 let dpi = window. get_dpi ( & self . window_state . user32 ) ?;
127155
128- if dpi != window_state. shared . current_dpi . get ( ) {
129- window_state. shared . current_dpi . set ( dpi) ;
156+ if let Some ( dpi) = dpi {
157+ if Some ( dpi) != window_state. shared . current_dpi . get ( ) {
158+ window_state. shared . current_dpi . set ( Some ( dpi) ) ;
130159
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 ( ) ) ;
160+ // We cannot create a window in "logical" pixels, and we can't DPI-scale to physical pixels because we
161+ // have no way to know where the window will end up.
162+ // So, at window creation, we assume a DPI=96, and if it ends up wrong, we resize the window
163+ // to the actual logical size the user desired.
164+ let new_size = self . initial_size . to_physical ( dpi. scale_factor ( ) ) ;
136165
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 ) ?;
166+ // Preemptively update so a synchronous WM_SIZE from SetWindowPos below
167+ // doesn't also emit Resized.
168+ window_state. shared . current_size . set ( new_size) ;
169+ window. resize_and_activate ( new_size, Some ( dpi) , & window_state. user32 ) ?;
170+ }
141171 }
142172
143173 let drop_target = ComObject :: new ( DropTarget :: new ( Rc :: downgrade ( window_state) , window) ) ;
@@ -377,14 +407,14 @@ unsafe fn wnd_proc_inner(
377407 let dpi_ctx = DpiAwarenessContext :: new ( & window_state. user32 ) . unwrap ( ) ;
378408 let style = window. get_style ( ) . unwrap ( ) ;
379409 let suggested_rect =
380- dpi_ctx. nc_area_to_client_area ( suggested_nc_rect, style, dpi) . unwrap ( ) ;
410+ dpi_ctx. nc_area_to_client_area ( suggested_nc_rect, style, Some ( dpi) ) . unwrap ( ) ;
381411
382412 let new_size = suggested_rect. size ( ) ;
383413
384414 let changed = window_state. shared . current_size . get ( ) != new_size
385- || window_state. shared . current_dpi . get ( ) != dpi;
415+ || window_state. shared . current_dpi . get ( ) != Some ( dpi) ;
386416
387- window_state. shared . current_dpi . replace ( dpi) ;
417+ window_state. shared . current_dpi . replace ( Some ( dpi) ) ;
388418 let previous_size = window_state. shared . current_size . replace ( new_size) ;
389419
390420 // Windows makes us resize the window manually. This however will not send a WM_SIZE event,
@@ -476,7 +506,7 @@ impl WindowHandle {
476506 } ;
477507
478508 let parent = options. parent . map ( |p| p. handle ) ;
479- let rect = dpi_ctx. client_area_to_nc_area ( window_size. into ( ) , style, Dpi :: default ( ) ) ?;
509+ let rect = dpi_ctx. client_area_to_nc_area ( window_size. into ( ) , style, None ) ?;
480510
481511 let window = create_window ( & title, style, rect. size ( ) , parent, & dpi_ctx, initializer) ?;
482512
0 commit comments