Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
35 changes: 34 additions & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,13 +1,46 @@
<Project>

<!--
Centralize the Windows App SDK version so all projects stay in sync.
Centralize the Windows App SDK + CsWinRT versions so all projects stay in sync.
This uses the public Microsoft.WindowsAppSDK package from NuGet.
To install: dotnet restore (NuGet will pull the package automatically).
-->
<PropertyGroup>
<WindowsAppSDKVersion>2.0.1</WindowsAppSDKVersion>
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
<!-- CsWinRT pin. Latest 2.3.x is currently a prerelease; bump to the next
stable when it ships. The PackageReference is added in
Directory.Build.targets for any project that opts into WinUI. -->
<CsWinRTVersion>2.3.0-prerelease.251115.2</CsWinRTVersion>
</PropertyGroup>

<!-- ──────────────────────────────────────────────────────────────────
CsWinRT best-practice defaults for WinUI projects.

Modeled on OSClient's UES.Common.CSharp.SDK.props
(microsoft.visualstudio.com/OS — Build/MSBuild/UES.Common.CSharp.SDK.props),
trimmed to the settings that make sense for a pure WinAppSDK repo
(no UWP, no OS XAML mixing, no AOT-merged WinRT components).

Gated on UseWinUI=true so analyzers/source-generators/etc that don't
reference WinAppSDK keep their default behavior.
────────────────────────────────────────────────────────────────── -->
<PropertyGroup Condition="'$(UseWinUI)' == 'true'">
<!-- Get verbose CsWinRT diagnostics in the build log — same default OSClient uses. -->
<CsWinRTEnableLogging>true</CsWinRTEnableLogging>

<!-- We don't author WinRT projections in this repo (we only consume them).
IID patching adds startup cost for projection authors and is not needed
for consumers. -->
<CsWinRTIIDOptimizerOptOut>true</CsWinRTIIDOptimizerOptOut>

<!-- Don't pick up a side-by-side UWP toolset that may exist on a dev box.
Keeps local builds matching what the CI/lab build will produce. -->
<CsWinRTUseEnvironmentalTools>false</CsWinRTUseEnvironmentalTools>

<!-- By default CsWinRT loads WinRT components into a separate AssemblyLoadContext,
which breaks JIT-only test/sample apps. Production AOT builds aren't affected. -->
<CsWinRTLoadComponentsInDefaultALC>true</CsWinRTLoadComponentsInDefaultALC>
</PropertyGroup>

<!-- Default Platform to the current machine architecture so that
Expand Down
16 changes: 16 additions & 0 deletions Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,20 @@
<PublishAot>false</PublishAot>
</PropertyGroup>

<!-- ───────────────────────────────────────────────────────────────────
Pin Microsoft.Windows.CsWinRT to the version centralized in
$(CsWinRTVersion) (Directory.Build.props). Without this the version
floats with whatever WinAppSDK pulls in transitively — currently a
very old 2.0.x — and we lose access to newer projection generators
and analyzer rules.

PrivateAssets=all because CsWinRT is a build-time generator; the
downstream nupkg should not list it as a dependency.
─────────────────────────────────────────────────────────────────── -->
<ItemGroup Condition="'$(UseWinUI)' == 'true'">
<PackageReference Include="Microsoft.Windows.CsWinRT"
Version="$(CsWinRTVersion)"
PrivateAssets="all" />
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion samples/Reactor.TestApp/Demos/SpecializedEditorsDemo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ static FieldDescriptor[] BuildExplicitColumns() =>
// Explicit: only offer three of the four enum values here.
TypedColumns.ComboBoxColumn<Gizmo, GizmoPriority>(
"Priority", g => g.Priority,
choices: [GizmoPriority.Low, GizmoPriority.Medium, GizmoPriority.High],
choices: (GizmoPriority[])[GizmoPriority.Low, GizmoPriority.Medium, GizmoPriority.High],
width: 110),
TypedColumns.HyperlinkColumn<Gizmo>("Website", g => g.Website, width: 200),
TypedColumns.ColorColumn<Gizmo>("AccentColor", g => g.AccentColor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ .. D3Axes(xs, ys, left, top, width, height),
.. Enumerable.Range(0, 4).Select(n => n * 5)
.Select(i => D3Charts.Text(xs.Map(i) - 12, top + height + 4, $"Day {i + 1}", 10, ChartMutedForeground)),
D3Charts.Text(2, top - 14, "Price", 11, ChartMutedForeground),
.. D3Legend(left + width - 120, top + 5, [("Bullish", bullBrush), ("Bearish", bearBrush)])]
.. D3Legend(left + width - 120, top + 5, ((string, Microsoft.UI.Xaml.Media.SolidColorBrush)[])[("Bullish", bullBrush), ("Bearish", bearBrush)])]
)
.AutomationName("Stock Price Candlestick Chart")
.FullDescription("Candlestick chart showing 20 trading days of OHLC price data, with green candles for bullish and red for bearish days.");
Expand Down
2 changes: 1 addition & 1 deletion samples/ReactorCharting.Gallery/Samples/CirclePacking.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ .. allNodes.SelectMany(node =>
};
}

return [circle];
return (Element[])[circle];
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public override Element Render()
stroke: greenBrush, strokeWidth: 2, curve: D3Curve.MonotoneX),
D3LinePath(data, x: d => xScale.Map(d.X), y: d => yScale.Map(d.B),
stroke: redBrush, strokeWidth: 2, curve: D3Curve.MonotoneX),
.. D3Legend(lx, marginTop + 6, [("Revenue", greenBrush), ("Expenses", redBrush)]),
.. D3Legend(lx, marginTop + 6, ((string, Microsoft.UI.Xaml.Media.SolidColorBrush)[])[("Revenue", greenBrush), ("Expenses", redBrush)]),
Microsoft.UI.Reactor.Charting.D3Charts.Text(marginLeft, 4, "Difference Chart (Revenue vs Expenses)", 14, ChartForeground),
])
.AutomationName("Difference Chart (Revenue vs Expenses)")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ .. items.Select((item, i) =>
TextRight(2, top + band.Map(item) + band.Bandwidth / 2 - 7, item, left - 6, 10, ChartMutedForeground)),

// Legend
.. D3Legend(left + plotW - 120, top + 2, [("Positive", posBrush), ("Negative", negBrush)]),
.. D3Legend(left + plotW - 120, top + 2, ((string, Microsoft.UI.Xaml.Media.SolidColorBrush)[])[("Positive", posBrush), ("Negative", negBrush)]),

D3Charts.Text(left, 4, "Customer Sentiment Scores", 13, ChartForeground),
]
Expand Down
2 changes: 1 addition & 1 deletion samples/ReactorCharting.Gallery/Samples/SlopeChart.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ .. items.SelectMany(item =>
}),

// Legend
.. D3Legend(canvasW / 2 - 80, canvasH - 22, [("Improved", Brush(Palette[2])), ("Declined", Brush(Palette[3]))]),
.. D3Legend(canvasW / 2 - 80, canvasH - 22, ((string, Microsoft.UI.Xaml.Media.SolidColorBrush)[])[("Improved", Brush(Palette[2])), ("Declined", Brush(Palette[3]))]),
]
)
.AutomationName("Department Performance: Before vs After")
Expand Down
8 changes: 4 additions & 4 deletions samples/TodoApp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,21 @@ static class TodoReducer
AddItem when !string.IsNullOrWhiteSpace(state.NewItemText) =>
state with
{
Items = [.. state.Items, new(Guid.NewGuid().ToString(), state.NewItemText.Trim(), false)],
Items = (TodoItem[])[.. state.Items, new(Guid.NewGuid().ToString(), state.NewItemText.Trim(), false)],
NewItemText = ""
},
ToggleItem t => state with
{
Items = [.. state.Items.Select(i =>
Items = (TodoItem[])[.. state.Items.Select(i =>
i.Id == t.Id ? i with { IsCompleted = !i.IsCompleted } : i)]
},
DeleteItem d => state with
{
Items = [.. state.Items.Where(i => i.Id != d.Id)]
Items = (TodoItem[])[.. state.Items.Where(i => i.Id != d.Id)]
},
SetNewItemText s => state with { NewItemText = s.Text },
SetFilter f => state with { Filter = f.Filter },
ClearCompleted => state with { Items = [.. state.Items.Where(i => !i.IsCompleted)] },
ClearCompleted => state with { Items = (TodoItem[])[.. state.Items.Where(i => !i.IsCompleted)] },
_ => state
};
}
Expand Down
4 changes: 2 additions & 2 deletions src/Reactor/Charting/Charts.Tree.cs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ IReadOnlyList<ChartSeriesDescriptor> IChartAccessibilityData.Series
return new ChartPointDescriptor(label, node.Depth);
}).ToArray();

return [new ChartSeriesDescriptor("Nodes", points)];
return (ChartSeriesDescriptor[])[new ChartSeriesDescriptor("Nodes", points)];
}
}

Expand Down Expand Up @@ -390,7 +390,7 @@ IReadOnlyList<ChartSeriesDescriptor> IChartAccessibilityData.Series
$"{sourceName} to {targetName}, weight {link.Strength}");
}).ToArray();

return [new ChartSeriesDescriptor("Edges", points)];
return (ChartSeriesDescriptor[])[new ChartSeriesDescriptor("Edges", points)];
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/Reactor/Charting/Charts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ IReadOnlyList<ChartSeriesDescriptor> IChartAccessibilityData.Series
return new ChartPointDescriptor(xLabel, yVal, label);
}).ToArray();

return [new ChartSeriesDescriptor(seriesName, points)];
return (ChartSeriesDescriptor[])[new ChartSeriesDescriptor(seriesName, points)];
}
}

Expand All @@ -407,7 +407,7 @@ IReadOnlyList<ChartAxisDescriptor> IChartAccessibilityData.Axes
var (xMin, xMax) = D3Extent.Extent(Data, XAccessor);
var (yMin, yMax) = D3Extent.Extent(Data, YAccessor);

return [
return (ChartAxisDescriptor[])[
new ChartAxisDescriptor(ChartAxisType.X, _xAxisLabel, xMin, xMax, _xUnits),
new ChartAxisDescriptor(ChartAxisType.Y, _yAxisLabel, yMin, yMax, _yUnits),
];
Expand Down Expand Up @@ -672,7 +672,7 @@ IReadOnlyList<ChartSeriesDescriptor> IChartAccessibilityData.Series
}).ToArray();

var seriesName = _seriesNames?.Length > 0 ? _seriesNames[0] : "Slices";
return [new ChartSeriesDescriptor(seriesName, points)];
return (ChartSeriesDescriptor[])[new ChartSeriesDescriptor(seriesName, points)];
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/Reactor/Hosting/ReactorHostControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ private void Render()
// additional reset steps, throttling) only need editing here.
void RecoverFromHookOrder(HookOrderException ex, RenderContext ctx, string mode)
{
_logger.LogWarning(ex,
_logger?.LogWarning(ex,
"Hot reload: hook order/type changed — resetting {Mode} state and re-rendering",
mode);
ctx.ResetForHotReload();
Expand Down
8 changes: 8 additions & 0 deletions tests/Reactor.AppTests.Host/Reactor.AppTests.Host.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@
<Nullable>enable</Nullable>
<UseWinUI>true</UseWinUI>
<WindowsPackageType>None</WindowsPackageType>
<!-- CsWinRT1032 (collection-literal targeting non-mutable interface) and
CsWinRT1033 (cast through [ComImport] interface) are AOT/trimming
warnings about data flowing across a WinRT ABI boundary. The
selftest harness uses ITaskbarList3 via classic COM interop and the
fixtures pass collection literals into managed Reactor APIs — neither
crosses a WinRT projection boundary, and the host is never AOT-
published. Suppress to keep selftest code idiomatic. -->
<NoWarn>$(NoWarn);CsWinRT1032;CsWinRT1033</NoWarn>
</PropertyGroup>

<ItemGroup>
Expand Down
6 changes: 6 additions & 0 deletions tests/Reactor.Tests/Reactor.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
<OutputType>Library</OutputType>
<!-- CsWinRT1032 (collection-literal targeting non-mutable interface) and
CsWinRT1033 (cast through [ComImport] interface) are AOT/trimming
warnings about data flowing across a WinRT ABI boundary. These tests
call managed Reactor APIs directly and are never AOT-published, so
neither concern applies. Suppress to keep test code idiomatic. -->
<NoWarn>$(NoWarn);CsWinRT1032;CsWinRT1033</NoWarn>
</PropertyGroup>

<ItemGroup>
Expand Down
Loading