Skip to content

Commit 19b3f80

Browse files
committed
Apply initial configuration, surprisingly little code...
1 parent 0c43395 commit 19b3f80

File tree

7 files changed

+254
-68
lines changed

7 files changed

+254
-68
lines changed

sources/Windowing/Windowing/Implementations/SDL3/SdlSurfaceComponents.Children.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using Silk.NET.SDL;
5+
46
namespace Silk.NET.Windowing.SDL3;
57

68
internal partial class SdlSurfaceComponents : ISurfaceChildren
@@ -10,6 +12,14 @@ internal partial class SdlSurfaceComponents : ISurfaceChildren
1012
public void Spawn<T>()
1113
where T : ISurfaceApplication
1214
{
15+
if (!IsSurfaceInitialized)
16+
{
17+
throw new InvalidOperationException(
18+
"Children cannot be spawned until ISurfaceApplication.Initialize<TSurface>(TSurface) has finished "
19+
+ "executing, consider using the Surface.Created callback instead."
20+
);
21+
}
22+
1323
_children ??= new List<SdlSurface>(1);
1424
var child = SdlSurfaceLifecycle.CoreInit<T>(surface);
1525
child.Terminating += _ =>
@@ -48,4 +58,15 @@ public void TerminateChildren()
4858
child.Terminate();
4959
}
5060
}
61+
62+
private unsafe void InitializeChildren(uint createProps)
63+
{
64+
if (
65+
surface.Parent is { Impl.Handle.Handle: not null and var handle }
66+
&& !Sdl.SetPointerProperty(createProps, Sdl.PropWindowCreateParentPointer, handle)
67+
)
68+
{
69+
Sdl.ThrowError();
70+
}
71+
}
5172
}

sources/Windowing/Windowing/Implementations/SDL3/SdlSurfaceComponents.Display.cs

Lines changed: 129 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,57 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
using System.Diagnostics.CodeAnalysis;
4+
using Silk.NET.Maths;
55
using Silk.NET.SDL;
66

77
namespace Silk.NET.Windowing.SDL3;
88

99
internal partial class SdlSurfaceComponents : ISurfaceDisplay
1010
{
1111
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+
1219
public IDisplay Current
1320
{
1421
get
1522
{
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)
1726
{
1827
return ret;
1928
}
2029

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+
2455
if (current == 0)
2556
{
2657
Sdl.ThrowError();
@@ -41,7 +72,8 @@ public IDisplay Current
4172
}
4273
set
4374
{
44-
if (value.Equals(_display))
75+
var current = Current;
76+
if (value.Equals(current))
4577
{
4678
return;
4779
}
@@ -67,36 +99,28 @@ public IDisplay Current
6799
}
68100

69101
var videoMode = VideoMode;
70-
if (!IsSurfaceInitialized)
102+
if (!IsSurfaceInitialized && !IsDisplayDeterminedByPosition)
71103
{
72104
Return(sdlDisplay, videoMode);
73105
return;
74106
}
75107

76108
if (videoMode == default) // not fullscreen
77109
{
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;
86112
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+
);
97117
}
98118
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+
)
100124
)
101125
{
102126
Sdl.ThrowError();
@@ -134,6 +158,36 @@ is not (WindowState.ExclusiveFullscreen or WindowState.WindowedFullscreen)
134158
new DisplayVideoModeAvailabilityChangeEvent(surface, display)
135159
);
136160
}
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+
}
137191
}
138192
}
139193

@@ -208,7 +262,7 @@ is not (WindowState.ExclusiveFullscreen or WindowState.WindowedFullscreen)
208262
{
209263
if (value != default)
210264
{
211-
Throw();
265+
ThrowBadVideoMode(nameof(value));
212266
}
213267

214268
return;
@@ -220,42 +274,48 @@ is not (WindowState.ExclusiveFullscreen or WindowState.WindowedFullscreen)
220274
}
221275

222276
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+
}
231286

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+
);
236292

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;
239302
}
240303

241-
if (!found)
304+
if (i > 0)
242305
{
243-
Throw();
306+
displayMode = display.DisplayModes[i - 1];
244307
}
245308

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));
258316
}
317+
318+
return displayMode;
259319
}
260320

261321
public IReadOnlyList<VideoMode> AvailableVideoModes =>
@@ -341,8 +401,6 @@ internal void OnPotentialVideoModeChanges(uint id, out bool isCurrent, uint curr
341401
}
342402
}
343403

344-
private void InitializeDisplay(uint props) { }
345-
346404
public void OnVideoModeChanged()
347405
{
348406
var oldVideoMode = _videoMode;
@@ -356,4 +414,18 @@ public void OnVideoModeChanged()
356414

357415
public void OnCurrentDisplayChanged() =>
358416
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+
}
359431
}

sources/Windowing/Windowing/Implementations/SDL3/SdlSurfaceComponents.OpenGL.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ private void InitializeOpenGL(uint props)
417417
return;
418418
}
419419

420-
AddWindowCreateFlag(props, Sdl.WindowOpengl);
420+
AddWindowCreateFlags(props, Sdl.WindowOpengl);
421421
}
422422

423423
private void PostInitializeOpenGL()

sources/Windowing/Windowing/Implementations/SDL3/SdlSurfaceComponents.Scale.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,6 @@ private void InitializeScale(uint createProps)
101101
Sdl.ThrowError();
102102
}
103103
}
104+
105+
private void PostInitializeScale() => OnPotentialScaleChanges();
104106
}

sources/Windowing/Windowing/Implementations/SDL3/SdlSurfaceComponents.Vulkan.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,6 @@ private void InitializeVulkan(uint props)
6868
return;
6969
}
7070

71-
AddWindowCreateFlag(props, Sdl.WindowVulkan);
71+
AddWindowCreateFlags(props, Sdl.WindowVulkan);
7272
}
7373
}

0 commit comments

Comments
 (0)