diff --git a/src/App.Commands.cs b/src/App.Commands.cs index 18016a1cd..172c73208 100644 --- a/src/App.Commands.cs +++ b/src/App.Commands.cs @@ -37,7 +37,8 @@ public static bool IsCheckForUpdateCommandVisible } } - public static readonly Command OpenPreferenceCommand = new Command(_ => OpenDialog(new Views.Preference())); + public static readonly Command Unminimize = new Command(_ => ShowWindow()); + public static readonly Command OpenPreferenceCommand = new Command(_ => { ShowWindow(); OpenDialog(new Views.Preference()); }); public static readonly Command OpenHotkeysCommand = new Command(_ => OpenDialog(new Views.Hotkeys())); public static readonly Command OpenAppDataDirCommand = new Command(_ => Native.OS.OpenInFileManager(Native.OS.DataDir)); public static readonly Command OpenAboutCommand = new Command(_ => OpenDialog(new Views.About())); diff --git a/src/App.axaml.cs b/src/App.axaml.cs index 3d1547c9d..94455df71 100644 --- a/src/App.axaml.cs +++ b/src/App.axaml.cs @@ -14,6 +14,8 @@ using Avalonia.Markup.Xaml; using Avalonia.Media; using Avalonia.Media.Fonts; +using Avalonia.Media.Imaging; +using Avalonia.Platform; using Avalonia.Platform.Storage; using Avalonia.Styling; using Avalonia.Threading; @@ -85,6 +87,7 @@ public override void Initialize() SetLocale(pref.Locale); SetTheme(pref.Theme, pref.ThemeOverrides); SetFonts(pref.DefaultFontFamily, pref.MonospaceFontFamily, pref.OnlyUseMonoFontInEditor); + SetupTrayIcon(pref.SystemTrayIcon); } public override void OnFrameworkInitializationCompleted() @@ -192,6 +195,34 @@ public static void SetTheme(string theme, string themeOverridesFile) } } + public static void SetupTrayIcon(bool enable) + { + if (enable) + { + var icons = new TrayIcons { + new TrayIcon { + Icon = new WindowIcon(new Bitmap(AssetLoader.Open(new Uri("avares://SourceGit/App.ico")))), + Menu = [ + new NativeMenuItem(Text("Open")) {Command = Unminimize}, + new NativeMenuItem(Text("Preference")) {Command = OpenPreferenceCommand}, + new NativeMenuItemSeparator(), + new NativeMenuItem(Text("Quit")) {Command = QuitCommand}, + ] + } + }; + icons[0].Clicked += (_, _) => ShowWindow(); + TrayIcon.SetIcons(Current, icons); + } + } + private static void ShowWindow() + { + if (Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { + desktop.MainWindow.WindowState = WindowState.Normal; + desktop.MainWindow.Show(); + desktop.MainWindow.BringIntoView(); + desktop.MainWindow.Focus(); + } + } public static void SetFonts(string defaultFont, string monospaceFont, bool onlyUseMonospaceFontInEditor) { var app = Current as App; @@ -545,11 +576,15 @@ private void TryLaunchedAsNormal(IClassicDesktopStyleApplicationLifetime desktop if (desktop.Args != null && desktop.Args.Length == 1 && Directory.Exists(desktop.Args[0])) startupRepo = desktop.Args[0]; + var pref = ViewModels.Preference.Instance; + if (pref.SystemTrayIcon) { + desktop.ShutdownMode = ShutdownMode.OnExplicitShutdown; + } + _launcher = new ViewModels.Launcher(startupRepo); desktop.MainWindow = new Views.Launcher() { DataContext = _launcher }; #if !DISABLE_UPDATE_DETECTION - var pref = ViewModels.Preference.Instance; if (pref.ShouldCheck4UpdateOnStartup()) Check4Update(); #endif diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index befad68a2..c3f68c808 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -420,6 +420,7 @@ Select parent node for: Name: Git has NOT been configured. Please to go [Preference] and configure it first. + Open SourceGit Open Data Storage Directory Open with... Optional. diff --git a/src/ViewModels/Preference.cs b/src/ViewModels/Preference.cs index 04f0fa912..94c44831d 100644 --- a/src/ViewModels/Preference.cs +++ b/src/ViewModels/Preference.cs @@ -333,6 +333,12 @@ public double LastCheckUpdateTime set => SetProperty(ref _lastCheckUpdateTime, value); } + public bool SystemTrayIcon + { + get => _systemTrayIcon; + set => SetProperty(ref _systemTrayIcon, value); + } + public bool IsGitConfigured() { var path = GitInstallPath; @@ -663,5 +669,7 @@ private string FixFontFamilyName(string name) private string _externalMergeToolPath = string.Empty; private uint _statisticsSampleColor = 0xFF00FF00; + + private bool _systemTrayIcon = false; } } diff --git a/src/Views/Launcher.axaml.cs b/src/Views/Launcher.axaml.cs index a3a3af8b0..c5d6289c5 100644 --- a/src/Views/Launcher.axaml.cs +++ b/src/Views/Launcher.axaml.cs @@ -255,7 +255,13 @@ protected override void OnKeyUp(KeyEventArgs e) protected override void OnClosing(WindowClosingEventArgs e) { - (DataContext as ViewModels.Launcher)?.Quit(Width, Height); + var pref = ViewModels.Preference.Instance; + if (pref.SystemTrayIcon) { + e.Cancel = true; + Hide(); + } else { + (DataContext as ViewModels.Launcher)?.Quit(Width, Height); + } base.OnClosing(e); }