mirror of
https://github.com/logos-co/logos-basecamp.git
synced 2026-08-27 14:51:07 +00:00
Measured on the built artefact: main_ui.dylib DEFINES zero and IMPORTS zero of
TokenManager, StoreRegistry, LogosAPI, LogosAPIClient and logos_core_*, out of
3410 symbols read. It links Qt and nothing else from this workspace, which
nix/symbol-gate.nix enforces across the in-process image set.
Getting there needed the last non-Qt types off the boundary: the model
properties cross as QAbstractItemModel*, catalogInstallStageChanged carries an
int rather than InstallStage::Value, and the two prebuilt AppsFilterProxy
instances are declared in QML instead of owned by MainUIBackend. That last one
removes a real inversion -- PackageCoordinator called setRequiredPackages() on
a proxy the host held a pointer to; it now emits requiredPackagesResolved() and
QML binds to the republished property.
Window resolves the plugin, qobject_casts it to IShellView, checks
hostAbiVersion() against IShellHost_abi, and calls createShell(IShellHost*).
No error-label fallback widget: that degraded to something that looked like a
working app with an empty window.
Filter proxies read role constants off host-side models and InstallEnums is
used by nine host files, so app/interfaces/ gains the contract headers both
sides compile against -- the models inherit the role structs, leaving every
AppsModel::NameRole call site unchanged. The plugin's include path is
app/interfaces only, so including a host header does not compile.
Four things only running it finds:
* Logos::DesignSystem may be linked by exactly ONE image -- both linked it
and the app aborted with "Cannot add multiple registrations for
Logos.Icons"; QML module registration is process-global
* qmltyperegistrar emits no #include for a SOURCES header given as an
absolute path outside the project
* each qt_add_qml_module is its own target and inherits no include dirs
* AUTOMOC pairs header<->cpp by same-basename-same-DIRECTORY, which the
split breaks
tst_AppManagerView.qml grows five tests for the QML binding, checked with a
negative control: breaking one assertion fails qml-tests, so they run.
51 lines
2.4 KiB
C++
51 lines
2.4 KiB
C++
#pragma once
|
|
|
|
#include "IShellHost.h"
|
|
|
|
#include <QObject>
|
|
#include <QPointer>
|
|
#include <QString>
|
|
|
|
class MainUIBackend;
|
|
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
// ShellHostAdapter — the host's side of the shell boundary. Implements
|
|
// IShellHost over MainUIBackend and translates its five signals into
|
|
// IShellObserver calls; every operation is a one-line delegation.
|
|
//
|
|
// It exists so the shell never names MainUIBackend, whose header pulls in
|
|
// InstallEnums, the models and logos_api.h and whose signals carry
|
|
// InstallStage::Value — none of which a Qt-only shell could compile against.
|
|
//
|
|
// Owned by Window, alongside the MainUIBackend it wraps.
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
class ShellHostAdapter : public QObject, public IShellHost {
|
|
Q_OBJECT
|
|
|
|
public:
|
|
// `backend` is borrowed; Window owns both and destroys this adapter first.
|
|
explicit ShellHostAdapter(MainUIBackend* backend, QObject* parent = nullptr);
|
|
~ShellHostAdapter() override;
|
|
|
|
// ── IShellHost ──────────────────────────────────────────────────────────
|
|
QObject* backendObject() override;
|
|
int currentSectionIndex() const override;
|
|
void setCurrentSectionIndex(int index) override;
|
|
void loadUiModule(const QString& name) override;
|
|
void unloadUiModule(const QString& name) override;
|
|
void setCurrentVisibleApp(const QString& name) override;
|
|
QString displayNameFor(const QString& name) const override;
|
|
void setObserver(IShellObserver* observer) override;
|
|
|
|
private:
|
|
// QPointer: Window deletes the backend during teardown, and a queued
|
|
// backend signal can still be in flight when it does.
|
|
QPointer<MainUIBackend> m_backend;
|
|
|
|
// Raw: IShellObserver is not a QObject, so QPointer cannot track it.
|
|
// destroyShell() nulls it; forwards are guarded anyway, since
|
|
// QTimer::singleShot(0, ...) and a 30s ViewModuleHost timeout can both
|
|
// fire after teardown has begun.
|
|
IShellObserver* m_observer = nullptr;
|
|
};
|