Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
5082678
Add application-level native lifecycle management
Scarlet-Bytes Sep 1, 2026
19d72d6
Merge branch 'core' into 406-feature-a-full-natively-supported-multiw…
Scarlet-Bytes Sep 1, 2026
2510eac
Add InfiniFrameApplication support & lifecycle cleanup
Scarlet-Bytes Sep 1, 2026
5a41cd5
Remove legacy platform registrations and loops
Scarlet-Bytes Sep 1, 2026
f21d7ca
Update Window.Win32.Internal.h
Scarlet-Bytes Sep 1, 2026
be3262c
Track windows and fix app lifecycle ordering
Scarlet-Bytes Sep 1, 2026
b12f00f
Remove IsMessageLoopRunning; unify WaitForExit
Scarlet-Bytes Sep 2, 2026
5529dd4
Refactor to unify application lifecycle management
Scarlet-Bytes Sep 2, 2026
92619fa
Refactor: separate Blazor and WebServer extensions into dedicated pro…
Scarlet-Bytes Sep 2, 2026
7838984
Treat AppUserModelId as app-level; add logging
Scarlet-Bytes Sep 2, 2026
6bd1379
Update shared-testing-linux.yml
Scarlet-Bytes Sep 2, 2026
a0de31f
Enable ESM-compatible Vite build
Scarlet-Bytes Sep 2, 2026
67aa523
Share DI provider across application and windows
Scarlet-Bytes Sep 2, 2026
923c58f
Refactor switch statements for improved readability and update DI reg…
Scarlet-Bytes Sep 2, 2026
e0881c2
Delay native handle destruction until safe
Scarlet-Bytes Sep 3, 2026
b49f143
Fix native handle teardown and service registration
Scarlet-Bytes Sep 3, 2026
40aeba2
Fix circular window creation and test flakiness
Scarlet-Bytes Sep 3, 2026
5acc258
Add timeouts for flaky webview tests
Scarlet-Bytes Sep 3, 2026
c42b3b0
Update GetCurrentUrlTests.cs
Scarlet-Bytes Sep 3, 2026
721722e
Ensure `IInfiniFrameWindow` registration in DI container during `Buil…
Scarlet-Bytes Sep 5, 2026
824abbb
Ensure thread-safe native handle destruction with atomic flags
Scarlet-Bytes Sep 5, 2026
6dbb7ca
Merge branch 'core' into 406-feature-a-full-natively-supported-multiw…
Scarlet-Bytes Sep 5, 2026
bb93413
Ensure thread-safe InfiniFrameWindow destruction with atomic guard flag
Scarlet-Bytes Sep 5, 2026
daeb3fc
Update WindowLifecycle.Cocoa.mm
Scarlet-Bytes Sep 5, 2026
ac99dbc
Update WindowLifecycle.Cocoa.mm
Scarlet-Bytes Sep 5, 2026
e686fea
Fix macOS mutex crash race and flaky Playwright timeout
Scarlet-Bytes Sep 5, 2026
881afe8
Fix macOS crash: call SignalTeardown synchronously after InvokeClosed
Scarlet-Bytes Sep 5, 2026
eb972f8
Fix macOS crash: use dispatch_async in ScheduleOperation (root cause)
Scarlet-Bytes Sep 5, 2026
d4775af
Install macOS diagnostics signal handler for crash stack traces
Scarlet-Bytes Sep 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions .github/workflows/shared-testing-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -273,17 +273,6 @@ jobs:
framework_exit=0
dotnet "${test_args[@]}" 2>&1 | sed 's/\x1b\[[0-9;]*[a-zA-Z]//g' | tee "artifacts/testresults/${framework}-output.log" || framework_exit=$?

# WebKitGTK emits SIGABRT (exit 134) during process teardown on
# Linux after all tests pass. This is a known race between WebKit
# web-process cleanup and display-server teardown. Treat it as
# success when every test assertion passed (failed: 0 in output).
if [ $framework_exit -eq 134 ]; then
if grep -qE '^\s*failed:\s+0\s*$' "artifacts/testresults/${framework}-output.log" 2>/dev/null; then
echo "WARN: SIGABRT during teardown with all tests passing (WebKitGTK cleanup race) — ignoring"
framework_exit=0
fi
fi

if [ $framework_exit -ne 0 ]; then
exit_code=$framework_exit
fi
Expand Down
30 changes: 13 additions & 17 deletions examples/InfiniFrameExample.BlazorWebView/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,21 @@ namespace InfiniFrameExample.BlazorWebView;
public static class Program {
[STAThread]
private static void Main(string[] args) {
var appBuilder = InfiniFrameBlazorAppBuilder.CreateDefault(args);
InfiniFrameApplication app = InfiniFrameApplication.Initialize();
app.WithBlazorWebView(blazorBuilder => {
blazorBuilder.Services.AddLogging(config => {
config.ClearProviders();
config.AddSerilog();
});

appBuilder.Services.AddLogging(config => {
config.ClearProviders();
config.AddSerilog();
});

appBuilder.Services.AddSerilog(config => {
config.WriteTo.Async(static c => c.Console())
.MinimumLevel.Debug();
});
blazorBuilder.Services.AddSerilog(config => {
config.WriteTo.Async(static c => c.Console())
.MinimumLevel.Debug();
});

// register the root component and selector
appBuilder.RootComponents.Add<App>("app");
blazorBuilder.RootComponents.Add<App>("app");

appBuilder.WithInfiniFrameWindowBuilder(builder => {
builder
blazorBuilder.WindowBuilder
// .SetTransparent(true)
// .SetChromeless(true)
// .SetResizable(true)
Expand All @@ -49,8 +47,6 @@ private static void Main(string[] args) {
;
});

InfiniFrameBlazorApp app = appBuilder.Build();

app.Run();
}
}
}
75 changes: 38 additions & 37 deletions examples/InfiniFrameExample.NativeMenu/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,48 +71,49 @@ public static void Main(string[] args) {
]
);

IInfiniFrameWindow window = InfiniFrameWindowBuilder.Create()
.SetTitle("InfiniFrame Native Menu Example")
.SetSize(new Size(960, 640))
.CenteredOnMainMonitor()
.SetMenuBar(menuBar)
.UseEmbeddedWwwrootAssets(
scheme: "app",
includePhysicalFallback: true,
physicalWwwrootPath: Path.Join(AppContext.BaseDirectory, "wwwroot"),
setStartUrl: true
)
.RegisterWebMessageReceivedHandler((win, message) => {
string? action = ExtractAction(message);
if (action == null) return;
var app = InfiniFrameApplication.Initialize()
.WithWindow(builder => builder
.SetTitle("InfiniFrame Native Menu Example")
.SetSize(new Size(960, 640))
.CenteredOnMainMonitor()
.SetMenuBar(menuBar)
.UseEmbeddedWwwrootAssets(
scheme: "app",
includePhysicalFallback: true,
physicalWwwrootPath: Path.Join(AppContext.BaseDirectory, "wwwroot"),
setStartUrl: true
)
.RegisterWebMessageReceivedHandler((win, message) => {
string? action = ExtractAction(message);
if (action == null) return;

switch (action) {
case "enable-save":
win.Features.Menu.SetMenuItemEnabled("file-save", true);
win.SendWebMessage("status:Save enabled");
break;
switch (action) {
case "enable-save":
win.Features.Menu.SetMenuItemEnabled("file-save", true);
win.SendWebMessage("status:Save enabled");
break;

case "disable-save":
win.Features.Menu.SetMenuItemEnabled("file-save", false);
win.SendWebMessage("status:Save disabled");
break;
case "disable-save":
win.Features.Menu.SetMenuItemEnabled("file-save", false);
win.SendWebMessage("status:Save disabled");
break;

case "toggle-undo":
bool undoVisible = win.Features.Menu.MenuBar.Items
.First(i => i.Id == "edit").Children
.First(i => i.Id == "edit-undo").IsVisible;
win.Features.Menu.SetMenuItemVisible("edit-undo", !undoVisible);
win.SendWebMessage($"status:Undo {(undoVisible ? "hidden" : "shown")}");
break;
case "toggle-undo":
bool undoVisible = win.Features.Menu.MenuBar.Items
.First(i => i.Id == "edit").Children
.First(i => i.Id == "edit-undo").IsVisible;
win.Features.Menu.SetMenuItemVisible("edit-undo", !undoVisible);
win.SendWebMessage($"status:Undo {(undoVisible ? "hidden" : "shown")}");
break;

default:
win.SendWebMessage($"status:Action: {action}");
break;
}
})
.Build();
default:
win.SendWebMessage($"status:Action: {action}");
break;
}
})
);

window.WaitForClose();
app.Run();
}

private static string? ExtractAction(string rawMessage) {
Expand Down
18 changes: 10 additions & 8 deletions examples/InfiniFrameExample.TrimAotSmoke/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ namespace InfiniFrameExample.TrimAotSmoke;
public static class Program {
[STAThread]
public static void Main() {
IInfiniFrameWindow window = InfiniFrameWindowBuilder.Create()
.SetTitle("InfiniFrame Trim/AOT Smoke")
.SetSize(800, 600)
.CenteredOnMainMonitor()
.UseEmbeddedWwwrootAssets()
.Build();
InfiniFrameApplication app = InfiniFrameApplication.Initialize()
.WithWindow(builder => {
builder
.SetTitle("InfiniFrame Trim/AOT Smoke")
.SetSize(800, 600)
.CenteredOnMainMonitor()
.UseEmbeddedWwwrootAssets();
});

window.WaitForClose();
app.Run();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,32 +25,30 @@ private static void Main(string[] args) {
try {
Log.Information("Starting InfiniFrame MudBlazor example...");

var appBuilder = InfiniFrameBlazorAppBuilder.CreateDefault(args);

appBuilder.Services
.AddLogging(config => {
config.ClearProviders();
config.AddSerilog();
})
.AddSerilog(config => {
config.WriteTo.Async(static c => c.Console())
.MinimumLevel.Debug();
})
.AddMudServices();

appBuilder.RootComponents.Add<App>("app");

appBuilder.WindowBuilder
.SetIconFile("wwwroot/favicon.ico")
.RegisterOpenExternalTargetWebMessageHandler();

InfiniFrameSingleFile.AddSingleFileRequirements(appBuilder);

Log.Information("Building InfiniFrame application...");
InfiniFrameBlazorApp application = appBuilder.Build();
InfiniFrameApplication app = InfiniFrameApplication.Initialize();
app.WithBlazorWebView(blazorBuilder => {
blazorBuilder.Services
.AddLogging(config => {
config.ClearProviders();
config.AddSerilog();
})
.AddSerilog(config => {
config.WriteTo.Async(static c => c.Console())
.MinimumLevel.Debug();
})
.AddMudServices();

blazorBuilder.RootComponents.Add<App>("app");

blazorBuilder.WindowBuilder
.SetIconFile("wwwroot/favicon.ico")
.RegisterOpenExternalTargetWebMessageHandler();

blazorBuilder.AddSingleFileRequirements();
});

Log.Information("Running application...");
application.Run();
app.Run();
}
catch (Exception ex) {
Log.Fatal(ex, "Application terminated unexpectedly");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
// ---------------------------------------------------------------------------------------------------------------------
// Imports
// ---------------------------------------------------------------------------------------------------------------------
using InfiniFrame;
using System.Drawing;
using InfiniFrame.SingleFile;

namespace InfiniFrameExample.SingleFileExe.React;

// ---------------------------------------------------------------------------------------------------------------------
// Code
// ---------------------------------------------------------------------------------------------------------------------
public static class Program {
[STAThread]
public static void Main(string[] args) {
InfiniFrameSingleFile.Initialize();

IInfiniFrameWindowBuilder builder = InfiniFrameWindowBuilder.Create()
.SetTitle("InfiniFrame + React")
.SetSize(new Size(960, 640))
.CenteredOnMainMonitor();

builder.AddSingleFileRequirements();
InfiniFrameApplication app = InfiniFrameApplication.Initialize()
.WithWindow(builder => {
builder
.SetTitle("InfiniFrame + React")
.SetSize(new Size(960, 640))
.CenteredOnMainMonitor()
.AddSingleFileRequirements();
});

IInfiniFrameWindow window = builder.Build();
window.WaitForClose();
app.Run();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ public static class Program {
public static void Main(string[] args) {
InfiniFrameSingleFile.Initialize();

IInfiniFrameWindowBuilder builder = InfiniFrameWindowBuilder.Create()
.SetTitle("InfiniFrame + Vue")
.SetSize(new Size(960, 640))
.CenteredOnMainMonitor();
InfiniFrameApplication app = InfiniFrameApplication.Initialize()
.WithWindow(builder => {
builder
.SetTitle("InfiniFrame + Vue")
.SetSize(new Size(960, 640))
.CenteredOnMainMonitor()
.AddSingleFileRequirements();
});

builder.AddSingleFileRequirements();

IInfiniFrameWindow window = builder.Build();
window.WaitForClose();
app.Run();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ public static class Program {
public static void Main(string[] args) {
InfiniFrameSingleFile.Initialize();

IInfiniFrameWindowBuilder builder = InfiniFrameWindowBuilder.Create()
.SetTitle("InfiniFrame Embedded wwwroot")
.SetSize(new Size(960, 640))
.CenteredOnMainMonitor();

builder.AddSingleFileRequirements();

IInfiniFrameWindow window = builder.Build();
InfiniFrameApplication app = InfiniFrameApplication.Initialize()
.WithWindow(builder => {
builder
.SetTitle("InfiniFrame Embedded wwwroot")
.SetSize(new Size(960, 640))
.CenteredOnMainMonitor()
.AddSingleFileRequirements();
});

window.WaitForClose();
app.Run();
}
}
Loading
Loading