Skip to content

feat(gui): a way to support the project, and a window that states its licence - #15

Merged
donislawdev merged 2 commits into
mainfrom
feat/support-link-in-the-title-bar
Sep 9, 2026
Merged

feat(gui): a way to support the project, and a window that states its licence#15
donislawdev merged 2 commits into
mainfrom
feat/support-link-in-the-title-bar

Conversation

@donislawdev

Copy link
Copy Markdown
Owner

Two commits, one theme: the window gains the two things it could not say before - a way to support the project, and what licence it came under.

The support link

A Donate button in the title bar, in the one strip both modules share. Pressing it hands an address to the shell, which starts the browser the user already chose.

This is the first control in the application that leads off the machine, and the product promises it never talks to the internet. That promise still holds - nothing here opens a socket, the browser is what connects - but a QA tool that makes such a promise has to be the one to raise the distinction rather than let somebody discover it. So the tooltip names the address before the button is pressed, and the README and the FAQ say the same in prose. The shorter claims in the footer, on the home page and on the download page are deliberately left alone: they stay true, and qualifying a bullet point ruins the bullet point.

ExternalLinks exposes named destinations rather than an open-this-string method. UseShellExecute runs whatever it is handed, so an address assembled from a dropped file, a recent target or a preset would be a way to start anything. A guard stops a later caller reintroducing that.

The network guard caught this before any new test did, which is exactly what it is for: it did not refuse, it asked for a register entry with a reason. Its own header turned out to contradict its register, offering a URL-opening shell verb as an example of the forbidden list while UseShellExecute has always sat in the watched one with no entry against it. The register was right and the prose was stale, so the prose is fixed rather than quietly worked around.

The About window

The command line has always answered this. chrono license prints the build, the copyright, the SPDX identifier, the warranty disclaimer and every bundled component - between them the Appropriate Legal Notices GPL-3 section 0 describes. The window had none of it, with the version buried in the title bar, and the window is the default way in.

This is not a licence requirement and should not be read as one. Both packages already ship LICENSE and THIRD-PARTY-NOTICES.md beside the executable, which is what MIT and GPL sections 4 and 6 ask for, and section 5(d) exempts an original program whose interfaces do not display such notices. Nobody was owed this window. A reader was.

One source of truth, three times over:

  • the component list comes from the core (chrono license --components), whose register is compiled in from the same file the release SBOM is generated from
  • the copyright is read from the assembly, so it comes from Directory.Build.props - the line a test on the Rust side already compares against the core's constant
  • the SPDX identifier, the one fact with no home on this side, is mirrored against Cargo.toml by a test

The core prints its whole notice ABOVE the component register, so the first build of this window showed every line of it twice - once in its own words and once raw. That is cut at the first group heading rather than by widening the command-line contract with a flag for one caller, and a mirror test pins the heading against the Rust source. When the heading is missing the whole text is shown: an empty component list would be this tool claiming there is nothing third-party inside it, which is the one answer it must never give by accident.

What the renders caught

Three faults that reasoning would not have found, each fixed on a screenshot rather than an argument: the spacing scale is uniform on four sides, so blocks carrying a vertical margin also indent and the first draft had three different left edges; the absent-file line said the same long sentence twice under itself; and the notice appeared twice, as above. Vertical-only gaps are now named resources.

WPF refuses to set Owner on a window that has never been shown, so ownership moved from the constructor to Show, where the owner is on screen by definition. A red build test found that.

Checks

  • gates 12/12, Rust 435 unchanged, C# 392 → 404
  • screenshots before and after the title-bar change are identical byte for byte below the bar, with the bar itself differing as the canary
  • six revert probes, each watched failing: the address, the failure path, an address chosen outside the links file, the scan canary, the window title, and the network register entry
  • the background guard's canary raised from two windows to three, so it notices the newest one

Known limits, stated rather than left to be found

  • the failure path of both link buttons is proven to the point where TryOpen returns false. That a dialog then appears is not verified live, which would need a machine with no browser associated with https
  • the About window says where LICENSE is and offers the online copy - it does not render the licence text itself. Section 0 asks that a reader be told how to view a copy, not that one be displayed

🤖 Generated with Claude Code

donislawdev and others added 2 commits September 9, 2026 12:05
…e it leads

The title bar gains a Donate button beside the window controls, in the one strip
both halves of the application share, so neither module gives up a row for it.
Pressing it hands an address to the shell, which starts the browser the user
already chose.

This is the first control here that leads off the machine, and the product
promises it never talks to the internet. That promise still holds - nothing here
opens a socket, the browser is what connects - but a QA tool that makes such a
promise has to be the one to raise the distinction rather than let somebody
discover it. So the tooltip names the address before the button is pressed, and
the README and the FAQ say the same in prose. The shorter claims in the footer,
on the home page and on the download page are deliberately left alone: they stay
true, and qualifying a bullet point ruins the bullet point.

ExternalLinks exposes named destinations rather than an open-this-string method.
UseShellExecute runs whatever it is handed, so an address assembled from a
dropped file, a recent target or a preset would be a way to start anything. A
guard stops a later caller reintroducing that, with a canary on the count of
calls inside the links file itself, because a scan that reaches nothing passes
just as happily as one that works.

The network guard caught this before any of the new tests did, which is exactly
what it is for: it did not refuse, it asked for a register entry with a reason.
Both entries are added. Its own header turned out to contradict its register,
offering a URL-opening shell verb as an example of the forbidden list while
UseShellExecute has always sat in the watched one with no entry against it. The
register was right and the prose was stale, so the prose is fixed rather than
quietly worked around.

Measured rather than assumed: screenshots before and after are identical byte for
byte everywhere below the title bar, with the bar itself differing as the canary
that makes the comparison mean something. The button reports itself keyboard
focusable to assistive tech, and the heart beside the label is decoration that
stays out of the automation name.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The command line has always answered this. `chrono license` prints the build, the
copyright, the SPDX identifier, the warranty disclaimer and every bundled
component - between them the Appropriate Legal Notices that GPL-3 section 0
describes. The window had none of it, with the version buried in the title bar,
and the window is the default way into this product.

This is not a licence requirement and should not be read as one. Both packages
already ship LICENSE and THIRD-PARTY-NOTICES.md beside the executable, which is
what MIT and GPL sections 4 and 6 actually ask for, and section 5(d) exempts an
original program whose interfaces do not display such notices. Nobody was owed
this window. A reader was.

The component list comes from the core, by running `chrono license --components`,
because the core carries that register compiled in from the same file the release
SBOM is generated from. A copy in C# would have been a fourth thing to keep in
step. For the same reason the copyright line is read from the assembly rather
than written down again, and the SPDX identifier - the one fact with no home on
this side - is mirrored against Cargo.toml by a test.

Three things the renders caught that reasoning would not have. The spacing scale
is uniform on four sides, so blocks carrying a vertical margin also indent, and
the first draft had three different left edges. The absent-file line said the
same long sentence twice under itself. And the core prints its whole notice ABOVE
the component register, so the window showed every line of it twice over - once
in its own words and once raw. That last one is cut at the first group heading
rather than by widening the command-line contract with a flag for one caller, and
a mirror test pins the heading against the Rust source: reworded, the cut would
silently stop finding it and the window would quietly go back to saying
everything twice, which reads as sloppiness rather than a bug and so gets
reported by nobody. When the heading is missing the whole text is shown, because
an empty component list would be this tool claiming there is nothing third-party
inside it, and that is the one answer it must never give by accident.

WPF refuses to set Owner on a window that has never been shown, so the ownership
moved from the constructor to Show, where the owner is on screen by definition.
A red build test found that, not a reading of the docs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@donislawdev
donislawdev merged commit 442ddff into main Sep 9, 2026
8 checks passed
@donislawdev
donislawdev deleted the feat/support-link-in-the-title-bar branch September 9, 2026 12:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant