Skip to content

Commit e1c068e

Browse files
donislawdevclaude
andauthored
gui: nine things the owner saw in the running window (#115)
* gui: nine things the owner saw in the running window Every one measured on the built window with the pilot before any code, and photographed again after. In the order the owner listed them: 1. A field's explanation opens on the surface an open list floats on, not on the panel's colour - drawn over a panel it had no edge anywhere. 2. A list opens downward whenever a few whole rows fit under its box, cut to that room in whole rows and scrolling, and turns upward only for a box standing just over the bar. The format list on the preset screen opened over the question the preset asks. 3. A list with pictures keeps its tick in front, then the picture, then the word - the shape it had before #107 moved the tick to the end of every row and pulled the picture and the word a column to the left. A list without pictures keeps the shape #107 gave it. 4. The window coming to the front no longer marks whatever holds the keyboard as if the keyboard had just arrived. The driver calls FocusGained on the focused control at every activation, the first one included - right after Open has put the keyboard on the first field quietly - so the first menu on the first screen opened blue and every other menu was grey. The foreground hook tells the control the window is returning, and the mark is drawn again only if it was drawn before. 5. A box for a name, a template, a file name, a password or a list of sizes is two number boxes wide (TextWidth), and only a path still takes the row. 6. The tick of a switch is drawn on the whole of its square. 7. A first start opens as tall as the screen it opens on wants, not as tall as the tallest screen - the band of nothing under the first screen's form. 8. A secondary button wears the surface a box to type in has, with its edge, lifted under the pointer and again under a press - an outline round nothing read as a bordered word. 9. The busy face - the frozen form, Cancel, the bar - waits BusyFaceAfter before it appears, so a preview that is over in 50 ms no longer flashes it and takes it back. The state is immediate: a second press inside that moment is refused. The row of buttons is laid out again whenever a button comes or goes, because the toolkit lays out the parent of a hidden child and hands the row its old size - Preview and Generate stood half a Cancel to the left after every preview. The runner stood at its ceiling of fields and of methods, so the state and the face moved into a type of their own, and the Host grew Later, the clock only a real window can promise lands on the thread that draws. Guards for each, the stored screens regenerated, the catalogue names the two new exports. The mutation entries live in the toolbox beside the docs. Co-Authored-By: Claude Opus 5 <[email protected]> * guard: the type ceilings move down to today's widest types The runner stood on both ceilings and is no longer the widest type: the busy state and its controls left it. The ratchet only goes down - parts.Fields at 27 methods, window.batch at 21 fields. The gate that says so was not in the local subset, which is how CI saw it first. Co-Authored-By: Claude Opus 5 <[email protected]> * gui: after the outside review of #115 - the hook under a guard, an epoch on the busy face, one changelog Three remarks, each measured before being taken: - The foreground hook lived inside Run, behind cgo, where no guard reaches. Its body is gui.WindowReturning now, in a file of its own, and a guard calls it with a canvas of the test driver's - a focused menu told the window is returning draws no mark, a focused box to type in is left alone, nothing focused and no canvas are fine. The registration line is read out of the source, the way the refusal seam's is. - Calling the clock off cannot cancel a face the real window's clock has already handed to the toolkit's queue, so a preview's face could land on the run pressed in that gap and leave it without a bar. Each piece of work is an epoch and a face checks it is still its own. The guard plays it out with the held clock and a hold armed twice, and goes red on an epoch check made always true. - Two Unreleased changelog entries described two sizing rules for the first start. The older one says what the window does now. Co-Authored-By: Claude Opus 5 <[email protected]> * gui: the hook's file asks for the method by shape, so the window binary builds with cgo off on darwin again returning.go imported parts for one interface, and parts reaches the toolkit's widget tree - whose internal/widget does not compile on darwin without cgo, as ci.yml has recorded since 2026-08-20. The guard that builds the window binary with cgo off runs on the system it is on, so Linux and Windows stayed green and only the macOS job went red. The interface is now asked for by shape, and a guard reads the import lists of every file of the window package outside the cgo build, so the question is asked the same on every system. Co-Authored-By: Claude Opus 5 <[email protected]> * guard: a full stop where a comment had a semicolon, so the punctuation guard is green on every system The fourth push of #115 went red on all four test jobs (ubuntu, macOS, Windows, coverage gate) for one cause: a comment in the guard added by 695df9d held a semicolon, and TestProseInTheRepositoryUsesFlatHyphensAndNoSemicolons asks every comment for a full stop or a comma instead (D17). The file was written after that session's cheap gates had run, so the gates proved a tree that no longer existed. One line changes. Checked before this push: the 44 cheap whole-tree gates named in the guard files, the window binary with cgo off on darwin/arm64 and on Windows, and preflight --quick with the full suite and the fidelity oracles, all green. Co-Authored-By: Claude Opus 5 <[email protected]> --------- Co-authored-by: Claude Opus 5 <[email protected]>
1 parent b98b4c6 commit e1c068e

89 files changed

Lines changed: 2614 additions & 1214 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎CHANGELOG.md‎

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,27 @@ because it turns other people's test suites red.
1616

1717
### Changed
1818

19+
- **Nine things the owner saw in the running window.** A field's
20+
explanation opens on the same raised surface as an open list, so it no
21+
longer lies flat on the section it covers. A list of formats keeps its
22+
tick in front of the picture and the word, the shape it had before the
23+
tick moved to the end of every row. A list opens downward whenever a few
24+
rows fit under its box, shorter and scrolling, and turns upward only for
25+
a box standing just over the bar at the foot. A menu no longer opens
26+
marked as holding the keyboard when the window comes to the front, which
27+
is what made the first menu on the first screen blue and every other one
28+
grey - the mark is drawn for the keyboard alone, as it always was meant to
29+
be. A box for a name, a template, a file name, a password or a list of
30+
sizes is the width of two number boxes rather than of the whole row, and
31+
only a path still takes the row. The tick in a checked box fills its
32+
square. The first start is sized for the first screen rather than the
33+
tallest one - see the entry on the window's height further down. Preview,
34+
Choose, Duplicate and Add a batch have a raised
35+
face rather than an outline round nothing. And the busy face - the frozen
36+
form, Cancel, the bar - waits a moment before it appears, so a preview
37+
that is over in a blink no longer flashes it and takes it back, and the
38+
run buttons stand where they stood once the work is done.
39+
1940
- **The window draws its own buttons, switches and choosers.** A button now
2041
has one filled face for the action that does the work and an outline for the
2142
ones beside it, lightens under the pointer, darkens when pressed, and shows a
@@ -84,13 +105,15 @@ because it turns other people's test suites red.
84105
binary is about 800 kB larger for it. The command line binary carries no
85106
font and is unchanged.
86107

87-
- **The window opens as tall as its screens need, and no taller than a
88-
1080p screen.** A first start used to open at a height measured against the
89-
forms of an earlier version, and left a band of nothing under the form once
90-
the forms grew shorter. It now opens exactly tall enough for the tallest
91-
screen to show whole - today that is 917 px - and never taller than fits a
92-
1080p screen with its taskbar. A window you have resized still comes back at
93-
the size you left it.
108+
- **The window opens as tall as the screen it opens on needs, and no taller
109+
than a 1080p screen.** A first start used to open at a height measured
110+
against the forms of an earlier version, and left a band of nothing under
111+
the form once the forms grew shorter. It now opens exactly tall enough for
112+
the first screen to show whole - today that is 851 px - and never taller
113+
than fits a 1080p screen with its taskbar. The taller screens scroll a
114+
little on arrival, which the batch screen does from the second batch on in
115+
any case. A window you have resized still comes back at the size you left
116+
it.
94117

95118
- **The files inside an archive are a table with one row of headings.** The
96119
table on the batch screen named every column again in every row, so two

‎internal/guard/boxwidth_test.go‎

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,3 +329,103 @@ func TestADeclaredSettingStandsOnTheSameEdgeAsTheFieldsAboveIt(t *testing.T) {
329329
})
330330
}
331331
}
332+
333+
// Only a path takes the whole row.
334+
//
335+
// The owner's question from the running window on 2026-09-21: why are Batch
336+
// name, File names, Password, Spread, Kind of case and Manifest file name so
337+
// long. They took the row on the sentence that free text has no length to
338+
// promise, which is true and beside the point - a name is a short thing, and
339+
// a box 806 px wide for one promises something the value will never be, the
340+
// same defect TestABoxForANumberIsNotAsWideAsTheForm holds for a number.
341+
// The one value that can be long is a path, so the output directory keeps
342+
// the row and everything else typed into these screens is held under half
343+
// the column.
344+
//
345+
// Every box a person types into, on all three screens, rather than the six
346+
// the owner named: the seventh is the one nobody names. The folded sections
347+
// are opened first, because a box that is not on the screen has no laid out
348+
// width (the lesson of the guard above), and the two boxes the report named
349+
// inside them - a password, a kind of case - are exactly the ones a guard
350+
// reading the open screen would never see.
351+
func TestOnlyAPathTakesTheWholeRow(t *testing.T) {
352+
ourTheme(t)
353+
host := newFakeHost(t)
354+
window.Open(host)
355+
if host.content == nil {
356+
t.Fatal("opening the window put no screen in it")
357+
}
358+
w := test.NewWindow(host.content)
359+
t.Cleanup(w.Close)
360+
layOut := func() {
361+
w.Resize(fyne.NewSize(window.LargestOpening.Width, 1599))
362+
w.Resize(fyne.NewSize(window.LargestOpening.Width, 1600))
363+
}
364+
layOut()
365+
366+
batches := selectTab(t, host.content, text.TabRecipe())
367+
// A zip holds the one password box in the registry, and the notes hold the
368+
// kind of case.
369+
if picker, ok := controlUnder(batches, text.FieldFormat()).(*parts.Chooser); ok {
370+
picker.SetSelected("zip")
371+
} else {
372+
t.Fatal("the first batch has no format list, so this guard read the wrong tree")
373+
}
374+
openFold(t, batches, "", text.SettingsFor("zip"))
375+
openFold(t, batches, text.BatchHeading(1), text.SectionManifestNotes())
376+
layOut()
377+
378+
half := float32(parts.ColumnWidth) / 2
379+
checked, paths := 0, 0
380+
for _, tab := range []string{text.TabOneTarget(), text.TabPresets(), text.TabRecipe()} {
381+
screen := selectTab(t, host.content, tab)
382+
layOut()
383+
path := controlUnder(screen, text.FieldOutputDir())
384+
if path == nil {
385+
t.Fatalf("the %s screen has no output directory, so this guard cannot tell the path from the rest", tab)
386+
}
387+
onThePath := map[fyne.CanvasObject]bool{}
388+
walk(path, func(o fyne.CanvasObject) { onThePath[o] = true })
389+
390+
walk(screen, func(o fyne.CanvasObject) {
391+
box, is := o.(*parts.Entry)
392+
if !is || !box.Visible() || box.Size().Width == 0 {
393+
return
394+
}
395+
if onThePath[box] {
396+
paths++
397+
return
398+
}
399+
checked++
400+
if box.Size().Width > half {
401+
t.Errorf("%s: the box holding %q (placeholder %q) is %.0f px of a %d px column, and only a path is allowed the row",
402+
tab, box.Text, box.PlaceHolder, box.Size().Width, parts.ColumnWidth)
403+
}
404+
})
405+
}
406+
// The boxes the owner named, by name, so a screen that stopped drawing
407+
// one of them is a red guard and not a smaller count.
408+
for _, named := range []struct{ tab, label string }{
409+
{text.TabOneTarget(), text.FieldTargetID()},
410+
{text.TabOneTarget(), text.FieldNameTemplate()},
411+
{text.TabPresets(), text.SettingLabel("spread")},
412+
{text.TabRecipe(), text.FieldManifest()},
413+
{text.TabRecipe(), text.FieldGroup()},
414+
{text.TabRecipe(), text.SettingLabel("password")},
415+
} {
416+
screen := selectTab(t, host.content, named.tab)
417+
layOut()
418+
control := controlUnder(screen, named.label)
419+
if control == nil {
420+
t.Errorf("%s: no field is labelled %q, so its width cannot be measured", named.tab, named.label)
421+
continue
422+
}
423+
if width := typedInWidth(control); width == 0 || width > half {
424+
t.Errorf("%s: the box under %q is %.0f px wide (nought is a box not on the screen)", named.tab, named.label, width)
425+
}
426+
}
427+
if checked < 6 || paths < 3 {
428+
t.Fatalf("checked %d boxes and %d paths across three screens, which is not the whole window", checked, paths)
429+
}
430+
t.Logf("%d boxes held under half the column, %d paths allowed the row", checked, paths)
431+
}

0 commit comments

Comments
 (0)