1
- use bevy_math:: IVec2 ;
2
- use bevy_utils:: { tracing :: warn , HashMap } ;
3
- use bevy_window:: { Window , WindowDescriptor , WindowId , WindowMode } ;
1
+ use bevy_math:: { DVec2 , IVec2 } ;
2
+ use bevy_utils:: HashMap ;
3
+ use bevy_window:: { MonitorSelection , Window , WindowDescriptor , WindowId , WindowMode } ;
4
4
use raw_window_handle:: HasRawWindowHandle ;
5
- use winit:: dpi:: { LogicalPosition , LogicalSize , PhysicalPosition } ;
5
+ use winit:: {
6
+ dpi:: { LogicalPosition , LogicalSize , PhysicalPosition , PhysicalSize } ,
7
+ window:: Fullscreen ,
8
+ } ;
6
9
7
10
#[ derive( Debug , Default ) ]
8
11
pub struct WinitWindows {
@@ -24,86 +27,43 @@ impl WinitWindows {
24
27
) -> Window {
25
28
let mut winit_window_builder = winit:: window:: WindowBuilder :: new ( ) ;
26
29
30
+ let & WindowDescriptor {
31
+ width,
32
+ height,
33
+ position,
34
+ monitor,
35
+ scale_factor_override,
36
+ ..
37
+ } = window_descriptor;
38
+
39
+ let logical_size = LogicalSize :: new ( width, height) ;
40
+
41
+ let monitor = match monitor {
42
+ MonitorSelection :: Current => None ,
43
+ MonitorSelection :: Primary => event_loop. primary_monitor ( ) ,
44
+ MonitorSelection :: Index ( i) => event_loop. available_monitors ( ) . nth ( i) ,
45
+ } ;
46
+
47
+ let selected_or_primary_monitor = monitor. clone ( ) . or_else ( || event_loop. primary_monitor ( ) ) ;
48
+
27
49
winit_window_builder = match window_descriptor. mode {
28
- WindowMode :: BorderlessFullscreen => winit_window_builder. with_fullscreen ( Some (
29
- winit:: window:: Fullscreen :: Borderless ( event_loop. primary_monitor ( ) ) ,
50
+ WindowMode :: BorderlessFullscreen => winit_window_builder
51
+ . with_fullscreen ( Some ( Fullscreen :: Borderless ( selected_or_primary_monitor) ) ) ,
52
+ WindowMode :: Fullscreen => winit_window_builder. with_fullscreen ( Some (
53
+ Fullscreen :: Exclusive ( get_best_videomode ( & selected_or_primary_monitor. unwrap ( ) ) ) ,
30
54
) ) ,
31
- WindowMode :: Fullscreen => {
32
- winit_window_builder. with_fullscreen ( Some ( winit:: window:: Fullscreen :: Exclusive (
33
- get_best_videomode ( & event_loop. primary_monitor ( ) . unwrap ( ) ) ,
34
- ) ) )
35
- }
36
55
WindowMode :: SizedFullscreen => winit_window_builder. with_fullscreen ( Some (
37
- winit :: window :: Fullscreen :: Exclusive ( get_fitting_videomode (
38
- & event_loop . primary_monitor ( ) . unwrap ( ) ,
56
+ Fullscreen :: Exclusive ( get_fitting_videomode (
57
+ & selected_or_primary_monitor . unwrap ( ) ,
39
58
window_descriptor. width as u32 ,
40
59
window_descriptor. height as u32 ,
41
60
) ) ,
42
61
) ) ,
43
62
_ => {
44
- let WindowDescriptor {
45
- width,
46
- height,
47
- position,
48
- scale_factor_override,
49
- ..
50
- } = window_descriptor;
51
-
52
- use bevy_window:: WindowPosition :: * ;
53
- match position {
54
- Automatic => { /* Window manager will handle position */ }
55
- Centered ( monitor_selection) => {
56
- use bevy_window:: MonitorSelection :: * ;
57
- let maybe_monitor = match monitor_selection {
58
- Current => {
59
- warn ! ( "Can't select current monitor on window creation!" ) ;
60
- None
61
- }
62
- Primary => event_loop. primary_monitor ( ) ,
63
- Number ( n) => event_loop. available_monitors ( ) . nth ( * n) ,
64
- } ;
65
-
66
- if let Some ( monitor) = maybe_monitor {
67
- let screen_size = monitor. size ( ) ;
68
-
69
- let scale_factor = monitor. scale_factor ( ) ;
70
-
71
- // Logical to physical window size
72
- let ( width, height) : ( u32 , u32 ) = LogicalSize :: new ( * width, * height)
73
- . to_physical :: < u32 > ( scale_factor)
74
- . into ( ) ;
75
-
76
- let position = PhysicalPosition {
77
- x : screen_size. width . saturating_sub ( width) as f64 / 2.
78
- + monitor. position ( ) . x as f64 ,
79
- y : screen_size. height . saturating_sub ( height) as f64 / 2.
80
- + monitor. position ( ) . y as f64 ,
81
- } ;
82
-
83
- winit_window_builder = winit_window_builder. with_position ( position) ;
84
- } else {
85
- warn ! ( "Couldn't get monitor selected with: {monitor_selection:?}" ) ;
86
- }
87
- }
88
- At ( position) => {
89
- if let Some ( sf) = scale_factor_override {
90
- winit_window_builder = winit_window_builder. with_position (
91
- LogicalPosition :: new ( position[ 0 ] as f64 , position[ 1 ] as f64 )
92
- . to_physical :: < f64 > ( * sf) ,
93
- ) ;
94
- } else {
95
- winit_window_builder = winit_window_builder. with_position (
96
- LogicalPosition :: new ( position[ 0 ] as f64 , position[ 1 ] as f64 ) ,
97
- ) ;
98
- }
99
- }
100
- }
101
-
102
63
if let Some ( sf) = scale_factor_override {
103
- winit_window_builder
104
- . with_inner_size ( LogicalSize :: new ( * width, * height) . to_physical :: < f64 > ( * sf) )
64
+ winit_window_builder. with_inner_size ( logical_size. to_physical :: < f64 > ( sf) )
105
65
} else {
106
- winit_window_builder. with_inner_size ( LogicalSize :: new ( * width , * height ) )
66
+ winit_window_builder. with_inner_size ( logical_size )
107
67
}
108
68
}
109
69
. with_resizable ( window_descriptor. resizable )
@@ -155,6 +115,49 @@ impl WinitWindows {
155
115
156
116
let winit_window = winit_window_builder. build ( event_loop) . unwrap ( ) ;
157
117
118
+ if window_descriptor. mode == WindowMode :: Windowed {
119
+ use bevy_window:: WindowPosition :: * ;
120
+ match position {
121
+ Automatic => {
122
+ if let Some ( monitor) = monitor {
123
+ winit_window. set_outer_position ( monitor. position ( ) ) ;
124
+ }
125
+ }
126
+ Centered => {
127
+ if let Some ( monitor) = monitor. or_else ( || winit_window. current_monitor ( ) ) {
128
+ let monitor_position = monitor. position ( ) . cast :: < f64 > ( ) ;
129
+ let size = monitor. size ( ) ;
130
+
131
+ // Logical to physical window size
132
+ let PhysicalSize :: < u32 > { width, height } =
133
+ logical_size. to_physical ( monitor. scale_factor ( ) ) ;
134
+
135
+ let position = PhysicalPosition {
136
+ x : size. width . saturating_sub ( width) as f64 / 2. + monitor_position. x ,
137
+ y : size. height . saturating_sub ( height) as f64 / 2. + monitor_position. y ,
138
+ } ;
139
+
140
+ winit_window. set_outer_position ( position) ;
141
+ }
142
+ }
143
+ At ( position) => {
144
+ if let Some ( monitor) = monitor. or_else ( || winit_window. current_monitor ( ) ) {
145
+ let monitor_position = DVec2 :: from ( <( _ , _ ) >:: from ( monitor. position ( ) ) ) ;
146
+ let position = monitor_position + position. as_dvec2 ( ) ;
147
+
148
+ if let Some ( sf) = scale_factor_override {
149
+ winit_window. set_outer_position (
150
+ LogicalPosition :: new ( position. x , position. y ) . to_physical :: < f64 > ( sf) ,
151
+ ) ;
152
+ } else {
153
+ winit_window
154
+ . set_outer_position ( LogicalPosition :: new ( position. x , position. y ) ) ;
155
+ }
156
+ }
157
+ }
158
+ }
159
+ }
160
+
158
161
if window_descriptor. cursor_locked {
159
162
match winit_window. set_cursor_grab ( true ) {
160
163
Ok ( _) | Err ( winit:: error:: ExternalError :: NotSupported ( _) ) => { }
0 commit comments