Re: [PATCH] phonesim: fix exporting of child widgets to javascript engine
Andres Salomon <[email protected]> Fri, 27 Feb 2026 16:27:21 -0500
| Newsgroups | dev.linux.lists.ofono |
|---|---|
| Message-ID | <[email protected]> |
BTW Marcel, I noticed in the latest phonesim release (2.1) that the
tarball dropped the doc/scriptable.txt file. Was this unintentional, or
is the javascript interface being deprecated?
If it's not being deprecated, I'd love some feedback on this patch. :)
On 12/29/25 03:10, Andres Salomon wrote:
> Using the example sms.js script in doc/scriptable.txt, the following
> error occurs with phonesim built using Qt5.15:
>
> Error org.ofono.phonesim.Error.ScriptExecError: /tmp/sms.js, line 1, TypeError: Cannot read property 'leMessageSender' of undefined
>
> This is due to phonesim creating javascript objects for all the gui
> tab widgets, but none of the child widgets inside of those tabs. So
> in the javascript engine, 'tabSMS' is available, but its child widget
> 'gbMessage1' is undefined.
>
> I'm not sure if this is related to behavior changes in current versions
> of QJSEngine/UIC or what, but we can manually add all those widgets
> to the javascript engine to fix this.
> ---
> src/control.cpp | 25 +++++++++++++++++++++++++
> src/control.h | 2 ++
> 2 files changed, 27 insertions(+)
>
> diff --git a/src/control.cpp b/src/control.cpp
> index 817a0b2..b85e9ad 100644
> --- a/src/control.cpp
> +++ b/src/control.cpp
> @@ -637,32 +637,57 @@ void ControlWidget::modemSilentReset()
> emit unsolicitedCommand("+CRST:");
> }
>
> +/*
> + * Recursively add all widgets in a controlbase.ui tab to the javascript
> + * engine so that scripts can reference them. Because the widgets
> + * aren't local to this function, they should remain in scope while the
> + * script executes.
> + */
> +void Script::AddChildren(const QWidget *parentW, QJSValue &parentJS)
> +{
> + QList<QWidget*> kids = parentW->findChildren<QWidget*>(QString(),
> + Qt::FindDirectChildrenOnly);
> + foreach (QWidget *w, kids) {
> + QJSValue obj = engine.newQObject(w);
> + parentJS.setProperty(w->objectName(), obj);
> + AddChildren(w, obj);
> + }
> +}
> +
> Script::Script(QObject *obj, Ui_ControlBase *ui) : QDBusAbstractAdaptor(obj)
> {
> /* Export tabs to be accessed by script */
> QJSValue qsTab = engine.newQObject(ui->tab);
> engine.globalObject().setProperty("tabRegistration", qsTab);
> + AddChildren(ui->tab, qsTab);
>
> QJSValue qsTab2 = engine.newQObject(ui->tab_2);
> engine.globalObject().setProperty("tabCBM", qsTab2);
> + AddChildren(ui->tab_2, qsTab2);
>
> QJSValue qsTab3 = engine.newQObject(ui->tab_3);
> engine.globalObject().setProperty("tabSMS", qsTab3);
> + AddChildren(ui->tab_3, qsTab3);
>
> QJSValue qsTab4 = engine.newQObject(ui->tab_4);
> engine.globalObject().setProperty("tabVoiceMail", qsTab4);
> + AddChildren(ui->tab_4, qsTab4);
>
> QJSValue qsTab5 = engine.newQObject(ui->tab_5);
> engine.globalObject().setProperty("tabUSSD", qsTab5);
> + AddChildren(ui->tab_5, qsTab5);
>
> QJSValue qsTab6 = engine.newQObject(ui->tab_6);
> engine.globalObject().setProperty("tabSIM", qsTab6);
> + AddChildren(ui->tab_6, qsTab6);
>
> QJSValue qsTab8 = engine.newQObject(ui->tab_8);
> engine.globalObject().setProperty("tabPosition", qsTab8);
> + AddChildren(ui->tab_8, qsTab8);
>
> QJSValue qsTab9 = engine.newQObject(ui->tab_9);
> engine.globalObject().setProperty("tabCall", qsTab9);
> + AddChildren(ui->tab_9, qsTab9);
> }
>
> void Script::SetPath(const QString &path, const QDBusMessage &msg)
> diff --git a/src/control.h b/src/control.h
> index be4a366..c160d61 100644
> --- a/src/control.h
> +++ b/src/control.h
> @@ -57,6 +57,8 @@ public slots:
> QString Run(const QString &name, const QDBusMessage &msg);
>
> private:
> + void AddChildren(const QWidget *parentW, QJSValue &parentJS);
> +
> QString dirPath;
> QJSEngine engine;
> };