diff --git a/CMakeLists.txt b/CMakeLists.txt
index 27f4e66005..40523fd14a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -222,6 +222,7 @@ set(kwin_OWN_LIBS
set(kwin_QT_LIBS
${Qt5Declarative_LIBRARIES}
+ ${Qt5Quick_LIBRARIES}
${Qt5X11Extras_LIBRARIES}
)
diff --git a/scene.cpp b/scene.cpp
index 6ed85dc1ec..78657157c7 100644
--- a/scene.cpp
+++ b/scene.cpp
@@ -70,8 +70,7 @@ along with this program. If not, see .
#include
-#include
-#include
+#include
#include
#include "client.h"
@@ -382,6 +381,26 @@ void Scene::paintWindow(Window* w, int mask, QRegion region, WindowQuadList quad
paintDesktopThumbnails(w);
}
+static void adjustClipRegion(AbstractThumbnailItem *item, QRegion &clippingRegion)
+{
+ if (item->clip() && item->clipTo()) {
+ // the x/y positions of the parent item are not correct. The margins are added, though the size seems fine
+ // that's why we have to get the offset by inspecting the anchors properties
+ QQuickItem *parentItem = item->clipTo();
+ QPointF offset;
+ QVariant anchors = parentItem->property("anchors");
+ if (anchors.isValid()) {
+ if (QObject *anchorsObject = anchors.value()) {
+ offset.setX(anchorsObject->property("leftMargin").toReal());
+ offset.setY(anchorsObject->property("topMargin").toReal());
+ }
+ }
+ const QRectF rect = parentItem->mapRectToScene(QRectF(parentItem->position() - offset,
+ QSizeF(parentItem->width(), parentItem->height())));
+ clippingRegion &= rect.adjusted(0,0,-1,-1).translated(item->window()->position()).toRect();
+ }
+}
+
void Scene::paintWindowThumbnails(Scene::Window *w, QRegion region, qreal opacity, qreal brightness, qreal saturation)
{
EffectWindowImpl *wImpl = static_cast(effectWindow(w));
@@ -410,18 +429,11 @@ void Scene::paintWindowThumbnails(Scene::Window *w, QRegion region, qreal opacit
}
thumbData.setXScale(size.width() / static_cast(visualThumbRect.width()));
thumbData.setYScale(size.height() / static_cast(visualThumbRect.height()));
- // it can happen in the init/closing phase of the tabbox
- // that the corresponding QGraphicsScene is not available
- if (item->scene() == 0) {
- continue;
- }
- QGraphicsView* declview = findViewForThumbnailItem(item, w);
- if (declview == 0) {
+ if (!item->window()) {
continue;
}
- QPoint viewPos = findOffsetInWindow(declview, w->window()->window());
- const QPoint point = viewPos + declview->mapFromScene(item->scenePos());
+ const QPointF point = item->mapToScene(item->position());
qreal x = point.x() + w->x() + (item->width() - size.width())/2;
qreal y = point.y() + w->y() + (item->height() - size.height()) / 2;
x -= thumb->x();
@@ -439,14 +451,7 @@ void Scene::paintWindowThumbnails(Scene::Window *w, QRegion region, qreal opacit
}
QRegion clippingRegion = region;
clippingRegion &= QRegion(wImpl->x(), wImpl->y(), wImpl->width(), wImpl->height());
- QPainterPath path = item->clipPath();
- if (!path.isEmpty()) {
- // here we assume that the clippath consists of a single rectangle
- const QPolygonF sceneBounds = item->mapToScene(path.boundingRect());
- const QRect viewBounds = declview->mapFromScene(sceneBounds).boundingRect();
- // shrinking the rect due to rounding errors
- clippingRegion &= viewBounds.adjusted(0,0,-1,-1).translated(viewPos + w->pos());
- }
+ adjustClipRegion(item, clippingRegion);
effects->drawWindow(thumb, thumbMask, clippingRegion, thumbData);
}
}
@@ -461,16 +466,9 @@ void Scene::paintDesktopThumbnails(Scene::Window *w)
if (!item->isVisible()) {
continue;
}
- // it can happen in the init/closing phase of the tabbox
- // that the corresponding QGraphicsScene is not available
- if (item->scene() == 0) {
+ if (!item->window()) {
continue;
}
- QGraphicsView* declview = findViewForThumbnailItem(item, w);
- if (declview == 0) {
- continue;
- }
- QPoint viewPos = findOffsetInWindow(declview, w->window()->window());
s_recursionCheck = w;
ScreenPaintData data;
@@ -479,20 +477,13 @@ void Scene::paintDesktopThumbnails(Scene::Window *w)
size.scale(item->width(), item->height(), Qt::KeepAspectRatio);
data *= QVector2D(size.width() / double(displayWidth()),
size.height() / double(displayHeight()));
- const QPoint point = viewPos + declview->mapFromScene(item->scenePos());
+ const QPointF point = item->mapToScene(item->position());
const qreal x = point.x() + w->x() + (item->width() - size.width())/2;
const qreal y = point.y() + w->y() + (item->height() - size.height()) / 2;
const QRect region = QRect(x, y, item->width(), item->height());
QRegion clippingRegion = region;
clippingRegion &= QRegion(wImpl->x(), wImpl->y(), wImpl->width(), wImpl->height());
- QPainterPath path = item->clipPath();
- if (!path.isEmpty()) {
- // here we assume that the clippath consists of a single rectangle
- const QPolygonF sceneBounds = item->mapToScene(path.boundingRect());
- const QRect viewBounds = declview->mapFromScene(sceneBounds).boundingRect();
- // shrinking the rect due to rounding errors
- clippingRegion &= viewBounds.adjusted(0,0,-1,-1).translated(viewPos + w->pos());
- }
+ adjustClipRegion(item, clippingRegion);
data += QPointF(x, y);
const int desktopMask = PAINT_SCREEN_TRANSFORMED | PAINT_WINDOW_TRANSFORMED | PAINT_SCREEN_BACKGROUND_FIRST;
paintDesktop(item->desktop(), desktopMask, clippingRegion, data);
@@ -500,41 +491,6 @@ void Scene::paintDesktopThumbnails(Scene::Window *w)
}
}
-QGraphicsView *Scene::findViewForThumbnailItem(AbstractThumbnailItem *item, Scene::Window *w)
-{
- // in principle there could be more than one QGraphicsView per QGraphicsScene,
- // although TabBox does not make use of it so far
- QList views = item->scene()->views();
- foreach (QGraphicsView* view, views) {
- if (view->winId() == w->window()->window()) {
- return view;
- }
- QWidget *parent = view;
- while ((parent = parent->parentWidget())) {
- // if the graphicsview is not the topmost widget we try to go up to the
- // toplevel widget and check whether that is the window we are looking for.
- if (parent->winId() == w->window()->window()) {
- return view;
- }
- }
- }
- return NULL;
-}
-
-QPoint Scene::findOffsetInWindow(QWidget *view, xcb_window_t idOfTopmostWindow)
-{
- if (view->winId() == idOfTopmostWindow) {
- return QPoint();
- }
- QWidget *parent = view;
- while ((parent = parent->parentWidget())) {
- if (parent->winId() == idOfTopmostWindow) {
- return view->mapTo(parent, QPoint());
- }
- }
- return QPoint();
-}
-
void Scene::paintDesktop(int desktop, int mask, const QRegion ®ion, ScreenPaintData &data)
{
static_cast(effects)->paintDesktop(desktop, mask, region, data);
diff --git a/scene.h b/scene.h
index 462a604d9e..93ba06c793 100644
--- a/scene.h
+++ b/scene.h
@@ -27,8 +27,6 @@ along with this program. If not, see .
#include
-class QGraphicsView;
-
namespace KWin
{
@@ -167,13 +165,6 @@ protected:
private:
void paintWindowThumbnails(Scene::Window *w, QRegion region, qreal opacity, qreal brightness, qreal saturation);
void paintDesktopThumbnails(Scene::Window *w);
- /**
- * Helper function to find the GraphicsView the ThumbnailItem @p item is rendered in which
- * matches our Window @p w.
- * If not found @c NULL is returned.
- **/
- QGraphicsView *findViewForThumbnailItem(AbstractThumbnailItem *item, Scene::Window *w);
- QPoint findOffsetInWindow(QWidget *view, xcb_window_t idOfTopmostWindow);
};
// The base class for windows representations in composite backends
diff --git a/scripting/scripting.cpp b/scripting/scripting.cpp
index 5a561aaaa3..3ab223ff15 100644
--- a/scripting/scripting.cpp
+++ b/scripting/scripting.cpp
@@ -26,7 +26,9 @@ along with this program. If not, see .
#include "workspace_wrapper.h"
#include "scripting_model.h"
#include "../client.h"
+#if KWIN_QT5_PORTING
#include "../thumbnailitem.h"
+#endif
#include "../options.h"
#include "../workspace.h"
// KDE
@@ -44,8 +46,10 @@ along with this program. If not, see .
#include
#include
#include
+#include
#include
#include
+#include
#include
#include
#include
@@ -552,9 +556,9 @@ void KWin::DeclarativeScript::run()
kdeclarative.initialize();
kdeclarative.setupBindings();
installScriptFunctions(kdeclarative.scriptEngine());
-#endif
qmlRegisterType("org.kde.kwin", 0, 1, "DesktopThumbnailItem");
qmlRegisterType("org.kde.kwin", 0, 1, "ThumbnailItem");
+#endif
qmlRegisterType();
qmlRegisterType("org.kde.kwin", 0, 1, "ClientModel");
qmlRegisterType("org.kde.kwin", 0, 1, "ClientModelByScreen");
diff --git a/tabbox/qml/clients/present_windows/contents/ui/main.qml b/tabbox/qml/clients/present_windows/contents/ui/main.qml
index 889fc900de..17531d8c43 100644
--- a/tabbox/qml/clients/present_windows/contents/ui/main.qml
+++ b/tabbox/qml/clients/present_windows/contents/ui/main.qml
@@ -88,6 +88,8 @@ Item {
KWin.ThumbnailItem {
id: thumbnailItem
wId: windowId
+ clip: true
+ clipTo: thumbnailListView
anchors {
top: parent.top
left: parent.left
diff --git a/tabbox/qml/clients/thumbnails/contents/ui/main.qml b/tabbox/qml/clients/thumbnails/contents/ui/main.qml
index 9cef0b44be..dda3b00009 100644
--- a/tabbox/qml/clients/thumbnails/contents/ui/main.qml
+++ b/tabbox/qml/clients/thumbnails/contents/ui/main.qml
@@ -98,6 +98,8 @@ Item {
property variant data: model
id: thumbnailItem
wId: windowId
+ clip: true
+ clipTo: thumbnailListView
anchors {
fill: parent
leftMargin: hoverItem.margins.left
diff --git a/tabbox/qml/desktops/previews/contents/ui/main.qml b/tabbox/qml/desktops/previews/contents/ui/main.qml
index 65f76314e4..38a02dd1e8 100644
--- a/tabbox/qml/desktops/previews/contents/ui/main.qml
+++ b/tabbox/qml/desktops/previews/contents/ui/main.qml
@@ -100,6 +100,7 @@ Item {
id: thumbnailItem
property variant data: model
clip: true
+ clipTo: listView
desktop: model.desktop
anchors {
fill: parent
diff --git a/thumbnailitem.cpp b/thumbnailitem.cpp
index bf7e6e1913..0048998638 100644
--- a/thumbnailitem.cpp
+++ b/thumbnailitem.cpp
@@ -26,24 +26,22 @@ along with this program. If not, see .
#include "workspace.h"
#include "composite.h"
// Qt
-#include
-#include
-#include
+#include
+#include
// KDE
#include
namespace KWin
{
-AbstractThumbnailItem::AbstractThumbnailItem(QDeclarativeItem *parent)
- : QDeclarativeItem(parent)
- , m_clip(true)
+AbstractThumbnailItem::AbstractThumbnailItem(QQuickItem *parent)
+ : QQuickPaintedItem(parent)
, m_parent(QWeakPointer())
, m_parentWindow(0)
, m_brightness(1.0)
, m_saturation(1.0)
+ , m_clipToItem()
{
- setFlags(flags() & ~QGraphicsItem::ItemHasNoContents);
Q_ASSERT(Compositor::isCreated());
connect(Compositor::self(), SIGNAL(compositingToggled(bool)), SLOT(compositingToggled()));
compositingToggled();
@@ -90,29 +88,18 @@ void AbstractThumbnailItem::findParentEffectWindow()
return;
}
}
- QDeclarativeContext *ctx = QDeclarativeEngine::contextForObject(this);
- if (!ctx) {
- kDebug(1212) << "No Context";
+ QQuickWindow *qw = window();
+ if (!qw) {
+ kDebug(1212) << "No QQuickWindow assigned yet";
return;
}
- const QVariant variant = ctx->engine()->rootContext()->contextProperty(QStringLiteral("viewId"));
- if (!variant.isValid()) {
- kDebug(1212) << "Required context property 'viewId' not found";
- return;
- }
- if (EffectWindowImpl *w = static_cast(effects->findWindow(variant.value()))) {
+ if (auto *w = static_cast(effects->findWindow(qw->winId()))) {
m_parent = QWeakPointer(w);
- m_parentWindow = variant.value();
+ m_parentWindow = qw->winId();
}
}
}
-void AbstractThumbnailItem::setClip(bool clip)
-{
- m_clip = clip;
- emit clipChanged(clip);
-}
-
void AbstractThumbnailItem::effectWindowAdded()
{
// the window might be added before the EffectWindow is created
@@ -145,8 +132,13 @@ void AbstractThumbnailItem::setSaturation(qreal saturation)
emit saturationChanged();
}
+void AbstractThumbnailItem::setClipTo(QQuickItem *clip)
+{
+ m_clipToItem = QPointer(clip);
+ emit clipToChanged();
+}
-WindowThumbnailItem::WindowThumbnailItem(QDeclarativeItem* parent)
+WindowThumbnailItem::WindowThumbnailItem(QQuickItem* parent)
: AbstractThumbnailItem(parent)
, m_wId(0)
, m_client(NULL)
@@ -186,15 +178,13 @@ void WindowThumbnailItem::setClient(Client *client)
emit clientChanged();
}
-void WindowThumbnailItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+void WindowThumbnailItem::paint(QPainter *painter)
{
if (effects) {
- QDeclarativeItem::paint(painter, option, widget);
return;
}
Client *client = Workspace::self()->findClient(WindowMatchPredicate(m_wId));
if (!client) {
- QDeclarativeItem::paint(painter, option, widget);
return;
}
QPixmap pixmap = client->icon(boundingRect().size().toSize());
@@ -210,7 +200,7 @@ void WindowThumbnailItem::repaint(KWin::EffectWindow *w)
}
}
-DesktopThumbnailItem::DesktopThumbnailItem(QDeclarativeItem *parent)
+DesktopThumbnailItem::DesktopThumbnailItem(QQuickItem *parent)
: AbstractThumbnailItem(parent)
, m_desktop(0)
{
@@ -231,10 +221,10 @@ void DesktopThumbnailItem::setDesktop(int desktop)
emit desktopChanged(m_desktop);
}
-void DesktopThumbnailItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+void DesktopThumbnailItem::paint(QPainter *painter)
{
+ Q_UNUSED(painter)
if (effects) {
- QDeclarativeItem::paint(painter, option, widget);
return;
}
// TODO: render icon
diff --git a/thumbnailitem.h b/thumbnailitem.h
index 89fd48d715..5592d7a0ed 100644
--- a/thumbnailitem.h
+++ b/thumbnailitem.h
@@ -21,8 +21,9 @@ along with this program. If not, see .
#ifndef KWIN_THUMBNAILITEM_H
#define KWIN_THUMBNAILITEM_H
+#include
#include
-#include
+#include
namespace KWin
{
@@ -31,37 +32,35 @@ class Client;
class EffectWindow;
class EffectWindowImpl;
-class AbstractThumbnailItem : public QDeclarativeItem
+class AbstractThumbnailItem : public QQuickPaintedItem
{
Q_OBJECT
- Q_PROPERTY(bool clip READ isClip WRITE setClip NOTIFY clipChanged SCRIPTABLE true)
Q_PROPERTY(qulonglong parentWindow READ parentWindow WRITE setParentWindow)
Q_PROPERTY(qreal brightness READ brightness WRITE setBrightness NOTIFY brightnessChanged)
Q_PROPERTY(qreal saturation READ saturation WRITE setSaturation NOTIFY saturationChanged)
+ Q_PROPERTY(QQuickItem *clipTo READ clipTo WRITE setClipTo NOTIFY clipToChanged)
public:
virtual ~AbstractThumbnailItem();
- bool isClip() const {
- return m_clip;
- }
- void setClip(bool clip);
qulonglong parentWindow() const {
return m_parentWindow;
}
void setParentWindow(qulonglong parentWindow);
qreal brightness() const;
qreal saturation() const;
+ QQuickItem *clipTo() const;
public Q_SLOTS:
void setBrightness(qreal brightness);
void setSaturation(qreal saturation);
+ void setClipTo(QQuickItem *clip);
Q_SIGNALS:
- void clipChanged(bool clipped);
void brightnessChanged();
void saturationChanged();
+ void clipToChanged();
protected:
- explicit AbstractThumbnailItem(QDeclarativeItem *parent = 0);
+ explicit AbstractThumbnailItem(QQuickItem *parent = 0);
protected Q_SLOTS:
virtual void repaint(KWin::EffectWindow* w) = 0;
@@ -73,11 +72,11 @@ private Q_SLOTS:
private:
void findParentEffectWindow();
- bool m_clip;
QWeakPointer m_parent;
qulonglong m_parentWindow;
qreal m_brightness;
qreal m_saturation;
+ QPointer m_clipToItem;
};
class WindowThumbnailItem : public AbstractThumbnailItem
@@ -86,7 +85,7 @@ class WindowThumbnailItem : public AbstractThumbnailItem
Q_PROPERTY(qulonglong wId READ wId WRITE setWId NOTIFY wIdChanged SCRIPTABLE true)
Q_PROPERTY(KWin::Client *client READ client WRITE setClient NOTIFY clientChanged)
public:
- explicit WindowThumbnailItem(QDeclarativeItem *parent = 0);
+ explicit WindowThumbnailItem(QQuickItem *parent = 0);
virtual ~WindowThumbnailItem();
qulonglong wId() const {
@@ -95,7 +94,7 @@ public:
void setWId(qulonglong wId);
Client *client() const;
void setClient(Client *client);
- virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+ virtual void paint(QPainter *painter);
Q_SIGNALS:
void wIdChanged(qulonglong wid);
void clientChanged();
@@ -111,14 +110,14 @@ class DesktopThumbnailItem : public AbstractThumbnailItem
Q_OBJECT
Q_PROPERTY(int desktop READ desktop WRITE setDesktop NOTIFY desktopChanged)
public:
- DesktopThumbnailItem(QDeclarativeItem *parent = 0);
+ DesktopThumbnailItem(QQuickItem *parent = 0);
virtual ~DesktopThumbnailItem();
int desktop() const {
return m_desktop;
}
void setDesktop(int desktop);
- virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+ virtual void paint(QPainter *painter);
Q_SIGNALS:
void desktopChanged(int desktop);
protected Q_SLOTS:
@@ -139,6 +138,12 @@ qreal AbstractThumbnailItem::saturation() const
return m_saturation;
}
+inline
+QQuickItem* AbstractThumbnailItem::clipTo() const
+{
+ return m_clipToItem.data();
+}
+
inline
Client *WindowThumbnailItem::client() const
{