From 4babec999165df5bf6590757341eebe5dc7940fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Mon, 11 Mar 2013 16:19:16 +0100 Subject: [PATCH 1/3] keep + track m_closeWindow to keep m_winData alive BUG: 259640 FIXED-IN: 4.10.2 REVIEW: 109509 --- effects/presentwindows/presentwindows.cpp | 26 +++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/effects/presentwindows/presentwindows.cpp b/effects/presentwindows/presentwindows.cpp index 7a59aece8c..79baadb958 100755 --- a/effects/presentwindows/presentwindows.cpp +++ b/effects/presentwindows/presentwindows.cpp @@ -64,6 +64,7 @@ PresentWindowsEffect::PresentWindowsEffect() , m_highlightedWindow(NULL) , m_filterFrame(NULL) , m_closeView(NULL) + , m_closeWindow(NULL) , m_dragInProgress(false) , m_dragWindow(NULL) , m_highlightedDropTarget(NULL) @@ -217,7 +218,7 @@ void PresentWindowsEffect::postPaintScreen() { if (m_motionManager.areWindowsMoving()) effects->addRepaintFull(); - else if (!m_activated && m_motionManager.managingWindows()) { + else if (!m_activated && m_motionManager.managingWindows() && !m_closeWindow) { // We have finished moving them back, stop processing m_motionManager.unmanageAll(); @@ -261,7 +262,7 @@ void PresentWindowsEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &d { // TODO: We should also check to see if any windows are fading just in case fading takes longer // than moving the windows when the effect is deactivated. - if (m_activated || m_motionManager.areWindowsMoving()) { + if (m_activated || m_motionManager.areWindowsMoving() || m_closeWindow) { DataHash::iterator winData = m_windowData.find(w); if (winData == m_windowData.end()) { effects->prePaintWindow(w, data, time); @@ -306,6 +307,9 @@ void PresentWindowsEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &d // we have to keep the window in the list to prevent flickering winData->referenced = false; w->unrefWindow(); + if (w == m_closeWindow) { + m_closeWindow = NULL; + } } else w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DELETE); } @@ -437,6 +441,15 @@ void PresentWindowsEffect::slotWindowAdded(EffectWindow *w) rearrangeWindows(); } if (m_closeView && w == effects->findWindow(m_closeView->winId())) { + if (m_closeWindow != w) { + DataHash::iterator winDataIt = m_windowData.find(m_closeWindow); + if (winDataIt != m_windowData.end()) { + if (winDataIt->referenced) { + m_closeWindow->unrefWindow(); + } + m_windowData.erase(winDataIt); + } + } winData->visible = true; winData->highlight = 1.0; m_closeWindow = w; @@ -452,13 +465,14 @@ void PresentWindowsEffect::slotWindowClosed(EffectWindow *w) if (winData == m_windowData.end()) return; winData->deleted = true; - winData->referenced = true; - w->refWindow(); + if (!winData->referenced) { + winData->referenced = true; + w->refWindow(); + } if (m_highlightedWindow == w) setHighlightedWindow(findFirstWindow()); if (m_closeWindow == w) { - m_closeWindow = 0; - return; // don't rearrange + return; // don't rearrange, get's nulled when unref'd } rearrangeWindows(); From 4e1944ef53ea43b27436dfc04a6017ea82788384 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Mon, 18 Mar 2013 17:08:58 +0100 Subject: [PATCH 2/3] catch geometry updates of moving clients and bind geometry change signals dynamically REVIEW: 109570 (cherry picked from commit eb2db41304f1ec1e597e9bd282a9c4f0b7dd1e54) Conflicts: kwin/libkwineffects/kwinanimationeffect.cpp --- libkwineffects/kwinanimationeffect.cpp | 40 ++++++++++++++++---------- libkwineffects/kwinanimationeffect.h | 1 + 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/libkwineffects/kwinanimationeffect.cpp b/libkwineffects/kwinanimationeffect.cpp index 9709be4517..4da2a98b54 100644 --- a/libkwineffects/kwinanimationeffect.cpp +++ b/libkwineffects/kwinanimationeffect.cpp @@ -58,10 +58,6 @@ void AnimationEffect::init() * and has pot. started an animation so we have the window in our hash :) */ connect ( effects, SIGNAL(windowClosed(KWin::EffectWindow*)), SLOT(_windowClosed(KWin::EffectWindow*)) ); connect ( effects, SIGNAL(windowDeleted(KWin::EffectWindow*)), SLOT(_windowDeleted(KWin::EffectWindow*)) ); - connect ( effects, SIGNAL(windowGeometryShapeChanged(KWin::EffectWindow*, const QRect&)), - SLOT(_expandedGeometryChanged(KWin::EffectWindow*, const QRect&)) ); - connect ( effects, SIGNAL(windowPaddingChanged(KWin::EffectWindow*, const QRect&)), - SLOT(_expandedGeometryChanged(KWin::EffectWindow*, const QRect&)) ); } bool AnimationEffect::isActive() const @@ -176,6 +172,14 @@ void AnimationEffect::animate( EffectWindow *w, Attribute a, uint meta, int ms, } Q_D(AnimationEffect); + if (d->m_animations.isEmpty()) { + connect (effects, SIGNAL(windowGeometryShapeChanged( KWin::EffectWindow*, const QRect&)), + SLOT(_expandedGeometryChanged( KWin::EffectWindow*, const QRect&))); + connect (effects, SIGNAL(windowStepUserMovedResized( KWin::EffectWindow*, const QRect&)), + SLOT(_expandedGeometryChanged( KWin::EffectWindow*, const QRect&))); + connect (effects, SIGNAL(windowPaddingChanged( KWin::EffectWindow*, const QRect&)), + SLOT(_expandedGeometryChanged( KWin::EffectWindow*, const QRect&))); + } AniMap::iterator it = d->m_animations.find(w); if (it == d->m_animations.end()) it = d->m_animations.insert(w, QPair, QRect>(QList(), QRect())); @@ -267,17 +271,14 @@ void AnimationEffect::prePaintScreen( ScreenPrePaintData& data, int time ) } } - // NOTICE PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_WITHOUT_FULL_REPAINTS and thus now no flag should be required - // ... unless we start to get glitches ;-) -// if ( transformed ) -// data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_WITHOUT_FULL_REPAINTS; //PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; - // janitorial... - if ( !(d->m_animations.count() || d->m_zombies.isEmpty()) ) - { - foreach ( EffectWindow *w, d->m_zombies ) - w->unrefWindow(); - d->m_zombies.clear(); + if (d->m_animations.isEmpty()) { + disconnectGeometryChanges(); + if (!d->m_zombies.isEmpty()) { // this is actually not supposed to happen + foreach (EffectWindow *w, d->m_zombies) + w->unrefWindow(); + d->m_zombies.clear(); + } } effects->prePaintScreen(data, time); @@ -365,6 +366,16 @@ void AnimationEffect::clipWindow(const EffectWindow *w, const AniData &anim, Win } } +void AnimationEffect::disconnectGeometryChanges() +{ + disconnect (effects,SIGNAL(windowGeometryShapeChanged( KWin::EffectWindow*, const QRect&)), + this, SLOT(_expandedGeometryChanged( KWin::EffectWindow*, const QRect&))); + disconnect (effects,SIGNAL(windowStepUserMovedResized( KWin::EffectWindow*, const QRect&)), + this, SLOT(_expandedGeometryChanged( KWin::EffectWindow*, const QRect&))); + disconnect (effects,SIGNAL(windowPaddingChanged( KWin::EffectWindow*, const QRect&)), + this, SLOT(_expandedGeometryChanged( KWin::EffectWindow*, const QRect&))); +} + void AnimationEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) { @@ -755,7 +766,6 @@ region_creation: void AnimationEffect::_expandedGeometryChanged(KWin::EffectWindow *w, const QRect &old) { - Q_UNUSED(old) Q_D(AnimationEffect); AniMap::const_iterator entry = d->m_animations.constFind(w); if (entry != d->m_animations.constEnd()) { diff --git a/libkwineffects/kwinanimationeffect.h b/libkwineffects/kwinanimationeffect.h index 76a5b9b504..9516bdaff1 100644 --- a/libkwineffects/kwinanimationeffect.h +++ b/libkwineffects/kwinanimationeffect.h @@ -174,6 +174,7 @@ private: void clipWindow(const EffectWindow *, const AniData &, WindowQuadList &) const; float interpolated( const AniData&, int i = 0 ) const; float progress( const AniData& ) const; + void disconnectGeometryChanges(); void updateLayerRepaints(); private Q_SLOTS: void init(); From c4d450455bb7af04bc86b0791d061fd548701800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Wed, 20 Mar 2013 20:19:35 +0100 Subject: [PATCH 3/3] catch maximized windows in ::keepInArea BUG: 317068 FIXED-IN: 4.10.2 --- geometry.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/geometry.cpp b/geometry.cpp index 90b4273b70..b1d55ef766 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -836,9 +836,9 @@ void Client::keepInArea(QRect area, bool partial) if (area.width() < width() || area.height() < height()) resizeWithChecks(qMin(area.width(), width()), qMin(area.height(), height())); } - if (geometry().right() > area.right() && width() < area.width()) + if (geometry().right() > area.right() && width() <= area.width()) move(area.right() - width() + 1, y()); - if (geometry().bottom() > area.bottom() && height() < area.height()) + if (geometry().bottom() > area.bottom() && height() <= area.height()) move(x(), area.bottom() - height() + 1); if (!area.contains(geometry().topLeft())) { int tx = x();