@@ -3,7 +3,7 @@ use crate::platform::x11::visual_info::WindowVisualConfig;
33use crate :: platform:: x11:: window_thread:: WindowThreadShared ;
44use crate :: platform:: x11:: xcb_window:: XcbWindow ;
55use crate :: platform:: * ;
6- use crate :: { MouseCursor , WindowOpenOptions , WindowScalePolicy , WindowSize } ;
6+ use crate :: { warn , MouseCursor , WindowHandler , WindowOpenOptions , WindowScalePolicy , WindowSize } ;
77use calloop:: LoopSignal ;
88use dpi:: { PhysicalSize , Size } ;
99use raw_window_handle:: { DisplayHandle , XlibWindowHandle } ;
@@ -13,14 +13,48 @@ use std::sync::Arc;
1313use x11rb:: protocol:: xproto:: { ChangeWindowAttributesAux , ConnectionExt , InputFocus , Visualid } ;
1414use x11rb:: CURRENT_TIME ;
1515
16+ pub struct ScalingFactor {
17+ system : Cell < Option < f64 > > ,
18+ suggested : Cell < Option < f64 > > ,
19+ }
20+
21+ impl ScalingFactor {
22+ pub fn get ( & self ) -> f64 {
23+ if let Some ( factor) = self . system . get ( ) {
24+ return factor;
25+ } ;
26+
27+ if let Some ( factor) = self . suggested . get ( ) {
28+ return factor;
29+ }
30+
31+ 1.0
32+ }
33+
34+ pub fn suggest ( & self , value : f64 ) -> bool {
35+ self . suggested . set ( Some ( value) ) ;
36+
37+ self . system . get ( ) . is_none ( )
38+ }
39+ }
40+
41+ impl From < Option < f64 > > for ScalingFactor {
42+ fn from ( value : Option < f64 > ) -> Self {
43+ // FIXME
44+ Self { system : None . into ( ) , suggested : None . into ( ) }
45+ }
46+ }
47+
1648pub ( crate ) struct WindowInner {
1749 // GlContext should be dropped **before** XcbConnection is dropped
1850 #[ cfg( feature = "opengl" ) ]
1951 gl_context : Option < super :: gl:: GlContext > ,
2052
2153 pub ( crate ) xcb_window : XcbWindow ,
2254 pub ( crate ) connection : Rc < X11Connection > ,
23- pub ( crate ) scaling_factor : Cell < f64 > ,
55+
56+ pub ( crate ) scaling_factor : ScalingFactor ,
57+
2458 window_size : Cell < PhysicalSize < u16 > > ,
2559 mouse_cursor : Cell < MouseCursor > ,
2660 pub ( crate ) visual_id : Visualid ,
@@ -41,11 +75,13 @@ impl WindowInner {
4175
4276 let scaling = match options. scale {
4377 WindowScalePolicy :: SystemScaleFactor => xcb_connection. get_scaling ( ) ,
44- WindowScalePolicy :: ScaleFactor ( scale) => scale,
78+ WindowScalePolicy :: ScaleFactor ( scale) => Some ( scale) ,
4579 } ;
4680
47- shared. set_scaling_factor ( scaling) ;
48- let physical_size = options. size . to_physical ( scaling) ;
81+ let initial_scale_factor = scaling. unwrap_or ( 1.0 ) ;
82+ shared. set_scaling_factor ( initial_scale_factor) ;
83+
84+ let physical_size = options. size . to_physical ( initial_scale_factor) ;
4985
5086 #[ cfg( feature = "opengl" ) ]
5187 let visual_info =
@@ -164,6 +200,28 @@ impl WindowInner {
164200 Ok ( ( ) )
165201 }
166202
203+ pub fn resize_immediately (
204+ & self , new_size : PhysicalSize < u16 > , handler : & dyn WindowHandler ,
205+ ) -> Result < ( ) > {
206+ let previous = self . store_size ( new_size) ;
207+
208+ if previous == new_size {
209+ return Ok ( ( ) ) ;
210+ } ;
211+
212+ self . xcb_window . resize ( new_size. cast ( ) ) ?; // Will not call handler, as size is the same as above.
213+
214+ if let Err ( e) =
215+ handler. resized ( WindowSize :: from_physical ( new_size. cast ( ) , self . scaling_factor . get ( ) ) )
216+ {
217+ warn ! ( "Window Handler failed to resize: {}. Reverting to previous size" , & e) ;
218+ self . store_size ( previous) ;
219+ return Err ( e. into ( ) ) ;
220+ }
221+
222+ Ok ( ( ) )
223+ }
224+
167225 pub fn window_handle ( & self ) -> Option < raw_window_handle:: WindowHandle < ' _ > > {
168226 let mut handle = XlibWindowHandle :: new ( self . xcb_window . id ( ) . get ( ) as _ ) ;
169227 handle. visual_id = self . visual_id . into ( ) ;
0 commit comments