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;