RANDOM MAC v1.1.1
RANDOM MAC v1.1.1
UX polish + correctness fixes on top of the WinUI 3 framework migration that landed in v1.1.0. Application logic in RandomMac.Core is unchanged. Existing settings.json / blacklist.json / history.json files load without migration.
Built with C# 13 / .NET 11 (preview) for the App project, .NET 9 for Core.
Highlights
- Tray quick action — right-click the tray icon → "Randomize Active Adapter" applies a fresh MAC to the first connected adapter without opening the window.
- Hamburger toggle — collapse the navigation pane to icon-only (48px).
- Auto-apply Settings — every toggle / combo applies immediately and persists with a 500ms debounce. The "Save" button is gone.
- Window 1024×680 — was 880×600. More breathing room for the DataGrid history and the Settings sections.
- Auto-update check on launch — silent, throttled to once every 24h. Surfaces a toast if a new version is available.
- History retention — entries older than 30 days are pruned automatically; saves are atomic via
.tmp+File.Move; corrupt files are backed up to.bak.<ts>before any new write. - Bundle export — Settings → "Export All (zip)" produces a single ZIP with
settings.json+blacklist.json+history.jsonfor backup or migrating between machines. - History filter — live search above the Recent History grid by adapter name or MAC string.
- Keyboard shortcuts —
Ctrl+1..5to jump pages,Ctrl+RRandomize,Ctrl+EnterApply. - Empty state + status InfoBars — Dashboard shows a "Pick an adapter" hint when nothing is selected; status messages appear in an InfoBar that auto-clears after 5 seconds.
- Polish — page transitions (slide+fade), Update view rewrite (state-driven hero card with last-checked), About rewrite (centered hero + compact dependency list), connection icon + text (was a 10px dot), WiFi/Ethernet glyphs in the adapter dropdown, relative timestamps in history ("just now" / "5 min ago" / "yesterday" /
yyyy-MM-dd HH:mm), Mica + Acrylic backdrop fallback chain, scrollbars hidden but scroll input still works.
Bug fixes
- DataGrid headers in Recent History showed the literal string
Microsoft.UI.Xaml.Data.Binding.DataGridColumnis not in the visual tree, so XAML{Binding}onHeaderdoesn't resolve. Headers are now set fromDashboardView.xaml.csand refreshed onLoc.PropertyChanged. - Dashboard Refresh always reported "Error loading adapters".
IAdapterCacheService.RefreshAsyncusesConfigureAwait(false), so subscribers ran on the threadpool and mutated the boundObservableCollectioncross-thread. Subscribers now marshal throughApp.MainDispatcher.TryEnqueue. - Recent History timestamps always read "7 h ago" on UTC+7 machines.
Timestampdefaults toDateTime.UtcNow(correct), but the converter computedDateTime.Now - when(local - utc). Fixed by normalizing the input viaKind-awareToLocalTime(). - Recent History wiped when in-memory list happened to be empty.
LoadAsyncused to swallow JSON parse failures; the nextSaveAsyncthen wrote the empty list, overwriting the user's on-disk entries. Hardened with a_loadCompletedgate, corrupt-file backup, and atomic.tmp+File.Movewrites. - FontIcon glyphs invisible — raw Private-Use-Area chars in XAML attribute values were silently stripped to empty by the file write pipeline. Replaced all inline glyphs with XML entity references (
). - Hamburger collapse left "first letter peek" — custom
MenuItemTemplaterendered the label TextBlock independently of the auto-collapse logic. AddedIsPaneOpentwo-way binding onMainWindowViewModeland aNavItem.Ownerback-reference so the template can hide the label. - Tray right-click menu items inert + double-click no-op + window not focused on Show. Added
XamlRootlazy-init forMenuFlyout,DoubleClickCommand, and Win32ShowWindow(SW_RESTORE)+SetForegroundWindow. - LogView "Failed to export log: File extensions must begin with '.' and contain no wildcards". WinUI 3
FileSavePicker.FileTypeChoicesrejects.*. Removed the wildcard entry. - Settings export / import / bundle export consistently failed in elevated unpackaged WinUI 3.
Windows.Storage.Pickers.FileSavePicker/FileOpenPickerroute through a broker that can't elevate cross-process. All four pickers (Settings export, Settings import, Bundle export, Log export) now use a Win32comdlg32wrapper (Helpers/Win32FileDialog.cs) running in-process. Output buffer usesIntPtrinstead ofStringBuilderso theOPENFILENAMEWstruct is blittable forMarshal.SizeOf. Resources["Loc"] = Loc.Instancecrashed at startup withCOMException 0x8000FFFF. The COM proxy isn't fully wired in the App constructor even afterInitializeComponent(). Moved to the start ofOnLaunched.- Plain
dotnet buildfailed withWindowsAppSDKSelfContained requires a supported Windows architecture. Added a defaultRuntimeIdentifier=win-x64in the csproj so Rider/VS builds work without-rflags.
Removed
- The 6-color accent picker. Brand accent is hardcoded to
#61AFEF. TheAccentColorfield is dropped fromAppSettings; existingsettings.jsonfiles load without migration (System.Text.Json ignores unknown keys). - The "Save" button from Settings (everything auto-applies + auto-saves now).
- The "All Files (
.*)" choice from LogView's export dialog (WinUI 3 picker rejects wildcards). - Dead
accentColorparameter fromThemeService.Apply(string mode, string accentColor)→ nowApply(string mode).
What did NOT change
- Every algorithm in
RandomMac.Core: MAC generation, registry write, WMI restart, blacklist, history, settings, OUI lookup, update service. - Velopack 0.0.1298 packaging (unpackaged, self-contained).
requireAdministratormanifest (no UAC at boot via Task Scheduler).- All 116 localization keys in
Lang.resx/Lang.vi.resx. - All 37 RandomMac.Tests unit tests still pass.
Smoke checklist (manual)
- Launch as Administrator. Window opens at 1024×680, fixed, no maximize.
- Toggle theme Dark↔Light and language EN↔VI in Settings — UI re-renders live, no Save click needed.
- Press
Ctrl+1..5from anywhere — jumps to corresponding nav page. - Minimize → tray icon visible. Double-click → window restored to foreground.
- Right-click tray → menu shows Show / Randomize Active Adapter / Exit. Each one fires.
- Apply MAC on Dashboard → Recent History row's Time column reads "just now". After ~5 min → "5 min ago".
- Filter Recent History by adapter name → grid filters live.
- Settings → Export → save dialog opens with JSON filter; pick a path → file written.
- Settings → Import → open dialog → pick a file → settings reloaded.
- Settings → Export All (zip) → save → unzip the result →
settings.json+blacklist.json+history.jsoninside. - Log → Export Log → save dialog with
.txt/.logchoices → file written. - Tail
%LOCALAPPDATA%\RandomMac\logs\log-*.txtafter cold launch — each adapter logs exactly once. - Restart app — log shows
Auto update check: status=…after ~5 seconds (skipped silently if last check < 24h ago).
Compatibility
- Windows 11 (Mica) / Windows 10 22H2 (Acrylic fallback) / older (solid backdrop).
- x64 only. ARM64 not supported in this release.
- Bundled WinAppSDK runtime + .NET 11 (~225 MB self-contained).
- Building from source needs the .NET 11 preview SDK (
global.jsonpinned); see DEV_ENVIRONMENT.md.