Add: Add desktop switching animation

This commit is contained in:
liling 2022-11-24 14:04:25 +08:00 committed by MouseZhang
parent 51f31b63cb
commit 3ac6dca31c
6 changed files with 294 additions and 1 deletions

View File

@ -9,7 +9,7 @@
*/
#include "effects.h"
#include "tablet_manager.h"
#include "abstract_output.h"
#include "effectsadaptor.h"
#include "effectloader.h"
@ -136,6 +136,10 @@ EffectsHandlerImpl::EffectsHandlerImpl(Compositor *compositor, Scene *scene)
VirtualDesktopManager *vds = VirtualDesktopManager::self();
connect(ws, &Workspace::showingDesktopChanged,
this, &EffectsHandlerImpl::showingDesktopChanged);
connect(TabletManager::self(), &TabletManager::tabletModeChanged,
this, &EffectsHandlerImpl::tabletModeChanged);
connect(ws, &Workspace::currentDesktopChanged, this,
[this](int old, AbstractClient *c) {
const int newDesktop = VirtualDesktopManager::self()->current();
@ -266,6 +270,38 @@ EffectsHandlerImpl::~EffectsHandlerImpl()
unloadAllEffects();
}
void EffectsHandlerImpl::setDesktopHide(const QString &desktopName)
{
if (desktopName == m_desktopName) {
return;
}
m_desktopName = desktopName;
auto list = Workspace::self()->stackingOrder();
for (auto window : list) {
if (!window->isDeleted()) {
auto win = qobject_cast<AbstractClient *> (window);
if (win->isDesktop()) {
if (TabletManager::self()->tabletMode()) {
if (win->caption() == "ukui-tablet-desktop") {
win->showClient();
} else {
win->hideClient();
}
} else {
if (win->caption() == "ukui-tablet-desktop") {
win->hideClient();
} else {
win->showClient();
}
}
}
}
}
Q_EMIT desktopAppearAnimatestart();
}
void EffectsHandlerImpl::unloadAllEffects()
{
for (const EffectPair &pair : qAsConst(loaded_effects)) {

View File

@ -136,6 +136,15 @@ public:
Effect* activeFullScreenEffect() const override;
bool hasActiveFullScreenEffect() const override;
/**
* When PC/TM is switched, this function will be triggered after the desktop vanishing animation is played,
* the desktop will be hidden, and the desktop animation will be displayed;
* eg:
* When PC ->TM, this function will be triggered after the disappearance animation of PC is played.
* This function will hide the PC desktop, and then send a signal to let the TM desktop play the display animation.
*/
void setDesktopHide(const QString &desktopName) override;
void addRepaintFull() override;
void addRepaint(const QRect& r) override;
void addRepaint(const QRegion& r) override;
@ -355,6 +364,9 @@ private:
int m_trackingCursorChanges;
std::unique_ptr<WindowPropertyNotifyX11Filter> m_x11WindowPropertyNotify;
QList<EffectScreen *> m_effectScreens;
//记录上一次进行消失动画的桌面是谁
QString m_desktopName;
};
class EffectScreenImpl : public EffectScreen

View File

@ -122,6 +122,7 @@ install_scripted_effect(squash)
install_scripted_effect(translucency)
install_scripted_effect(windowaperture)
install_scripted_effect(sessionquit)
install_scripted_effect(scaledesktop)
###############################################################################
# Built-in effects go here

View File

@ -0,0 +1,195 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2017 Martin Gräßlin <mgraesslin@kde.org>
SPDX-FileCopyrightText: 2022 KylinSoft Co., Ltd.
SPDX-License-Identifier: GPL-2.0-or-later
*/
"use strict";
var pcDesktop;
var tmDesktop;
var appearDesktop;
var disappearDesktop;
var currentTabletMode = false;
var scaledesktopEffect = {
duration: animationTime(250),
loadConfig: function ()
{
scaledesktopEffect.duration = animationTime(250);
},
opacitydesktop: function()
{
var stackingOrder = effects.stackingOrder;
var w;
for (var i = 0; i < stackingOrder.length; ++i) {
w = stackingOrder[i];
if (!w.visible || w.dock || w.caption == "" || w.caption.includes("tablet_blur_background")
|| w.slurpedByEyeOnScreen || w.caption.includes("UKUI Panel")) {
continue;
}
if(!w.desktopWindow) {
animate({
window: w,
animations: [{
type: Effect.Opacity,
curve: QEasingCurve.Linear,
duration: 3 * scaledesktopEffect.duration,
from: 0,
to: 0
}]
});
}
}
},
appearAnimate: function ()
{
scaledesktopEffect.opacitydesktop();
var windowRect = appearDesktop.geometry;
animate({
window: appearDesktop,
duration: 2 * scaledesktopEffect.duration,
animations: [
{
type: Effect.Size,
from: {
value1: windowRect.width * 0.9,
value2: windowRect.height * 0.9
},
to: {
value1: windowRect.width,
value2: windowRect.height
}
},
{
type: Effect.Opacity,
from: 0,
to: 1.0
}
]
});
},
disappearAnimate: function ()
{
var windowRect = disappearDesktop.geometry;
animate({
window: disappearDesktop,
duration: 2 * scaledesktopEffect.duration,
animations: [
{
type: Effect.Size,
from: {
value1: windowRect.width,
value2: windowRect.height
},
to: {
value1: windowRect.width * 0.9,
value2: windowRect.height * 0.9
}
},
{
type: Effect.Opacity,
from: 1.0,
to: 0.0
}
]
});
animate({
window: appearDesktop,
duration: 2 * scaledesktopEffect.duration,
animations: [
{
type: Effect.Size,
from: {
value1: windowRect.width,
value2: windowRect.height
},
to: {
value1: windowRect.width * 0.9,
value2: windowRect.height * 0.9
}
},
{
type: Effect.Opacity,
from: 1.0,
to: 0.0
}
]
});
},
toggleAnimationSignal: function(win)
{
if(win.desktopWindow) {
if(currentTabletMode) {
if(win.caption != "ukui-tablet-desktop") {
effects.setDesktopHide(win.caption);
}
} else {
if(win.caption == "ukui-tablet-desktop") {
effects.setDesktopHide(win.caption);
}
}
}
},
scaleDesktop: function (tabletmode) {
var stackingOrder = effects.stackingOrder;
var w;
for (var i = 0; i < stackingOrder.length; ++i) {
w = stackingOrder[i];
if (!w.visible || w.dock || w.caption == "" || w.caption.includes("tablet_blur_background")
|| w.slurpedByEyeOnScreen || w.caption.includes("UKUI Panel")) {
continue;
}
if(w.desktopWindow) {
if(w.caption == "ukui-tablet-desktop") {
tmDesktop = w;
} else {
pcDesktop = w;
}
} else {
animate({
window: w,
animations: [{
type: Effect.Opacity,
curve: QEasingCurve.Linear,
duration: 2 * scaledesktopEffect.duration,
to: 0
}]
});
}
}
if(tabletmode) {
currentTabletMode = true;
disappearDesktop = pcDesktop;
appearDesktop = tmDesktop;
} else {
currentTabletMode = false;
disappearDesktop = tmDesktop;
appearDesktop = pcDesktop;
}
scaledesktopEffect.disappearAnimate();
},
init: function () {
scaledesktopEffect.loadConfig();
effects.tabletModeChanged.connect(scaledesktopEffect.scaleDesktop);
effects.desktopAppearAnimatestart.connect(scaledesktopEffect.appearAnimate)
effect.animationEnded.connect(scaledesktopEffect.toggleAnimationSignal);
}
};
scaledesktopEffect.init();

View File

@ -0,0 +1,40 @@
[Desktop Entry]
Name=scaledesktop
Name[ar]=سكاليدسكتوب
Name[az]=Masaüstü ölçülə
Name[ca]=de bureau à grande échelle
Name[ca@valencia]=de bureau à grande échelle
Name[de]=Desktop skalieren
Name[en_GB]=scale desktop
Name[es]=Ampliar el escritorio
Name[et]=Skaleeri töölaud
Name[zh_CN]=缩放桌面
Name[zh_TW]=縮放桌面
Comment=scale desktop
Comment[ar]=سكاليدسكتوب
Comment[az]=Masaüstü ölçülə
Comment[ca]=de bureau à grande échelle
Comment[ca@valencia]=de bureau à grande échelle
Comment[de]= Desktop skalieren
Comment[en_GB]=scale desktop
Comment[es]=Ampliar el escritorio
Comment[et]=Skaleeri töölaud
Comment[zh_CN]=缩放桌面
Comment[zh_TW]=縮放桌面
Type=Service
X-KDE-ParentApp=
X-KDE-PluginInfo-Author=liling
X-KDE-PluginInfo-Category=Appearance
X-KDE-PluginInfo-Email=liling@kylinos.cn
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-Name=kwin4_effect_scaledesktop
X-KDE-PluginInfo-Version=1
X-KDE-PluginInfo-Website=
X-KDE-ServiceTypes=KWin/Effect
X-KDE-PluginInfo-EnabledByDefault=true
X-KDE-Ordering=60
X-Plasma-API=javascript
X-Plasma-MainScript=code/main.js
X-KWin-Exclusive-Category=scale desktop

View File

@ -1068,6 +1068,13 @@ public:
* @since 5.16
*/
Q_SCRIPTABLE virtual KWin::EffectWindow *findWindow(QWindow *w) const = 0;
/**
* When switching PC/TM,set to hide desktop ,
* for explame ,when PC switches to TM,hide the PC desktop;
*/
Q_SCRIPTABLE virtual void setDesktopHide(const QString &desktopName) = 0;
/**
* Finds the EffectWindow for the Toplevel with KWin internal @p id.
* If there is no such window @c null is returned.
@ -1814,6 +1821,8 @@ Q_SIGNALS:
void startupAdded(const QString &id, const QIcon &icon);
void startupChanged(const QString &id, const QIcon &icon);
void startupRemoved(const QString &id);
void tabletModeChanged(bool);
void desktopAppearAnimatestart() const;
protected:
QVector< EffectPair > loaded_effects;