Skip to content

forms: every DynamicForm warns about onOptionsReceived on any controller without a Choice field #387

Description

@Yaraslaut

DynamicForm.qml:1092-1129 declares one Connections block on the controller
with two handlers:

Connections {
    target: form.controller
    function onReplyReceived(actionType, ok, payload) { ... }
    function onOptionsReceived(optionsAction, ok, payload) { ... }
}

optionsReceived only exists on a controller that serves a
morph::forms::Choice field. A controller that serves none does not declare it
— and deliberately does not: bookmarks::gui::BookmarkFormsController's own
doc comment has a "No fetchOptions()" section saying that adding one with
nothing to call it "would be a stub with nothing to call it"
(examples/bookmarks/gui_lib/bookmark_forms_controller.hpp:62-69), and
PasteFormsController is cited there as the same case.

So the sanctioned shape produces a QML warning, once per form instance, as soon
as a real controller is attached:

qrc:/qt/qml/MorphForms/qml/DynamicForm.qml:1093:5: QML Connections: Detected
function "onOptionsReceived" in Connections element. This is probably intended
to be a signal handler but no signal of the target matches the name.

Verification status: reproduced

Measured at 1f7a4619 (branch scenario-corpus-both-axes), Qt 6.11.2,
QT_QPA_PLATFORM=offscreen, on a
-DMORPH_BUILD_FORMS_QML=ON -DMORPH_BUILD_LADDER=ON -DMORPH_LADDER_RUNGS=kanban
configure. It appears when examples/kanban's ProjectListView/BoardView are
loaded into a QQmlApplicationEngine with a live ProjectAdminBridge /
BoardBridge as an initial property — the new
examples/kanban/tests/test_gui_forms_render.cpp does exactly that, and had to
grow an explicit tolerance for this one warning text to keep its
"no other warning" assertion.

Why nobody has hit it before: every rung's rule-6 smoke test
(examples/TESTING.md) loads its roots with all controllers null. A
Connections block with a null target matches nothing and warns about
nothing, so the warning is invisible to the one QML test each rung ships.

Not verified: whether the desktop clients emit it at runtime. Inferred yes,
from the same code path (ladder_kanban_gui writes to stderr and I did not
capture per-warning output from a real session); not measured.

Why it matters beyond noise

The rung smoke tests assert "the engine emitted zero QML warnings" — that is the
whole assertion. The moment any rung tests a form against a real controller,
that assertion has to be weakened to "zero warnings except this one", which is
exactly the kind of tolerance that later swallows a real warning. It also means
a shipped, correct, documented controller shape cannot produce a clean log.

A shape for the fix

Either ignoreUnknownSignals: true on that block (the Qt-idiomatic answer for
an optional signal), or split the two handlers into two Connections blocks so
replyReceived — which every controller has — is unaffected. The second is
probably better: it keeps an actually-misspelled onReplyReceived loud.

What would change the verdict

Close when loading a form with a controller that serves no Choice field emits
no QML warning, with the assertion made by a test that fails without the fix
(the kanban test above can drop its tolerance and become that regression check).

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: formsSubsystem: formsbugSomething isn't workingtriage: rescopeReal problem, wrong framing; rewrite before building

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions