diff --git a/effects/glide/glide.cpp b/effects/glide/glide.cpp --- a/effects/glide/glide.cpp +++ b/effects/glide/glide.cpp @@ -313,7 +313,14 @@ return true; } - if (!w->isManaged()) { + // Don't animate combobox popups, tooltips, popup menus, etc. + if (w->isPopupWindow()) { + return false; + } + + // Override-redirect windows are usually used for user interface + // concepts that are not expected to be animated by this effect. + if (w->isX11Client() && !w->isManaged()) { return false; } diff --git a/effects/scale/scale.cpp b/effects/scale/scale.cpp --- a/effects/scale/scale.cpp +++ b/effects/scale/scale.cpp @@ -274,7 +274,14 @@ return true; } - if (!w->isManaged()) { + // Don't animate combobox popups, tooltips, popup menus, etc. + if (w->isPopupWindow()) { + return false; + } + + // Override-redirect windows are usually used for user interface + // concepts that are not expected to be animated by this effect. + if (w->isX11Client() && !w->isManaged()) { return false; } diff --git a/libkwineffects/kwineffects.h b/libkwineffects/kwineffects.h --- a/libkwineffects/kwineffects.h +++ b/libkwineffects/kwineffects.h @@ -1979,6 +1979,29 @@ * @since 5.10 */ Q_PROPERTY(bool unresponsive READ isUnresponsive) + + /** + * Whether this is a Wayland client. + * @since 5.15 + **/ + Q_PROPERTY(bool waylandClient READ isWaylandClient CONSTANT) + + /** + * Whether this is an X11 client. + * @since 5.15 + **/ + Q_PROPERTY(bool x11Client READ isX11Client CONSTANT) + + /** + * Whether the window is a popup. + * + * A popup is a window that can be used to implement tooltips, combo box popups, + * popup menus and other similar user interface concepts. + * + * @since 5.15 + **/ + Q_PROPERTY(bool popupWindow READ isPopupWindow CONSTANT) + public: /** Flags explaining why painting should be disabled */ enum { @@ -2230,6 +2253,21 @@ */ bool isUnresponsive() const; + /** + * @since 5.15 + **/ + bool isWaylandClient() const; + + /** + * @since 5.15 + **/ + bool isX11Client() const; + + /** + * @since 5.15 + **/ + bool isPopupWindow() 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 @@ -776,6 +776,9 @@ EffectWindow *q; bool managed = false; + bool waylandClient; + bool x11Client; + bool popupWindow; }; EffectWindow::Private::Private(EffectWindow *q) @@ -795,6 +798,10 @@ // 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 = parent->inherits("KWin::ShellClient"); + d->x11Client = !d->waylandClient; + d->popupWindow = parent->property("popupWindow").value(); } EffectWindow::~EffectWindow() @@ -992,6 +999,20 @@ return d->managed; } +bool EffectWindow::isWaylandClient() const +{ + return d->waylandClient; +} + +bool EffectWindow::isX11Client() const +{ + return d->x11Client; +} + +bool EffectWindow::isPopupWindow() const +{ + return d->popupWindow; +} //**************************************** // EffectWindowGroup diff --git a/shell_client.h b/shell_client.h --- a/shell_client.h +++ b/shell_client.h @@ -166,6 +166,8 @@ void updateColorScheme() override; + bool isPopupWindow() const override; + protected: void addDamage(const QRegion &damage) override; bool belongsToSameApplication(const AbstractClient *other, SameApplicationChecks checks) const override; diff --git a/shell_client.cpp b/shell_client.cpp --- a/shell_client.cpp +++ b/shell_client.cpp @@ -1768,4 +1768,15 @@ surface()->setOutputs(clientOutputs); } +bool ShellClient::isPopupWindow() const +{ + if (m_shellSurface != nullptr) { + return m_shellSurface->isPopup(); + } + if (m_xdgShellPopup != nullptr) { + return true; + } + return false; +} + } diff --git a/toplevel.h b/toplevel.h --- a/toplevel.h +++ b/toplevel.h @@ -210,6 +210,11 @@ */ Q_PROPERTY(KWayland::Server::SurfaceInterface *surface READ surface) + /** + * Whether the window is a popup. + **/ + Q_PROPERTY(bool popupWindow READ isPopupWindow) + public: explicit Toplevel(); virtual xcb_window_t frameId() const; @@ -443,6 +448,15 @@ template static T *findInList(const QList &list, std::function func); + /** + * Whether the window is a popup. + * + * Popups can be used to implement popup menus, tooltips, combo boxes, etc. + * + * @since 5.15 + **/ + virtual bool isPopupWindow() const; + Q_SIGNALS: void opacityChanged(KWin::Toplevel* toplevel, qreal oldOpacity); void damaged(KWin::Toplevel* toplevel, const QRect& damage); @@ -846,6 +860,20 @@ return *it; } +inline bool Toplevel::isPopupWindow() const +{ + switch (windowType()) { + case NET::ComboBox: + case NET::DropdownMenu: + case NET::PopupMenu: + case NET::Tooltip: + return true; + + default: + return false; + } +} + QDebug& operator<<(QDebug& stream, const Toplevel*); QDebug& operator<<(QDebug& stream, const ToplevelList&);