diff --git a/assets/locales.json b/assets/locales.json
index 8899bf692..a311a52a2 100644
--- a/assets/locales.json
+++ b/assets/locales.json
@@ -12067,6 +12067,56 @@
"zh_TW": "淺色"
}
},
+ {
+ "ID": "SettingsTabGeneralIcon",
+ "Translations": {
+ "ar_SA": "",
+ "de_DE": "",
+ "el_GR": "",
+ "en_US": "Application icon:",
+ "es_ES": "Icono de aplicación:",
+ "fr_FR": "",
+ "he_IL": "",
+ "it_IT": "",
+ "ja_JP": "",
+ "ko_KR": "",
+ "no_NO": "",
+ "pl_PL": "",
+ "pt_BR": "",
+ "ru_RU": "",
+ "sv_SE": "",
+ "th_TH": "",
+ "tr_TR": "",
+ "uk_UA": "",
+ "zh_CN": "",
+ "zh_TW": ""
+ }
+ },
+ {
+ "ID": "SettingsTabGeneralIconTooltip",
+ "Translations": {
+ "ar_SA": "",
+ "de_DE": "",
+ "el_GR": "",
+ "en_US": "An app restart may be required for the app icon to display properly across Ryujinx.",
+ "es_ES": "Podría ser necesario reiniciar la aplicación para que el icono se muestre correctamente en todo Ryujinx.",
+ "fr_FR": "",
+ "he_IL": "",
+ "it_IT": "",
+ "ja_JP": "",
+ "ko_KR": "",
+ "no_NO": "",
+ "pl_PL": "",
+ "pt_BR": "",
+ "ru_RU": "",
+ "sv_SE": "",
+ "th_TH": "",
+ "tr_TR": "",
+ "uk_UA": "",
+ "zh_CN": "",
+ "zh_TW": ""
+ }
+ },
{
"ID": "ControllerSettingsConfigureGeneral",
"Translations": {
diff --git a/src/Ryujinx/Assets/Icons/AppIcons/Bordered Ryugay.svg b/src/Ryujinx/Assets/Icons/AppIcons/Bordered Ryugay.svg
new file mode 100644
index 000000000..847d617fa
--- /dev/null
+++ b/src/Ryujinx/Assets/Icons/AppIcons/Bordered Ryugay.svg
@@ -0,0 +1,24 @@
+
+
+
+
diff --git a/src/Ryujinx/Assets/Icons/AppIcons/Bordered Ryupride.svg b/src/Ryujinx/Assets/Icons/AppIcons/Bordered Ryupride.svg
new file mode 100644
index 000000000..00bba42f0
--- /dev/null
+++ b/src/Ryujinx/Assets/Icons/AppIcons/Bordered Ryupride.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/src/Ryujinx/Assets/Icons/AppIcons/Ryubi.png b/src/Ryujinx/Assets/Icons/AppIcons/Ryubi.png
new file mode 100644
index 000000000..5744a057f
Binary files /dev/null and b/src/Ryujinx/Assets/Icons/AppIcons/Ryubi.png differ
diff --git a/src/Ryujinx/Assets/Icons/AppIcons/Ryufluid.webp b/src/Ryujinx/Assets/Icons/AppIcons/Ryufluid.webp
new file mode 100644
index 000000000..cd34ac32f
Binary files /dev/null and b/src/Ryujinx/Assets/Icons/AppIcons/Ryufluid.webp differ
diff --git a/src/Ryujinx/Assets/Icons/AppIcons/Ryulesbian.webp b/src/Ryujinx/Assets/Icons/AppIcons/Ryulesbian.webp
new file mode 100644
index 000000000..253773ab2
Binary files /dev/null and b/src/Ryujinx/Assets/Icons/AppIcons/Ryulesbian.webp differ
diff --git a/src/Ryujinx/Assets/Icons/AppIcons/Ryupan.webp b/src/Ryujinx/Assets/Icons/AppIcons/Ryupan.webp
new file mode 100644
index 000000000..5fb55aae5
Binary files /dev/null and b/src/Ryujinx/Assets/Icons/AppIcons/Ryupan.webp differ
diff --git a/src/Ryujinx/Assets/Icons/AppIcons/Ryupride.webp b/src/Ryujinx/Assets/Icons/AppIcons/Ryupride.webp
new file mode 100644
index 000000000..64a6748e6
Binary files /dev/null and b/src/Ryujinx/Assets/Icons/AppIcons/Ryupride.webp differ
diff --git a/src/Ryujinx/Assets/Icons/AppIcons/Ryutrans.webp b/src/Ryujinx/Assets/Icons/AppIcons/Ryutrans.webp
new file mode 100644
index 000000000..e6800d3ec
Binary files /dev/null and b/src/Ryujinx/Assets/Icons/AppIcons/Ryutrans.webp differ
diff --git a/src/Ryujinx/Common/Models/ApplicationIcon.cs b/src/Ryujinx/Common/Models/ApplicationIcon.cs
new file mode 100644
index 000000000..95e0fb07f
--- /dev/null
+++ b/src/Ryujinx/Common/Models/ApplicationIcon.cs
@@ -0,0 +1,23 @@
+using Avalonia.Media.Imaging;
+using Ryujinx.Ava.UI.Controls;
+
+namespace Ryujinx.Ava.Common.Models
+{
+ public class ApplicationIcon
+ {
+ public string Name { get; set; }
+ public string Filename { get; set; }
+ public string FullPath
+ {
+ get => $"Ryujinx/Assets/Icons/AppIcons/{Filename}";
+ }
+
+ public Bitmap Icon
+ {
+ get
+ {
+ return RyujinxLogo.GetBitmapForLogo(this);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Ryujinx/Ryujinx.csproj b/src/Ryujinx/Ryujinx.csproj
index 31dc20aac..f0c1b8377 100644
--- a/src/Ryujinx/Ryujinx.csproj
+++ b/src/Ryujinx/Ryujinx.csproj
@@ -164,6 +164,7 @@
+
diff --git a/src/Ryujinx/Systems/Configuration/ConfigurationFileFormat.cs b/src/Ryujinx/Systems/Configuration/ConfigurationFileFormat.cs
index f0fafb4e0..0ccc5e5d1 100644
--- a/src/Ryujinx/Systems/Configuration/ConfigurationFileFormat.cs
+++ b/src/Ryujinx/Systems/Configuration/ConfigurationFileFormat.cs
@@ -356,6 +356,11 @@ namespace Ryujinx.Ava.Systems.Configuration
///
public string BaseStyle { get; set; }
+ ///
+ /// The name of the currently selected window icon
+ ///
+ public string SelectedWindowIcon { get; set; }
+
///
/// Chooses the view mode of the game list // Not Used
///
diff --git a/src/Ryujinx/Systems/Configuration/ConfigurationState.Migration.cs b/src/Ryujinx/Systems/Configuration/ConfigurationState.Migration.cs
index 163b7e98f..9f68820c0 100644
--- a/src/Ryujinx/Systems/Configuration/ConfigurationState.Migration.cs
+++ b/src/Ryujinx/Systems/Configuration/ConfigurationState.Migration.cs
@@ -134,6 +134,7 @@ namespace Ryujinx.Ava.Systems.Configuration
UI.ShownFileTypes.NSO.Value = shouldLoadFromFile ? cff.ShownFileTypes.NSO : UI.ShownFileTypes.NSO.Value;
UI.LanguageCode.Value = shouldLoadFromFile ? cff.LanguageCode : UI.LanguageCode.Value;
UI.BaseStyle.Value = shouldLoadFromFile ? cff.BaseStyle : UI.BaseStyle.Value;
+ UI.SelectedWindowIcon.Value = shouldLoadFromFile ? cff.SelectedWindowIcon : UI.SelectedWindowIcon.Value;
UI.GameListViewMode.Value = shouldLoadFromFile ? cff.GameListViewMode : UI.GameListViewMode.Value;
UI.ShowNames.Value = shouldLoadFromFile ? cff.ShowNames : UI.ShowNames.Value;
UI.IsAscendingOrder.Value = shouldLoadFromFile ? cff.IsAscendingOrder : UI.IsAscendingOrder.Value;
diff --git a/src/Ryujinx/Systems/Configuration/ConfigurationState.Model.cs b/src/Ryujinx/Systems/Configuration/ConfigurationState.Model.cs
index 2b4c8f991..de5846718 100644
--- a/src/Ryujinx/Systems/Configuration/ConfigurationState.Model.cs
+++ b/src/Ryujinx/Systems/Configuration/ConfigurationState.Model.cs
@@ -151,6 +151,11 @@ namespace Ryujinx.Ava.Systems.Configuration
///
public ReactiveObject BaseStyle { get; private set; }
+ ///
+ /// The currently selected window icon.
+ ///
+ public ReactiveObject SelectedWindowIcon { get; private set; }
+
///
/// Start games in fullscreen mode
///
@@ -200,6 +205,7 @@ namespace Ryujinx.Ava.Systems.Configuration
ShownFileTypes = new ShownFileTypeSettings();
WindowStartup = new WindowStartupSettings();
BaseStyle = new ReactiveObject();
+ SelectedWindowIcon = new ReactiveObject();
StartFullscreen = new ReactiveObject();
StartNoUI = new ReactiveObject();
GameListViewMode = new ReactiveObject();
diff --git a/src/Ryujinx/Systems/Configuration/ConfigurationState.cs b/src/Ryujinx/Systems/Configuration/ConfigurationState.cs
index 0e2f6aaec..8b4ded14c 100644
--- a/src/Ryujinx/Systems/Configuration/ConfigurationState.cs
+++ b/src/Ryujinx/Systems/Configuration/ConfigurationState.cs
@@ -126,6 +126,7 @@ namespace Ryujinx.Ava.Systems.Configuration
},
LanguageCode = UI.LanguageCode,
BaseStyle = UI.BaseStyle,
+ SelectedWindowIcon = UI.SelectedWindowIcon,
GameListViewMode = UI.GameListViewMode,
ShowNames = UI.ShowNames,
GridSize = UI.GridSize,
diff --git a/src/Ryujinx/UI/Controls/RyujinxLogo.cs b/src/Ryujinx/UI/Controls/RyujinxLogo.cs
index e1908fc2b..37d7bed04 100644
--- a/src/Ryujinx/UI/Controls/RyujinxLogo.cs
+++ b/src/Ryujinx/UI/Controls/RyujinxLogo.cs
@@ -1,28 +1,146 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Media.Imaging;
+using Ryujinx.Ava.Common.Models;
using Ryujinx.Ava.Systems.Configuration;
-using Ryujinx.Ava.UI.ViewModels;
-using System.Reflection;
+using Ryujinx.Common;
+using SkiaSharp;
+using Svg.Skia;
+using System;
+using System.IO;
+using System.Linq;
namespace Ryujinx.Ava.UI.Controls
{
public class RyujinxLogo : Image
{
- // The UI specifically uses a thicker bordered variant of the icon to avoid crunching out the border at lower resolutions.
- // For an example of this, download canary 1.2.95, then open the settings menu, and look at the icon in the top-left.
- // The border gets reduced to colored pixels in the 4 corners.
- public static readonly Bitmap Bitmap =
- new(Assembly.GetAssembly(typeof(MainWindowViewModel))!
- .GetManifestResourceStream("Ryujinx.Assets.UIImages.Logo_Ryujinx_AntiAlias.png")!);
+ public static ReactiveObject CurrentLogoBitmap { get; private set; } = new();
public RyujinxLogo()
{
Margin = new Thickness(7, 7, 7, 0);
Height = 25;
Width = 25;
- Source = Bitmap;
+ Source = CurrentLogoBitmap.Value;
IsVisible = !ConfigurationState.Instance.ShowOldUI;
+ ConfigurationState.Instance.UI.SelectedWindowIcon.Event += WindowIconChanged_Event;
+ CurrentLogoBitmap.Event += CurrentLogoBitmapChanged_Event;
+ }
+
+ private void CurrentLogoBitmapChanged_Event(object _, ReactiveEventArgs e)
+ {
+ Source = e.NewValue;
+ }
+
+ public static void RefreshAppIconFromSettings()
+ {
+ SetNewAppIcon(ConfigurationState.Instance.UI.SelectedWindowIcon.Value);
+ }
+
+ private static void SetNewAppIcon(string newIconName)
+ {
+ string defaultIconName = "Bordered Ryupride";
+ if (string.IsNullOrEmpty(newIconName))
+ {
+ SetDefaultAppIcon(defaultIconName);
+ }
+
+ ApplicationIcon selectedIcon = RyujinxApp.AvailableApplicationIcons.FirstOrDefault(x => x.Name == newIconName);
+ if (selectedIcon == null)
+ {
+ // Always try to fallback to "Bordered Ryupride" as a default
+ // If not found, fallback to first found icon
+ if (newIconName != defaultIconName)
+ {
+ SetDefaultAppIcon(defaultIconName);
+ return;
+ }
+
+ if (RyujinxApp.AvailableApplicationIcons.Count > 0)
+ {
+ SetDefaultAppIcon(RyujinxApp.AvailableApplicationIcons.First().Name);
+ return;
+ }
+ }
+
+ Stream activeIconStream = EmbeddedResources.GetStream(selectedIcon.FullPath);
+ if (activeIconStream != null)
+ {
+ Bitmap logoBitmap = GetBitmapForLogo(selectedIcon);
+ if (logoBitmap != null)
+ {
+ CurrentLogoBitmap.Value = logoBitmap;
+ }
+ }
+ }
+
+ private static void SetDefaultAppIcon(string defaultIconName)
+ {
+ // Doing this triggers the WindowIconChanged_Event, which will then
+ // call SetNewAppIcon again
+ ConfigurationState.Instance.UI.SelectedWindowIcon.Value = defaultIconName;
+ }
+
+ private void WindowIconChanged_Event(object _, ReactiveEventArgs rArgs) => SetNewAppIcon(rArgs.NewValue);
+
+ public static Bitmap GetBitmapForLogo(ApplicationIcon icon)
+ {
+ Stream activeIconStream = EmbeddedResources.GetStream(icon.FullPath);
+ if (activeIconStream == null)
+ return null;
+
+ // SVG files need to be converted to an image first
+ if (icon.FullPath.EndsWith(".svg", StringComparison.OrdinalIgnoreCase))
+ {
+ Stream pngStream = ConvertSvgToPng(activeIconStream);
+ return new Bitmap(pngStream);
+ }
+ else
+ {
+ return new Bitmap(activeIconStream);
+ }
+ }
+
+ private static Stream ConvertSvgToPng(Stream svgStream)
+ {
+ int width = 256;
+ int height = 256;
+
+ // Load SVG
+ var svg = new SKSvg();
+ svg.Load(svgStream);
+
+ // Determine size
+ var picture = svg.Picture;
+ if (picture == null)
+ throw new InvalidOperationException("Invalid SVG data");
+
+ var picWidth = width > 0 ? width : (int)svg.Picture.CullRect.Width;
+ var picHeight = height > 0 ? height : (int)svg.Picture.CullRect.Height;
+
+ // Create bitmap
+ using var bitmap = new SKBitmap(picWidth, picHeight);
+ using var canvas = new SKCanvas(bitmap);
+ canvas.Clear(SKColors.Transparent);
+
+ // Scale to fit
+ float scaleX = (float)picWidth / svg.Picture.CullRect.Width;
+ float scaleY = (float)picHeight / svg.Picture.CullRect.Height;
+ canvas.Scale(scaleX, scaleY);
+
+ canvas.DrawPicture(svg.Picture);
+ canvas.Flush();
+
+ // Encode PNG into memory stream
+ var outputStream = new MemoryStream();
+ using (var image = SKImage.FromBitmap(bitmap))
+ using (var data = image.Encode(SKEncodedImageFormat.Png, 100))
+ {
+ data.SaveTo(outputStream);
+ }
+
+ outputStream.Position = 0;
+ return outputStream;
}
}
}
diff --git a/src/Ryujinx/UI/RyujinxApp.axaml.cs b/src/Ryujinx/UI/RyujinxApp.axaml.cs
index 34c2d96ca..714f7703a 100644
--- a/src/Ryujinx/UI/RyujinxApp.axaml.cs
+++ b/src/Ryujinx/UI/RyujinxApp.axaml.cs
@@ -8,7 +8,9 @@ using Avalonia.Threading;
using FluentAvalonia.UI.Windowing;
using Gommon;
using Ryujinx.Ava.Common.Locale;
+using Ryujinx.Ava.Common.Models;
using Ryujinx.Ava.Systems.Configuration;
+using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Views.Dialog;
using Ryujinx.Ava.UI.Windows;
@@ -16,7 +18,10 @@ using Ryujinx.Ava.Utilities;
using Ryujinx.Common;
using Ryujinx.Common.Logging;
using System;
+using System.Collections.Generic;
using System.Diagnostics;
+using System.IO;
+using System.Linq;
namespace Ryujinx.Ava
{
@@ -52,6 +57,9 @@ namespace Ryujinx.Ava
{
Name = FormatTitle();
+ RetrieveAvailableAppIcons();
+ RyujinxLogo.RefreshAppIconFromSettings();
+
AvaloniaXamlLoader.Load(this);
if (OperatingSystem.IsMacOS())
@@ -72,7 +80,6 @@ namespace Ryujinx.Ava
if (Program.PreviewerDetached)
{
ApplyConfiguredTheme(ConfigurationState.Instance.UI.BaseStyle);
-
ConfigurationState.Instance.UI.BaseStyle.Event += ThemeChanged_Event;
}
}
@@ -151,5 +158,27 @@ namespace Ryujinx.Ava
{
await AboutView.Show();
}
+
+ public static List AvailableApplicationIcons { get; set; } = [];
+ private static void RetrieveAvailableAppIcons()
+ {
+ AvailableApplicationIcons.Clear();
+ string resourceAssemblyPrefix = "Ryujinx.Assets.Icons.AppIcons.";
+
+ IEnumerable availableAppIconResources = EmbeddedResources
+ .GetAllAvailableResources("Ryujinx/Assets")
+ .Where(x => x.StartsWith(resourceAssemblyPrefix));
+
+ foreach (string resource in availableAppIconResources)
+ {
+ string filename = resource.Remove(0, resourceAssemblyPrefix.Length);
+ string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filename);
+ AvailableApplicationIcons.Add(new ApplicationIcon()
+ {
+ Name = fileNameWithoutExtension,
+ Filename = filename
+ });
+ }
+ }
}
}
diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs
index d5d9b8218..3f275b368 100644
--- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs
@@ -9,12 +9,14 @@ using Ryujinx.Audio.Backends.OpenAL;
using Ryujinx.Audio.Backends.SDL3;
using Ryujinx.Audio.Backends.SoundIo;
using Ryujinx.Ava.Common.Locale;
+using Ryujinx.Ava.Common.Models;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.Systems.Configuration.System;
using Ryujinx.Ava.Systems.Configuration.UI;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Models.Input;
using Ryujinx.Ava.UI.Windows;
+using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Multiplayer;
using Ryujinx.Common.GraphicsDriver;
@@ -507,6 +509,7 @@ namespace Ryujinx.Ava.UI.ViewModels
Task.Run(CheckSoundBackends);
Task.Run(PopulateNetworkInterfaces);
+ ApplicationIcons = new(RyujinxApp.AvailableApplicationIcons);
if (Program.PreviewerDetached)
{
@@ -632,6 +635,7 @@ namespace Ryujinx.Ava.UI.ViewModels
HideCursor = (int)config.HideCursor.Value;
UpdateCheckerType = (int)config.UpdateCheckerType.Value;
FocusLostActionType = (int)config.FocusLostActionType.Value;
+ AppIconSelectedIndex = _appIcons.ToList().FindIndex(x => x.Name == config.UI.SelectedWindowIcon.Value);
GameDirectories.Clear();
GameDirectories.AddRange(config.UI.GameDirs.Value);
@@ -750,6 +754,7 @@ namespace Ryujinx.Ava.UI.ViewModels
config.FocusLostActionType.Value = (FocusLostType)FocusLostActionType;
config.UI.GameDirs.Value = [.. GameDirectories];
config.UI.AutoloadDirs.Value = [.. AutoloadDirectories];
+ config.UI.SelectedWindowIcon.Value = _appIcons[_appIconSelectedIndex].Name;
config.UI.BaseStyle.Value = BaseStyleIndex switch
{
@@ -937,5 +942,27 @@ namespace Ryujinx.Ava.UI.ViewModels
RevertIfNotSaved(IsCustomConfig, IsGameRunning);
CloseWindow?.Invoke();
}
+
+ private AvaloniaList _appIcons = [];
+ public AvaloniaList ApplicationIcons
+ {
+ get => _appIcons;
+ set
+ {
+ _appIcons = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private int _appIconSelectedIndex;
+ public int AppIconSelectedIndex
+ {
+ get => _appIconSelectedIndex;
+ set
+ {
+ _appIconSelectedIndex = value;
+ OnPropertyChanged();
+ }
+ }
}
}
diff --git a/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml
index e55c20b88..2cd2819b5 100644
--- a/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml
+++ b/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml
@@ -140,6 +140,32 @@
Content="{ext:Locale SettingsTabGeneralThemeDark}" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Ryujinx/UI/Windows/StyleableWindow.cs b/src/Ryujinx/UI/Windows/StyleableWindow.cs
index 066440382..a91b7593c 100644
--- a/src/Ryujinx/UI/Windows/StyleableWindow.cs
+++ b/src/Ryujinx/UI/Windows/StyleableWindow.cs
@@ -3,11 +3,13 @@ using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Media;
+using Avalonia.Media.Imaging;
using Avalonia.Platform;
using FluentAvalonia.UI.Windowing;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.UI.Controls;
+using Ryujinx.Common;
using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.Windows
@@ -39,7 +41,8 @@ namespace Ryujinx.Ava.UI.Windows
TitleBar.Height = titleBarHeight.Value;
}
- Icon = RyujinxLogo.Bitmap;
+ Icon = RyujinxLogo.CurrentLogoBitmap.Value;
+ RyujinxLogo.CurrentLogoBitmap.Event += WindowIconChanged_Event;
}
private void LocaleChanged()
@@ -53,6 +56,12 @@ namespace Ryujinx.Ava.UI.Windows
ExtendClientAreaChromeHints = ExtendClientAreaChromeHints.SystemChrome | ExtendClientAreaChromeHints.OSXThickTitleBar;
}
+
+ private void WindowIconChanged_Event(object _, ReactiveEventArgs rArgs) => UpdateIcon(rArgs.NewValue);
+ private void UpdateIcon(Bitmap newIcon)
+ {
+ Icon = newIcon;
+ }
}
public abstract class StyleableWindow : Window
@@ -73,7 +82,8 @@ namespace Ryujinx.Ava.UI.Windows
LocaleManager.Instance.LocaleChanged += LocaleChanged;
LocaleChanged();
- Icon = new WindowIcon(RyujinxLogo.Bitmap);
+ Icon = new WindowIcon(RyujinxLogo.CurrentLogoBitmap.Value);
+ RyujinxLogo.CurrentLogoBitmap.Event += WindowIconChanged_Event;
}
private void LocaleChanged()
@@ -87,5 +97,11 @@ namespace Ryujinx.Ava.UI.Windows
ExtendClientAreaChromeHints = ExtendClientAreaChromeHints.SystemChrome | ExtendClientAreaChromeHints.OSXThickTitleBar;
}
+
+ private void WindowIconChanged_Event(object _, ReactiveEventArgs rArgs) => UpdateIcon(rArgs.NewValue);
+ private void UpdateIcon(Bitmap newIcon)
+ {
+ Icon = new WindowIcon(newIcon);
+ }
}
}