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);