[wayland] Make sure that only the fading popups effect animates outline

Summary:
Window open/close animation effects should not animate the outline
because the end result is a bit awkward.

Reviewers: #kwin, davidedmundson

Reviewed By: #kwin, davidedmundson

Subscribers: kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D19886
This commit is contained in:
Vlad Zagorodniy 2019-03-19 16:01:29 +02:00
parent 02a5a08a6c
commit 3d46801e5f
16 changed files with 95 additions and 0 deletions

View file

@ -248,6 +248,9 @@ public:
bool isX11Client() const override {
return false;
}
bool isOutline() const override {
return false;
}
private:
qreal m_opacity = 1.0;

View file

@ -53,6 +53,7 @@ Deleted::Deleted()
, m_wasWaylandClient(false)
, m_wasGroupTransient(false)
, m_wasPopupWindow(false)
, m_wasOutline(false)
{
}
@ -149,6 +150,7 @@ void Deleted::copyToDeleted(Toplevel* c)
m_wasWaylandClient = qobject_cast<ShellClient *>(c) != nullptr;
m_wasX11Client = !m_wasWaylandClient;
m_wasPopupWindow = c->isPopupWindow();
m_wasOutline = c->isOutline();
}
void Deleted::unrefWindow()

View file

@ -177,6 +177,13 @@ public:
QVector<uint> x11DesktopIds() const;
/**
* Whether this Deleted represents the outline.
**/
bool isOutline() const override {
return m_wasOutline;
}
protected:
virtual void debug(QDebug& stream) const;
@ -229,6 +236,7 @@ private:
ToplevelList m_transientFor;
DeletedList m_transients;
bool m_wasPopupWindow;
bool m_wasOutline;
};
inline void Deleted::refWindow()

View file

@ -1832,6 +1832,7 @@ TOPLEVEL_HELPER(QStringList, activities, activities)
TOPLEVEL_HELPER(bool, skipsCloseAnimation, skipsCloseAnimation)
TOPLEVEL_HELPER(KWayland::Server::SurfaceInterface *, surface, surface)
TOPLEVEL_HELPER(bool, isPopupWindow, isPopupWindow)
TOPLEVEL_HELPER(bool, isOutline, isOutline)
#undef TOPLEVEL_HELPER

View file

@ -442,6 +442,7 @@ public:
bool keepBelow() const override;
bool isModal() const override;
bool isPopupWindow() const override;
bool isOutline() const override;
KWayland::Server::SurfaceInterface *surface() const override;
bool isFullScreen() const override;

View file

@ -43,6 +43,9 @@ function isFadeWindow(w) {
if (!w.visible) {
return false;
}
if (w.outline) {
return false;
}
if (w.deleted && effect.isGrabbed(w, Effect.WindowClosedGrabRole)) {
return false;
} else if (!w.deleted && effect.isGrabbed(w, Effect.WindowAddedGrabRole)) {

View file

@ -42,6 +42,11 @@ function isPopupWindow(window) {
return true;
}
// Maybe the outline deserves its own effect.
if (window.outline) {
return true;
}
// Override-redirect windows are usually used for user interface
// concepts that are expected to be animated by this effect, e.g.
// popups that contain window thumbnails on X11, etc.

View file

@ -319,6 +319,11 @@ bool GlideEffect::isGlideWindow(EffectWindow *w) const
return false;
}
// Dont't animate the outline because it looks very sick.
if (w->isOutline()) {
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()) {

View file

@ -66,6 +66,11 @@ var scaleEffect = {
return false;
}
// Dont't animate the outline because it looks very sick.
if (window.outline) {
return false;
}
// Override-redirect windows are usually used for user interface
// concepts that are not expected to be animated by this effect.
if (window.x11Client && !window.managed) {

View file

@ -211,6 +211,14 @@ bool InternalClient::isInputMethod() const
return false;
}
bool InternalClient::isOutline() const
{
if (m_internalWindow) {
return m_internalWindow->property("__kwin_outline").toBool();
}
return false;
}
quint32 InternalClient::windowId() const
{
return m_windowId;

View file

@ -55,6 +55,7 @@ public:
bool isInternal() const override;
bool isLockScreen() const override;
bool isInputMethod() const override;
bool isOutline() const override;
quint32 windowId() const override;
using AbstractClient::resizeWithChecks;
void resizeWithChecks(int w, int h, ForceGeometry_t force = NormalGeometrySet) override;

View file

@ -2066,6 +2066,15 @@ class KWINEFFECTS_EXPORT EffectWindow : public QObject
**/
Q_PROPERTY(QWindow *internalWindow READ internalWindow CONSTANT)
/**
* Whether this EffectWindow represents the outline.
*
* When compositing is turned on, the outline is an actual window.
*
* @since 5.16
**/
Q_PROPERTY(bool outline READ isOutline CONSTANT)
public:
/** Flags explaining why painting should be disabled */
enum {
@ -2354,6 +2363,11 @@ public:
**/
virtual QWindow *internalWindow() const = 0;
/**
* @since 5.16
**/
virtual bool isOutline() const = 0;
/**
* Can be used to by effects to store arbitrary data in the EffectWindow.
*

View file

@ -180,6 +180,9 @@ void CompositedOutlineVisual::show()
} else {
m_mainItem.reset(m_qmlComponent->create(m_qmlContext.data()));
}
if (auto w = qobject_cast<QQuickWindow *>(m_mainItem.data())) {
w->setProperty("__kwin_outline", true);
}
}
}

View file

@ -216,6 +216,13 @@ class KWIN_EXPORT Toplevel
**/
Q_PROPERTY(bool popupWindow READ isPopupWindow)
/**
* Whether this Toplevel represents the outline.
*
* @note It's always @c false if compositing is turned off.
**/
Q_PROPERTY(bool outline READ isOutline)
public:
explicit Toplevel();
virtual xcb_window_t frameId() const;
@ -283,6 +290,7 @@ public:
virtual bool isLockScreen() const;
virtual bool isInputMethod() const;
virtual bool isOutline() const;
/**
* Returns the virtual desktop within the workspace() the client window
@ -764,6 +772,11 @@ inline bool Toplevel::isInputMethod() const
return false;
}
inline bool Toplevel::isOutline() const
{
return false;
}
inline QRegion Toplevel::damage() const
{
return damage_region;

View file

@ -28,6 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QTimer>
#include <QDebug>
#include <QWindow>
#include <xcb/shape.h>
@ -81,6 +82,9 @@ bool Unmanaged::track(Window w)
getWmOpaqueRegion();
getSkipCloseAnimation();
setupCompositing();
if (QWindow *internalWindow = findInternalWindow()) {
m_outline = internalWindow->property("__kwin_outline").toBool();
}
if (effects)
static_cast<EffectsHandlerImpl*>(effects)->checkInputWindowStacking();
return true;
@ -159,11 +163,27 @@ NET::WindowType Unmanaged::windowType(bool direct, int supportedTypes) const
return info->windowType(NET::WindowTypes(supportedTypes));
}
bool Unmanaged::isOutline() const
{
return m_outline;
}
void Unmanaged::addDamage(const QRegion &damage)
{
repaints_region += damage;
Toplevel::addDamage(damage);
}
QWindow *Unmanaged::findInternalWindow() const
{
const QWindowList windows = kwinApp()->topLevelWindows();
for (QWindow *w : windows) {
if (w->winId() == window()) {
return w;
}
}
return nullptr;
}
} // namespace

View file

@ -47,6 +47,7 @@ public:
return UnmanagedLayer;
}
NET::WindowType windowType(bool direct = false, int supported_types = 0) const;
bool isOutline() const override;
public Q_SLOTS:
void release(ReleaseReason releaseReason = ReleaseReason::Release);
@ -57,6 +58,8 @@ private:
virtual ~Unmanaged(); // use release()
// handlers for X11 events
void configureNotifyEvent(xcb_configure_notify_event_t *e);
QWindow *findInternalWindow() const;
bool m_outline = false;
};
} // namespace