From bdc1883fcffc447f43f8d0b97225a661086fab5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Tue, 6 Aug 2013 07:50:24 +0200 Subject: [PATCH 1/5] Better activation check in KillWindow If the grab keyboard fails we better do not activate the window killer otherwise we are in an inconsistent state. CCBUG: 323191 REVIEW: 111903 --- killwindow.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/killwindow.cpp b/killwindow.cpp index 92481a7db8..f12cab9c92 100644 --- a/killwindow.cpp +++ b/killwindow.cpp @@ -52,7 +52,6 @@ void KillWindow::start() if (m_active) { return; } - m_active = true; xcb_connection_t *c = connection(); ScopedCPointer grabPointer(xcb_grab_pointer_reply(c, xcb_grab_pointer_unchecked(c, false, rootWindow(), @@ -64,7 +63,11 @@ void KillWindow::start() if (grabPointer.isNull() || grabPointer->status != XCB_GRAB_STATUS_SUCCESS) { return; } - grabXKeyboard(); + m_active = grabXKeyboard(); + if (!m_active) { + xcb_ungrab_pointer(connection(), XCB_TIME_CURRENT_TIME); + return; + } grabXServer(); } From a61009b152d4cbc4a07137e5515ce65e9a13c5c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=B6glund?= Date: Sun, 7 Jul 2013 19:49:51 +0200 Subject: [PATCH 2/5] kwin: Make PaintRedirector work without NPOT texture support BUG: 321865 --- paintredirector.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/paintredirector.cpp b/paintredirector.cpp index c021549c74..982ab6f58b 100644 --- a/paintredirector.cpp +++ b/paintredirector.cpp @@ -348,6 +348,13 @@ void OpenGLPaintRedirector::resizePixmaps(const QRect *rects) size[TopBottom] = QSize(align(qMax(rects[TopPixmap].width(), rects[BottomPixmap].width()), 128), rects[TopPixmap].height() + rects[BottomPixmap].height()); + if (!GLTexture::NPOTTextureSupported()) { + for (int i = 0; i < 2; i++) { + size[i].rwidth() = nearestPowerOfTwo(size[i].width()); + size[i].rheight() = nearestPowerOfTwo(size[i].height()); + } + } + bool fbo_bound = false; for (int i = 0; i < 2; i++) { From ebfd3f58d8cd2a5e4e2be9c7cafb93632fbdaca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Wed, 3 Jul 2013 21:30:51 +0200 Subject: [PATCH 3/5] implement crossfading on xrender REVIEW: 111383 --- scene_xrender.cpp | 48 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/scene_xrender.cpp b/scene_xrender.cpp index b5c217228c..8d38a2e2ea 100644 --- a/scene_xrender.cpp +++ b/scene_xrender.cpp @@ -48,6 +48,10 @@ namespace KWin xcb_render_picture_t SceneXrender::buffer = XCB_RENDER_PICTURE_NONE; ScreenPaintData SceneXrender::screen_paint; +#define DOUBLE_TO_FIXED(d) ((xcb_render_fixed_t) ((d) * 65536)) +#define FIXED_TO_DOUBLE(f) ((double) ((f) / 65536.0)) + + static xcb_render_pictformat_t findFormatForVisual(xcb_visualid_t visual) { static QHash s_cache; @@ -445,7 +449,6 @@ void SceneXrender::Window::performPaint(int mask, QRegion region, WindowPaintDat if (toplevel->hasShadow()) transformed_shape |= toplevel->shadow()->shadowRegion(); -#define DOUBLE_TO_FIXED(d) ((xcb_render_fixed_t) ((d) * 65536)) xcb_render_transform_t xform = { DOUBLE_TO_FIXED(1), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(1), DOUBLE_TO_FIXED(0), @@ -479,7 +482,6 @@ void SceneXrender::Window::performPaint(int mask, QRegion region, WindowPaintDat } transformed_shape.setRects(rects.constData(), rects.count()); } -#undef DOUBLE_TO_FIXED transformed_shape.translate(mapToScreen(mask, data, QPoint(0, 0))); PaintClipper pcreg(region); // clip by the region to paint @@ -495,7 +497,8 @@ void SceneXrender::Window::performPaint(int mask, QRegion region, WindowPaintDat // the window has border // This solves a number of glitches and on top of this // it optimizes painting quite a bit - const bool blitInTempPixmap = xRenderOffscreen() || (scaled && (wantShadow || (client && !client->noBorder()) || (deleted && !deleted->noBorder()))); + const bool blitInTempPixmap = xRenderOffscreen() || (data.crossFadeProgress() < 1.0 && !opaque) || + (scaled && (wantShadow || (client && !client->noBorder()) || (deleted && !deleted->noBorder()))); xcb_render_picture_t renderTarget = buffer; if (blitInTempPixmap) { @@ -630,7 +633,38 @@ xcb_render_composite(connection(), XCB_RENDER_PICT_OP_OVER, m_xrenderShadow->pic if (!opaque) { clientAlpha = xRenderBlendPicture(data.opacity()); } - xcb_render_composite(connection(), clientRenderOp, pic, clientAlpha, renderTarget, cr.x(), cr.y(), 0, 0, dr.x(), dr.y(), dr.width(), dr.height()); + xcb_render_composite(connection(), clientRenderOp, pic, clientAlpha, renderTarget, + cr.x(), cr.y(), 0, 0, dr.x(), dr.y(), dr.width(), dr.height()); + if (data.crossFadeProgress() < 1.0 && data.crossFadeProgress() > 0.0) { + XRenderWindowPixmap *previous = previousWindowPixmap(); + if (previous && previous != pixmap) { + static XRenderPicture cFadeAlpha(XCB_RENDER_PICTURE_NONE); + static xcb_render_color_t cFadeColor = {0, 0, 0, 0}; + cFadeColor.alpha = uint16_t((1.0 - data.crossFadeProgress()) * 0xffff); + if (cFadeAlpha == XCB_RENDER_PICTURE_NONE) { + cFadeAlpha = xRenderFill(cFadeColor); + } else { + xcb_rectangle_t rect = {0, 0, 1, 1}; + xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, cFadeAlpha, cFadeColor , 1, &rect); + } + if (previous->size() != pixmap->size()) { + xcb_render_transform_t xform2 = { + DOUBLE_TO_FIXED(FIXED_TO_DOUBLE(xform.matrix11) * previous->size().width() / pixmap->size().width()), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), + DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(FIXED_TO_DOUBLE(xform.matrix22) * previous->size().height() / pixmap->size().height()), DOUBLE_TO_FIXED(0), + DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(0), DOUBLE_TO_FIXED(1) + }; + xcb_render_set_picture_transform(connection(), previous->picture(), xform2); + } + + xcb_render_composite(connection(), opaque ? XCB_RENDER_PICT_OP_OVER : XCB_RENDER_PICT_OP_ATOP, + previous->picture(), cFadeAlpha, renderTarget, + cr.x(), cr.y(), 0, 0, dr.x(), dr.y(), dr.width(), dr.height()); + + if (previous->size() != pixmap->size()) { + xcb_render_set_picture_transform(connection(), previous->picture(), identity); + } + } + } if (!opaque) transformed_shape = QRegion(); } @@ -926,7 +960,7 @@ void SceneXrender::EffectFrame::renderUnstyled(xcb_render_picture_t pict, const qreal x = roundness;//we start at angle = 0 qreal y = 0; - #define DOUBLE_TO_FIXED(d) ((xcb_render_fixed_t) ((d) * 65536)) + QVector points; xcb_render_pointfix_t point; point.x = DOUBLE_TO_FIXED(roundness); @@ -944,7 +978,6 @@ void SceneXrender::EffectFrame::renderUnstyled(xcb_render_picture_t pict, const XRenderPicture fill = xRenderFill(Qt::black); xcb_render_tri_fan(connection(), XCB_RENDER_PICT_OP_OVER, fill, *s_effectFrameCircle, 0, 0, 0, points.count(), points.constData()); - #undef DOUBLE_TO_FIXED } // TODO: merge alpha mask with SceneXrender::Window::alphaMask // alpha mask @@ -1096,5 +1129,8 @@ xcb_render_picture_t SceneXRenderShadow::picture(Shadow::ShadowElements element) return *m_pictures[element]; } +#undef DOUBLE_TO_FIXED +#undef FIXED_TO_DOUBLE + } // namespace #endif From c2219f973b95284ad04db94e4b9f44ba3a5bbcc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Wed, 3 Jul 2013 17:14:25 +0200 Subject: [PATCH 4/5] crossfade for resize effect REVIEW: 111383 --- effects/resize/resize.cpp | 14 +++++++++----- effects/resize/resize.h | 6 +++--- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/effects/resize/resize.cpp b/effects/resize/resize.cpp index b5c6a65287..a24e1241f7 100644 --- a/effects/resize/resize.cpp +++ b/effects/resize/resize.cpp @@ -37,7 +37,8 @@ namespace KWin KWIN_EFFECT(resize, ResizeEffect) ResizeEffect::ResizeEffect() - : m_active(false) + : AnimationEffect() + , m_active(false) , m_resizeWindow(0) { reconfigure(ReconfigureAll); @@ -55,14 +56,14 @@ void ResizeEffect::prePaintScreen(ScreenPrePaintData& data, int time) if (m_active) { data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; } - effects->prePaintScreen(data, time); + AnimationEffect::prePaintScreen(data, time); } void ResizeEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time) { if (m_active && w == m_resizeWindow) data.mask |= PAINT_WINDOW_TRANSFORMED; - effects->prePaintWindow(w, data, time); + AnimationEffect::prePaintWindow(w, data, time); } void ResizeEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) @@ -118,8 +119,9 @@ void ResizeEffect::paintWindow(EffectWindow* w, int mask, QRegion region, Window } #endif } - } else - effects->paintWindow(w, mask, region, data); + } else { + AnimationEffect::paintWindow(w, mask, region, data); + } } void ResizeEffect::reconfigure(ReconfigureFlags) @@ -148,6 +150,8 @@ void ResizeEffect::slotWindowFinishUserMovedResized(EffectWindow *w) if (m_active && w == m_resizeWindow) { m_active = false; m_resizeWindow = NULL; + if (m_features & TextureScale) + animate(w, CrossFadePrevious, 0, 150, FPx2(1.0)); effects->addRepaintFull(); } } diff --git a/effects/resize/resize.h b/effects/resize/resize.h index d900ea6adf..5b1610fe06 100644 --- a/effects/resize/resize.h +++ b/effects/resize/resize.h @@ -21,13 +21,13 @@ along with this program. If not, see . #ifndef KWIN_RESIZE_H #define KWIN_RESIZE_H -#include +#include namespace KWin { class ResizeEffect - : public Effect + : public AnimationEffect { Q_OBJECT Q_PROPERTY(bool textureScale READ isTextureScale) @@ -38,7 +38,7 @@ public: virtual inline bool provides(Effect::Feature ef) { return ef == Effect::Resize; } - inline bool isActive() const { return m_active; } + inline bool isActive() const { return m_active || AnimationEffect::isActive(); } virtual void prePaintScreen(ScreenPrePaintData& data, int time); virtual void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time); virtual void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data); From 3f33d0c2d5c3d5d425fba4d612aced5db5387cf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Tue, 6 Aug 2013 14:36:00 +0200 Subject: [PATCH 5/5] poll mouse at 20Hz required until there's a dynamic poll rate, because 10Hz is too low for magnifiers (lag), mousemark (paints too edgy), mouseclick (often fails because it's easy to cycle the button state within 100ms) - and the bouncing icon lags behind the mouse as well ;-) REVIEW: 111909 --- cursor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cursor.cpp b/cursor.cpp index 8ec8511e2e..5e35a209e7 100644 --- a/cursor.cpp +++ b/cursor.cpp @@ -166,7 +166,7 @@ X11Cursor::X11Cursor(QObject *parent) m_resetTimeStampTimer->setSingleShot(true); connect(m_resetTimeStampTimer, SIGNAL(timeout()), SLOT(resetTimeStamp())); // TODO: How often do we really need to poll? - m_mousePollingTimer->setInterval(100); + m_mousePollingTimer->setInterval(50); connect(m_mousePollingTimer, SIGNAL(timeout()), SLOT(mousePolled())); }