mxcli version: main at 643271e8 (Mendix 11.12.1, MPR v2, macOS)
Summary
Running the layout examples added in #1157 (mdl-examples/doctype-tests/02c-complex-layout-examples.mdl) through exec and reading the coordinates back with describe: 15 pairs of elements overlap, in 3 of the 6 flows. mx check reports 0 errors either way, so nothing automatic sees it.
Repro
./bin/mxcli exec mdl-examples/doctype-tests/02c-complex-layout-examples.mdl -p App.mpr
./bin/mxcli -p App.mpr -c "DESCRIBE MICROFLOW CxLayout.CX_SYNC_FactoryTelemetry"
Three shapes, each an example from that file:
| Where |
Coordinates on 643271e8 |
Problem |
CX_SYNC_FactoryTelemetry, after merge rejoin2 |
merge (850, 200), next activity (930, 200) |
80 px apart: the merge's right edge and the activity's left edge are the same line |
CX_ACT_HandleAuthCode, end of a case branch |
set $Success (2855, 200), the split's merge (2885, 200) |
30 px apart — the activity covers the merge |
CX_SYNC_FactoryTelemetry, nested decisions |
set $Outcome (2365, 300), the outer else at (2475, 350) |
the two lanes are 50 px apart where an activity is 60 tall |
Cause
Three fixed-size disagreements between what measureStatements predicts and where the builder places things. Every merge, every following statement and every branch lane is positioned from the first and drawn by the second, so a few pixels of disagreement is an overlap, not a cosmetic difference.
- A split is measured to its branch, not to the merge that closes it.
measureIfStatement and measureEnumSplitStatement return SplitWidth + HorizontalSpacing/2 + branchWidth + MergeSize, which is 25 px short of the distance from the split's left edge to the merge's right edge.
- The advance past a merge treats it as an activity's width.
fb.posX = mergeX + HorizontalSpacing/2 (enum split) and fb.posX += fb.spacing/2 (addMergeStatement) move half a pitch from the merge's centre; a merge is MergeSize = 40 wide against an activity's 120, so the gap comes out 0. addIfStatement uses mergeX + MergeSize + HorizontalSpacing/2 and is right.
- A branch lane is placed half the branch's measured height below the line. That holds only for content centred on its line. A branch containing a nested
if hangs entirely below its own: measured 160 tall, it occupies 30 above the line and 130 below, so the next lane lands 50 px inside it.
All three predate the layout work in #1155 — they were covered by slack in the spacing that #1155 removed, which is why they surface now.
Fix
I have a branch that removes all three, geometry only:
- measure a split from its left edge to the merge's right edge;
- clear the merge, then leave the ordinary gap, in the two places that did not;
- place a lane below what the branch above actually occupies — it is already built by then, the same approach
separateRows already uses for wrapped rows.
Result on the same file: 15 overlapping pairs → 0. The three describe reports afterwards are each one activity printed twice at the same coordinates by the shared-tail traversal (see the note at the end), not two elements on the canvas. mx check 0 errors, make test and the integration suite pass.
Two new tests hold the invariant rather than the pixel values: one asks the measurer and the builder the same question about the same run and compares, the other asserts directly that no two elements of a built flow overlap, over eight shapes. Each of the three fixes was reverted in turn to confirm the tests fail with the symptom above.
Happy to open the PR.
Separate observation, not part of this
describe → exec of CX_SYNC_FactoryTelemetry does not round-trip: the shared tail after merge shared4 is printed twice, the labels are renumbered (join finish comes back as join shared3), and the re-executed model fails mx check with [error] [CE0773] "Value must be of type Boolean." at Sequence flow. Reproduced identically on the v0.23.0 release binary, so it is not from the layout work. I can file it separately if useful.
mxcli version: main at
643271e8(Mendix 11.12.1, MPR v2, macOS)Summary
Running the layout examples added in #1157 (
mdl-examples/doctype-tests/02c-complex-layout-examples.mdl) throughexecand reading the coordinates back withdescribe: 15 pairs of elements overlap, in 3 of the 6 flows.mx checkreports 0 errors either way, so nothing automatic sees it.Repro
Three shapes, each an example from that file:
643271e8CX_SYNC_FactoryTelemetry, aftermerge rejoin2(850, 200), next activity(930, 200)CX_ACT_HandleAuthCode, end of acasebranchset $Success(2855, 200), the split's merge(2885, 200)CX_SYNC_FactoryTelemetry, nested decisionsset $Outcome(2365, 300), the outerelseat(2475, 350)Cause
Three fixed-size disagreements between what
measureStatementspredicts and where the builder places things. Every merge, every following statement and every branch lane is positioned from the first and drawn by the second, so a few pixels of disagreement is an overlap, not a cosmetic difference.measureIfStatementandmeasureEnumSplitStatementreturnSplitWidth + HorizontalSpacing/2 + branchWidth + MergeSize, which is 25 px short of the distance from the split's left edge to the merge's right edge.fb.posX = mergeX + HorizontalSpacing/2(enum split) andfb.posX += fb.spacing/2(addMergeStatement) move half a pitch from the merge's centre; a merge isMergeSize= 40 wide against an activity's 120, so the gap comes out 0.addIfStatementusesmergeX + MergeSize + HorizontalSpacing/2and is right.ifhangs entirely below its own: measured 160 tall, it occupies 30 above the line and 130 below, so the next lane lands 50 px inside it.All three predate the layout work in #1155 — they were covered by slack in the spacing that #1155 removed, which is why they surface now.
Fix
I have a branch that removes all three, geometry only:
separateRowsalready uses for wrapped rows.Result on the same file: 15 overlapping pairs → 0. The three
describereports afterwards are each one activity printed twice at the same coordinates by the shared-tail traversal (see the note at the end), not two elements on the canvas.mx check0 errors,make testand the integration suite pass.Two new tests hold the invariant rather than the pixel values: one asks the measurer and the builder the same question about the same run and compares, the other asserts directly that no two elements of a built flow overlap, over eight shapes. Each of the three fixes was reverted in turn to confirm the tests fail with the symptom above.
Happy to open the PR.
Separate observation, not part of this
describe→execofCX_SYNC_FactoryTelemetrydoes not round-trip: the shared tail aftermerge shared4is printed twice, the labels are renumbered (join finishcomes back asjoin shared3), and the re-executed model failsmx checkwith[error] [CE0773] "Value must be of type Boolean." at Sequence flow. Reproduced identically on the v0.23.0 release binary, so it is not from the layout work. I can file it separately if useful.