mirror of
https://github.com/logos-co/logos-app-poc.git
synced 2026-08-27 18:01:13 +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.
88 lines
2.5 KiB
C++
88 lines
2.5 KiB
C++
#include "ShellHostAdapter.h"
|
|
|
|
#include "MainUIBackend.h"
|
|
|
|
#include <QWidget>
|
|
|
|
ShellHostAdapter::ShellHostAdapter(MainUIBackend* backend, QObject* parent)
|
|
: QObject(parent)
|
|
, m_backend(backend)
|
|
{
|
|
if (!m_backend) {
|
|
qFatal("ShellHostAdapter requires a MainUIBackend instance");
|
|
}
|
|
|
|
// Signal → observer translation, guarded on m_observer: the shell detaches
|
|
// in destroyShell(), but PluginLoader's QTimer::singleShot(0, ...) and a 30s
|
|
// ViewModuleHost timeout can still deliver a backend signal afterwards.
|
|
connect(m_backend, &MainUIBackend::currentActiveSectionIndexChanged, this, [this]() {
|
|
if (!m_observer || !m_backend) return;
|
|
m_observer->onSectionIndexChanged(m_backend->currentActiveSectionIndex());
|
|
});
|
|
|
|
connect(m_backend, &MainUIBackend::navigateToApps, this, [this]() {
|
|
if (!m_observer) return;
|
|
m_observer->onNavigateToApps();
|
|
});
|
|
|
|
connect(m_backend, &MainUIBackend::pluginWindowRequested, this,
|
|
[this](QWidget* widget, const QString& title) {
|
|
if (!m_observer) return;
|
|
m_observer->onPluginWindowRequested(widget, title);
|
|
});
|
|
|
|
connect(m_backend, &MainUIBackend::pluginWindowRemoveRequested, this,
|
|
[this](QWidget* widget) {
|
|
if (!m_observer) return;
|
|
m_observer->onPluginWindowRemoveRequested(widget);
|
|
});
|
|
|
|
connect(m_backend, &MainUIBackend::pluginWindowActivateRequested, this,
|
|
[this](QWidget* widget) {
|
|
if (!m_observer) return;
|
|
m_observer->onPluginWindowActivateRequested(widget);
|
|
});
|
|
}
|
|
|
|
ShellHostAdapter::~ShellHostAdapter() = default;
|
|
|
|
QObject* ShellHostAdapter::backendObject()
|
|
{
|
|
return m_backend.data();
|
|
}
|
|
|
|
int ShellHostAdapter::currentSectionIndex() const
|
|
{
|
|
return m_backend ? m_backend->currentActiveSectionIndex() : 0;
|
|
}
|
|
|
|
void ShellHostAdapter::setCurrentSectionIndex(int index)
|
|
{
|
|
if (m_backend) m_backend->setCurrentActiveSectionIndex(index);
|
|
}
|
|
|
|
void ShellHostAdapter::loadUiModule(const QString& name)
|
|
{
|
|
if (m_backend) m_backend->loadUiModule(name);
|
|
}
|
|
|
|
void ShellHostAdapter::unloadUiModule(const QString& name)
|
|
{
|
|
if (m_backend) m_backend->unloadUiModule(name);
|
|
}
|
|
|
|
void ShellHostAdapter::setCurrentVisibleApp(const QString& name)
|
|
{
|
|
if (m_backend) m_backend->setCurrentVisibleApp(name);
|
|
}
|
|
|
|
QString ShellHostAdapter::displayNameFor(const QString& name) const
|
|
{
|
|
return m_backend ? m_backend->displayNameFor(name) : name;
|
|
}
|
|
|
|
void ShellHostAdapter::setObserver(IShellObserver* observer)
|
|
{
|
|
m_observer = observer;
|
|
}
|