scripting: Make QTimer constructible

If a QObject is exposed to js using QJSEngine::newQMetaObject(), a new
instance of it can be made only with constructors exposed by Q_INVOKABLE

At the moment, QTimer's constructor is not Q_INVOKABLE, so code such as
`const timer = new QTimer()` will not work.

BUG: 439630
FIXED-IN: 5.22.4
This commit is contained in:
Vlad Zahorodnii 2021-07-19 12:12:06 +03:00
parent 73bfe648ef
commit d29954ae33
2 changed files with 19 additions and 1 deletions

View file

@ -92,6 +92,11 @@ void KWin::AbstractScript::stop()
deleteLater();
}
KWin::ScriptTimer::ScriptTimer(QObject *parent)
: QTimer(parent)
{
}
KWin::Script::Script(int id, QString scriptName, QString pluginName, QObject* parent)
: AbstractScript(id, scriptName, pluginName, parent)
, m_engine(new QJSEngine(this))
@ -167,7 +172,7 @@ void KWin::Script::slotScriptLoadedFromFile()
m_engine->installExtensions(QJSEngine::ConsoleExtension);
// Make the timer visible to QJSEngine.
QJSValue timerMetaObject = m_engine->newQMetaObject(&QTimer::staticMetaObject);
QJSValue timerMetaObject = m_engine->newQMetaObject(&ScriptTimer::staticMetaObject);
m_engine->globalObject().setProperty("QTimer", timerMetaObject);
// Expose enums.

View file

@ -18,6 +18,7 @@
#include <QStringList>
#include <QJSEngine>
#include <QJSValue>
#include <QTimer>
#include <QDBusContext>
#include <QDBusMessage>
@ -83,6 +84,18 @@ private:
bool m_running;
};
/**
* In order to be able to construct QTimer objects in javascript, the constructor
* must be declared with Q_INVOKABLE.
*/
class ScriptTimer : public QTimer
{
Q_OBJECT
public:
Q_INVOKABLE ScriptTimer(QObject *parent = nullptr);
};
class Script : public AbstractScript, QDBusContext
{
Q_OBJECT