diff --git a/CHANGELOG.md b/CHANGELOG.md
index d08446a..a84e35d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -475,6 +475,16 @@ because it turns other people's test suites red.
### Fixed
+- **The window uses far less memory, and rebuilding a screen no longer adds
+ to it.** Every
+ quiet line on a screen - a subtitle, a caption, the count of bytes beside a
+ size, the line a folded section keeps, the message under a field - parsed
+ its own copy of the fonts, and parsed another each time the screen was
+ rebuilt and the line said something new. After visiting the four tabs the
+ window held about 290 MB and it now holds about 120 MB, and rebuilding a
+ screen no longer adds to it. Nothing on the screen looks different. The open
+ list of formats still does this when you type into its filter, and is next.
+
- **The `Several batches` screen no longer slows down the longer it is
used.** Every batch added, removed or copied, every format chosen and every
press of `Start from a preset` made each box on the screen report a change
diff --git a/internal/guard/leftedge_test.go b/internal/guard/leftedge_test.go
index 0f70a00..a2f06db 100644
--- a/internal/guard/leftedge_test.go
+++ b/internal/guard/leftedge_test.go
@@ -138,7 +138,9 @@ func TestTheActionBarSpeaksOnTheSameEdgeAsTheForm(t *testing.T) {
if status == nil {
t.Fatal("the bar is not naming the destination at rest, so this guard read the wrong tree")
}
- at, found := absoluteOf(generate, status)
+ // Measured where its words are, which labelBox knows for a line drawn
+ // ink tight - the label itself stands one padding to the left of them.
+ at, found := labelBox(generate, status.Text)
if !found {
t.Fatal("the status line is not on the screen it was found in")
}
diff --git a/internal/guard/spacingscale_test.go b/internal/guard/spacingscale_test.go
index 0eb52f1..2feec5f 100644
--- a/internal/guard/spacingscale_test.go
+++ b/internal/guard/spacingscale_test.go
@@ -239,17 +239,34 @@ func gapBelowField(t *testing.T, screen fyne.CanvasObject, above, below string)
//
// Found by the text on the label rather than by a position handed in, because
// a guard given coordinates would be a copy of the layout it is checking.
+//
+// A sentence drawn ink tight (parts.inkTight) is measured by the room it was
+// given, not by the label. Since 2026-09-23 the layout places the label one
+// inner padding up and left and one larger on every side, so its padding falls
+// outside the room and its words land on the room's edge - the label's own
+// box is where its padding is, and the room is where the ink is, exactly
+// where the label stood when a theme override took the padding off instead.
func labelBox(screen fyne.CanvasObject, words string) (band, bool) {
found := band{}
ok := false
+ tight := map[fyne.CanvasObject]band{}
atAbsolute(screen, func(o fyne.CanvasObject, at fyne.Position) {
if ok {
return
}
+ if room, is := o.(*fyne.Container); is && len(room.Objects) == 1 {
+ if p := room.Objects[0].Position(); p.X < 0 && p.X == p.Y {
+ tight[room.Objects[0]] = band{X: at.X, Y: at.Y, Width: room.Size().Width, Height: room.Size().Height}
+ }
+ }
shown, is := wordsOf(o)
if !is || shown != words {
return
}
+ if room, drawnTight := tight[o]; drawnTight {
+ found, ok = room, true
+ return
+ }
found, ok = band{X: at.X, Y: at.Y, Width: o.Size().Width, Height: o.Size().Height}, true
})
return found, ok
diff --git a/internal/guard/testdata/screens/about.xml b/internal/guard/testdata/screens/about.xml
index 60dfad9..50012c6 100644
--- a/internal/guard/testdata/screens/about.xml
+++ b/internal/guard/testdata/screens/about.xml
@@ -33,26 +33,22 @@
-
-
-
-
- Testing Files Generator 0.3.0
-
+
+
+
+ Testing Files Generator 0.3.0
-
-
+
+
-
-
-
-
- Generate test files, and know how the system under test should react to them.
-
+
+
+
+ Generate test files, and know how the system under test should react to them.
-
-
+
+
@@ -63,41 +59,35 @@
•
-
-
-
-
- Choose a preset, or fill in one batch on the first screen.
-
-
-
-
+
+
+
+ Choose a preset, or fill in one batch on the first screen.
+
+
+
•
-
-
-
-
- Press Generate. The files and a manifest land in the output folder.
-
-
-
-
+
+
+
+ Press Generate. The files and a manifest land in the output folder.
+
+
+
•
-
-
-
-
- Point your test at the manifest. For every file it says what the system under test should do with it - accept it, reject it
- or sanitize it - or records the outcome as unspecified, where the right answer belongs to the application's own
- policy.
-
-
-
-
+
+
+
+ Point your test at the manifest. For every file it says what the system under test should do with it - accept it, reject it
+ or sanitize it - or records the outcome as unspecified, where the right answer belongs to the application's own
+ policy.
+
+
+
@@ -110,28 +100,26 @@
Licence
-
-
-
-
- Testing Files Generator
- Copyright (C) 2026 DonislawDev
-
- Released under the GNU General Public License, version 3. The full text is at
- https://www.gnu.org/licenses/gpl-3.0.html, and in the LICENSE file if you have the source or the full release.
-
- There is no warranty, to the extent the law allows.
-
- The files you generate are yours. Generated files, recipes and manifests are output of this program and not derived
- works of it, so this licence does not reach them. You can generate fixtures, commit them and ship them inside a closed
- source product with no obligation of any kind.
-
- Code from other projects is compiled into this program. Their licences and copyright notices are in
- THIRD-PARTY-NOTICES.md, which comes with the source and with the full release.
-
+
+
+
+ Testing Files Generator
+ Copyright (C) 2026 DonislawDev
+
+ Released under the GNU General Public License, version 3. The full text is at
+ https://www.gnu.org/licenses/gpl-3.0.html, and in the LICENSE file if you have the source or the full release.
+
+ There is no warranty, to the extent the law allows.
+
+ The files you generate are yours. Generated files, recipes and manifests are output of this program and not derived
+ works of it, so this licence does not reach them. You can generate fixtures, commit them and ship them inside a closed
+ source product with no obligation of any kind.
+
+ Code from other projects is compiled into this program. Their licences and copyright notices are in
+ THIRD-PARTY-NOTICES.md, which comes with the source and with the full release.
-
-
+
+
@@ -142,15 +130,13 @@
Support
-
-
-
-
- Opens the support page in your browser. The tool is free and stays free - this pays for the time that goes into it.
-
+
+
+
+ Opens the support page in your browser. The tool is free and stays free - this pays for the time that goes into it.
-
-
+
+
@@ -158,15 +144,13 @@
Donate
-
-
-
-
- https://donislawdev.com/support/
-
+
+
+
+ https://donislawdev.com/support/
-
-
+
+
@@ -179,904 +163,718 @@
-
-
-
-
- Go runtime and standard library
-
-
-
-
-
-
-
-
- BSD-3-Clause
-
-
-
-
-
-
-
-
- Copyright 2009 The Go Authors
-
-
-
-
+
+
+
+ Go runtime and standard library
+
+
+
+
+
+
+ BSD-3-Clause
+
+
+
+
+
+
+ Copyright 2009 The Go Authors
+
+
+
-
-
-
-
- fyne.io/fyne/v2
-
-
-
-
-
-
-
-
- BSD-3-Clause
-
-
-
-
-
-
-
-
- (C) 2018 Fyne.io developers (see AUTHORS)
-
-
-
-
+
+
+
+ fyne.io/fyne/v2
+
+
+
+
+
+
+ BSD-3-Clause
+
+
+
+
+
+
+ (C) 2018 Fyne.io developers (see AUTHORS)
+
+
+
-
-
-
-
- fyne.io/systray
-
-
-
-
-
-
-
-
- Apache-2.0
-
-
-
-
-
-
-
-
- 2014 Brave New Software Project, Inc.
-
-
-
-
+
+
+
+ fyne.io/systray
+
+
+
+
+
+
+ Apache-2.0
+
+
+
+
+
+
+ 2014 Brave New Software Project, Inc.
+
+
+
-
-
-
-
- github.com/BurntSushi/toml
-
-
-
-
-
-
-
-
- MIT
-
-
-
-
-
-
-
-
- (c) 2013 TOML authors
-
-
-
-
+
+
+
+ github.com/BurntSushi/toml
+
+
+
+
+
+
+ MIT
+
+
+
+
+
+
+ (c) 2013 TOML authors
+
+
+
-
-
-
-
- github.com/FyshOS/fancyfs
-
-
-
-
-
-
-
-
- BSD-3-Clause
-
-
-
-
-
-
-
-
- (C) 2025 FyshOS developers (see AUTHORS)
-
-
-
-
+
+
+
+ github.com/FyshOS/fancyfs
+
+
+
+
+
+
+ BSD-3-Clause
+
+
+
+
+
+
+ (C) 2025 FyshOS developers (see AUTHORS)
+
+
+
-
-
-
-
- github.com/anthonynsimon/bild
-
-
-
-
-
-
-
-
- MIT
-
-
-
-
-
-
-
-
- (c) 2021 Anthony Najjar Simon
-
-
-
-
+
+
+
+ github.com/anthonynsimon/bild
+
+
+
+
+
+
+ MIT
+
+
+
+
+
+
+ (c) 2021 Anthony Najjar Simon
+
+
+
-
-
-
-
- github.com/clipperhouse/uax29/v2
-
-
-
-
-
-
-
-
- MIT
-
-
-
-
-
-
-
-
- (c) 2020 Matt Sherman
-
-
-
-
+
+
+
+ github.com/clipperhouse/uax29/v2
+
+
+
+
+
+
+ MIT
+
+
+
+
+
+
+ (c) 2020 Matt Sherman
+
+
+
-
-
-
-
- github.com/fsnotify/fsnotify
-
-
-
-
-
-
-
-
- BSD-3-Clause
-
-
-
-
-
-
-
-
- Copyright 2012 The Go Authors
-
-
-
-
+
+
+
+ github.com/fsnotify/fsnotify
+
+
+
+
+
+
+ BSD-3-Clause
+
+
+
+
+
+
+ Copyright 2012 The Go Authors
+
+
+
-
-
-
-
- github.com/fyne-io/image
-
-
-
-
-
-
-
-
- BSD-3-Clause
-
-
-
-
-
-
-
-
- (c) 2022, Fyne.io
-
-
-
-
+
+
+
+ github.com/fyne-io/image
+
+
+
+
+
+
+ BSD-3-Clause
+
+
+
+
+
+
+ (c) 2022, Fyne.io
+
+
+
-
-
-
-
- github.com/fyne-io/oksvg
-
-
-
-
-
-
-
-
- BSD-3-Clause
-
-
-
-
-
-
-
-
- (c) 2018, Steven R Wiley
-
-
-
-
+
+
+
+ github.com/fyne-io/oksvg
+
+
+
+
+
+
+ BSD-3-Clause
+
+
+
+
+
+
+ (c) 2018, Steven R Wiley
+
+
+
-
-
-
-
- github.com/gen2brain/gav1d
-
-
-
-
-
-
-
-
- BSD-2-Clause
-
-
-
-
-
-
-
-
- (c) 2018-2025 VideoLAN and dav1d authors, (c) 2016 Alliance
- for Open Media
-
-
-
-
+
+
+
+ github.com/gen2brain/gav1d
+
+
+
+
+
+
+ BSD-2-Clause
+
+
+
+
+
+
+ (c) 2018-2025 VideoLAN and dav1d authors, (c) 2016 Alliance
+ for Open Media
+
+
+
-
-
-
-
- github.com/gen2brain/jxl
-
-
-
-
-
-
-
-
- BSD-3-Clause
-
-
-
-
-
-
-
-
- (c) the JPEG XL Project Authors
-
-
-
-
+
+
+
+ github.com/gen2brain/jxl
+
+
+
+
+
+
+ BSD-3-Clause
+
+
+
+
+
+
+ (c) the JPEG XL Project Authors
+
+
+
-
-
-
-
- github.com/go-gl/gl
-
-
-
-
-
-
-
-
- MIT
-
-
-
-
-
-
-
-
- (c) 2014 Eric Woroshow
-
-
-
-
+
+
+
+ github.com/go-gl/gl
+
+
+
+
+
+
+ MIT
+
+
+
+
+
+
+ (c) 2014 Eric Woroshow
+
+
+
-
-
-
-
- github.com/go-gl/glfw/v3.4/glfw
-
-
-
-
-
-
-
-
- BSD-3-Clause
-
-
-
-
-
-
-
-
- (c) 2012 The glfw3-go Authors. All rights reserved.
-
-
-
-
+
+
+
+ github.com/go-gl/glfw/v3.4/glfw
+
+
+
+
+
+
+ BSD-3-Clause
+
+
+
+
+
+
+ (c) 2012 The glfw3-go Authors. All rights reserved.
+
+
+
-
-
-
-
- github.com/go-text/render
-
-
-
-
-
-
-
-
- BSD-3-Clause
-
-
-
-
-
-
-
-
- 2021 The go-text authors
-
-
-
-
+
+
+
+ github.com/go-text/render
+
+
+
+
+
+
+ BSD-3-Clause
+
+
+
+
+
+
+ 2021 The go-text authors
+
+
+
-
-
-
-
- github.com/go-text/typesetting
-
-
-
-
-
-
-
-
- BSD-3-Clause
-
-
-
-
-
-
-
-
- 2021 The go-text authors
-
-
-
-
+
+
+
+ github.com/go-text/typesetting
+
+
+
+
+
+
+ BSD-3-Clause
+
+
+
+
+
+
+ 2021 The go-text authors
+
+
+
-
-
-
-
- github.com/goccy/go-yaml
-
-
-
-
-
-
-
-
- MIT
-
-
-
-
-
-
-
-
- (c) 2019 Masaaki Goshima
-
-
-
-
+
+
+
+ github.com/goccy/go-yaml
+
+
+
+
+
+
+ MIT
+
+
+
+
+
+
+ (c) 2019 Masaaki Goshima
+
+
+
-
-
-
-
- github.com/godbus/dbus/v5
-
-
-
-
-
-
-
-
- BSD-2-Clause
-
-
-
-
-
-
-
-
- (c) 2013, Georg Reinke (), Google
-
-
-
-
+
+
+
+ github.com/godbus/dbus/v5
+
+
+
+
+
+
+ BSD-2-Clause
+
+
+
+
+
+
+ (c) 2013, Georg Reinke (), Google
+
+
+
-
-
-
-
- github.com/jeandeaual/go-locale
-
-
-
-
-
-
-
-
- MIT
-
-
-
-
-
-
-
-
- (c) 2020 Alexis Jeandeau
-
-
-
-
+
+
+
+ github.com/jeandeaual/go-locale
+
+
+
+
+
+
+ MIT
+
+
+
+
+
+
+ (c) 2020 Alexis Jeandeau
+
+
+
-
-
-
-
- github.com/jsummers/gobmp
-
-
-
-
-
-
-
-
- MIT
-
-
-
-
-
-
-
-
- (c) 2012-2015 Jason Summers
-
-
-
-
+
+
+
+ github.com/jsummers/gobmp
+
+
+
+
+
+
+ MIT
+
+
+
+
+
+
+ (c) 2012-2015 Jason Summers
+
+
+
-
-
-
-
- github.com/mattn/go-runewidth
-
-
-
-
-
-
-
-
- MIT
-
-
-
-
-
-
-
-
- (c) 2016 Yasuhiro Matsumoto
-
-
-
-
+
+
+
+ github.com/mattn/go-runewidth
+
+
+
+
+
+
+ MIT
+
+
+
+
+
+
+ (c) 2016 Yasuhiro Matsumoto
+
+
+
-
-
-
-
- github.com/nfnt/resize
-
-
-
-
-
-
-
-
- ISC
-
-
-
-
-
-
-
-
- (c) 2012, Jan Schlicht
-
-
-
-
+
+
+
+ github.com/nfnt/resize
+
+
+
+
+
+
+ ISC
+
+
+
+
+
+
+ (c) 2012, Jan Schlicht
+
+
+
-
-
-
-
- github.com/nicksnyder/go-i18n/v2
-
-
-
-
-
-
-
-
- MIT
-
-
-
-
-
-
-
-
- (c) 2014 Nick Snyder https://github.com/nicksnyder
-
-
-
-
+
+
+
+ github.com/nicksnyder/go-i18n/v2
+
+
+
+
+
+
+ MIT
+
+
+
+
+
+
+ (c) 2014 Nick Snyder https://github.com/nicksnyder
+
+
+
-
-
-
-
- github.com/rymdport/portal
-
-
-
-
-
-
-
-
- Apache-2.0
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ github.com/rymdport/portal
+
+
+
+
+
+
+ Apache-2.0
+
+
+
+
+
+
+
+
+
+
-
-
-
-
- github.com/srwiley/oksvg
-
-
-
-
-
-
-
-
- BSD-3-Clause
-
-
-
-
-
-
-
-
- (c) 2018, Steven R Wiley
-
-
-
-
+
+
+
+ github.com/srwiley/oksvg
+
+
+
+
+
+
+ BSD-3-Clause
+
+
+
+
+
+
+ (c) 2018, Steven R Wiley
+
+
+
-
-
-
-
- github.com/srwiley/rasterx
-
-
-
-
-
-
-
-
- BSD-3-Clause
-
-
-
-
-
-
-
-
- (c) 2018, Steven R Wiley
-
-
-
-
+
+
+
+ github.com/srwiley/rasterx
+
+
+
+
+
+
+ BSD-3-Clause
+
+
+
+
+
+
+ (c) 2018, Steven R Wiley
+
+
+
-
-
-
-
- github.com/yuin/goldmark
-
-
-
-
-
-
-
-
- MIT
-
-
-
-
-
-
-
-
- (c) 2019 Yusuke Inuzuka
-
-
-
-
+
+
+
+ github.com/yuin/goldmark
+
+
+
+
+
+
+ MIT
+
+
+
+
+
+
+ (c) 2019 Yusuke Inuzuka
+
+
+
-
-
-
-
- golang.org/x/image
-
-
-
-
-
-
-
-
- BSD-3-Clause
-
-
-
-
-
-
-
-
- 2009 The Go Authors.
-
-
-
-
+
+
+
+ golang.org/x/image
+
+
+
+
+
+
+ BSD-3-Clause
+
+
+
+
+
+
+ 2009 The Go Authors.
+
+
+
-
-
-
-
- golang.org/x/net
-
-
-
-
-
-
-
-
- BSD-3-Clause
-
-
-
-
-
-
-
-
- 2009 The Go Authors.
-
-
-
-
+
+
+
+ golang.org/x/net
+
+
+
+
+
+
+ BSD-3-Clause
+
+
+
+
+
+
+ 2009 The Go Authors.
+
+
+
-
-
-
-
- golang.org/x/sys
-
-
-
-
-
-
-
-
- BSD-3-Clause
-
-
-
-
-
-
-
-
- 2009 The Go Authors.
-
-
-
-
+
+
+
+ golang.org/x/sys
+
+
+
+
+
+
+ BSD-3-Clause
+
+
+
+
+
+
+ 2009 The Go Authors.
+
+
+
-
-
-
-
- golang.org/x/text
-
-
-
-
-
-
-
-
- BSD-3-Clause
-
-
-
-
-
-
-
-
- Copyright 2009 The Go Authors
-
-
-
-
+
+
+
+ golang.org/x/text
+
+
+
+
+
+
+ BSD-3-Clause
+
+
+
+
+
+
+ Copyright 2009 The Go Authors
+
+
+
@@ -1091,237 +889,189 @@
-
-
-
-
- DejaVu Sans Mono for Powerline
-
-
-
-
-
-
-
-
- Bitstream-Vera
-
-
-
-
-
-
-
-
- Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved.
- DejaVu changes are in public domain
-
-
-
-
+
+
+
+ DejaVu Sans Mono for Powerline
+
+
+
+
+
+
+ Bitstream-Vera
+
+
+
+
+
+
+ Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved.
+ DejaVu changes are in public domain
+
+
+
-
-
-
-
- EmojiOne Color
-
-
-
-
-
-
-
-
- MIT
-
-
-
-
-
-
-
-
- Copyright 2016 Adobe Systems Incorporated
-
-
-
-
+
+
+
+ EmojiOne Color
+
+
+
+
+
+
+ MIT
+
+
+
+
+
+
+ Copyright 2016 Adobe Systems Incorporated
+
+
+
-
-
-
-
- Fyne icon set
-
-
-
-
-
-
-
-
- BSD-3-Clause
-
-
-
-
-
-
-
-
- (C) 2018 Fyne.io developers (see AUTHORS)
-
-
-
-
+
+
+
+ Fyne icon set
+
+
+
+
+
+
+ BSD-3-Clause
+
+
+
+
+
+
+ (C) 2018 Fyne.io developers (see AUTHORS)
+
+
+
-
-
-
-
- Fyne shaders
-
-
-
-
-
-
-
-
- BSD-3-Clause
-
-
-
-
-
-
-
-
- (C) 2018 Fyne.io developers (see AUTHORS)
-
-
-
-
+
+
+
+ Fyne shaders
+
+
+
+
+
+
+ BSD-3-Clause
+
+
+
+
+
+
+ (C) 2018 Fyne.io developers (see AUTHORS)
+
+
+
-
-
-
-
- Fyne translations
-
-
-
-
-
-
-
-
- BSD-3-Clause
-
-
-
-
-
-
-
-
- (C) 2018 Fyne.io developers (see AUTHORS)
-
-
-
-
+
+
+
+ Fyne translations
+
+
+
+
+
+
+ BSD-3-Clause
+
+
+
+
+
+
+ (C) 2018 Fyne.io developers (see AUTHORS)
+
+
+
-
-
-
-
- Inter
-
-
-
-
-
-
-
-
- OFL-1.1
-
-
-
-
-
-
-
-
- Copyright 2016 The Inter Project Authors
-
-
-
-
+
+
+
+ Inter
+
+
+
+
+
+
+ OFL-1.1
+
+
+
+
+
+
+ Copyright 2016 The Inter Project Authors
+
+
+
-
-
-
-
- Inter Symbols
-
-
-
-
-
-
-
-
- OFL-1.1
-
-
-
-
-
-
-
-
- (c) 2020 The Inter Project Authors
-
-
-
-
+
+
+
+ Inter Symbols
+
+
+
+
+
+
+ OFL-1.1
+
+
+
+
+
+
+ (c) 2020 The Inter Project Authors
+
+
+
-
-
-
-
- Noto Sans
-
-
-
-
-
-
-
-
- OFL-1.1
-
-
-
-
-
-
-
-
- Copyright 2015 Google Inc. All Rights Reserved.
-
-
-
-
+
+
+
+ Noto Sans
+
+
+
+
+
+
+ OFL-1.1
+
+
+
+
+
+
+ Copyright 2015 Google Inc. All Rights Reserved.
+
+
+
@@ -1336,36 +1086,30 @@
-
-
-
-
- Mesa 3D, llvmpipe software
- renderer 26.2.0
-
-
-
-
-
-
-
-
- MIT AND Apache-2.0 WITH
- LLVM-exception AND BSL-1.0
-
-
-
-
-
-
-
-
- Copyright (C) 1999-2007 Brian Paul,
- Copyright (C) 2008 VMware, Inc.
-
-
-
-
+
+
+
+ Mesa 3D, llvmpipe software
+ renderer 26.2.0
+
+
+
+
+
+
+ MIT AND Apache-2.0 WITH
+ LLVM-exception AND BSL-1.0
+
+
+
+
+
+
+ Copyright (C) 1999-2007 Brian Paul,
+ Copyright (C) 2008 VMware, Inc.
+
+
+
diff --git a/internal/guard/testdata/screens/catalogue.xml b/internal/guard/testdata/screens/catalogue.xml
index 5450baf..38fc683 100644
--- a/internal/guard/testdata/screens/catalogue.xml
+++ b/internal/guard/testdata/screens/catalogue.xml
@@ -4,21 +4,17 @@
-
-
-
-
- Catalogue
-
+
+
+
+ Catalogue
-
-
-
+
+
+
-
-
- Every part of the window, in every state it has.
-
+
+ Every part of the window, in every state it has.
@@ -31,12 +27,10 @@
Button
-
+
-
-
- primary at rest
-
+
+ primary at rest
@@ -49,12 +43,10 @@
-
+
-
-
- primary under the pointer
-
+
+ primary under the pointer
@@ -67,12 +59,10 @@
-
+
-
-
- primary pressed
-
+
+ primary pressed
@@ -85,12 +75,10 @@
-
+
-
-
- primary holding the keyboard
-
+
+ primary holding the keyboard
@@ -103,12 +91,10 @@
-
+
-
-
- secondary at rest
-
+
+ secondary at rest
@@ -121,12 +107,10 @@
-
+
-
-
- secondary under the pointer
-
+
+ secondary under the pointer
@@ -139,12 +123,10 @@
-
+
-
-
- secondary pressed
-
+
+ secondary pressed
@@ -157,12 +139,10 @@
-
+
-
-
- secondary holding the keyboard
-
+
+ secondary holding the keyboard
@@ -175,12 +155,10 @@
-
+
-
-
- secondary disabled
-
+
+ secondary disabled
@@ -193,12 +171,10 @@
-
+
-
-
- quiet at rest
-
+
+ quiet at rest
@@ -211,12 +187,10 @@
-
+
-
-
- quiet under the pointer
-
+
+ quiet under the pointer
@@ -229,12 +203,10 @@
-
+
-
-
- quiet pressed
-
+
+ quiet pressed
@@ -247,12 +219,10 @@
-
+
-
-
- quiet holding the keyboard
-
+
+ quiet holding the keyboard
@@ -265,12 +235,10 @@
-
+
-
-
- quiet disabled
-
+
+ quiet disabled
@@ -283,12 +251,10 @@
-
+
-
-
- long text
-
+
+ long text
@@ -301,12 +267,10 @@
-
+
-
-
- glyph at rest
-
+
+ glyph at rest
@@ -319,12 +283,10 @@
-
+
-
-
- glyph under the pointer
-
+
+ glyph under the pointer
@@ -337,12 +299,10 @@
-
+
-
-
- glyph holding the keyboard
-
+
+ glyph holding the keyboard
@@ -355,12 +315,10 @@
-
+
-
-
- glyph disabled
-
+
+ glyph disabled
@@ -383,12 +341,10 @@
Chooser
-
+
-
-
- at rest
-
+
+ at rest
@@ -408,12 +364,10 @@
-
+
-
-
- chosen
-
+
+ chosen
@@ -433,12 +387,10 @@
-
+
-
-
- holding the keyboard
-
+
+ holding the keyboard
@@ -461,12 +413,10 @@
-
+
-
-
- refused
-
+
+ refused
@@ -489,12 +439,10 @@
-
+
-
-
- disabled
-
+
+ disabled
@@ -514,12 +462,10 @@
-
+
-
-
- long value
-
+
+ long value
@@ -539,12 +485,10 @@
-
+
-
-
- every format, showing the kind of its value
-
+
+ every format, showing the kind of its value
@@ -575,12 +519,10 @@
Entry
-
+
-
-
- empty, with its hint
-
+
+ empty, with its hint
@@ -600,12 +542,10 @@
-
+
-
-
- typed
-
+
+ typed
@@ -622,12 +562,10 @@
-
+
-
-
- holding the keyboard
-
+
+ holding the keyboard
@@ -645,12 +583,10 @@
-
+
-
-
- disabled
-
+
+ disabled
@@ -667,12 +603,10 @@
-
+
-
-
- long text
-
+
+ long text
@@ -699,12 +633,10 @@
Toggle
-
+
-
-
- off
-
+
+ off
@@ -717,12 +649,10 @@
-
+
-
-
- on
-
+
+ on
@@ -736,12 +666,10 @@
-
+
-
-
- under the pointer
-
+
+ under the pointer
@@ -754,12 +682,10 @@
-
+
-
-
- holding the keyboard
-
+
+ holding the keyboard
@@ -773,12 +699,10 @@
-
+
-
-
- disabled
-
+
+ disabled
@@ -801,12 +725,10 @@
Segments
-
+
-
-
- first chosen
-
+
+ first chosen
@@ -825,12 +747,10 @@
-
+
-
-
- middle chosen
-
+
+ middle chosen
@@ -848,12 +768,10 @@
-
+
-
-
- holding the keyboard
-
+
+ holding the keyboard
@@ -872,12 +790,10 @@
-
+
-
-
- the last one under the pointer
-
+
+ the last one under the pointer
@@ -896,12 +812,10 @@
-
+
-
-
- frozen, middle chosen
-
+
+ frozen, middle chosen
@@ -919,12 +833,10 @@
-
+
-
-
- long words
-
+
+ long words
@@ -953,12 +865,10 @@
OpenList
-
+
-
-
- a few values, one chosen
-
+
+ a few values, one chosen
@@ -1011,12 +921,10 @@
-
+
-
-
- nothing chosen yet
-
+
+ nothing chosen yet
@@ -1068,12 +976,10 @@
-
+
-
-
- more values than a short window shows at once
-
+
+ more values than a short window shows at once
@@ -1151,12 +1057,10 @@
-
+
-
-
- every value with the kind of thing it is
-
+
+ every value with the kind of thing it is
@@ -1302,12 +1206,10 @@
-
+
-
-
- a long value
-
+
+ a long value
@@ -1351,12 +1253,10 @@
-
+
-
-
- every format, under the heading of its kind, with a box to filter
-
+
+ every format, under the heading of its kind, with a box to filter
@@ -1514,12 +1414,10 @@
-
+
-
-
- typed into, with the letters that matched in bold
-
+
+ typed into, with the letters that matched in bold
@@ -1688,12 +1586,10 @@
-
+
-
-
- typed into, with nothing left
-
+
+ typed into, with nothing left
@@ -1749,12 +1645,10 @@
Tabs
-
+
-
-
- the strip, first word chosen
-
+
+ the strip, first word chosen
@@ -1783,12 +1677,10 @@
-
+
-
-
- a word under the pointer
-
+
+ a word under the pointer
@@ -1817,12 +1709,10 @@
-
+
-
-
- a word holding the keyboard
-
+
+ a word holding the keyboard
@@ -1851,12 +1741,10 @@
-
+
-
-
- the strip with its screens under it
-
+
+ the strip with its screens under it
@@ -1889,24 +1777,20 @@
-
-
-
-
- the first screen
-
+
+
+
+ the first screen
-
-
+
+
-
+
-
-
- long words
-
+
+ long words
@@ -1935,12 +1819,10 @@
Fields
-
+
-
-
- a row
-
+
+ a row
@@ -1969,12 +1851,10 @@
-
+
-
-
- a row that has to be filled in
-
+
+ a row that has to be filled in
@@ -2006,12 +1886,10 @@
-
+
-
-
- a row the run refused
-
+
+ a row the run refused
@@ -2038,25 +1916,21 @@
-
-
-
-
- a size of 3 B is below the smallest png, which is 73 B
-
+
+
+
+ a size of 3 B is below the smallest png, which is 73 B
-
-
+
+
-
+
-
-
- a row frozen while a run goes
-
+
+ a row frozen while a run goes
@@ -2085,12 +1959,10 @@
-
+
-
-
- a box to tick with its name beside it
-
+
+ a box to tick with its name beside it
@@ -2113,12 +1985,10 @@
-
+
-
-
- a box to tick beside a named field, level with its box
-
+
+ a box to tick beside a named field, level with its box
@@ -2169,12 +2039,10 @@
-
+
-
-
- a named control with no setting behind it
-
+
+ a named control with no setting behind it
@@ -2198,12 +2066,10 @@
-
+
-
-
- a table: the names once over the columns, cells under them
-
+
+ a table: the names once over the columns, cells under them
@@ -2313,26 +2179,22 @@
-
+
-
-
- a row of arbitrary cells
-
+
+ a row of arbitrary cells
-
-
-
-
- Anything
-
+
+
+
+ Anything
-
-
+
+
@@ -2356,12 +2218,10 @@
-
+
-
-
- a long name
-
+
+ a long name
@@ -2401,12 +2261,10 @@
PropertyField
-
+
-
-
- a number with a range
-
+
+ a number with a range
@@ -2449,12 +2307,10 @@
-
+
-
-
- a choice from a closed set
-
+
+ a choice from a closed set
@@ -2493,12 +2349,10 @@
-
+
-
-
- a yes or no
-
+
+ a yes or no
@@ -2532,12 +2386,10 @@
-
+
-
-
- a size
-
+
+ a size
@@ -2572,12 +2424,10 @@
-
+
-
-
-
-
+
+
@@ -2589,12 +2439,10 @@
-
+
-
-
- free text
-
+
+ free text
@@ -2647,12 +2495,10 @@
ByteCount
-
+
-
-
- a size counted out
-
+
+ a size counted out
@@ -2677,12 +2523,10 @@
-
+
-
-
- 10 485 760 B
-
+
+ 10 485 760 B
@@ -2690,12 +2534,10 @@
-
+
-
-
- nothing to count yet
-
+
+ nothing to count yet
@@ -2723,12 +2565,10 @@
-
+
-
-
-
-
+
+
@@ -2736,12 +2576,10 @@
-
+
-
-
- a large size
-
+
+ a large size
@@ -2766,12 +2604,10 @@
-
+
-
-
- 2 147 483 648 B
-
+
+ 2 147 483 648 B
@@ -2789,12 +2625,10 @@
Tips
-
+
-
-
- the button beside a name
-
+
+ the button beside a name
@@ -2835,12 +2669,10 @@
-
+
-
-
- the button under the pointer
-
+
+ the button under the pointer
@@ -2883,16 +2715,14 @@
-
-
-
-
- 10mb The exact size every file will have, to the byte.
- Units count in 1024s, so 10mb is 10 485 760 B.
-
+
+
+
+ 10mb The exact size every file will have, to the byte.
+ Units count in 1024s, so 10mb is 10 485 760 B.
-
-
+
+
@@ -2909,81 +2739,67 @@
ErrorArea
-
+
-
-
- silent
-
+
+ silent
-
+
-
-
- one line
-
+
+ one line
-
-
-
-
- size 3 B is below the smallest png, which is 73 B
-
+
+
+
+ size 3 B is below the smallest png, which is 73 B
-
-
+
+
-
+
-
-
- a long message
-
+
+ a long message
-
-
-
-
- Write a label inside each generated file, including the ones that are far too small to hold it. Write a label inside each
- generated file, including the ones that are far too small to hold it
-
+
+
+
+ Write a label inside each generated file, including the ones that are far too small to hold it. Write a label inside each
+ generated file, including the ones that are far too small to hold it
-
-
+
+
-
+
-
-
- offering the fix it asks for
-
+
+ offering the fix it asks for
-
-
-
-
- AVIF cannot be smaller than 311 B. Requested: 1 B
-
+
+
+
+ AVIF cannot be smaller than 311 B. Requested: 1 B
-
-
+
+
@@ -3004,12 +2820,10 @@
Progress
-
+
-
-
- nothing done yet
-
+
+ nothing done yet
@@ -3019,12 +2833,10 @@
-
+
-
-
- half done
-
+
+ half done
@@ -3034,12 +2846,10 @@
-
+
-
-
- done
-
+
+ done
@@ -3059,12 +2869,10 @@
Folding
-
+
-
-
- open
-
+
+ open
@@ -3085,10 +2893,8 @@
Notes for the manifest
-
-
-
-
+
+
@@ -3097,27 +2903,23 @@
-
-
-
-
- inside the fold
-
+
+
+
+ inside the fold
-
-
+
+
-
+
-
-
- closed
-
+
+ closed
@@ -3138,10 +2940,8 @@
Notes for the manifest
-
-
-
-
+
+
@@ -3154,12 +2954,10 @@
-
+
-
-
- closed, saying what it holds
-
+
+ closed, saying what it holds
@@ -3180,15 +2978,15 @@
Settings for png
-
-
-
-
- width 800, height 600
+
+
+
+
+ width 800, height 600
-
-
-
+
+
+
@@ -3201,12 +2999,10 @@
-
+
-
-
- inner, open
-
+
+ inner, open
@@ -3231,10 +3027,8 @@
Advanced
-
-
-
-
+
+
@@ -3243,15 +3037,13 @@
-
-
-
-
- inside the inner fold
-
+
+
+
+ inside the inner fold
-
-
+
+
@@ -3259,12 +3051,10 @@
-
+
-
-
- inner, closed
-
+
+ inner, closed
@@ -3289,10 +3079,8 @@
Advanced
-
-
-
-
+
+
@@ -3306,12 +3094,10 @@
-
+
-
-
- inner, a damage's settings
-
+
+ inner, a damage's settings
@@ -3336,10 +3122,8 @@
Settings for zero-head
-
-
-
-
+
+
@@ -3348,15 +3132,13 @@
-
-
-
-
- inside the inner fold
-
+
+
+
+ inside the inner fold
-
-
+
+
@@ -3364,12 +3146,10 @@
-
+
-
-
- inner, notes for the manifest
-
+
+ inner, notes for the manifest
@@ -3394,10 +3174,8 @@
Notes for the manifest
-
-
-
-
+
+
@@ -3406,15 +3184,13 @@
-
-
-
-
- inside the inner fold
-
+
+
+
+ inside the inner fold
-
-
+
+
@@ -3422,12 +3198,10 @@
-
+
-
-
- a long title
-
+
+ a long title
@@ -3448,10 +3222,8 @@
Write a label inside each generated file, including the ones that are far too small to hold it
-
-
-
-
+
+
@@ -3460,27 +3232,23 @@
-
-
-
-
- inside the fold
-
+
+
+
+ inside the fold
-
-
+
+
-
+
-
-
- the head under the pointer
-
+
+ the head under the pointer
@@ -3501,10 +3269,8 @@
Notes for the manifest
-
-
-
-
+
+
@@ -3513,27 +3279,23 @@
-
-
-
-
- inside the fold
-
+
+
+
+ inside the fold
-
-
+
+
-
+
-
-
- the head holding the keyboard
-
+
+ the head holding the keyboard
@@ -3554,10 +3316,8 @@
Notes for the manifest
-
-
-
-
+
+
@@ -3566,27 +3326,23 @@
-
-
-
-
- inside the fold
-
+
+
+
+ inside the fold
-
-
+
+
-
+
-
-
- shut, the head under the pointer
-
+
+ shut, the head under the pointer
@@ -3607,15 +3363,15 @@
Settings for png
-
-
-
-
- width 800, height 600
+
+
+
+
+ width 800, height 600
-
-
-
+
+
+
@@ -3638,406 +3394,330 @@
Title
-
+
-
-
- the title of a screen
-
+
+ the title of a screen
-
-
-
-
- Single batch
-
+
+
+
+ Single batch
-
-
+
+
-
+
-
-
- the sentence under a title
-
+
+ the sentence under a title
-
+
-
-
- Files of one format and one size, with a manifest that says how the system under test should react to them.
-
+
+ Files of one format and one size, with a manifest that says how the system under test should react to them.
-
+
-
-
- a title with its sentence
-
+
+ a title with its sentence
-
-
-
-
- Single batch
-
+
+
+
+ Single batch
-
-
-
+
+
+
-
-
- Files of one format and one size, with a manifest that says how the system under test should react to them.
-
+
+ Files of one format and one size, with a manifest that says how the system under test should react to them.
-
+
-
-
- the name of a field
-
+
+ the name of a field
Output directory
-
+
-
-
- the name of a block inside a section
-
+
+ the name of a block inside a section
-
-
-
-
- Typically finds
-
+
+
+
+ Typically finds
-
-
+
+
-
+
-
-
- a paragraph
-
+
+ a paragraph
-
-
-
-
- Every file has exactly the size you ask for, to the byte, or the run refuses before writing anything.
-
+
+
+
+ Every file has exactly the size you ask for, to the byte, or the run refuses before writing anything.
-
-
+
+
-
+
-
-
- a note that has to stay visible
-
+
+ a note that has to stay visible
-
+
-
-
- The limit of 100 000 files is this tool's, not the disk's.
-
+
+ The limit of 100 000 files is this tool's, not the disk's.
-
+
-
-
- a list of short statements
-
+
+ a list of short statements
•
-
-
-
-
- Upload validators
-
+
+
+
+ Upload validators
-
-
+
+
•
-
-
-
-
- Size limits
-
+
+
+
+ Size limits
-
-
+
+
•
-
-
-
-
- Archive handling
-
+
+
+
+ Archive handling
-
-
+
+
-
+
-
-
- a list whose items do not fit on one line
-
+
+ a list whose items do not fit on one line
•
-
-
-
-
- One line
-
+
+
+
+ One line
-
-
+
+
•
-
-
-
-
- Write a label inside each generated file, including the ones that are far too small to hold it Write a label inside each
- generated file, including the ones that are far too small to hold it
-
+
+
+
+ Write a label inside each generated file, including the ones that are far too small to hold it Write a label inside each
+ generated file, including the ones that are far too small to hold it
-
-
+
+
-
+
-
-
- a caption, the smallest rank
-
+
+ a caption, the smallest rank
-
+
-
-
- 10 485 760 B
-
+
+ 10 485 760 B
-
+
-
-
- a table of three columns, the last one wrapping
-
+
+ a table of three columns, the last one wrapping
-
-
-
-
- fyne.io/fyne/v2
-
+
+
+
+ fyne.io/fyne/v2
-
-
-
-
-
-
- BSD-3-Clause
-
+
+
+
+
+
+ BSD-3-Clause
-
-
-
-
-
-
- (C) 2018 Fyne.io developers (see
- AUTHORS)
-
+
+
+
+
+
+ (C) 2018 Fyne.io developers (see
+ AUTHORS)
-
-
+
+
-
-
-
-
- Mesa 3D, llvmpipe software
- renderer 26.2.0
-
+
+
+
+ Mesa 3D, llvmpipe software
+ renderer 26.2.0
-
-
-
-
-
-
- MIT AND Apache-2.0 WITH
- LLVM-exception AND BSL-1.0
-
+
+
+
+
+
+ MIT AND Apache-2.0 WITH
+ LLVM-exception AND BSL-1.0
-
-
-
-
-
-
- Copyright (C) 1999-2007 Brian Paul,
- Copyright (C) 2008 VMware, Inc.
-
+
+
+
+
+
+ Copyright (C) 1999-2007 Brian Paul,
+ Copyright (C) 2008 VMware, Inc.
-
-
+
+
-
-
-
-
- golang.org/x/text
-
+
+
+
+ golang.org/x/text
-
-
-
-
-
-
- BSD-3-Clause
-
+
+
+
+
+
+ BSD-3-Clause
-
-
-
-
-
-
- Write a label inside each generated
- file, including the ones that are far too
- small to hold it
-
+
+
+
+
+
+ Write a label inside each generated
+ file, including the ones that are far too
+ small to hold it
-
-
+
+
-
+
-
-
- a long line at every rank
-
+
+ a long line at every rank
-
-
-
-
- Write a label inside each generated file, including the ones that are far too sma…
-
+
+
+
+ Write a label inside each generated file, including the ones that are far too sma…
-
-
+
+
Write a label inside each generated file, including the ones that are far too small to hold it
-
-
-
-
- Write a label inside each generated file, including the ones that are far too small to hold it
-
+
+
+
+ Write a label inside each generated file, including the ones that are far too small to hold it
-
-
-
-
-
-
- Write a label inside each generated file, including the ones that are far too small to hold it
-
+
+
+
+
+
+ Write a label inside each generated file, including the ones that are far too small to hold it
-
-
-
+
+
+
-
-
- Write a label inside each generated file, including the ones that are far too small to hold it
-
+
+ Write a label inside each generated file, including the ones that are far too small to hold it
@@ -4054,12 +3734,10 @@
Section
-
+
-
-
- a section of two rows
-
+
+ a section of two rows
@@ -4123,12 +3801,10 @@
-
+
-
-
- a section with a line across it
-
+
+ a section with a line across it
@@ -4194,12 +3870,10 @@
-
+
-
-
- the bar a run starts from
-
+
+ the bar a run starts from
@@ -4239,12 +3913,10 @@
-
+
-
-
- fields in columns, each as wide as its value needs
-
+
+ fields in columns, each as wide as its value needs
@@ -4379,12 +4051,10 @@
-
+
-
-
- a row with a refusal under it
-
+
+ a row with a refusal under it
@@ -4420,15 +4090,13 @@
-
-
-
-
- size 3 B is below the smallest png, which is 73 B
-
+
+
+
+ size 3 B is below the smallest png, which is 73 B
-
-
+
+
@@ -4457,16 +4125,14 @@
-
-
-
-
- Write a label inside each generated file, including the ones that are far too small to
- hold it
-
+
+
+
+ Write a label inside each generated file, including the ones that are far too small to
+ hold it
-
-
+
+
@@ -4501,12 +4167,10 @@
-
+
-
-
- a section with a long title
-
+
+ a section with a long title
@@ -4580,12 +4244,10 @@
Swatch
-
+
-
-
- a surface near the bottom of the ladder
-
+
+ a surface near the bottom of the ladder
@@ -4594,12 +4256,10 @@
-
+
-
-
- a surface near the top of it
-
+
+ a surface near the top of it
@@ -4608,12 +4268,10 @@
-
+
-
-
- a colour that carries meaning
-
+
+ a colour that carries meaning
@@ -4622,12 +4280,10 @@
-
+
-
-
- an ink, which is nearly white
-
+
+ an ink, which is nearly white
@@ -4636,12 +4292,10 @@
-
+
-
-
- something the toolkit blends, laid over a panel first
-
+
+ something the toolkit blends, laid over a panel first
@@ -4659,42 +4313,34 @@
Palette, as this window draws it
-
+
-
-
- Every colour the window paints with, measured against what it is drawn on.
-
+
+ Every colour the window paints with, measured against what it is drawn on.
-
-
-
-
- The ladder of surfaces
-
+
+
+
+ The ladder of surfaces
-
-
+
+
-
+
-
-
- background - the page the window stands on
-
+
+ background - the page the window stands on
-
+
-
-
- #1E1E20
-
+
+ #1E1E20
@@ -4703,21 +4349,17 @@
-
+
-
-
- panel - the surface a section is drawn on
-
+
+ panel - the surface a section is drawn on
-
+
-
-
- #2B2B2F - 17.7 L*, +6.3 from the page
-
+
+ #2B2B2F - 17.7 L*, +6.3 from the page
@@ -4726,21 +4368,17 @@
-
+
-
-
- inputBackground - the fill of a box to type in
-
+
+ inputBackground - the fill of a box to type in
-
+
-
-
- #39393F - 24.2 L*, +6.5 from the panel
-
+
+ #39393F - 24.2 L*, +6.5 from the panel
@@ -4749,21 +4387,17 @@
-
+
-
-
- button - the face of a button that is not the main one
-
+
+ button - the face of a button that is not the main one
-
+
-
-
- #48484E - 30.8 L*, +6.6 from a box to type in
-
+
+ #48484E - 30.8 L*, +6.6 from a box to type in
@@ -4772,21 +4406,17 @@
-
+
-
-
- separator - a line that separates and says nothing else
-
+
+ separator - a line that separates and says nothing else
-
+
-
-
- #48484E - 30.8 L*, +13.1 from the panel
-
+
+ #48484E - 30.8 L*, +13.1 from the panel
@@ -4795,21 +4425,17 @@
-
+
-
-
- menuBackground - what an open list floats on
-
+
+ menuBackground - what an open list floats on
-
+
-
-
- #57575F - 37.2 L*, +13.1 from a box to type in
-
+
+ #57575F - 37.2 L*, +13.1 from a box to type in
@@ -4818,53 +4444,43 @@
-
+
-
-
- inputBorder - the edge that says where the typing goes
-
+
+ inputBorder - the edge that says where the typing goes
-
+
-
-
- #65656D - 43.0 L*, +18.9 from its own fill
-
+
+ #65656D - 43.0 L*, +18.9 from its own fill
-
-
-
-
- The inks
-
+
+
+
+ The inks
-
-
+
+
-
+
-
-
- foreground - a value, and everything read at rest
-
+
+ foreground - a value, and everything read at rest
-
+
-
-
- #E6E6E8 - 5.74:1 on an open list
-
+
+ #E6E6E8 - 5.74:1 on an open list
@@ -4873,21 +4489,17 @@
-
+
-
-
- label - the name of a field, a step quieter than its value
-
+
+ label - the name of a field, a step quieter than its value
-
+
-
-
- #D3D3D7 - 9.45:1 on a panel
-
+
+ #D3D3D7 - 9.45:1 on a panel
@@ -4896,21 +4508,17 @@
-
+
-
-
- disabled - a value in a box switched off for the length of a run
-
+
+ disabled - a value in a box switched off for the length of a run
-
+
-
-
- #C7C7CC - 6.81:1 on a box to type in
-
+
+ #C7C7CC - 6.81:1 on a box to type in
@@ -4919,53 +4527,43 @@
-
+
-
-
- placeholder - a hint in a box nobody has typed in
-
+
+ placeholder - a hint in a box nobody has typed in
-
+
-
-
- #A2A2A9 - 4.52:1 on a box to type in
-
+
+ #A2A2A9 - 4.52:1 on a box to type in
-
-
-
-
- What carries meaning
-
+
+
+
+ What carries meaning
-
-
+
+
-
+
-
-
- primary - the action a screen is for, and the line round a focused control
-
+
+ primary - the action a screen is for, and the line round a focused control
-
+
-
-
- #5AB3F2 - 7.26:1 on the page
-
+
+ #5AB3F2 - 7.26:1 on the page
@@ -4974,21 +4572,17 @@
-
+
-
-
- hyperlink - a link, the same blue as the action
-
+
+ hyperlink - a link, the same blue as the action
-
+
-
-
- #5AB3F2 - 7.26:1 on the page
-
+
+ #5AB3F2 - 7.26:1 on the page
@@ -4997,21 +4591,17 @@
-
+
-
-
- error - a refusal, and a file that failed
-
+
+ error - a refusal, and a file that failed
-
+
-
-
- #F48F8D - 7.26:1 on the page
-
+
+ #F48F8D - 7.26:1 on the page
@@ -5020,21 +4610,17 @@
-
+
-
-
- success - a run that wrote everything it promised
-
+
+ success - a run that wrote everything it promised
-
+
-
-
- #42C260 - 7.23:1 on the page
-
+
+ #42C260 - 7.23:1 on the page
@@ -5043,21 +4629,17 @@
-
+
-
-
- warning - a run that wrote files and skipped some
-
+
+ warning - a run that wrote files and skipped some
-
+
-
-
- #DAA131 - 7.23:1 on the page
-
+
+ #DAA131 - 7.23:1 on the page
@@ -5066,53 +4648,43 @@
-
+
-
-
- selection - the row or the segment somebody chose
-
+
+ selection - the row or the segment somebody chose
-
+
-
-
- #224B69 - 30.4 L*, +19.0 from the page
-
+
+ #224B69 - 30.4 L*, +19.0 from the page
-
-
-
-
- What the pointer, a press and the keyboard do
-
+
+
+
+ What the pointer, a press and the keyboard do
-
-
+
+
-
+
-
-
- hover - what the pointer does to a dark face
-
+
+ hover - what the pointer does to a dark face
-
+
-
-
- #FFFFFF at 0x22 - over the page it comes to #3C3C3D, 25.4 L*, a move of +14.0
-
+
+ #FFFFFF at 0x22 - over the page it comes to #3C3C3D, 25.4 L*, a move of +14.0
@@ -5121,21 +4693,17 @@
-
+
-
-
- pressed - what a press does to a dark face
-
+
+ pressed - what a press does to a dark face
-
+
-
-
- #FFFFFF at 0x40 - over a button's face it comes to #76767A, 49.7 L*, a move of +19.0
-
+
+ #FFFFFF at 0x40 - over a button's face it comes to #76767A, 49.7 L*, a move of +19.0
@@ -5144,21 +4712,17 @@
-
+
-
-
- lift - what the pointer does to the filled main button
-
+
+ lift - what the pointer does to the filled main button
-
+
-
-
- #FFFFFF at 0x66 - over the main button it comes to #9CD2F8, 81.6 L*, a move of +11.6
-
+
+ #FFFFFF at 0x66 - over the main button it comes to #9CD2F8, 81.6 L*, a move of +11.6
@@ -5167,21 +4731,17 @@
-
+
-
-
- shade - what a press does to the filled main button
-
+
+ shade - what a press does to the filled main button
-
+
-
-
- #000000 at 0x33 - over the main button it comes to #488FC2, 57.0 L*, a move of -13.0
-
+
+ #000000 at 0x33 - over the main button it comes to #488FC2, 57.0 L*, a move of -13.0
@@ -5190,21 +4750,17 @@
-
+
-
-
- focus - the wash the toolkit lays over a control the keyboard is in
-
+
+ focus - the wash the toolkit lays over a control the keyboard is in
-
+
-
-
- #00A5F0 at 0x66 - over a box to type in it comes to #226486, 39.9 L*, a move of +15.8
-
+
+ #00A5F0 at 0x66 - over a box to type in it comes to #226486, 39.9 L*, a move of +15.8
@@ -5213,21 +4769,17 @@
-
+
-
-
- tipshade - the shade an explanation casts on the form under it
-
+
+ tipshade - the shade an explanation casts on the form under it
-
+
-
-
- #000000 at 0x66 - over a panel it comes to #19191C, 9.3 L*, a move of -8.4
-
+
+ #000000 at 0x66 - over a panel it comes to #19191C, 9.3 L*, a move of -8.4
@@ -5236,53 +4788,43 @@
-
+
-
-
- shadow - what a popup casts - nothing here, on purpose
-
+
+ shadow - what a popup casts - nothing here, on purpose
-
+
-
-
- nothing - drawn transparent on purpose
-
+
+ nothing - drawn transparent on purpose
-
-
-
-
- What is written on a filled face
-
+
+
+
+ What is written on a filled face
-
-
+
+
-
+
-
-
- foregroundOnPrimary - the word on the main button
-
+
+ foregroundOnPrimary - the word on the main button
-
+
-
-
- #1A1A1A - 7.60:1 on the main button
-
+
+ #1A1A1A - 7.60:1 on the main button
@@ -5291,21 +4833,17 @@
-
+
-
-
- foregroundOnError - what is written on a filled red
-
+
+ foregroundOnError - what is written on a filled red
-
+
-
-
- #1A1A1A - 7.59:1 on a filled red
-
+
+ #1A1A1A - 7.59:1 on a filled red
@@ -5314,21 +4852,17 @@
-
+
-
-
- foregroundOnSuccess - what is written on a filled green
-
+
+ foregroundOnSuccess - what is written on a filled green
-
+
-
-
- #1A1A1A - 7.56:1 on a filled green
-
+
+ #1A1A1A - 7.56:1 on a filled green
@@ -5337,21 +4871,17 @@
-
+
-
-
- foregroundOnWarning - what is written on a filled amber
-
+
+ foregroundOnWarning - what is written on a filled amber
-
+
-
-
- #1A1A1A - 7.56:1 on a filled amber
-
+
+ #1A1A1A - 7.56:1 on a filled amber
@@ -5367,42 +4897,34 @@
Palette, light - computed and not installed
-
+
-
-
- Worked out and guarded to the same thresholds. The window does not use it: this program has one look.
-
+
+ Worked out and guarded to the same thresholds. The window does not use it: this program has one look.
-
-
-
-
- The ladder of surfaces
-
+
+
+
+ The ladder of surfaces
-
-
+
+
-
+
-
-
- background - the page the window stands on
-
+
+ background - the page the window stands on
-
+
-
-
- #FFFFFF
-
+
+ #FFFFFF
@@ -5411,21 +4933,17 @@
-
+
-
-
- panel - the surface a section is drawn on
-
+
+ panel - the surface a section is drawn on
-
+
-
-
- #EEEEEF - 94.1 L*, -5.9 from the page
-
+
+ #EEEEEF - 94.1 L*, -5.9 from the page
@@ -5434,21 +4952,17 @@
-
+
-
-
- inputBackground - the fill of a box to type in
-
+
+ inputBackground - the fill of a box to type in
-
+
-
-
- #DCDCE0 - 87.9 L*, -6.3 from the panel
-
+
+ #DCDCE0 - 87.9 L*, -6.3 from the panel
@@ -5457,21 +4971,17 @@
-
+
-
-
- button - the face of a button that is not the main one
-
+
+ button - the face of a button that is not the main one
-
+
-
-
- #CCCBD1 - 81.9 L*, -5.9 from a box to type in
-
+
+ #CCCBD1 - 81.9 L*, -5.9 from a box to type in
@@ -5480,21 +4990,17 @@
-
+
-
-
- separator - a line that separates and says nothing else
-
+
+ separator - a line that separates and says nothing else
-
+
-
-
- #CCCBD1 - 81.9 L*, -12.2 from the panel
-
+
+ #CCCBD1 - 81.9 L*, -12.2 from the panel
@@ -5503,21 +5009,17 @@
-
+
-
-
- menuBackground - what an open list floats on
-
+
+ menuBackground - what an open list floats on
-
+
-
-
- #FFFFFF - 100.0 L*, +12.1 from a box to type in
-
+
+ #FFFFFF - 100.0 L*, +12.1 from a box to type in
@@ -5526,53 +5028,43 @@
-
+
-
-
- inputBorder - the edge that says where the typing goes
-
+
+ inputBorder - the edge that says where the typing goes
-
+
-
-
- #ABAAB2 - 69.9 L*, -18.0 from its own fill
-
+
+ #ABAAB2 - 69.9 L*, -18.0 from its own fill
-
-
-
-
- The inks
-
+
+
+
+ The inks
-
-
+
+
-
+
-
-
- foreground - a value, and everything read at rest
-
+
+ foreground - a value, and everything read at rest
-
+
-
-
- #1A1A1C - 17.38:1 on an open list
-
+
+ #1A1A1C - 17.38:1 on an open list
@@ -5581,21 +5073,17 @@
-
+
-
-
- label - the name of a field, a step quieter than its value
-
+
+ label - the name of a field, a step quieter than its value
-
+
-
-
- #434349 - 8.47:1 on a panel
-
+
+ #434349 - 8.47:1 on a panel
@@ -5604,21 +5092,17 @@
-
+
-
-
- disabled - a value in a box switched off for the length of a run
-
+
+ disabled - a value in a box switched off for the length of a run
-
+
-
-
- #3D3D42 - 7.90:1 on a box to type in
-
+
+ #3D3D42 - 7.90:1 on a box to type in
@@ -5627,53 +5111,43 @@
-
+
-
-
- placeholder - a hint in a box nobody has typed in
-
+
+ placeholder - a hint in a box nobody has typed in
-
+
-
-
- #585860 - 5.15:1 on a box to type in
-
+
+ #585860 - 5.15:1 on a box to type in
-
-
-
-
- What carries meaning
-
+
+
+
+ What carries meaning
-
-
+
+
-
+
-
-
- primary - the action a screen is for, and the line round a focused control
-
+
+ primary - the action a screen is for, and the line round a focused control
-
+
-
-
- #286893 - 6.01:1 on the page
-
+
+ #286893 - 6.01:1 on the page
@@ -5682,21 +5156,17 @@
-
+
-
-
- hyperlink - a link, the same blue as the action
-
+
+ hyperlink - a link, the same blue as the action
-
+
-
-
- #286893 - 6.01:1 on the page
-
+
+ #286893 - 6.01:1 on the page
@@ -5705,21 +5175,17 @@
-
+
-
-
- error - a refusal, and a file that failed
-
+
+ error - a refusal, and a file that failed
-
+
-
-
- #BB293B - 6.01:1 on the page
-
+
+ #BB293B - 6.01:1 on the page
@@ -5728,21 +5194,17 @@
-
+
-
-
- success - a run that wrote everything it promised
-
+
+ success - a run that wrote everything it promised
-
+
-
-
- #237135 - 6.03:1 on the page
-
+
+ #237135 - 6.03:1 on the page
@@ -5751,21 +5213,17 @@
-
+
-
-
- warning - a run that wrote files and skipped some
-
+
+ warning - a run that wrote files and skipped some
-
+
-
-
- #805D18 - 6.01:1 on the page
-
+
+ #805D18 - 6.01:1 on the page
@@ -5774,53 +5232,43 @@
-
+
-
-
- selection - the row or the segment somebody chose
-
+
+ selection - the row or the segment somebody chose
-
+
-
-
- #C1E0FF - 87.9 L*, -12.1 from the page
-
+
+ #C1E0FF - 87.9 L*, -12.1 from the page
-
-
-
-
- What the pointer, a press and the keyboard do
-
+
+
+
+ What the pointer, a press and the keyboard do
-
-
+
+
-
+
-
-
- hover - what the pointer does to a dark face
-
+
+ hover - what the pointer does to a dark face
-
+
-
-
- #000000 at 0x20 - over the page it comes to #DFDFDF, 88.8 L*, a move of -11.2
-
+
+ #000000 at 0x20 - over the page it comes to #DFDFDF, 88.8 L*, a move of -11.2
@@ -5829,21 +5277,17 @@
-
+
-
-
- pressed - what a press does to a dark face
-
+
+ pressed - what a press does to a dark face
-
+
-
-
- #000000 at 0x33 - over a button's face it comes to #A3A3A7, 67.0 L*, a move of -15.0
-
+
+ #000000 at 0x33 - over a button's face it comes to #A3A3A7, 67.0 L*, a move of -15.0
@@ -5852,21 +5296,17 @@
-
+
-
-
- lift - what the pointer does to the filled main button
-
+
+ lift - what the pointer does to the filled main button
-
+
-
-
- #FFFFFF at 0x66 - over the main button it comes to #7EA5BE, 65.6 L*, a move of +23.7
-
+
+ #FFFFFF at 0x66 - over the main button it comes to #7EA5BE, 65.6 L*, a move of +23.7
@@ -5875,21 +5315,17 @@
-
+
-
-
- shade - what a press does to the filled main button
-
+
+ shade - what a press does to the filled main button
-
+
-
-
- #000000 at 0x33 - over the main button it comes to #205376, 33.6 L*, a move of -8.3
-
+
+ #000000 at 0x33 - over the main button it comes to #205376, 33.6 L*, a move of -8.3
@@ -5898,21 +5334,17 @@
-
+
-
-
- focus - the wash the toolkit lays over a control the keyboard is in
-
+
+ focus - the wash the toolkit lays over a control the keyboard is in
-
+
-
-
- #007FBA at 0x66 - over a box to type in it comes to #84B7D1, 71.7 L*, a move of -16.1
-
+
+ #007FBA at 0x66 - over a box to type in it comes to #84B7D1, 71.7 L*, a move of -16.1
@@ -5921,21 +5353,17 @@
-
+
-
-
- tipshade - the shade an explanation casts on the form under it
-
+
+ tipshade - the shade an explanation casts on the form under it
-
+
-
-
- #000000 at 0x40 - over a panel it comes to #B2B2B3, 72.7 L*, a move of -21.4
-
+
+ #000000 at 0x40 - over a panel it comes to #B2B2B3, 72.7 L*, a move of -21.4
@@ -5944,53 +5372,43 @@
-
+
-
-
- shadow - what a popup casts - nothing here, on purpose
-
+
+ shadow - what a popup casts - nothing here, on purpose
-
+
-
-
- #000000 at 0x40
-
+
+ #000000 at 0x40
-
-
-
-
- What is written on a filled face
-
+
+
+
+ What is written on a filled face
-
-
+
+
-
+
-
-
- foregroundOnPrimary - the word on the main button
-
+
+ foregroundOnPrimary - the word on the main button
-
+
-
-
- #FFFFFF - 6.01:1 on the main button
-
+
+ #FFFFFF - 6.01:1 on the main button
@@ -5999,21 +5417,17 @@
-
+
-
-
- foregroundOnError - what is written on a filled red
-
+
+ foregroundOnError - what is written on a filled red
-
+
-
-
- #FFFFFF - 6.01:1 on a filled red
-
+
+ #FFFFFF - 6.01:1 on a filled red
@@ -6022,21 +5436,17 @@
-
+
-
-
- foregroundOnSuccess - what is written on a filled green
-
+
+ foregroundOnSuccess - what is written on a filled green
-
+
-
-
- #FFFFFF - 6.03:1 on a filled green
-
+
+ #FFFFFF - 6.03:1 on a filled green
@@ -6045,21 +5455,17 @@
-
+
-
-
- foregroundOnWarning - what is written on a filled amber
-
+
+ foregroundOnWarning - what is written on a filled amber
-
+
-
-
- #FFFFFF - 6.01:1 on a filled amber
-
+
+ #FFFFFF - 6.01:1 on a filled amber
@@ -6078,136 +5484,114 @@
•
-
-
-
-
- Choice - a value: one row of an open list, read back by a guard
-
+
+
+
+ Choice - a value: one row of an open list, read back by a guard
-
-
+
+
•
-
-
-
-
- Detail - data: the longer explanation of a field and the sheet it opens on
-
+
+
+
+ Detail - data: the longer explanation of a field and the sheet it opens on
-
-
+
+
•
-
-
-
-
- Field - the model of one row of a form, drawn by Fields
-
+
+
+
+ Field - the model of one row of a form, drawn by Fields
-
-
+
+
•
-
-
-
-
- Built - a value: what building a field comes to, handed to the registry in one piece
-
+
+
+
+ Built - a value: what building a field comes to, handed to the registry in one piece
-
-
+
+
•
-
-
-
-
- Tab - data: one screen and the word that leads to it, drawn by Tabs
-
+
+
+
+ Tab - data: one screen and the word that leads to it, drawn by Tabs
-
-
+
+
•
-
-
-
-
- Look - an enum: which face a Button wears, every value drawn under Button
-
+
+
+
+ Look - an enum: which face a Button wears, every value drawn under Button
-
-
+
+
•
-
-
-
-
- PointerFocus - a piece inside a control, knowing what put the keyboard there - no picture of its own
-
+
+
+
+ PointerFocus - a piece inside a control, knowing what put the keyboard there - no picture of its own
-
-
+
+
•
-
-
-
-
- Returnable - an interface: a control the window can tell it is coming back to the front, nothing of its own to draw
-
+
+
+
+ Returnable - an interface: a control the window can tell it is coming back to the front, nothing of its own to draw
-
-
+
+
•
-
-
-
-
- Shortcuts - a keyboard map: nothing to draw, and saying so is the point of this row
-
+
+
+
+ Shortcuts - a keyboard map: nothing to draw, and saying so is the point of this row
-
-
+
+
•
-
-
-
-
- GroupKind - an enum: what a group of settings is about, every value drawn under Folding as the colour of its rail
-
+
+
+
+ GroupKind - an enum: what a group of settings is about, every value drawn under Folding as the colour of its rail
-
-
+
+
•
-
-
-
-
- NameTap - an invisible target over the name beside a box to tick, so pressing the name ticks the box - nothing of its
- own to draw
-
+
+
+
+ NameTap - an invisible target over the name beside a box to tick, so pressing the name ticks the box - nothing of its
+ own to draw
-
-
+
+
@@ -6223,207 +5607,173 @@
•
-
-
-
-
- Column - stacks children at one gap of the scale
-
+
+
+
+ Column - stacks children at one gap of the scale
-
-
+
+
•
-
-
-
-
- Row - puts fields side by side
-
+
+
+
+ Row - puts fields side by side
-
-
+
+
•
-
-
-
-
- FieldColumn - the column a screen refills at run time, stacked like a section
-
+
+
+
+ FieldColumn - the column a screen refills at run time, stacked like a section
-
-
+
+
•
-
-
-
-
- Indented - the same left edge as the fields inside a panel
-
+
+
+
+ Indented - the same left edge as the fields inside a panel
-
-
+
+
•
-
-
-
-
- Sized - one width, given
-
+
+
+
+ Sized - one width, given
-
-
+
+
•
-
-
-
-
- Numeric - the width a number needs
-
+
+
+
+ Numeric - the width a number needs
-
-
+
+
•
-
-
-
-
- Text - the width a short piece of text needs - a name, a template, a file name
-
+
+
+
+ Text - the width a short piece of text needs - a name, a template, a file name
-
-
+
+
•
-
-
-
-
- Padded - one distance of the scale round its content
-
+
+
+
+ Padded - one distance of the scale round its content
-
-
+
+
•
-
-
-
-
- Stacked - panels one under another
-
+
+
+
+ Stacked - panels one under another
-
-
+
+
•
-
-
-
-
- Screen - the readable width round a head and its sections
-
+
+
+
+ Screen - the readable width round a head and its sections
-
-
+
+
•
-
-
-
-
- BesideFields - the room to the right of the column of names
-
+
+
+
+ BesideFields - the room to the right of the column of names
-
-
+
+
•
-
-
-
-
- WithRoomForARun - the room under a form for the bar to speak into
-
+
+
+
+ WithRoomForARun - the room under a form for the bar to speak into
-
-
+
+
•
-
-
-
-
- Flush - a label kept by a screen, on the edge every other word stands on
-
+
+
+
+ Flush - a label kept by a screen, on the edge every other word stands on
-
-
+
+
•
-
-
-
-
- Clear - a shape that takes room and draws nothing
-
+
+
+
+ Clear - a shape that takes room and draws nothing
-
-
+
+
•
-
-
-
-
- Grid - lays a section's fields in columns, each taking the columns its value needs - drawn under Section
-
+
+
+
+ Grid - lays a section's fields in columns, each taking the columns its value needs - drawn under Section
-
-
+
+
•
-
-
-
-
- Wide - marks something that takes a whole row of a Grid
-
+
+
+
+ Wide - marks something that takes a whole row of a Grid
-
-
+
+
•
-
-
-
-
- ButtonRow - buttons side by side, one gap of the scale apart and centred - drawn under Section
-
+
+
+
+ ButtonRow - buttons side by side, one gap of the scale apart and centred - drawn under Section
-
-
+
+
diff --git a/internal/guard/testdata/screens/generate-chosen-by-key.xml b/internal/guard/testdata/screens/generate-chosen-by-key.xml
index 53378a3..ea60d4f 100644
--- a/internal/guard/testdata/screens/generate-chosen-by-key.xml
+++ b/internal/guard/testdata/screens/generate-chosen-by-key.xml
@@ -36,21 +36,17 @@
-
-
-
-
- Single batch
-
+
+
+
+ Single batch
-
-
-
+
+
+
-
-
- Files of one format and one size, with a manifest that says how the system under test should react to them.
-
+
+ Files of one format and one size, with a manifest that says how the system under test should react to them.
@@ -73,10 +69,8 @@
File configuration
-
-
-
-
+
+
@@ -142,12 +136,10 @@
-
+
-
-
- 10 485 760 B
-
+
+ 10 485 760 B
@@ -290,10 +282,8 @@
Settings for png
-
-
-
-
+
+
@@ -329,10 +319,8 @@
Output
-
-
-
-
+
+
@@ -462,15 +450,13 @@
-
-
-
-
- 1 file · 10.0 MB (10 485 760 B) · png · will go to /tfg/out
-
+
+
+
+ 1 file · 10.0 MB (10 485 760 B) · png · will go to /tfg/out
-
-
+
+
diff --git a/internal/guard/testdata/screens/generate-chosen.xml b/internal/guard/testdata/screens/generate-chosen.xml
index 59cab24..778cc5f 100644
--- a/internal/guard/testdata/screens/generate-chosen.xml
+++ b/internal/guard/testdata/screens/generate-chosen.xml
@@ -36,21 +36,17 @@
-
-
-
-
- Single batch
-
+
+
+
+ Single batch
-
-
-
+
+
+
-
-
- Files of one format and one size, with a manifest that says how the system under test should react to them.
-
+
+ Files of one format and one size, with a manifest that says how the system under test should react to them.
@@ -73,10 +69,8 @@
File configuration
-
-
-
-
+
+
@@ -142,12 +136,10 @@
-
+
-
-
- 10 485 760 B
-
+
+ 10 485 760 B
@@ -290,10 +282,8 @@
Settings for png
-
-
-
-
+
+
@@ -329,10 +319,8 @@
Output
-
-
-
-
+
+
@@ -462,15 +450,13 @@
-
-
-
-
- 1 file · 10.0 MB (10 485 760 B) · png · will go to /tfg/out
-
+
+
+
+ 1 file · 10.0 MB (10 485 760 B) · png · will go to /tfg/out
-
-
+
+
diff --git a/internal/guard/testdata/screens/generate-empty.xml b/internal/guard/testdata/screens/generate-empty.xml
index db2047c..66eafad 100644
--- a/internal/guard/testdata/screens/generate-empty.xml
+++ b/internal/guard/testdata/screens/generate-empty.xml
@@ -36,21 +36,17 @@
-
-
-
-
- Single batch
-
+
+
+
+ Single batch
-
-
-
+
+
+
-
-
- Files of one format and one size, with a manifest that says how the system under test should react to them.
-
+
+ Files of one format and one size, with a manifest that says how the system under test should react to them.
@@ -73,10 +69,8 @@
File configuration
-
-
-
-
+
+
@@ -142,12 +136,10 @@
-
+
-
-
- 10 485 760 B
-
+
+ 10 485 760 B
@@ -180,15 +172,13 @@
-
-
-
-
- target "files" asks for 0 files. Ask for at least one
-
+
+
+
+ target "files" asks for 0 files. Ask for at least one
-
-
+
+
@@ -302,10 +292,8 @@
Settings for avif
-
-
-
-
+
+
@@ -341,10 +329,8 @@
Output
-
-
-
-
+
+
@@ -474,15 +460,13 @@
-
-
-
-
- 0 files · 0 B · avif · will go to /tfg/out
-
+
+
+
+ 0 files · 0 B · avif · will go to /tfg/out
-
-
+
+
diff --git a/internal/guard/testdata/screens/generate-focused.xml b/internal/guard/testdata/screens/generate-focused.xml
index 04c979f..03f03a6 100644
--- a/internal/guard/testdata/screens/generate-focused.xml
+++ b/internal/guard/testdata/screens/generate-focused.xml
@@ -36,21 +36,17 @@
-
-
-
-
- Single batch
-
+
+
+
+ Single batch
-
-
-
+
+
+
-
-
- Files of one format and one size, with a manifest that says how the system under test should react to them.
-
+
+ Files of one format and one size, with a manifest that says how the system under test should react to them.
@@ -73,10 +69,8 @@
File configuration
-
-
-
-
+
+
@@ -143,12 +137,10 @@
-
+
-
-
- 10 485 760 B
-
+
+ 10 485 760 B
@@ -291,10 +283,8 @@
Settings for avif
-
-
-
-
+
+
@@ -330,10 +320,8 @@
Output
-
-
-
-
+
+
@@ -463,15 +451,13 @@
-
-
-
-
- 1 file · 10.0 MB (10 485 760 B) · avif · will go to /tfg/out
-
+
+
+
+ 1 file · 10.0 MB (10 485 760 B) · avif · will go to /tfg/out
-
-
+
+
diff --git a/internal/guard/testdata/screens/generate-hovered.xml b/internal/guard/testdata/screens/generate-hovered.xml
index 90c189a..cbcc47d 100644
--- a/internal/guard/testdata/screens/generate-hovered.xml
+++ b/internal/guard/testdata/screens/generate-hovered.xml
@@ -36,21 +36,17 @@
-
-
-
-
- Single batch
-
+
+
+
+ Single batch
-
-
-
+
+
+
-
-
- Files of one format and one size, with a manifest that says how the system under test should react to them.
-
+
+ Files of one format and one size, with a manifest that says how the system under test should react to them.
@@ -73,10 +69,8 @@
File configuration
-
-
-
-
+
+
@@ -142,12 +136,10 @@
-
+
-
-
- 10 485 760 B
-
+
+ 10 485 760 B
@@ -290,10 +282,8 @@
Settings for avif
-
-
-
-
+
+
@@ -329,10 +319,8 @@
Output
-
-
-
-
+
+
@@ -462,15 +450,13 @@
-
-
-
-
- 1 file · 10.0 MB (10 485 760 B) · avif · will go to /tfg/out
-
+
+
+
+ 1 file · 10.0 MB (10 485 760 B) · avif · will go to /tfg/out
-
-
+
+
@@ -497,17 +483,15 @@
-
-
-
-
- Exact size of every file. Units count in 1024s, so
- 10mb is 10485760 bytes. A plain number is a count
- of bytes.
-
+
+
+
+ Exact size of every file. Units count in 1024s, so
+ 10mb is 10485760 bytes. A plain number is a count
+ of bytes.
-
-
+
+
diff --git a/internal/guard/testdata/screens/generate-menu-hovered.xml b/internal/guard/testdata/screens/generate-menu-hovered.xml
index 6cc8440..d4d7039 100644
--- a/internal/guard/testdata/screens/generate-menu-hovered.xml
+++ b/internal/guard/testdata/screens/generate-menu-hovered.xml
@@ -36,21 +36,17 @@
-
-
-
-
- Single batch
-
+
+
+
+ Single batch
-
-
-
+
+
+
-
-
- Files of one format and one size, with a manifest that says how the system under test should react to them.
-
+
+ Files of one format and one size, with a manifest that says how the system under test should react to them.
@@ -73,10 +69,8 @@
File configuration
-
-
-
-
+
+
@@ -142,12 +136,10 @@
-
+
-
-
- 10 485 760 B
-
+
+ 10 485 760 B
@@ -290,10 +282,8 @@
Settings for avif
-
-
-
-
+
+
@@ -329,10 +319,8 @@
Output
-
-
-
-
+
+
@@ -462,15 +450,13 @@
-
-
-
-
- 1 file · 10.0 MB (10 485 760 B) · avif · will go to /tfg/out
-
+
+
+
+ 1 file · 10.0 MB (10 485 760 B) · avif · will go to /tfg/out
-
-
+
+
diff --git a/internal/guard/testdata/screens/generate-menu-keyed.xml b/internal/guard/testdata/screens/generate-menu-keyed.xml
index 200cfe0..ce19722 100644
--- a/internal/guard/testdata/screens/generate-menu-keyed.xml
+++ b/internal/guard/testdata/screens/generate-menu-keyed.xml
@@ -36,21 +36,17 @@
-
-
-
-
- Single batch
-
+
+
+
+ Single batch
-
-
-
+
+
+
-
-
- Files of one format and one size, with a manifest that says how the system under test should react to them.
-
+
+ Files of one format and one size, with a manifest that says how the system under test should react to them.
@@ -73,10 +69,8 @@
File configuration
-
-
-
-
+
+
@@ -142,12 +136,10 @@
-
+
-
-
- 10 485 760 B
-
+
+ 10 485 760 B
@@ -290,10 +282,8 @@
Settings for avif
-
-
-
-
+
+
@@ -329,10 +319,8 @@
Output
-
-
-
-
+
+
@@ -462,15 +450,13 @@
-
-
-
-
- 1 file · 10.0 MB (10 485 760 B) · avif · will go to /tfg/out
-
+
+
+
+ 1 file · 10.0 MB (10 485 760 B) · avif · will go to /tfg/out
-
-
+
+
diff --git a/internal/guard/testdata/screens/generate-menu.xml b/internal/guard/testdata/screens/generate-menu.xml
index 40fa0b6..4ba61bd 100644
--- a/internal/guard/testdata/screens/generate-menu.xml
+++ b/internal/guard/testdata/screens/generate-menu.xml
@@ -36,21 +36,17 @@
-
-
-
-
- Single batch
-
+
+
+
+ Single batch
-
-
-
+
+
+
-
-
- Files of one format and one size, with a manifest that says how the system under test should react to them.
-
+
+ Files of one format and one size, with a manifest that says how the system under test should react to them.
@@ -73,10 +69,8 @@
File configuration
-
-
-
-
+
+
@@ -142,12 +136,10 @@
-
+
-
-
- 10 485 760 B
-
+
+ 10 485 760 B
@@ -290,10 +282,8 @@
Settings for avif
-
-
-
-
+
+
@@ -329,10 +319,8 @@
Output
-
-
-
-
+
+
@@ -462,15 +450,13 @@
-
-
-
-
- 1 file · 10.0 MB (10 485 760 B) · avif · will go to /tfg/out
-
+
+
+
+ 1 file · 10.0 MB (10 485 760 B) · avif · will go to /tfg/out
-
-
+
+
diff --git a/internal/guard/testdata/screens/generate-refused-both.xml b/internal/guard/testdata/screens/generate-refused-both.xml
index a327525..a7483f7 100644
--- a/internal/guard/testdata/screens/generate-refused-both.xml
+++ b/internal/guard/testdata/screens/generate-refused-both.xml
@@ -36,21 +36,17 @@
-
-
-
-
- Single batch
-
+
+
+
+ Single batch
-
-
-
+
+
+
-
-
- Files of one format and one size, with a manifest that says how the system under test should react to them.
-
+
+ Files of one format and one size, with a manifest that says how the system under test should react to them.
@@ -73,10 +69,8 @@
File configuration
-
-
-
-
+
+
@@ -143,26 +137,22 @@
-
+
-
-
-
-
+
+
-
-
-
-
- Size "abc" has no number: write something like 10mb or 1048576
-
+
+
+
+ Size "abc" has no number: write something like 10mb or 1048576
-
-
+
+
@@ -191,16 +181,14 @@
-
-
-
-
- How many files is "many", which is not a whole number.
- Write the digits out, such as 1 or 500
-
+
+
+
+ How many files is "many", which is not a whole number.
+ Write the digits out, such as 1 or 500
-
-
+
+
@@ -314,10 +302,8 @@
Settings for avif
-
-
-
-
+
+
@@ -353,10 +339,8 @@
Output
-
-
-
-
+
+
@@ -486,15 +470,13 @@
-
-
-
-
- Files will go to /tfg/out
-
+
+
+
+ Files will go to /tfg/out
-
-
+
+
diff --git a/internal/guard/testdata/screens/generate-refused-setting.xml b/internal/guard/testdata/screens/generate-refused-setting.xml
index 696f034..ad0c6f2 100644
--- a/internal/guard/testdata/screens/generate-refused-setting.xml
+++ b/internal/guard/testdata/screens/generate-refused-setting.xml
@@ -36,21 +36,17 @@
-
-
-
-
- Single batch
-
+
+
+
+ Single batch
-
-
-
+
+
+
-
-
- Files of one format and one size, with a manifest that says how the system under test should react to them.
-
+
+ Files of one format and one size, with a manifest that says how the system under test should react to them.
@@ -73,10 +69,8 @@
File configuration
-
-
-
-
+
+
@@ -142,12 +136,10 @@
-
+
-
-
- 10 485 760 B
-
+
+ 10 485 760 B
@@ -290,10 +282,8 @@
Settings for png
-
-
-
-
+
+
@@ -331,15 +321,13 @@
-
-
-
-
- png: Width cannot be "99999" - it takes a whole number of pixels from 1 to 20000
-
+
+
+
+ png: Width cannot be "99999" - it takes a whole number of pixels from 1 to 20000
-
-
+
+
@@ -373,12 +361,10 @@
-
+
-
-
- width times height cannot pass 40 megapixels, because the picture is held in memory while it is encoded
-
+
+ width times height cannot pass 40 megapixels, because the picture is held in memory while it is encoded
@@ -411,10 +397,8 @@
Output
-
-
-
-
+
+
@@ -544,15 +528,13 @@
-
-
-
-
- 1 file · 10.0 MB (10 485 760 B) · png · will go to /tfg/out
-
+
+
+
+ 1 file · 10.0 MB (10 485 760 B) · png · will go to /tfg/out
-
-
+
+
diff --git a/internal/guard/testdata/screens/generate-refused.xml b/internal/guard/testdata/screens/generate-refused.xml
index 2b3bdfd..f3d432d 100644
--- a/internal/guard/testdata/screens/generate-refused.xml
+++ b/internal/guard/testdata/screens/generate-refused.xml
@@ -36,21 +36,17 @@
-
-
-
-
- Single batch
-
+
+
+
+ Single batch
-
-
-
+
+
+
-
-
- Files of one format and one size, with a manifest that says how the system under test should react to them.
-
+
+ Files of one format and one size, with a manifest that says how the system under test should react to them.
@@ -73,10 +69,8 @@
File configuration
-
-
-
-
+
+
@@ -143,29 +137,25 @@
-
+
-
-
- 1 B
-
+
+ 1 B
-
-
-
-
- AVIF cannot be smaller than 311 B - the smallest picture this format draws codes to 303
- B at worst, and the file always carries a free box, which costs 8 B even when it holds
- nothing. Requested: 1 B. Ask for 311 B or more, or set a smaller width and height, or a
- lower quality
-
+
+
+
+ AVIF cannot be smaller than 311 B - the smallest picture this format draws codes to 303
+ B at worst, and the file always carries a free box, which costs 8 B even when it holds
+ nothing. Requested: 1 B. Ask for 311 B or more, or set a smaller width and height, or a
+ lower quality
-
-
+
+
@@ -312,10 +302,8 @@
Settings for avif
-
-
-
-
+
+
@@ -351,10 +339,8 @@
Output
-
-
-
-
+
+
@@ -484,15 +470,13 @@
-
-
-
-
- 1 file · 1 B · avif · will go to /tfg/out
-
+
+
+
+ 1 file · 1 B · avif · will go to /tfg/out
-
-
+
+
diff --git a/internal/guard/testdata/screens/generate-switch-by-key.xml b/internal/guard/testdata/screens/generate-switch-by-key.xml
index 4b17e1b..3451cb0 100644
--- a/internal/guard/testdata/screens/generate-switch-by-key.xml
+++ b/internal/guard/testdata/screens/generate-switch-by-key.xml
@@ -36,21 +36,17 @@
-
-
-
-
- Single batch
-
+
+
+
+ Single batch
-
-
-
+
+
+
-
-
- Files of one format and one size, with a manifest that says how the system under test should react to them.
-
+
+ Files of one format and one size, with a manifest that says how the system under test should react to them.
@@ -73,10 +69,8 @@
File configuration
-
-
-
-
+
+
@@ -142,12 +136,10 @@
-
+
-
-
- 10 485 760 B
-
+
+ 10 485 760 B
@@ -290,10 +282,8 @@
Settings for avif
-
-
-
-
+
+
@@ -329,10 +319,8 @@
Output
-
-
-
-
+
+
@@ -462,15 +450,13 @@
-
-
-
-
- 1 file · 10.0 MB (10 485 760 B) · avif · will go to /tfg/out
-
+
+
+
+ 1 file · 10.0 MB (10 485 760 B) · avif · will go to /tfg/out
-
-
+
+
diff --git a/internal/guard/testdata/screens/generate-typed.xml b/internal/guard/testdata/screens/generate-typed.xml
index e31c12d..92444fb 100644
--- a/internal/guard/testdata/screens/generate-typed.xml
+++ b/internal/guard/testdata/screens/generate-typed.xml
@@ -36,21 +36,17 @@
-
-
-
-
- Single batch
-
+
+
+
+ Single batch
-
-
-
+
+
+
-
-
- Files of one format and one size, with a manifest that says how the system under test should react to them.
-
+
+ Files of one format and one size, with a manifest that says how the system under test should react to them.
@@ -73,10 +69,8 @@
File configuration
-
-
-
-
+
+
@@ -142,26 +136,22 @@
-
+
-
-
-
-
+
+
-
-
-
-
- Size "abc" has no number: write something like 10mb or 1048576
-
+
+
+
+ Size "abc" has no number: write something like 10mb or 1048576
-
-
+
+
@@ -301,10 +291,8 @@
Settings for avif
-
-
-
-
+
+
@@ -340,10 +328,8 @@
Output
-
-
-
-
+
+
@@ -473,15 +459,13 @@
-
-
-
-
- Files will go to /tfg/out
-
+
+
+
+ Files will go to /tfg/out
-
-
+
+
diff --git a/internal/guard/testdata/screens/generate-unchecked.xml b/internal/guard/testdata/screens/generate-unchecked.xml
index a3f14b0..51135a4 100644
--- a/internal/guard/testdata/screens/generate-unchecked.xml
+++ b/internal/guard/testdata/screens/generate-unchecked.xml
@@ -36,21 +36,17 @@
-
-
-
-
- Single batch
-
+
+
+
+ Single batch
-
-
-
+
+
+
-
-
- Files of one format and one size, with a manifest that says how the system under test should react to them.
-
+
+ Files of one format and one size, with a manifest that says how the system under test should react to them.
@@ -73,10 +69,8 @@
File configuration
-
-
-
-
+
+
@@ -142,12 +136,10 @@
-
+
-
-
- 10 485 760 B
-
+
+ 10 485 760 B
@@ -290,10 +282,8 @@
Settings for avif
-
-
-
-
+
+
@@ -329,10 +319,8 @@
Output
-
-
-
-
+
+
@@ -461,15 +449,13 @@
-
-
-
-
- 1 file · 10.0 MB (10 485 760 B) · avif · will go to /tfg/out
-
+
+
+
+ 1 file · 10.0 MB (10 485 760 B) · avif · will go to /tfg/out
-
-
+
+
diff --git a/internal/guard/testdata/screens/generate.xml b/internal/guard/testdata/screens/generate.xml
index 6dd1326..54ebb5f 100644
--- a/internal/guard/testdata/screens/generate.xml
+++ b/internal/guard/testdata/screens/generate.xml
@@ -36,21 +36,17 @@
-
-
-
-
- Single batch
-
+
+
+
+ Single batch
-
-
-
+
+
+
-
-
- Files of one format and one size, with a manifest that says how the system under test should react to them.
-
+
+ Files of one format and one size, with a manifest that says how the system under test should react to them.
@@ -73,10 +69,8 @@
File configuration
-
-
-
-
+
+
@@ -142,12 +136,10 @@
-
+
-
-
- 10 485 760 B
-
+
+ 10 485 760 B
@@ -290,10 +282,8 @@
Settings for avif
-
-
-
-
+
+
@@ -329,10 +319,8 @@
Output
-
-
-
-
+
+
@@ -462,15 +450,13 @@
-
-
-
-
- 1 file · 10.0 MB (10 485 760 B) · avif · will go to /tfg/out
-
+
+
+
+ 1 file · 10.0 MB (10 485 760 B) · avif · will go to /tfg/out
-
-
+
+
diff --git a/internal/guard/testdata/screens/preset-many-settings.xml b/internal/guard/testdata/screens/preset-many-settings.xml
index 3b16f3d..0145481 100644
--- a/internal/guard/testdata/screens/preset-many-settings.xml
+++ b/internal/guard/testdata/screens/preset-many-settings.xml
@@ -36,21 +36,17 @@
-
-
-
-
- Presets
-
+
+
+
+ Presets
-
-
-
+
+
+
-
-
- Ready-made sets of files, each built to answer one question about the system under test.
-
+
+ Ready-made sets of files, each built to answer one question about the system under test.
@@ -73,10 +69,8 @@
The question
-
-
-
-
+
+
@@ -113,96 +107,80 @@
-
-
-
-
- Does my upload form take what it should and turn the rest away?
-
+
+
+
+ Does my upload form take what it should and turn the rest away?
-
-
-
-
-
-
- Typically finds:
-
+
+
+
+
+
+ Typically finds:
-
-
+
+
•
-
-
-
-
- a limit enforced in the browser and not on the server
-
+
+
+
+ a limit enforced in the browser and not on the server
-
-
+
+
•
-
-
-
-
- an SVG or an HTML file taken for a picture or for plain text, which is a way to get a script past a form
-
+
+
+
+ an SVG or an HTML file taken for a picture or for plain text, which is a way to get a script past a form
-
-
+
+
•
-
-
-
-
- a file checked by its extension and never opened, so a PDF named .jpg goes through
-
+
+
+
+ a file checked by its extension and never opened, so a PDF named .jpg goes through
-
-
+
+
•
-
-
-
-
- a form that reads the whole body into memory before it looks at how big it is
-
+
+
+
+ a form that reads the whole body into memory before it looks at how big it is
-
-
+
+
•
-
-
-
-
- an upload named PHOTO.JPG turned away where photo.jpg is taken, or the other way round
-
+
+
+
+ an upload named PHOTO.JPG turned away where photo.jpg is taken, or the other way round
-
-
+
+
•
-
-
-
-
- a name with spaces, brackets or characters outside ASCII written to disk unchanged
-
+
+
+
+ a name with spaces, brackets or characters outside ASCII written to disk unchanged
-
-
+
+
@@ -227,10 +205,8 @@
Settings
-
-
-
-
+
+
@@ -269,12 +245,10 @@
-
+
-
-
-
-
+
+
@@ -422,10 +396,8 @@
Output
-
-
-
-
+
+
@@ -532,15 +504,13 @@
-
-
-
-
- 71 files · 115.1 MB (120 639 488 B) · 6 formats · will go to /tfg/out
-
+
+
+
+ 71 files · 115.1 MB (120 639 488 B) · 6 formats · will go to /tfg/out
-
-
+
+
diff --git a/internal/guard/testdata/screens/preset-menu-setting.xml b/internal/guard/testdata/screens/preset-menu-setting.xml
index 42fcc20..4c6533b 100644
--- a/internal/guard/testdata/screens/preset-menu-setting.xml
+++ b/internal/guard/testdata/screens/preset-menu-setting.xml
@@ -36,21 +36,17 @@
-
-
-
-
- Presets
-
+
+
+
+ Presets
-
-
-
+
+
+
-
-
- Ready-made sets of files, each built to answer one question about the system under test.
-
+
+ Ready-made sets of files, each built to answer one question about the system under test.
@@ -73,10 +69,8 @@
The question
-
-
-
-
+
+
@@ -113,60 +107,50 @@
-
-
-
-
- Is a size limit enforced exactly where it is declared?
-
+
+
+
+ Is a size limit enforced exactly where it is declared?
-
-
-
-
-
-
- Typically finds:
-
+
+
+
+
+
+ Typically finds:
-
-
+
+
•
-
-
-
-
- off by one errors at the limit
-
+
+
+
+ off by one errors at the limit
-
-
+
+
•
-
-
-
-
- MB confused with MiB, which is 4.8 per cent and enough to let a file through that should not pass
-
+
+
+
+ MB confused with MiB, which is 4.8 per cent and enough to let a file through that should not pass
-
-
+
+
•
-
-
-
-
- a limit enforced in the browser and not on the server
-
+
+
+
+ a limit enforced in the browser and not on the server
-
-
+
+
@@ -191,10 +175,8 @@
Settings
-
-
-
-
+
+
@@ -233,12 +215,10 @@
-
+
-
-
-
-
+
+
@@ -325,10 +305,8 @@
Output
-
-
-
-
+
+
@@ -435,15 +413,13 @@
-
-
-
-
- 7 files · 70.0 MB (73 400 320 B) · pdf · will go to /tfg/out
-
+
+
+
+ 7 files · 70.0 MB (73 400 320 B) · pdf · will go to /tfg/out
-
-
+
+
diff --git a/internal/guard/testdata/screens/preset-menu.xml b/internal/guard/testdata/screens/preset-menu.xml
index cda8f82..e658e2b 100644
--- a/internal/guard/testdata/screens/preset-menu.xml
+++ b/internal/guard/testdata/screens/preset-menu.xml
@@ -36,21 +36,17 @@
-
-
-
-
- Presets
-
+
+
+
+ Presets
-
-
-
+
+
+
-
-
- Ready-made sets of files, each built to answer one question about the system under test.
-
+
+ Ready-made sets of files, each built to answer one question about the system under test.
@@ -73,10 +69,8 @@
The question
-
-
-
-
+
+
@@ -113,72 +107,60 @@
-
-
-
-
- Does a file that is valid and as small as the format allows get through?
-
+
+
+
+ Does a file that is valid and as small as the format allows get through?
-
-
-
-
-
-
- Typically finds:
-
+
+
+
+
+
+ Typically finds:
-
-
+
+
•
-
-
-
-
- a valid file turned away for being too small, where the check counts bytes instead of reading them
-
+
+
+
+ a valid file turned away for being too small, where the check counts bytes instead of reading them
-
-
+
+
•
-
-
-
-
- an empty file that brings the reader down rather than being reported
-
+
+
+
+ an empty file that brings the reader down rather than being reported
-
-
+
+
•
-
-
-
-
- a picture one pixel wide that divides by zero on the way to a thumbnail
-
+
+
+
+ a picture one pixel wide that divides by zero on the way to a thumbnail
-
-
+
+
•
-
-
-
-
- storage that reads nought bytes as a failed upload and keeps retrying
-
+
+
+
+ storage that reads nought bytes as a failed upload and keeps retrying
-
-
+
+
@@ -203,10 +185,8 @@
Settings
-
-
-
-
+
+
@@ -269,10 +249,8 @@
Output
-
-
-
-
+
+
@@ -379,15 +357,13 @@
-
-
-
-
- 28 files · 31.9 KB (32 667 B) · 26 formats · will go to /tfg/out
-
+
+
+
+ 28 files · 31.9 KB (32 667 B) · 26 formats · will go to /tfg/out
-
-
+
+
diff --git a/internal/guard/testdata/screens/preset-refused.xml b/internal/guard/testdata/screens/preset-refused.xml
index 9b359ba..f3d2d05 100644
--- a/internal/guard/testdata/screens/preset-refused.xml
+++ b/internal/guard/testdata/screens/preset-refused.xml
@@ -36,21 +36,17 @@
-
-
-
-
- Presets
-
+
+
+
+ Presets
-
-
-
+
+
+
-
-
- Ready-made sets of files, each built to answer one question about the system under test.
-
+
+ Ready-made sets of files, each built to answer one question about the system under test.
@@ -73,10 +69,8 @@
The question
-
-
-
-
+
+
@@ -113,60 +107,50 @@
-
-
-
-
- Is a size limit enforced exactly where it is declared?
-
+
+
+
+ Is a size limit enforced exactly where it is declared?
-
-
-
-
-
-
- Typically finds:
-
+
+
+
+
+
+ Typically finds:
-
-
+
+
•
-
-
-
-
- off by one errors at the limit
-
+
+
+
+ off by one errors at the limit
-
-
+
+
•
-
-
-
-
- MB confused with MiB, which is 4.8 per cent and enough to let a file through that should not pass
-
+
+
+
+ MB confused with MiB, which is 4.8 per cent and enough to let a file through that should not pass
-
-
+
+
•
-
-
-
-
- a limit enforced in the browser and not on the server
-
+
+
+
+ a limit enforced in the browser and not on the server
-
-
+
+
@@ -191,10 +175,8 @@
Settings
-
-
-
-
+
+
@@ -231,28 +213,24 @@
-
+
-
-
- 512 B
-
+
+ 512 B
-
-
-
-
- the preset size-boundaries cannot build this set - under_1mb would be -1048064 B, and a file cannot be smaller than
- nothing. Raise the Limit above 1051991 B, narrow the spread, or choose a format with a smaller minimum. The Limit
- asked for was 512 B.
-
+
+
+
+ the preset size-boundaries cannot build this set - under_1mb would be -1048064 B, and a file cannot be smaller than
+ nothing. Raise the Limit above 1051991 B, narrow the spread, or choose a format with a smaller minimum. The Limit
+ asked for was 512 B.
-
-
+
+
@@ -336,10 +314,8 @@
Output
-
-
-
-
+
+
@@ -446,15 +422,13 @@
-
-
-
-
- Files will go to /tfg/out
-
+
+
+
+ Files will go to /tfg/out
-
-
+
+
diff --git a/internal/guard/testdata/screens/preset.xml b/internal/guard/testdata/screens/preset.xml
index a16cefb..8f60917 100644
--- a/internal/guard/testdata/screens/preset.xml
+++ b/internal/guard/testdata/screens/preset.xml
@@ -36,21 +36,17 @@
-
-
-
-
- Presets
-
+
+
+
+ Presets
-
-
-
+
+
+
-
-
- Ready-made sets of files, each built to answer one question about the system under test.
-
+
+ Ready-made sets of files, each built to answer one question about the system under test.
@@ -73,10 +69,8 @@
The question
-
-
-
-
+
+
@@ -113,72 +107,60 @@
-
-
-
-
- Does a file that is valid and as small as the format allows get through?
-
+
+
+
+ Does a file that is valid and as small as the format allows get through?
-
-
-
-
-
-
- Typically finds:
-
+
+
+
+
+
+ Typically finds:
-
-
+
+
•
-
-
-
-
- a valid file turned away for being too small, where the check counts bytes instead of reading them
-
+
+
+
+ a valid file turned away for being too small, where the check counts bytes instead of reading them
-
-
+
+
•
-
-
-
-
- an empty file that brings the reader down rather than being reported
-
+
+
+
+ an empty file that brings the reader down rather than being reported
-
-
+
+
•
-
-
-
-
- a picture one pixel wide that divides by zero on the way to a thumbnail
-
+
+
+
+ a picture one pixel wide that divides by zero on the way to a thumbnail
-
-
+
+
•
-
-
-
-
- storage that reads nought bytes as a failed upload and keeps retrying
-
+
+
+
+ storage that reads nought bytes as a failed upload and keeps retrying
-
-
+
+
@@ -203,10 +185,8 @@
Settings
-
-
-
-
+
+
@@ -269,10 +249,8 @@
Output
-
-
-
-
+
+
@@ -379,15 +357,13 @@
-
-
-
-
- 28 files · 31.9 KB (32 667 B) · 26 formats · will go to /tfg/out
-
+
+
+
+ 28 files · 31.9 KB (32 667 B) · 26 formats · will go to /tfg/out
-
-
+
+
diff --git a/internal/guard/testdata/screens/recipe-contents.xml b/internal/guard/testdata/screens/recipe-contents.xml
index 4687fb4..e1a2ea2 100644
--- a/internal/guard/testdata/screens/recipe-contents.xml
+++ b/internal/guard/testdata/screens/recipe-contents.xml
@@ -36,21 +36,17 @@
-
-
-
-
- Several batches
-
+
+
+
+ Several batches
-
-
-
+
+
+
-
-
- Batches of different formats and sizes, generated together in one run.
-
+
+ Batches of different formats and sizes, generated together in one run.
@@ -74,10 +70,8 @@
Build on a preset
-
-
-
-
+
+
@@ -86,13 +80,11 @@
-
+
-
-
- With the box ticked, the chosen preset's files come first and the batches below are added after them. Without it, the batches are the whole
- recipe.
-
+
+ With the box ticked, the chosen preset's files come first and the batches below are added after them. Without it, the batches are the whole
+ recipe.
@@ -133,8 +125,8 @@
-
-
+
+
@@ -142,10 +134,8 @@
Batch 1
-
-
-
-
+
+
@@ -265,12 +255,10 @@
-
+
-
-
- 10 485 760 B
-
+
+ 10 485 760 B
@@ -359,10 +347,8 @@
Settings for zip
-
-
-
-
+
+
@@ -395,10 +381,8 @@
Notes for the manifest
-
-
-
-
+
+
@@ -411,15 +395,13 @@
-
-
-
-
- Files inside each archive
-
+
+
+
+ Files inside each archive
-
-
+
+
Format
@@ -530,10 +512,8 @@
Output
-
-
-
-
+
+
@@ -695,15 +675,13 @@
-
-
-
-
- Files will go to /tfg/out
-
+
+
+
+ Files will go to /tfg/out
-
-
+
+
diff --git a/internal/guard/testdata/screens/recipe-on-a-preset.xml b/internal/guard/testdata/screens/recipe-on-a-preset.xml
index 11adb13..a23c2e4 100644
--- a/internal/guard/testdata/screens/recipe-on-a-preset.xml
+++ b/internal/guard/testdata/screens/recipe-on-a-preset.xml
@@ -36,21 +36,17 @@
-
-
-
-
- Several batches
-
+
+
+
+ Several batches
-
-
-
+
+
+
-
-
- Batches of different formats and sizes, generated together in one run.
-
+
+ Batches of different formats and sizes, generated together in one run.
@@ -74,10 +70,8 @@
Build on a preset
-
-
-
-
+
+
@@ -86,13 +80,11 @@
-
+
-
-
- With the box ticked, the chosen preset's files come first and the batches below are added after them. Without it, the batches are the whole
- recipe.
-
+
+ With the box ticked, the chosen preset's files come first and the batches below are added after them. Without it, the batches are the whole
+ recipe.
@@ -192,8 +184,8 @@
-
-
+
+
@@ -201,10 +193,8 @@
Batch 1
-
-
-
-
+
+
@@ -329,12 +319,10 @@
-
+
-
-
- 10 485 760 B
-
+
+ 10 485 760 B
@@ -423,10 +411,8 @@
Settings for avif
-
-
-
-
+
+
@@ -459,10 +445,8 @@
Notes for the manifest
-
-
-
-
+
+
@@ -498,10 +482,8 @@
Output
-
-
-
-
+
+
@@ -663,15 +645,13 @@
-
-
-
-
- 29 files · 10.0 MB (10 518 427 B) · 26 formats · will go to /tfg/out
-
+
+
+
+ 29 files · 10.0 MB (10 518 427 B) · 26 formats · will go to /tfg/out
-
-
+
+
diff --git a/internal/guard/testdata/screens/recipe-refused-with-one-batch-filled.xml b/internal/guard/testdata/screens/recipe-refused-with-one-batch-filled.xml
index 6f6b4f8..16f6acf 100644
--- a/internal/guard/testdata/screens/recipe-refused-with-one-batch-filled.xml
+++ b/internal/guard/testdata/screens/recipe-refused-with-one-batch-filled.xml
@@ -36,21 +36,17 @@
-
-
-
-
- Several batches
-
+
+
+
+ Several batches
-
-
-
+
+
+
-
-
- Batches of different formats and sizes, generated together in one run.
-
+
+ Batches of different formats and sizes, generated together in one run.
@@ -74,10 +70,8 @@
Build on a preset
-
-
-
-
+
+
@@ -86,13 +80,11 @@
-
+
-
-
- With the box ticked, the chosen preset's files come first and the batches below are added after them. Without it, the batches are the whole
- recipe.
-
+
+ With the box ticked, the chosen preset's files come first and the batches below are added after them. Without it, the batches are the whole
+ recipe.
@@ -133,8 +125,8 @@
-
-
+
+
@@ -142,10 +134,8 @@
Batch 1
-
-
-
-
+
+
@@ -273,28 +263,24 @@
-
+
-
-
-
-
+
+
-
-
-
-
- target 1 has no Size - every target declares its Size, which is what lets a dry run report exact numbers before anything
- reaches the disk.
- add size: 2mb, size-range: 1kb-8kb, a boundary, contains, or a plain number of bytes.
-
+
+
+
+ target 1 has no Size - every target declares its Size, which is what lets a dry run report exact numbers before anything
+ reaches the disk.
+ add size: 2mb, size-range: 1kb-8kb, a boundary, contains, or a plain number of bytes.
-
-
+
+
@@ -332,17 +318,15 @@
-
-
-
-
- target 1 has no Batch name - a Batch name anchors the seed of a target, so editing one
- target never moves the bytes of another.
- give it a Batch name, for example id: invoices.
-
+
+
+
+ target 1 has no Batch name - a Batch name anchors the seed of a target, so editing one
+ target never moves the bytes of another.
+ give it a Batch name, for example id: invoices.
-
-
+
+
@@ -397,10 +381,8 @@
Settings for avif
-
-
-
-
+
+
@@ -433,10 +415,8 @@
Notes for the manifest
-
-
-
-
+
+
@@ -460,8 +440,8 @@
-
-
+
+
@@ -469,10 +449,8 @@
Batch 2
-
-
-
-
+
+
@@ -597,12 +575,10 @@
-
+
-
-
- 1 024 B
-
+
+ 1 024 B
@@ -691,10 +667,8 @@
Settings for avif
-
-
-
-
+
+
@@ -727,10 +701,8 @@
Notes for the manifest
-
-
-
-
+
+
@@ -766,10 +738,8 @@
Output
-
-
-
-
+
+
@@ -939,15 +909,13 @@
-
-
-
-
- Files will go to /tfg/out
-
+
+
+
+ Files will go to /tfg/out
-
-
+
+
diff --git a/internal/guard/testdata/screens/recipe-refused.xml b/internal/guard/testdata/screens/recipe-refused.xml
index d159e50..856c46e 100644
--- a/internal/guard/testdata/screens/recipe-refused.xml
+++ b/internal/guard/testdata/screens/recipe-refused.xml
@@ -36,21 +36,17 @@
-
-
-
-
- Several batches
-
+
+
+
+ Several batches
-
-
-
+
+
+
-
-
- Batches of different formats and sizes, generated together in one run.
-
+
+ Batches of different formats and sizes, generated together in one run.
@@ -74,10 +70,8 @@
Build on a preset
-
-
-
-
+
+
@@ -86,13 +80,11 @@
-
+
-
-
- With the box ticked, the chosen preset's files come first and the batches below are added after them. Without it, the batches are the whole
- recipe.
-
+
+ With the box ticked, the chosen preset's files come first and the batches below are added after them. Without it, the batches are the whole
+ recipe.
@@ -133,8 +125,8 @@
-
-
+
+
@@ -142,10 +134,8 @@
Batch 1
-
-
-
-
+
+
@@ -268,28 +258,24 @@
-
+
-
-
-
-
+
+
-
-
-
-
- target 1 has no Size - every target declares its Size, which is what lets a dry run report exact numbers before anything
- reaches the disk.
- add size: 2mb, size-range: 1kb-8kb, a boundary, contains, or a plain number of bytes.
-
+
+
+
+ target 1 has no Size - every target declares its Size, which is what lets a dry run report exact numbers before anything
+ reaches the disk.
+ add size: 2mb, size-range: 1kb-8kb, a boundary, contains, or a plain number of bytes.
-
-
+
+
@@ -327,17 +313,15 @@
-
-
-
-
- target 1 has no Batch name - a Batch name anchors the seed of a target, so editing one
- target never moves the bytes of another.
- give it a Batch name, for example id: invoices.
-
+
+
+
+ target 1 has no Batch name - a Batch name anchors the seed of a target, so editing one
+ target never moves the bytes of another.
+ give it a Batch name, for example id: invoices.
-
-
+
+
@@ -392,10 +376,8 @@
Settings for avif
-
-
-
-
+
+
@@ -428,10 +410,8 @@
Notes for the manifest
-
-
-
-
+
+
@@ -467,10 +447,8 @@
Output
-
-
-
-
+
+
@@ -632,15 +610,13 @@
-
-
-
-
- Files will go to /tfg/out
-
+
+
+
+ Files will go to /tfg/out
-
-
+
+
diff --git a/internal/guard/testdata/screens/recipe-two-batches.xml b/internal/guard/testdata/screens/recipe-two-batches.xml
index d12eabf..d7c2c96 100644
--- a/internal/guard/testdata/screens/recipe-two-batches.xml
+++ b/internal/guard/testdata/screens/recipe-two-batches.xml
@@ -36,21 +36,17 @@
-
-
-
-
- Several batches
-
+
+
+
+ Several batches
-
-
-
+
+
+
-
-
- Batches of different formats and sizes, generated together in one run.
-
+
+ Batches of different formats and sizes, generated together in one run.
@@ -74,10 +70,8 @@
Build on a preset
-
-
-
-
+
+
@@ -86,13 +80,11 @@
-
+
-
-
- With the box ticked, the chosen preset's files come first and the batches below are added after them. Without it, the batches are the whole
- recipe.
-
+
+ With the box ticked, the chosen preset's files come first and the batches below are added after them. Without it, the batches are the whole
+ recipe.
@@ -133,8 +125,8 @@
-
-
+
+
@@ -142,10 +134,8 @@
Batch 1
-
-
-
-
+
+
@@ -270,12 +260,10 @@
-
+
-
-
- 10 485 760 B
-
+
+ 10 485 760 B
@@ -364,10 +352,8 @@
Settings for avif
-
-
-
-
+
+
@@ -400,10 +386,8 @@
Notes for the manifest
-
-
-
-
+
+
@@ -427,8 +411,8 @@
-
-
+
+
@@ -436,10 +420,8 @@
Batch 2
-
-
-
-
+
+
@@ -567,12 +549,10 @@
-
+
-
-
-
-
+
+
@@ -664,10 +644,8 @@
Settings for avif
-
-
-
-
+
+
@@ -700,10 +678,8 @@
Notes for the manifest
-
-
-
-
+
+
@@ -739,10 +715,8 @@
Output
-
-
-
-
+
+
@@ -912,15 +886,13 @@
-
-
-
-
- Files will go to /tfg/out
-
+
+
+
+ Files will go to /tfg/out
-
-
+
+
diff --git a/internal/guard/testdata/screens/recipe.xml b/internal/guard/testdata/screens/recipe.xml
index d824209..266bcdf 100644
--- a/internal/guard/testdata/screens/recipe.xml
+++ b/internal/guard/testdata/screens/recipe.xml
@@ -36,21 +36,17 @@
-
-
-
-
- Several batches
-
+
+
+
+ Several batches
-
-
-
+
+
+
-
-
- Batches of different formats and sizes, generated together in one run.
-
+
+ Batches of different formats and sizes, generated together in one run.
@@ -74,10 +70,8 @@
Build on a preset
-
-
-
-
+
+
@@ -86,13 +80,11 @@
-
+
-
-
- With the box ticked, the chosen preset's files come first and the batches below are added after them. Without it, the batches are the whole
- recipe.
-
+
+ With the box ticked, the chosen preset's files come first and the batches below are added after them. Without it, the batches are the whole
+ recipe.
@@ -133,8 +125,8 @@
-
-
+
+
@@ -142,10 +134,8 @@
Batch 1
-
-
-
-
+
+
@@ -265,12 +255,10 @@
-
+
-
-
- 10 485 760 B
-
+
+ 10 485 760 B
@@ -359,10 +347,8 @@
Settings for avif
-
-
-
-
+
+
@@ -395,10 +381,8 @@
Notes for the manifest
-
-
-
-
+
+
@@ -434,10 +418,8 @@
Output
-
-
-
-
+
+
@@ -599,15 +581,13 @@
-
-
-
-
- 1 file · 10.0 MB (10 485 760 B) · avif · will go to /tfg/out
-
+
+
+
+ 1 file · 10.0 MB (10 485 760 B) · avif · will go to /tfg/out
-
-
+
+
diff --git a/internal/guard/themescope_test.go b/internal/guard/themescope_test.go
new file mode 100644
index 0000000..a48c840
--- /dev/null
+++ b/internal/guard/themescope_test.go
@@ -0,0 +1,66 @@
+package guard
+
+import (
+ "testing"
+
+ "fyne.io/fyne/v2"
+ "fyne.io/fyne/v2/container"
+ "fyne.io/fyne/v2/test"
+
+ "github.com/donislawdev/TestingFilesGenerator/internal/gui/catalogue"
+ "github.com/donislawdev/TestingFilesGenerator/internal/gui/parts"
+)
+
+// No screen, and nothing in the catalogue of parts, stands in a theme override.
+//
+// An override is the toolkit's one public door into a subtree's theme, and it
+// costs memory that never comes back. Fyne 2.8.1 gives an override a NEW scope
+// at construction, at CreateRenderer and at every Refresh, and keys its parsed
+// fonts by scope - so every rebuild of a screen followed by a new string drawn
+// under an override parsed another ~7.4 MB set of fonts. Measured in the real
+// window on 2026-09-23 (tools/probes/guilag, docs/GUI-MEMORY-2026-09-23.md
+// section 4c): 26 sets after visiting the tabs, a live heap of 205 MB, and ten
+// rebuilds each followed by a new size added 84 MB more. Every sentence, error
+// area, caption and count of bytes was under one. Without them: 2 sets, 27 MB,
+// and nothing added by the rebuilds.
+//
+// The open list of formats is not on this screen - it is a popup - and it
+// still draws its rows under one (parts/openlist.go, rowTheme). That is the
+// next thing the same document names, and it is named here so that nobody
+// reads this guard as covering it.
+func TestNoScreenStandsInAThemeOverride(t *testing.T) {
+ content, _ := laidOutWindow(t)
+
+ quiet, counts := 0, 0
+ walk(content, func(o fyne.CanvasObject) {
+ switch o.(type) {
+ case *parts.QuietText:
+ quiet++
+ case *parts.ByteCount:
+ counts++
+ }
+ })
+ // The things that stood under an override until 2026-09-23 have to be on
+ // the screen for their absence from one to mean anything: a subtitle on
+ // each of three work screens, and the count of bytes beside a size.
+ if quiet < 3 || counts < 1 {
+ t.Fatalf("the window holds %d quiet line(s) and %d count(s) of bytes, so this guard is not "+
+ "looking at the screens it asks about", quiet, counts)
+ }
+
+ cat := test.NewWindow(catalogue.Screen())
+ t.Cleanup(cat.Close)
+
+ for name, root := range map[string]fyne.CanvasObject{"the window": content, "the catalogue": cat.Content()} {
+ overrides := 0
+ walk(root, func(o fyne.CanvasObject) {
+ if _, is := o.(*container.ThemeOverride); is {
+ overrides++
+ }
+ })
+ if overrides > 0 {
+ t.Errorf("%s holds %d theme override(s), and each one parses the fonts again in a scope of its own - "+
+ "take the room off with a layout (inkTight) and name the colour in the words (QuietText)", name, overrides)
+ }
+ }
+}
diff --git a/internal/guard/words_test.go b/internal/guard/words_test.go
index 7deff14..b263e34 100644
--- a/internal/guard/words_test.go
+++ b/internal/guard/words_test.go
@@ -4,6 +4,8 @@ import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/widget"
+
+ "github.com/donislawdev/TestingFilesGenerator/internal/gui/parts"
)
// wordsOf is the text an object shows, whichever of the two kinds of object
@@ -19,6 +21,10 @@ import (
// one place the two kinds are told apart, so the next kind is one more case
// here rather than a hunt through thirty type assertions.
//
+// The third kind since 2026-09-23: parts.QuietText, the words that recede -
+// a subtitle, a caption, a folded section's line, the count of bytes - which
+// stopped being toolkit labels under a theme override (see QuietText).
+//
// A hidden object still answers. Whether something is on the screen is a
// question about its ancestors as well, and sizechoice_test.go asks it
// properly. Nothing here filters.
@@ -28,6 +34,10 @@ func wordsOf(o fyne.CanvasObject) (string, bool) {
return v.Text, true
case *canvas.Text:
return v.Text, true
+ case *parts.QuietText:
+ return v.Text, true
+ case *parts.ByteCount:
+ return v.Text, true
}
return "", false
}
@@ -46,6 +56,20 @@ func boldWordsAt(o fyne.CanvasObject) (text string, bold bool, size float32, ok
return v.Text, v.TextStyle.Bold, fyne.CurrentApp().Settings().Theme().Size(name), true
case *canvas.Text:
return v.Text, v.TextStyle.Bold, v.TextSize, true
+ case *parts.QuietText:
+ return v.Text, false, quietSize(v), true
+ case *parts.ByteCount:
+ return v.Text, false, quietSize(&v.QuietText), true
}
return "", false, 0, false
}
+
+// quietSize is the size quiet words are drawn at: their rank of the scale,
+// the body text when none is named - the rule widget.Label keeps.
+func quietSize(q *parts.QuietText) float32 {
+ name := q.SizeName
+ if name == "" {
+ name = "text"
+ }
+ return fyne.CurrentApp().Settings().Theme().Size(name)
+}
diff --git a/internal/gui/catalogue/words.go b/internal/gui/catalogue/words.go
index 9eb2168..454757a 100644
--- a/internal/gui/catalogue/words.go
+++ b/internal/gui/catalogue/words.go
@@ -13,7 +13,7 @@ import (
// thing a person looks at as a whole, which is why every rank is here once,
// one under another, and once more with a long line to see where it wraps.
func textRanks() Entry {
- return Entry{Name: "Title", Covers: []string{"Subtitle", "Titled", "Heading", "Subheading", "Prose", "Note", "Caption", "Bullets", "Ledger"}, States: []State{
+ return Entry{Name: "Title", Covers: []string{"Subtitle", "Titled", "Heading", "Subheading", "Prose", "Note", "Caption", "QuietText", "Bullets", "Ledger"}, States: []State{
{"the title of a screen", func() fyne.CanvasObject { return parts.Title("Single batch") }},
{"the sentence under a title", func() fyne.CanvasObject {
return parts.Subtitle("Files of one format and one size, with a manifest that says how the system under test should react to them.")
diff --git a/internal/gui/parts/bytecount.go b/internal/gui/parts/bytecount.go
index e4c6495..89d3923 100644
--- a/internal/gui/parts/bytecount.go
+++ b/internal/gui/parts/bytecount.go
@@ -2,7 +2,6 @@ package parts
import (
"fyne.io/fyne/v2/theme"
- "fyne.io/fyne/v2/widget"
"github.com/donislawdev/TestingFilesGenerator/internal/core"
)
@@ -28,18 +27,21 @@ import (
// Spelled by core.ExactBytes, which is what the command line prints. The
// window had a spelling of its own without the grouping until 2026-09-14, so
// one number came out as 10485760 B here and 10 485 760 B there.
+//
+// Quiet words since 2026-09-23, rather than a low importance label under a
+// theme override - see QuietText for what the override cost.
type ByteCount struct {
- widget.Label
+ QuietText
}
func newByteCount() *ByteCount {
c := &ByteCount{}
+ c.start("")
c.ExtendBaseWidget(c)
// The same rank as the line explaining a field, because it is the same kind
// of thing: something quiet beside a control that the eye should skip until
// it wants it.
c.SizeName = theme.SizeNameCaptionText
- c.Importance = widget.LowImportance
return c
}
diff --git a/internal/gui/parts/field.go b/internal/gui/parts/field.go
index 2f8309d..716d7c4 100644
--- a/internal/gui/parts/field.go
+++ b/internal/gui/parts/field.go
@@ -130,16 +130,15 @@ func shapedForItsValues(control fyne.CanvasObject) fyne.CanvasObject {
// worse than the italics it was replacing. So it went in as ordinary text
// until the palette arrived.
//
-// It goes through quiet rather than inkTight since 2026-09-15, which is O213:
+// It is QuietText since 2026-09-23 and was a quiet label before, which is O213:
// widget.LowImportance draws in ColorNameDisabled, #C2C8CD at 80 L*, a step
-// brighter than the hint a caption is meant to be. quiet remaps it to the
+// brighter than the hint a caption is meant to be. QuietText draws the
// placeholder, #9DA3A8 at 66.7 L*, 5.61:1 on a panel. O70 and O71.
func Note(content string) fyne.CanvasObject {
- label := widget.NewLabel(content)
- label.Wrapping = fyne.TextWrapWord
- label.Importance = widget.LowImportance
- label.SizeName = theme.SizeNameCaptionText
- return quiet(label)
+ note := NewQuietText(content)
+ note.Wrapping = fyne.TextWrapWord
+ note.SizeName = theme.SizeNameCaptionText
+ return note
}
// ErrorArea is where a field says what a run said about it.
diff --git a/internal/gui/parts/fields.go b/internal/gui/parts/fields.go
index d944505..9ae19b2 100644
--- a/internal/gui/parts/fields.go
+++ b/internal/gui/parts/fields.go
@@ -226,10 +226,9 @@ func (s *Fields) counter(setting string, control fyne.CanvasObject) fyne.CanvasO
// Beside the box on its own line, with no room of its own around the ink,
// so what the row puts between the box and the count is what reaches the
// screen. Until 2026-09-14 it stood at the far end of the name's line, 190
- // px from the box it was counting for. Drawn through quiet since 2026-09-15
- // - it is a low importance label, so the same O213 that dimmed a caption
- // dimmed this. See parts.quiet.
- return quiet(count)
+ // px from the box it was counting for. Quiet words since 2026-09-15 - the
+ // same O213 that dimmed a caption dimmed this. See QuietText.
+ return count
}
// Add builds a field and hands back the thing to put on the screen.
diff --git a/internal/gui/parts/folding.go b/internal/gui/parts/folding.go
index 4629234..faa8b01 100644
--- a/internal/gui/parts/folding.go
+++ b/internal/gui/parts/folding.go
@@ -36,7 +36,7 @@ type Folding struct {
open bool
title string
body fyne.CanvasObject
- line *widget.Label
+ line *QuietText
// head is the one control the whole head row is - see FoldHead.
head *FoldHead
@@ -167,8 +167,7 @@ type groupCell struct{ wideCell }
func newFolding(title string, titled fyne.CanvasObject, head []fyne.CanvasObject, content ...fyne.CanvasObject) *Folding {
f := &Folding{open: true, title: title}
- f.line = widget.NewLabel("")
- f.line.Importance = widget.LowImportance
+ f.line = NewQuietText("")
f.line.Hide()
f.body = Grid(content...)
@@ -182,7 +181,7 @@ func newFolding(title string, titled fyne.CanvasObject, head []fyne.CanvasObject
// (TestEverythingAPersonReadsStartsOnOneLeftEdge). Indenting the section's
// contents to match would put its fields off that edge instead, which is
// worse - there are more of them and they are what somebody is reading.
- // The summary line goes through quiet, so it recedes to the hint's colour
+ // The summary line is QuietText, so it recedes to the hint's colour
// rather than the brighter disabled one widget.LowImportance draws (O213).
//
// The whole row is the control, since O221, and the arrow is its mark
@@ -198,7 +197,14 @@ func newFolding(title string, titled fyne.CanvasObject, head []fyne.CanvasObject
// words it was a 6 px triangle at the end of a heading, and the heading
// read as an orphaned subtitle rather than as something that opens. The
// arrow now stands on the left edge and the words start after it.
- words := Padded(TabInset, container.NewHBox(arrow, titled, quiet(f.line)))
+ //
+ // The line stands in a container of its own that never hides, so the row
+ // keeps the gap before it even while the line is hidden - which is how the
+ // head of an open section gets as much room after its title as before its
+ // arrow. The line sat inside a theme override until 2026-09-23, and it was
+ // the override that stayed visible. Taking the override away took 4 px off
+ // the right of every open head, measured on the stored catalogue.
+ words := Padded(TabInset, container.NewHBox(arrow, titled, container.NewStack(f.line)))
f.head.under = words
row := container.NewBorder(nil, nil, nil, ButtonRow(head...), container.NewStack(f.head, words))
diff --git a/internal/gui/parts/parts.go b/internal/gui/parts/parts.go
index 8017a66..787f8de 100644
--- a/internal/gui/parts/parts.go
+++ b/internal/gui/parts/parts.go
@@ -21,8 +21,6 @@
package parts
import (
- "image/color"
-
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
@@ -118,18 +116,17 @@ func oneLine(text string, size fyne.ThemeSizeName) fyne.CanvasObject {
// hint rather than of a value, so it reads as an explanation of the word above
// it and not as a second heading competing with it.
//
-// A toolkit label rather than canvas words, because a sentence wraps and a
+// Wrapping words rather than canvas words, because a sentence wraps and a
// name does not - the same split words and Prose make. Its colour is the
// hint's, the same step the words on the strip stand at when they are not
-// chosen, so the head of a screen has one quiet colour and not two. Asked for
-// through quiet below, because the toolkit draws a low importance label in the
-// DISABLED colour, and this palette keeps that a step brighter than a hint on
-// purpose - see ColorNameDisabled in theme.go.
+// chosen, so the head of a screen has one quiet colour and not two. QuietText,
+// because the toolkit draws a low importance label in the DISABLED colour, and
+// this palette keeps that a step brighter than a hint on purpose - see
+// ColorNameDisabled in theme.go.
func Subtitle(sentence string) fyne.CanvasObject {
- label := widget.NewLabel(sentence)
- label.Wrapping = fyne.TextWrapWord
- label.Importance = widget.LowImportance
- return quiet(label)
+ subtitle := NewQuietText(sentence)
+ subtitle.Wrapping = fyne.TextWrapWord
+ return subtitle
}
// Caption is a short quiet line over or under a thing, at the smallest rank
@@ -138,39 +135,10 @@ func Subtitle(sentence string) fyne.CanvasObject {
// on 2026-09-15 when a second thing needed it - a rank used twice without a
// name is GUI rule 7's definition of a missing style.
func Caption(text string) fyne.CanvasObject {
- label := widget.NewLabel(text)
- label.Wrapping = fyne.TextWrapWord
- label.SizeName = theme.SizeNameCaptionText
- label.Importance = widget.LowImportance
- return quiet(label)
-}
-
-// quiet draws a low importance label in the hint's colour rather than the
-// disabled one, and takes the room a label keeps around itself off it.
-//
-// One helper rather than one at each call site, because O213 was four call
-// sites saying different things: a caption under a field, the count of bytes, a
-// folded section's summary and this subtitle were all widget.LowImportance,
-// which the toolkit draws in ColorNameDisabled - #C2C8CD, 80 L*, a step
-// BRIGHTER than a hint. So a caption meant to recede sat louder than the
-// placeholder in an empty box beside it. Owner's decision on 2026-09-15: one
-// quiet, the hint's, and the disabled colour kept for a value that is switched
-// off - which is content somebody may want to re-read and so is right to be the
-// brighter of the two.
-func quiet(o fyne.CanvasObject) fyne.CanvasObject {
- return container.NewThemeOverride(o, quietInk{noInnerPadding{Theme()}})
-}
-
-// quietInk is the window's theme with a low importance label drawn in the
-// hint's colour rather than the disabled one, and without the room a label
-// keeps around itself.
-type quietInk struct{ noInnerPadding }
-
-func (q quietInk) Color(name fyne.ThemeColorName, variant fyne.ThemeVariant) color.Color {
- if name == theme.ColorNameDisabled {
- return q.noInnerPadding.Color(theme.ColorNamePlaceHolder, variant)
- }
- return q.noInnerPadding.Color(name, variant)
+ caption := NewQuietText(text)
+ caption.Wrapping = fyne.TextWrapWord
+ caption.SizeName = theme.SizeNameCaptionText
+ return caption
}
// Titled is what stands above a screen's sections: its name, and under it the
diff --git a/internal/gui/parts/quiet.go b/internal/gui/parts/quiet.go
new file mode 100644
index 0000000..f28dc54
--- /dev/null
+++ b/internal/gui/parts/quiet.go
@@ -0,0 +1,97 @@
+package parts
+
+import (
+ "fyne.io/fyne/v2"
+ "fyne.io/fyne/v2/theme"
+ "fyne.io/fyne/v2/widget"
+)
+
+// QuietText is words that recede: a screen's subtitle, a caption, the line a
+// folded section keeps, the count of bytes beside a size. Drawn in the hint's
+// colour, with no room of its own around the ink.
+//
+// The hint's colour and not the disabled one is O213, the owner's decision of
+// 2026-09-15: the toolkit draws a low importance label in ColorNameDisabled,
+// #C2C8CD at 80 L*, a step BRIGHTER than a hint - so a caption meant to recede
+// sat louder than the placeholder in an empty box beside it. The disabled
+// colour stays for a value that is switched off.
+//
+// Its own widget rather than a toolkit label under a theme override, since
+// 2026-09-23. A label's colour follows its importance and nothing else, so the
+// only way to give it the hint's colour was an override - and Fyne gives an
+// override a new scope at construction, at CreateRenderer and at every
+// Refresh, and parses a fresh ~7.4 MB set of fonts for every scope a new
+// string is drawn in. Measured in the real window: ten rebuilds of the batch
+// screen, each followed by a new size, parsed ten sets for the count of bytes
+// alone, and nothing frees them (docs/GUI-MEMORY-2026-09-23.md section 4c).
+// A rich text names its colour per segment, so none of that is needed.
+//
+// The segment is the one widget.Label builds for itself (widget/label.go,
+// syncSegments), with the colour changed and nothing else, and the room is
+// taken off by the layout inkTight uses - so what reaches the screen is what
+// the label under the override drew, pixel for pixel on every stored screen.
+//
+// Like a label it does not wrap unless asked to.
+type QuietText struct {
+ widget.BaseWidget
+
+ // Text is what it says, SizeName the rank of the scale it says it at
+ // (the body text when empty), and Wrapping whether a long line breaks.
+ Text string
+ SizeName fyne.ThemeSizeName
+ Wrapping fyne.TextWrap
+
+ rich *widget.RichText
+}
+
+// NewQuietText makes quiet words.
+func NewQuietText(text string) *QuietText {
+ q := &QuietText{}
+ q.start(text)
+ q.ExtendBaseWidget(q)
+ return q
+}
+
+// start is what every QuietText needs before it is drawn, a ByteCount
+// included - which is a QuietText inside and extends itself rather than this.
+func (q *QuietText) start(text string) {
+ q.Text = text
+ q.rich = widget.NewRichText(&widget.TextSegment{})
+}
+
+// SetText changes what it says.
+func (q *QuietText) SetText(text string) {
+ q.Text = text
+ q.Refresh()
+}
+
+// Refresh carries the fields into the segment before anything is redrawn.
+// The rich text is refreshed once, by the renderer through its container -
+// widget.Label refreshes its own twice, which a count redrawn on every key
+// has no need of.
+func (q *QuietText) Refresh() {
+ q.sync()
+ q.BaseWidget.Refresh()
+}
+
+// CreateRenderer draws the rich text ink tight.
+func (q *QuietText) CreateRenderer() fyne.WidgetRenderer {
+ q.sync()
+ return widget.NewSimpleRenderer(inkTight(q.rich))
+}
+
+// sync is widget.Label's syncSegments with the hint's colour.
+func (q *QuietText) sync() {
+ size := q.SizeName
+ if size == "" {
+ size = theme.SizeNameText
+ }
+ q.rich.Wrapping = q.Wrapping
+ segment := q.rich.Segments[0].(*widget.TextSegment)
+ segment.Text = q.Text
+ segment.Style = widget.RichTextStyle{
+ ColorName: theme.ColorNamePlaceHolder,
+ Inline: true,
+ SizeName: size,
+ }
+}
diff --git a/internal/gui/parts/words.go b/internal/gui/parts/words.go
index 5123b3a..6218f96 100644
--- a/internal/gui/parts/words.go
+++ b/internal/gui/parts/words.go
@@ -35,14 +35,49 @@ func words(text string, size float32, bold bool, colour fyne.ThemeColorName) *ca
// inkTight takes the toolkit's own padding off a label, so a sentence that
// wraps stands on the scale like everything else.
//
-// A theme override rather than a widget of ours, because the label keeps
-// everything a sentence needs - wrapping, the caption size, the colour an
-// importance gives it - and the only thing wrong with it is the room it keeps
-// around itself. The override is the toolkit's one public door into a
-// subtree's theme, and it is used bare rather than wrapped in a type of ours,
-// because the driver casts to it.
+// A layout rather than a theme, since 2026-09-23. The label keeps everything a
+// sentence needs - wrapping, the caption size, the colour an importance gives
+// it - and the only thing wrong with it is the room it keeps around itself, so
+// the layout gives it that room outside its own edge: one inner padding larger
+// on every side and one inner padding up and to the left. The words land where
+// a label with no inner padding would put them and wrap at the same width -
+// all 28 stored screens came out pixel for pixel the same.
+//
+// It was a container.ThemeOverride until then, and that is the reason it is
+// not one now. Fyne gives an override a NEW scope at construction, at
+// CreateRenderer and at every Refresh, and keys its parsed fonts by scope - so
+// every rebuild of a screen followed by a new string in one of these labels
+// parsed another ~7.4 MB set of fonts that nothing ever frees. Measured in the
+// real window: 19 of the 26 sets after visiting the tabs were this override's,
+// and the live heap there went from 205 MB to 64 MB without it
+// (docs/GUI-MEMORY-2026-09-23.md section 4c).
func inkTight(o fyne.CanvasObject) fyne.CanvasObject {
- return container.NewThemeOverride(o, noInnerPadding{Theme()})
+ return container.New(inkTightLayout{}, o)
+}
+
+// inkTightLayout places a label so that its inner padding falls outside the
+// room it is given - see inkTight. A hidden label takes no room, as it did
+// inside the override it replaced.
+type inkTightLayout struct{}
+
+func (inkTightLayout) MinSize(objects []fyne.CanvasObject) fyne.Size {
+ pad := Theme().Size(theme.SizeNameInnerPadding)
+ size := fyne.NewSize(0, 0)
+ for _, o := range objects {
+ if !o.Visible() {
+ continue
+ }
+ size = size.Max(o.MinSize().Subtract(fyne.NewSquareSize(2 * pad)))
+ }
+ return size
+}
+
+func (inkTightLayout) Layout(objects []fyne.CanvasObject, size fyne.Size) {
+ pad := Theme().Size(theme.SizeNameInnerPadding)
+ for _, o := range objects {
+ o.Move(fyne.NewPos(-pad, -pad))
+ o.Resize(size.Add(fyne.NewSquareSize(2 * pad)))
+ }
}
// Flush puts a label a screen keeps hold of on the edge every other word
@@ -51,18 +86,6 @@ func inkTight(o fyne.CanvasObject) fyne.CanvasObject {
// - which has to be built by the runner and placed by the bar.
func Flush(label *widget.Label) fyne.CanvasObject { return inkTight(label) }
-// noInnerPadding is the window's theme with the room inside a label taken out.
-// Only that one size, so a box to type in under the same override would still
-// be a box.
-type noInnerPadding struct{ fyne.Theme }
-
-func (n noInnerPadding) Size(name fyne.ThemeSizeName) float32 {
- if name == theme.SizeNameInnerPadding {
- return 0
- }
- return n.Theme.Size(name)
-}
-
// Padded keeps one distance from the scale between its edge and its content.
//
// The toolkit's padded container reads the theme's padding, which is the