@@ -27,7 +27,7 @@ private void setupWindowing(FrameworkConfigManager config)
2727 ScheduleCommand ( ( ) => SDL_SetHint ( SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS , e . NewValue ? "1" : "0" ) ) ;
2828 } , true ) ;
2929
30- fetchDisplays ( ) ;
30+ fetchDisplays ( generateFakeDisplayIfEmpty : true ) ;
3131
3232 DisplaysChanged += _ => CurrentDisplayBindable . Default = PrimaryDisplay ;
3333 CurrentDisplayBindable . Default = PrimaryDisplay ;
@@ -292,6 +292,8 @@ public WindowState WindowState
292292 // ReSharper disable once UnusedParameter.Local
293293 private void handleDisplayEvent ( SDL_DisplayEvent evtDisplay ) => fetchDisplays ( ) ;
294294
295+ private static bool fetchDisplayModes => RuntimeInfo . IsDesktop ;
296+
295297 /// <summary>
296298 /// Updates <see cref="Displays"/> with the latest display information reported by SDL.
297299 /// </summary>
@@ -300,10 +302,36 @@ public WindowState WindowState
300302 /// <see cref="currentDisplay"/> /
301303 /// <see cref="CurrentDisplayBindable"/>.
302304 /// </remarks>
303- private void fetchDisplays ( )
305+ private void fetchDisplays ( bool generateFakeDisplayIfEmpty = false )
304306 {
305- Displays = getSDLDisplays ( ) ;
306- DisplaysChanged ? . Invoke ( Displays ) ;
307+ var newDisplays = getSDLDisplays ( ) ;
308+
309+ if ( generateFakeDisplayIfEmpty && newDisplays . Length == 0 )
310+ {
311+ Logger . Log ( "Got zero displays from SDL during startup. Generating a fake display so we have a valid one to prevent crashes." ) ;
312+
313+ newDisplays =
314+ [
315+ new Display ( 0 ,
316+ "Fake osu!framework display" ,
317+ new Rectangle ( 0 , 0 , 1920 , 1080 ) ,
318+ new Rectangle ( 0 , 0 , 1920 , 1080 ) ,
319+ fetchDisplayModes ? [ new DisplayMode ( "SDL_PIXELFORMAT_XRGB8888" , new Size ( 1920 , 1080 ) , 32 , 60f , 0 ) ] : [ ] )
320+ ] ;
321+ }
322+
323+ if ( newDisplays . Length > 0 )
324+ {
325+ Displays = newDisplays ;
326+ DisplaysChanged ? . Invoke ( newDisplays ) ;
327+ }
328+ else
329+ {
330+ // keep Displays stale if zero displays are currently detected
331+ Logger . Log ( "Got zero displays from SDL, ignoring." ) ;
332+ }
333+
334+ Debug . Assert ( Displays . Length > 0 ) ;
307335 }
308336
309337 /// <summary>
@@ -328,7 +356,7 @@ private static ImmutableArray<Display> getSDLDisplays()
328356 {
329357 int numDisplays = SDL_GetNumVideoDisplays ( ) ;
330358
331- if ( numDisplays <= 0 )
359+ if ( numDisplays < 0 )
332360 throw new InvalidOperationException ( $ "Failed to get number of SDL displays. Return code: { numDisplays } . SDL Error: { SDL_GetError ( ) } ") ;
333361
334362 var builder = ImmutableArray . CreateBuilder < Display > ( numDisplays ) ;
@@ -363,7 +391,7 @@ private static bool tryGetDisplayFromSDL(int displayIndex, [NotNullWhen(true)] o
363391
364392 DisplayMode [ ] displayModes = Array . Empty < DisplayMode > ( ) ;
365393
366- if ( RuntimeInfo . IsDesktop )
394+ if ( fetchDisplayModes )
367395 {
368396 int numModes = SDL_GetNumDisplayModes ( displayIndex ) ;
369397
0 commit comments