Skip to content

Fix five open bugs: stretch sharing, env values, state any, grid clipping, sidebar tones - #1088

Merged
Yaraslaut merged 8 commits into
masterfrom
fix/bugs-1068-1067-1056-1086-1078
Nov 5, 2026
Merged

Yaraslaut merged 8 commits into
masterfrom
fix/bugs-1068-1067-1056-1086-1078

Conversation

@Yaraslaut

@Yaraslaut Yaraslaut commented Nov 5, 2026 •

Copy link
Copy Markdown
Member

Fixes five of the six open bugs on one branch, and adds measurements to the sixth (#1083), which stays open because its closing test needs a Qt release that isn't out yet.

Changes

Issues closed by this PR:

Fixes #1068
Fixes #1067
Fixes #1056
Fixes #1086
Fixes #1078

Still open: #1083

The workaround already on master (QV4_GC_TIMELIMIT=0) stays, and so does the issue. No code changes here. Measured on 122b09fff, 16 runs in parallel, counting SIGSEGV only:

Qt Slice Crashes
6.12.0 1 ms 4/32
6.12.0 5 ms 5/32
6.12.0 workaround 0/32
6.8.1 1 ms 0/64
6.8.1 5 ms 0/64

This strengthens the case for a Qt 6.12 defect, but it's still inferred: there is no plain-QML reproducer. Qt 6.12.1 isn't published, so the issue's closing test can't run.

Testing

CI on 543c97699: 27 checks pass and 1 is skipped (Publish the master compiler cache). That includes both Windows jobs, all Linux sanitizer jobs, clang-coverage, Docs and clang-tidy-diff. An earlier push failed clang-format, clang-tidy-diff and clang-coverage on this branch's changes (formatting, a preprocessor-style finding, drifted allowlist line hints), and those fixes are folded into the commits that own them. clang-ubsan also failed on that push when its runner ran out of disk at link time; it needed no code change and passes here.

Measured locally, not on the final head:

Not verified:

  • online end to end: Source-level online is covered with a fake source's hooks. The real SocketBackend hook has its own test, but no test runs the two together.
  • Gallery visuals: gallery tests pass, and two screens were checked by eye, with no baseline diff.
  • Review: per-ticket review was by reading each lane's diff. /code-review and /simplify were not run, to avoid the agent fan-out.

Related

Found during this work and filed separately: #1087, a horizontal scroll on Qt Quick stacks its children vertically. The new horizontal-scroll conformance case passes on both frontends for different reasons until that is settled.

🤖 Generated with Claude Code

https://claude.ai/code/session_01No1NzpAge5HHW2666MzjXS

Yaraslaut and others added 8 commits November 5, 2026 11:06
The loader gave an absent type and a declared `any` the same value, so a
state with `"type": "any"` took its init's type and a `set` of another
type was refused. StateDecl now records whether the document named a type,
and only a state with none takes its init's.

Fixes #1068

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01No1NzpAge5HHW2666MzjXS
Signed-off-by: Yaraslau Tamashevich <yaraslau.tamashevich@gmail.com>
The default theme's error and info tones are 2.76:1 and 2.70:1 on the dark
sidebar surface, below the 3:1 a graphic or large text needs, and a
navigator count with a tone is drawn there. The sidebar scheme now sets
ok, warn, err and info itself (colour, dot and border one value, fill that
at 15 %), each 4.45:1 or more on the surface. A test sweeps every tone on
every built-in surface and on its own fill and fails below 3:1.

Fixes #1067

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01No1NzpAge5HHW2666MzjXS
Signed-off-by: Yaraslau Tamashevich <yaraslau.tamashevich@gmail.com>
…dler

SocketBackend did not override IBackend::setDisconnectHandler, so the
default no-op swallowed any handler installed on it and a client over the
net transport never learned its connection had dropped. The handler is
stored on the I/O loop and run once per drop of an established connection,
before the pending calls are failed and before a reconnect is scheduled.
It does not run for a retry that fails to connect, nor for the backend's
own close. A handler that throws is logged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01No1NzpAge5HHW2666MzjXS
Signed-off-by: Yaraslau Tamashevich <yaraslau.tamashevich@gmail.com>
…client

A screen mounted by morph::client read null for `locale`, `platform` and
`online`, and for `backend` until a switch. `locale` is now always the
session's formatting locale (Session::setFormatting writes it, so setLocale
moves it and setEnvironment keeps it). The shell writes `platform` (the
build's target), `backend` (Source::backendName: local or remote) and
`online` before the first mount. `online` is Source::online, set from the
backend's connect and disconnect hooks, and each change reaches the session
through Source::onOnline.

Fixes #1056

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01No1NzpAge5HHW2666MzjXS
Signed-off-by: Yaraslau Tamashevich <yaraslau.tamashevich@gmail.com>
…estor keeps a cell's border

A select in the second column of a two-column grid in a dialog lost its right
border at the dialog's edge, with nothing logged. The select was not wider than
its column: a minimal dialog holding a two-column grid draws it at the
column's width (221.5 px at 63 units) and shrinks it with the dialog. The
column is half a pixel wide when the width the gap leaves is odd, so the second
cell started on a half pixel; it is drawn with its far edge a pixel out, which
the dialog's scroll area clips, and the border was the pixel cut. A select
beside it in a stack row and a lone select with the same right edge keep their
border, as a stack places its children on whole pixels.

MorphGrid.place now rounds each track's left and right edge, and a cell covers
the rounded edges of its tracks. The terminal places cells on whole cells
already. A grid gives each cell its track whatever the cell's own minimum, so
it has no overflow to report; the issue's premise of a minimum wider than the
column does not hold.

Fixes #1086

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01No1NzpAge5HHW2666MzjXS
Signed-off-by: Yaraslau Tamashevich <yaraslau.tamashevich@gmail.com>
…of its children

A panel, a collapsible, a scroll area, a slot, a tab page, an overlay and a
drop zone summed their children's natural extents, where a stack asked for
`W * max(n / w)` for its stretching children, so a content-sized one of them
held two stretch children of one and ten lines in 11 lines and shared them 5
and 6. `stackNaturalSize` now applies the stack's rule, so each share is at
least its child's natural, and a splitter, whose panes' sizes are its own,
keeps the plain sum under `summedNaturalSize`.

Refs #1078

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01No1NzpAge5HHW2666MzjXS
Signed-off-by: Yaraslau Tamashevich <yaraslau.tamashevich@gmail.com>
…one column

The panel, collapsible, scroll, slot, tab pages, dialog and drawer held their
content in a plain ColumnLayout, so a stretch-height child there still grew
from its own implicit height: two of one and eight lines came out as tall as
their content, and the natural height of the container was the sum of
theirs. They now hold it in MorphShareColumn, which gives each stretching child
(or spacer) a share of the column's height by weight from zero, held at its
bounds, and exposes naturalHeight, the rule the stack uses (others plus
W * max(n / w)), for the container to read in place of the layout's implicit
height, which sums the shares and follows the height it is given. The pass
loop and the natural rule move to MorphShares.js, which MorphStack uses too.

A column with no stretching child evaluates nothing per child but the check that it has none, so a long page or
scroll is not evaluated again when one child reflows.

Conformance cases run on both frontends for a panel, a dialog, a drawer, a tab
page, a horizontal scroll area, and a content-sized panel, scroll area, slot
and collapsible.

Fixes #1078

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01No1NzpAge5HHW2666MzjXS
Signed-off-by: Yaraslau Tamashevich <yaraslau.tamashevich@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01No1NzpAge5HHW2666MzjXS
Signed-off-by: Yaraslau Tamashevich <yaraslau.tamashevich@gmail.com>
@Yaraslaut
Yaraslaut force-pushed the fix/bugs-1068-1067-1056-1086-1078 branch from af08300 to 543c976 Compare November 5, 2026 10:12
@codecov

codecov Bot commented Nov 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.24561% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
include/morph/client/source.hpp 75.00% 1 Missing ⚠️
include/morph/net/socket_backend.hpp 92.85% 1 Missing ⚠️
include/morph/ui/testing/backend_conformance.hpp 99.28% 0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@Yaraslaut
Yaraslaut merged commit bdffdf2 into master Nov 5, 2026
28 checks passed
@Yaraslaut
Yaraslaut deleted the fix/bugs-1068-1067-1056-1086-1078 branch November 5, 2026 16:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment