Support status, Copy diagnostics and local logs

What the user gets

Settings → Support (reachable by Ctrl+PageDown or the tab strip) looks like this:

Support page

ControlBehaviour
Status (read-only text)App version, Windows build, a one-word state and a plain explanation. When the native clock is showing, the text says why and what to do (see the table below)
Refresh status (Alt+F)Asks for a fresh, bounded discovery. The window stays responsive; the line below the page says “Checking the taskbars…”, then “Status refreshed.”
Report text that Copy diagnostics will copy (read-only, selectable)Exactly the text that will be copied
Copy diagnostics (Alt+D)Writes that text to the clipboard only on this click. The line below the page says “Diagnostics copied to the clipboard.” or what went wrong

Tab order on the page: status, Refresh status, report, Copy diagnostics. The result line raises a screen-reader alert (EVENT_SYSTEM_ALERT) whenever it changes, the same way Settings’ main status line does.

Status states

StateWhenWhat it says to do
ActiveThe clock is on every selected taskbarNothing. Displays the user left out in Settings are mentioned, never counted as a problem
Active on some taskbarsAt least one but not all selected taskbarsNames each remaining taskbar and why
Active, clock hidden for nowHidden by design (full screen, locked, taskbar auto-hidden)It returns by itself
PausedThe user paused from the clock/tray menuChoose Resume
Windows clock in usePosition unverified, unusable geometry, text does not fit, draw/placement failure, calendar action failed, discovery failed, Explorer not running, discovery turned offOne actionable sentence per cause: shorter format or smaller font, Pause then Resume, restart Explorer, Exit and start again, “this Windows version may not be supported yet”
Looking for the taskbarDiscovery has not answered yetWait

The report

A real sample, produced by the harness on the machine above:

ElevenClock-rs diagnostics
Generated (UTC): 2026-10-16 07:16:25
Contains no user name, file paths or window titles. Nothing is sent anywhere; this text is only copied if you choose Copy diagnostics.

App version: 0.1.0
App commit: 482dd5f36842+modified
Windows: 10.0.26200.9711 (25H2)
Architecture: Windows x64, app x64

Clock replacement: Active
Summary: The ElevenClock-rs clock is showing on your taskbar. Other displays keep the Windows clock because Settings shows the clock on the primary display only.
Paused by user: no
Windows Explorer running: yes
Taskbar discovery: last attempt succeeded

Taskbars: 2
1. Primary taskbar: clock replaced
   Monitor: 1280x720 px at (0, 0), DPI 96 (100%)
   Discovery strategy: UI Automation; clock located: yes
2. Secondary taskbar: not used: this display is not selected in Settings (Appearance)
   Monitor: 1280x720 px at (1280, 0), DPI 96 (100%)
   Discovery strategy: UI Automation; clock located: yes

A managed copy (ADR 0004) adds two lines after Architecture: and the Status text shows “(managed by your organization)” after the version. The sample above predates them; a current report has Managed: no and Startup: off there:

LineValues
Managed:yes when elevenclock-rs-launcher.exe sits in the app’s own folder, otherwise no. Checked again each time Settings opens
Startup:Which program the sign-in entry starts: app, launcher (the sibling launcher), off (no entry, or Windows has it turned off) or stale (registered for something else). Never a path

It is plain text for a person, with no schema: the layout may change between versions and nothing parses it. The commit is recorded by clock-windows/build.rs (+modified marks a build from uncommitted changes; unknown means no git checkout).

Privacy

Bounded refresh, with no blocking

Runtime::refresh_status() requests the ordinary discovery as if the display layout had changed (a 250 ms settle, then the existing helper process with its five second deadline, never UI Automation on the UI thread). The answer arrives as a normal Input::Discovery, which bumps Diagnostics::discovery_completed. RefreshWatch (pure, in support) turns that into Waiting / Done / TimedOut:

SituationResult
Answer arrives“Status refreshed.” and the page shows the new state
Helper fails or hits its deadlineStill an answer: a failure report, shown with its reason (“Taskbar discovery did not finish in time.”)
Nothing arrives within 10 s (REFRESH_LIMIT)“Checking the taskbars took too long. Showing the last known status. Choose Refresh status to try again.”
Discovery is turned off for the sessionDone at once; the status explains it
Refresh clicked again while one is running“Still checking the taskbars.”; no second request

The Refresh button is never disabled, so the keyboard cannot be stranded on a disabled control. The page rewrites its text only when the diagnostics changed.

Copy diagnostics and the clipboard

support::WindowsClipboard writes CF_UNICODETEXT in this order, so every failure that can happen before the old contents are replaced leaves them alone:

  1. Allocate and fill the global memory. Failure → “Windows is low on memory.” Clipboard untouched.
  2. OpenClipboard with the dialog as owner, up to 5 attempts 10 ms apart (about 40 ms on the UI thread, in total). Failure → “Another program is using the clipboard. Wait a moment and choose Copy diagnostics again. Your clipboard was not changed.”
  3. EmptyClipboard, then SetClipboardData. If the second call fails the message says “The clipboard was cleared.” instead (the only window in which contents are lost; Windows offers no atomic replace).

Bounded local log

logging::RotatingLog keeps elevenclock-rs.log, .1.log and .2.log in %LOCALAPPDATA%\ElevenClock-rs\logs: at most three files of 1 MiB (MAX_FILE_BYTES, MAX_FILES), a line is cut at 1 KiB, and rotation happens before a write could exceed the limit. It logs transitions, not repaints: a taskbar’s outcome changing, a discovery failure or recovery, pause/resume, discovery turned off, a refresh request, a copy, a failed save, start and stop, and a panic message. Runtime::transition_lines compares against what it last logged, so a minute of ticks writes nothing.

The managed launcher (ADR 0004) writes the same bounded log under its own name, launcher.log, launcher.1.log and launcher.2.log beside the app’s files (RotatingLog::named), through the same redaction. It records one line per decision (updated, unchanged, skipped: running, source unreachable, source invalid: ..., refused: installed copy, started) and never a path or user name. The Copy diagnostics report does not read these files.

Every write error (no folder, disk full, locked file) is swallowed and the next write starts from a fresh look at the disk. Only the primary instance logs. Lines pass through support::redact. Sample from the harness run:

2026-10-16T07:12:32Z ElevenClock-rs 0.1.0 started
2026-10-16T07:12:33Z primary taskbar 1: clock replaced
2026-10-16T07:12:33Z secondary taskbar 2: clock hidden for now: this display is not selected in Settings (Appearance)
2026-10-16T07:12:42Z status refresh requested
2026-10-16T07:12:44Z diagnostics copied to the clipboard
2026-10-16T07:12:48Z ElevenClock-rs stopped

Where the code is

The dependency direction is app → windows, but Settings (in clock-windows) must show the report and the runtime (in clock-windows) produces the transition lines, so the report and the writer live in clock-windows:

FileOwns
clock-windows/src/support.rs (+ support/native.rs)Status wording, report, redaction, RefreshWatch, clipboard wording and trait; Windows build/architecture; the clipboard
clock-windows/src/logging.rsRotatingLog, global best-effort log, init
clock-windows/build.rsRecords the commit
clock-windows/src/runtime.rsDiagnostics gains monitor bounds, DPI, strategy, clock_located, shell_running, discovery_pending, discovery_completed; refresh_status; transition_lines
clock-windows/src/settings.rs, clock-app/resources/settings.rcThe Support page
clock-app/src/logging.rsStarts logging, panic hook, start/stop lines

No dependency was added (tracing and clap are not used); the clipboard APIs are listed in clock-windows/bindings.txt. preferences_store::app_data_dir is the one Known Folder lookup, now shared by preferences and logs.

Known limits