mirror of
https://github.com/logos-co/logos-view-module-runtime.git
synced 2026-08-27 11:01:13 +00:00
* feat(bridge): a QML view's bridge carries ITS identity, not the host's The QML a view module ships runs inside the host process, and the bridge it was handed was the host's own LogosAPI — which carries the host's ambient token ring, holding every loaded module's root auth token. A view could reach any module in the system with no requestModule in the log at all. LogosQmlBridge::forIdentity(name) builds the bridge on a LogosAPI bound to that identity's ISOLATED store, and returns nullptr rather than falling back to the host's authority. tokenStore() exposes the store a bridge presents from, because that — not the name — is the identity that decides anything. tests/test_bridge_identity.cpp is the acceptance test: two real published providers, an ambient ring seeded the way module_manager seeds it, and a capability_module that mints only for declared (origin, target) pairs. A host-identity bridge reaches an undeclared backend with requestModuleCalls == 0; an identity bridge is refused. * feat(b4): link the Qt host runtime from logos-plugin-qt, not logos-qt-sdk The B1 split moved the Qt host runtime — LogosAPI and the provider objects — out of logos-qt-sdk into logos-plugin-qt, which publishes it as packages.<sys>.logos-qt-host with the CMake target logos-qt-host::logos_qt_host. This repo now consumes that target directly, so B2b can delete the forwarding shim in logos-qt-sdk. logos-qt-sdk is dropped as an input entirely rather than kept alongside: the host runtime was the only thing this repo ever took from it. logos_api.h is the single qt-sdk-provided header anything here includes; every other non-Qt header on the include lines (token_manager.h, logos_api_client.h, module_proxy.h, remote_transport.h, logos_instance.h, logos_mode.h, logos_types.h, logos_json_convert.h, logos_call_error.h, logos_object.h, logos_provider_interface.h) comes from logos-protocol, which logos-qt-host links PUBLIC. Nothing here touches the surface that stays behind in qt-sdk — no logos_ui_plugin_context.h (that is for ui_qml module backends, not for the host that loads them), no logos_qt_lp_bridge.h / logos_qt_wire.h, no logos-qt-generator. LOGOS_QT_SDK_ROOT becomes LOGOS_QT_HOST_ROOT, matching what logos-standalone-app already passes. Because a find_package that resolves to the wrong prefix would leave the target undefined and every LogosAPI symbol unresolved at link time — an error a long way from its cause — the import is followed by an explicit TARGET check that is a FATAL_ERROR, never a skip. Evidence the swap is a no-op for the produced artifacts: with the same inputs, lib/liblogos_view_module_runtime.a is byte-identical (md5 2e205e1668f57f59fd5ccfc005a26600) before and after, bin/.ui-host-wrapped is byte-identical, the installed headers are identical, and the 317 LogosAPI symbols in the ui-host binary are unchanged. The only difference in the derivation is that logos-qt-sdk.drv left the input closure and logos-qt-host-0.1.0.drv took its place. checks.default runs the same six ctest cases (LogosQmlBridgeUnitTests, LogosQmlBridgeE2ETests, LogosQmlBridgeGuiTests, LogosQmlBridgeResultTests, LogosQmlBridgeHandshakeTests, BridgeIdentityTests), 6/6 passing on both sides. * docs: name the check that holds these headers to the module side LogosViewPlugin and LogosViewReplicaFactory are the HOST half of a pair. The module half is declared separately, by logos-plugin-qt's LogosView*.in templates, and the two cannot share a header: a module plugin must compile against Qt alone, and this repo depends on logos-plugin-qt, so the include could only ever point the wrong way. They bind at runtime through the IID string, where a mismatch is silent — qobject_cast returns nullptr and the view never appears. The module-side copy used to carry a comment asking whoever edited it to keep these files in sync. It pointed at src/; the files are in include/. That is what a sync comment is worth. logos-module-builder — the one repo that depends on both sides — now runs a `view-interface-abi` check in CI comparing the IID and the pure-virtual list. These headers say so, so an editor of this half knows what will catch them. No code change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs: say what the ABI check reads, and that nothing here runs it The note pointed at logos-module-builder's `view-interface-abi` and described it as comparing "the IID and the pure-virtual list". That undersold it and, more importantly, it did not say that the argument of Q_DECLARE_INTERFACE below is itself compared after resolution — that macro argument is the string qobject_cast matches on, it does not have to be the #define above it, and changing just that one token is a real divergence. Also states the thing that is easy to miss from inside this repo: there is no .github here, so nothing checks these headers at the moment they are edited. The check first sees a change when logos-module-builder bumps its pin. Editing this header is a two-repo change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * chore(deps): rev-pin logos-plugin-qt and logos-protocol at the pushed tips Both inputs were master-tracking, and neither master can build this repo after the qt-host retarget: * logos-plugin-qt's master (8846fc5) has no `logos-qt-host` package at all — evaluation died with "attribute 'logos-qt-host' missing" at flake.nix:48. cc24fa1 is the tip of that repo's feat/b4-qt-host-windows-target, already rebased onto its master, and is the SUPERSET of the two branches carrying the qt-host work: the sibling feat/b4-qt-host-windows-target-8ccb1fc (989f6ae) drops the commits logos-module-builder pins. Pinning the superset is what keeps ONE logos-qt-host in the downstream closure rather than two. * logos-protocol had to move with it. logos-qt-host calls TokenManager::forIdentity / isolateIdentity, which are on feat/per-client-token-store (c8bab12) and not on protocol master — and because logos-plugin-qt's logos-protocol `follows` THIS input, leaving it master-tracking would have built the Qt host runtime against a protocol lacking those symbols. c8bab12 is a fast-forward from master, so nothing is given up. Both revs are pushed branch tips, not local-only commits. Drop the revs once the branches merge. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(tests): retarget the two tests master added onto logos-qt-host Rebasing this branch onto master replayed the qt-host retarget over a master that had meanwhile added test_logos_qml_bridge_deferred (#20) and test_logos_qml_bridge_calls (#21). Both link logos-qt-sdk::logos_qt_sdk, and the retarget commit never saw them, so the textual auto-merge left them pointing at a target this repo no longer imports. CMake failed the generate step outright: Target "test_logos_qml_bridge_calls" links to: logos-qt-sdk::logos_qt_sdk but the target was not found. Retargeted to logos-qt-host::logos_qt_host, the same rename the other eight executables already carry. Restoring the logos-qt-sdk input was the wrong fix in the other direction: it would put a second copy of the Qt host runtime back in the closure, which is what the retarget exists to prevent. Both tests only include logos_api.h (now from qt-host) and the protocol headers qt-host links PUBLIC, so nothing qt-sdk-only is lost. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs: the module-side templates live in logos-view-module now Both host-side interface headers named logos-plugin-qt/cmake/LogosView*.h.in, a path that no longer exists — the view-authoring concerns moved to logos-view-module. LogosViewReplicaFactory.h also justified the split with "that repo is upstream of this one, so the two cannot share a header". That was true of logos-plugin-qt, which this repo really does depend on. It is false of logos-view-module: there is no edge between the two in either direction, which is the actual reason they cannot share a header, and is what logos-module-builder's view-interface-abi check now says. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * chore(deps): track protocol and plugin-qt master, and fix the check that was red logos-protocol#59 and logos-plugin-qt#19 merged, so both rev pins are retired. Also repairs this repo's ONLY check, which was already red before the pin work and would have kept the PR red regardless: tests/CMakeLists.txt linked logos-qt-sdk::logos_qt_sdk, a target that cannot exist since the split removed logos-qt-sdk as an input here. The other ten test targets already linked logos-qt-host::logos_qt_host —5510acdretargeted the two tests master had added, then the master merge in3ef779cbrought a third the retarget had not covered. Confirmed pre-existing rather than pin fallout with a control: a pristine `git archive HEAD` carrying the OLD pins fails with the byte-identical CMake error. checks.default builds green. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
48 lines
2.4 KiB
C++
48 lines
2.4 KiB
C++
#pragma once
|
|
|
|
#include <QtPlugin>
|
|
|
|
class QObject;
|
|
class QRemoteObjectNode;
|
|
class QMetaObject;
|
|
|
|
// The HOST side of this interface. The module side is declared separately, by
|
|
// logos-view-module/cmake/LogosViewReplicaFactory.h.in, which logos_module()
|
|
// instantiates into every ui_qml module — a module plugin has to compile
|
|
// against Qt alone, and there is no dependency edge between that repo and this
|
|
// one in either direction, so the two cannot share a header. (The template
|
|
// lived in logos-plugin-qt until the view-authoring concerns moved to
|
|
// logos-view-module, which owns the ui_qml flavour end to end.) They bind at runtime through the IID string alone, where a
|
|
// mismatch is silent: qobject_cast returns nullptr and the view never appears.
|
|
//
|
|
// That pair is CHECKED, not trusted: logos-module-builder (the one repo that
|
|
// depends on both) runs `view-interface-abi` in CI. It compares the IID
|
|
// `#define`, the RESOLVED argument of Q_DECLARE_INTERFACE below (the string
|
|
// qobject_cast actually compares — it need not be the macro), this class's
|
|
// base list, and its ordered pure-virtual list; and on the module side it
|
|
// also checks the concrete plugin class's Q_PLUGIN_METADATA IID and
|
|
// Q_INTERFACES against the IID declared here. Editing this class, or just
|
|
// that macro argument, without editing the template turns the check red.
|
|
//
|
|
// This repo has no CI of its own, so the check does not run on changes to
|
|
// THIS file at the time they are made — it runs when logos-module-builder
|
|
// next bumps its logos-view-module-runtime pin. Editing this header is
|
|
// therefore a two-repo change: land it, then bump the pin there.
|
|
//
|
|
// A tiny Qt plugin interface that lets a view module ship a typed
|
|
// QRemoteObjectReplica factory alongside its backend plugin. The host loads
|
|
// the factory via QPluginLoader and asks it to construct a replica from a
|
|
// QRemoteObjectNode — the returned QObject has a real static metaobject
|
|
// (generated by `repc`) so QML's QObjectWrapper caches a correct property
|
|
// cache and all the dynamic-replica QML quirks go away.
|
|
class LogosViewReplicaFactory {
|
|
public:
|
|
virtual ~LogosViewReplicaFactory() = default;
|
|
|
|
virtual QObject* acquire(QRemoteObjectNode* node) = 0;
|
|
virtual const QMetaObject* replicaMetaObject() const = 0;
|
|
};
|
|
|
|
#define LogosViewReplicaFactory_iid "logos.view.replica_factory/1.0"
|
|
Q_DECLARE_INTERFACE(LogosViewReplicaFactory, LogosViewReplicaFactory_iid)
|