diff --git a/effects/maximize/package/contents/code/maximize.js b/effects/maximize/package/contents/code/maximize.js
--- a/effects/maximize/package/contents/code/maximize.js
+++ b/effects/maximize/package/contents/code/maximize.js
@@ -17,25 +17,47 @@
along with this program. If not, see .
*********************************************************************/
/*global effect, effects, animate, animationTime, Effect*/
+
+// This effect depends on order in which windowGeometryShapeChanged
+// and windowMaximizedStateChanged signals are emitted. That order
+// is different for X11 and Wayland clients:
+//
+// On X11, those signals are emitted in the following order(for both
+// maximize and restore):
+// * windowGeometryShapeChanged
+// * windowGeometryShapeChanged
+// * windowGeometryShapeChanged
+// * windowMaximizedStateChanged
+//
+// we usually care only about geometries in the last windowGeometryShapeChanged.
+// The maximize animation should be started after windowMaximizedStateChanged
+// has been emitted.
+//
+// On Wayland, those signals are emitted in different order for both maximize
+// and restore:
+//
+// maximize:
+// * windowGeometryShapeChanged
+// * windowGeometryShapeChanged
+// * windowMaximizedStateChanged
+// * windowGeometryShapeChanged
+//
+// restore:
+// * windowGeometryShapeChanged
+// * windowMaximizedStateChanged
+// * windowGeometryShapeChanged
+//
+// in both cases, we care only about geometries in the last windowGeometryShapeChanged
+// signal. Thus, the maximize animation should be started after that signal is emitted.
+
var maximizeEffect = {
duration: animationTime(250),
loadConfig: function () {
"use strict";
maximizeEffect.duration = animationTime(250);
},
- maximizeChanged: function (window) {
- "use strict";
- if (!window.oldGeometry) {
- return;
- }
+ startAnimation: function (window, oldGeometry, newGeometry) {
window.setData(Effect.WindowForceBlurRole, true);
- var oldGeometry, newGeometry;
- oldGeometry = window.oldGeometry;
- newGeometry = window.geometry;
- if (oldGeometry.width == newGeometry.width && oldGeometry.height == newGeometry.height)
- oldGeometry = window.olderGeometry;
- window.olderGeometry = window.oldGeometry;
- window.oldGeometry = newGeometry;
window.maximizeAnimation1 = animate({
window: window,
duration: maximizeEffect.duration,
@@ -73,10 +95,20 @@
});
}
},
- restoreForceBlurState: function(window) {
- window.setData(Effect.WindowForceBlurRole, null);
+ maximizeChangedX11: function (window) {
+ "use strict";
+ if (!window.oldGeometry) {
+ return;
+ }
+ var oldGeometry = window.oldGeometry;
+ var newGeometry = window.geometry;
+ if (oldGeometry.width == newGeometry.width && oldGeometry.height == newGeometry.height)
+ oldGeometry = window.olderGeometry;
+ window.olderGeometry = window.oldGeometry;
+ window.oldGeometry = newGeometry;
+ maximizeEffect.startAnimation(window, oldGeometry, newGeometry);
},
- geometryChange: function (window, oldGeometry) {
+ geometryChangedX11: function (window, oldGeometry) {
"use strict";
if (window.maximizeAnimation1) {
if (window.geometry.width != window.oldGeometry.width ||
@@ -92,10 +124,40 @@
window.oldGeometry = window.geometry;
window.olderGeometry = oldGeometry;
},
+ maximizeChangedWayland: function (window) {
+ "use strict";
+ window.waylandCanStartAnimation = true;
+ },
+ geometryChangedWayland: function (window, oldGeometry) {
+ "use strict";
+ if (window.waylandCanStartAnimation) {
+ delete window.waylandCanStartAnimation;
+ maximizeEffect.startAnimation(window, oldGeometry, window.geometry);
+ }
+ },
+ maximizeChanged: function (window) {
+ "use strict";
+ if (window.waylandClient) {
+ maximizeEffect.maximizeChangedWayland(window);
+ } else {
+ maximizeEffect.maximizeChangedX11(window);
+ }
+ },
+ geometryChanged: function (window, oldGeometry) {
+ "use strict";
+ if (window.waylandClient) {
+ maximizeEffect.geometryChangedWayland(window, oldGeometry);
+ } else {
+ maximizeEffect.geometryChangedX11(window, oldGeometry);
+ }
+ },
+ restoreForceBlurState: function(window) {
+ window.setData(Effect.WindowForceBlurRole, null);
+ },
init: function () {
"use strict";
effect.configChanged.connect(maximizeEffect.loadConfig);
- effects.windowGeometryShapeChanged.connect(maximizeEffect.geometryChange);
+ effects.windowGeometryShapeChanged.connect(maximizeEffect.geometryChanged);
effects.windowMaximizedStateChanged.connect(maximizeEffect.maximizeChanged);
effect.animationEnded.connect(maximizeEffect.restoreForceBlurState);
}
diff --git a/libkwineffects/kwineffects.h b/libkwineffects/kwineffects.h
--- a/libkwineffects/kwineffects.h
+++ b/libkwineffects/kwineffects.h
@@ -1963,6 +1963,19 @@
* @since 5.10
*/
Q_PROPERTY(bool unresponsive READ isUnresponsive)
+
+ /**
+ * Whether this client is an X11 client.
+ * @since 5.XX
+ **/
+ Q_PROPERTY(bool x11Client READ isX11Client)
+
+ /**
+ * Whether this client is a Wayland client.
+ * @since 5.XX
+ **/
+ Q_PROPERTY(bool waylandClient READ isWaylandClient)
+
public:
/** Flags explaining why painting should be disabled */
enum {
@@ -2214,6 +2227,16 @@
*/
bool isUnresponsive() const;
+ /**
+ * @since 5.XX
+ **/
+ bool isX11Client() const;
+
+ /**
+ * @since 5.XX
+ **/
+ bool isWaylandClient() const;
+
/**
* Can be used to by effects to store arbitrary data in the EffectWindow.
*
diff --git a/libkwineffects/kwineffects.cpp b/libkwineffects/kwineffects.cpp
--- a/libkwineffects/kwineffects.cpp
+++ b/libkwineffects/kwineffects.cpp
@@ -775,6 +775,8 @@
EffectWindow *q;
bool managed = false;
+ bool x11Client;
+ bool waylandClient;
};
EffectWindow::Private::Private(EffectWindow *q)
@@ -794,6 +796,9 @@
// an instance of Deleted becomes parent of the EffectWindow, effects
// can still figure out whether it is/was a managed window.
d->managed = parent->property("managed").value();
+
+ d->waylandClient = qstrcmp(parent->metaObject()->className(), "KWin::ShellClient") == 0;
+ d->x11Client = !d->waylandClient; // parent can be either X11 or Wayland client.
}
EffectWindow::~EffectWindow()
@@ -991,6 +996,15 @@
return d->managed;
}
+bool EffectWindow::isX11Client() const
+{
+ return d->x11Client;
+}
+
+bool EffectWindow::isWaylandClient() const
+{
+ return d->waylandClient;
+}
//****************************************
// EffectWindowGroup