diff --git a/.github/workflows/ci-windows.yml b/.github/workflows/ci-windows.yml new file mode 100644 index 0000000..354fde5 --- /dev/null +++ b/.github/workflows/ci-windows.yml @@ -0,0 +1,77 @@ +on: + push: + branches: + - master + - develop + pull_request: + branches: + - master + - develop + types: [opened, reopened, synchronize] + workflow_call: + workflow_dispatch: + +name: ci-windowsl + +env: + DOTNET_VERSION: 8.0.x + REGISTRY: ghcr.io + +jobs: + + build: + runs-on: windows-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup .NET SDK ${{ env.DOTNET_VERSION }} + uses: actions/setup-dotnet@v4 + with: + dotnet-version: ${{ env.DOTNET_VERSION }} + + - name: Install dependencies + run: dotnet restore + + - name: Install maui workload + run: dotnet workload install maui + + - name: Build + run: dotnet build --configuration Release --no-restore + + - name: Test + run: dotnet test --no-restore --verbosity normal + + - name: Publish ShockOSC Windows + run: dotnet publish ShockOsc/ShockOsc.csproj -c Release -f net8.0-windows10.0.19041.0 -o ./publish/API + + - name: Upload ShockOSC Windows artifacts + uses: actions/upload-artifact@v4 + with: + name: ShockOsc + path: publish/ShockOsc/* + retention-days: 1 + if-no-files-found: error + + instller: + runs-on: windows-latest + needs: build + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + sparse-checkout: | + Installer + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + name: ShockOsc + path: publish/ + + \ No newline at end of file diff --git a/ShockOsc/Config/AppConfig.cs b/ShockOsc/Config/AppConfig.cs new file mode 100644 index 0000000..267d166 --- /dev/null +++ b/ShockOsc/Config/AppConfig.cs @@ -0,0 +1,6 @@ +namespace OpenShock.ShockOsc.Config; + +public sealed class AppConfig +{ + public bool CloseToTray { get; set; } = true; +} \ No newline at end of file diff --git a/ShockOsc/Config/ShockOscConfig.cs b/ShockOsc/Config/ShockOscConfig.cs index bb334dc..845e530 100644 --- a/ShockOsc/Config/ShockOscConfig.cs +++ b/ShockOsc/Config/ShockOscConfig.cs @@ -9,5 +9,5 @@ public sealed class ShockOscConfig public IDictionary Groups { get; set; } = new Dictionary(); public Version? LastIgnoredVersion { get; set; } = null; - + public AppConfig App { get; set; } = new(); } \ No newline at end of file diff --git a/ShockOsc/MauiProgram.cs b/ShockOsc/MauiProgram.cs index 386e7d7..3da63a1 100644 --- a/ShockOsc/MauiProgram.cs +++ b/ShockOsc/MauiProgram.cs @@ -19,6 +19,8 @@ namespace OpenShock.ShockOsc; public static class MauiProgram { + private static ShockOscConfig? _config; + public static Microsoft.Maui.Hosting.MauiApp CreateMauiApp() { var builder = Microsoft.Maui.Hosting.MauiApp.CreateBuilder(); @@ -76,9 +78,43 @@ public static Microsoft.Maui.Hosting.MauiApp CreateMauiApp() builder.Services.AddSingleton(); builder.Services.AddSingleton(); - - + #if WINDOWS + builder.ConfigureLifecycleEvents(lifecycleBuilder => + { + lifecycleBuilder.AddWindows(windowsLifecycleBuilder => + { + windowsLifecycleBuilder.OnWindowCreated(window => + { + //use Microsoft.UI.Windowing functions for window + var handle = WinRT.Interop.WindowNative.GetWindowHandle(window); + var id = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(handle); + var appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(id); + + //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) => + { + e.Cancel = true; + + if (_config?.App.CloseToTray ?? false) + { + appWindow.Hide(); + return; + } + + var result = await Application.Current.MainPage.DisplayAlert( + "Close?", + "Do you want to close ShockOSC?", + "Yes", + "Cancel"); + + if (result) Application.Current.Quit(); + }; + }); + }); + }); + + builder.Services.AddSingleton(); #endif @@ -99,6 +135,8 @@ public static Microsoft.Maui.Hosting.MauiApp CreateMauiApp() var app = builder.Build(); + _config = app.Services.GetRequiredService().Config; + app.Services.GetService()?.Initialize(); // <---- Warmup ----> diff --git a/ShockOsc/Platforms/Windows/WindowsTrayService.cs b/ShockOsc/Platforms/Windows/WindowsTrayService.cs index f497249..eb0cb7b 100644 --- a/ShockOsc/Platforms/Windows/WindowsTrayService.cs +++ b/ShockOsc/Platforms/Windows/WindowsTrayService.cs @@ -72,6 +72,8 @@ private static void OnMainClick(object? sender, EventArgs eventArgs) var windowId = Win32Interop.GetWindowIdFromWindow(windowHandle); var appWindow = AppWindow.GetFromWindowId(windowId); + + if (appWindow.IsVisible) appWindow.Hide(); else appWindow.Show(); }