scene/item: add ItemEffect
Right now it's just a helper to mark items as being affected by some effect, to prevent direct scanout of the relevant item without needing to block direct scanout for the whole screen
This commit is contained in:
parent
418143a45b
commit
18f1092728
17 changed files with 152 additions and 46 deletions
|
@ -71,7 +71,7 @@ void DontCrashCancelAnimationFromAnimationEndedTest::cleanup()
|
||||||
void DontCrashCancelAnimationFromAnimationEndedTest::testScript()
|
void DontCrashCancelAnimationFromAnimationEndedTest::testScript()
|
||||||
{
|
{
|
||||||
// load a scripted effect which deletes animation data
|
// load a scripted effect which deletes animation data
|
||||||
ScriptedEffect *effect = ScriptedEffect::create(QStringLiteral("crashy"), QFINDTESTDATA("data/anim-data-delete-effect/effect.js"), 10, QString(), true);
|
ScriptedEffect *effect = ScriptedEffect::create(QStringLiteral("crashy"), QFINDTESTDATA("data/anim-data-delete-effect/effect.js"), 10, QString());
|
||||||
QVERIFY(effect);
|
QVERIFY(effect);
|
||||||
|
|
||||||
const auto children = effects->children();
|
const auto children = effects->children();
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "effect/effecthandler.h"
|
#include "effect/effecthandler.h"
|
||||||
#include "opengl/gltexture.h"
|
#include "opengl/gltexture.h"
|
||||||
#include "opengl/glutils.h"
|
#include "opengl/glutils.h"
|
||||||
|
#include "scene/windowitem.h"
|
||||||
|
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
@ -34,6 +35,7 @@ public:
|
||||||
GLShader *m_shader = nullptr;
|
GLShader *m_shader = nullptr;
|
||||||
RenderGeometry::VertexSnappingMode m_vertexSnappingMode = RenderGeometry::VertexSnappingMode::Round;
|
RenderGeometry::VertexSnappingMode m_vertexSnappingMode = RenderGeometry::VertexSnappingMode::Round;
|
||||||
QMetaObject::Connection m_windowDamagedConnection;
|
QMetaObject::Connection m_windowDamagedConnection;
|
||||||
|
ItemEffect m_windowEffect;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OffscreenEffectPrivate
|
class OffscreenEffectPrivate
|
||||||
|
@ -65,7 +67,7 @@ void OffscreenEffect::redirect(EffectWindow *window)
|
||||||
}
|
}
|
||||||
offscreenData = std::make_unique<OffscreenData>();
|
offscreenData = std::make_unique<OffscreenData>();
|
||||||
offscreenData->setVertexSnappingMode(d->vertexSnappingMode);
|
offscreenData->setVertexSnappingMode(d->vertexSnappingMode);
|
||||||
|
offscreenData->m_windowEffect = ItemEffect(window->windowItem());
|
||||||
offscreenData->m_windowDamagedConnection =
|
offscreenData->m_windowDamagedConnection =
|
||||||
connect(window, &EffectWindow::windowDamaged, this, &OffscreenEffect::handleWindowDamaged);
|
connect(window, &EffectWindow::windowDamaged, this, &OffscreenEffect::handleWindowDamaged);
|
||||||
|
|
||||||
|
@ -274,6 +276,11 @@ void OffscreenEffect::setVertexSnappingMode(RenderGeometry::VertexSnappingMode m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OffscreenEffect::blocksDirectScanout() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
class CrossFadeWindowData : public OffscreenData
|
class CrossFadeWindowData : public OffscreenData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -356,6 +363,7 @@ void CrossFadeEffect::redirect(EffectWindow *window)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
offscreenData = std::make_unique<CrossFadeWindowData>();
|
offscreenData = std::make_unique<CrossFadeWindowData>();
|
||||||
|
offscreenData->m_windowEffect = ItemEffect(window->windowItem());
|
||||||
|
|
||||||
// Avoid including blur and contrast effects. During a normal painting cycle they
|
// Avoid including blur and contrast effects. During a normal painting cycle they
|
||||||
// won't be included, but since we call effects->drawWindow() outside usual compositing
|
// won't be included, but since we call effects->drawWindow() outside usual compositing
|
||||||
|
@ -393,6 +401,11 @@ void CrossFadeEffect::setShader(EffectWindow *window, GLShader *shader)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CrossFadeEffect::blocksDirectScanout() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace KWin
|
} // namespace KWin
|
||||||
|
|
||||||
#include "moc_offscreeneffect.cpp"
|
#include "moc_offscreeneffect.cpp"
|
||||||
|
|
|
@ -72,6 +72,8 @@ protected:
|
||||||
*/
|
*/
|
||||||
void setVertexSnappingMode(RenderGeometry::VertexSnappingMode mode);
|
void setVertexSnappingMode(RenderGeometry::VertexSnappingMode mode);
|
||||||
|
|
||||||
|
bool blocksDirectScanout() const override;
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void handleWindowDamaged(EffectWindow *window);
|
void handleWindowDamaged(EffectWindow *window);
|
||||||
void handleWindowDeleted(EffectWindow *window);
|
void handleWindowDeleted(EffectWindow *window);
|
||||||
|
@ -121,6 +123,8 @@ public:
|
||||||
**/
|
**/
|
||||||
void setShader(EffectWindow *window, GLShader *shader);
|
void setShader(EffectWindow *window, GLShader *shader);
|
||||||
|
|
||||||
|
bool blocksDirectScanout() const override;
|
||||||
|
|
||||||
static bool supported();
|
static bool supported();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
#include "core/rendertarget.h"
|
#include "core/rendertarget.h"
|
||||||
#include "core/renderviewport.h"
|
#include "core/renderviewport.h"
|
||||||
#include "effect/effecthandler.h"
|
#include "effect/effecthandler.h"
|
||||||
|
#include "scene/surfaceitem.h"
|
||||||
|
#include "scene/windowitem.h"
|
||||||
#include "wayland/contrast.h"
|
#include "wayland/contrast.h"
|
||||||
#include "wayland/display.h"
|
#include "wayland/display.h"
|
||||||
#include "wayland/surface.h"
|
#include "wayland/surface.h"
|
||||||
|
@ -174,6 +176,7 @@ void ContrastEffect::updateContrastRegion(EffectWindow *w)
|
||||||
Data &data = m_windowData[w];
|
Data &data = m_windowData[w];
|
||||||
data.colorMatrix = matrix;
|
data.colorMatrix = matrix;
|
||||||
data.contrastRegion = region;
|
data.contrastRegion = region;
|
||||||
|
data.surfaceEffect = ItemEffect(w->windowItem()->surfaceItem());
|
||||||
} else {
|
} else {
|
||||||
if (auto it = m_windowData.find(w); it != m_windowData.end()) {
|
if (auto it = m_windowData.find(w); it != m_windowData.end()) {
|
||||||
effects->makeOpenGLContextCurrent();
|
effects->makeOpenGLContextCurrent();
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "effect/effect.h"
|
#include "effect/effect.h"
|
||||||
#include "opengl/glplatform.h"
|
#include "opengl/glplatform.h"
|
||||||
#include "opengl/glutils.h"
|
#include "opengl/glutils.h"
|
||||||
|
#include "scene/item.h"
|
||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QVector2D>
|
#include <QVector2D>
|
||||||
|
@ -75,6 +76,7 @@ private:
|
||||||
QRegion contrastRegion;
|
QRegion contrastRegion;
|
||||||
std::unique_ptr<GLTexture> texture;
|
std::unique_ptr<GLTexture> texture;
|
||||||
std::unique_ptr<GLFramebuffer> fbo;
|
std::unique_ptr<GLFramebuffer> fbo;
|
||||||
|
ItemEffect surfaceEffect;
|
||||||
};
|
};
|
||||||
std::unordered_map<const EffectWindow *, Data> m_windowData;
|
std::unordered_map<const EffectWindow *, Data> m_windowData;
|
||||||
static ContrastManagerInterface *s_contrastManager;
|
static ContrastManagerInterface *s_contrastManager;
|
||||||
|
|
|
@ -15,6 +15,9 @@
|
||||||
#include "core/renderviewport.h"
|
#include "core/renderviewport.h"
|
||||||
#include "effect/effecthandler.h"
|
#include "effect/effecthandler.h"
|
||||||
#include "opengl/glplatform.h"
|
#include "opengl/glplatform.h"
|
||||||
|
#include "scene/decorationitem.h"
|
||||||
|
#include "scene/surfaceitem.h"
|
||||||
|
#include "scene/windowitem.h"
|
||||||
#include "wayland/blur.h"
|
#include "wayland/blur.h"
|
||||||
#include "wayland/display.h"
|
#include "wayland/display.h"
|
||||||
#include "wayland/surface.h"
|
#include "wayland/surface.h"
|
||||||
|
@ -263,6 +266,12 @@ void BlurEffect::updateBlurRegion(EffectWindow *w)
|
||||||
BlurEffectData &data = m_windows[w];
|
BlurEffectData &data = m_windows[w];
|
||||||
data.content = content;
|
data.content = content;
|
||||||
data.frame = frame;
|
data.frame = frame;
|
||||||
|
if (content) {
|
||||||
|
data.surfaceEffect = ItemEffect(w->windowItem()->surfaceItem());
|
||||||
|
}
|
||||||
|
if (frame) {
|
||||||
|
data.surfaceEffect = ItemEffect(w->windowItem()->decorationItem());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (auto it = m_windows.find(w); it != m_windows.end()) {
|
if (auto it = m_windows.find(w); it != m_windows.end()) {
|
||||||
effects->makeOpenGLContextCurrent();
|
effects->makeOpenGLContextCurrent();
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "effect/effect.h"
|
#include "effect/effect.h"
|
||||||
#include "opengl/glutils.h"
|
#include "opengl/glutils.h"
|
||||||
|
#include "scene/item.h"
|
||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
|
||||||
|
@ -31,9 +32,11 @@ struct BlurEffectData
|
||||||
{
|
{
|
||||||
/// The region that should be blurred behind the window
|
/// The region that should be blurred behind the window
|
||||||
std::optional<QRegion> content;
|
std::optional<QRegion> content;
|
||||||
|
ItemEffect surfaceEffect;
|
||||||
|
|
||||||
/// The region that should be blurred behind the frame
|
/// The region that should be blurred behind the frame
|
||||||
std::optional<QRegion> frame;
|
std::optional<QRegion> frame;
|
||||||
|
ItemEffect decorationEffect;
|
||||||
|
|
||||||
/// The render data per screen. Screens can have different color spaces.
|
/// The render data per screen. Screens can have different color spaces.
|
||||||
std::unordered_map<Output *, BlurRenderData> render;
|
std::unordered_map<Output *, BlurRenderData> render;
|
||||||
|
|
|
@ -105,7 +105,6 @@
|
||||||
"Name[zh_CN]": "气泡显隐渐变动画",
|
"Name[zh_CN]": "气泡显隐渐变动画",
|
||||||
"Name[zh_TW]": "淡化彈出視窗"
|
"Name[zh_TW]": "淡化彈出視窗"
|
||||||
},
|
},
|
||||||
"X-KDE-BlocksDirectScanout": false,
|
|
||||||
"X-KDE-Ordering": 60,
|
"X-KDE-Ordering": 60,
|
||||||
"X-Plasma-API": "javascript"
|
"X-Plasma-API": "javascript"
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "core/rendertarget.h"
|
#include "core/rendertarget.h"
|
||||||
#include "core/renderviewport.h"
|
#include "core/renderviewport.h"
|
||||||
#include "effect/effecthandler.h"
|
#include "effect/effecthandler.h"
|
||||||
|
#include "scene/windowitem.h"
|
||||||
|
|
||||||
// Qt
|
// Qt
|
||||||
#include <QMatrix4x4>
|
#include <QMatrix4x4>
|
||||||
|
@ -79,7 +80,7 @@ void GlideEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std:
|
||||||
{
|
{
|
||||||
auto animationIt = m_animations.find(w);
|
auto animationIt = m_animations.find(w);
|
||||||
if (animationIt != m_animations.end()) {
|
if (animationIt != m_animations.end()) {
|
||||||
(*animationIt).timeLine.advance(presentTime);
|
animationIt->second.timeLine.advance(presentTime);
|
||||||
data.setTransformed();
|
data.setTransformed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,13 +89,13 @@ void GlideEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std:
|
||||||
|
|
||||||
void GlideEffect::apply(EffectWindow *window, int mask, WindowPaintData &data, WindowQuadList &quads)
|
void GlideEffect::apply(EffectWindow *window, int mask, WindowPaintData &data, WindowQuadList &quads)
|
||||||
{
|
{
|
||||||
auto animationIt = m_animations.constFind(window);
|
auto animationIt = m_animations.find(window);
|
||||||
if (animationIt == m_animations.constEnd()) {
|
if (animationIt == m_animations.end()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GlideParams params = window->isDeleted() ? m_outParams : m_inParams;
|
const GlideParams params = window->isDeleted() ? m_outParams : m_inParams;
|
||||||
const qreal t = (*animationIt).timeLine.value();
|
const qreal t = animationIt->second.timeLine.value();
|
||||||
|
|
||||||
const QRectF rect = window->expandedGeometry().translated(-window->pos());
|
const QRectF rect = window->expandedGeometry().translated(-window->pos());
|
||||||
const float fovY = std::tan(qDegreesToRadians(60.0f) / 2);
|
const float fovY = std::tan(qDegreesToRadians(60.0f) / 2);
|
||||||
|
@ -162,8 +163,8 @@ void GlideEffect::postPaintWindow(EffectWindow *w)
|
||||||
if (auto animationIt = m_animations.find(w); animationIt != m_animations.end()) {
|
if (auto animationIt = m_animations.find(w); animationIt != m_animations.end()) {
|
||||||
w->addRepaintFull();
|
w->addRepaintFull();
|
||||||
|
|
||||||
if ((*animationIt).timeLine.done()) {
|
if (animationIt->second.timeLine.done()) {
|
||||||
unredirect(animationIt.key());
|
unredirect(animationIt->first);
|
||||||
animationIt = m_animations.erase(animationIt);
|
animationIt = m_animations.erase(animationIt);
|
||||||
} else {
|
} else {
|
||||||
++animationIt;
|
++animationIt;
|
||||||
|
@ -175,7 +176,7 @@ void GlideEffect::postPaintWindow(EffectWindow *w)
|
||||||
|
|
||||||
bool GlideEffect::isActive() const
|
bool GlideEffect::isActive() const
|
||||||
{
|
{
|
||||||
return !m_animations.isEmpty();
|
return !m_animations.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GlideEffect::supported()
|
bool GlideEffect::supported()
|
||||||
|
@ -210,6 +211,7 @@ void GlideEffect::windowAdded(EffectWindow *w)
|
||||||
animation.timeLine.setDirection(TimeLine::Forward);
|
animation.timeLine.setDirection(TimeLine::Forward);
|
||||||
animation.timeLine.setDuration(m_duration);
|
animation.timeLine.setDuration(m_duration);
|
||||||
animation.timeLine.setEasingCurve(QEasingCurve::InCurve);
|
animation.timeLine.setEasingCurve(QEasingCurve::InCurve);
|
||||||
|
animation.effect = ItemEffect(w->windowItem());
|
||||||
|
|
||||||
redirect(w);
|
redirect(w);
|
||||||
effects->addRepaintFull();
|
effects->addRepaintFull();
|
||||||
|
@ -255,7 +257,7 @@ void GlideEffect::windowDataChanged(EffectWindow *w, int role)
|
||||||
|
|
||||||
auto animationIt = m_animations.find(w);
|
auto animationIt = m_animations.find(w);
|
||||||
if (animationIt != m_animations.end()) {
|
if (animationIt != m_animations.end()) {
|
||||||
unredirect(animationIt.key());
|
unredirect(animationIt->first);
|
||||||
m_animations.erase(animationIt);
|
m_animations.erase(animationIt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -301,6 +303,11 @@ bool GlideEffect::isGlideWindow(EffectWindow *w) const
|
||||||
|| w->isDialog();
|
|| w->isDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GlideEffect::blocksDirectScanout() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace KWin
|
} // namespace KWin
|
||||||
|
|
||||||
#include "moc_glide.cpp"
|
#include "moc_glide.cpp"
|
||||||
|
|
|
@ -16,6 +16,9 @@
|
||||||
#include "effect/effectwindow.h"
|
#include "effect/effectwindow.h"
|
||||||
#include "effect/offscreeneffect.h"
|
#include "effect/offscreeneffect.h"
|
||||||
#include "effect/timeline.h"
|
#include "effect/timeline.h"
|
||||||
|
#include "scene/item.h"
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
@ -24,6 +27,7 @@ struct GlideAnimation
|
||||||
{
|
{
|
||||||
EffectWindowDeletedRef deletedRef;
|
EffectWindowDeletedRef deletedRef;
|
||||||
TimeLine timeLine;
|
TimeLine timeLine;
|
||||||
|
ItemEffect effect;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GlideEffect : public OffscreenEffect
|
class GlideEffect : public OffscreenEffect
|
||||||
|
@ -68,6 +72,7 @@ public:
|
||||||
qreal outRotationAngle() const;
|
qreal outRotationAngle() const;
|
||||||
qreal outDistance() const;
|
qreal outDistance() const;
|
||||||
qreal outOpacity() const;
|
qreal outOpacity() const;
|
||||||
|
bool blocksDirectScanout() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void apply(EffectWindow *window, int mask, WindowPaintData &data, WindowQuadList &quads) override;
|
void apply(EffectWindow *window, int mask, WindowPaintData &data, WindowQuadList &quads) override;
|
||||||
|
@ -81,7 +86,7 @@ private:
|
||||||
bool isGlideWindow(EffectWindow *w) const;
|
bool isGlideWindow(EffectWindow *w) const;
|
||||||
|
|
||||||
std::chrono::milliseconds m_duration;
|
std::chrono::milliseconds m_duration;
|
||||||
QHash<EffectWindow *, GlideAnimation> m_animations;
|
std::unordered_map<EffectWindow *, GlideAnimation> m_animations;
|
||||||
|
|
||||||
struct GlideParams
|
struct GlideParams
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "slidingpopupsconfig.h"
|
#include "slidingpopupsconfig.h"
|
||||||
|
|
||||||
#include "effect/effecthandler.h"
|
#include "effect/effecthandler.h"
|
||||||
|
#include "scene/windowitem.h"
|
||||||
#include "wayland/display.h"
|
#include "wayland/display.h"
|
||||||
#include "wayland/slide.h"
|
#include "wayland/slide.h"
|
||||||
#include "wayland/surface.h"
|
#include "wayland/surface.h"
|
||||||
|
@ -107,13 +108,8 @@ void SlidingPopupsEffect::reconfigure(ReconfigureFlags flags)
|
||||||
m_slideOutDuration = std::chrono::milliseconds(
|
m_slideOutDuration = std::chrono::milliseconds(
|
||||||
static_cast<int>(animationTime(SlidingPopupsConfig::slideOutTime() != 0 ? std::chrono::milliseconds(SlidingPopupsConfig::slideOutTime()) : 200ms)));
|
static_cast<int>(animationTime(SlidingPopupsConfig::slideOutTime() != 0 ? std::chrono::milliseconds(SlidingPopupsConfig::slideOutTime()) : 200ms)));
|
||||||
|
|
||||||
auto animationIt = m_animations.begin();
|
for (auto &[window, animation] : m_animations) {
|
||||||
while (animationIt != m_animations.end()) {
|
animation.timeLine.setDuration(animation.kind == AnimationKind::In ? m_slideInDuration : m_slideOutDuration);
|
||||||
const auto duration = ((*animationIt).kind == AnimationKind::In)
|
|
||||||
? m_slideInDuration
|
|
||||||
: m_slideOutDuration;
|
|
||||||
(*animationIt).timeLine.setDuration(duration);
|
|
||||||
++animationIt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto dataIt = m_animationsData.begin();
|
auto dataIt = m_animationsData.begin();
|
||||||
|
@ -132,7 +128,7 @@ void SlidingPopupsEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &da
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*animationIt).timeLine.advance(presentTime);
|
animationIt->second.timeLine.advance(presentTime);
|
||||||
data.setTransformed();
|
data.setTransformed();
|
||||||
|
|
||||||
effects->prePaintWindow(w, data, presentTime);
|
effects->prePaintWindow(w, data, presentTime);
|
||||||
|
@ -140,8 +136,8 @@ void SlidingPopupsEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &da
|
||||||
|
|
||||||
void SlidingPopupsEffect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
|
void SlidingPopupsEffect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
|
||||||
{
|
{
|
||||||
auto animationIt = m_animations.constFind(w);
|
auto animationIt = m_animations.find(w);
|
||||||
if (animationIt == m_animations.constEnd()) {
|
if (animationIt == m_animations.end()) {
|
||||||
effects->paintWindow(renderTarget, viewport, w, mask, region, data);
|
effects->paintWindow(renderTarget, viewport, w, mask, region, data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -152,7 +148,7 @@ void SlidingPopupsEffect::paintWindow(const RenderTarget &renderTarget, const Re
|
||||||
const QRectF screenRect = effects->clientArea(FullScreenArea, w->screen(), effects->currentDesktop());
|
const QRectF screenRect = effects->clientArea(FullScreenArea, w->screen(), effects->currentDesktop());
|
||||||
int splitPoint = 0;
|
int splitPoint = 0;
|
||||||
const QRectF geo = w->expandedGeometry();
|
const QRectF geo = w->expandedGeometry();
|
||||||
const qreal t = (*animationIt).timeLine.value();
|
const qreal t = animationIt->second.timeLine.value();
|
||||||
|
|
||||||
switch (animData.location) {
|
switch (animData.location) {
|
||||||
case Location::Left:
|
case Location::Left:
|
||||||
|
@ -197,7 +193,7 @@ void SlidingPopupsEffect::postPaintWindow(EffectWindow *w)
|
||||||
auto animationIt = m_animations.find(w);
|
auto animationIt = m_animations.find(w);
|
||||||
if (animationIt != m_animations.end()) {
|
if (animationIt != m_animations.end()) {
|
||||||
effects->addRepaint(w->expandedGeometry());
|
effects->addRepaint(w->expandedGeometry());
|
||||||
if ((*animationIt).timeLine.done()) {
|
if (animationIt->second.timeLine.done()) {
|
||||||
if (!w->isDeleted()) {
|
if (!w->isDeleted()) {
|
||||||
w->setData(WindowForceBackgroundContrastRole, QVariant());
|
w->setData(WindowForceBackgroundContrastRole, QVariant());
|
||||||
w->setData(WindowForceBlurRole, QVariant());
|
w->setData(WindowForceBlurRole, QVariant());
|
||||||
|
@ -292,7 +288,7 @@ void SlidingPopupsEffect::slotPropertyNotify(EffectWindow *w, long atom)
|
||||||
if (w->data(WindowClosedGrabRole).value<void *>() == this) {
|
if (w->data(WindowClosedGrabRole).value<void *>() == this) {
|
||||||
w->setData(WindowClosedGrabRole, QVariant());
|
w->setData(WindowClosedGrabRole, QVariant());
|
||||||
}
|
}
|
||||||
m_animations.remove(w);
|
m_animations.erase(w);
|
||||||
m_animationsData.remove(w);
|
m_animationsData.remove(w);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -531,6 +527,7 @@ void SlidingPopupsEffect::slideIn(EffectWindow *w)
|
||||||
animation.timeLine.setDirection(TimeLine::Forward);
|
animation.timeLine.setDirection(TimeLine::Forward);
|
||||||
animation.timeLine.setDuration((*dataIt).slideInDuration);
|
animation.timeLine.setDuration((*dataIt).slideInDuration);
|
||||||
animation.timeLine.setEasingCurve(QEasingCurve::OutCubic);
|
animation.timeLine.setEasingCurve(QEasingCurve::OutCubic);
|
||||||
|
animation.windowEffect = ItemEffect(w->windowItem());
|
||||||
|
|
||||||
// If the opposite animation (Out) was active and it had shorter duration,
|
// If the opposite animation (Out) was active and it had shorter duration,
|
||||||
// at this point, the timeline can end up in the "done" state. Thus, we have
|
// at this point, the timeline can end up in the "done" state. Thus, we have
|
||||||
|
@ -586,12 +583,10 @@ void SlidingPopupsEffect::slideOut(EffectWindow *w)
|
||||||
|
|
||||||
void SlidingPopupsEffect::stopAnimations()
|
void SlidingPopupsEffect::stopAnimations()
|
||||||
{
|
{
|
||||||
for (auto it = m_animations.constBegin(); it != m_animations.constEnd(); ++it) {
|
for (const auto &[window, animation] : m_animations) {
|
||||||
EffectWindow *w = it.key();
|
if (!window->isDeleted()) {
|
||||||
|
window->setData(WindowForceBackgroundContrastRole, QVariant());
|
||||||
if (!w->isDeleted()) {
|
window->setData(WindowForceBlurRole, QVariant());
|
||||||
w->setData(WindowForceBackgroundContrastRole, QVariant());
|
|
||||||
w->setData(WindowForceBlurRole, QVariant());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -600,7 +595,12 @@ void SlidingPopupsEffect::stopAnimations()
|
||||||
|
|
||||||
bool SlidingPopupsEffect::isActive() const
|
bool SlidingPopupsEffect::isActive() const
|
||||||
{
|
{
|
||||||
return !m_animations.isEmpty();
|
return !m_animations.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SlidingPopupsEffect::blocksDirectScanout() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "effect/effect.h"
|
#include "effect/effect.h"
|
||||||
#include "effect/effectwindow.h"
|
#include "effect/effectwindow.h"
|
||||||
#include "effect/timeline.h"
|
#include "effect/timeline.h"
|
||||||
|
#include "scene/item.h"
|
||||||
|
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
@ -49,6 +50,7 @@ public:
|
||||||
int slideOutDuration() const;
|
int slideOutDuration() const;
|
||||||
|
|
||||||
bool eventFilter(QObject *watched, QEvent *event) override;
|
bool eventFilter(QObject *watched, QEvent *event) override;
|
||||||
|
bool blocksDirectScanout() const override;
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void slotWindowAdded(EffectWindow *w);
|
void slotWindowAdded(EffectWindow *w);
|
||||||
|
@ -91,8 +93,9 @@ private:
|
||||||
EffectWindowVisibleRef visibleRef;
|
EffectWindowVisibleRef visibleRef;
|
||||||
AnimationKind kind;
|
AnimationKind kind;
|
||||||
TimeLine timeLine;
|
TimeLine timeLine;
|
||||||
|
ItemEffect windowEffect;
|
||||||
};
|
};
|
||||||
QHash<EffectWindow *, Animation> m_animations;
|
std::unordered_map<EffectWindow *, Animation> m_animations;
|
||||||
|
|
||||||
enum class Location {
|
enum class Location {
|
||||||
Left,
|
Left,
|
||||||
|
|
|
@ -12,6 +12,34 @@
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
|
||||||
|
ItemEffect::ItemEffect(Item *item)
|
||||||
|
: m_item(item)
|
||||||
|
{
|
||||||
|
item->addEffect();
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemEffect::ItemEffect(ItemEffect &&move)
|
||||||
|
: m_item(std::exchange(move.m_item, nullptr))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemEffect::ItemEffect()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemEffect::~ItemEffect()
|
||||||
|
{
|
||||||
|
if (m_item) {
|
||||||
|
m_item->removeEffect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemEffect &ItemEffect::operator=(ItemEffect &&move)
|
||||||
|
{
|
||||||
|
std::swap(m_item, move.m_item);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
Item::Item(Item *parent)
|
Item::Item(Item *parent)
|
||||||
{
|
{
|
||||||
setParentItem(parent);
|
setParentItem(parent);
|
||||||
|
@ -516,6 +544,22 @@ void Item::setPresentationHint(PresentationModeHint hint)
|
||||||
m_presentationHint = hint;
|
m_presentationHint = hint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Item::hasEffects() const
|
||||||
|
{
|
||||||
|
return m_effectCount != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Item::addEffect()
|
||||||
|
{
|
||||||
|
m_effectCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Item::removeEffect()
|
||||||
|
{
|
||||||
|
Q_ASSERT(m_effectCount > 0);
|
||||||
|
m_effectCount--;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace KWin
|
} // namespace KWin
|
||||||
|
|
||||||
#include "moc_item.cpp"
|
#include "moc_item.cpp"
|
||||||
|
|
|
@ -24,6 +24,23 @@ class SceneDelegate;
|
||||||
class Scene;
|
class Scene;
|
||||||
class SyncReleasePoint;
|
class SyncReleasePoint;
|
||||||
class DrmDevice;
|
class DrmDevice;
|
||||||
|
class Item;
|
||||||
|
|
||||||
|
class KWIN_EXPORT ItemEffect
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit ItemEffect(Item *item);
|
||||||
|
explicit ItemEffect(const ItemEffect ©) = delete;
|
||||||
|
explicit ItemEffect(ItemEffect &&move);
|
||||||
|
explicit ItemEffect();
|
||||||
|
virtual ~ItemEffect();
|
||||||
|
|
||||||
|
ItemEffect &operator=(const ItemEffect ©) = delete;
|
||||||
|
ItemEffect &operator=(ItemEffect &&move);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QPointer<Item> m_item;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Item class is the base class for items in the scene.
|
* The Item class is the base class for items in the scene.
|
||||||
|
@ -116,6 +133,10 @@ public:
|
||||||
RenderingIntent renderingIntent() const;
|
RenderingIntent renderingIntent() const;
|
||||||
PresentationModeHint presentationHint() const;
|
PresentationModeHint presentationHint() const;
|
||||||
|
|
||||||
|
bool hasEffects() const;
|
||||||
|
void addEffect();
|
||||||
|
void removeEffect();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void childAdded(Item *item);
|
void childAdded(Item *item);
|
||||||
/**
|
/**
|
||||||
|
@ -173,6 +194,7 @@ private:
|
||||||
ColorDescription m_colorDescription = ColorDescription::sRGB;
|
ColorDescription m_colorDescription = ColorDescription::sRGB;
|
||||||
RenderingIntent m_renderingIntent = RenderingIntent::Perceptual;
|
RenderingIntent m_renderingIntent = RenderingIntent::Perceptual;
|
||||||
PresentationModeHint m_presentationHint = PresentationModeHint::VSync;
|
PresentationModeHint m_presentationHint = PresentationModeHint::VSync;
|
||||||
|
int m_effectCount = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace KWin
|
} // namespace KWin
|
||||||
|
|
|
@ -177,7 +177,7 @@ static bool addCandidates(SurfaceItem *item, QList<SurfaceItem *> &candidates, s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (candidates.size() >= maxCount) {
|
if (candidates.size() >= maxCount || item->hasEffects()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
candidates.push_back(item);
|
candidates.push_back(item);
|
||||||
|
@ -202,7 +202,7 @@ QList<SurfaceItem *> WorkspaceScene::scanoutCandidates(ssize_t maxCount) const
|
||||||
WindowItem *windowItem = stacking_order[i];
|
WindowItem *windowItem = stacking_order[i];
|
||||||
Window *window = windowItem->window();
|
Window *window = windowItem->window();
|
||||||
if (window->isOnOutput(painted_screen) && window->opacity() > 0 && windowItem->isVisible()) {
|
if (window->isOnOutput(painted_screen) && window->opacity() > 0 && windowItem->isVisible()) {
|
||||||
if (!window->isClient() || window->opacity() != 1.0 || !window->isFullScreen()) {
|
if (!window->isClient() || window->opacity() != 1.0 || !window->isFullScreen() || window->windowItem()->hasEffects()) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
if (!windowItem->surfaceItem()) {
|
if (!windowItem->surfaceItem()) {
|
||||||
|
|
|
@ -165,10 +165,10 @@ ScriptedEffect *ScriptedEffect::create(const KPluginMetaData &effect)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ScriptedEffect::create(name, scriptFile, effect.value(QStringLiteral("X-KDE-Ordering"), 0), effect.value(QStringLiteral("X-KWin-Exclusive-Category")), effect.value(QStringLiteral("X-KDE-BlocksDirectScanout"), true));
|
return ScriptedEffect::create(name, scriptFile, effect.value(QStringLiteral("X-KDE-Ordering"), 0), effect.value(QStringLiteral("X-KWin-Exclusive-Category")));
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptedEffect *ScriptedEffect::create(const QString &effectName, const QString &pathToScript, int chainPosition, const QString &exclusiveCategory, bool blocksDirectScanout)
|
ScriptedEffect *ScriptedEffect::create(const QString &effectName, const QString &pathToScript, int chainPosition, const QString &exclusiveCategory)
|
||||||
{
|
{
|
||||||
ScriptedEffect *effect = new ScriptedEffect();
|
ScriptedEffect *effect = new ScriptedEffect();
|
||||||
effect->m_exclusiveCategory = exclusiveCategory;
|
effect->m_exclusiveCategory = exclusiveCategory;
|
||||||
|
@ -177,7 +177,6 @@ ScriptedEffect *ScriptedEffect::create(const QString &effectName, const QString
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
effect->m_chainPosition = chainPosition;
|
effect->m_chainPosition = chainPosition;
|
||||||
effect->m_blocksDirectScanout = blocksDirectScanout;
|
|
||||||
|
|
||||||
return effect;
|
return effect;
|
||||||
}
|
}
|
||||||
|
@ -307,11 +306,6 @@ bool ScriptedEffect::isActiveFullScreenEffect() const
|
||||||
return effects->activeFullScreenEffect() == this;
|
return effects->activeFullScreenEffect() == this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScriptedEffect::blocksDirectScanout() const
|
|
||||||
{
|
|
||||||
return m_blocksDirectScanout;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<int> ScriptedEffect::touchEdgesForAction(const QString &action) const
|
QList<int> ScriptedEffect::touchEdgesForAction(const QString &action) const
|
||||||
{
|
{
|
||||||
QList<int> ret;
|
QList<int> ret;
|
||||||
|
|
|
@ -80,7 +80,7 @@ public:
|
||||||
}
|
}
|
||||||
QString activeConfig() const;
|
QString activeConfig() const;
|
||||||
void setActiveConfig(const QString &name);
|
void setActiveConfig(const QString &name);
|
||||||
static ScriptedEffect *create(const QString &effectName, const QString &pathToScript, int chainPosition, const QString &exclusiveCategory, bool blocksDirectScanout);
|
static ScriptedEffect *create(const QString &effectName, const QString &pathToScript, int chainPosition, const QString &exclusiveCategory);
|
||||||
static ScriptedEffect *create(const KPluginMetaData &effect);
|
static ScriptedEffect *create(const KPluginMetaData &effect);
|
||||||
static bool supported();
|
static bool supported();
|
||||||
~ScriptedEffect() override;
|
~ScriptedEffect() override;
|
||||||
|
@ -182,7 +182,6 @@ public:
|
||||||
|
|
||||||
QString pluginId() const;
|
QString pluginId() const;
|
||||||
bool isActiveFullScreenEffect() const;
|
bool isActiveFullScreenEffect() const;
|
||||||
bool blocksDirectScanout() const override;
|
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
bool borderActivated(ElectricBorder border) override;
|
bool borderActivated(ElectricBorder border) override;
|
||||||
|
@ -223,6 +222,5 @@ private:
|
||||||
Effect *m_activeFullScreenEffect = nullptr;
|
Effect *m_activeFullScreenEffect = nullptr;
|
||||||
std::map<uint, std::unique_ptr<GLShader>> m_shaders;
|
std::map<uint, std::unique_ptr<GLShader>> m_shaders;
|
||||||
uint m_nextShaderId{1u};
|
uint m_nextShaderId{1u};
|
||||||
bool m_blocksDirectScanout = true;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue