@@ -2642,13 +2642,37 @@ fn handle_user_message<T: UserEvent>(
26422642 }
26432643 // Setters
26442644 WindowMessage :: Center => {
2645+ #[ cfg( not( target_os = "macos" ) ) ]
26452646 if let Some ( monitor) = window. current_monitor ( ) {
2646- let window_size = inner_size ( & window, & webviews, has_children) ;
2647- let screen_size = monitor. size ( ) ;
2648- let monitor_pos = monitor. position ( ) ;
2649- let x = ( screen_size. width as i32 - window_size. width as i32 ) / 2 + monitor_pos. x ;
2650- let y = ( screen_size. height as i32 - window_size. height as i32 ) / 2 + monitor_pos. y ;
2651- window. set_outer_position ( TaoPhysicalPosition :: new ( x, y) ) ;
2647+ #[ allow( unused_mut) ]
2648+ let mut window_size = window. outer_size ( ) ;
2649+ #[ cfg( windows) ]
2650+ if window. is_decorated ( ) {
2651+ use windows:: Win32 :: Foundation :: RECT ;
2652+ use windows:: Win32 :: Graphics :: Dwm :: {
2653+ DwmGetWindowAttribute , DWMWA_EXTENDED_FRAME_BOUNDS ,
2654+ } ;
2655+ let mut rect = RECT :: default ( ) ;
2656+ let result = unsafe {
2657+ DwmGetWindowAttribute (
2658+ HWND ( window. hwnd ( ) ) ,
2659+ DWMWA_EXTENDED_FRAME_BOUNDS ,
2660+ & mut rect as * mut _ as * mut _ ,
2661+ std:: mem:: size_of :: < RECT > ( ) as u32 ,
2662+ )
2663+ } ;
2664+ if result. is_ok ( ) {
2665+ window_size. height = ( rect. bottom - rect. top ) as u32 ;
2666+ }
2667+ }
2668+ window. set_outer_position ( calculate_window_center_position ( window_size, monitor) ) ;
2669+ }
2670+
2671+ #[ cfg( target_os = "macos" ) ]
2672+ {
2673+ use cocoa:: { appkit:: NSWindow , base:: id} ;
2674+ let ns_window: id = window. ns_window ( ) as _ ;
2675+ unsafe { ns_window. center ( ) } ;
26522676 }
26532677 }
26542678 WindowMessage :: RequestUserAttention ( request_type) => {
@@ -3511,18 +3535,29 @@ fn create_window<T: UserEvent, F: Fn(RawWindow) + Send + 'static>(
35113535 . inner_size
35123536 . unwrap_or_else ( || TaoPhysicalSize :: new ( 800 , 600 ) . into ( ) ) ;
35133537 let scale_factor = monitor. scale_factor ( ) ;
3514- let window_size = window_builder
3538+ #[ allow( unused_mut) ]
3539+ let mut window_size = window_builder
35153540 . inner
35163541 . window
35173542 . inner_size_constraints
35183543 . clamp ( desired_size, scale_factor)
3519- . to_logical :: < i32 > ( scale_factor) ;
3520- let screen_size = monitor. size ( ) . to_logical :: < i32 > ( scale_factor) ;
3521- let monitor_pos = monitor. position ( ) . to_logical :: < i32 > ( scale_factor) ;
3522- let x = ( screen_size. width - window_size. width ) / 2 + monitor_pos. x ;
3523- let y = ( screen_size. height - window_size. height ) / 2 + monitor_pos. y ;
3524-
3525- window_builder = window_builder. position ( x as f64 , y as f64 ) ;
3544+ . to_physical :: < u32 > ( scale_factor) ;
3545+ #[ cfg( windows) ]
3546+ {
3547+ if window_builder. inner . window . decorations {
3548+ use windows:: Win32 :: UI :: WindowsAndMessaging :: { AdjustWindowRect , WS_OVERLAPPEDWINDOW } ;
3549+ let mut rect = windows:: Win32 :: Foundation :: RECT :: default ( ) ;
3550+ let result = unsafe { AdjustWindowRect ( & mut rect, WS_OVERLAPPEDWINDOW , false ) } ;
3551+ if result. is_ok ( ) {
3552+ window_size. width += ( rect. right - rect. left ) as u32 ;
3553+ // rect.bottom is made out of shadow, and we don't care about it
3554+ window_size. height += -rect. top as u32 ;
3555+ }
3556+ }
3557+ }
3558+ let position = calculate_window_center_position ( window_size, monitor) ;
3559+ let logical_position = position. to_logical :: < f64 > ( scale_factor) ;
3560+ window_builder = window_builder. position ( logical_position. x , logical_position. y ) ;
35263561 }
35273562 }
35283563
@@ -4060,6 +4095,32 @@ fn inner_size(
40604095 window. inner_size ( )
40614096}
40624097
4098+ fn calculate_window_center_position (
4099+ window_size : TaoPhysicalSize < u32 > ,
4100+ target_monitor : MonitorHandle ,
4101+ ) -> TaoPhysicalPosition < i32 > {
4102+ #[ cfg( windows) ]
4103+ {
4104+ use tao:: platform:: windows:: MonitorHandleExtWindows ;
4105+ use windows:: Win32 :: Graphics :: Gdi :: { GetMonitorInfoW , HMONITOR , MONITORINFO } ;
4106+ let mut monitor_info = MONITORINFO :: default ( ) ;
4107+ monitor_info. cbSize = std:: mem:: size_of :: < MONITORINFO > ( ) as u32 ;
4108+ let status = unsafe { GetMonitorInfoW ( HMONITOR ( target_monitor. hmonitor ( ) ) , & mut monitor_info) } ;
4109+ if status. into ( ) {
4110+ let available_width = monitor_info. rcWork . right - monitor_info. rcWork . left ;
4111+ let available_height = monitor_info. rcWork . bottom - monitor_info. rcWork . top ;
4112+ let x = ( available_width - window_size. width as i32 ) / 2 + monitor_info. rcWork . left ;
4113+ let y = ( available_height - window_size. height as i32 ) / 2 + monitor_info. rcWork . top ;
4114+ return TaoPhysicalPosition :: new ( x, y) ;
4115+ }
4116+ }
4117+ let screen_size = target_monitor. size ( ) ;
4118+ let monitor_pos = target_monitor. position ( ) ;
4119+ let x = ( screen_size. width as i32 - window_size. width as i32 ) / 2 + monitor_pos. x ;
4120+ let y = ( screen_size. height as i32 - window_size. height as i32 ) / 2 + monitor_pos. y ;
4121+ TaoPhysicalPosition :: new ( x, y)
4122+ }
4123+
40634124#[ cfg( windows) ]
40644125fn clear_window_surface (
40654126 window : & Window ,
0 commit comments