/ src / Ryujinx / App.axaml.cs
App.axaml.cs
  1  using Avalonia;
  2  using Avalonia.Controls.ApplicationLifetimes;
  3  using Avalonia.Markup.Xaml;
  4  using Avalonia.Platform;
  5  using Avalonia.Styling;
  6  using Avalonia.Threading;
  7  using Ryujinx.Ava.Common;
  8  using Ryujinx.Ava.Common.Locale;
  9  using Ryujinx.Ava.UI.Helpers;
 10  using Ryujinx.Ava.UI.Windows;
 11  using Ryujinx.Common;
 12  using Ryujinx.Common.Logging;
 13  using Ryujinx.UI.Common.Configuration;
 14  using Ryujinx.UI.Common.Helper;
 15  using System;
 16  using System.Diagnostics;
 17  
 18  namespace Ryujinx.Ava
 19  {
 20      public class App : Application
 21      {
 22          public override void Initialize()
 23          {
 24              Name = $"Ryujinx {Program.Version}";
 25  
 26              AvaloniaXamlLoader.Load(this);
 27  
 28              if (OperatingSystem.IsMacOS())
 29              {
 30                  Process.Start("/usr/bin/defaults", "write org.ryujinx.Ryujinx ApplePressAndHoldEnabled -bool false");
 31              }
 32          }
 33  
 34          public override void OnFrameworkInitializationCompleted()
 35          {
 36              if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
 37              {
 38                  desktop.MainWindow = new MainWindow();
 39              }
 40  
 41              base.OnFrameworkInitializationCompleted();
 42  
 43              if (Program.PreviewerDetached)
 44              {
 45                  ApplyConfiguredTheme();
 46  
 47                  ConfigurationState.Instance.UI.BaseStyle.Event += ThemeChanged_Event;
 48                  ConfigurationState.Instance.UI.CustomThemePath.Event += ThemeChanged_Event;
 49                  ConfigurationState.Instance.UI.EnableCustomTheme.Event += CustomThemeChanged_Event;
 50              }
 51          }
 52  
 53          private void CustomThemeChanged_Event(object sender, ReactiveEventArgs<bool> e)
 54          {
 55              ApplyConfiguredTheme();
 56          }
 57  
 58          private void ShowRestartDialog()
 59          {
 60  #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
 61              Dispatcher.UIThread.InvokeAsync(async () =>
 62              {
 63                  if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
 64                  {
 65                      var result = await ContentDialogHelper.CreateConfirmationDialog(
 66                          LocaleManager.Instance[LocaleKeys.DialogThemeRestartMessage],
 67                          LocaleManager.Instance[LocaleKeys.DialogThemeRestartSubMessage],
 68                          LocaleManager.Instance[LocaleKeys.InputDialogYes],
 69                          LocaleManager.Instance[LocaleKeys.InputDialogNo],
 70                          LocaleManager.Instance[LocaleKeys.DialogRestartRequiredMessage]);
 71  
 72                      if (result == UserResult.Yes)
 73                      {
 74                          var path = Environment.ProcessPath;
 75                          var proc = Process.Start(path, CommandLineState.Arguments);
 76                          desktop.Shutdown();
 77                          Environment.Exit(0);
 78                      }
 79                  }
 80              });
 81  #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
 82          }
 83  
 84          private void ThemeChanged_Event(object sender, ReactiveEventArgs<string> e)
 85          {
 86              ApplyConfiguredTheme();
 87          }
 88  
 89          public void ApplyConfiguredTheme()
 90          {
 91              try
 92              {
 93                  string baseStyle = ConfigurationState.Instance.UI.BaseStyle;
 94  
 95                  if (string.IsNullOrWhiteSpace(baseStyle))
 96                  {
 97                      ConfigurationState.Instance.UI.BaseStyle.Value = "Auto";
 98  
 99                      baseStyle = ConfigurationState.Instance.UI.BaseStyle;
100                  }
101  
102                  ThemeVariant systemTheme = DetectSystemTheme();
103  
104                  ThemeManager.OnThemeChanged();
105  
106                  RequestedThemeVariant = baseStyle switch
107                  {
108                      "Auto" => systemTheme,
109                      "Light" => ThemeVariant.Light,
110                      "Dark" => ThemeVariant.Dark,
111                      _ => ThemeVariant.Default,
112                  };
113              }
114              catch (Exception)
115              {
116                  Logger.Warning?.Print(LogClass.Application, "Failed to Apply Theme. A restart is needed to apply the selected theme");
117  
118                  ShowRestartDialog();
119              }
120          }
121  
122          /// <summary>
123          /// Converts a PlatformThemeVariant value to the corresponding ThemeVariant value.
124          /// </summary>
125          public static ThemeVariant ConvertThemeVariant(PlatformThemeVariant platformThemeVariant) =>
126              platformThemeVariant switch
127              {
128                  PlatformThemeVariant.Dark => ThemeVariant.Dark,
129                  PlatformThemeVariant.Light => ThemeVariant.Light,
130                  _ => ThemeVariant.Default,
131              };
132  
133          public static ThemeVariant DetectSystemTheme()
134          {
135              if (Application.Current is App app)
136              {
137                  var colorValues = app.PlatformSettings.GetColorValues();
138  
139                  return ConvertThemeVariant(colorValues.ThemeVariant);
140              }
141  
142              return ThemeVariant.Default;
143          }
144      }
145  }