mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Merge remote-tracking branch 'origin/feature/avalonia' into feature/avalonia
This commit is contained in:
commit
55337fe120
@ -24,10 +24,15 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
public static readonly string ExecutablePath = Utilities.GetCurrentLocation();
|
||||
|
||||
/// <summary>
|
||||
/// The base path for Artemis application data folder
|
||||
/// </summary>
|
||||
public static readonly string BaseFolder = Environment.GetFolderPath(OperatingSystem.IsWindows() ? Environment.SpecialFolder.ApplicationData : Environment.SpecialFolder.LocalApplicationData);
|
||||
|
||||
/// <summary>
|
||||
/// The full path to the Artemis data folder
|
||||
/// </summary>
|
||||
public static readonly string DataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Artemis");
|
||||
public static readonly string DataFolder = Path.Combine(BaseFolder, "Artemis");
|
||||
|
||||
/// <summary>
|
||||
/// The full path to the Artemis logs folder
|
||||
|
||||
@ -2,14 +2,19 @@ using Avalonia;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.Threading;
|
||||
using ReactiveUI;
|
||||
using Ninject;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
|
||||
namespace Artemis.UI.Linux
|
||||
{
|
||||
public class App : Application
|
||||
{
|
||||
private StandardKernel? _kernel;
|
||||
private ApplicationStateManager? _applicationStateManager;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
ArtemisBootstrapper.Bootstrap(this);
|
||||
_kernel = ArtemisBootstrapper.Bootstrap(this);
|
||||
RxApp.MainThreadScheduler = AvaloniaScheduler.Instance;
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
@ -17,6 +22,8 @@ namespace Artemis.UI.Linux
|
||||
public override void OnFrameworkInitializationCompleted()
|
||||
{
|
||||
ArtemisBootstrapper.Initialize();
|
||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
_applicationStateManager = new ApplicationStateManager(_kernel!, desktop.Args);
|
||||
}
|
||||
}
|
||||
}
|
||||
141
src/Avalonia/Artemis.UI.Linux/ApplicationStateManager.cs
Normal file
141
src/Avalonia/Artemis.UI.Linux/ApplicationStateManager.cs
Normal file
@ -0,0 +1,141 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Security.Principal;
|
||||
using System.Threading;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Shared.Services.Interfaces;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Threading;
|
||||
using Ninject;
|
||||
|
||||
namespace Artemis.UI.Linux
|
||||
{
|
||||
public class ApplicationStateManager
|
||||
{
|
||||
private readonly IWindowService _windowService;
|
||||
|
||||
// ReSharper disable once NotAccessedField.Local - Kept in scope to ensure it does not get released
|
||||
private Mutex? _artemisMutex;
|
||||
|
||||
public ApplicationStateManager(IKernel kernel, string[] startupArguments)
|
||||
{
|
||||
_windowService = kernel.Get<IWindowService>();
|
||||
StartupArguments = startupArguments;
|
||||
|
||||
Core.Utilities.ShutdownRequested += UtilitiesOnShutdownRequested;
|
||||
Core.Utilities.RestartRequested += UtilitiesOnRestartRequested;
|
||||
|
||||
// On OS shutdown dispose the kernel just so device providers get a chance to clean up
|
||||
if (Application.Current.ApplicationLifetime is IControlledApplicationLifetime controlledApplicationLifetime)
|
||||
{
|
||||
controlledApplicationLifetime.Exit += (_, _) =>
|
||||
{
|
||||
RunForcedShutdownIfEnabled();
|
||||
kernel.Dispose();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public string[] StartupArguments { get; }
|
||||
|
||||
public bool FocusExistingInstance()
|
||||
{
|
||||
_artemisMutex = new Mutex(true, "Artemis-3c24b502-64e6-4587-84bf-9072970e535d", out bool createdNew);
|
||||
if (createdNew)
|
||||
return false;
|
||||
|
||||
return RemoteFocus();
|
||||
}
|
||||
|
||||
public void DisplayException(Exception e)
|
||||
{
|
||||
try
|
||||
{
|
||||
_windowService.ShowExceptionDialog("An unhandled exception occured", e);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored, we tried
|
||||
}
|
||||
}
|
||||
|
||||
private bool RemoteFocus()
|
||||
{
|
||||
// At this point we cannot read the database yet to retrieve the web server port.
|
||||
// Instead use the method external applications should use as well.
|
||||
if (!File.Exists(Path.Combine(Constants.DataFolder, "webserver.txt")))
|
||||
{
|
||||
KillOtherInstances();
|
||||
return false;
|
||||
}
|
||||
|
||||
string url = File.ReadAllText(Path.Combine(Constants.DataFolder, "webserver.txt"));
|
||||
using HttpClient client = new();
|
||||
try
|
||||
{
|
||||
CancellationTokenSource cts = new();
|
||||
cts.CancelAfter(2000);
|
||||
|
||||
HttpResponseMessage httpResponseMessage = client.Send(new HttpRequestMessage(HttpMethod.Post, url + "remote/bring-to-foreground"), cts.Token);
|
||||
httpResponseMessage.EnsureSuccessStatusCode();
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
KillOtherInstances();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void KillOtherInstances()
|
||||
{
|
||||
// Kill everything else heh
|
||||
List<Process> processes = Process.GetProcessesByName("Artemis.UI").Where(p => p.Id != Process.GetCurrentProcess().Id).ToList();
|
||||
foreach (Process process in processes)
|
||||
{
|
||||
try
|
||||
{
|
||||
process.Kill(true);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UtilitiesOnRestartRequested(object? sender, RestartEventArgs e)
|
||||
{
|
||||
List<string> argsList = new();
|
||||
argsList.AddRange(StartupArguments);
|
||||
if (e.ExtraArgs != null)
|
||||
argsList.AddRange(e.ExtraArgs.Except(argsList));
|
||||
|
||||
//TODO: start new instance with correct arguments
|
||||
|
||||
if (Application.Current.ApplicationLifetime is IControlledApplicationLifetime controlledApplicationLifetime)
|
||||
Dispatcher.UIThread.Post(() => controlledApplicationLifetime.Shutdown());
|
||||
}
|
||||
|
||||
private void UtilitiesOnShutdownRequested(object? sender, EventArgs e)
|
||||
{
|
||||
RunForcedShutdownIfEnabled();
|
||||
|
||||
if (Application.Current.ApplicationLifetime is IControlledApplicationLifetime controlledApplicationLifetime)
|
||||
Dispatcher.UIThread.Post(() => controlledApplicationLifetime.Shutdown());
|
||||
}
|
||||
|
||||
private void RunForcedShutdownIfEnabled()
|
||||
{
|
||||
if (StartupArguments.Contains("--disable-forced-shutdown"))
|
||||
return;
|
||||
|
||||
//todo
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -14,6 +14,7 @@
|
||||
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="0.10.10" />
|
||||
<PackageReference Include="Avalonia.ReactiveUI" Version="0.10.10" />
|
||||
<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="2.80.3" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Artemis.Core\Artemis.Core.csproj" />
|
||||
|
||||
@ -53,6 +53,15 @@
|
||||
"System.Reactive": "5.0.0"
|
||||
}
|
||||
},
|
||||
"SkiaSharp.NativeAssets.Linux": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.80.3, )",
|
||||
"resolved": "2.80.3",
|
||||
"contentHash": "LYl/mvEXrsKMdDNPVjA4ul8JDDGZI8DIkFE0a5GdhaC/aooxgwjuaXZ9NfPg4cJsRf8tb6VhGHvjSNUngNOcJw==",
|
||||
"dependencies": {
|
||||
"SkiaSharp": "2.80.3"
|
||||
}
|
||||
},
|
||||
"Avalonia.Angle.Windows.Natives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.0.2020091801",
|
||||
@ -678,14 +687,6 @@
|
||||
"SkiaSharp": "2.80.2"
|
||||
}
|
||||
},
|
||||
"SkiaSharp.NativeAssets.Linux": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.80.2",
|
||||
"contentHash": "uQSxFy5iVTK6tENWrlc+HCKGSCLgJ+d2KGXUlC1OMCXlKOVkzMqdwa0gMukrEA6HYdO+qk6IUq3ya4fk70EB4g==",
|
||||
"dependencies": {
|
||||
"SkiaSharp": "2.80.2"
|
||||
}
|
||||
},
|
||||
"Splat": {
|
||||
"type": "Transitive",
|
||||
"resolved": "13.1.63",
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using Artemis.Core.Ninject;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Exceptions;
|
||||
using Artemis.UI.Ninject;
|
||||
using Artemis.UI.Screens.Root;
|
||||
@ -20,6 +21,8 @@ namespace Artemis.UI
|
||||
{
|
||||
if (_application != null || _kernel != null)
|
||||
throw new ArtemisUIException("UI already bootstrapped");
|
||||
|
||||
Utilities.PrepareFirstLaunch();
|
||||
|
||||
_application = application;
|
||||
_kernel = new StandardKernel();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user