Bug 340125

Summary: workspace.clientList() doesn't work in declarativescript
Product: [Plasma] kwin Reporter: Fabian Homborg <FHomborg>
Component: scriptingAssignee: KWin default assignee <kwin-bugs-null>
Status: RESOLVED FIXED    
Severity: normal CC: bugs.kde.org, github
Priority: NOR    
Version: 5.1.0   
Target Milestone: ---   
Platform: Arch Linux   
OS: Linux   
URL: https://github.com/faho/kwin-tiling/tree/plasma5
Latest Commit: Version Fixed In: 5.8.4
Sentry Crash Report:
Attachments: kwinscript to test this functionality

Description Fabian Homborg 2014-10-19 16:23:17 UTC
When I call workspace.clientList() in a declarativescript script, it errors out with the message:

>Error: Unknown method return type: QList<KWin::Client*>

In a javascript script (like the ones shipped with KWin), it works.


Reproducible: Always

Steps to Reproduce:
1. Make declarativescript (like the tiling script)
2. Call workspace.clientList()


Expected Results:  
I can work with the clientList

(There are some other discrepancies/bugs related to declarativescript, including other inacessible functions, I'll open separate bugs for all of those)
Comment 1 Martin Flöser 2014-10-19 16:26:39 UTC
hmm that's annoying :-( declarativescripts use the new scripting system in Qt. 
Might be it's not up to the task.

It would be totally awesome if you could provide some small examples for the 
bugs your going to report.
Comment 2 Fabian Homborg 2014-10-19 17:20:36 UTC
Sure, but keep in mind that I'm not sure which are my fault (or rather semantic changes that I need to react to). One example for that is that I thought inheritance was borked, which was caused by Qt.include (currently the only QML-thing I use) working differently now. I'd rather try to reproduce once too often than bug you with invalid bug reports.

Now for the things that are probably bugs:

A big part is (seeming) API changes - readConfig is accesible through KWin.readConfig now,

Another is that I can't find register{Shortcut,UserActionsMenu}, assertTrue. min/maxSizes now look different (and I just caused a crash by fiddling around with them, so I'd rather send this now). 

All in all, this one is the biggest, followed by registerShortcut.
Comment 3 github 2016-10-26 17:20:34 UTC
Cool if you check http://stackoverflow.com/questions/27312189/expose-qlistqobject-hierarchy-to-qml it provides a way to get this working in declarative script.

Martin: I couldn't find where the "workspace" property is set for declarative script, I assume in the DeclarativeScript constructor that it is copied from the qmlEngine when QQmlContext is constructed? If so then I'm worried that if I modify the "clientList()" interface to work via QQmlListProperty that I'll break it for javascript? I understand a fair bit of Qml now but I'm not sure how the clientList() interface works in the pure javascript mode.
Comment 4 Martin Flöser 2016-10-27 05:38:50 UTC
> I couldn't find where the "workspace" property is set for declarative script,

It's in KWin::Scripting::init()

m_qmlEngine->rootContext()->setContextProperty(QStringLiteral("workspace"), m_workspaceWrapper);

We might need to split the WorkspaceWrapper into a QScript variant and a QmlScript variant.
Comment 5 github 2016-10-27 09:44:11 UTC
Okay that's as I expected, how come JavaScript can convert from QList<KWin*> and declarativescript can't? Can both scripting systems not work via QQmlListProperty?
Comment 6 Martin Flöser 2016-10-27 10:47:33 UTC
(In reply to kdebugs from comment #5)
> Okay that's as I expected, how come JavaScript can convert from QList<KWin*>
> and declarativescript can't?

I have no idea. It used to work with Qt 4.

> Can both scripting systems not work via
> QQmlListProperty?


No, QtScript doesn't support it. What we can in long term try is to remove the QtScript variant and only use the declarative scripts also for javascript scripts.
Comment 7 github 2016-10-27 19:42:35 UTC
Cool. In the short term I could turn WorkspaceWrapper into WorkspaceWrapperAbstract and then move the existing clientList()into QtScriptWorkspaceWrapper and a declarativescript specific version into DeclarativeScriptWorkspaceWrapper. Then I can set a new workspace via DeclarativeScript::m_context which will mask the QtScript specific version in the root context. Or maybe the root context can be avoided for "workspace" altogether?
Comment 8 github 2016-10-27 23:45:49 UTC
I've got this working now except:

    Q_INVOKABLE QQmlListProperty<KWin::Client> clientList();

Using that `workspace.clientList().length` doesn't work right (nor does indexing). I have to use:

    Q_PROPERTY(QQmlListProperty<KWin::Client> clientList READ clientList)

And access it via `workspace.clientList.length`

I can submit the code as it is for a review, maybe there's a way to make the former work.
Comment 9 github 2016-10-28 01:04:29 UTC
Submitted code review at https://phabricator.kde.org/differential/diff/7713/

I managed to work around the limitation with QQmlListProperty having to be a property by using QQmlExpression. I also use a shared context as the parent of each declarative script's individual context so that workspace can be shared. Perhaps the "KWin" global should also be placed in that shared context, this would mimic how the javascript version works. That can be handled in a different commit anyway.
Comment 10 github 2016-10-28 01:11:19 UTC
Created attachment 101845 [details]
kwinscript to test this functionality
Comment 11 github 2016-10-28 13:32:29 UTC
This kwinscript can also be used to test my patch: https://github.com/ohjames/kwin-window-switch

It requires my registerShortcut patch also.
Comment 12 github 2016-11-03 00:30:56 UTC
Git commit 4730be084c1b071db5b0869f13e6c444a35e2fb3 by James Pike.
Committed on 02/11/2016 at 23:31.
Pushed by pikejames into branch 'Plasma/5.8'.

Support for workspace.clientList() in declarative script

Summary:
The version provided is only compatible with QtScript so it became
necessary to split WorkspaceWrapper into a base class and two child
classes, one for QtScript and one for QmlScript.
FIXED-IN: 5.8.4
REVIEW: D3185

M  +1    -1    scripting/scriptedeffect.cpp
M  +10   -3    scripting/scripting.cpp
M  +19   -4    scripting/scripting.h
M  +26   -4    scripting/workspace_wrapper.cpp
M  +29   -4    scripting/workspace_wrapper.h

http://commits.kde.org/kwin/4730be084c1b071db5b0869f13e6c444a35e2fb3