diff --git a/5_27_9_Patch.patch b/5_27_9_Patch.patch
new file mode 100644
index 0000000..0969f7b
--- /dev/null
+++ b/5_27_9_Patch.patch
@@ -0,0 +1,179 @@
+Subject: [PATCH] 5.27.9 Patch
+---
+Index: src/effects/slide/slide.kcfg
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+diff --git a/src/effects/slide/slide.kcfg b/src/effects/slide/slide.kcfg
+--- a/src/effects/slide/slide.kcfg (revision 9d677be2a82a781e6ab19216716d9e0d2dba6d53)
++++ b/src/effects/slide/slide.kcfg (date 1699986700881)
+@@ -6,11 +6,17 @@
+ http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
+
+
++
++ 0
++
+
+ 45
+
+
+ 20
++
++
++ false
+
+
+ true
+Index: src/effects/slide/slide.cpp
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+diff --git a/src/effects/slide/slide.cpp b/src/effects/slide/slide.cpp
+--- a/src/effects/slide/slide.cpp (revision 9d677be2a82a781e6ab19216716d9e0d2dba6d53)
++++ b/src/effects/slide/slide.cpp (date 1699986700867)
+@@ -25,6 +25,8 @@
+ initConfig();
+ reconfigure(ReconfigureAll);
+
++ m_timeLine.setEasingCurve(QEasingCurve::OutCubic);
++
+ connect(effects, QOverload::of(&EffectsHandler::desktopChanged),
+ this, &SlideEffect::desktopChanged);
+ connect(effects, QOverload::of(&EffectsHandler::desktopChanging),
+@@ -59,11 +61,8 @@
+ {
+ SlideConfig::self()->read();
+
+- const qreal springConstant = 300.0 / effects->animationTimeFactor();
+- const qreal dampingRatio = 1.1;
+-
+- m_motionX = SpringMotion(springConstant, dampingRatio);
+- m_motionY = SpringMotion(springConstant, dampingRatio);
++ m_fullAnimationDuration = animationTime(500);
++ m_timeLine.setDuration(std::chrono::milliseconds(m_fullAnimationDuration));
+
+ m_hGap = SlideConfig::horizontalGap();
+ m_vGap = SlideConfig::verticalGap();
+@@ -96,13 +95,10 @@
+ timeDelta = presentTime - m_lastPresentTime;
+ }
+ m_lastPresentTime = presentTime;
++ m_timeLine.update(timeDelta);
+
+ if (m_state == State::ActiveAnimation) {
+- m_motionX.advance(timeDelta);
+- m_motionY.advance(timeDelta);
+- const QSize virtualSpaceSize = effects->virtualScreenSize();
+- m_currentPosition.setX(m_motionX.position() / virtualSpaceSize.width());
+- m_currentPosition.setY(m_motionY.position() / virtualSpaceSize.height());
++ m_currentPosition = m_startPos + (m_endPos - m_startPos) * m_timeLine.value();
+ }
+
+ const int w = effects->desktopGridWidth();
+@@ -252,7 +248,7 @@
+
+ void SlideEffect::postPaintScreen()
+ {
+- if (m_state == State::ActiveAnimation && !m_motionX.isMoving() && !m_motionY.isMoving()) {
++ if (m_state == State::ActiveAnimation && m_timeLine.done()) {
+ finishedSwitching();
+ }
+
+@@ -295,6 +291,7 @@
+
+ m_state = State::ActiveAnimation;
+ m_movingWindow = movingWindow;
++ m_timeLine.reset();
+
+ m_startPos = m_currentPosition;
+ m_endPos = effects->desktopGridCoords(current);
+@@ -302,11 +299,19 @@
+ optimizePath();
+ }
+
+- const QSize virtualSpaceSize = effects->virtualScreenSize();
+- m_motionX.setAnchor(m_endPos.x() * virtualSpaceSize.width());
+- m_motionX.setPosition(m_startPos.x() * virtualSpaceSize.width());
+- m_motionY.setAnchor(m_endPos.y() * virtualSpaceSize.height());
+- m_motionY.setPosition(m_startPos.y() * virtualSpaceSize.height());
++ // Find an apropriate duration
++ QPointF distance = m_startPos - m_endPos;
++ distance.setX(std::abs(distance.x()));
++ distance.setY(std::abs(distance.y()));
++ if (distance.x() < 1 && distance.y() < 1) {
++ if (distance.x() > distance.y()) {
++ m_timeLine.setDuration(std::chrono::milliseconds(std::max(1, (int)(m_fullAnimationDuration * distance.x()))));
++ } else {
++ m_timeLine.setDuration(std::chrono::milliseconds(std::max(1, (int)(m_fullAnimationDuration * distance.y()))));
++ }
++ } else {
++ m_timeLine.setDuration(std::chrono::milliseconds(m_fullAnimationDuration));
++ }
+
+ effects->setActiveFullScreenEffect(this);
+ effects->addRepaintFull();
+Index: src/effects/slide/slide_config.ui
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+diff --git a/src/effects/slide/slide_config.ui b/src/effects/slide/slide_config.ui
+--- a/src/effects/slide/slide_config.ui (revision 9d677be2a82a781e6ab19216716d9e0d2dba6d53)
++++ b/src/effects/slide/slide_config.ui (date 1699986700887)
+@@ -12,6 +12,39 @@
+
+
+ -
++
++
-
++
++
++ Duration:
++
++
++
++ -
++
++
++
++ 0
++ 0
++
++
++
++ Default
++
++
++ milliseconds
++
++
++ 9999
++
++
++ 10
++
++
++
++
++
++ -
+
+
+ Gap between desktops
+@@ -64,6 +97,13 @@
+
+
+
++
++
++ -
++
++
++ Slide docks
++
+
+
+ -
diff --git a/PKGBUILD b/PKGBUILD
index fd7f122..38c1568 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -16,7 +16,7 @@ makedepends=(extra-cmake-modules qt5-tools kdoctools5 krunner5 wayland-protocols
optdepends=('maliit-keyboard: virtual keyboard for kwin-wayland')
replaces=(kwayland-server)
groups=(plasma)
-source=(https://download.kde.org/stable/plasma/$_dirver/$pkgname-$pkgver.tar.xz{,.sig} https://git.smiesznadomena.pl/kde-fix/kwin-patch/raw/branch/master/revert_mass-spring-damper_model_for_slide_animation.patch)
+source=(https://download.kde.org/stable/plasma/$_dirver/$pkgname-$pkgver.tar.xz{,.sig})
install=$pkgname.install
sha256sums=('d94f691fa6f88966d74d1307554cda59847d5907539f86e79171170a655578bb'
'SKIP'
@@ -27,8 +27,8 @@ validpgpkeys=('E0A3EB202F8E57528E13E72FD7574483BB57B18D' # Jonathan Esk-Riddell
'1FA881591C26B276D7A5518EEAAF29B42A678C20') # Marco Martin
build() {
- cd kwin-5.27.9
- git apply ../revert_mass-spring-damper_model_for_slide_animation.patch
+ cd $pkgname-$pkgver
+ patch -p1 < ../5_27_9_Patch.patch
cd ..
cmake -B build -S $pkgname-$pkgver \
-DCMAKE_INSTALL_LIBEXECDIR=lib \
diff --git a/revert_mass-spring-damper_model_for_slide_animation.patch b/revert_mass-spring-damper_model_for_slide_animation.patch
new file mode 100644
index 0000000..cb1d8ab
--- /dev/null
+++ b/revert_mass-spring-damper_model_for_slide_animation.patch
@@ -0,0 +1,179 @@
+Subject: [PATCH] revert mass-spring-damper model for slide animation
+---
+Index: src/effects/slide/slide.kcfg
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+diff --git a/src/effects/slide/slide.kcfg b/src/effects/slide/slide.kcfg
+--- a/src/effects/slide/slide.kcfg (revision 9ae6a9fc7377d72e8a320e1eca4dce7fba40205c)
++++ b/src/effects/slide/slide.kcfg (date 1699716587537)
+@@ -6,11 +6,17 @@
+ http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
+
+
++
++ 0
++
+
+ 45
+
+
+ 20
++
++
++ false
+
+
+ true
+Index: src/effects/slide/slide_config.ui
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+diff --git a/src/effects/slide/slide_config.ui b/src/effects/slide/slide_config.ui
+--- a/src/effects/slide/slide_config.ui (revision 9ae6a9fc7377d72e8a320e1eca4dce7fba40205c)
++++ b/src/effects/slide/slide_config.ui (date 1699716657985)
+@@ -12,6 +12,39 @@
+
+
+
-
++
++
-
++
++
++ Duration:
++
++
++
++ -
++
++
++
++ 0
++ 0
++
++
++
++ Default
++
++
++ milliseconds
++
++
++ 9999
++
++
++ 10
++
++
++
++
++
++ -
+
+
+ Gap between desktops
+@@ -64,6 +97,13 @@
+
+
+
++
++
++ -
++
++
++ Slide docks
++
+
+
+ -
+Index: src/effects/slide/slide.cpp
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+diff --git a/src/effects/slide/slide.cpp b/src/effects/slide/slide.cpp
+--- a/src/effects/slide/slide.cpp (revision 9ae6a9fc7377d72e8a320e1eca4dce7fba40205c)
++++ b/src/effects/slide/slide.cpp (date 1699716419773)
+@@ -26,6 +26,8 @@
+ initConfig();
+ reconfigure(ReconfigureAll);
+
++ m_timeLine.setEasingCurve(QEasingCurve::OutCubic);
++
+ connect(effects, &EffectsHandler::desktopChanged,
+ this, &SlideEffect::desktopChanged);
+ connect(effects, &EffectsHandler::desktopChanging,
+@@ -62,11 +64,8 @@
+ {
+ SlideConfig::self()->read();
+
+- const qreal springConstant = 300.0 / effects->animationTimeFactor();
+- const qreal dampingRatio = 1.1;
+-
+- m_motionX = SpringMotion(springConstant, dampingRatio);
+- m_motionY = SpringMotion(springConstant, dampingRatio);
++ m_fullAnimationDuration = animationTime(500);
++ m_timeLine.setDuration(std::chrono::milliseconds(m_fullAnimationDuration));
+
+ m_hGap = SlideConfig::horizontalGap();
+ m_vGap = SlideConfig::verticalGap();
+@@ -99,13 +98,10 @@
+ timeDelta = presentTime - m_lastPresentTime;
+ }
+ m_lastPresentTime = presentTime;
++ m_timeLine.update(timeDelta);
+
+ if (m_state == State::ActiveAnimation) {
+- m_motionX.advance(timeDelta);
+- m_motionY.advance(timeDelta);
+- const QSize virtualSpaceSize = effects->virtualScreenSize();
+- m_currentPosition.setX(m_motionX.position() / virtualSpaceSize.width());
+- m_currentPosition.setY(m_motionY.position() / virtualSpaceSize.height());
++ m_currentPosition = m_startPos + (m_endPos - m_startPos) * m_timeLine.value();
+ }
+
+ const QList desktops = effects->desktops();
+@@ -252,7 +248,7 @@
+
+ void SlideEffect::postPaintScreen()
+ {
+- if (m_state == State::ActiveAnimation && !m_motionX.isMoving() && !m_motionY.isMoving()) {
++ if (m_state == State::ActiveAnimation && m_timeLine.done()) {
+ finishedSwitching();
+ }
+
+@@ -295,6 +291,7 @@
+
+ m_state = State::ActiveAnimation;
+ m_movingWindow = movingWindow;
++ m_timeLine.reset();
+
+ m_startPos = m_currentPosition;
+ m_endPos = effects->desktopGridCoords(current);
+@@ -302,11 +299,19 @@
+ optimizePath();
+ }
+
+- const QSize virtualSpaceSize = effects->virtualScreenSize();
+- m_motionX.setAnchor(m_endPos.x() * virtualSpaceSize.width());
+- m_motionX.setPosition(m_startPos.x() * virtualSpaceSize.width());
+- m_motionY.setAnchor(m_endPos.y() * virtualSpaceSize.height());
+- m_motionY.setPosition(m_startPos.y() * virtualSpaceSize.height());
++ // Find an apropriate duration
++ QPointF distance = m_startPos - m_endPos;
++ distance.setX(std::abs(distance.x()));
++ distance.setY(std::abs(distance.y()));
++ if (distance.x() < 1 && distance.y() < 1) {
++ if (distance.x() > distance.y()) {
++ m_timeLine.setDuration(std::chrono::milliseconds(std::max(1, (int)(m_fullAnimationDuration * distance.x()))));
++ } else {
++ m_timeLine.setDuration(std::chrono::milliseconds(std::max(1, (int)(m_fullAnimationDuration * distance.y()))));
++ }
++ } else {
++ m_timeLine.setDuration(std::chrono::milliseconds(m_fullAnimationDuration));
++ }
+
+ effects->setActiveFullScreenEffect(this);
+ effects->addRepaintFull();