lightweight variant (#1)
Reviewed-on: #1 Co-authored-by: Aleksandr Neychev <alexnejchev73@gmail.com>
This commit was merged in pull request #1.
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
using System.Windows;
|
||||
using CursorLang.Core.Services;
|
||||
using CursorLang.Settings.Services;
|
||||
using CursorLang.Settings.ViewModels;
|
||||
using CursorLang.Settings.Views;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace CursorLang.Settings;
|
||||
|
||||
/// <summary>
|
||||
/// The settings window as a process of its own.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// It is started by the agent — from the tray menu, or straight away when the user
|
||||
/// launches the application themselves — and it ends when the window is closed. That
|
||||
/// is the whole point of the split: WPF costs around a hundred megabytes, and this way
|
||||
/// the system gets all of it back the moment the user is done, instead of the
|
||||
/// background process carrying it until sign-out.
|
||||
///
|
||||
/// Nothing here talks to the agent directly. Every edit goes into settings.json, and
|
||||
/// <see cref="SettingsService"/> nudges the agent to re-read it once the file is
|
||||
/// written. An agent that is not running is a normal case: the window works the same.
|
||||
/// </remarks>
|
||||
// ReSharper disable once RedundantExtendsListEntry
|
||||
public partial class App : Application
|
||||
{
|
||||
private ServiceProvider? _services;
|
||||
private SingleInstanceGate? _instanceGate;
|
||||
|
||||
protected override void OnStartup(StartupEventArgs e)
|
||||
{
|
||||
base.OnStartup(e);
|
||||
|
||||
var gate = new SingleInstanceGate(SingleInstanceGate.SettingsName);
|
||||
if (!gate.TryAcquire(showRunningInstance: true))
|
||||
{
|
||||
gate.Dispose();
|
||||
Shutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
_instanceGate = gate;
|
||||
_instanceGate.ActivationRequested += OnActivationRequested;
|
||||
|
||||
var services = new ServiceCollection();
|
||||
ConfigureServices(services);
|
||||
_services = services.BuildServiceProvider();
|
||||
|
||||
_services.GetRequiredService<SettingsService>().TrackChanges();
|
||||
_services.GetRequiredService<ThemeService>();
|
||||
|
||||
MainWindow = _services.GetRequiredService<MainWindow>();
|
||||
|
||||
ShutdownMode = ShutdownMode.OnMainWindowClose;
|
||||
MainWindow.Show();
|
||||
|
||||
_ = _services.GetRequiredService<SettingsViewModel>().InitializeAsync();
|
||||
_ = _services.GetRequiredService<UpdateViewModel>().StartAsync();
|
||||
}
|
||||
|
||||
protected override void OnExit(ExitEventArgs e)
|
||||
{
|
||||
_services?.Dispose();
|
||||
|
||||
if (_instanceGate is not null)
|
||||
{
|
||||
_instanceGate.ActivationRequested -= OnActivationRequested;
|
||||
_instanceGate.Dispose();
|
||||
}
|
||||
|
||||
base.OnExit(e);
|
||||
}
|
||||
|
||||
internal static void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton(new UpdateOptions());
|
||||
|
||||
services.AddSingleton<SettingsService>();
|
||||
services.AddSingleton(provider => provider.GetRequiredService<SettingsService>().Load());
|
||||
|
||||
services.AddSingleton<ThemeService>();
|
||||
services.AddSingleton<IThemeService>(provider => provider.GetRequiredService<ThemeService>());
|
||||
|
||||
services.AddSingleton<MainWindowPlacement>();
|
||||
|
||||
services.AddSingleton<ILocalizationService, LocalizationService>();
|
||||
services.AddSingleton<IStartupService, StartupService>();
|
||||
services.AddSingleton<IUpdateService, UpdateService>();
|
||||
|
||||
services.AddSingleton<UpdateViewModel>();
|
||||
services.AddSingleton<SettingsViewModel>();
|
||||
|
||||
services.AddSingleton<MainWindow>();
|
||||
}
|
||||
|
||||
// A second launch — another click on "Settings" in the tray menu, say. The gate
|
||||
// answers on a thread pool thread, and a window obeys only its own
|
||||
private void OnActivationRequested(object? sender, EventArgs e) =>
|
||||
Dispatcher.BeginInvoke(ShowMainWindow);
|
||||
|
||||
private void ShowMainWindow()
|
||||
{
|
||||
if (MainWindow is not { } window)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (window.WindowState == WindowState.Minimized)
|
||||
{
|
||||
window.WindowState = WindowState.Normal;
|
||||
}
|
||||
|
||||
window.Show();
|
||||
window.Activate();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user