Commit 02a05610 authored by Martin Flöser's avatar Martin Flöser

Add windowsystem plugin for KWin's qpa

Summary:
KWindowSystem provides a plugin interface to have platform specific
implementations. So far KWin relied on the implementation in
KWayland-integration repository.

This is something I find unsuited, for the following reasons:
 * any test in KWin for functionality set through the plugin would fail
 * it's not clear what's going on where
 * in worst case some code could deadlock
 * KWin shouldn't use KWindowSystem and only a small subset is allowed
to be used

The last point needs some further explanation. KWin internally does not
and cannot use KWindowSystem. KWindowSystem (especially KWindowInfo) is
exposing information which KWin sets. It's more than weird if KWin asks
KWindowSystem for the state of a window it set itself. On X11 it's just
slow, on Wayland it can result in roundtrips to KWin itself which is
dangerous.

But due to using Plasma components we have a few areas where we use
KWindowSystem. E.g. a Plasma::Dialog sets a window type, the slide in
direction, blur and background contrast. This we want to support and
need to support. Other API elements we do not want, like for examples
the available windows. KWin internal windows either have direct access
to KWin or a scripting interface exposed providing (limited) access -
there is just no need to have this in KWindowSystem.

To make it more clear what KWin supports as API of KWindowSystem for
internal windows this change implements a stripped down version of the
kwayland-integration plugin. The main difference is that it does not use
KWayland at all, but a QWindow internal side channel.

To support this EffectWindow provides an accessor for internalWindow and
the three already mentioned effects are adjusted to read from the
internal QWindow and it's dynamic properties.

This change is a first step for a further refactoring. I plan to split
the internal window out of ShellClient into a dedicated class. I think
there are nowadays too many special cases. If it moves out there is the
question whether we really want to use Wayland for the internal windows
or whether this is just historic ballast (after all we used to use
qwayland for that in the beginning).

As the change could introduce regressions I'm targetting 5.16.

Test Plan:
new test case for window type, manual testing using Alt+Tab
for the effects integration. Sliding popups, blur and contrast worked fine.

Reviewers: #kwin

Subscribers: kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D18228
parent ef510b4e
...@@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. ...@@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "kwin_wayland_test.h" #include "kwin_wayland_test.h"
#include "platform.h" #include "platform.h"
#include "cursor.h" #include "cursor.h"
#include "effects.h"
#include "shell_client.h" #include "shell_client.h"
#include "screens.h" #include "screens.h"
#include "wayland_server.h" #include "wayland_server.h"
...@@ -32,6 +33,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. ...@@ -32,6 +33,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <KWayland/Client/surface.h> #include <KWayland/Client/surface.h>
#include <KWayland/Client/seat.h> #include <KWayland/Client/seat.h>
#include <KWayland/Client/shell.h> #include <KWayland/Client/shell.h>
#include <KWindowSystem>
#include <KWayland/Server/surface_interface.h> #include <KWayland/Server/surface_interface.h>
...@@ -39,6 +41,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. ...@@ -39,6 +41,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
using namespace KWayland::Client; using namespace KWayland::Client;
Q_DECLARE_METATYPE(NET::WindowType);
namespace KWin namespace KWin
{ {
...@@ -67,6 +71,11 @@ private Q_SLOTS: ...@@ -67,6 +71,11 @@ private Q_SLOTS:
void testModifierScroll(); void testModifierScroll();
void testPopup(); void testPopup();
void testScale(); void testScale();
void testWindowType_data();
void testWindowType();
void testChangeWindowType_data();
void testChangeWindowType();
void testEffectWindow();
}; };
class HelperWindow : public QRasterWindow class HelperWindow : public QRasterWindow
...@@ -712,6 +721,98 @@ void InternalWindowTest::testScale() ...@@ -712,6 +721,98 @@ void InternalWindowTest::testScale()
QMetaObject::invokeMethod(kwinApp()->platform(), "setVirtualOutputs", Qt::DirectConnection, Q_ARG(int, 2)); QMetaObject::invokeMethod(kwinApp()->platform(), "setVirtualOutputs", Qt::DirectConnection, Q_ARG(int, 2));
} }
void InternalWindowTest::testWindowType_data()
{
QTest::addColumn<NET::WindowType>("windowType");
QTest::newRow("normal") << NET::Normal;
QTest::newRow("desktop") << NET::Desktop;
QTest::newRow("Dock") << NET::Dock;
QTest::newRow("Toolbar") << NET::Toolbar;
QTest::newRow("Menu") << NET::Menu;
QTest::newRow("Dialog") << NET::Dialog;
QTest::newRow("Utility") << NET::Utility;
QTest::newRow("Splash") << NET::Splash;
QTest::newRow("DropdownMenu") << NET::DropdownMenu;
QTest::newRow("PopupMenu") << NET::PopupMenu;
QTest::newRow("Tooltip") << NET::Tooltip;
QTest::newRow("Notification") << NET::Notification;
QTest::newRow("ComboBox") << NET::ComboBox;
QTest::newRow("OnScreenDisplay") << NET::OnScreenDisplay;
}
void InternalWindowTest::testWindowType()
{
QSignalSpy clientAddedSpy(waylandServer(), &WaylandServer::shellClientAdded);
QVERIFY(clientAddedSpy.isValid());
HelperWindow win;
win.setGeometry(0, 0, 100, 100);
QFETCH(NET::WindowType, windowType);
KWindowSystem::setType(win.winId(), windowType);
win.show();
QVERIFY(clientAddedSpy.wait());
QTRY_COMPARE(clientAddedSpy.count(), 1);
auto internalClient = clientAddedSpy.first().first().value<ShellClient*>();
QVERIFY(internalClient);
QCOMPARE(internalClient->windowType(), windowType);
}
void InternalWindowTest::testChangeWindowType_data()
{
QTest::addColumn<NET::WindowType>("windowType");
QTest::newRow("desktop") << NET::Desktop;
QTest::newRow("Dock") << NET::Dock;
QTest::newRow("Toolbar") << NET::Toolbar;
QTest::newRow("Menu") << NET::Menu;
QTest::newRow("Dialog") << NET::Dialog;
QTest::newRow("Utility") << NET::Utility;
QTest::newRow("Splash") << NET::Splash;
QTest::newRow("DropdownMenu") << NET::DropdownMenu;
QTest::newRow("PopupMenu") << NET::PopupMenu;
QTest::newRow("Tooltip") << NET::Tooltip;
QTest::newRow("Notification") << NET::Notification;
QTest::newRow("ComboBox") << NET::ComboBox;
QTest::newRow("OnScreenDisplay") << NET::OnScreenDisplay;
}
void InternalWindowTest::testChangeWindowType()
{
QSignalSpy clientAddedSpy(waylandServer(), &WaylandServer::shellClientAdded);
QVERIFY(clientAddedSpy.isValid());
HelperWindow win;
win.setGeometry(0, 0, 100, 100);
win.show();
QVERIFY(clientAddedSpy.wait());
QTRY_COMPARE(clientAddedSpy.count(), 1);
auto internalClient = clientAddedSpy.first().first().value<ShellClient*>();
QVERIFY(internalClient);
QCOMPARE(internalClient->windowType(), NET::Normal);
QFETCH(NET::WindowType, windowType);
KWindowSystem::setType(win.winId(), windowType);
QTRY_COMPARE(internalClient->windowType(), windowType);
KWindowSystem::setType(win.winId(), NET::Normal);
QTRY_COMPARE(internalClient->windowType(), NET::Normal);
}
void InternalWindowTest::testEffectWindow()
{
QSignalSpy clientAddedSpy(waylandServer(), &WaylandServer::shellClientAdded);
QVERIFY(clientAddedSpy.isValid());
HelperWindow win;
win.setGeometry(0, 0, 100, 100);
win.show();
QVERIFY(clientAddedSpy.wait());
auto internalClient = clientAddedSpy.first().first().value<ShellClient*>();
QVERIFY(internalClient);
QVERIFY(internalClient->effectWindow());
QCOMPARE(internalClient->effectWindow()->internalWindow(), &win);
QCOMPARE(effects->findWindow(&win), internalClient->effectWindow());
QCOMPARE(effects->findWindow(&win)->internalWindow(), &win);
}
} }
......
...@@ -184,6 +184,9 @@ void TestShellClient::testMapUnmapMap() ...@@ -184,6 +184,9 @@ void TestShellClient::testMapUnmapMap()
QVERIFY(client->property("moveable").toBool()); QVERIFY(client->property("moveable").toBool());
QVERIFY(client->property("moveableAcrossScreens").toBool()); QVERIFY(client->property("moveableAcrossScreens").toBool());
QVERIFY(client->property("resizeable").toBool()); QVERIFY(client->property("resizeable").toBool());
QCOMPARE(client->isInternal(), false);
QVERIFY(client->effectWindow());
QVERIFY(!client->effectWindow()->internalWindow());
QCOMPARE(client->internalId().isNull(), false); QCOMPARE(client->internalId().isNull(), false);
const auto uuid = client->internalId(); const auto uuid = client->internalId();
QUuid deletedUuid; QUuid deletedUuid;
......
...@@ -134,6 +134,9 @@ public: ...@@ -134,6 +134,9 @@ public:
KWin::EffectWindow *findWindow(KWayland::Server::SurfaceInterface *) const override { KWin::EffectWindow *findWindow(KWayland::Server::SurfaceInterface *) const override {
return nullptr; return nullptr;
} }
KWin::EffectWindow *findWindow(QWindow *w) const override {
return nullptr;
}
void *getProxy(QString) override { void *getProxy(QString) override {
return nullptr; return nullptr;
} }
......
...@@ -59,6 +59,9 @@ public: ...@@ -59,6 +59,9 @@ public:
void closeWindow() override; void closeWindow() override;
void referencePreviousWindowPixmap() override {} void referencePreviousWindowPixmap() override {}
void unreferencePreviousWindowPixmap() override {} void unreferencePreviousWindowPixmap() override {}
QWindow *internalWindow() const override {
return nullptr;
}
bool isDeleted() const override { bool isDeleted() const override {
return false; return false;
} }
......
...@@ -1086,6 +1086,19 @@ EffectWindow* EffectsHandlerImpl::findWindow(KWayland::Server::SurfaceInterface ...@@ -1086,6 +1086,19 @@ EffectWindow* EffectsHandlerImpl::findWindow(KWayland::Server::SurfaceInterface
return nullptr; return nullptr;
} }
EffectWindow *EffectsHandlerImpl::findWindow(QWindow *w) const
{
if (waylandServer()) {
if (auto c = waylandServer()->findClient(w)) {
return c->effectWindow();
}
}
if (auto u = Workspace::self()->findUnmanaged(w->winId())) {
return u->effectWindow();
}
return nullptr;
}
EffectWindowList EffectsHandlerImpl::stackingOrder() const EffectWindowList EffectsHandlerImpl::stackingOrder() const
{ {
...@@ -1936,6 +1949,15 @@ EffectWindow* EffectWindowImpl::findModal() ...@@ -1936,6 +1949,15 @@ EffectWindow* EffectWindowImpl::findModal()
return nullptr; return nullptr;
} }
QWindow *EffectWindowImpl::internalWindow() const
{
auto client = qobject_cast<ShellClient*>(toplevel);
if (!client) {
return nullptr;
}
return client->internalWindow();
}
template <typename T> template <typename T>
EffectWindowList getMainWindows(T *c) EffectWindowList getMainWindows(T *c)
{ {
......
...@@ -134,6 +134,7 @@ public: ...@@ -134,6 +134,7 @@ public:
void stopMousePolling() override; void stopMousePolling() override;
EffectWindow* findWindow(WId id) const override; EffectWindow* findWindow(WId id) const override;
EffectWindow* findWindow(KWayland::Server::SurfaceInterface *surf) const override; EffectWindow* findWindow(KWayland::Server::SurfaceInterface *surf) const override;
EffectWindow *findWindow(QWindow *w) const override;
EffectWindowList stackingOrder() const override; EffectWindowList stackingOrder() const override;
void setElevatedWindow(KWin::EffectWindow* w, bool set) override; void setElevatedWindow(KWin::EffectWindow* w, bool set) override;
...@@ -474,6 +475,8 @@ public: ...@@ -474,6 +475,8 @@ public:
void referencePreviousWindowPixmap() override; void referencePreviousWindowPixmap() override;
void unreferencePreviousWindowPixmap() override; void unreferencePreviousWindowPixmap() override;
QWindow *internalWindow() const override;
const Toplevel* window() const; const Toplevel* window() const;
Toplevel* window(); Toplevel* window();
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <QMatrix4x4> #include <QMatrix4x4>
#include <QLinkedList> #include <QLinkedList>
#include <QWindow>
#include <KWayland/Server/surface_interface.h> #include <KWayland/Server/surface_interface.h>
#include <KWayland/Server/contrast_interface.h> #include <KWayland/Server/contrast_interface.h>
...@@ -140,6 +141,27 @@ void ContrastEffect::updateContrastRegion(EffectWindow *w) ...@@ -140,6 +141,27 @@ void ContrastEffect::updateContrastRegion(EffectWindow *w)
m_colorMatrices[w] = colorMatrix(surf->contrast()->contrast(), surf->contrast()->intensity(), surf->contrast()->saturation()); m_colorMatrices[w] = colorMatrix(surf->contrast()->contrast(), surf->contrast()->intensity(), surf->contrast()->saturation());
} }
if (auto internal = w->internalWindow()) {
const auto property = internal->property("kwin_background_region");
if (property.isValid()) {
region = property.value<QRegion>();
bool ok = false;
qreal contrast = internal->property("kwin_background_contrast").toReal(&ok);
if (!ok) {
contrast = 1.0;
}
qreal intensity = internal->property("kwin_background_intensity").toReal(&ok);
if (!ok) {
intensity = 1.0;
}
qreal saturation = internal->property("kwin_background_saturation").toReal(&ok);
if (!ok) {
saturation = 1.0;
}
m_colorMatrices[w] = colorMatrix(contrast, intensity, saturation);
}
}
//!value.isNull() full window in X11 case, surf->contrast() //!value.isNull() full window in X11 case, surf->contrast()
//valid, full window in wayland case //valid, full window in wayland case
if (region.isEmpty() && (!value.isNull() || (surf && surf->contrast()))) { if (region.isEmpty() && (!value.isNull() || (surf && surf->contrast()))) {
...@@ -163,9 +185,31 @@ void ContrastEffect::slotWindowAdded(EffectWindow *w) ...@@ -163,9 +185,31 @@ void ContrastEffect::slotWindowAdded(EffectWindow *w)
} }
}); });
} }
if (auto internal = w->internalWindow()) {
internal->installEventFilter(this);
}
updateContrastRegion(w); updateContrastRegion(w);
} }
bool ContrastEffect::eventFilter(QObject *watched, QEvent *event)
{
auto internal = qobject_cast<QWindow*>(watched);
if (internal && event->type() == QEvent::DynamicPropertyChange) {
QDynamicPropertyChangeEvent *pe = static_cast<QDynamicPropertyChangeEvent*>(event);
if (pe->propertyName() == "kwin_background_region" ||
pe->propertyName() == "kwin_background_contrast" ||
pe->propertyName() == "kwin_background_intensity" ||
pe->propertyName() == "kwin_background_saturation") {
if (auto w = effects->findWindow(internal)) {
updateContrastRegion(w);
}
}
}
return false;
}
void ContrastEffect::slotWindowDeleted(EffectWindow *w) void ContrastEffect::slotWindowDeleted(EffectWindow *w)
{ {
if (m_contrastChangedConnections.contains(w)) { if (m_contrastChangedConnections.contains(w)) {
......
...@@ -64,6 +64,8 @@ public: ...@@ -64,6 +64,8 @@ public:
return 76; return 76;
} }
bool eventFilter(QObject *watched, QEvent *event) override;
public Q_SLOTS: public Q_SLOTS:
void slotWindowAdded(KWin::EffectWindow *w); void slotWindowAdded(KWin::EffectWindow *w);
void slotWindowDeleted(KWin::EffectWindow *w); void slotWindowDeleted(KWin::EffectWindow *w);
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <QLinkedList> #include <QLinkedList>
#include <QScreen> // for QGuiApplication #include <QScreen> // for QGuiApplication
#include <QTime> #include <QTime>
#include <QWindow>
#include <cmath> // for ceil() #include <cmath> // for ceil()
#include <KWayland/Server/surface_interface.h> #include <KWayland/Server/surface_interface.h>
...@@ -272,6 +273,13 @@ void BlurEffect::updateBlurRegion(EffectWindow *w) const ...@@ -272,6 +273,13 @@ void BlurEffect::updateBlurRegion(EffectWindow *w) const
region = surf->blur()->region(); region = surf->blur()->region();
} }
if (auto internal = w->internalWindow()) {
const auto property = internal->property("kwin_blur");
if (property.isValid()) {
region = property.value<QRegion>();
}
}
//!value.isNull() full window in X11 case, surf->blur() //!value.isNull() full window in X11 case, surf->blur()
//valid, full window in wayland case //valid, full window in wayland case
if (region.isEmpty() && (!value.isNull() || (surf && surf->blur()))) { if (region.isEmpty() && (!value.isNull() || (surf && surf->blur()))) {
...@@ -294,6 +302,9 @@ void BlurEffect::slotWindowAdded(EffectWindow *w) ...@@ -294,6 +302,9 @@ void BlurEffect::slotWindowAdded(EffectWindow *w)
} }
}); });
} }
if (auto internal = w->internalWindow()) {
internal->installEventFilter(this);
}
updateBlurRegion(w); updateBlurRegion(w);
} }
...@@ -315,6 +326,20 @@ void BlurEffect::slotPropertyNotify(EffectWindow *w, long atom) ...@@ -315,6 +326,20 @@ void BlurEffect::slotPropertyNotify(EffectWindow *w, long atom)
} }
} }
bool BlurEffect::eventFilter(QObject *watched, QEvent *event)
{
auto internal = qobject_cast<QWindow*>(watched);
if (internal && event->type() == QEvent::DynamicPropertyChange) {
QDynamicPropertyChangeEvent *pe = static_cast<QDynamicPropertyChangeEvent*>(event);
if (pe->propertyName() == "kwin_blur") {
if (auto w = effects->findWindow(internal)) {
updateBlurRegion(w);
}
}
}
return false;
}
bool BlurEffect::enabledByDefault() bool BlurEffect::enabledByDefault()
{ {
GLPlatform *gl = GLPlatform::instance(); GLPlatform *gl = GLPlatform::instance();
......
...@@ -67,6 +67,8 @@ public: ...@@ -67,6 +67,8 @@ public:
return 75; return 75;
} }
bool eventFilter(QObject *watched, QEvent *event) override;
public Q_SLOTS: public Q_SLOTS:
void slotWindowAdded(KWin::EffectWindow *w); void slotWindowAdded(KWin::EffectWindow *w);
void slotWindowDeleted(KWin::EffectWindow *w); void slotWindowDeleted(KWin::EffectWindow *w);
......
...@@ -24,11 +24,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. ...@@ -24,11 +24,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QApplication> #include <QApplication>
#include <QFontMetrics> #include <QFontMetrics>
#include <QWindow>
#include <KWayland/Server/surface_interface.h> #include <KWayland/Server/surface_interface.h>
#include <KWayland/Server/slide_interface.h> #include <KWayland/Server/slide_interface.h>
#include <KWayland/Server/display.h> #include <KWayland/Server/display.h>
#include <KWindowEffects>
Q_DECLARE_METATYPE(KWindowEffects::SlideFromLocation)
namespace KWin namespace KWin
{ {
...@@ -200,6 +205,11 @@ void SlidingPopupsEffect::slotWindowAdded(EffectWindow *w) ...@@ -200,6 +205,11 @@ void SlidingPopupsEffect::slotWindowAdded(EffectWindow *w)
}); });
} }
if (auto internal = w->internalWindow()) {
internal->installEventFilter(this);
setupInternalWindowSlide(w);
}
slideIn(w); slideIn(w);
} }
...@@ -377,6 +387,62 @@ void SlidingPopupsEffect::slotWaylandSlideOnShowChanged(EffectWindow* w) ...@@ -377,6 +387,62 @@ void SlidingPopupsEffect::slotWaylandSlideOnShowChanged(EffectWindow* w)
} }
} }
void SlidingPopupsEffect::setupInternalWindowSlide(EffectWindow *w)
{
if (!w) {
return;
}
auto internal = w->internalWindow();
if (!internal) {
return;
}
const QVariant slideProperty = internal->property("kwin_slide");
if (!slideProperty.isValid()) {
return;
}
AnimationData &animData = m_animationsData[w];
switch (slideProperty.value<KWindowEffects::SlideFromLocation>()) {
case KWindowEffects::BottomEdge:
animData.location = Location::Bottom;
break;
case KWindowEffects::TopEdge:
animData.location = Location::Top;
break;
case KWindowEffects::RightEdge:
animData.location = Location::Right;
break;
case KWindowEffects::LeftEdge:
animData.location = Location::Left;
break;
default:
return;
}
bool intOk = false;
animData.offset = internal->property("kwin_slide_offset").toInt(&intOk);
if (!intOk) {
animData.offset = -1;
}
animData.slideLength = 0;
animData.slideInDuration = m_slideInDuration;
animData.slideOutDuration = m_slideOutDuration;
setupAnimData(w);
}
bool SlidingPopupsEffect::eventFilter(QObject *watched, QEvent *event)
{
auto internal = qobject_cast<QWindow*>(watched);
if (internal && event->type() == QEvent::DynamicPropertyChange) {
QDynamicPropertyChangeEvent *pe = static_cast<QDynamicPropertyChangeEvent*>(event);
if (pe->propertyName() == "kwin_slide" || pe->propertyName() == "kwin_slide_offset") {
if (auto w = effects->findWindow(internal)) {
setupInternalWindowSlide(w);
}
}
}
return false;
}
void SlidingPopupsEffect::slideIn(EffectWindow *w) void SlidingPopupsEffect::slideIn(EffectWindow *w)
{ {
if (effects->activeFullScreenEffect()) { if (effects->activeFullScreenEffect()) {
......
...@@ -53,6 +53,8 @@ public: ...@@ -53,6 +53,8 @@ public:
int slideInDuration() const; int slideInDuration() const;
int slideOutDuration() const; int slideOutDuration() const;
bool eventFilter(QObject *watched, QEvent *event) override;
private Q_SLOTS: private Q_SLOTS:
void slotWindowAdded(EffectWindow *w); void slotWindowAdded(EffectWindow *w);
void slotWindowDeleted(EffectWindow *w); void slotWindowDeleted(EffectWindow *w);
...@@ -65,6 +67,7 @@ private Q_SLOTS: ...@@ -65,6 +67,7 @@ private Q_SLOTS:
private: private:
void setupAnimData(EffectWindow *w); void setupAnimData(EffectWindow *w);
void setupInternalWindowSlide(EffectWindow *w);
long m_atom; long m_atom;
......
...@@ -1078,6 +1078,16 @@ public: ...@@ -1078,6 +1078,16 @@ public:
Q_SCRIPTABLE virtual KWin::EffectWindow* findWindow(WId id) const = 0; Q_SCRIPTABLE virtual KWin::EffectWindow* findWindow(WId id) const = 0;
Q_SCRIPTABLE virtual KWin::EffectWindow* findWindow(KWayland::Server::SurfaceInterface *surf) const = 0; Q_SCRIPTABLE virtual KWin::EffectWindow* findWindow(KWayland::Server::SurfaceInterface *surf) const = 0;
/**
* Finds the EffectWindow for the internal window @p w.
* If there is no such window @c null is returned.
*
* On Wayland this returns the internal window. On X11 it returns an Unamanged with the
* window id matching that of the provided window @p w.
*
* @since 5.16
**/
Q_SCRIPTABLE virtual KWin::EffectWindow *findWindow(QWindow *w) const = 0;
virtual EffectWindowList stackingOrder() const = 0; virtual EffectWindowList stackingOrder() const = 0;
// window will be temporarily painted as if being at the top of the stack // window will be temporarily painted as if being at the top of the stack
Q_SCRIPTABLE virtual void setElevatedWindow(KWin::EffectWindow* w, bool set) = 0; Q_SCRIPTABLE virtual void setElevatedWindow(KWin::EffectWindow* w, bool set) = 0;
...@@ -2041,6 +2051,14 @@ class KWINEFFECTS_EXPORT EffectWindow : public QObject ...@@ -2041,6 +2051,14 @@ class KWINEFFECTS_EXPORT EffectWindow : public QObject
**/ **/
Q_PROPERTY(bool popupWindow READ isPopupWindow CONSTANT) Q_PROPERTY(bool popupWindow READ isPopupWindow CONSTANT)