diff --git a/effects/mouseclick/mouseclick.cpp b/effects/mouseclick/mouseclick.cpp
index 41472374ef..0b76074a6d 100644
--- a/effects/mouseclick/mouseclick.cpp
+++ b/effects/mouseclick/mouseclick.cpp
@@ -24,6 +24,11 @@ along with this program. If not, see .
#include
+#ifdef KWIN_HAVE_XRENDER_COMPOSITING
+#include
+#include
+#endif
+
#include
#include
#include
@@ -36,6 +41,10 @@ namespace KWin
KWIN_EFFECT(mouseclick, MouseClickEffect)
KWIN_EFFECT_SUPPORTED(mouseclick, MouseClickEffect::supported())
+#ifdef KWIN_HAVE_XRENDER_COMPOSITING
+static QPixmap s_XrBuffer;
+#endif
+
MouseClickEffect::MouseClickEffect()
{
m_enabled = false;
@@ -55,6 +64,10 @@ MouseClickEffect::MouseClickEffect()
MouseClickEffect::~MouseClickEffect()
{
+#ifdef KWIN_HAVE_XRENDER_COMPOSITING
+ if (!s_XrBuffer.isNull())
+ XFreePixmap(display(), s_XrBuffer.handle());
+#endif
effects->stopMousePolling();
foreach (const MouseEvent* click, m_clicks) {
delete click;
@@ -68,7 +81,7 @@ MouseClickEffect::~MouseClickEffect()
bool MouseClickEffect::supported()
{
- return effects->isOpenGLCompositing();
+ return true;
}
void MouseClickEffect::reconfigure(ReconfigureFlags)
@@ -252,17 +265,22 @@ bool MouseClickEffect::isActive() const
void MouseClickEffect::drawCircle(const QColor& color, float cx, float cy, float r)
{
- drawCircleGl(color, cx, cy, r);
+ if (effects->isOpenGLCompositing())
+ drawCircleGl(color, cx, cy, r);
+ if (effects->compositingType() == XRenderCompositing)
+ drawCircleXr(color, cx, cy, r);
}
void MouseClickEffect::paintScreenSetup(int mask, QRegion region, ScreenPaintData& data)
{
- paintScreenSetupGl(mask, region, data);
+ if (effects->isOpenGLCompositing())
+ paintScreenSetupGl(mask, region, data);
}
void MouseClickEffect::paintScreenFinish(int mask, QRegion region, ScreenPaintData& data)
{
- paintScreenFinishGl(mask, region, data);
+ if (effects->isOpenGLCompositing())
+ paintScreenFinishGl(mask, region, data);
}
void MouseClickEffect::drawCircleGl(const QColor& color, float cx, float cy, float r)
@@ -294,6 +312,35 @@ void MouseClickEffect::drawCircleGl(const QColor& color, float cx, float cy, flo
vbo->render(GL_LINE_LOOP);
}
+void MouseClickEffect::drawCircleXr(const QColor& color, float cx, float cy, float r)
+{
+#ifdef KWIN_HAVE_XRENDER_COMPOSITING
+ const int bufferSize = qRound(1.41421356*(2*m_ringMaxSize + m_lineWidth)) | 1;
+ if (bufferSize < 0) // should not happen, but we neither want to leak XPixmaps
+ return;
+ if (s_XrBuffer.size() != QSize(bufferSize, bufferSize)) {
+ if (!s_XrBuffer.isNull()) {
+ XFreePixmap(display(), s_XrBuffer.handle());
+ }
+ Pixmap xpix = XCreatePixmap(display(), rootWindow(), bufferSize, bufferSize, 32);
+ s_XrBuffer = QPixmap::fromX11Pixmap(xpix, QPixmap::ExplicitlyShared);
+ }
+ s_XrBuffer.fill(Qt::transparent);
+ QRect rct(s_XrBuffer.rect());
+ QPainter p(&s_XrBuffer);
+ p.setBrush(Qt::NoBrush);
+ p.setPen(QPen(color, m_lineWidth));
+ p.setRenderHint(QPainter::Antialiasing);
+ const int ir = qRound(r);
+ p.drawEllipse(rct.center(), ir, ir);
+ p.end();
+ rct.moveCenter(QPoint(qRound(cx), qRound(cy)));
+ XRenderComposite( display(), PictOpOver,
+ s_XrBuffer.x11PictureHandle(), 0, effects->xrenderBufferPicture(),
+ 0, 0, 0, 0, rct.x(), rct.y(), rct.width(), rct.height() );
+#endif
+}
+
void MouseClickEffect::paintScreenSetupGl(int, QRegion, ScreenPaintData&)
{
if (ShaderManager::instance()->isValid()) {
diff --git a/effects/mouseclick/mouseclick.h b/effects/mouseclick/mouseclick.h
index 563554026d..35932ebaa3 100644
--- a/effects/mouseclick/mouseclick.h
+++ b/effects/mouseclick/mouseclick.h
@@ -160,6 +160,7 @@ private:
void repaint();
void drawCircleGl(const QColor& color, float cx, float cy, float r);
+ void drawCircleXr(const QColor& color, float cx, float cy, float r);
void paintScreenSetupGl(int mask, QRegion region, ScreenPaintData& data);
void paintScreenFinishGl(int mask, QRegion region, ScreenPaintData& data);