diff --git a/effects/magnifier/magnifier.cpp b/effects/magnifier/magnifier.cpp index 0cc4c4e1fc..69ae3b6b61 100644 --- a/effects/magnifier/magnifier.cpp +++ b/effects/magnifier/magnifier.cpp @@ -30,6 +30,7 @@ along with this program. If not, see . #include #include +#include namespace KWin { @@ -45,6 +46,7 @@ MagnifierEffect::MagnifierEffect() , polling(false) , m_texture(0) , m_fbo(0) + , m_pixmap(0) { KActionCollection* actionCollection = new KActionCollection(this); KAction* a; @@ -63,11 +65,13 @@ MagnifierEffect::~MagnifierEffect() { delete m_fbo; delete m_texture; + delete m_pixmap; } bool MagnifierEffect::supported() { - return effects->compositingType() == OpenGLCompositing && GLRenderTarget::blitSupported(); + return effects->compositingType() == XRenderCompositing || + (effects->compositingType() == OpenGLCompositing && GLRenderTarget::blitSupported()); } void MagnifierEffect::reconfigure(ReconfigureFlags) @@ -91,8 +95,10 @@ void MagnifierEffect::prePaintScreen(ScreenPrePaintData& data, int time) // zoom ended - delete FBO and texture delete m_fbo; delete m_texture; + delete m_pixmap; m_fbo = NULL; m_texture = NULL; + m_pixmap = NULL; } } } @@ -108,51 +114,91 @@ void MagnifierEffect::paintScreen(int mask, QRegion region, ScreenPaintData& dat // get the right area from the current rendered screen const QRect area = magnifierArea(); const QPoint cursor = cursorPos(); - m_fbo->blitFromFramebuffer(QRect(cursor.x() - (double)area.width() / (zoom*2), cursor.y() - (double)area.height() / (zoom*2), - (double)area.width() / zoom, (double)area.height() / zoom)); - // paint magnifier - m_texture->bind(); - m_texture->render(infiniteRegion(), area); - m_texture->unbind(); - QVector verts; - GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer(); - vbo->reset(); - vbo->setColor(QColor(0, 0, 0)); - // top frame - verts << area.right() + FRAME_WIDTH << area.top() - FRAME_WIDTH; - verts << area.left() - FRAME_WIDTH << area.top() - FRAME_WIDTH; - verts << area.left() - FRAME_WIDTH << area.top() - 1; - verts << area.left() - FRAME_WIDTH << area.top() - 1; - verts << area.right() + FRAME_WIDTH << area.top() - 1; - verts << area.right() + FRAME_WIDTH << area.top() - FRAME_WIDTH; - // left frame - verts << area.left() - 1 << area.top() - FRAME_WIDTH; - verts << area.left() - FRAME_WIDTH << area.top() - FRAME_WIDTH; - verts << area.left() - FRAME_WIDTH << area.bottom() + FRAME_WIDTH; - verts << area.left() - FRAME_WIDTH << area.bottom() + FRAME_WIDTH; - verts << area.left() - 1 << area.bottom() + FRAME_WIDTH; - verts << area.left() - 1 << area.top() - FRAME_WIDTH; - // right frame - verts << area.right() + FRAME_WIDTH << area.top() - FRAME_WIDTH; - verts << area.right() + 1 << area.top() - FRAME_WIDTH; - verts << area.right() + 1 << area.bottom() + FRAME_WIDTH; - verts << area.right() + 1 << area.bottom() + FRAME_WIDTH; - verts << area.right() + FRAME_WIDTH << area.bottom() + FRAME_WIDTH; - verts << area.right() + FRAME_WIDTH << area.top() - FRAME_WIDTH; - // bottom frame - verts << area.right() + FRAME_WIDTH << area.bottom() + 1; - verts << area.left() - FRAME_WIDTH << area.bottom() + 1; - verts << area.left() - FRAME_WIDTH << area.bottom() + FRAME_WIDTH; - verts << area.left() - FRAME_WIDTH << area.bottom() + FRAME_WIDTH; - verts << area.right() + FRAME_WIDTH << area.bottom() + FRAME_WIDTH; - verts << area.right() + FRAME_WIDTH << area.bottom() + 1; - vbo->setData(verts.size() / 2, 2, verts.constData(), NULL); - if (ShaderManager::instance()->isValid()) { - ShaderManager::instance()->pushShader(ShaderManager::ColorShader); + + QRect srcArea(cursor.x() - (double)area.width() / (zoom*2), + cursor.y() - (double)area.height() / (zoom*2), + (double)area.width() / zoom, (double)area.height() / zoom); + if (effects->compositingType() == OpenGLCompositing) { + m_fbo->blitFromFramebuffer(srcArea); + // paint magnifier + m_texture->bind(); + m_texture->render(infiniteRegion(), area); + m_texture->unbind(); + QVector verts; + GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer(); + vbo->reset(); + vbo->setColor(QColor(0, 0, 0)); + // top frame + verts << area.right() + FRAME_WIDTH << area.top() - FRAME_WIDTH; + verts << area.left() - FRAME_WIDTH << area.top() - FRAME_WIDTH; + verts << area.left() - FRAME_WIDTH << area.top() - 1; + verts << area.left() - FRAME_WIDTH << area.top() - 1; + verts << area.right() + FRAME_WIDTH << area.top() - 1; + verts << area.right() + FRAME_WIDTH << area.top() - FRAME_WIDTH; + // left frame + verts << area.left() - 1 << area.top() - FRAME_WIDTH; + verts << area.left() - FRAME_WIDTH << area.top() - FRAME_WIDTH; + verts << area.left() - FRAME_WIDTH << area.bottom() + FRAME_WIDTH; + verts << area.left() - FRAME_WIDTH << area.bottom() + FRAME_WIDTH; + verts << area.left() - 1 << area.bottom() + FRAME_WIDTH; + verts << area.left() - 1 << area.top() - FRAME_WIDTH; + // right frame + verts << area.right() + FRAME_WIDTH << area.top() - FRAME_WIDTH; + verts << area.right() + 1 << area.top() - FRAME_WIDTH; + verts << area.right() + 1 << area.bottom() + FRAME_WIDTH; + verts << area.right() + 1 << area.bottom() + FRAME_WIDTH; + verts << area.right() + FRAME_WIDTH << area.bottom() + FRAME_WIDTH; + verts << area.right() + FRAME_WIDTH << area.top() - FRAME_WIDTH; + // bottom frame + verts << area.right() + FRAME_WIDTH << area.bottom() + 1; + verts << area.left() - FRAME_WIDTH << area.bottom() + 1; + verts << area.left() - FRAME_WIDTH << area.bottom() + FRAME_WIDTH; + verts << area.left() - FRAME_WIDTH << area.bottom() + FRAME_WIDTH; + verts << area.right() + FRAME_WIDTH << area.bottom() + FRAME_WIDTH; + verts << area.right() + FRAME_WIDTH << area.bottom() + 1; + vbo->setData(verts.size() / 2, 2, verts.constData(), NULL); + if (ShaderManager::instance()->isValid()) { + ShaderManager::instance()->pushShader(ShaderManager::ColorShader); + } + vbo->render(GL_TRIANGLES); + if (ShaderManager::instance()->isValid()) { + ShaderManager::instance()->popShader(); + } } - vbo->render(GL_TRIANGLES); - if (ShaderManager::instance()->isValid()) { - ShaderManager::instance()->popShader(); + if (effects->compositingType() == XRenderCompositing) { + if (!m_pixmap || m_pixmap->size() != srcArea.size()) { + delete m_pixmap; + m_pixmap = new QPixmap(srcArea.size()); + } + static XTransform identity = {{ + { XDoubleToFixed(1), XDoubleToFixed(0), XDoubleToFixed(0) }, + { XDoubleToFixed(0), XDoubleToFixed(1), XDoubleToFixed(0) }, + { XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1) } + } + }; + static XTransform xform = {{ + { XDoubleToFixed(1), XDoubleToFixed(0), XDoubleToFixed(0) }, + { XDoubleToFixed(0), XDoubleToFixed(1), XDoubleToFixed(0) }, + { XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1) } + } + }; + XRenderComposite( display(), PictOpSrc, effects->xrenderBufferPicture(), 0, m_pixmap->x11PictureHandle(), + srcArea.x(), srcArea.y(), 0, 0, 0, 0, srcArea.width(), srcArea.height() ); + XFlush(display()); + xform.matrix[0][0] = XDoubleToFixed(1.0/zoom); + xform.matrix[1][1] = XDoubleToFixed(1.0/zoom); + XRenderSetPictureTransform(display(), m_pixmap->x11PictureHandle(), &xform); + XRenderSetPictureFilter(display(), m_pixmap->x11PictureHandle(), const_cast("good"), NULL, 0); + XRenderComposite( display(), PictOpSrc, m_pixmap->x11PictureHandle(), 0, effects->xrenderBufferPicture(), + 0, 0, 0, 0, area.x(), area.y(), area.width(), area.height() ); + XRenderSetPictureFilter(display(), m_pixmap->x11PictureHandle(), const_cast("fast"), NULL, 0); + XRenderSetPictureTransform(display(), m_pixmap->x11PictureHandle(), &identity); + const XRectangle rects[4] = { { area.x()+FRAME_WIDTH, area.y(), area.width()-FRAME_WIDTH, FRAME_WIDTH}, + { area.right()-FRAME_WIDTH, area.y()+FRAME_WIDTH, FRAME_WIDTH, area.height()-FRAME_WIDTH}, + { area.x(), area.bottom()-FRAME_WIDTH, area.width()-FRAME_WIDTH, FRAME_WIDTH}, + { area.x(), area.y(), FRAME_WIDTH, area.height()-FRAME_WIDTH} }; + XRenderColor c = preMultiply(QColor(0,0,0,255)); + XRenderFillRectangles(display(), PictOpSrc, effects->xrenderBufferPicture(), &c, rects, 4); } } } @@ -199,8 +245,10 @@ void MagnifierEffect::zoomOut() if (zoom == target_zoom) { delete m_fbo; delete m_texture; + delete m_pixmap; m_fbo = NULL; m_texture = NULL; + m_pixmap = NULL; } } effects->addRepaint(magnifierArea().adjusted(-FRAME_WIDTH, -FRAME_WIDTH, FRAME_WIDTH, FRAME_WIDTH)); diff --git a/effects/magnifier/magnifier.h b/effects/magnifier/magnifier.h index b1b6f9e2b3..979685373a 100644 --- a/effects/magnifier/magnifier.h +++ b/effects/magnifier/magnifier.h @@ -58,6 +58,7 @@ private: QSize magnifier_size; GLTexture *m_texture; GLRenderTarget *m_fbo; + QPixmap *m_pixmap; }; } // namespace diff --git a/effects/snaphelper/snaphelper.cpp b/effects/snaphelper/snaphelper.cpp index bb44e50e8f..1c3ae22e26 100644 --- a/effects/snaphelper/snaphelper.cpp +++ b/effects/snaphelper/snaphelper.cpp @@ -21,13 +21,12 @@ along with this program. If not, see . #include "snaphelper.h" #include "kwinglutils.h" -//#include "kwinxrenderutils.h" +#include "kwinxrenderutils.h" namespace KWin { KWIN_EFFECT(snaphelper, SnapHelperEffect) -KWIN_EFFECT_SUPPORTED(snaphelper, SnapHelperEffect::supported()) SnapHelperEffect::SnapHelperEffect() : m_active(false) @@ -59,11 +58,6 @@ void SnapHelperEffect::reconfigure(ReconfigureFlags) m_timeline.setDuration(animationTime(250)); } -bool SnapHelperEffect::supported() -{ - return effects->compositingType() == OpenGLCompositing; -} - void SnapHelperEffect::prePaintScreen(ScreenPrePaintData &data, int time) { double oldValue = m_timeline.currentValue(); @@ -139,50 +133,48 @@ void SnapHelperEffect::postPaintScreen() glPopAttrib(); #endif } - /*if ( effects->compositingType() == XRenderCompositing ) - { // TODO - for ( int i = 0; i < effects->numScreens(); i++ ) - { + if ( effects->compositingType() == XRenderCompositing ) { + for ( int i = 0; i < effects->numScreens(); i++ ) { const QRect& rect = effects->clientArea( ScreenArea, i, 0 ); int midX = rect.x() + rect.width() / 2; int midY = rect.y() + rect.height() / 2 ; int halfWidth = m_window->width() / 2; int halfHeight = m_window->height() / 2; - XSegment segments[6]; - + XRectangle rects[6]; // Center lines - segments[0].x1 = rect.x() + rect.width() / 2; - segments[0].y1 = rect.y(); - segments[0].x2 = rect.x() + rect.width() / 2; - segments[0].y2 = rect.y() + rect.height(); - segments[1].x1 = rect.x(); - segments[1].y1 = rect.y() + rect.height() / 2; - segments[1].x2 = rect.x() + rect.width(); - segments[1].y2 = rect.y() + rect.height() / 2; + rects[0].x = rect.x() + rect.width() / 2 - 2; + rects[0].y = rect.y(); + rects[0].width = 4; + rects[0].height = rect.height(); + rects[1].x = rect.x(); + rects[1].y = rect.y() + rect.height() / 2 - 2; + rects[1].width = rect.width(); + rects[1].height = 4; // Window outline - // The +/- 2 is to prevent line overlap - segments[2].x1 = midX - halfWidth + 2; - segments[2].y1 = midY - halfHeight; - segments[2].x2 = midX + halfWidth + 2; - segments[2].y2 = midY - halfHeight; - segments[3].x1 = midX + halfWidth; - segments[3].y1 = midY - halfHeight + 2; - segments[3].x2 = midX + halfWidth; - segments[3].y2 = midY + halfHeight + 2; - segments[4].x1 = midX + halfWidth - 2; - segments[4].y1 = midY + halfHeight; - segments[4].x2 = midX - halfWidth - 2; - segments[4].y2 = midY + halfHeight; - segments[5].x1 = midX - halfWidth; - segments[5].y1 = midY + halfHeight - 2; - segments[5].x2 = midX - halfWidth; - segments[5].y2 = midY - halfHeight - 2; + // The +/- 4 is to prevent line overlap + rects[2].x = midX - halfWidth + 4; + rects[2].y = midY - halfHeight; + rects[2].width = 2*halfWidth - 4; + rects[2].height = 4; + rects[3].x = midX + halfWidth - 4; + rects[3].y = midY - halfHeight + 4; + rects[3].width = 4; + rects[3].height = 2*halfHeight - 4; + rects[4].x = midX - halfWidth; + rects[4].y = midY + halfHeight - 4; + rects[4].width = 2*halfWidth - 4; + rects[4].height = 4; + rects[5].x = midX - halfWidth; + rects[5].y = midY - halfHeight; + rects[5].width = 4; + rects[5].height = 2*halfHeight - 4; - XDrawSegments( display(), effects->xrenderBufferPicture(), m_gc, segments, 6 ); - } - }*/ + XRenderColor c = preMultiply(QColor(128, 128, 128, m_timeline.currentValue()*128)); + XRenderFillRectangles(display(), PictOpOver, effects->xrenderBufferPicture(), &c, rects, 6); + } + } } else if (m_window && !m_active) { if (m_window->isDeleted()) m_window->unrefWindow(); diff --git a/effects/snaphelper/snaphelper.h b/effects/snaphelper/snaphelper.h index 594fdf06ed..464ae3f080 100644 --- a/effects/snaphelper/snaphelper.h +++ b/effects/snaphelper/snaphelper.h @@ -41,8 +41,6 @@ public: virtual void postPaintScreen(); virtual bool isActive() const; - static bool supported(); - public Q_SLOTS: void slotWindowClosed(KWin::EffectWindow *w); void slotWindowStartUserMovedResized(KWin::EffectWindow *w); diff --git a/geometry.cpp b/geometry.cpp index 08a1518cb6..defe54b89d 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -2086,6 +2086,8 @@ void Client::changeMaximize(bool vertical, bool horizontal, bool adjust) { if (changeMaximizeRecursion) return; + + // sic! codeblock for TemporaryAssign { // isMovable() and isResizable() may be false for maximized windows // with moving/resizing maximized windows disabled @@ -2122,6 +2124,28 @@ void Client::changeMaximize(bool vertical, bool horizontal, bool adjust) else clientArea = workspace()->clientArea(MaximizeArea, this); + // save sizes for restoring, if maximalizing + QSize sz; + if (isShade()) + sz = sizeForClientSize(clientSize()); + else + sz = size(); + if (!adjust && !(old_mode & MaximizeVertical)) { + geom_restore.setTop(y()); + geom_restore.setHeight(sz.height()); + // we can fall from maximize to tiled + // TODO unify quicktiling and regular maximization + geom_pretile.setTop(y()); + geom_pretile.setHeight(sz.height()); + } + if (!adjust && !(old_mode & MaximizeHorizontal)) { + geom_restore.setLeft(x()); + geom_restore.setWidth(sz.width()); + // see above + geom_pretile.setLeft(x()); + geom_pretile.setWidth(sz.width()); + } + if (options->borderlessMaximizedWindows()) { // triggers a maximize change. // The next setNoBorder interation will exit since there's no change but the first recursion pullutes the restore/pretile geometry @@ -2130,23 +2154,6 @@ void Client::changeMaximize(bool vertical, bool horizontal, bool adjust) changeMaximizeRecursion = false; } - // save sizes for restoring, if maximalizing - if (!adjust && !(old_mode & MaximizeVertical)) { - geom_restore.setTop(y()); - geom_restore.setHeight(height()); - // we can fall from maximize to tiled - // TODO unify quicktiling and regular maximization - geom_pretile.setTop(y()); - geom_pretile.setHeight(height()); - } - if (!adjust && !(old_mode & MaximizeHorizontal)) { - geom_restore.setLeft(x()); - geom_restore.setWidth(width()); - // see above - geom_pretile.setLeft(x()); - geom_pretile.setWidth(width()); - } - if (!adjust) { if ((vertical && !(old_mode & MaximizeVertical)) || (horizontal && !(old_mode & MaximizeHorizontal))) diff --git a/layers.cpp b/layers.cpp index 212f9e71de..192adc55a7 100644 --- a/layers.cpp +++ b/layers.cpp @@ -515,20 +515,23 @@ ClientList Workspace::constrainedStackingOrder() kDebug(1212) << (void*)(*it) << *it << ":" << (*it)->layer(); #endif // build the order from layers - QHash< Group*, Layer > minimum_layer; - for (ClientList::ConstIterator it = unconstrained_stacking_order.constBegin(); - it != unconstrained_stacking_order.constEnd(); - ++it) { + QVector< QMap > minimum_layer(numScreens()); + for (ClientList::ConstIterator it = unconstrained_stacking_order.constBegin(), + end = unconstrained_stacking_order.constEnd(); it != end; ++it) { Layer l = (*it)->layer(); - // If a window is raised above some other window in the same window group - // which is in the ActiveLayer (i.e. it's fulscreened), make sure it stays - // above that window (see #95731). - if (minimum_layer.contains((*it)->group()) - && minimum_layer[(*it)->group()] == ActiveLayer - && (l == NormalLayer || l == AboveLayer)) { - l = minimum_layer[(*it)->group()]; + + const int screen = (*it)->screen(); + QMap< Group*, Layer >::iterator mLayer = minimum_layer[screen].find((*it)->group()); + if (mLayer != minimum_layer[screen].end()) { + // If a window is raised above some other window in the same window group + // which is in the ActiveLayer (i.e. it's fulscreened), make sure it stays + // above that window (see #95731). + if (*mLayer == ActiveLayer && (l == NormalLayer || l == AboveLayer)) + l = ActiveLayer; + *mLayer = l; + } else { + minimum_layer[screen].insertMulti((*it)->group(), l); } - minimum_layer[(*it)->group()] = l; layer[ l ].append(*it); } ClientList stacking;