-
Notifications
You must be signed in to change notification settings - Fork 0
EN Windows 11 WinUI Guide
This document defines the current WinUI 3 presentation rules. It is not a migration log.
-
Shadowsocks.WinUIis the only desktop presentation project. - Use the existing left
NavigationViewshell and built-in Settings entry. - Primary window uses Mica Base where supported; page backgrounds remain transparent unless a dedicated surface is required.
- Closing the window hides it; tray state remains active until explicit Quit.
- Keep persistent application preferences in the main Settings page. The tray is for quick runtime actions, not logging/update preference switches.
- Settings exposes the current data root with an explicit LocalAppData/Clean Mode folder action. In Clean Mode the Start with Windows control is disabled and the displayed root points to the Temp session.
- New profiles automatically download, verify and install newer releases after startup by default. Update preferences live under About & updates; verbose logging and plugin-output preferences live on the Logs page.
- Command labels do not use trailing ellipses; reserve ellipses for transient progress/status text.
- Tray integration belongs to
Shadowsocks.Windows.WinUI; baseShadowsocks.Windowsstays WinUI-free.
- Standard page gutter: 24 epx; compact/minimal navigation: 12 epx.
- Prefer measurements in multiples of 4.
- Use WinUI type-ramp resources such as
TitleTextBlockStyle,BodyTextBlockStyle,BodyStrongTextBlockStyleandCaptionTextBlockStyle. - Use sentence case for UI copy.
- Prefer theme resources (
CardBackgroundFillColorDefaultBrush, etc.) over custom RGB surfaces. - Do not encode state solely by color; combine color with text, glyph or selection state.
Prefer native Fluent controls:
-
NavigationViewfor app navigation; -
ContentDialogfor modal confirmation/details; -
InfoBarfor non-blocking state/errors; -
TeachingTipfor contextual education; -
NumberBoxfor ports/timeouts; -
ToggleSwitchfor binary settings; -
ComboBoxfor typed choices.
Code-only pages are constructed explicitly and hosted in the shell. Avoid introducing another desktop UI framework for missing controls.
- Traffic exposes only User/Admin as selectable modes.
- Administrator mode uses the UAC/shield affordance and applies immediately when selected.
- Traffic reports configured/runtime mode, NetworkService, WinDivert, TCP/UDP capture and redirect ports.
- Game Mode is displayed as automatic state, never as a third selectable traffic mode.
- Game Mode keeps manual executable/path/wildcard rules and may offer best-effort game suggestions from Steam, Epic Games, GOG and Xbox.
- Discovery never adds or enables a game without explicit user action.
- Server Name appears before Server IP in the editor.
- The server plugin field is a
ComboBox:Noneplus plugins installed and resolved byPluginManager; arbitrary PATH/absolute executable fallbacks are not exposed. - Plugin Options and optional Plugin Arguments remain per-server settings.
- The Plugins page owns installation/removal. Built-in entries are
xray-plugin,v2ray-pluginandqtun; manual import accepts ZIP and TAR.GZ packages. Importing anss://URL that references a known missing built-in plugin must offer installation before the normal server-import confirmation, with explicit import-without-plugin and cancel paths. - Catalog-installed plugins expose Automatic updates and are checked once per day while not in use; Check updates forces a pass. In-use packages are deferred and manual imports never perform background network updates.
- Plugin packages are stored below the active storage root so Clean Mode automatically uses its Temp session. Arbitrary custom repository input remains intentionally unavailable until repository trust and release-asset selection are designed.
- Validate the current server before changing selection when edits could be lost.
- Keep an explicit discard path for an unconfigured/new entry.
- Password reveal is available for manually configured servers.
- Password reveal is not shown for servers imported from
ss://links or online configuration sources.
- The Logs toolbar is always visible.
- Do not restore the removed Font or Show toolbar commands.
- The current viewer is a selectable
RichTextBlock(IsTextSelectionEnabled = true), not the retiredListViewimplementation. - Keep the viewer bounded and vertically/horizontally scrollable; long log lines must not force page re-layout.
- Preserve styled severity rendering through the current paragraph/run pipeline, including multiline continuation handling.
- WARN/ERROR/FATAL state must remain visually distinguishable with WinUI theme brushes.
- Top Most uses the WinUI/AppWindow presenter path, not WinForms/WPF APIs.
PAC/GeoSite page controls and tray commands share the same state matrix. In Local PAC mode the page exposes Open user-rule.txt together with managed-routing diagnostics and GeoSite source controls. When Online PAC is selected, those Local managed-routing/user-rule/GeoSite cards are hidden rather than presenting irrelevant state.
DNSCrypt first-use installation/verification/activation must keep an active ProgressRing/ProgressBar and operation text visible. Temporarily unavailable DNS settings should be hidden during that transition instead of presenting a disabled page that looks stalled.
Long-running network/update operations must use async controller APIs and keep the shell responsive.
- WinUI depends on
ILocalizationService; pages do not use the Core compatibility facade directly. - One localization service instance flows through app, shell, pages and tray integration.
- Static control text is localized after control-tree construction; dynamic/formatted text uses page-context localization helpers.
- Do not use translated labels as persisted enum/configuration values.
- CSV column order is
en,ru-RU,zh-CN,zh-TW,ja,ko,fr. - Localization has one source of truth: the embedded
i18n.csv; do not add extracted/user override catalogs.
-
App.xamlownsXamlControlsResources. -
App.InitializeComponent()loads Fluent resources before the first window/control is created. - Custom
Program.Mainperforms same-identity AppInstance redirection, acquires the identity-independentProcessSingleInstanceGuardbefore controller startup, creates startup services, initializes C#/WinRT COM wrappers and starts WinUI through publicApplication.Start(...). Hidden--start-hiddenactivation must never surface the user-visible already-running dialog. - Do not call generated
XamlGeneratedProgramentry points directly. - Keep
Appparameterless for generated XAML compatibility; pass startup context through the existing configuration path.
Shadowsocks.WinUI and Shadowsocks.Windows.WinUI must keep compatible Windows App SDK/WinUI package versions. The base Windows project remains free of those dependencies. After any Windows App SDK update, perform a clean restore/build and smoke-test NavigationView, dialogs, InfoBar, TeachingTip, NumberBox, ToggleSwitch and tray integration.
- Windows App SDK application structure
- WinUI custom title bar
- NavigationView
- Windows design guidelines
- Typography
- Alignment, margin and padding
- Mica material
- Windows app settings guidelines
Use current Microsoft documentation when changing these primitives; do not preserve retired framework workarounds.
- Main pages use a fixed 16-DIP content gutter in every
NavigationViewdisplay mode; page-specific max-width centering must not shift the left edge.
- Hide scenario-specific controls when they have no meaning instead of leaving a large disabled block (for example Plugin=None, No forward proxy, Online PAC versus Local PAC, or non-Admin traffic diagnostics).
- Selection-dependent actions remain disabled until a valid item is selected. Save/Discard actions represent actual unsaved state; duplicate Add actions remain disabled.
- Long-running network/package operations expose visible progress and block conflicting edits/actions until completion. This applies to DNSCrypt, GeoSite refresh, online configurations, plugins and application updates.
- Online PAC URL validation is identical in the page and tray and accepts only absolute HTTP/HTTPS URLs. An invalid persisted URL must be corrected before Online PAC can be enabled.
- Do not destroy hidden unsaved form values merely because a contextual option is temporarily deselected; normalize/clear them only when the configuration is actually saved.
- If an action changes meaning with context, update its label and tooltip together (for example Plugins Install versus Reinstall).
- When an action is intentionally disabled by unsaved prerequisite state, explain the prerequisite in visible localized text rather than leaving the user to infer it (for example GeoSite sources must be saved before refresh).
- Add localized tooltips to non-obvious interactive controls and mirror the same text through
AutomationProperties.HelpTextfor accessibility.
Shadowsocks Reborn refreshes the signed DNSCrypt resolver catalog itself instead of allowing dnscrypt-proxy to bootstrap remote source hostnames. Cloudflare DoH (1.1.1.1, TLS/SNI cloudflare-dns.com) is the primary resolver and Google DoH (8.8.8.8, TLS/SNI dns.google) is the fallback; both DoH HTTPS connections are opened through the active local Shadowsocks SOCKS5 listener. The HTTPS download of public-resolvers.md and .minisig also travels through Shadowsocks after the source hostname is resolved by that DoH path.
The downloaded pair is size-bounded and verified with the pinned DNSCrypt public Minisign key before publication. dnscrypt-proxy then receives only the local authenticated cache with urls = [], bootstrap_resolvers = [] and ignore_system_dns = true. If refresh is temporarily unavailable, an existing valid signed cache may continue to be used; without a valid cache the operation fails closed and the previous DNS mode is retained.