Provide expected presentation time to effects
Effects are given the interval between two consecutive frames. The main flaw of this approach is that if the Compositor transitions from the idle state to "active" state, i.e. when there is something to repaint, effects may see a very large interval between the last painted frame and the current. In order to address this issue, the Scene invalidates the timer that is used to measure time between consecutive frames before the Compositor is about to become idle. While this works perfectly fine with Xinerama-style rendering, with per screen rendering, determining whether the compositor is about to idle is rather a tedious task mostly because a single output can't be used for the test. Furthermore, since the Compositor schedules pointless repaints just to ensure that it's idle, it might take several attempts to figure out whether the scene timer must be invalidated if you use (true) per screen rendering. Ideally, all effects should use a timeline helper that is aware of the underlying render loop and its timings. However, this option is off the table because it will involve a lot of work to implement it. Alternative and much simpler option is to pass the expected presentation time to effects rather than time between consecutive frames. This means that effects are responsible for determining how much animation timelines have to be advanced. Typically, an effect would have to store the presentation timestamp provided in either prePaint{Screen,Window} and use it in the subsequent prePaint{Screen,Window} call to estimate the amount of time passed between the next and the last frames. Unfortunately, this is an API incompatible change. However, it shouldn't take a lot of work to port third-party binary effects, which don't use the AnimationEffect class, to the new API. On the bright side, we no longer need to be concerned about the Compositor getting idle. We do still try to determine whether the Compositor is about to idle, primarily, because the OpenGL render backend swaps buffers on present, but that will change with the ongoing compositing timing rework.icc-effect-5.26.4
parent
6646422007
commit
9f2cb0ae1b
|
@ -167,8 +167,8 @@ public:
|
||||||
void paintWindow(KWin::EffectWindow *, int, const QRegion &, KWin::WindowPaintData &) override {}
|
void paintWindow(KWin::EffectWindow *, int, const QRegion &, KWin::WindowPaintData &) override {}
|
||||||
void postPaintScreen() override {}
|
void postPaintScreen() override {}
|
||||||
void postPaintWindow(KWin::EffectWindow *) override {}
|
void postPaintWindow(KWin::EffectWindow *) override {}
|
||||||
void prePaintScreen(KWin::ScreenPrePaintData &, int) override {}
|
void prePaintScreen(KWin::ScreenPrePaintData &, std::chrono::milliseconds) override {}
|
||||||
void prePaintWindow(KWin::EffectWindow *, KWin::WindowPrePaintData &, int) override {}
|
void prePaintWindow(KWin::EffectWindow *, KWin::WindowPrePaintData &, std::chrono::milliseconds) override {}
|
||||||
QByteArray readRootProperty(long int, long int, int) const override {
|
QByteArray readRootProperty(long int, long int, int) const override {
|
||||||
return QByteArray();
|
return QByteArray();
|
||||||
}
|
}
|
||||||
|
|
|
@ -681,16 +681,20 @@ void Compositor::performCompositing()
|
||||||
// clear all repaints, so that post-pass can add repaints for the next repaint
|
// clear all repaints, so that post-pass can add repaints for the next repaint
|
||||||
repaints_region = QRegion();
|
repaints_region = QRegion();
|
||||||
|
|
||||||
|
const std::chrono::nanoseconds now = std::chrono::steady_clock::now().time_since_epoch();
|
||||||
|
const std::chrono::milliseconds presentTime =
|
||||||
|
std::chrono::duration_cast<std::chrono::milliseconds>(now);
|
||||||
|
|
||||||
if (m_framesToTestForSafety > 0 && (m_scene->compositingType() & OpenGLCompositing)) {
|
if (m_framesToTestForSafety > 0 && (m_scene->compositingType() & OpenGLCompositing)) {
|
||||||
kwinApp()->platform()->createOpenGLSafePoint(Platform::OpenGLSafePoint::PreFrame);
|
kwinApp()->platform()->createOpenGLSafePoint(Platform::OpenGLSafePoint::PreFrame);
|
||||||
}
|
}
|
||||||
m_renderTimer.start();
|
m_renderTimer.start();
|
||||||
if (kwinApp()->platform()->isPerScreenRenderingEnabled()) {
|
if (kwinApp()->platform()->isPerScreenRenderingEnabled()) {
|
||||||
for (int screenId = 0; screenId < screens()->count(); ++screenId) {
|
for (int screenId = 0; screenId < screens()->count(); ++screenId) {
|
||||||
m_scene->paint(screenId, repaints, windows);
|
m_scene->paint(screenId, repaints, windows, presentTime);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m_scene->paint(-1, repaints, windows);
|
m_scene->paint(-1, repaints, windows, presentTime);
|
||||||
}
|
}
|
||||||
m_timeSinceLastVBlank = m_renderTimer.elapsed();
|
m_timeSinceLastVBlank = m_renderTimer.elapsed();
|
||||||
if (m_framesToTestForSafety > 0) {
|
if (m_framesToTestForSafety > 0) {
|
||||||
|
|
|
@ -363,10 +363,10 @@ void EffectsHandlerImpl::reconfigure()
|
||||||
}
|
}
|
||||||
|
|
||||||
// the idea is that effects call this function again which calls the next one
|
// the idea is that effects call this function again which calls the next one
|
||||||
void EffectsHandlerImpl::prePaintScreen(ScreenPrePaintData& data, int time)
|
void EffectsHandlerImpl::prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
if (m_currentPaintScreenIterator != m_activeEffects.constEnd()) {
|
if (m_currentPaintScreenIterator != m_activeEffects.constEnd()) {
|
||||||
(*m_currentPaintScreenIterator++)->prePaintScreen(data, time);
|
(*m_currentPaintScreenIterator++)->prePaintScreen(data, presentTime);
|
||||||
--m_currentPaintScreenIterator;
|
--m_currentPaintScreenIterator;
|
||||||
}
|
}
|
||||||
// no special final code
|
// no special final code
|
||||||
|
@ -406,10 +406,10 @@ void EffectsHandlerImpl::postPaintScreen()
|
||||||
// no special final code
|
// no special final code
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectsHandlerImpl::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
|
void EffectsHandlerImpl::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
if (m_currentPaintWindowIterator != m_activeEffects.constEnd()) {
|
if (m_currentPaintWindowIterator != m_activeEffects.constEnd()) {
|
||||||
(*m_currentPaintWindowIterator++)->prePaintWindow(w, data, time);
|
(*m_currentPaintWindowIterator++)->prePaintWindow(w, data, presentTime);
|
||||||
--m_currentPaintWindowIterator;
|
--m_currentPaintWindowIterator;
|
||||||
}
|
}
|
||||||
// no special final code
|
// no special final code
|
||||||
|
|
|
@ -59,14 +59,14 @@ class KWIN_EXPORT EffectsHandlerImpl : public EffectsHandler
|
||||||
public:
|
public:
|
||||||
EffectsHandlerImpl(Compositor *compositor, Scene *scene);
|
EffectsHandlerImpl(Compositor *compositor, Scene *scene);
|
||||||
~EffectsHandlerImpl() override;
|
~EffectsHandlerImpl() override;
|
||||||
void prePaintScreen(ScreenPrePaintData& data, int time) override;
|
void prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) override;
|
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) override;
|
||||||
/**
|
/**
|
||||||
* Special hook to perform a paintScreen but just with the windows on @p desktop.
|
* Special hook to perform a paintScreen but just with the windows on @p desktop.
|
||||||
*/
|
*/
|
||||||
void paintDesktop(int desktop, int mask, QRegion region, ScreenPaintData& data);
|
void paintDesktop(int desktop, int mask, QRegion region, ScreenPaintData& data);
|
||||||
void postPaintScreen() override;
|
void postPaintScreen() override;
|
||||||
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time) override;
|
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintWindow(EffectWindow* w, int mask, const QRegion ®ion, WindowPaintData& data) override;
|
void paintWindow(EffectWindow* w, int mask, const QRegion ®ion, WindowPaintData& data) override;
|
||||||
void postPaintWindow(EffectWindow* w) override;
|
void postPaintWindow(EffectWindow* w) override;
|
||||||
void paintEffectFrame(EffectFrame* frame, const QRegion ®ion, double opacity, double frameOpacity) override;
|
void paintEffectFrame(EffectFrame* frame, const QRegion ®ion, double opacity, double frameOpacity) override;
|
||||||
|
|
|
@ -336,19 +336,19 @@ void ContrastEffect::uploadGeometry(GLVertexBuffer *vbo, const QRegion ®ion)
|
||||||
vbo->setAttribLayout(layout, 2, sizeof(QVector2D));
|
vbo->setAttribLayout(layout, 2, sizeof(QVector2D));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContrastEffect::prePaintScreen(ScreenPrePaintData &data, int time)
|
void ContrastEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
m_paintedArea = QRegion();
|
m_paintedArea = QRegion();
|
||||||
m_currentContrast = QRegion();
|
m_currentContrast = QRegion();
|
||||||
|
|
||||||
effects->prePaintScreen(data, time);
|
effects->prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContrastEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
|
void ContrastEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
// this effect relies on prePaintWindow being called in the bottom to top order
|
// this effect relies on prePaintWindow being called in the bottom to top order
|
||||||
|
|
||||||
effects->prePaintWindow(w, data, time);
|
effects->prePaintWindow(w, data, presentTime);
|
||||||
|
|
||||||
if (!w->isPaintingEnabled()) {
|
if (!w->isPaintingEnabled()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -37,8 +37,8 @@ public:
|
||||||
|
|
||||||
static QMatrix4x4 colorMatrix(qreal contrast, qreal intensity, qreal saturation);
|
static QMatrix4x4 colorMatrix(qreal contrast, qreal intensity, qreal saturation);
|
||||||
void reconfigure(ReconfigureFlags flags) override;
|
void reconfigure(ReconfigureFlags flags) override;
|
||||||
void prePaintScreen(ScreenPrePaintData &data, int time) override;
|
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override;
|
||||||
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time) override;
|
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) override;
|
||||||
void drawWindow(EffectWindow *w, int mask, const QRegion ®ion, WindowPaintData &data) override;
|
void drawWindow(EffectWindow *w, int mask, const QRegion ®ion, WindowPaintData &data) override;
|
||||||
void paintEffectFrame(EffectFrame *frame, const QRegion ®ion, double opacity, double frameOpacity) override;
|
void paintEffectFrame(EffectFrame *frame, const QRegion ®ion, double opacity, double frameOpacity) override;
|
||||||
|
|
||||||
|
|
|
@ -469,19 +469,19 @@ void BlurEffect::uploadGeometry(GLVertexBuffer *vbo, const QRegion &blurRegion,
|
||||||
vbo->setAttribLayout(layout, 2, sizeof(QVector2D));
|
vbo->setAttribLayout(layout, 2, sizeof(QVector2D));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlurEffect::prePaintScreen(ScreenPrePaintData &data, int time)
|
void BlurEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
m_paintedArea = QRegion();
|
m_paintedArea = QRegion();
|
||||||
m_currentBlur = QRegion();
|
m_currentBlur = QRegion();
|
||||||
|
|
||||||
effects->prePaintScreen(data, time);
|
effects->prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlurEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
|
void BlurEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
// this effect relies on prePaintWindow being called in the bottom to top order
|
// this effect relies on prePaintWindow being called in the bottom to top order
|
||||||
|
|
||||||
effects->prePaintWindow(w, data, time);
|
effects->prePaintWindow(w, data, presentTime);
|
||||||
|
|
||||||
if (!w->isPaintingEnabled()) {
|
if (!w->isPaintingEnabled()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -40,8 +40,8 @@ public:
|
||||||
static bool enabledByDefault();
|
static bool enabledByDefault();
|
||||||
|
|
||||||
void reconfigure(ReconfigureFlags flags) override;
|
void reconfigure(ReconfigureFlags flags) override;
|
||||||
void prePaintScreen(ScreenPrePaintData &data, int time) override;
|
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override;
|
||||||
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time) override;
|
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void drawWindow(EffectWindow *w, int mask, const QRegion ®ion, WindowPaintData &data) override;
|
void drawWindow(EffectWindow *w, int mask, const QRegion ®ion, WindowPaintData &data) override;
|
||||||
void paintEffectFrame(EffectFrame *frame, const QRegion ®ion, double opacity, double frameOpacity) override;
|
void paintEffectFrame(EffectFrame *frame, const QRegion ®ion, double opacity, double frameOpacity) override;
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ CoverSwitchEffect::CoverSwitchEffect()
|
||||||
, stop(false)
|
, stop(false)
|
||||||
, stopRequested(false)
|
, stopRequested(false)
|
||||||
, startRequested(false)
|
, startRequested(false)
|
||||||
|
, lastPresentTime(std::chrono::milliseconds::zero())
|
||||||
, zPosition(900.0)
|
, zPosition(900.0)
|
||||||
, scaleFactor(0.0)
|
, scaleFactor(0.0)
|
||||||
, direction(Left)
|
, direction(Left)
|
||||||
|
@ -103,17 +104,23 @@ void CoverSwitchEffect::reconfigure(ReconfigureFlags)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoverSwitchEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
void CoverSwitchEffect::prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
|
std::chrono::milliseconds delta = std::chrono::milliseconds::zero();
|
||||||
|
if (lastPresentTime.count()) {
|
||||||
|
delta = presentTime - lastPresentTime;
|
||||||
|
}
|
||||||
|
lastPresentTime = presentTime;
|
||||||
|
|
||||||
if (mActivated || stop || stopRequested) {
|
if (mActivated || stop || stopRequested) {
|
||||||
data.mask |= Effect::PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
|
data.mask |= Effect::PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
|
||||||
if (animation || start || stop) {
|
if (animation || start || stop) {
|
||||||
timeLine.update(std::chrono::milliseconds(time));
|
timeLine.update(delta);
|
||||||
}
|
}
|
||||||
if (selected_window == nullptr)
|
if (selected_window == nullptr)
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
effects->prePaintScreen(data, time);
|
effects->prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoverSwitchEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data)
|
void CoverSwitchEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data)
|
||||||
|
@ -285,6 +292,7 @@ void CoverSwitchEffect::postPaintScreen()
|
||||||
}
|
}
|
||||||
referrencedWindows.clear();
|
referrencedWindows.clear();
|
||||||
currentWindowList.clear();
|
currentWindowList.clear();
|
||||||
|
lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
if (startRequested) {
|
if (startRequested) {
|
||||||
startRequested = false;
|
startRequested = false;
|
||||||
mActivated = true;
|
mActivated = true;
|
||||||
|
@ -538,6 +546,7 @@ void CoverSwitchEffect::slotTabBoxClosed()
|
||||||
start = false;
|
start = false;
|
||||||
animation = false;
|
animation = false;
|
||||||
timeLine.reset();
|
timeLine.reset();
|
||||||
|
lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
}
|
}
|
||||||
mActivated = false;
|
mActivated = false;
|
||||||
effects->unrefTabBox();
|
effects->unrefTabBox();
|
||||||
|
@ -907,6 +916,7 @@ void CoverSwitchEffect::abort()
|
||||||
}
|
}
|
||||||
effects->setActiveFullScreenEffect(nullptr);
|
effects->setActiveFullScreenEffect(nullptr);
|
||||||
timeLine.reset();
|
timeLine.reset();
|
||||||
|
lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
mActivated = false;
|
mActivated = false;
|
||||||
stop = false;
|
stop = false;
|
||||||
stopRequested = false;
|
stopRequested = false;
|
||||||
|
|
|
@ -42,7 +42,7 @@ public:
|
||||||
~CoverSwitchEffect() override;
|
~CoverSwitchEffect() override;
|
||||||
|
|
||||||
void reconfigure(ReconfigureFlags) override;
|
void reconfigure(ReconfigureFlags) override;
|
||||||
void prePaintScreen(ScreenPrePaintData &data, int time) override;
|
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData &data) override;
|
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData &data) override;
|
||||||
void postPaintScreen() override;
|
void postPaintScreen() override;
|
||||||
void paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override;
|
void paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override;
|
||||||
|
@ -123,6 +123,7 @@ private:
|
||||||
bool stopRequested;
|
bool stopRequested;
|
||||||
bool startRequested;
|
bool startRequested;
|
||||||
TimeLine timeLine;
|
TimeLine timeLine;
|
||||||
|
std::chrono::milliseconds lastPresentTime;
|
||||||
QRect area;
|
QRect area;
|
||||||
float zPosition;
|
float zPosition;
|
||||||
float scaleFactor;
|
float scaleFactor;
|
||||||
|
|
|
@ -50,6 +50,7 @@ CubeEffect::CubeEffect()
|
||||||
, wallpaper(nullptr)
|
, wallpaper(nullptr)
|
||||||
, texturedCaps(true)
|
, texturedCaps(true)
|
||||||
, capTexture(nullptr)
|
, capTexture(nullptr)
|
||||||
|
, lastPresentTime(std::chrono::milliseconds::zero())
|
||||||
, reflectionPainting(false)
|
, reflectionPainting(false)
|
||||||
, activeScreen(0)
|
, activeScreen(0)
|
||||||
, bottomCap(false)
|
, bottomCap(false)
|
||||||
|
@ -360,8 +361,14 @@ void CubeEffect::startVerticalAnimation(VerticalAnimationState state)
|
||||||
verticalAnimationState = state;
|
verticalAnimationState = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubeEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
void CubeEffect::prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
|
std::chrono::milliseconds delta = std::chrono::milliseconds::zero();
|
||||||
|
if (lastPresentTime.count()) {
|
||||||
|
delta = presentTime - lastPresentTime;
|
||||||
|
}
|
||||||
|
lastPresentTime = presentTime;
|
||||||
|
|
||||||
if (activated) {
|
if (activated) {
|
||||||
data.mask |= PAINT_SCREEN_TRANSFORMED | Effect::PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS | PAINT_SCREEN_BACKGROUND_FIRST;
|
data.mask |= PAINT_SCREEN_TRANSFORMED | Effect::PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS | PAINT_SCREEN_BACKGROUND_FIRST;
|
||||||
if (animationState == AnimationState::None && !animations.empty()) {
|
if (animationState == AnimationState::None && !animations.empty()) {
|
||||||
|
@ -373,15 +380,15 @@ void CubeEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
||||||
|
|
||||||
if (animationState != AnimationState::None || verticalAnimationState != VerticalAnimationState::None) {
|
if (animationState != AnimationState::None || verticalAnimationState != VerticalAnimationState::None) {
|
||||||
if (animationState != AnimationState::None) {
|
if (animationState != AnimationState::None) {
|
||||||
timeLine.update(std::chrono::milliseconds(time));
|
timeLine.update(delta);
|
||||||
}
|
}
|
||||||
if (verticalAnimationState != VerticalAnimationState::None) {
|
if (verticalAnimationState != VerticalAnimationState::None) {
|
||||||
verticalTimeLine.update(std::chrono::milliseconds(time));
|
verticalTimeLine.update(delta);
|
||||||
}
|
}
|
||||||
rotateCube();
|
rotateCube();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
effects->prePaintScreen(data, time);
|
effects->prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubeEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data)
|
void CubeEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data)
|
||||||
|
@ -973,6 +980,7 @@ void CubeEffect::postPaintScreen()
|
||||||
animations.clear();
|
animations.clear();
|
||||||
verticalAnimationState = VerticalAnimationState::None;
|
verticalAnimationState = VerticalAnimationState::None;
|
||||||
verticalAnimations.clear();
|
verticalAnimations.clear();
|
||||||
|
lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
} else {
|
} else {
|
||||||
if (!animations.empty())
|
if (!animations.empty())
|
||||||
startAnimation(animations.dequeue());
|
startAnimation(animations.dequeue());
|
||||||
|
@ -991,10 +999,12 @@ void CubeEffect::postPaintScreen()
|
||||||
/* Repaint if there is any animation */
|
/* Repaint if there is any animation */
|
||||||
if (animation) {
|
if (animation) {
|
||||||
effects->addRepaintFull();
|
effects->addRepaintFull();
|
||||||
|
} else {
|
||||||
|
lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubeEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
|
void CubeEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
if (activated) {
|
if (activated) {
|
||||||
if (cube_painting) {
|
if (cube_painting) {
|
||||||
|
@ -1046,7 +1056,7 @@ void CubeEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int t
|
||||||
data.quads = data.quads.splitAtY(rect.height() - w->y());
|
data.quads = data.quads.splitAtY(rect.height() - w->y());
|
||||||
}
|
}
|
||||||
data.setTransformed();
|
data.setTransformed();
|
||||||
effects->prePaintWindow(w, data, time);
|
effects->prePaintWindow(w, data, presentTime);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1066,7 +1076,7 @@ void CubeEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int t
|
||||||
data.quads = data.quads.splitAtY(rect.height() - w->y());
|
data.quads = data.quads.splitAtY(rect.height() - w->y());
|
||||||
}
|
}
|
||||||
data.setTransformed();
|
data.setTransformed();
|
||||||
effects->prePaintWindow(w, data, time);
|
effects->prePaintWindow(w, data, presentTime);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1074,7 +1084,7 @@ void CubeEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
effects->prePaintWindow(w, data, time);
|
effects->prePaintWindow(w, data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubeEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
void CubeEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
||||||
|
|
|
@ -47,10 +47,10 @@ public:
|
||||||
CubeEffect();
|
CubeEffect();
|
||||||
~CubeEffect() override;
|
~CubeEffect() override;
|
||||||
void reconfigure(ReconfigureFlags) override;
|
void reconfigure(ReconfigureFlags) override;
|
||||||
void prePaintScreen(ScreenPrePaintData& data, int time) override;
|
void prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) override;
|
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) override;
|
||||||
void postPaintScreen() override;
|
void postPaintScreen() override;
|
||||||
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time) override;
|
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) override;
|
void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) override;
|
||||||
bool borderActivated(ElectricBorder border) override;
|
bool borderActivated(ElectricBorder border) override;
|
||||||
void grabbedKeyboardEvent(QKeyEvent* e) override;
|
void grabbedKeyboardEvent(QKeyEvent* e) override;
|
||||||
|
@ -200,6 +200,7 @@ private:
|
||||||
VerticalAnimationState verticalAnimationState;
|
VerticalAnimationState verticalAnimationState;
|
||||||
TimeLine verticalTimeLine;
|
TimeLine verticalTimeLine;
|
||||||
QQueue<VerticalAnimationState> verticalAnimations;
|
QQueue<VerticalAnimationState> verticalAnimations;
|
||||||
|
std::chrono::milliseconds lastPresentTime;
|
||||||
|
|
||||||
bool reflectionPainting;
|
bool reflectionPainting;
|
||||||
std::chrono::milliseconds rotationDuration;
|
std::chrono::milliseconds rotationDuration;
|
||||||
|
|
|
@ -22,6 +22,7 @@ namespace KWin
|
||||||
|
|
||||||
CubeSlideEffect::CubeSlideEffect()
|
CubeSlideEffect::CubeSlideEffect()
|
||||||
: stickyPainting(false)
|
: stickyPainting(false)
|
||||||
|
, lastPresentTime(std::chrono::milliseconds::zero())
|
||||||
, windowMoving(false)
|
, windowMoving(false)
|
||||||
, desktopChangedWhileMoving(false)
|
, desktopChangedWhileMoving(false)
|
||||||
, progressRestriction(0.0f)
|
, progressRestriction(0.0f)
|
||||||
|
@ -64,15 +65,21 @@ void CubeSlideEffect::reconfigure(ReconfigureFlags)
|
||||||
useWindowMoving = CubeSlideConfig::useWindowMoving();
|
useWindowMoving = CubeSlideConfig::useWindowMoving();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubeSlideEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
void CubeSlideEffect::prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
|
std::chrono::milliseconds delta = std::chrono::milliseconds::zero();
|
||||||
|
if (lastPresentTime.count()) {
|
||||||
|
delta = presentTime - lastPresentTime;
|
||||||
|
}
|
||||||
|
lastPresentTime = presentTime;
|
||||||
|
|
||||||
if (isActive()) {
|
if (isActive()) {
|
||||||
data.mask |= PAINT_SCREEN_TRANSFORMED | PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS | PAINT_SCREEN_BACKGROUND_FIRST;
|
data.mask |= PAINT_SCREEN_TRANSFORMED | PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS | PAINT_SCREEN_BACKGROUND_FIRST;
|
||||||
timeLine.setCurrentTime(timeLine.currentTime() + time);
|
timeLine.setCurrentTime(timeLine.currentTime() + delta.count());
|
||||||
if (windowMoving && timeLine.currentTime() > progressRestriction * (qreal)timeLine.duration())
|
if (windowMoving && timeLine.currentTime() > progressRestriction * (qreal)timeLine.duration())
|
||||||
timeLine.setCurrentTime(progressRestriction * (qreal)timeLine.duration());
|
timeLine.setCurrentTime(progressRestriction * (qreal)timeLine.duration());
|
||||||
}
|
}
|
||||||
effects->prePaintScreen(data, time);
|
effects->prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubeSlideEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data)
|
void CubeSlideEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data)
|
||||||
|
@ -169,7 +176,7 @@ void CubeSlideEffect::paintSlideCube(int mask, QRegion region, ScreenPaintData&
|
||||||
painting_desktop = effects->currentDesktop();
|
painting_desktop = effects->currentDesktop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubeSlideEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
|
void CubeSlideEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
if (stickyPainting) {
|
if (stickyPainting) {
|
||||||
if (staticWindows.contains(w)) {
|
if (staticWindows.contains(w)) {
|
||||||
|
@ -180,7 +187,7 @@ void CubeSlideEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data,
|
||||||
} else if (isActive() && cube_painting) {
|
} else if (isActive() && cube_painting) {
|
||||||
if (staticWindows.contains(w)) {
|
if (staticWindows.contains(w)) {
|
||||||
w->disablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
|
w->disablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
|
||||||
effects->prePaintWindow(w, data, time);
|
effects->prePaintWindow(w, data, presentTime);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QRect rect = effects->clientArea(FullArea, effects->activeScreen(), painting_desktop);
|
QRect rect = effects->clientArea(FullArea, effects->activeScreen(), painting_desktop);
|
||||||
|
@ -230,7 +237,7 @@ void CubeSlideEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data,
|
||||||
} else
|
} else
|
||||||
w->disablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
|
w->disablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
|
||||||
}
|
}
|
||||||
effects->prePaintWindow(w, data, time);
|
effects->prePaintWindow(w, data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubeSlideEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
void CubeSlideEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
||||||
|
@ -375,6 +382,7 @@ void CubeSlideEffect::postPaintScreen()
|
||||||
w->setData(WindowForceBackgroundContrastRole, QVariant());
|
w->setData(WindowForceBackgroundContrastRole, QVariant());
|
||||||
}
|
}
|
||||||
staticWindows.clear();
|
staticWindows.clear();
|
||||||
|
lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
effects->setActiveFullScreenEffect(nullptr);
|
effects->setActiveFullScreenEffect(nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -572,6 +580,7 @@ void CubeSlideEffect::slotWindowStepUserMovedResized(EffectWindow* w)
|
||||||
windowMoving = false;
|
windowMoving = false;
|
||||||
desktopChangedWhileMoving = false;
|
desktopChangedWhileMoving = false;
|
||||||
timeLine.setCurrentTime(0);
|
timeLine.setCurrentTime(0);
|
||||||
|
lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
if (!slideRotations.isEmpty())
|
if (!slideRotations.isEmpty())
|
||||||
slideRotations.clear();
|
slideRotations.clear();
|
||||||
effects->setActiveFullScreenEffect(nullptr);
|
effects->setActiveFullScreenEffect(nullptr);
|
||||||
|
@ -652,6 +661,7 @@ void CubeSlideEffect::slotNumberDesktopsChanged()
|
||||||
|
|
||||||
slideRotations.clear();
|
slideRotations.clear();
|
||||||
staticWindows.clear();
|
staticWindows.clear();
|
||||||
|
lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
|
|
||||||
effects->setActiveFullScreenEffect(nullptr);
|
effects->setActiveFullScreenEffect(nullptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,10 +31,10 @@ public:
|
||||||
CubeSlideEffect();
|
CubeSlideEffect();
|
||||||
~CubeSlideEffect() override;
|
~CubeSlideEffect() override;
|
||||||
void reconfigure(ReconfigureFlags) override;
|
void reconfigure(ReconfigureFlags) override;
|
||||||
void prePaintScreen(ScreenPrePaintData& data, int time) override;
|
void prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) override;
|
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) override;
|
||||||
void postPaintScreen() override;
|
void postPaintScreen() override;
|
||||||
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time) override;
|
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) override;
|
void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) override;
|
||||||
bool isActive() const override;
|
bool isActive() const override;
|
||||||
|
|
||||||
|
@ -90,6 +90,7 @@ private:
|
||||||
bool stickyPainting;
|
bool stickyPainting;
|
||||||
QSet<EffectWindow*> staticWindows;
|
QSet<EffectWindow*> staticWindows;
|
||||||
QTimeLine timeLine;
|
QTimeLine timeLine;
|
||||||
|
std::chrono::milliseconds lastPresentTime;
|
||||||
QQueue<RotationDirection> slideRotations;
|
QQueue<RotationDirection> slideRotations;
|
||||||
bool dontSlidePanels;
|
bool dontSlidePanels;
|
||||||
bool dontSlideStickyWindows;
|
bool dontSlideStickyWindows;
|
||||||
|
|
|
@ -49,6 +49,7 @@ DesktopGridEffect::DesktopGridEffect()
|
||||||
, windowMove(nullptr)
|
, windowMove(nullptr)
|
||||||
, windowMoveDiff()
|
, windowMoveDiff()
|
||||||
, windowMoveElevateTimer(new QTimer(this))
|
, windowMoveElevateTimer(new QTimer(this))
|
||||||
|
, lastPresentTime(std::chrono::milliseconds::zero())
|
||||||
, gridSize()
|
, gridSize()
|
||||||
, orientation(Qt::Horizontal)
|
, orientation(Qt::Horizontal)
|
||||||
, activeCell(1, 1)
|
, activeCell(1, 1)
|
||||||
|
@ -143,8 +144,17 @@ void DesktopGridEffect::reconfigure(ReconfigureFlags)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Screen painting
|
// Screen painting
|
||||||
|
|
||||||
void DesktopGridEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
void DesktopGridEffect::prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
|
// The animation code assumes that the time diff cannot be 0, let's work around it.
|
||||||
|
int time;
|
||||||
|
if (lastPresentTime.count()) {
|
||||||
|
time = std::max(1, int((presentTime - lastPresentTime).count()));
|
||||||
|
} else {
|
||||||
|
time = 1;
|
||||||
|
}
|
||||||
|
lastPresentTime = presentTime;
|
||||||
|
|
||||||
if (timeline.currentValue() != 0 || activated || (isUsingPresentWindows() && isMotionManagerMovingWindows())) {
|
if (timeline.currentValue() != 0 || activated || (isUsingPresentWindows() && isMotionManagerMovingWindows())) {
|
||||||
if (activated)
|
if (activated)
|
||||||
timeline.setCurrentTime(timeline.currentTime() + time);
|
timeline.setCurrentTime(timeline.currentTime() + time);
|
||||||
|
@ -173,7 +183,7 @@ void DesktopGridEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
||||||
w->setData(WindowForceBlurRole, QVariant(true));
|
w->setData(WindowForceBlurRole, QVariant(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
effects->prePaintScreen(data, time);
|
effects->prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopGridEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data)
|
void DesktopGridEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data)
|
||||||
|
@ -237,20 +247,31 @@ void DesktopGridEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaint
|
||||||
|
|
||||||
void DesktopGridEffect::postPaintScreen()
|
void DesktopGridEffect::postPaintScreen()
|
||||||
{
|
{
|
||||||
if (activated ? timeline.currentValue() != 1 : timeline.currentValue() != 0)
|
bool resetLastPresentTime = true;
|
||||||
|
|
||||||
|
if (activated ? timeline.currentValue() != 1 : timeline.currentValue() != 0) {
|
||||||
effects->addRepaintFull(); // Repaint during zoom
|
effects->addRepaintFull(); // Repaint during zoom
|
||||||
if (isUsingPresentWindows() && isMotionManagerMovingWindows())
|
resetLastPresentTime = false;
|
||||||
|
}
|
||||||
|
if (isUsingPresentWindows() && isMotionManagerMovingWindows()) {
|
||||||
effects->addRepaintFull();
|
effects->addRepaintFull();
|
||||||
|
resetLastPresentTime = false;
|
||||||
|
}
|
||||||
if (activated) {
|
if (activated) {
|
||||||
for (int i = 0; i < effects->numberOfDesktops(); i++) {
|
for (int i = 0; i < effects->numberOfDesktops(); i++) {
|
||||||
if (hoverTimeline[i]->currentValue() != 0.0 && hoverTimeline[i]->currentValue() != 1.0) {
|
if (hoverTimeline[i]->currentValue() != 0.0 && hoverTimeline[i]->currentValue() != 1.0) {
|
||||||
// Repaint during soft highlighting
|
// Repaint during soft highlighting
|
||||||
effects->addRepaintFull();
|
effects->addRepaintFull();
|
||||||
|
resetLastPresentTime = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (resetLastPresentTime) {
|
||||||
|
lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
|
}
|
||||||
|
|
||||||
for (auto &w : effects->stackingOrder()) {
|
for (auto &w : effects->stackingOrder()) {
|
||||||
w->setData(WindowForceBlurRole, QVariant());
|
w->setData(WindowForceBlurRole, QVariant());
|
||||||
}
|
}
|
||||||
|
@ -261,7 +282,7 @@ void DesktopGridEffect::postPaintScreen()
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Window painting
|
// Window painting
|
||||||
|
|
||||||
void DesktopGridEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
|
void DesktopGridEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
if (timeline.currentValue() != 0 || (isUsingPresentWindows() && isMotionManagerMovingWindows())) {
|
if (timeline.currentValue() != 0 || (isUsingPresentWindows() && isMotionManagerMovingWindows())) {
|
||||||
if (w->isOnDesktop(paintingDesktop)) {
|
if (w->isOnDesktop(paintingDesktop)) {
|
||||||
|
@ -287,7 +308,7 @@ void DesktopGridEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data
|
||||||
} else
|
} else
|
||||||
w->disablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
|
w->disablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
|
||||||
}
|
}
|
||||||
effects->prePaintWindow(w, data, time);
|
effects->prePaintWindow(w, data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopGridEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
void DesktopGridEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
||||||
|
@ -1218,6 +1239,7 @@ void DesktopGridEffect::finish()
|
||||||
if (keyboardGrab)
|
if (keyboardGrab)
|
||||||
effects->ungrabKeyboard();
|
effects->ungrabKeyboard();
|
||||||
keyboardGrab = false;
|
keyboardGrab = false;
|
||||||
|
lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
effects->stopMouseInterception(this);
|
effects->stopMouseInterception(this);
|
||||||
effects->setActiveFullScreenEffect(nullptr);
|
effects->setActiveFullScreenEffect(nullptr);
|
||||||
if (isUsingPresentWindows()) {
|
if (isUsingPresentWindows()) {
|
||||||
|
|
|
@ -39,10 +39,10 @@ public:
|
||||||
DesktopGridEffect();
|
DesktopGridEffect();
|
||||||
~DesktopGridEffect() override;
|
~DesktopGridEffect() override;
|
||||||
void reconfigure(ReconfigureFlags) override;
|
void reconfigure(ReconfigureFlags) override;
|
||||||
void prePaintScreen(ScreenPrePaintData& data, int time) override;
|
void prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) override;
|
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) override;
|
||||||
void postPaintScreen() override;
|
void postPaintScreen() override;
|
||||||
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time) override;
|
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) override;
|
void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) override;
|
||||||
void windowInputMouseEvent(QEvent* e) override;
|
void windowInputMouseEvent(QEvent* e) override;
|
||||||
void grabbedKeyboardEvent(QKeyEvent* e) override;
|
void grabbedKeyboardEvent(QKeyEvent* e) override;
|
||||||
|
@ -131,6 +131,7 @@ private:
|
||||||
QPoint windowMoveDiff;
|
QPoint windowMoveDiff;
|
||||||
QPoint dragStartPos;
|
QPoint dragStartPos;
|
||||||
QTimer *windowMoveElevateTimer;
|
QTimer *windowMoveElevateTimer;
|
||||||
|
std::chrono::milliseconds lastPresentTime;
|
||||||
|
|
||||||
// Soft highlighting
|
// Soft highlighting
|
||||||
QList<QTimeLine*> hoverTimeline;
|
QList<QTimeLine*> hoverTimeline;
|
||||||
|
|
|
@ -82,9 +82,13 @@ void DimInactiveEffect::reconfigure(ReconfigureFlags flags)
|
||||||
effects->addRepaintFull();
|
effects->addRepaintFull();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DimInactiveEffect::prePaintScreen(ScreenPrePaintData &data, int time)
|
void DimInactiveEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
const std::chrono::milliseconds delta(time);
|
std::chrono::milliseconds delta(0);
|
||||||
|
if (m_lastPresentTime.count()) {
|
||||||
|
delta = presentTime - m_lastPresentTime;
|
||||||
|
}
|
||||||
|
m_lastPresentTime = presentTime;
|
||||||
|
|
||||||
if (m_fullScreenTransition.active) {
|
if (m_fullScreenTransition.active) {
|
||||||
m_fullScreenTransition.timeLine.update(delta);
|
m_fullScreenTransition.timeLine.update(delta);
|
||||||
|
@ -96,7 +100,7 @@ void DimInactiveEffect::prePaintScreen(ScreenPrePaintData &data, int time)
|
||||||
++transitionIt;
|
++transitionIt;
|
||||||
}
|
}
|
||||||
|
|
||||||
effects->prePaintScreen(data, time);
|
effects->prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DimInactiveEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
|
void DimInactiveEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
|
||||||
|
@ -144,6 +148,10 @@ void DimInactiveEffect::postPaintScreen()
|
||||||
w->addRepaintFull();
|
w->addRepaintFull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_transitions.isEmpty() && !m_fullScreenTransition.active) {
|
||||||
|
m_lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
|
}
|
||||||
|
|
||||||
effects->postPaintScreen();
|
effects->postPaintScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ public:
|
||||||
|
|
||||||
void reconfigure(ReconfigureFlags flags) override;
|
void reconfigure(ReconfigureFlags flags) override;
|
||||||
|
|
||||||
void prePaintScreen(ScreenPrePaintData &data, int time) override;
|
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override;
|
void paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override;
|
||||||
void postPaintScreen() override;
|
void postPaintScreen() override;
|
||||||
|
|
||||||
|
@ -77,6 +77,7 @@ private:
|
||||||
const EffectWindowGroup *m_activeWindowGroup;
|
const EffectWindowGroup *m_activeWindowGroup;
|
||||||
QHash<EffectWindow*, TimeLine> m_transitions;
|
QHash<EffectWindow*, TimeLine> m_transitions;
|
||||||
QHash<EffectWindow*, qreal> m_forceDim;
|
QHash<EffectWindow*, qreal> m_forceDim;
|
||||||
|
std::chrono::milliseconds m_lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
bool active = false;
|
bool active = false;
|
||||||
|
|
|
@ -36,18 +36,25 @@ void FallApartEffect::reconfigure(ReconfigureFlags)
|
||||||
blockSize = FallApartConfig::blockSize();
|
blockSize = FallApartConfig::blockSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FallApartEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
void FallApartEffect::prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
if (!windows.isEmpty())
|
if (!windows.isEmpty())
|
||||||
data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
|
data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
|
||||||
effects->prePaintScreen(data, time);
|
effects->prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FallApartEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
|
void FallApartEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
if (windows.contains(w) && isRealWindow(w)) {
|
auto animationIt = windows.find(w);
|
||||||
if (windows[ w ] < 1) {
|
if (animationIt != windows.end() && isRealWindow(w)) {
|
||||||
windows[ w ] += time / animationTime(1000.);
|
if (animationIt->progress < 1) {
|
||||||
|
int time = 0;
|
||||||
|
if (animationIt->lastPresentTime.count()) {
|
||||||
|
time = (presentTime - animationIt->lastPresentTime).count();
|
||||||
|
}
|
||||||
|
animationIt->lastPresentTime = presentTime;
|
||||||
|
|
||||||
|
animationIt->progress += time / animationTime(1000.);
|
||||||
data.setTransformed();
|
data.setTransformed();
|
||||||
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DELETE);
|
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DELETE);
|
||||||
// Request the window to be divided into cells
|
// Request the window to be divided into cells
|
||||||
|
@ -57,13 +64,14 @@ void FallApartEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data,
|
||||||
w->unrefWindow();
|
w->unrefWindow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
effects->prePaintWindow(w, data, time);
|
effects->prePaintWindow(w, data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FallApartEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
void FallApartEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
||||||
{
|
{
|
||||||
if (windows.contains(w) && isRealWindow(w)) {
|
auto animationIt = windows.constFind(w);
|
||||||
const qreal t = windows[w];
|
if (animationIt != windows.constEnd() && isRealWindow(w)) {
|
||||||
|
const qreal t = animationIt->progress;
|
||||||
WindowQuadList new_quads;
|
WindowQuadList new_quads;
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
foreach (WindowQuad quad, data.quads) { // krazy:exclude=foreach
|
foreach (WindowQuad quad, data.quads) { // krazy:exclude=foreach
|
||||||
|
@ -99,7 +107,7 @@ void FallApartEffect::paintWindow(EffectWindow* w, int mask, QRegion region, Win
|
||||||
double x = quad[ j ].x() - center.x();
|
double x = quad[ j ].x() - center.x();
|
||||||
double y = quad[ j ].y() - center.y();
|
double y = quad[ j ].y() - center.y();
|
||||||
double angle = atan2(y, x);
|
double angle = atan2(y, x);
|
||||||
angle += windows[ w ] * adiff;
|
angle += animationIt->progress * adiff;
|
||||||
double dist = sqrt(x * x + y * y);
|
double dist = sqrt(x * x + y * y);
|
||||||
x = dist * cos(angle);
|
x = dist * cos(angle);
|
||||||
y = dist * sin(angle);
|
y = dist * sin(angle);
|
||||||
|
@ -156,7 +164,7 @@ void FallApartEffect::slotWindowClosed(EffectWindow* c)
|
||||||
if (e && e != this)
|
if (e && e != this)
|
||||||
return;
|
return;
|
||||||
c->setData(WindowClosedGrabRole, QVariant::fromValue(static_cast<void*>(this)));
|
c->setData(WindowClosedGrabRole, QVariant::fromValue(static_cast<void*>(this)));
|
||||||
windows[ c ] = 0;
|
windows[ c ].progress = 0;
|
||||||
c->refWindow();
|
c->refWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,12 @@
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
|
||||||
|
struct FallApartAnimation
|
||||||
|
{
|
||||||
|
std::chrono::milliseconds lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
|
qreal progress = 0;
|
||||||
|
};
|
||||||
|
|
||||||
class FallApartEffect
|
class FallApartEffect
|
||||||
: public Effect
|
: public Effect
|
||||||
{
|
{
|
||||||
|
@ -23,8 +29,8 @@ class FallApartEffect
|
||||||
public:
|
public:
|
||||||
FallApartEffect();
|
FallApartEffect();
|
||||||
void reconfigure(ReconfigureFlags) override;
|
void reconfigure(ReconfigureFlags) override;
|
||||||
void prePaintScreen(ScreenPrePaintData& data, int time) override;
|
void prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time) override;
|
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) override;
|
void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) override;
|
||||||
void postPaintScreen() override;
|
void postPaintScreen() override;
|
||||||
bool isActive() const override;
|
bool isActive() const override;
|
||||||
|
@ -46,7 +52,7 @@ public Q_SLOTS:
|
||||||
void slotWindowDataChanged(KWin::EffectWindow *w, int role);
|
void slotWindowDataChanged(KWin::EffectWindow *w, int role);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QHash< EffectWindow*, double > windows;
|
QHash< EffectWindow*, FallApartAnimation > windows;
|
||||||
bool isRealWindow(EffectWindow* w);
|
bool isRealWindow(EffectWindow* w);
|
||||||
int blockSize;
|
int blockSize;
|
||||||
};
|
};
|
||||||
|
|
|
@ -27,6 +27,7 @@ namespace KWin
|
||||||
FlipSwitchEffect::FlipSwitchEffect()
|
FlipSwitchEffect::FlipSwitchEffect()
|
||||||
: m_selectedWindow(nullptr)
|
: m_selectedWindow(nullptr)
|
||||||
, m_currentAnimationEasingCurve(QEasingCurve::InOutSine)
|
, m_currentAnimationEasingCurve(QEasingCurve::InOutSine)
|
||||||
|
, m_lastPresentTime(std::chrono::milliseconds::zero())
|
||||||
, m_active(false)
|
, m_active(false)
|
||||||
, m_start(false)
|
, m_start(false)
|
||||||
, m_stop(false)
|
, m_stop(false)
|
||||||
|
@ -93,8 +94,14 @@ void FlipSwitchEffect::reconfigure(ReconfigureFlags)
|
||||||
m_windowTitle = FlipSwitchConfig::windowTitle();
|
m_windowTitle = FlipSwitchConfig::windowTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlipSwitchEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
void FlipSwitchEffect::prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
|
int time = 0;
|
||||||
|
if (m_lastPresentTime.count()) {
|
||||||
|
time = (presentTime - m_lastPresentTime).count();
|
||||||
|
}
|
||||||
|
m_lastPresentTime = presentTime;
|
||||||
|
|
||||||
if (m_active) {
|
if (m_active) {
|
||||||
data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
|
data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
|
||||||
if (m_start)
|
if (m_start)
|
||||||
|
@ -104,7 +111,7 @@ void FlipSwitchEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
||||||
if (m_animation)
|
if (m_animation)
|
||||||
m_timeLine.setCurrentTime(m_timeLine.currentTime() + time);
|
m_timeLine.setCurrentTime(m_timeLine.currentTime() + time);
|
||||||
}
|
}
|
||||||
effects->prePaintScreen(data, time);
|
effects->prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlipSwitchEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data)
|
void FlipSwitchEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data)
|
||||||
|
@ -318,6 +325,7 @@ void FlipSwitchEffect::postPaintScreen()
|
||||||
m_stop = false;
|
m_stop = false;
|
||||||
m_active = false;
|
m_active = false;
|
||||||
m_captionFrame->free();
|
m_captionFrame->free();
|
||||||
|
m_lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
effects->setActiveFullScreenEffect(nullptr);
|
effects->setActiveFullScreenEffect(nullptr);
|
||||||
effects->addRepaintFull();
|
effects->addRepaintFull();
|
||||||
qDeleteAll(m_windows);
|
qDeleteAll(m_windows);
|
||||||
|
@ -347,7 +355,7 @@ void FlipSwitchEffect::postPaintScreen()
|
||||||
effects->postPaintScreen();
|
effects->postPaintScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlipSwitchEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
|
void FlipSwitchEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
if (m_active) {
|
if (m_active) {
|
||||||
if (m_windows.contains(w)) {
|
if (m_windows.contains(w)) {
|
||||||
|
@ -364,7 +372,7 @@ void FlipSwitchEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data,
|
||||||
w->disablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
|
w->disablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
effects->prePaintWindow(w, data, time);
|
effects->prePaintWindow(w, data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlipSwitchEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
void FlipSwitchEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
||||||
|
|
|
@ -35,10 +35,10 @@ public:
|
||||||
~FlipSwitchEffect() override;
|
~FlipSwitchEffect() override;
|
||||||
|
|
||||||
void reconfigure(ReconfigureFlags) override;
|
void reconfigure(ReconfigureFlags) override;
|
||||||
void prePaintScreen(ScreenPrePaintData& data, int time) override;
|
void prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) override;
|
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) override;
|
||||||
void postPaintScreen() override;
|
void postPaintScreen() override;
|
||||||
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time) override;
|
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) override;
|
void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) override;
|
||||||
void grabbedKeyboardEvent(QKeyEvent* e) override;
|
void grabbedKeyboardEvent(QKeyEvent* e) override;
|
||||||
void windowInputMouseEvent(QEvent* e) override;
|
void windowInputMouseEvent(QEvent* e) override;
|
||||||
|
@ -112,6 +112,7 @@ private:
|
||||||
QTimeLine m_timeLine;
|
QTimeLine m_timeLine;
|
||||||
QTimeLine m_startStopTimeLine;
|
QTimeLine m_startStopTimeLine;
|
||||||
QEasingCurve m_currentAnimationEasingCurve;
|
QEasingCurve m_currentAnimationEasingCurve;
|
||||||
|
std::chrono::milliseconds m_lastPresentTime;
|
||||||
QRect m_screenArea;
|
QRect m_screenArea;
|
||||||
int m_activeScreen;
|
int m_activeScreen;
|
||||||
bool m_active;
|
bool m_active;
|
||||||
|
|
|
@ -68,29 +68,33 @@ void GlideEffect::reconfigure(ReconfigureFlags flags)
|
||||||
m_outParams.opacity.to = GlideConfig::outOpacity();
|
m_outParams.opacity.to = GlideConfig::outOpacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlideEffect::prePaintScreen(ScreenPrePaintData &data, int time)
|
void GlideEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
const std::chrono::milliseconds delta(time);
|
|
||||||
|
|
||||||
auto animationIt = m_animations.begin();
|
auto animationIt = m_animations.begin();
|
||||||
while (animationIt != m_animations.end()) {
|
while (animationIt != m_animations.end()) {
|
||||||
(*animationIt).update(delta);
|
std::chrono::milliseconds delta = std::chrono::milliseconds::zero();
|
||||||
|
if (animationIt->lastPresentTime.count()) {
|
||||||
|
delta = presentTime - animationIt->lastPresentTime;
|
||||||
|
}
|
||||||
|
animationIt->lastPresentTime = presentTime;
|
||||||
|
|
||||||
|
(*animationIt).timeLine.update(delta);
|
||||||
++animationIt;
|
++animationIt;
|
||||||
}
|
}
|
||||||
|
|
||||||
data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
|
data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
|
||||||
|
|
||||||
effects->prePaintScreen(data, time);
|
effects->prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlideEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time)
|
void GlideEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
if (m_animations.contains(w)) {
|
if (m_animations.contains(w)) {
|
||||||
data.setTransformed();
|
data.setTransformed();
|
||||||
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DELETE);
|
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DELETE);
|
||||||
}
|
}
|
||||||
|
|
||||||
effects->prePaintWindow(w, data, time);
|
effects->prePaintWindow(w, data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlideEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
|
void GlideEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
|
||||||
|
@ -123,7 +127,7 @@ void GlideEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowP
|
||||||
data.translate(offset.x(), offset.y());
|
data.translate(offset.x(), offset.y());
|
||||||
|
|
||||||
const GlideParams params = w->isDeleted() ? m_outParams : m_inParams;
|
const GlideParams params = w->isDeleted() ? m_outParams : m_inParams;
|
||||||
const qreal t = (*animationIt).value();
|
const qreal t = (*animationIt).timeLine.value();
|
||||||
|
|
||||||
switch (params.edge) {
|
switch (params.edge) {
|
||||||
case RotationEdge::Top:
|
case RotationEdge::Top:
|
||||||
|
@ -168,7 +172,7 @@ void GlideEffect::postPaintScreen()
|
||||||
{
|
{
|
||||||
auto animationIt = m_animations.begin();
|
auto animationIt = m_animations.begin();
|
||||||
while (animationIt != m_animations.end()) {
|
while (animationIt != m_animations.end()) {
|
||||||
if ((*animationIt).done()) {
|
if ((*animationIt).timeLine.done()) {
|
||||||
EffectWindow *w = animationIt.key();
|
EffectWindow *w = animationIt.key();
|
||||||
if (w->isDeleted()) {
|
if (w->isDeleted()) {
|
||||||
w->unrefWindow();
|
w->unrefWindow();
|
||||||
|
@ -215,11 +219,11 @@ void GlideEffect::windowAdded(EffectWindow *w)
|
||||||
|
|
||||||
w->setData(WindowAddedGrabRole, QVariant::fromValue(static_cast<void*>(this)));
|
w->setData(WindowAddedGrabRole, QVariant::fromValue(static_cast<void*>(this)));
|
||||||
|
|
||||||
TimeLine &timeLine = m_animations[w];
|
GlideAnimation &animation = m_animations[w];
|
||||||
timeLine.reset();
|
animation.timeLine.reset();
|
||||||
timeLine.setDirection(TimeLine::Forward);
|
animation.timeLine.setDirection(TimeLine::Forward);
|
||||||
timeLine.setDuration(m_duration);
|
animation.timeLine.setDuration(m_duration);
|
||||||
timeLine.setEasingCurve(QEasingCurve::InCurve);
|
animation.timeLine.setEasingCurve(QEasingCurve::InCurve);
|
||||||
|
|
||||||
effects->addRepaintFull();
|
effects->addRepaintFull();
|
||||||
}
|
}
|
||||||
|
@ -246,11 +250,11 @@ void GlideEffect::windowClosed(EffectWindow *w)
|
||||||
w->refWindow();
|
w->refWindow();
|
||||||
w->setData(WindowClosedGrabRole, QVariant::fromValue(static_cast<void*>(this)));
|
w->setData(WindowClosedGrabRole, QVariant::fromValue(static_cast<void*>(this)));
|
||||||
|
|
||||||
TimeLine &timeLine = m_animations[w];
|
GlideAnimation &animation = m_animations[w];
|
||||||
timeLine.reset();
|
animation.timeLine.reset();
|
||||||
timeLine.setDirection(TimeLine::Forward);
|
animation.timeLine.setDirection(TimeLine::Forward);
|
||||||
timeLine.setDuration(m_duration);
|
animation.timeLine.setDuration(m_duration);
|
||||||
timeLine.setEasingCurve(QEasingCurve::OutCurve);
|
animation.timeLine.setEasingCurve(QEasingCurve::OutCurve);
|
||||||
|
|
||||||
effects->addRepaintFull();
|
effects->addRepaintFull();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,12 @@
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
|
||||||
|
struct GlideAnimation
|
||||||
|
{
|
||||||
|
TimeLine timeLine;
|
||||||
|
std::chrono::milliseconds lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
|
};
|
||||||
|
|
||||||
class GlideEffect : public Effect
|
class GlideEffect : public Effect
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -38,8 +44,8 @@ public:
|
||||||
|
|
||||||
void reconfigure(ReconfigureFlags flags) override;
|
void reconfigure(ReconfigureFlags flags) override;
|
||||||
|
|
||||||
void prePaintScreen(ScreenPrePaintData &data, int time) override;
|
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override;
|
||||||
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time) override;
|
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override;
|
void paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override;
|
||||||
void postPaintScreen() override;
|
void postPaintScreen() override;
|
||||||
|
|
||||||
|
@ -76,7 +82,7 @@ private:
|
||||||
bool isGlideWindow(EffectWindow *w) const;
|
bool isGlideWindow(EffectWindow *w) const;
|
||||||
|
|
||||||
std::chrono::milliseconds m_duration;
|
std::chrono::milliseconds m_duration;
|
||||||
QHash<EffectWindow*, TimeLine> m_animations;
|
QHash<EffectWindow *, GlideAnimation> m_animations;
|
||||||
|
|
||||||
struct GlideParams {
|
struct GlideParams {
|
||||||
RotationEdge edge;
|
RotationEdge edge;
|
||||||
|
|
|
@ -43,59 +43,76 @@ static bool isInitiallyHidden(EffectWindow* w)
|
||||||
return w->isMinimized() || !w->isOnCurrentDesktop();
|
return w->isMinimized() || !w->isOnCurrentDesktop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HighlightWindowEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
|
void HighlightWindowEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
// Calculate window opacities
|
// Calculate window opacities
|
||||||
QHash<EffectWindow*, float>::iterator opacity = m_windowOpacity.find(w);
|
QHash<EffectWindow*, HightlightWindowData>::iterator it = m_animations.find(w);
|
||||||
if (!m_highlightedWindows.isEmpty()) {
|
if (!m_highlightedWindows.isEmpty()) {
|
||||||
// Initial fade out and changing highlight animation
|
// Initial fade out and changing highlight animation
|
||||||
if (opacity == m_windowOpacity.end())
|
if (it == m_animations.end())
|
||||||
opacity = m_windowOpacity.insert(w, 0.0f);
|
it = m_animations.insert(w, HightlightWindowData());
|
||||||
float oldOpacity = *opacity;
|
|
||||||
|
int time = 1;
|
||||||
|
if (it->lastPresentTime.count()) {
|
||||||
|
time = std::max(1, int((presentTime - it->lastPresentTime).count()));
|
||||||
|
}
|
||||||
|
it->lastPresentTime = presentTime;
|
||||||
|
|
||||||
|
float oldOpacity = it->opacity;
|
||||||
if (m_highlightedWindows.contains(w))
|
if (m_highlightedWindows.contains(w))
|
||||||
*opacity = qMin(1.0f, oldOpacity + time / m_fadeDuration);
|
it->opacity = qMin(1.0f, oldOpacity + time / m_fadeDuration);
|
||||||
else if (w->isNormalWindow() || w->isDialog()) // Only fade out windows
|
else if (w->isNormalWindow() || w->isDialog()) // Only fade out windows
|
||||||
*opacity = qMax(isInitiallyHidden(w) ? 0.0f : 0.15f, oldOpacity - time / m_fadeDuration);
|
it->opacity = qMax(isInitiallyHidden(w) ? 0.0f : 0.15f, oldOpacity - time / m_fadeDuration);
|
||||||
|
|
||||||
if (*opacity < 0.98f)
|
if (it->opacity < 0.98f)
|
||||||
data.setTranslucent();
|
data.setTranslucent();
|
||||||
if (oldOpacity != *opacity)
|
if (oldOpacity != it->opacity)
|
||||||
effects->addRepaint(w->expandedGeometry());
|
effects->addRepaint(w->expandedGeometry());
|
||||||
} else if (m_finishing && m_windowOpacity.contains(w)) {
|
} else if (m_finishing && m_animations.contains(w)) {
|
||||||
// Final fading back in animation
|
// Final fading back in animation
|
||||||
if (opacity == m_windowOpacity.end())
|
if (it == m_animations.end())
|
||||||
opacity = m_windowOpacity.insert(w, 0.0f);
|
it = m_animations.insert(w, HightlightWindowData());
|
||||||
float oldOpacity = *opacity;
|
|
||||||
if (isInitiallyHidden(w))
|
|
||||||
*opacity = qMax(0.0f, oldOpacity - time / m_fadeDuration);
|
|
||||||
else
|
|
||||||
*opacity = qMin(1.0f, oldOpacity + time / m_fadeDuration);
|
|
||||||
|
|
||||||
if (*opacity < 0.98f)
|
int time = 1;
|
||||||
|
if (it->lastPresentTime.count()) {
|
||||||
|
time = std::max(1, int((presentTime - it->lastPresentTime).count()));
|
||||||
|
}
|
||||||
|
it->lastPresentTime = presentTime;
|
||||||
|
|
||||||
|
float oldOpacity = it->opacity;
|
||||||
|
if (isInitiallyHidden(w))
|
||||||
|
it->opacity = qMax(0.0f, oldOpacity - time / m_fadeDuration);
|
||||||
|
else
|
||||||
|
it->opacity = qMin(1.0f, oldOpacity + time / m_fadeDuration);
|
||||||
|
|
||||||
|
if (it->opacity < 0.98f)
|
||||||
data.setTranslucent();
|
data.setTranslucent();
|
||||||
if (oldOpacity != *opacity)
|
if (oldOpacity != it->opacity)
|
||||||
effects->addRepaint(w->expandedGeometry());
|
effects->addRepaint(w->expandedGeometry());
|
||||||
|
|
||||||
if (*opacity > 0.98f || *opacity < 0.02f) {
|
if (it->opacity > 0.98f || it->opacity < 0.02f) {
|
||||||
m_windowOpacity.remove(w); // We default to 1.0
|
m_animations.remove(w); // We default to 1.0
|
||||||
opacity = m_windowOpacity.end();
|
it = m_animations.end();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show tabbed windows and windows on other desktops if highlighted
|
// Show tabbed windows and windows on other desktops if highlighted
|
||||||
if (opacity != m_windowOpacity.end() && *opacity > 0.01) {
|
if (it != m_animations.end() && it->opacity > 0.01) {
|
||||||
if (w->isMinimized())
|
if (w->isMinimized())
|
||||||
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_MINIMIZE);
|
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_MINIMIZE);
|
||||||
if (!w->isOnCurrentDesktop())
|
if (!w->isOnCurrentDesktop())
|
||||||
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
|
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
effects->prePaintWindow(w, data, time);
|
effects->prePaintWindow(w, data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HighlightWindowEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
void HighlightWindowEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
||||||
{
|
{
|
||||||
data.multiplyOpacity(m_windowOpacity.value(w, 1.0f));
|
auto it = m_animations.constFind(w);
|
||||||
|
if (it != m_animations.constEnd()) {
|
||||||
|
data.multiplyOpacity(it->opacity);
|
||||||
|
}
|
||||||
effects->paintWindow(w, mask, region, data);
|
effects->paintWindow(w, mask, region, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,11 +122,11 @@ void HighlightWindowEffect::slotWindowAdded(EffectWindow* w)
|
||||||
// The effect is activated thus we need to add it to the opacity hash
|
// The effect is activated thus we need to add it to the opacity hash
|
||||||
foreach (const WId id, m_highlightedIds) {
|
foreach (const WId id, m_highlightedIds) {
|
||||||
if (w == effects->findWindow(id)) {
|
if (w == effects->findWindow(id)) {
|
||||||
m_windowOpacity[w] = 1.0; // this window was demanded to be highlighted before it appeared
|
m_animations[w].opacity = 1.0; // this window was demanded to be highlighted before it appeared
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_windowOpacity[w] = 0.15; // this window is not currently highlighted
|
m_animations[w].opacity = 0.15; // this window is not currently highlighted
|
||||||
}
|
}
|
||||||
slotPropertyNotify(w, m_atom, w); // Check initial value
|
slotPropertyNotify(w, m_atom, w); // Check initial value
|
||||||
}
|
}
|
||||||
|
@ -122,7 +139,7 @@ void HighlightWindowEffect::slotWindowClosed(EffectWindow* w)
|
||||||
|
|
||||||
void HighlightWindowEffect::slotWindowDeleted(EffectWindow* w)
|
void HighlightWindowEffect::slotWindowDeleted(EffectWindow* w)
|
||||||
{
|
{
|
||||||
m_windowOpacity.remove(w);
|
m_animations.remove(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HighlightWindowEffect::slotPropertyNotify(EffectWindow* w, long a, EffectWindow *addedWindow)
|
void HighlightWindowEffect::slotPropertyNotify(EffectWindow* w, long a, EffectWindow *addedWindow)
|
||||||
|
@ -172,7 +189,7 @@ void HighlightWindowEffect::slotPropertyNotify(EffectWindow* w, long a, EffectWi
|
||||||
}
|
}
|
||||||
prepareHighlighting();
|
prepareHighlighting();
|
||||||
if (w)
|
if (w)
|
||||||
m_windowOpacity[w] = 1.0; // Because it's not in stackingOrder() yet
|
m_animations[w].opacity = 1.0; // Because it's not in stackingOrder() yet
|
||||||
|
|
||||||
/* TODO: Finish thumbnails of offscreen windows, not sure if it's worth it though
|
/* TODO: Finish thumbnails of offscreen windows, not sure if it's worth it though
|
||||||
if ( !m_highlightedWindow->isOnCurrentDesktop() )
|
if ( !m_highlightedWindow->isOnCurrentDesktop() )
|
||||||
|
@ -238,8 +255,8 @@ void HighlightWindowEffect::prepareHighlighting()
|
||||||
// Create window data for every window. Just calling [w] creates it.
|
// Create window data for every window. Just calling [w] creates it.
|
||||||
m_finishing = false;
|
m_finishing = false;
|
||||||
foreach (EffectWindow * w, effects->stackingOrder()) {
|
foreach (EffectWindow * w, effects->stackingOrder()) {
|
||||||
if (!m_windowOpacity.contains(w)) // Just in case we are still finishing from last time
|
if (!m_animations.contains(w)) // Just in case we are still finishing from last time
|
||||||
m_windowOpacity.insert(w, isInitiallyHidden(w) ? 0.0 : 1.0);
|
m_animations[w].opacity = isInitiallyHidden(w) ? 0.0 : 1.0;
|
||||||
if (!m_highlightedWindows.isEmpty())
|
if (!m_highlightedWindows.isEmpty())
|
||||||
m_highlightedWindows.at(0)->addRepaintFull();
|
m_highlightedWindows.at(0)->addRepaintFull();
|
||||||
}
|
}
|
||||||
|
@ -250,8 +267,8 @@ void HighlightWindowEffect::finishHighlighting()
|
||||||
m_finishing = true;
|
m_finishing = true;
|
||||||
m_monitorWindow = nullptr;
|
m_monitorWindow = nullptr;
|
||||||
m_highlightedWindows.clear();
|
m_highlightedWindows.clear();
|
||||||
if (!m_windowOpacity.isEmpty())
|
if (!m_animations.isEmpty())
|
||||||
m_windowOpacity.constBegin().key()->addRepaintFull();
|
m_animations.constBegin().key()->addRepaintFull();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HighlightWindowEffect::highlightWindows(const QVector<KWin::EffectWindow *> &windows)
|
void HighlightWindowEffect::highlightWindows(const QVector<KWin::EffectWindow *> &windows)
|
||||||
|
@ -272,7 +289,7 @@ void HighlightWindowEffect::highlightWindows(const QVector<KWin::EffectWindow *>
|
||||||
|
|
||||||
bool HighlightWindowEffect::isActive() const
|
bool HighlightWindowEffect::isActive() const
|
||||||
{
|
{
|
||||||
return !(m_windowOpacity.isEmpty() || effects->isScreenLocked());
|
return !(m_animations.isEmpty() || effects->isScreenLocked());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HighlightWindowEffect::provides(Feature feature)
|
bool HighlightWindowEffect::provides(Feature feature)
|
||||||
|
|
|
@ -15,6 +15,12 @@
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
|
||||||
|
struct HightlightWindowData
|
||||||
|
{
|
||||||
|
std::chrono::milliseconds lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
|
float opacity = 0;
|
||||||
|
};
|
||||||
|
|
||||||
class HighlightWindowEffect
|
class HighlightWindowEffect
|
||||||
: public Effect
|
: public Effect
|
||||||
{
|
{
|
||||||
|
@ -23,7 +29,7 @@ public:
|
||||||
HighlightWindowEffect();
|
HighlightWindowEffect();
|
||||||
~HighlightWindowEffect() override;
|
~HighlightWindowEffect() override;
|
||||||
|
|
||||||
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time) override;
|
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) override;
|
void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) override;
|
||||||
bool isActive() const override;
|
bool isActive() const override;
|
||||||
|
|
||||||
|
@ -49,7 +55,7 @@ private:
|
||||||
bool m_finishing;
|
bool m_finishing;
|
||||||
|
|
||||||
float m_fadeDuration;
|
float m_fadeDuration;
|
||||||
QHash<EffectWindow*, float> m_windowOpacity;
|
QHash<EffectWindow *, HightlightWindowData> m_animations;
|
||||||
|
|
||||||
long m_atom;
|
long m_atom;
|
||||||
QList<EffectWindow*> m_highlightedWindows;
|
QList<EffectWindow*> m_highlightedWindows;
|
||||||
|
|
|
@ -41,6 +41,7 @@ namespace KWin
|
||||||
|
|
||||||
KscreenEffect::KscreenEffect()
|
KscreenEffect::KscreenEffect()
|
||||||
: Effect()
|
: Effect()
|
||||||
|
, m_lastPresentTime(std::chrono::milliseconds::zero())
|
||||||
, m_state(StateNormal)
|
, m_state(StateNormal)
|
||||||
, m_atom(effects->announceSupportProperty("_KDE_KWIN_KSCREEN_SUPPORT", this))
|
, m_atom(effects->announceSupportProperty("_KDE_KWIN_KSCREEN_SUPPORT", this))
|
||||||
{
|
{
|
||||||
|
@ -67,15 +68,27 @@ void KscreenEffect::reconfigure(ReconfigureFlags flags)
|
||||||
std::chrono::milliseconds(animationTime<KscreenConfig>(250)));
|
std::chrono::milliseconds(animationTime<KscreenConfig>(250)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void KscreenEffect::prePaintScreen(ScreenPrePaintData &data, int time)
|
void KscreenEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
|
std::chrono::milliseconds delta = std::chrono::milliseconds::zero();
|
||||||
|
if (m_lastPresentTime.count()) {
|
||||||
|
delta = presentTime - m_lastPresentTime;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_state == StateFadingIn || m_state == StateFadingOut) {
|
if (m_state == StateFadingIn || m_state == StateFadingOut) {
|
||||||
m_timeLine.update(std::chrono::milliseconds(time));
|
m_timeLine.update(delta);
|
||||||
if (m_timeLine.done()) {
|
if (m_timeLine.done()) {
|
||||||
switchState();
|
switchState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
effects->prePaintScreen(data, time);
|
|
||||||
|
if (isActive()) {
|
||||||
|
m_lastPresentTime = presentTime;
|
||||||
|
} else {
|
||||||
|
m_lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
|
}
|
||||||
|
|
||||||
|
effects->prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KscreenEffect::postPaintScreen()
|
void KscreenEffect::postPaintScreen()
|
||||||
|
@ -85,12 +98,12 @@ void KscreenEffect::postPaintScreen()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KscreenEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time)
|
void KscreenEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
if (m_state != StateNormal) {
|
if (m_state != StateNormal) {
|
||||||
data.setTranslucent();
|
data.setTranslucent();
|
||||||
}
|
}
|
||||||
effects->prePaintWindow(w, data, time);
|
effects->prePaintWindow(w, data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KscreenEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
|
void KscreenEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
|
||||||
|
|
|
@ -22,9 +22,9 @@ public:
|
||||||
KscreenEffect();
|
KscreenEffect();
|
||||||
~KscreenEffect() override;
|
~KscreenEffect() override;
|
||||||
|
|
||||||
void prePaintScreen(ScreenPrePaintData &data, int time) override;
|
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override;
|
||||||
void postPaintScreen() override;
|
void postPaintScreen() override;
|
||||||
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time) override;
|
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override;
|
void paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override;
|
||||||
|
|
||||||
void reconfigure(ReconfigureFlags flags) override;
|
void reconfigure(ReconfigureFlags flags) override;
|
||||||
|
@ -46,6 +46,7 @@ private:
|
||||||
StateFadingIn
|
StateFadingIn
|
||||||
};
|
};
|
||||||
TimeLine m_timeLine;
|
TimeLine m_timeLine;
|
||||||
|
std::chrono::milliseconds m_lastPresentTime;
|
||||||
FadeOutState m_state;
|
FadeOutState m_state;
|
||||||
xcb_atom_t m_atom;
|
xcb_atom_t m_atom;
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,6 +38,7 @@ LookingGlassEffect::LookingGlassEffect()
|
||||||
, m_fbo(nullptr)
|
, m_fbo(nullptr)
|
||||||
, m_vbo(nullptr)
|
, m_vbo(nullptr)
|
||||||
, m_shader(nullptr)
|
, m_shader(nullptr)
|
||||||
|
, m_lastPresentTime(std::chrono::milliseconds::zero())
|
||||||
, m_enabled(false)
|
, m_enabled(false)
|
||||||
, m_valid(false)
|
, m_valid(false)
|
||||||
{
|
{
|
||||||
|
@ -179,8 +180,9 @@ void LookingGlassEffect::zoomOut()
|
||||||
effects->addRepaint(cursorPos().x() - radius, cursorPos().y() - radius, 2 * radius, 2 * radius);
|
effects->addRepaint(cursorPos().x() - radius, cursorPos().y() - radius, 2 * radius, 2 * radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LookingGlassEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
void LookingGlassEffect::prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
|
const int time = m_lastPresentTime.count() ? (presentTime - m_lastPresentTime).count() : 0;
|
||||||
if (zoom != target_zoom) {
|
if (zoom != target_zoom) {
|
||||||
double diff = time / animationTime(500.0);
|
double diff = time / animationTime(500.0);
|
||||||
if (target_zoom > zoom)
|
if (target_zoom > zoom)
|
||||||
|
@ -196,13 +198,18 @@ void LookingGlassEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
||||||
|
|
||||||
effects->addRepaint(cursorPos().x() - radius, cursorPos().y() - radius, 2 * radius, 2 * radius);
|
effects->addRepaint(cursorPos().x() - radius, cursorPos().y() - radius, 2 * radius, 2 * radius);
|
||||||
}
|
}
|
||||||
|
if (zoom != target_zoom) {
|
||||||
|
m_lastPresentTime = presentTime;
|
||||||
|
} else {
|
||||||
|
m_lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
|
}
|
||||||
if (m_valid && m_enabled) {
|
if (m_valid && m_enabled) {
|
||||||
data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
|
data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
|
||||||
// Start rendering to texture
|
// Start rendering to texture
|
||||||
GLRenderTarget::pushRenderTarget(m_fbo);
|
GLRenderTarget::pushRenderTarget(m_fbo);
|
||||||
}
|
}
|
||||||
|
|
||||||
effects->prePaintScreen(data, time);
|
effects->prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LookingGlassEffect::slotMouseChanged(const QPoint& pos, const QPoint& old, Qt::MouseButtons,
|
void LookingGlassEffect::slotMouseChanged(const QPoint& pos, const QPoint& old, Qt::MouseButtons,
|
||||||
|
|
|
@ -34,7 +34,7 @@ public:
|
||||||
|
|
||||||
void reconfigure(ReconfigureFlags) override;
|
void reconfigure(ReconfigureFlags) override;
|
||||||
|
|
||||||
void prePaintScreen(ScreenPrePaintData& data, int time) override;
|
void prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData &data) override;
|
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData &data) override;
|
||||||
bool isActive() const override;
|
bool isActive() const override;
|
||||||
|
|
||||||
|
@ -63,6 +63,7 @@ private:
|
||||||
GLRenderTarget *m_fbo;
|
GLRenderTarget *m_fbo;
|
||||||
GLVertexBuffer *m_vbo;
|
GLVertexBuffer *m_vbo;
|
||||||
GLShader *m_shader;
|
GLShader *m_shader;
|
||||||
|
std::chrono::milliseconds m_lastPresentTime;
|
||||||
bool m_enabled;
|
bool m_enabled;
|
||||||
bool m_valid;
|
bool m_valid;
|
||||||
};
|
};
|
||||||
|
|
|
@ -42,13 +42,17 @@ void MagicLampEffect::reconfigure(ReconfigureFlags)
|
||||||
m_duration = std::chrono::milliseconds(static_cast<int>(animationTime(d)));
|
m_duration = std::chrono::milliseconds(static_cast<int>(animationTime(d)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MagicLampEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
void MagicLampEffect::prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
const std::chrono::milliseconds delta(time);
|
|
||||||
|
|
||||||
auto animationIt = m_animations.begin();
|
auto animationIt = m_animations.begin();
|
||||||
while (animationIt != m_animations.end()) {
|
while (animationIt != m_animations.end()) {
|
||||||
(*animationIt).update(delta);
|
std::chrono::milliseconds delta = std::chrono::milliseconds::zero();
|
||||||
|
if (animationIt->lastPresentTime.count()) {
|
||||||
|
delta = presentTime - animationIt->lastPresentTime;
|
||||||
|
}
|
||||||
|
animationIt->lastPresentTime = presentTime;
|
||||||
|
|
||||||
|
(*animationIt).timeLine.update(delta);
|
||||||
++animationIt;
|
++animationIt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,10 +60,10 @@ void MagicLampEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
||||||
// whole screen won't be repainted, resulting in artefacts.
|
// whole screen won't be repainted, resulting in artefacts.
|
||||||
data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
|
data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
|
||||||
|
|
||||||
effects->prePaintScreen(data, time);
|
effects->prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MagicLampEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
|
void MagicLampEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
// Schedule window for transformation if the animation is still in
|
// Schedule window for transformation if the animation is still in
|
||||||
// progress
|
// progress
|
||||||
|
@ -70,7 +74,7 @@ void MagicLampEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data,
|
||||||
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_MINIMIZE);
|
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_MINIMIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
effects->prePaintWindow(w, data, time);
|
effects->prePaintWindow(w, data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MagicLampEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
void MagicLampEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
||||||
|
@ -78,7 +82,7 @@ void MagicLampEffect::paintWindow(EffectWindow* w, int mask, QRegion region, Win
|
||||||
auto animationIt = m_animations.constFind(w);
|
auto animationIt = m_animations.constFind(w);
|
||||||
if (animationIt != m_animations.constEnd()) {
|
if (animationIt != m_animations.constEnd()) {
|
||||||
// 0 = not minimized, 1 = fully minimized
|
// 0 = not minimized, 1 = fully minimized
|
||||||
const qreal progress = (*animationIt).value();
|
const qreal progress = (*animationIt).timeLine.value();
|
||||||
|
|
||||||
QRect geo = w->geometry();
|
QRect geo = w->geometry();
|
||||||
QRect icon = w->iconGeometry();
|
QRect icon = w->iconGeometry();
|
||||||
|
@ -301,7 +305,7 @@ void MagicLampEffect::postPaintScreen()
|
||||||
{
|
{
|
||||||
auto animationIt = m_animations.begin();
|
auto animationIt = m_animations.begin();
|
||||||
while (animationIt != m_animations.end()) {
|
while (animationIt != m_animations.end()) {
|
||||||
if ((*animationIt).done()) {
|
if ((*animationIt).timeLine.done()) {
|
||||||
animationIt = m_animations.erase(animationIt);
|
animationIt = m_animations.erase(animationIt);
|
||||||
} else {
|
} else {
|
||||||
++animationIt;
|
++animationIt;
|
||||||
|
@ -324,14 +328,14 @@ void MagicLampEffect::slotWindowMinimized(EffectWindow* w)
|
||||||
if (effects->activeFullScreenEffect())
|
if (effects->activeFullScreenEffect())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TimeLine &timeLine = m_animations[w];
|
MagicLampAnimation &animation = m_animations[w];
|
||||||
|
|
||||||
if (timeLine.running()) {
|
if (animation.timeLine.running()) {
|
||||||
timeLine.toggleDirection();
|
animation.timeLine.toggleDirection();
|
||||||
} else {
|
} else {
|
||||||
timeLine.setDirection(TimeLine::Forward);
|
animation.timeLine.setDirection(TimeLine::Forward);
|
||||||
timeLine.setDuration(m_duration);
|
animation.timeLine.setDuration(m_duration);
|
||||||
timeLine.setEasingCurve(QEasingCurve::Linear);
|
animation.timeLine.setEasingCurve(QEasingCurve::Linear);
|
||||||
}
|
}
|
||||||
|
|
||||||
effects->addRepaintFull();
|
effects->addRepaintFull();
|
||||||
|
@ -342,14 +346,14 @@ void MagicLampEffect::slotWindowUnminimized(EffectWindow* w)
|
||||||
if (effects->activeFullScreenEffect())
|
if (effects->activeFullScreenEffect())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TimeLine &timeLine = m_animations[w];
|
MagicLampAnimation &animation = m_animations[w];
|
||||||
|
|
||||||
if (timeLine.running()) {
|
if (animation.timeLine.running()) {
|
||||||
timeLine.toggleDirection();
|
animation.timeLine.toggleDirection();
|
||||||
} else {
|
} else {
|
||||||
timeLine.setDirection(TimeLine::Backward);
|
animation.timeLine.setDirection(TimeLine::Backward);
|
||||||
timeLine.setDuration(m_duration);
|
animation.timeLine.setDuration(m_duration);
|
||||||
timeLine.setEasingCurve(QEasingCurve::Linear);
|
animation.timeLine.setEasingCurve(QEasingCurve::Linear);
|
||||||
}
|
}
|
||||||
|
|
||||||
effects->addRepaintFull();
|
effects->addRepaintFull();
|
||||||
|
|
|
@ -15,6 +15,12 @@
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
|
||||||
|
struct MagicLampAnimation
|
||||||
|
{
|
||||||
|
TimeLine timeLine;
|
||||||
|
std::chrono::milliseconds lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
|
};
|
||||||
|
|
||||||
class MagicLampEffect
|
class MagicLampEffect
|
||||||
: public Effect
|
: public Effect
|
||||||
{
|
{
|
||||||
|
@ -24,8 +30,8 @@ public:
|
||||||
MagicLampEffect();
|
MagicLampEffect();
|
||||||
|
|
||||||
void reconfigure(ReconfigureFlags) override;
|
void reconfigure(ReconfigureFlags) override;
|
||||||
void prePaintScreen(ScreenPrePaintData& data, int time) override;
|
void prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time) override;
|
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) override;
|
void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) override;
|
||||||
void postPaintScreen() override;
|
void postPaintScreen() override;
|
||||||
bool isActive() const override;
|
bool isActive() const override;
|
||||||
|
@ -43,7 +49,7 @@ public Q_SLOTS:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::chrono::milliseconds m_duration;
|
std::chrono::milliseconds m_duration;
|
||||||
QHash<const EffectWindow*, TimeLine> m_animations;
|
QHash<const EffectWindow *, MagicLampAnimation> m_animations;
|
||||||
|
|
||||||
enum IconPosition {
|
enum IconPosition {
|
||||||
Top,
|
Top,
|
||||||
|
|
|
@ -33,6 +33,7 @@ MagnifierEffect::MagnifierEffect()
|
||||||
: zoom(1)
|
: zoom(1)
|
||||||
, target_zoom(1)
|
, target_zoom(1)
|
||||||
, polling(false)
|
, polling(false)
|
||||||
|
, m_lastPresentTime(std::chrono::milliseconds::zero())
|
||||||
, m_texture(nullptr)
|
, m_texture(nullptr)
|
||||||
, m_fbo(nullptr)
|
, m_fbo(nullptr)
|
||||||
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
|
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
|
||||||
|
@ -104,8 +105,10 @@ void MagnifierEffect::reconfigure(ReconfigureFlags)
|
||||||
toggle();
|
toggle();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MagnifierEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
void MagnifierEffect::prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
|
const int time = m_lastPresentTime.count() ? (presentTime - m_lastPresentTime).count() : 0;
|
||||||
|
|
||||||
if (zoom != target_zoom) {
|
if (zoom != target_zoom) {
|
||||||
double diff = time / animationTime(500.0);
|
double diff = time / animationTime(500.0);
|
||||||
if (target_zoom > zoom)
|
if (target_zoom > zoom)
|
||||||
|
@ -122,7 +125,14 @@ void MagnifierEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
effects->prePaintScreen(data, time);
|
|
||||||
|
if (zoom != target_zoom) {
|
||||||
|
m_lastPresentTime = presentTime;
|
||||||
|
} else {
|
||||||
|
m_lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
|
}
|
||||||
|
|
||||||
|
effects->prePaintScreen(data, presentTime);
|
||||||
if (zoom != 1.0)
|
if (zoom != 1.0)
|
||||||
data.paint |= magnifierArea().adjusted(-FRAME_WIDTH, -FRAME_WIDTH, FRAME_WIDTH, FRAME_WIDTH);
|
data.paint |= magnifierArea().adjusted(-FRAME_WIDTH, -FRAME_WIDTH, FRAME_WIDTH, FRAME_WIDTH);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ public:
|
||||||
MagnifierEffect();
|
MagnifierEffect();
|
||||||
~MagnifierEffect() override;
|
~MagnifierEffect() override;
|
||||||
void reconfigure(ReconfigureFlags) override;
|
void reconfigure(ReconfigureFlags) override;
|
||||||
void prePaintScreen(ScreenPrePaintData& data, int time) override;
|
void prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) override;
|
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) override;
|
||||||
void postPaintScreen() override;
|
void postPaintScreen() override;
|
||||||
bool isActive() const override;
|
bool isActive() const override;
|
||||||
|
@ -56,6 +56,7 @@ private:
|
||||||
double zoom;
|
double zoom;
|
||||||
double target_zoom;
|
double target_zoom;
|
||||||
bool polling; // Mouse polling
|
bool polling; // Mouse polling
|
||||||
|
std::chrono::milliseconds m_lastPresentTime;
|
||||||
QSize magnifier_size;
|
QSize magnifier_size;
|
||||||
GLTexture *m_texture;
|
GLTexture *m_texture;
|
||||||
GLRenderTarget *m_fbo;
|
GLRenderTarget *m_fbo;
|
||||||
|
|
|
@ -74,8 +74,10 @@ void MouseClickEffect::reconfigure(ReconfigureFlags)
|
||||||
m_font = MouseClickConfig::font();
|
m_font = MouseClickConfig::font();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MouseClickEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
void MouseClickEffect::prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
|
const int time = m_lastPresentTime.count() ? (presentTime - m_lastPresentTime).count() : 0;
|
||||||
|
|
||||||
foreach (MouseEvent* click, m_clicks) {
|
foreach (MouseEvent* click, m_clicks) {
|
||||||
click->m_time += time;
|
click->m_time += time;
|
||||||
}
|
}
|
||||||
|
@ -95,7 +97,13 @@ void MouseClickEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
||||||
delete first;
|
delete first;
|
||||||
}
|
}
|
||||||
|
|
||||||
effects->prePaintScreen(data, time);
|
if (isActive()) {
|
||||||
|
m_lastPresentTime = presentTime;
|
||||||
|
} else {
|
||||||
|
m_lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
|
}
|
||||||
|
|
||||||
|
effects->prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MouseClickEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data)
|
void MouseClickEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data)
|
||||||
|
|
|
@ -92,7 +92,7 @@ public:
|
||||||
MouseClickEffect();
|
MouseClickEffect();
|
||||||
~MouseClickEffect() override;
|
~MouseClickEffect() override;
|
||||||
void reconfigure(ReconfigureFlags) override;
|
void reconfigure(ReconfigureFlags) override;
|
||||||
void prePaintScreen(ScreenPrePaintData& data, int time) override;
|
void prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) override;
|
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) override;
|
||||||
void postPaintScreen() override;
|
void postPaintScreen() override;
|
||||||
bool isActive() const override;
|
bool isActive() const override;
|
||||||
|
@ -161,6 +161,7 @@ private:
|
||||||
float m_ringMaxSize;
|
float m_ringMaxSize;
|
||||||
bool m_showText;
|
bool m_showText;
|
||||||
QFont m_font;
|
QFont m_font;
|
||||||
|
std::chrono::milliseconds m_lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
|
|
||||||
QList<MouseEvent*> m_clicks;
|
QList<MouseEvent*> m_clicks;
|
||||||
MouseButton* m_buttons[BUTTON_COUNT];
|
MouseButton* m_buttons[BUTTON_COUNT];
|
||||||
|
|
|
@ -46,6 +46,7 @@ PresentWindowsEffect::PresentWindowsEffect()
|
||||||
, m_managerWindow(nullptr)
|
, m_managerWindow(nullptr)
|
||||||
, m_needInitialSelection(false)
|
, m_needInitialSelection(false)
|
||||||
, m_highlightedWindow(nullptr)
|
, m_highlightedWindow(nullptr)
|
||||||
|
, m_lastPresentTime(std::chrono::milliseconds::zero())
|
||||||
, m_filterFrame(nullptr)
|
, m_filterFrame(nullptr)
|
||||||
, m_closeView(nullptr)
|
, m_closeView(nullptr)
|
||||||
, m_exposeAction(new QAction(this))
|
, m_exposeAction(new QAction(this))
|
||||||
|
@ -199,8 +200,17 @@ void PresentWindowsEffect::toggleActiveClass()
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Screen painting
|
// Screen painting
|
||||||
|
|
||||||
void PresentWindowsEffect::prePaintScreen(ScreenPrePaintData &data, int time)
|
void PresentWindowsEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
|
// The animation code assumes that the time diff cannot be 0, let's work around it.
|
||||||
|
int time;
|
||||||
|
if (m_lastPresentTime.count()) {
|
||||||
|
time = std::max(1, int((presentTime - m_lastPresentTime).count()));
|
||||||
|
} else {
|
||||||
|
time = 1;
|
||||||
|
}
|
||||||
|
m_lastPresentTime = presentTime;
|
||||||
|
|
||||||
m_motionManager.calculate(time);
|
m_motionManager.calculate(time);
|
||||||
|
|
||||||
// We need to mark the screen as having been transformed otherwise there will be no repainting
|
// We need to mark the screen as having been transformed otherwise there will be no repainting
|
||||||
|
@ -212,7 +222,7 @@ void PresentWindowsEffect::prePaintScreen(ScreenPrePaintData &data, int time)
|
||||||
else
|
else
|
||||||
m_decalOpacity = qMax(0.0, m_decalOpacity - time / m_fadeDuration);
|
m_decalOpacity = qMax(0.0, m_decalOpacity - time / m_fadeDuration);
|
||||||
|
|
||||||
effects->prePaintScreen(data, time);
|
effects->prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PresentWindowsEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData &data)
|
void PresentWindowsEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData &data)
|
||||||
|
@ -229,43 +239,58 @@ void PresentWindowsEffect::paintScreen(int mask, const QRegion ®ion, ScreenPa
|
||||||
|
|
||||||
void PresentWindowsEffect::postPaintScreen()
|
void PresentWindowsEffect::postPaintScreen()
|
||||||
{
|
{
|
||||||
if (m_motionManager.areWindowsMoving())
|
if (m_motionManager.areWindowsMoving()) {
|
||||||
effects->addRepaintFull();
|
effects->addRepaintFull();
|
||||||
else if (!m_activated && m_motionManager.managingWindows() && !(m_closeView && m_closeView->isVisible())) {
|
} else {
|
||||||
// We have finished moving them back, stop processing
|
m_lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
m_motionManager.unmanageAll();
|
|
||||||
|
|
||||||
DataHash::iterator i = m_windowData.begin();
|
if (!m_activated && m_motionManager.managingWindows() && !(m_closeView && m_closeView->isVisible())) {
|
||||||
while (i != m_windowData.end()) {
|
// We have finished moving them back, stop processing
|
||||||
delete i.value().textFrame;
|
m_motionManager.unmanageAll();
|
||||||
delete i.value().iconFrame;
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
m_windowData.clear();
|
|
||||||
|
|
||||||
foreach (EffectWindow * w, effects->stackingOrder()) {
|
DataHash::iterator i = m_windowData.begin();
|
||||||
w->setData(WindowForceBlurRole, QVariant());
|
while (i != m_windowData.end()) {
|
||||||
w->setData(WindowForceBackgroundContrastRole, QVariant());
|
delete i.value().textFrame;
|
||||||
|
delete i.value().iconFrame;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
m_windowData.clear();
|
||||||
|
|
||||||
|
foreach (EffectWindow * w, effects->stackingOrder()) {
|
||||||
|
w->setData(WindowForceBlurRole, QVariant());
|
||||||
|
w->setData(WindowForceBackgroundContrastRole, QVariant());
|
||||||
|
}
|
||||||
|
effects->setActiveFullScreenEffect(nullptr);
|
||||||
|
effects->addRepaintFull();
|
||||||
|
} else if (m_activated && m_needInitialSelection) {
|
||||||
|
m_needInitialSelection = false;
|
||||||
|
QMouseEvent me(QEvent::MouseMove, cursorPos(), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
|
||||||
|
windowInputMouseEvent(&me);
|
||||||
}
|
}
|
||||||
effects->setActiveFullScreenEffect(nullptr);
|
|
||||||
effects->addRepaintFull();
|
|
||||||
} else if (m_activated && m_needInitialSelection) {
|
|
||||||
m_needInitialSelection = false;
|
|
||||||
QMouseEvent me(QEvent::MouseMove, cursorPos(), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
|
|
||||||
windowInputMouseEvent(&me);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update windows that are changing brightness or opacity
|
// Update windows that are changing brightness or opacity
|
||||||
DataHash::const_iterator i;
|
for (auto i = m_windowData.begin(); i != m_windowData.end(); ++i) {
|
||||||
for (i = m_windowData.constBegin(); i != m_windowData.constEnd(); ++i) {
|
bool resetLastPresentTime = true;
|
||||||
if (i.value().opacity > 0.0 && i.value().opacity < 1.0)
|
|
||||||
|
if (i.value().opacity > 0.0 && i.value().opacity < 1.0) {
|
||||||
i.key()->addRepaintFull();
|
i.key()->addRepaintFull();
|
||||||
if (i.key()->isDesktop() && !m_motionManager.isManaging(i.key())) {
|
resetLastPresentTime = false;
|
||||||
if (i.value().highlight != 0.3)
|
|
||||||
i.key()->addRepaintFull();
|
|
||||||
}
|
}
|
||||||
else if (i.value().highlight > 0.0 && i.value().highlight < 1.0)
|
if (i.key()->isDesktop() && !m_motionManager.isManaging(i.key())) {
|
||||||
|
if (i.value().highlight != 0.3) {
|
||||||
|
i.key()->addRepaintFull();
|
||||||
|
resetLastPresentTime = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (i.value().highlight > 0.0 && i.value().highlight < 1.0) {
|
||||||
i.key()->addRepaintFull();
|
i.key()->addRepaintFull();
|
||||||
|
resetLastPresentTime = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resetLastPresentTime) {
|
||||||
|
i->lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
effects->postPaintScreen();
|
effects->postPaintScreen();
|
||||||
|
@ -274,19 +299,28 @@ void PresentWindowsEffect::postPaintScreen()
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Window painting
|
// Window painting
|
||||||
|
|
||||||
void PresentWindowsEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time)
|
void PresentWindowsEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
// TODO: We should also check to see if any windows are fading just in case fading takes longer
|
// TODO: We should also check to see if any windows are fading just in case fading takes longer
|
||||||
// than moving the windows when the effect is deactivated.
|
// than moving the windows when the effect is deactivated.
|
||||||
if (m_activated || m_motionManager.areWindowsMoving() || m_closeView) {
|
if (m_activated || m_motionManager.areWindowsMoving() || m_closeView) {
|
||||||
DataHash::iterator winData = m_windowData.find(w);
|
DataHash::iterator winData = m_windowData.find(w);
|
||||||
if (winData == m_windowData.end()) {
|
if (winData == m_windowData.end()) {
|
||||||
effects->prePaintWindow(w, data, time);
|
effects->prePaintWindow(w, data, presentTime);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_MINIMIZE); // Display always
|
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_MINIMIZE); // Display always
|
||||||
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
|
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
|
||||||
|
|
||||||
|
// The animation code assumes that the time diff cannot be 0, let's work around it.
|
||||||
|
int time;
|
||||||
|
if (winData->lastPresentTime.count()) {
|
||||||
|
time = std::max(1, int((presentTime - winData->lastPresentTime).count()));
|
||||||
|
} else {
|
||||||
|
time = 1;
|
||||||
|
}
|
||||||
|
winData->lastPresentTime = presentTime;
|
||||||
|
|
||||||
// Calculate window's opacity
|
// Calculate window's opacity
|
||||||
// TODO: Minimized windows or windows not on the current desktop are only 75% visible?
|
// TODO: Minimized windows or windows not on the current desktop are only 75% visible?
|
||||||
if (winData->visible) {
|
if (winData->visible) {
|
||||||
|
@ -333,7 +367,7 @@ void PresentWindowsEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &d
|
||||||
if (isInMotion)
|
if (isInMotion)
|
||||||
data.setTransformed(); // We will be moving this window
|
data.setTransformed(); // We will be moving this window
|
||||||
}
|
}
|
||||||
effects->prePaintWindow(w, data, time);
|
effects->prePaintWindow(w, data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PresentWindowsEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
|
void PresentWindowsEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
|
||||||
|
|
|
@ -64,6 +64,7 @@ class PresentWindowsEffect
|
||||||
private:
|
private:
|
||||||
// Structures
|
// Structures
|
||||||
struct WindowData {
|
struct WindowData {
|
||||||
|
std::chrono::milliseconds lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
bool visible;
|
bool visible;
|
||||||
bool deleted;
|
bool deleted;
|
||||||
bool referenced;
|
bool referenced;
|
||||||
|
@ -86,12 +87,12 @@ public:
|
||||||
void* proxy() override;
|
void* proxy() override;
|
||||||
|
|
||||||
// Screen painting
|
// Screen painting
|
||||||
void prePaintScreen(ScreenPrePaintData &data, int time) override;
|
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData &data) override;
|
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData &data) override;
|
||||||
void postPaintScreen() override;
|
void postPaintScreen() override;
|
||||||
|
|
||||||
// Window painting
|
// Window painting
|
||||||
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time) override;
|
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override;
|
void paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override;
|
||||||
|
|
||||||
// User interaction
|
// User interaction
|
||||||
|
@ -279,6 +280,9 @@ private:
|
||||||
DataHash m_windowData;
|
DataHash m_windowData;
|
||||||
EffectWindow *m_highlightedWindow;
|
EffectWindow *m_highlightedWindow;
|
||||||
|
|
||||||
|
// Timing
|
||||||
|
std::chrono::milliseconds m_lastPresentTime;
|
||||||
|
|
||||||
// Grid layout info
|
// Grid layout info
|
||||||
QList<GridSize> m_gridSizes;
|
QList<GridSize> m_gridSizes;
|
||||||
|
|
||||||
|
|
|
@ -40,19 +40,19 @@ ResizeEffect::~ResizeEffect()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResizeEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
void ResizeEffect::prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
if (m_active) {
|
if (m_active) {
|
||||||
data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
|
data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
|
||||||
}
|
}
|
||||||
AnimationEffect::prePaintScreen(data, time);
|
AnimationEffect::prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResizeEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
|
void ResizeEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
if (m_active && w == m_resizeWindow)
|
if (m_active && w == m_resizeWindow)
|
||||||
data.mask |= PAINT_WINDOW_TRANSFORMED;
|
data.mask |= PAINT_WINDOW_TRANSFORMED;
|
||||||
AnimationEffect::prePaintWindow(w, data, time);
|
AnimationEffect::prePaintWindow(w, data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResizeEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
void ResizeEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
||||||
|
|
|
@ -28,8 +28,8 @@ public:
|
||||||
return ef == Effect::Resize;
|
return ef == Effect::Resize;
|
||||||
}
|
}
|
||||||
inline bool isActive() const override { return m_active || AnimationEffect::isActive(); }
|
inline bool isActive() const override { return m_active || AnimationEffect::isActive(); }
|
||||||
void prePaintScreen(ScreenPrePaintData& data, int time) override;
|
void prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time) override;
|
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) override;
|
void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) override;
|
||||||
void reconfigure(ReconfigureFlags) override;
|
void reconfigure(ReconfigureFlags) override;
|
||||||
|
|
||||||
|
|
|
@ -65,9 +65,9 @@ void ScreenEdgeEffect::cleanup()
|
||||||
m_borders.clear();
|
m_borders.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenEdgeEffect::prePaintScreen(ScreenPrePaintData &data, int time)
|
void ScreenEdgeEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
effects->prePaintScreen(data, time);
|
effects->prePaintScreen(data, presentTime);
|
||||||
for (QHash<ElectricBorder, Glow*>::iterator it = m_borders.begin();
|
for (QHash<ElectricBorder, Glow*>::iterator it = m_borders.begin();
|
||||||
it != m_borders.end();
|
it != m_borders.end();
|
||||||
++it) {
|
++it) {
|
||||||
|
|
|
@ -25,7 +25,7 @@ class ScreenEdgeEffect : public Effect
|
||||||
public:
|
public:
|
||||||
ScreenEdgeEffect();
|
ScreenEdgeEffect();
|
||||||
~ScreenEdgeEffect() override;
|
~ScreenEdgeEffect() override;
|
||||||
void prePaintScreen(ScreenPrePaintData &data, int time) override;
|
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData &data) override;
|
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData &data) override;
|
||||||
bool isActive() const override;
|
bool isActive() const override;
|
||||||
|
|
||||||
|
|
|
@ -44,29 +44,33 @@ void SheetEffect::reconfigure(ReconfigureFlags flags)
|
||||||
m_duration = std::chrono::milliseconds(static_cast<int>(d));
|
m_duration = std::chrono::milliseconds(static_cast<int>(d));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SheetEffect::prePaintScreen(ScreenPrePaintData &data, int time)
|
void SheetEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
const std::chrono::milliseconds delta(time);
|
|
||||||
|
|
||||||
auto animationIt = m_animations.begin();
|
auto animationIt = m_animations.begin();
|
||||||
while (animationIt != m_animations.end()) {
|
while (animationIt != m_animations.end()) {
|
||||||
|
std::chrono::milliseconds delta = std::chrono::milliseconds::zero();
|
||||||
|
if (animationIt->lastPresentTime.count()) {
|
||||||
|
delta = presentTime - animationIt->lastPresentTime;
|
||||||
|
}
|
||||||
|
animationIt->lastPresentTime = presentTime;
|
||||||
|
|
||||||
(*animationIt).timeLine.update(delta);
|
(*animationIt).timeLine.update(delta);
|
||||||
++animationIt;
|
++animationIt;
|
||||||
}
|
}
|
||||||
|
|
||||||
data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
|
data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
|
||||||
|
|
||||||
effects->prePaintScreen(data, time);
|
effects->prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SheetEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time)
|
void SheetEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
if (m_animations.contains(w)) {
|
if (m_animations.contains(w)) {
|
||||||
data.setTransformed();
|
data.setTransformed();
|
||||||
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DELETE);
|
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DELETE);
|
||||||
}
|
}
|
||||||
|
|
||||||
effects->prePaintWindow(w, data, time);
|
effects->prePaintWindow(w, data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SheetEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
|
void SheetEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
|
||||||
|
|
|
@ -28,8 +28,8 @@ public:
|
||||||
|
|
||||||
void reconfigure(ReconfigureFlags flags) override;
|
void reconfigure(ReconfigureFlags flags) override;
|
||||||
|
|
||||||
void prePaintScreen(ScreenPrePaintData &data, int time) override;
|
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override;
|
||||||
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time) override;
|
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override;
|
void paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override;
|
||||||
void postPaintWindow(EffectWindow *w) override;
|
void postPaintWindow(EffectWindow *w) override;
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@ private:
|
||||||
struct Animation {
|
struct Animation {
|
||||||
TimeLine timeLine;
|
TimeLine timeLine;
|
||||||
int parentY;
|
int parentY;
|
||||||
|
std::chrono::milliseconds lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
};
|
};
|
||||||
|
|
||||||
QHash<EffectWindow*, Animation> m_animations;
|
QHash<EffectWindow*, Animation> m_animations;
|
||||||
|
|
|
@ -110,12 +110,12 @@ void ShowFpsEffect::reconfigure(ReconfigureFlags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowFpsEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
void ShowFpsEffect::prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
frames[ frames_pos ] = QDateTime::currentMSecsSinceEpoch();
|
frames[ frames_pos ] = QDateTime::currentMSecsSinceEpoch();
|
||||||
if (++frames_pos == MAX_FPS)
|
if (++frames_pos == MAX_FPS)
|
||||||
frames_pos = 0;
|
frames_pos = 0;
|
||||||
effects->prePaintScreen(data, time);
|
effects->prePaintScreen(data, presentTime);
|
||||||
data.paint += fps_rect;
|
data.paint += fps_rect;
|
||||||
|
|
||||||
paint_size[ paints_pos ] = 0;
|
paint_size[ paints_pos ] = 0;
|
||||||
|
|
|
@ -34,7 +34,7 @@ class ShowFpsEffect
|
||||||
public:
|
public:
|
||||||
ShowFpsEffect();
|
ShowFpsEffect();
|
||||||
void reconfigure(ReconfigureFlags) override;
|
void reconfigure(ReconfigureFlags) override;
|
||||||
void prePaintScreen(ScreenPrePaintData& data, int time) override;
|
void prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) override;
|
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) override;
|
||||||
void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) override;
|
void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) override;
|
||||||
void postPaintScreen() override;
|
void postPaintScreen() override;
|
||||||
|
|
|
@ -62,14 +62,20 @@ void SlideEffect::reconfigure(ReconfigureFlags)
|
||||||
m_slideBackground = SlideConfig::slideBackground();
|
m_slideBackground = SlideConfig::slideBackground();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SlideEffect::prePaintScreen(ScreenPrePaintData &data, int time)
|
void SlideEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
m_timeLine.update(std::chrono::milliseconds(time));
|
std::chrono::milliseconds delta = std::chrono::milliseconds::zero();
|
||||||
|
if (m_lastPresentTime.count()) {
|
||||||
|
delta = presentTime - m_lastPresentTime;
|
||||||
|
}
|
||||||
|
m_lastPresentTime = presentTime;
|
||||||
|
|
||||||
|
m_timeLine.update(delta);
|
||||||
|
|
||||||
data.mask |= PAINT_SCREEN_TRANSFORMED
|
data.mask |= PAINT_SCREEN_TRANSFORMED
|
||||||
| PAINT_SCREEN_BACKGROUND_FIRST;
|
| PAINT_SCREEN_BACKGROUND_FIRST;
|
||||||
|
|
||||||
effects->prePaintScreen(data, time);
|
effects->prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -249,7 +255,7 @@ bool SlideEffect::isPainted(const EffectWindow *w) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SlideEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time)
|
void SlideEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
const bool painted = isPainted(w);
|
const bool painted = isPainted(w);
|
||||||
if (painted) {
|
if (painted) {
|
||||||
|
@ -260,7 +266,7 @@ void SlideEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int
|
||||||
if (painted && isTranslated(w)) {
|
if (painted && isTranslated(w)) {
|
||||||
data.setTransformed();
|
data.setTransformed();
|
||||||
}
|
}
|
||||||
effects->prePaintWindow(w, data, time);
|
effects->prePaintWindow(w, data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SlideEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
|
void SlideEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
|
||||||
|
@ -392,6 +398,7 @@ void SlideEffect::stop()
|
||||||
m_paintCtx.fullscreenWindows.clear();
|
m_paintCtx.fullscreenWindows.clear();
|
||||||
m_movingWindow = nullptr;
|
m_movingWindow = nullptr;
|
||||||
m_active = false;
|
m_active = false;
|
||||||
|
m_lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
effects->setActiveFullScreenEffect(nullptr);
|
effects->setActiveFullScreenEffect(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,11 +33,11 @@ public:
|
||||||
|
|
||||||
void reconfigure(ReconfigureFlags) override;
|
void reconfigure(ReconfigureFlags) override;
|
||||||
|
|
||||||
void prePaintScreen(ScreenPrePaintData &data, int time) override;
|
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData &data) override;
|
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData &data) override;
|
||||||
void postPaintScreen() override;
|
void postPaintScreen() override;
|
||||||
|
|
||||||
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time) override;
|
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override;
|
void paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override;
|
||||||
|
|
||||||
bool isActive() const override {
|
bool isActive() const override {
|
||||||
|
@ -88,6 +88,7 @@ private:
|
||||||
QPoint m_startPos;
|
QPoint m_startPos;
|
||||||
QPoint m_diff;
|
QPoint m_diff;
|
||||||
EffectWindow *m_movingWindow = nullptr;
|
EffectWindow *m_movingWindow = nullptr;
|
||||||
|
std::chrono::milliseconds m_lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int desktop;
|
int desktop;
|
||||||
|
|
|
@ -126,8 +126,14 @@ QRect SlideBackEffect::getSlideDestination(const QRect &windowUnderGeometry, con
|
||||||
return slideRect;
|
return slideRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SlideBackEffect::prePaintScreen(ScreenPrePaintData &data, int time)
|
void SlideBackEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
|
int time = 0;
|
||||||
|
if (m_lastPresentTime.count()) {
|
||||||
|
time = (presentTime - m_lastPresentTime).count();
|
||||||
|
}
|
||||||
|
m_lastPresentTime = presentTime;
|
||||||
|
|
||||||
if (motionManager.managingWindows()) {
|
if (motionManager.managingWindows()) {
|
||||||
motionManager.calculate(time);
|
motionManager.calculate(time);
|
||||||
data.mask |= Effect::PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
|
data.mask |= Effect::PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
|
||||||
|
@ -137,7 +143,7 @@ void SlideBackEffect::prePaintScreen(ScreenPrePaintData &data, int time)
|
||||||
w->setData(WindowForceBlurRole, QVariant(true));
|
w->setData(WindowForceBlurRole, QVariant(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
effects->prePaintScreen(data, time);
|
effects->prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SlideBackEffect::postPaintScreen()
|
void SlideBackEffect::postPaintScreen()
|
||||||
|
@ -153,13 +159,13 @@ void SlideBackEffect::postPaintScreen()
|
||||||
effects->postPaintScreen();
|
effects->postPaintScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SlideBackEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time)
|
void SlideBackEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
if (motionManager.isManaging(w)) {
|
if (motionManager.isManaging(w)) {
|
||||||
data.setTransformed();
|
data.setTransformed();
|
||||||
}
|
}
|
||||||
|
|
||||||
effects->prePaintWindow(w, data, time);
|
effects->prePaintWindow(w, data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SlideBackEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
|
void SlideBackEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
|
||||||
|
@ -242,6 +248,9 @@ void SlideBackEffect::postPaintWindow(EffectWindow* w)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!isActive()) {
|
||||||
|
m_lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
|
}
|
||||||
effects->postPaintWindow(w);
|
effects->postPaintWindow(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,11 +23,11 @@ class SlideBackEffect
|
||||||
public:
|
public:
|
||||||
SlideBackEffect();
|
SlideBackEffect();
|
||||||
|
|
||||||
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time) override;
|
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) override;
|
void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) override;
|
||||||
void postPaintWindow(EffectWindow* w) override;
|
void postPaintWindow(EffectWindow* w) override;
|
||||||
|
|
||||||
void prePaintScreen(ScreenPrePaintData &data, int time) override;
|
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override;
|
||||||
void postPaintScreen() override;
|
void postPaintScreen() override;
|
||||||
bool isActive() const override;
|
bool isActive() const override;
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@ private:
|
||||||
QHash<EffectWindow *, QRect> destinationList;
|
QHash<EffectWindow *, QRect> destinationList;
|
||||||
int m_tabboxActive;
|
int m_tabboxActive;
|
||||||
QList <QRegion> clippedRegions;
|
QList <QRegion> clippedRegions;
|
||||||
|
std::chrono::milliseconds m_lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
|
|
||||||
QRect getSlideDestination(const QRect &windowUnderGeometry, const QRect &windowOverGeometry);
|
QRect getSlideDestination(const QRect &windowUnderGeometry, const QRect &windowOverGeometry);
|
||||||
bool isWindowUsable(EffectWindow *w);
|
bool isWindowUsable(EffectWindow *w);
|
||||||
|
|
|
@ -91,19 +91,25 @@ void SlidingPopupsEffect::reconfigure(ReconfigureFlags flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SlidingPopupsEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time)
|
void SlidingPopupsEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
auto animationIt = m_animations.find(w);
|
auto animationIt = m_animations.find(w);
|
||||||
if (animationIt == m_animations.end()) {
|
if (animationIt == m_animations.end()) {
|
||||||
effects->prePaintWindow(w, data, time);
|
effects->prePaintWindow(w, data, presentTime);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*animationIt).timeLine.update(std::chrono::milliseconds(time));
|
std::chrono::milliseconds delta = std::chrono::milliseconds::zero();
|
||||||
|
if (animationIt->lastPresentTime.count()) {
|
||||||
|
delta = presentTime - animationIt->lastPresentTime;
|
||||||
|
}
|
||||||
|
animationIt->lastPresentTime = presentTime;
|
||||||
|
|
||||||
|
(*animationIt).timeLine.update(delta);
|
||||||
data.setTransformed();
|
data.setTransformed();
|
||||||
w->enablePainting(EffectWindow::PAINT_DISABLED | EffectWindow::PAINT_DISABLED_BY_DELETE);
|
w->enablePainting(EffectWindow::PAINT_DISABLED | EffectWindow::PAINT_DISABLED_BY_DELETE);
|
||||||
|
|
||||||
effects->prePaintWindow(w, data, time);
|
effects->prePaintWindow(w, data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SlidingPopupsEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
|
void SlidingPopupsEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
|
||||||
|
|
|
@ -27,7 +27,7 @@ public:
|
||||||
SlidingPopupsEffect();
|
SlidingPopupsEffect();
|
||||||
~SlidingPopupsEffect() override;
|
~SlidingPopupsEffect() override;
|
||||||
|
|
||||||
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time) override;
|
void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override;
|
void paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override;
|
||||||
void postPaintWindow(EffectWindow *w) override;
|
void postPaintWindow(EffectWindow *w) override;
|
||||||
void reconfigure(ReconfigureFlags flags) override;
|
void reconfigure(ReconfigureFlags flags) override;
|
||||||
|
@ -72,6 +72,7 @@ private:
|
||||||
struct Animation {
|
struct Animation {
|
||||||
AnimationKind kind;
|
AnimationKind kind;
|
||||||
TimeLine timeLine;
|
TimeLine timeLine;
|
||||||
|
std::chrono::milliseconds lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
};
|
};
|
||||||
QHash<EffectWindow *, Animation> m_animations;
|
QHash<EffectWindow *, Animation> m_animations;
|
||||||
|
|
||||||
|
|
|
@ -85,13 +85,19 @@ void SnapHelperEffect::reconfigure(ReconfigureFlags flags)
|
||||||
std::chrono::milliseconds(static_cast<int>(animationTime(250))));
|
std::chrono::milliseconds(static_cast<int>(animationTime(250))));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SnapHelperEffect::prePaintScreen(ScreenPrePaintData &data, int time)
|
void SnapHelperEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
|
std::chrono::milliseconds delta = std::chrono::milliseconds::zero();
|
||||||
|
if (m_animation.lastPresentTime.count()) {
|
||||||
|
delta = (presentTime - m_animation.lastPresentTime);
|
||||||
|
}
|
||||||
|
m_animation.lastPresentTime = presentTime;
|
||||||
|
|
||||||
if (m_animation.active) {
|
if (m_animation.active) {
|
||||||
m_animation.timeLine.update(std::chrono::milliseconds(time));
|
m_animation.timeLine.update(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
effects->prePaintScreen(data, time);
|
effects->prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SnapHelperEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData &data)
|
void SnapHelperEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData &data)
|
||||||
|
@ -244,6 +250,7 @@ void SnapHelperEffect::postPaintScreen()
|
||||||
|
|
||||||
if (m_animation.timeLine.done()) {
|
if (m_animation.timeLine.done()) {
|
||||||
m_animation.active = false;
|
m_animation.active = false;
|
||||||
|
m_animation.lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
effects->postPaintScreen();
|
effects->postPaintScreen();
|
||||||
|
|
|
@ -26,7 +26,7 @@ public:
|
||||||
|
|
||||||
void reconfigure(ReconfigureFlags flags) override;
|
void reconfigure(ReconfigureFlags flags) override;
|
||||||
|
|
||||||
void prePaintScreen(ScreenPrePaintData &data, int time) override;
|
void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData &data) override;
|
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData &data) override;
|
||||||
void postPaintScreen() override;
|
void postPaintScreen() override;
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@ private:
|
||||||
struct Animation {
|
struct Animation {
|
||||||
bool active = false;
|
bool active = false;
|
||||||
TimeLine timeLine;
|
TimeLine timeLine;
|
||||||
|
std::chrono::milliseconds lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
};
|
};
|
||||||
|
|
||||||
Animation m_animation;
|
Animation m_animation;
|
||||||
|
|
|
@ -68,6 +68,7 @@ StartupFeedbackEffect::StartupFeedbackEffect()
|
||||||
, m_active(false)
|
, m_active(false)
|
||||||
, m_frame(0)
|
, m_frame(0)
|
||||||
, m_progress(0)
|
, m_progress(0)
|
||||||
|
, m_lastPresentTime(std::chrono::milliseconds::zero())
|
||||||
, m_type(BouncingFeedback)
|
, m_type(BouncingFeedback)
|
||||||
, m_cursorSize(24)
|
, m_cursorSize(24)
|
||||||
, m_configWatcher(KConfigWatcher::create(KSharedConfig::openConfig("klaunchrc", KConfig::NoGlobals)))
|
, m_configWatcher(KConfigWatcher::create(KSharedConfig::openConfig("klaunchrc", KConfig::NoGlobals)))
|
||||||
|
@ -142,8 +143,14 @@ void StartupFeedbackEffect::reconfigure(Effect::ReconfigureFlags flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartupFeedbackEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
void StartupFeedbackEffect::prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
|
int time = 0;
|
||||||
|
if (m_lastPresentTime.count()) {
|
||||||
|
time = (presentTime - m_lastPresentTime).count();
|
||||||
|
}
|
||||||
|
m_lastPresentTime = presentTime;
|
||||||
|
|
||||||
if (m_active) {
|
if (m_active) {
|
||||||
// need the unclipped version
|
// need the unclipped version
|
||||||
switch(m_type) {
|
switch(m_type) {
|
||||||
|
@ -161,7 +168,7 @@ void StartupFeedbackEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
||||||
break; // nothing
|
break; // nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
effects->prePaintScreen(data, time);
|
effects->prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartupFeedbackEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data)
|
void StartupFeedbackEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data)
|
||||||
|
@ -289,6 +296,7 @@ void StartupFeedbackEffect::stop()
|
||||||
if (m_active)
|
if (m_active)
|
||||||
effects->stopMousePolling();
|
effects->stopMousePolling();
|
||||||
m_active = false;
|
m_active = false;
|
||||||
|
m_lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
effects->makeOpenGLContextCurrent();
|
effects->makeOpenGLContextCurrent();
|
||||||
switch(m_type) {
|
switch(m_type) {
|
||||||
case BouncingFeedback:
|
case BouncingFeedback:
|
||||||
|
@ -324,6 +332,7 @@ void StartupFeedbackEffect::prepareTextures(const QPixmap& pix)
|
||||||
default:
|
default:
|
||||||
// for safety
|
// for safety
|
||||||
m_active = false;
|
m_active = false;
|
||||||
|
m_lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
~StartupFeedbackEffect() override;
|
~StartupFeedbackEffect() override;
|
||||||
|
|
||||||
void reconfigure(ReconfigureFlags flags) override;
|
void reconfigure(ReconfigureFlags flags) override;
|
||||||
void prePaintScreen(ScreenPrePaintData& data, int time) override;
|
void prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) override;
|
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) override;
|
||||||
void postPaintScreen() override;
|
void postPaintScreen() override;
|
||||||
bool isActive() const override;
|
bool isActive() const override;
|
||||||
|
@ -71,6 +71,7 @@ private:
|
||||||
bool m_active;
|
bool m_active;
|
||||||
int m_frame;
|
int m_frame;
|
||||||
int m_progress;
|
int m_progress;
|
||||||
|
std::chrono::milliseconds m_lastPresentTime;
|
||||||
QScopedPointer<GLTexture> m_bouncingTextures[5];
|
QScopedPointer<GLTexture> m_bouncingTextures[5];
|
||||||
QScopedPointer<GLTexture> m_texture; // for passive and blinking
|
QScopedPointer<GLTexture> m_texture; // for passive and blinking
|
||||||
FeedbackType m_type;
|
FeedbackType m_type;
|
||||||
|
|
|
@ -101,8 +101,13 @@ bool TouchPointsEffect::touchUp(qint32 id, quint32 time)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TouchPointsEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
void TouchPointsEffect::prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
|
int time = 0;
|
||||||
|
if (m_lastPresentTime.count()) {
|
||||||
|
time = (presentTime - m_lastPresentTime).count();
|
||||||
|
}
|
||||||
|
|
||||||
auto it = m_points.begin();
|
auto it = m_points.begin();
|
||||||
while (it != m_points.end()) {
|
while (it != m_points.end()) {
|
||||||
it->time += time;
|
it->time += time;
|
||||||
|
@ -113,7 +118,13 @@ void TouchPointsEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
effects->prePaintScreen(data, time);
|
if (m_points.isEmpty()) {
|
||||||
|
m_lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
|
} else {
|
||||||
|
m_lastPresentTime = presentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
effects->prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TouchPointsEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data)
|
void TouchPointsEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data)
|
||||||
|
|
|
@ -27,7 +27,7 @@ class TouchPointsEffect
|
||||||
public:
|
public:
|
||||||
TouchPointsEffect();
|
TouchPointsEffect();
|
||||||
~TouchPointsEffect() override;
|
~TouchPointsEffect() override;
|
||||||
void prePaintScreen(ScreenPrePaintData& data, int time) override;
|
void prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) override;
|
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) override;
|
||||||
void postPaintScreen() override;
|
void postPaintScreen() override;
|
||||||
bool isActive() const override;
|
bool isActive() const override;
|
||||||
|
@ -80,6 +80,7 @@ private:
|
||||||
QVector<TouchPoint> m_points;
|
QVector<TouchPoint> m_points;
|
||||||
QHash<quint32, QPointF> m_latestPositions;
|
QHash<quint32, QPointF> m_latestPositions;
|
||||||
QHash<quint32, Qt::GlobalColor> m_colors;
|
QHash<quint32, Qt::GlobalColor> m_colors;
|
||||||
|
std::chrono::milliseconds m_lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ void TrackMouseEffect::reconfigure(ReconfigureFlags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackMouseEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
void TrackMouseEffect::prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
QTime t = QTime::currentTime();
|
QTime t = QTime::currentTime();
|
||||||
m_angle = ((t.second() % 4) * m_angleBase) + (t.msec() / 1000.0 * m_angleBase);
|
m_angle = ((t.second() % 4) * m_angleBase) + (t.msec() / 1000.0 * m_angleBase);
|
||||||
|
@ -101,7 +101,7 @@ void TrackMouseEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
||||||
m_lastRect[1].moveCenter(cursorPos());
|
m_lastRect[1].moveCenter(cursorPos());
|
||||||
data.paint |= m_lastRect[0].adjusted(-1,-1,1,1);
|
data.paint |= m_lastRect[0].adjusted(-1,-1,1,1);
|
||||||
|
|
||||||
effects->prePaintScreen(data, time);
|
effects->prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackMouseEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data)
|
void TrackMouseEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data)
|
||||||
|
|
|
@ -29,7 +29,7 @@ class TrackMouseEffect
|
||||||
public:
|
public:
|
||||||
TrackMouseEffect();
|
TrackMouseEffect();
|
||||||
~TrackMouseEffect() override;
|
~TrackMouseEffect() override;
|
||||||
void prePaintScreen(ScreenPrePaintData& data, int time) override;
|
void prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) override;
|
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) override;
|
||||||
void postPaintScreen() override;
|
void postPaintScreen() override;
|
||||||
void reconfigure(ReconfigureFlags) override;
|
void reconfigure(ReconfigureFlags) override;
|
||||||
|
|
|
@ -228,7 +228,7 @@ void WobblyWindowsEffect::setDrag(qreal drag)
|
||||||
m_drag = drag;
|
m_drag = drag;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WobblyWindowsEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
void WobblyWindowsEffect::prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
// We need to mark the screen windows as transformed. Otherwise the whole
|
// We need to mark the screen windows as transformed. Otherwise the whole
|
||||||
// screen won't be repainted, resulting in artefacts.
|
// screen won't be repainted, resulting in artefacts.
|
||||||
|
@ -237,16 +237,22 @@ void WobblyWindowsEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
||||||
m_updateRegion = QRegion();
|
m_updateRegion = QRegion();
|
||||||
}
|
}
|
||||||
|
|
||||||
effects->prePaintScreen(data, time);
|
effects->prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
const qreal maxTime = 10.0;
|
const qreal maxTime = 10.0;
|
||||||
void WobblyWindowsEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
|
void WobblyWindowsEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
if (windows.contains(w)) {
|
auto infoIt = windows.find(w);
|
||||||
|
if (infoIt != windows.end()) {
|
||||||
data.setTransformed();
|
data.setTransformed();
|
||||||
data.quads = data.quads.makeRegularGrid(m_xTesselation, m_yTesselation);
|
data.quads = data.quads.makeRegularGrid(m_xTesselation, m_yTesselation);
|
||||||
bool stop = false;
|
bool stop = false;
|
||||||
qreal updateTime = time;
|
|
||||||
|
qreal updateTime = 0;
|
||||||
|
if (infoIt->lastPresentTime.count()) {
|
||||||
|
updateTime = (presentTime - infoIt->lastPresentTime).count();
|
||||||
|
}
|
||||||
|
infoIt->lastPresentTime = presentTime;
|
||||||
|
|
||||||
// We have to reset the clip region in order to render clients below
|
// We have to reset the clip region in order to render clients below
|
||||||
// opaque wobbly windows.
|
// opaque wobbly windows.
|
||||||
|
@ -264,7 +270,7 @@ void WobblyWindowsEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& da
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
effects->prePaintWindow(w, data, time);
|
effects->prePaintWindow(w, data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WobblyWindowsEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
void WobblyWindowsEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
||||||
|
@ -464,6 +470,7 @@ void WobblyWindowsEffect::initWobblyInfo(WindowWobblyInfos& wwi, QRect geometry)
|
||||||
wwi.bezierSurface = new Pair[wwi.bezierCount];
|
wwi.bezierSurface = new Pair[wwi.bezierCount];
|
||||||
|
|
||||||
wwi.status = Moving;
|
wwi.status = Moving;
|
||||||
|
wwi.lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
|
|
||||||
qreal x = geometry.x(), y = geometry.y();
|
qreal x = geometry.x(), y = geometry.y();
|
||||||
qreal width = geometry.width(), height = geometry.height();
|
qreal width = geometry.width(), height = geometry.height();
|
||||||
|
|
|
@ -43,8 +43,8 @@ public:
|
||||||
~WobblyWindowsEffect() override;
|
~WobblyWindowsEffect() override;
|
||||||
|
|
||||||
void reconfigure(ReconfigureFlags) override;
|
void reconfigure(ReconfigureFlags) override;
|
||||||
void prePaintScreen(ScreenPrePaintData& data, int time) override;
|
void prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time) override;
|
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) override;
|
void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) override;
|
||||||
void postPaintScreen() override;
|
void postPaintScreen() override;
|
||||||
bool isActive() const override;
|
bool isActive() const override;
|
||||||
|
@ -151,6 +151,8 @@ private:
|
||||||
// for resizing. Only sides that have moved will wobble
|
// for resizing. Only sides that have moved will wobble
|
||||||
bool can_wobble_top, can_wobble_left, can_wobble_right, can_wobble_bottom;
|
bool can_wobble_top, can_wobble_left, can_wobble_right, can_wobble_bottom;
|
||||||
QRect resize_original_rect;
|
QRect resize_original_rect;
|
||||||
|
|
||||||
|
std::chrono::milliseconds lastPresentTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
QHash< const EffectWindow*, WindowWobblyInfos > windows;
|
QHash< const EffectWindow*, WindowWobblyInfos > windows;
|
||||||
|
|
|
@ -49,6 +49,7 @@ ZoomEffect::ZoomEffect()
|
||||||
, xMove(0)
|
, xMove(0)
|
||||||
, yMove(0)
|
, yMove(0)
|
||||||
, moveFactor(20.0)
|
, moveFactor(20.0)
|
||||||
|
, lastPresentTime(std::chrono::milliseconds::zero())
|
||||||
{
|
{
|
||||||
initConfig<ZoomConfig>();
|
initConfig<ZoomConfig>();
|
||||||
QAction* a = nullptr;
|
QAction* a = nullptr;
|
||||||
|
@ -249,9 +250,14 @@ void ZoomEffect::reconfigure(ReconfigureFlags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZoomEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
void ZoomEffect::prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
if (zoom != target_zoom) {
|
if (zoom != target_zoom) {
|
||||||
|
int time = 0;
|
||||||
|
if (lastPresentTime.count())
|
||||||
|
time = (presentTime - lastPresentTime).count();
|
||||||
|
lastPresentTime = presentTime;
|
||||||
|
|
||||||
const float zoomDist = qAbs(target_zoom - source_zoom);
|
const float zoomDist = qAbs(target_zoom - source_zoom);
|
||||||
if (target_zoom > zoom)
|
if (target_zoom > zoom)
|
||||||
zoom = qMin(zoom + ((zoomDist * time) / animationTime(150*zoomFactor)), target_zoom);
|
zoom = qMin(zoom + ((zoomDist * time) / animationTime(150*zoomFactor)), target_zoom);
|
||||||
|
@ -266,7 +272,7 @@ void ZoomEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
||||||
data.mask |= PAINT_SCREEN_TRANSFORMED;
|
data.mask |= PAINT_SCREEN_TRANSFORMED;
|
||||||
}
|
}
|
||||||
|
|
||||||
effects->prePaintScreen(data, time);
|
effects->prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZoomEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data)
|
void ZoomEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data)
|
||||||
|
@ -389,6 +395,8 @@ void ZoomEffect::postPaintScreen()
|
||||||
{
|
{
|
||||||
if (zoom != target_zoom)
|
if (zoom != target_zoom)
|
||||||
effects->addRepaintFull();
|
effects->addRepaintFull();
|
||||||
|
else
|
||||||
|
lastPresentTime = std::chrono::milliseconds::zero();
|
||||||
effects->postPaintScreen();
|
effects->postPaintScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ public:
|
||||||
ZoomEffect();
|
ZoomEffect();
|
||||||
~ZoomEffect() override;
|
~ZoomEffect() override;
|
||||||
void reconfigure(ReconfigureFlags flags) override;
|
void reconfigure(ReconfigureFlags flags) override;
|
||||||
void prePaintScreen(ScreenPrePaintData& data, int time) override;
|
void prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime) override;
|
||||||
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) override;
|
void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) override;
|
||||||
void postPaintScreen() override;
|
void postPaintScreen() override;
|
||||||
bool isActive() const override;
|
bool isActive() const override;
|
||||||
|
@ -119,6 +119,7 @@ private:
|
||||||
QTimeLine timeline;
|
QTimeLine timeline;
|
||||||
int xMove, yMove;
|
int xMove, yMove;
|
||||||
double moveFactor;
|
double moveFactor;
|
||||||
|
std::chrono::milliseconds lastPresentTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -64,6 +64,7 @@ AniData::AniData()
|
||||||
, startTime(0)
|
, startTime(0)
|
||||||
, waitAtSource(false)
|
, waitAtSource(false)
|
||||||
, keepAlive(true)
|
, keepAlive(true)
|
||||||
|
, lastPresentTime(std::chrono::milliseconds::zero())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +81,7 @@ AniData::AniData(AnimationEffect::Attribute a, int meta_, const FPx2 &to_,
|
||||||
, waitAtSource(waitAtSource_)
|
, waitAtSource(waitAtSource_)
|
||||||
, keepAlive(keepAlive)
|
, keepAlive(keepAlive)
|
||||||
, previousWindowPixmapLock(std::move(previousWindowPixmapLock_))
|
, previousWindowPixmapLock(std::move(previousWindowPixmapLock_))
|
||||||
|
, lastPresentTime(std::chrono::milliseconds::zero())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,7 @@ public:
|
||||||
KeepAliveLockPtr keepAliveLock;
|
KeepAliveLockPtr keepAliveLock;
|
||||||
PreviousWindowPixmapLockPtr previousWindowPixmapLock;
|
PreviousWindowPixmapLockPtr previousWindowPixmapLock;
|
||||||
AnimationEffect::TerminationFlags terminationFlags;
|
AnimationEffect::TerminationFlags terminationFlags;
|
||||||
|
std::chrono::milliseconds lastPresentTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -391,11 +391,11 @@ bool AnimationEffect::cancel(quint64 animationId)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimationEffect::prePaintScreen( ScreenPrePaintData& data, int time )
|
void AnimationEffect::prePaintScreen( ScreenPrePaintData& data, std::chrono::milliseconds presentTime )
|
||||||
{
|
{
|
||||||
Q_D(AnimationEffect);
|
Q_D(AnimationEffect);
|
||||||
if (d->m_animations.isEmpty()) {
|
if (d->m_animations.isEmpty()) {
|
||||||
effects->prePaintScreen(data, time);
|
effects->prePaintScreen(data, presentTime);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,7 +415,10 @@ void AnimationEffect::prePaintScreen( ScreenPrePaintData& data, int time )
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
anim->timeLine.update(std::chrono::milliseconds(time));
|
if (anim->lastPresentTime.count()) {
|
||||||
|
anim->timeLine.update(presentTime - anim->lastPresentTime);
|
||||||
|
}
|
||||||
|
anim->lastPresentTime = presentTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (anim->isActive()) {
|
if (anim->isActive()) {
|
||||||
|
@ -465,7 +468,7 @@ void AnimationEffect::prePaintScreen( ScreenPrePaintData& data, int time )
|
||||||
disconnectGeometryChanges();
|
disconnectGeometryChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
effects->prePaintScreen(data, time);
|
effects->prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xCoord(const QRect &r, int flag) {
|
static int xCoord(const QRect &r, int flag) {
|
||||||
|
@ -561,7 +564,7 @@ void AnimationEffect::disconnectGeometryChanges()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AnimationEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time )
|
void AnimationEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime )
|
||||||
{
|
{
|
||||||
Q_D(AnimationEffect);
|
Q_D(AnimationEffect);
|
||||||
if ( d->m_animated ) {
|
if ( d->m_animated ) {
|
||||||
|
@ -596,7 +599,7 @@ void AnimationEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
effects->prePaintWindow( w, data, time );
|
effects->prePaintWindow(w, data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float geometryCompensation(int flags, float v)
|
static inline float geometryCompensation(int flags, float v)
|
||||||
|
|
|
@ -198,8 +198,8 @@ public:
|
||||||
|
|
||||||
// Reimplemented from KWin::Effect.
|
// Reimplemented from KWin::Effect.
|
||||||
QString debug(const QString ¶meter) const override;
|
QString debug(const QString ¶meter) const override;
|
||||||
void prePaintScreen( ScreenPrePaintData& data, int time ) override;
|
void prePaintScreen( ScreenPrePaintData& data, std::chrono::milliseconds presentTime ) override;
|
||||||
void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) override;
|
void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime ) override;
|
||||||
void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ) override;
|
void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ) override;
|
||||||
void postPaintScreen() override;
|
void postPaintScreen() override;
|
||||||
|
|
||||||
|
|
|
@ -567,9 +567,9 @@ bool Effect::borderActivated(ElectricBorder)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Effect::prePaintScreen(ScreenPrePaintData& data, int time)
|
void Effect::prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
effects->prePaintScreen(data, time);
|
effects->prePaintScreen(data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Effect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data)
|
void Effect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data)
|
||||||
|
@ -582,9 +582,9 @@ void Effect::postPaintScreen()
|
||||||
effects->postPaintScreen();
|
effects->postPaintScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Effect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
|
void Effect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
effects->prePaintWindow(w, data, time);
|
effects->prePaintWindow(w, data, presentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Effect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
void Effect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
||||||
|
|
|
@ -402,8 +402,12 @@ public:
|
||||||
*
|
*
|
||||||
* In OpenGL based compositing, the frameworks ensures that the context is current
|
* In OpenGL based compositing, the frameworks ensures that the context is current
|
||||||
* when this method is invoked.
|
* when this method is invoked.
|
||||||
|
*
|
||||||
|
* @a presentTime specifies the expected monotonic time when the rendered frame
|
||||||
|
* will be displayed on the screen.
|
||||||
*/
|
*/
|
||||||
virtual void prePaintScreen(ScreenPrePaintData& data, int time);
|
virtual void prePaintScreen(ScreenPrePaintData &data,
|
||||||
|
std::chrono::milliseconds presentTime);
|
||||||
/**
|
/**
|
||||||
* In this method you can:
|
* In this method you can:
|
||||||
* @li paint something on top of the windows (by painting after calling
|
* @li paint something on top of the windows (by painting after calling
|
||||||
|
@ -436,8 +440,12 @@ public:
|
||||||
*
|
*
|
||||||
* In OpenGL based compositing, the frameworks ensures that the context is current
|
* In OpenGL based compositing, the frameworks ensures that the context is current
|
||||||
* when this method is invoked.
|
* when this method is invoked.
|
||||||
|
*
|
||||||
|
* @a presentTime specifies the expected monotonic time when the rendered frame
|
||||||
|
* will be displayed on the screen.
|
||||||
*/
|
*/
|
||||||
virtual void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time);
|
virtual void prePaintWindow(EffectWindow *w, WindowPrePaintData &data,
|
||||||
|
std::chrono::milliseconds presentTime);
|
||||||
/**
|
/**
|
||||||
* This is the main method for painting windows.
|
* This is the main method for painting windows.
|
||||||
* In this method you can:
|
* In this method you can:
|
||||||
|
@ -824,10 +832,10 @@ public:
|
||||||
explicit EffectsHandler(CompositingType type);
|
explicit EffectsHandler(CompositingType type);
|
||||||
~EffectsHandler() override;
|
~EffectsHandler() override;
|
||||||
// for use by effects
|
// for use by effects
|
||||||
virtual void prePaintScreen(ScreenPrePaintData& data, int time) = 0;
|
virtual void prePaintScreen(ScreenPrePaintData& data, std::chrono::milliseconds presentTime) = 0;
|
||||||
virtual void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) = 0;
|
virtual void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) = 0;
|
||||||
virtual void postPaintScreen() = 0;
|
virtual void postPaintScreen() = 0;
|
||||||
virtual void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time) = 0;
|
virtual void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, std::chrono::milliseconds presentTime) = 0;
|
||||||
virtual void paintWindow(EffectWindow* w, int mask, const QRegion ®ion, WindowPaintData& data) = 0;
|
virtual void paintWindow(EffectWindow* w, int mask, const QRegion ®ion, WindowPaintData& data) = 0;
|
||||||
virtual void postPaintWindow(EffectWindow* w) = 0;
|
virtual void postPaintWindow(EffectWindow* w) = 0;
|
||||||
virtual void paintEffectFrame(EffectFrame* frame, const QRegion ®ion, double opacity, double frameOpacity) = 0;
|
virtual void paintEffectFrame(EffectFrame* frame, const QRegion ®ion, double opacity, double frameOpacity) = 0;
|
||||||
|
|
|
@ -620,7 +620,8 @@ void SceneOpenGL::aboutToStartPainting(int screenId, const QRegion &damage)
|
||||||
m_backend->aboutToStartPainting(screenId, damage);
|
m_backend->aboutToStartPainting(screenId, damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneOpenGL::paint(int screenId, const QRegion &damage, const QList<Toplevel *> &toplevels)
|
void SceneOpenGL::paint(int screenId, const QRegion &damage, const QList<Toplevel *> &toplevels,
|
||||||
|
std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
if (m_resetOccurred) {
|
if (m_resetOccurred) {
|
||||||
return; // A graphics reset has occurred, do nothing.
|
return; // A graphics reset has occurred, do nothing.
|
||||||
|
@ -658,7 +659,8 @@ void SceneOpenGL::paint(int screenId, const QRegion &damage, const QList<Topleve
|
||||||
int mask = 0;
|
int mask = 0;
|
||||||
updateProjectionMatrix();
|
updateProjectionMatrix();
|
||||||
|
|
||||||
paintScreen(&mask, damage.intersected(geo), repaint, &update, &valid, projectionMatrix(), geo, scaling); // call generic implementation
|
paintScreen(&mask, damage.intersected(geo), repaint, &update, &valid,
|
||||||
|
presentTime, projectionMatrix(), geo, scaling); // call generic implementation
|
||||||
paintCursor(valid);
|
paintCursor(valid);
|
||||||
|
|
||||||
if (!GLPlatform::instance()->isGLES() && screenId == -1) {
|
if (!GLPlatform::instance()->isGLES() && screenId == -1) {
|
||||||
|
|
|
@ -35,7 +35,8 @@ public:
|
||||||
~SceneOpenGL() override;
|
~SceneOpenGL() override;
|
||||||
bool initFailed() const override;
|
bool initFailed() const override;
|
||||||
bool hasPendingFlush() const override;
|
bool hasPendingFlush() const override;
|
||||||
void paint(int screenId, const QRegion &damage, const QList<Toplevel *> &windows) override;
|
void paint(int screenId, const QRegion &damage, const QList<Toplevel *> &windows,
|
||||||
|
std::chrono::milliseconds presentTime) override;
|
||||||
Scene::EffectFrame *createEffectFrame(EffectFrameImpl *frame) override;
|
Scene::EffectFrame *createEffectFrame(EffectFrameImpl *frame) override;
|
||||||
Shadow *createShadow(Toplevel *toplevel) override;
|
Shadow *createShadow(Toplevel *toplevel) override;
|
||||||
void screenGeometryChanged(const QSize &size) override;
|
void screenGeometryChanged(const QSize &size) override;
|
||||||
|
|
|
@ -80,7 +80,8 @@ void SceneQPainter::paintGenericScreen(int mask, const ScreenPaintData &data)
|
||||||
m_painter->restore();
|
m_painter->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneQPainter::paint(int screenId, const QRegion &_damage, const QList<Toplevel *> &toplevels)
|
void SceneQPainter::paint(int screenId, const QRegion &_damage, const QList<Toplevel *> &toplevels,
|
||||||
|
std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
Q_ASSERT(kwinApp()->platform()->isPerScreenRenderingEnabled());
|
Q_ASSERT(kwinApp()->platform()->isPerScreenRenderingEnabled());
|
||||||
painted_screen = screenId;
|
painted_screen = screenId;
|
||||||
|
@ -103,7 +104,8 @@ void SceneQPainter::paint(int screenId, const QRegion &_damage, const QList<Topl
|
||||||
m_painter->setWindow(geometry);
|
m_painter->setWindow(geometry);
|
||||||
|
|
||||||
QRegion updateRegion, validRegion;
|
QRegion updateRegion, validRegion;
|
||||||
paintScreen(&mask, damage.intersected(geometry), QRegion(), &updateRegion, &validRegion);
|
paintScreen(&mask, damage.intersected(geometry), QRegion(), &updateRegion, &validRegion,
|
||||||
|
presentTime);
|
||||||
paintCursor(updateRegion);
|
paintCursor(updateRegion);
|
||||||
|
|
||||||
m_painter->end();
|
m_painter->end();
|
||||||
|
|
|
@ -25,7 +25,8 @@ public:
|
||||||
~SceneQPainter() override;
|
~SceneQPainter() override;
|
||||||
bool usesOverlayWindow() const override;
|
bool usesOverlayWindow() const override;
|
||||||
OverlayWindow* overlayWindow() const override;
|
OverlayWindow* overlayWindow() const override;
|
||||||
void paint(int screenId, const QRegion &damage, const QList<Toplevel *> &windows) override;
|
void paint(int screenId, const QRegion &damage, const QList<Toplevel *> &windows,
|
||||||
|
std::chrono::milliseconds presentTime) override;
|
||||||
void paintGenericScreen(int mask, const ScreenPaintData &data) override;
|
void paintGenericScreen(int mask, const ScreenPaintData &data) override;
|
||||||
CompositingType compositingType() const override;
|
CompositingType compositingType() const override;
|
||||||
bool initFailed() const override;
|
bool initFailed() const override;
|
||||||
|
|
|
@ -75,7 +75,8 @@ bool SceneXrender::initFailed() const
|
||||||
}
|
}
|
||||||
|
|
||||||
// the entry point for painting
|
// the entry point for painting
|
||||||
void SceneXrender::paint(int screenId, const QRegion &damage, const QList<Toplevel *> &toplevels)
|
void SceneXrender::paint(int screenId, const QRegion &damage, const QList<Toplevel *> &toplevels,
|
||||||
|
std::chrono::milliseconds presentTime)
|
||||||
{
|
{
|
||||||
painted_screen = screenId;
|
painted_screen = screenId;
|
||||||
|
|
||||||
|
@ -83,7 +84,7 @@ void SceneXrender::paint(int screenId, const QRegion &damage, const QList<Toplev
|
||||||
|
|
||||||
int mask = 0;
|
int mask = 0;
|
||||||
QRegion updateRegion, validRegion;
|
QRegion updateRegion, validRegion;
|
||||||
paintScreen(&mask, damage, QRegion(), &updateRegion, &validRegion);
|
paintScreen(&mask, damage, QRegion(), &updateRegion, &validRegion, presentTime);
|
||||||
|
|
||||||
m_backend->showOverlay();
|
m_backend->showOverlay();
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,8 @@ public:
|
||||||
CompositingType compositingType() const override {
|
CompositingType compositingType() const override {
|
||||||
return XRenderCompositing;
|
return XRenderCompositing;
|
||||||
}
|
}
|
||||||
void paint(int screenId, const QRegion &damage, const QList<Toplevel *> &windows) override;
|
void paint(int screenId, const QRegion &damage, const QList<Toplevel *> &windows,
|
||||||
|
std::chrono::milliseconds presentTime) override;
|
||||||
Scene::EffectFrame *createEffectFrame(EffectFrameImpl *frame) override;
|
Scene::EffectFrame *createEffectFrame(EffectFrameImpl *frame) override;
|
||||||
Shadow *createShadow(Toplevel *toplevel) override;
|
Shadow *createShadow(Toplevel *toplevel) override;
|
||||||
void screenGeometryChanged(const QSize &size) override;
|
void screenGeometryChanged(const QSize &size) override;
|
||||||
|
|
40
scene.cpp
40
scene.cpp
|
@ -86,7 +86,6 @@ namespace KWin
|
||||||
Scene::Scene(QObject *parent)
|
Scene::Scene(QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
{
|
{
|
||||||
last_time.invalidate(); // Initialize the timer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene::~Scene()
|
Scene::~Scene()
|
||||||
|
@ -96,13 +95,22 @@ Scene::~Scene()
|
||||||
|
|
||||||
// returns mask and possibly modified region
|
// returns mask and possibly modified region
|
||||||
void Scene::paintScreen(int* mask, const QRegion &damage, const QRegion &repaint,
|
void Scene::paintScreen(int* mask, const QRegion &damage, const QRegion &repaint,
|
||||||
QRegion *updateRegion, QRegion *validRegion, const QMatrix4x4 &projection, const QRect &outputGeometry, const qreal screenScale)
|
QRegion *updateRegion, QRegion *validRegion,
|
||||||
|
std::chrono::milliseconds presentTime,
|
||||||
|
const QMatrix4x4 &projection, const QRect &outputGeometry,
|
||||||
|
qreal screenScale)
|
||||||
{
|
{
|
||||||
const QSize &screenSize = screens()->size();
|
const QSize &screenSize = screens()->size();
|
||||||
const QRegion displayRegion(0, 0, screenSize.width(), screenSize.height());
|
const QRegion displayRegion(0, 0, screenSize.width(), screenSize.height());
|
||||||
*mask = (damage == displayRegion) ? 0 : PAINT_SCREEN_REGION;
|
*mask = (damage == displayRegion) ? 0 : PAINT_SCREEN_REGION;
|
||||||
|
|
||||||
updateTimeDiff();
|
if (Q_UNLIKELY(presentTime < m_expectedPresentTimestamp)) {
|
||||||
|
qCDebug(KWIN_CORE, "Provided presentation timestamp is invalid: %ld (current: %ld)",
|
||||||
|
presentTime.count(), m_expectedPresentTimestamp.count());
|
||||||
|
} else {
|
||||||
|
m_expectedPresentTimestamp = presentTime;
|
||||||
|
}
|
||||||
|
|
||||||
// preparation step
|
// preparation step
|
||||||
static_cast<EffectsHandlerImpl*>(effects)->startPaint();
|
static_cast<EffectsHandlerImpl*>(effects)->startPaint();
|
||||||
|
|
||||||
|
@ -112,7 +120,7 @@ void Scene::paintScreen(int* mask, const QRegion &damage, const QRegion &repaint
|
||||||
pdata.mask = *mask;
|
pdata.mask = *mask;
|
||||||
pdata.paint = region;
|
pdata.paint = region;
|
||||||
|
|
||||||
effects->prePaintScreen(pdata, time_diff);
|
effects->prePaintScreen(pdata, m_expectedPresentTimestamp);
|
||||||
*mask = pdata.mask;
|
*mask = pdata.mask;
|
||||||
region = pdata.paint;
|
region = pdata.paint;
|
||||||
|
|
||||||
|
@ -154,29 +162,9 @@ void Scene::paintScreen(int* mask, const QRegion &damage, const QRegion &repaint
|
||||||
Q_ASSERT(!PaintClipper::clip());
|
Q_ASSERT(!PaintClipper::clip());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute time since the last painting pass.
|
|
||||||
void Scene::updateTimeDiff()
|
|
||||||
{
|
|
||||||
if (!last_time.isValid()) {
|
|
||||||
// Painting has been idle (optimized out) for some time,
|
|
||||||
// which means time_diff would be huge and would break animations.
|
|
||||||
// Simply set it to one (zero would mean no change at all and could
|
|
||||||
// cause problems).
|
|
||||||
time_diff = 1;
|
|
||||||
last_time.start();
|
|
||||||
} else
|
|
||||||
|
|
||||||
time_diff = last_time.restart();
|
|
||||||
|
|
||||||
if (time_diff < 0) // check time rollback
|
|
||||||
time_diff = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Painting pass is optimized away.
|
// Painting pass is optimized away.
|
||||||
void Scene::idle()
|
void Scene::idle()
|
||||||
{
|
{
|
||||||
// Don't break time since last paint for the next pass.
|
|
||||||
last_time.invalidate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// the function that'll be eventually called by paintScreen() above
|
// the function that'll be eventually called by paintScreen() above
|
||||||
|
@ -213,7 +201,7 @@ void Scene::paintGenericScreen(int orig_mask, const ScreenPaintData &)
|
||||||
data.clip = QRegion();
|
data.clip = QRegion();
|
||||||
data.quads = w->buildQuads();
|
data.quads = w->buildQuads();
|
||||||
// preparation step
|
// preparation step
|
||||||
effects->prePaintWindow(effectWindow(w), data, time_diff);
|
effects->prePaintWindow(effectWindow(w), data, m_expectedPresentTimestamp);
|
||||||
#if !defined(QT_NO_DEBUG)
|
#if !defined(QT_NO_DEBUG)
|
||||||
if (data.quads.isTransformed()) {
|
if (data.quads.isTransformed()) {
|
||||||
qFatal("Pre-paint calls are not allowed to transform quads!");
|
qFatal("Pre-paint calls are not allowed to transform quads!");
|
||||||
|
@ -306,7 +294,7 @@ void Scene::paintSimpleScreen(int orig_mask, const QRegion ®ion)
|
||||||
|
|
||||||
data.quads = window->buildQuads();
|
data.quads = window->buildQuads();
|
||||||
// preparation step
|
// preparation step
|
||||||
effects->prePaintWindow(effectWindow(window), data, time_diff);
|
effects->prePaintWindow(effectWindow(window), data, m_expectedPresentTimestamp);
|
||||||
#if !defined(QT_NO_DEBUG)
|
#if !defined(QT_NO_DEBUG)
|
||||||
if (data.quads.isTransformed()) {
|
if (data.quads.isTransformed()) {
|
||||||
qFatal("Pre-paint calls are not allowed to transform quads!");
|
qFatal("Pre-paint calls are not allowed to transform quads!");
|
||||||
|
|
14
scene.h
14
scene.h
|
@ -65,7 +65,8 @@ public:
|
||||||
// The entry point for the main part of the painting pass.
|
// The entry point for the main part of the painting pass.
|
||||||
// returns the time since the last vblank signal - if there's one
|
// returns the time since the last vblank signal - if there's one
|
||||||
// ie. "what of this frame is lost to painting"
|
// ie. "what of this frame is lost to painting"
|
||||||
virtual void paint(int screenId, const QRegion &damage, const QList<Toplevel *> &windows) = 0;
|
virtual void paint(int screenId, const QRegion &damage, const QList<Toplevel *> &windows,
|
||||||
|
std::chrono::milliseconds presentTime) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the Toplevel to the Scene.
|
* Adds the Toplevel to the Scene.
|
||||||
|
@ -207,7 +208,10 @@ protected:
|
||||||
void clearStackingOrder();
|
void clearStackingOrder();
|
||||||
// shared implementation, starts painting the screen
|
// shared implementation, starts painting the screen
|
||||||
void paintScreen(int *mask, const QRegion &damage, const QRegion &repaint,
|
void paintScreen(int *mask, const QRegion &damage, const QRegion &repaint,
|
||||||
QRegion *updateRegion, QRegion *validRegion, const QMatrix4x4 &projection = QMatrix4x4(), const QRect &outputGeometry = QRect(), const qreal screenScale = 1.0);
|
QRegion *updateRegion, QRegion *validRegion,
|
||||||
|
std::chrono::milliseconds presentTime,
|
||||||
|
const QMatrix4x4 &projection = QMatrix4x4(),
|
||||||
|
const QRect &outputGeometry = QRect(), qreal screenScale = 1.0);
|
||||||
// Render cursor texture in case hardware cursor is disabled/non-applicable
|
// Render cursor texture in case hardware cursor is disabled/non-applicable
|
||||||
virtual void paintCursor(const QRegion ®ion) = 0;
|
virtual void paintCursor(const QRegion ®ion) = 0;
|
||||||
friend class EffectsHandlerImpl;
|
friend class EffectsHandlerImpl;
|
||||||
|
@ -240,8 +244,6 @@ protected:
|
||||||
|
|
||||||
virtual void paintEffectQuickView(EffectQuickView *w) = 0;
|
virtual void paintEffectQuickView(EffectQuickView *w) = 0;
|
||||||
|
|
||||||
// compute time since the last repaint
|
|
||||||
void updateTimeDiff();
|
|
||||||
// saved data for 2nd pass of optimized screen painting
|
// saved data for 2nd pass of optimized screen painting
|
||||||
struct Phase2Data {
|
struct Phase2Data {
|
||||||
Window *window = nullptr;
|
Window *window = nullptr;
|
||||||
|
@ -260,14 +262,12 @@ protected:
|
||||||
QRegion repaint_region;
|
QRegion repaint_region;
|
||||||
// The dirty region before it was unioned with repaint_region
|
// The dirty region before it was unioned with repaint_region
|
||||||
QRegion damaged_region;
|
QRegion damaged_region;
|
||||||
// time since last repaint
|
|
||||||
int time_diff;
|
|
||||||
QElapsedTimer last_time;
|
|
||||||
// The screen that is being currently painted
|
// The screen that is being currently painted
|
||||||
int painted_screen = -1;
|
int painted_screen = -1;
|
||||||
private:
|
private:
|
||||||
void paintWindowThumbnails(Scene::Window *w, const QRegion ®ion, qreal opacity, qreal brightness, qreal saturation);
|
void paintWindowThumbnails(Scene::Window *w, const QRegion ®ion, qreal opacity, qreal brightness, qreal saturation);
|
||||||
void paintDesktopThumbnails(Scene::Window *w);
|
void paintDesktopThumbnails(Scene::Window *w);
|
||||||
|
std::chrono::milliseconds m_expectedPresentTimestamp = std::chrono::milliseconds::zero();
|
||||||
QHash< Toplevel*, Window* > m_windows;
|
QHash< Toplevel*, Window* > m_windows;
|
||||||
// windows in their stacking order
|
// windows in their stacking order
|
||||||
QVector< Window* > stacking_order;
|
QVector< Window* > stacking_order;
|
||||||
|
|
Loading…
Reference in New Issue