Skip to content

Commit

Permalink
Show window on single instance kill
Browse files Browse the repository at this point in the history
  • Loading branch information
LucHeart committed May 10, 2024
1 parent 9d8402f commit fa647e5
Show file tree
Hide file tree
Showing 13 changed files with 110 additions and 58 deletions.
1 change: 1 addition & 0 deletions ShockOsc/Cli/Uri/UriParameterType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@

public enum UriParameterType
{
Show,
Token
}
3 changes: 3 additions & 0 deletions ShockOsc/HeadlessProgram.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using Microsoft.Extensions.Hosting;
#if WINDOWS
using OpenShock.ShockOsc.Platforms.Windows;
#endif

namespace OpenShock.ShockOsc;

Expand Down
41 changes: 28 additions & 13 deletions ShockOsc/MauiProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@
using Microsoft.Maui.LifecycleEvents;
using OpenShock.ShockOsc.Config;
using MauiApp = OpenShock.ShockOsc.Ui.MauiApp;
using Microsoft.UI;
using OpenShock.ShockOsc.Services.Pipes;
#if WINDOWS
using OpenShock.ShockOsc.Platforms.Windows;
#endif

namespace OpenShock.ShockOsc;

public static class MauiProgram
{
private static ShockOscConfig? _config;
private static PipeServerService? _pipeServerService;

public static Microsoft.Maui.Hosting.MauiApp CreateMauiApp()
{
Expand All @@ -17,20 +21,28 @@ public static Microsoft.Maui.Hosting.MauiApp CreateMauiApp()
// <---- Services ---->

builder.Services.AddShockOscServices();

#if WINDOWS
builder.Services.AddWindowsServices();

builder.ConfigureLifecycleEvents(lifecycleBuilder =>
{
lifecycleBuilder.AddWindows(windowsLifecycleBuilder =>
{
windowsLifecycleBuilder.OnWindowCreated(window =>
{
var handle = WinRT.Interop.WindowNative.GetWindowHandle(window);
var id = Win32Interop.GetWindowIdFromWindow(handle);
var appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(id);
var appWindow = WindowUtils.GetAppWindow(window);
if (_pipeServerService != null)
{
_pipeServerService.OnMessageReceived += () =>
{
appWindow.ShowOnTop();
return Task.CompletedTask;
};
}
//When user execute the closing method, we can push a display alert. If user click Yes, close this application, if click the cancel, display alert will dismiss.
appWindow.Closing += async (s, e) =>
{
Expand All @@ -41,32 +53,35 @@ public static Microsoft.Maui.Hosting.MauiApp CreateMauiApp()
appWindow.Hide();
return;
}
if(Application.Current == null) return;
var result = await Application.Current.MainPage.DisplayAlert(
var result = await Application.Current.MainPage!.DisplayAlert(
"Close?",
"Do you want to close ShockOSC?",
"Yes",
"Cancel");
if (result) Application.Current.Quit();
if (result) Application.Current?.Quit();
};
});
});
});
#endif

// <---- App ---->

builder
.UseMauiApp<MauiApp>()
.ConfigureFonts(fonts => { fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); });

var app = builder.Build();

_config = app.Services.GetRequiredService<ConfigManager>().Config;
_pipeServerService = app.Services.GetRequiredService<PipeServerService>();

app.Services.StartShockOscServices(false);

return app;
}
}
Expand Down
9 changes: 6 additions & 3 deletions ShockOsc/Platforms/Windows/PipeHelper.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System.Collections;
#if WINDOWS
using System.Collections;

namespace OpenShock.ShockOsc;
// ReSharper disable once CheckNamespace
namespace OpenShock.ShockOsc.Platforms.Windows;

public static class PipeHelper
{
Expand Down Expand Up @@ -29,4 +31,5 @@ bool MoveNextSafe(IEnumerator enumerator) {
}
}
}
}
}
#endif
26 changes: 26 additions & 0 deletions ShockOsc/Platforms/Windows/WindowUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#if WINDOWS
using Microsoft.UI;
using Microsoft.UI.Windowing;

// ReSharper disable once CheckNamespace
namespace OpenShock.ShockOsc.Platforms.Windows;

public static class WindowUtils
{
public static void ShowOnTop(this AppWindow appWindow)
{
appWindow.Show();

if (appWindow.Presenter is not OverlappedPresenter presenter) return;
presenter.IsAlwaysOnTop = true;
presenter.IsAlwaysOnTop = false;
}

public static AppWindow GetAppWindow(object window)
{
var handle = WinRT.Interop.WindowNative.GetWindowHandle(window);
var id = Win32Interop.GetWindowIdFromWindow(handle);
return AppWindow.GetFromWindowId(id);
}
}
#endif
24 changes: 13 additions & 11 deletions ShockOsc/Platforms/Windows/WindowsEntryPoint.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
#if WINDOWS
using System.Diagnostics;
using System.IO.Pipes;
using System.Runtime.InteropServices;
using System.Text.Json;
using CommandLine;
using Microsoft.Extensions.Hosting;
using Microsoft.UI.Dispatching;
using Microsoft.Windows.AppLifecycle;
using OpenShock.ShockOsc.Cli;
using OpenShock.ShockOsc.Cli.Uri;
using OpenShock.ShockOsc.Services;
Expand All @@ -16,6 +14,7 @@
using Application = Microsoft.UI.Xaml.Application;
using UriParser = OpenShock.ShockOsc.Cli.Uri.UriParser;

// ReSharper disable once CheckNamespace
namespace OpenShock.ShockOsc.Platforms.Windows;

public static class WindowsEntryPoint
Expand Down Expand Up @@ -54,7 +53,7 @@ private static void Start(CliOptions config)
}

const string pipeName = @"\\.\pipe\OpenShock.ShockOSC";

if (PipeHelper.EnumeratePipes().Any(x => x.Equals(pipeName, StringComparison.InvariantCultureIgnoreCase)))
{
// TODO: Refactor this
Expand All @@ -63,19 +62,22 @@ private static void Start(CliOptions config)
using var pipeClientStream = new NamedPipeClientStream(".", "OpenShock.ShockOsc", PipeDirection.Out);
pipeClientStream.Connect(500);

var parsedUri = UriParser.Parse(config.Uri);

using var writer = new StreamWriter(pipeClientStream);
writer.AutoFlush = true;

var parsedUri = UriParser.Parse(config.Uri);

if (parsedUri.Type == UriParameterType.Token)
var pipeMessage = parsedUri.Type switch
{
writer.WriteLine(JsonSerializer.Serialize(new PipeMessage
UriParameterType.Show => new PipeMessage { Type = PipeMessageType.Show },
UriParameterType.Token => new PipeMessage
{
Type = PipeMessageType.Token,
Data = string.Join('/', parsedUri.Arguments)
}));
}
Type = PipeMessageType.Token, Data = string.Join('/', parsedUri.Arguments)
},
_ => null
};

if (pipeMessage != null) writer.WriteLine(JsonSerializer.Serialize(pipeMessage));

return;
}
Expand Down
3 changes: 2 additions & 1 deletion ShockOsc/Platforms/Windows/WindowsServices.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#if WINDOWS
using OpenShock.ShockOsc.Services;

namespace OpenShock.ShockOsc;
// ReSharper disable once CheckNamespace
namespace OpenShock.ShockOsc.Platforms.Windows;

public static class WindowsServices
{
Expand Down
26 changes: 10 additions & 16 deletions ShockOsc/Platforms/Windows/WindowsTrayService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,22 @@

using System.Drawing;
using System.Windows.Forms;
using Microsoft.UI;
using Microsoft.UI.Windowing;
using OpenShock.SDK.CSharp.Hub;
using OpenShock.ShockOsc.Services;
using Application = Microsoft.Maui.Controls.Application;
using Color = System.Drawing.Color;
using Image = System.Drawing.Image;

namespace OpenShock.ShockOsc;
// ReSharper disable once CheckNamespace
namespace OpenShock.ShockOsc.Platforms.Windows;

public class WindowsTrayService : ITrayService
{
private readonly OpenShockHubClient _apiHubClient;

/// <summary>
/// Windows Tray Service
/// </summary>
/// <param name="apiHubClient"></param>
public WindowsTrayService(OpenShockHubClient apiHubClient)

Check warning on line 21 in ShockOsc/Platforms/Windows/WindowsTrayService.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field '_stateLabel' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.
{
_apiHubClient = apiHubClient;
Expand Down Expand Up @@ -61,7 +63,7 @@ public void Initialize()
tray.Visible = true;
}

private void Restart(object? sender, EventArgs e)
private static void Restart(object? sender, EventArgs e)
{
Application.Current?.Quit();
}
Expand All @@ -73,18 +75,10 @@ private static void OnMainClick(object? sender, EventArgs eventArgs)
var window = Application.Current?.Windows[0];
var nativeWindow = window?.Handler?.PlatformView;
if (nativeWindow == null) return;

var windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(nativeWindow);
var windowId = Win32Interop.GetWindowIdFromWindow(windowHandle);
var appWindow = AppWindow.GetFromWindowId(windowId);

appWindow.Show();

if (appWindow.Presenter is OverlappedPresenter presenter)
{
presenter.IsAlwaysOnTop = true;
presenter.IsAlwaysOnTop = false;
}
var appWindow = WindowUtils.GetAppWindow(nativeWindow);

appWindow.ShowOnTop();
}

private static void OnQuitClick(object? sender, EventArgs eventArgs)
Expand Down
1 change: 1 addition & 0 deletions ShockOsc/Services/Pipes/PipeMessageType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@

public enum PipeMessageType
{
Show,
Token
}
8 changes: 4 additions & 4 deletions ShockOsc/Services/Pipes/PipeServerService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ private async Task ServerLoop()
case PipeMessageType.Token:
Token = jsonObj.Data?.ToString();
break;
case PipeMessageType.Show:
default:
break;
}
{

}


await OnMessageReceived.Raise();
_logger.LogInformation("[{Id}], Received pipe message of type: {Type}", id, jsonObj.Type);
}
Expand Down
19 changes: 11 additions & 8 deletions ShockOsc/Services/ShockOsc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,17 @@ public ShockOsc(ILogger<ShockOsc> logger,
_dataLayer = dataLayer;
_oscHandler = oscHandler;
_liveControlManager = liveControlManager;


OnGroupsChanged += SetupGroups;

OnGroupsChanged += () =>
{
SetupGroups();
return Task.CompletedTask;
};

oscQueryServer.FoundVrcClient += FoundVrcClient;
oscQueryServer.ParameterUpdate += OnAvatarChange;
SetupGroups().Wait();

SetupGroups();

if (!_configManager.Config.Osc.OscQuery)
{
Expand All @@ -87,7 +90,7 @@ public ShockOsc(ILogger<ShockOsc> logger,
_logger.LogInformation("Started ShockOsc.cs");
}

private async Task SetupGroups()
private void SetupGroups()
{
_dataLayer.ProgramGroups.Clear();
_dataLayer.ProgramGroups[Guid.Empty] = new ProgramGroup(Guid.Empty, "_All", _oscClient, null);
Expand All @@ -101,7 +104,7 @@ private void OnParamChange(bool shockOscParam)
OnParamsChange?.Invoke(shockOscParam);
}

public async Task FoundVrcClient(IPEndPoint? oscClient)
private async Task FoundVrcClient(IPEndPoint? oscClient)
{
_logger.LogInformation("Found VRC client");
// stop tasks
Expand Down Expand Up @@ -129,7 +132,7 @@ public async Task FoundVrcClient(IPEndPoint? oscClient)
_logger.LogInformation("Ready");
OsTask.Run(_underscoreConfig.SendUpdateForAll);

_oscClient.SendChatboxMessage($"{_configManager.Config.Chatbox.Prefix} Game Connected");
await _oscClient.SendChatboxMessage($"{_configManager.Config.Chatbox.Prefix} Game Connected");
}

public async Task OnAvatarChange(Dictionary<string, object?> parameters, string avatarId)
Expand Down
5 changes: 3 additions & 2 deletions ShockOsc/Ui/Pages/Authentication/LoginPart.razor
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@

private string? _server = null;

[Parameter] public Func<Task> ProceedAuthenticated { get; set; }
[Parameter] public required Func<Task> ProceedAuthenticated { get; set; }

public async Task Login()
{
Expand Down Expand Up @@ -141,7 +141,8 @@
BackendServer.Production => _productionServer,
BackendServer.Staging => _stagingServer,
BackendServer.Custom => _customServerUri,
};
_ => throw new ArgumentOutOfRangeException(nameof(value), value, null)
} ?? throw new InvalidOperationException();
}

private struct WrongSchema;
Expand Down
2 changes: 2 additions & 0 deletions ShockOsc/Ui/Utils/DebouncedSlider.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ protected override void OnInitialized()
private T _sliderValue = default!;

[Parameter]
#pragma warning disable BL0007
public T SliderValue
#pragma warning restore BL0007
{
get => _sliderValue;
set
Expand Down

0 comments on commit fa647e5

Please sign in to comment.