1
1
// Licensed to the .NET Foundation under one or more agreements.
2
2
// The .NET Foundation licenses this file to you under the MIT license.
3
3
4
- using System . Diagnostics . CodeAnalysis ;
4
+ using Silk . NET . Maths ;
5
5
using Silk . NET . SDL ;
6
6
7
7
namespace Silk . NET . Windowing . SDL3 ;
8
8
9
9
internal partial class SdlSurfaceComponents : ISurfaceDisplay
10
10
{
11
11
private SdlDisplay ? _display ;
12
+ private bool CanPositionDetermineDisplay =>
13
+ IsWindowEnabled
14
+ && _state is not ( WindowState . ExclusiveFullscreen or WindowState . WindowedFullscreen ) ;
15
+
16
+ private bool IsDisplayDeterminedByPosition =>
17
+ CanPositionDetermineDisplay && ClientArea is not ( { Origin . X : - 1 } or { Origin . Y : - 1 } ) ;
18
+
12
19
public IDisplay Current
13
20
{
14
21
get
15
22
{
16
- if ( ! IsSurfaceInitialized && _display is { } ret )
23
+ // If Window decoration is not supported, then the display field is the exclusive determinant of the
24
+ // display. Note that if the surface is initialized we defer to SDL to get the most accurate result.
25
+ if ( ! IsSurfaceInitialized && ! IsDisplayDeterminedByPosition && _display is { } ret )
17
26
{
18
27
return ret ;
19
28
}
20
29
21
- var current = IsSurfaceInitialized
22
- ? Sdl . GetDisplayForWindow ( Handle )
23
- : Sdl . GetPrimaryDisplay ( ) ;
30
+ uint current ;
31
+ if ( IsSurfaceInitialized )
32
+ {
33
+ // Get the most up-to-date value.
34
+ current = Sdl . GetDisplayForWindow ( Handle ) ;
35
+ }
36
+ else if ( IsDisplayDeterminedByPosition )
37
+ {
38
+ // Determine the display from the requested position. -1 indicates "don't care" for which _display is
39
+ // the determinant.
40
+ var ca = ClientArea ;
41
+ var rect = new Rect
42
+ {
43
+ X = ( int ) ca . Origin . X ,
44
+ Y = ( int ) ca . Origin . Y ,
45
+ W = ( int ) ca . Size . X ,
46
+ H = ( int ) ca . Size . Y ,
47
+ } ;
48
+ current = Sdl . GetDisplayForRect ( rect . AsRef ( ) ) ;
49
+ }
50
+ else
51
+ {
52
+ current = Sdl . GetPrimaryDisplay ( ) ;
53
+ }
54
+
24
55
if ( current == 0 )
25
56
{
26
57
Sdl . ThrowError ( ) ;
@@ -41,7 +72,8 @@ public IDisplay Current
41
72
}
42
73
set
43
74
{
44
- if ( value . Equals ( _display ) )
75
+ var current = Current ;
76
+ if ( value . Equals ( current ) )
45
77
{
46
78
return ;
47
79
}
@@ -67,36 +99,28 @@ public IDisplay Current
67
99
}
68
100
69
101
var videoMode = VideoMode ;
70
- if ( ! IsSurfaceInitialized )
102
+ if ( ! IsSurfaceInitialized && ! IsDisplayDeterminedByPosition )
71
103
{
72
104
Return ( sdlDisplay , videoMode ) ;
73
105
return ;
74
106
}
75
107
76
108
if ( videoMode == default ) // not fullscreen
77
109
{
78
- var x = 0 ;
79
- var y = 0 ;
80
- if ( ! Sdl . GetWindowPosition ( Handle , x . AsRef ( ) , y . AsRef ( ) ) )
81
- {
82
- Sdl . ThrowError ( ) ;
83
- }
84
-
85
- var currentDisplayWorkArea = Current . WorkArea ;
110
+ GetPosition ( out var x , out var y ) ;
111
+ var currentDisplayWorkArea = current . WorkArea ;
86
112
var newDisplayWorkArea = sdlDisplay . WorkArea ;
87
- if (
88
- ! Sdl . SetWindowPosition (
89
- Handle ,
90
- ( int ) ( x - currentDisplayWorkArea . Origin . X + newDisplayWorkArea . Origin . X ) ,
91
- ( int ) ( y - currentDisplayWorkArea . Origin . Y + newDisplayWorkArea . Origin . Y )
92
- )
93
- )
94
- {
95
- Sdl . ThrowError ( ) ;
96
- }
113
+ SetPosition (
114
+ ( int ) ( x - currentDisplayWorkArea . Origin . X + newDisplayWorkArea . Origin . X ) ,
115
+ ( int ) ( y - currentDisplayWorkArea . Origin . Y + newDisplayWorkArea . Origin . Y )
116
+ ) ;
97
117
}
98
118
else if (
99
- ! Sdl . SetWindowFullscreenMode ( Handle , ( Ref < DisplayMode > ) sdlDisplay . DisplayModes [ 0 ] )
119
+ IsSurfaceInitialized
120
+ && ! Sdl . SetWindowFullscreenMode (
121
+ Handle ,
122
+ ( Ref < DisplayMode > ) sdlDisplay . DisplayModes [ 0 ]
123
+ )
100
124
)
101
125
{
102
126
Sdl . ThrowError ( ) ;
@@ -134,6 +158,36 @@ is not (WindowState.ExclusiveFullscreen or WindowState.WindowedFullscreen)
134
158
new DisplayVideoModeAvailabilityChangeEvent ( surface , display )
135
159
) ;
136
160
}
161
+
162
+ void GetPosition ( out int x , out int y )
163
+ {
164
+ ( x , y ) = ( 0 , 0 ) ;
165
+ if ( ! IsSurfaceInitialized )
166
+ {
167
+ var ca = ClientArea ;
168
+ ( x , y ) = ( ( int ) ca . Origin . X , ( int ) ca . Origin . Y ) ;
169
+ return ;
170
+ }
171
+
172
+ if ( ! Sdl . GetWindowPosition ( Handle , x . AsRef ( ) , y . AsRef ( ) ) )
173
+ {
174
+ Sdl . ThrowError ( ) ;
175
+ }
176
+ }
177
+
178
+ void SetPosition ( int x , int y )
179
+ {
180
+ if ( ! IsSurfaceInitialized )
181
+ {
182
+ ClientArea = ClientArea with { Origin = new Vector2D < float > ( x , y ) } ;
183
+ return ;
184
+ }
185
+
186
+ if ( ! Sdl . SetWindowPosition ( Handle , x , y ) )
187
+ {
188
+ Sdl . ThrowError ( ) ;
189
+ }
190
+ }
137
191
}
138
192
}
139
193
@@ -208,7 +262,7 @@ is not (WindowState.ExclusiveFullscreen or WindowState.WindowedFullscreen)
208
262
{
209
263
if ( value != default )
210
264
{
211
- Throw ( ) ;
265
+ ThrowBadVideoMode ( nameof ( value ) ) ;
212
266
}
213
267
214
268
return ;
@@ -220,42 +274,48 @@ is not (WindowState.ExclusiveFullscreen or WindowState.WindowedFullscreen)
220
274
}
221
275
222
276
var display = ( SdlDisplay ) Current ;
223
- Ptr < DisplayMode > displayMode = nullptr ;
224
- var found = false ;
225
- for ( var i = 0 ; i < display . KnownVideoModes ? . Count ; i ++ )
226
- {
227
- if ( display . KnownVideoModes [ i ] != value )
228
- {
229
- continue ;
230
- }
277
+ var displayMode = GetDisplayMode ( display , in value ) ;
278
+ SetState (
279
+ currentState ,
280
+ value == default ? WindowState . WindowedFullscreen : WindowState . ExclusiveFullscreen ,
281
+ ( value , displayMode ) ,
282
+ display
283
+ ) ;
284
+ }
285
+ }
231
286
232
- if ( i > 0 )
233
- {
234
- displayMode = display . DisplayModes [ i - 1 ] ;
235
- }
287
+ private static void ThrowBadVideoMode ( string ? arg ) =>
288
+ throw new ArgumentException (
289
+ "The given video mode is not one of the AvailableVideoModes." ,
290
+ arg
291
+ ) ;
236
292
237
- found = true ;
238
- break ;
293
+ private Ptr < DisplayMode > GetDisplayMode ( SdlDisplay display , in VideoMode value )
294
+ {
295
+ Ptr < DisplayMode > displayMode = nullptr ;
296
+ var found = false ;
297
+ for ( var i = 0 ; i < display . KnownVideoModes ? . Count ; i ++ )
298
+ {
299
+ if ( display . KnownVideoModes [ i ] != value )
300
+ {
301
+ continue ;
239
302
}
240
303
241
- if ( ! found )
304
+ if ( i > 0 )
242
305
{
243
- Throw ( ) ;
306
+ displayMode = display . DisplayModes [ i - 1 ] ;
244
307
}
245
308
246
- SetState (
247
- currentState ,
248
- value == default ? WindowState . WindowedFullscreen : WindowState . ExclusiveFullscreen ,
249
- ( value , displayMode ) ,
250
- display
251
- ) ;
252
- return ;
253
- static void Throw ( ) =>
254
- throw new ArgumentException (
255
- "The given video mode is not one of the AvailableVideoModes." ,
256
- nameof ( value )
257
- ) ;
309
+ found = true ;
310
+ break ;
311
+ }
312
+
313
+ if ( ! found )
314
+ {
315
+ ThrowBadVideoMode ( nameof ( value ) ) ;
258
316
}
317
+
318
+ return displayMode ;
259
319
}
260
320
261
321
public IReadOnlyList < VideoMode > AvailableVideoModes =>
@@ -341,8 +401,6 @@ internal void OnPotentialVideoModeChanges(uint id, out bool isCurrent, uint curr
341
401
}
342
402
}
343
403
344
- private void InitializeDisplay ( uint props ) { }
345
-
346
404
public void OnVideoModeChanged ( )
347
405
{
348
406
var oldVideoMode = _videoMode ;
@@ -356,4 +414,18 @@ public void OnVideoModeChanged()
356
414
357
415
public void OnCurrentDisplayChanged ( ) =>
358
416
CurrentDisplayChanged ? . Invoke ( new DisplayChangeEvent ( surface , Current ) ) ;
417
+
418
+ private void PostInitializeDisplay ( )
419
+ {
420
+ if (
421
+ _state == WindowState . ExclusiveFullscreen
422
+ && ! Sdl . SetWindowFullscreenMode (
423
+ Handle ,
424
+ ( Ref < DisplayMode > ) GetDisplayMode ( ( SdlDisplay ) Current , in _videoMode )
425
+ )
426
+ )
427
+ {
428
+ Sdl . ThrowError ( ) ;
429
+ }
430
+ }
359
431
}
0 commit comments