[effects] Make Scale and Glide effects Wayland-friendly

Summary:
The Scale effect and the Glide effect have to animate only ordinary
windows(i.e. the ones that are considered to be apps).

On X11, in order to distinguish ordinary windows from combo box popups,
popup menus, and other popups, those effects check whether given window
is managed.

On Wayland, there is no concept of managed/unmanaged windows.

XDG Shell protocol defines 2 surface roles:
* xdg_toplevel;
* and, xdg_popup.

The former can be used to implement typical windows, the ones that can
be minimized, maximized, etc.

The latter can be used to implement tooltips, popup menus, etc. Thus,
that's a good criteria to filter popup windows.

CCBUG: 398100

Reviewers: #kwin, graesslin, davidedmundson

Reviewed By: #kwin, graesslin, davidedmundson

Subscribers: davidedmundson, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D15117
icc-effect-5.17.5
Vlad Zagorodniy 2018-10-08 21:08:13 +03:00
parent 66a91f0861
commit 769f2659dd
7 changed files with 116 additions and 2 deletions

View File

@ -313,7 +313,14 @@ bool GlideEffect::isGlideWindow(EffectWindow *w) const
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;
}

View File

@ -274,7 +274,14 @@ bool ScaleEffect::isScaleWindow(EffectWindow *w) const
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;
}

View File

@ -776,6 +776,9 @@ public:
EffectWindow *q;
bool managed = false;
bool waylandClient;
bool x11Client;
bool popupWindow;
};
EffectWindow::Private::Private(EffectWindow *q)
@ -795,6 +798,10 @@ EffectWindow::EffectWindow(QObject *parent)
// 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<bool>();
d->waylandClient = parent->inherits("KWin::ShellClient");
d->x11Client = !d->waylandClient;
d->popupWindow = parent->property("popupWindow").value<bool>();
}
EffectWindow::~EffectWindow()
@ -992,6 +999,20 @@ bool EffectWindow::isManaged() const
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

View File

@ -1979,6 +1979,29 @@ class KWINEFFECTS_EXPORT EffectWindow : public QObject
* @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 @@ public:
*/
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.
*

View File

@ -1768,4 +1768,15 @@ void ShellClient::updateClientOutputs()
surface()->setOutputs(clientOutputs);
}
bool ShellClient::isPopupWindow() const
{
if (m_shellSurface != nullptr) {
return m_shellSurface->isPopup();
}
if (m_xdgShellPopup != nullptr) {
return true;
}
return false;
}
}

View File

@ -166,6 +166,8 @@ public:
void updateColorScheme() override;
bool isPopupWindow() const override;
protected:
void addDamage(const QRegion &damage) override;
bool belongsToSameApplication(const AbstractClient *other, SameApplicationChecks checks) const override;

View File

@ -210,6 +210,11 @@ class KWIN_EXPORT Toplevel
*/
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 @@ public:
template <class T, class U>
static T *findInList(const QList<T*> &list, std::function<bool (const U*)> 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 @@ inline T *Toplevel::findInList(const QList<T*> &list, std::function<bool (const
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&);