2009-02-06 21:53:16 +03:00
|
|
|
/********************************************************************
|
|
|
|
KWin - the KDE window manager
|
|
|
|
This file is part of the KDE project.
|
|
|
|
|
2013-03-12 16:17:53 +04:00
|
|
|
Copyright (C) 2009 Martin Gräßlin <mgraesslin@kde.org>
|
2009-02-06 21:53:16 +03:00
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*********************************************************************/
|
|
|
|
|
|
|
|
#include "cubeslide.h"
|
2012-09-12 20:39:13 +04:00
|
|
|
// KConfigSkeleton
|
|
|
|
#include "cubeslideconfig.h"
|
2009-02-06 21:53:16 +03:00
|
|
|
|
|
|
|
#include <kwinconfig.h>
|
2013-02-26 11:02:27 +04:00
|
|
|
#include <QVector3D>
|
2009-02-06 21:53:16 +03:00
|
|
|
|
|
|
|
#include <math.h>
|
|
|
|
|
2010-12-18 12:18:54 +03:00
|
|
|
#include <kwinglutils.h>
|
2009-02-06 21:53:16 +03:00
|
|
|
|
|
|
|
namespace KWin
|
|
|
|
{
|
|
|
|
|
|
|
|
CubeSlideEffect::CubeSlideEffect()
|
2011-01-30 17:34:42 +03:00
|
|
|
: windowMoving(false)
|
|
|
|
, desktopChangedWhileMoving(false)
|
|
|
|
, progressRestriction(0.0f)
|
|
|
|
{
|
2016-12-02 22:27:43 +03:00
|
|
|
initConfig<CubeSlideConfig>();
|
2011-08-18 01:51:55 +04:00
|
|
|
connect(effects, SIGNAL(desktopChanged(int,int)), this, SLOT(slotDesktopChanged(int,int)));
|
2012-01-29 15:29:24 +04:00
|
|
|
connect(effects, SIGNAL(windowStepUserMovedResized(KWin::EffectWindow*,QRect)), this, SLOT(slotWindowStepUserMovedResized(KWin::EffectWindow*)));
|
|
|
|
connect(effects, SIGNAL(windowFinishUserMovedResized(KWin::EffectWindow*)), this, SLOT(slotWindowFinishUserMovedResized(KWin::EffectWindow*)));
|
2011-01-30 17:34:42 +03:00
|
|
|
reconfigure(ReconfigureAll);
|
|
|
|
}
|
2009-02-06 21:53:16 +03:00
|
|
|
|
|
|
|
CubeSlideEffect::~CubeSlideEffect()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
|
|
|
}
|
2009-02-06 21:53:16 +03:00
|
|
|
|
|
|
|
bool CubeSlideEffect::supported()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2016-08-10 10:24:53 +03:00
|
|
|
return effects->isOpenGLCompositing() && effects->animationsSupported();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2009-02-06 21:53:16 +03:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void CubeSlideEffect::reconfigure(ReconfigureFlags)
|
|
|
|
{
|
2014-03-25 19:29:03 +04:00
|
|
|
CubeSlideConfig::self()->read();
|
2012-11-25 21:46:13 +04:00
|
|
|
// TODO: rename rotationDuration to duration
|
2012-09-12 20:39:13 +04:00
|
|
|
rotationDuration = animationTime(CubeSlideConfig::rotationDuration() != 0 ? CubeSlideConfig::rotationDuration() : 500);
|
2011-03-15 00:50:05 +03:00
|
|
|
timeLine.setCurveShape(QTimeLine::EaseInOutCurve);
|
2011-01-30 17:34:42 +03:00
|
|
|
timeLine.setDuration(rotationDuration);
|
2012-09-12 20:39:13 +04:00
|
|
|
dontSlidePanels = CubeSlideConfig::dontSlidePanels();
|
|
|
|
dontSlideStickyWindows = CubeSlideConfig::dontSlideStickyWindows();
|
|
|
|
usePagerLayout = CubeSlideConfig::usePagerLayout();
|
|
|
|
useWindowMoving = CubeSlideConfig::useWindowMoving();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2009-02-06 21:53:16 +03:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void CubeSlideEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
|
|
|
{
|
|
|
|
if (!slideRotations.empty()) {
|
2009-02-06 21:53:16 +03:00
|
|
|
data.mask |= PAINT_SCREEN_TRANSFORMED | Effect::PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS | PAINT_SCREEN_BACKGROUND_FIRST;
|
2011-03-15 00:50:05 +03:00
|
|
|
timeLine.setCurrentTime(timeLine.currentTime() + time);
|
|
|
|
if (windowMoving && timeLine.currentTime() > progressRestriction * (qreal)timeLine.duration())
|
|
|
|
timeLine.setCurrentTime(progressRestriction * (qreal)timeLine.duration());
|
2011-01-30 17:34:42 +03:00
|
|
|
if (dontSlidePanels)
|
2009-02-06 21:53:16 +03:00
|
|
|
panels.clear();
|
2009-10-14 11:22:11 +04:00
|
|
|
stickyWindows.clear();
|
2009-02-06 21:53:16 +03:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
effects->prePaintScreen(data, time);
|
|
|
|
}
|
2009-02-06 21:53:16 +03:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void CubeSlideEffect::paintScreen(int mask, QRegion region, ScreenPaintData& data)
|
|
|
|
{
|
|
|
|
if (!slideRotations.empty()) {
|
|
|
|
glEnable(GL_CULL_FACE);
|
|
|
|
glCullFace(GL_FRONT);
|
|
|
|
paintSlideCube(mask, region, data);
|
|
|
|
glCullFace(GL_BACK);
|
|
|
|
paintSlideCube(mask, region, data);
|
|
|
|
glDisable(GL_CULL_FACE);
|
2012-01-27 19:50:27 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
if (dontSlidePanels) {
|
|
|
|
foreach (EffectWindow * w, panels) {
|
|
|
|
WindowPaintData wData(w);
|
2013-03-21 19:38:23 +04:00
|
|
|
effects->paintWindow(w, 0, infiniteRegion(), wData);
|
2009-02-06 21:53:16 +03:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
foreach (EffectWindow * w, stickyWindows) {
|
|
|
|
WindowPaintData wData(w);
|
2013-03-21 19:38:23 +04:00
|
|
|
effects->paintWindow(w, 0, infiniteRegion(), wData);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
|
|
|
} else
|
|
|
|
effects->paintScreen(mask, region, data);
|
|
|
|
}
|
2009-02-06 21:53:16 +03:00
|
|
|
|
|
|
|
void CubeSlideEffect::paintSlideCube(int mask, QRegion region, ScreenPaintData& data)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2009-02-06 21:53:16 +03:00
|
|
|
// slide cube only paints to desktops at a time
|
|
|
|
// first the horizontal rotations followed by vertical rotations
|
2011-01-30 17:34:42 +03:00
|
|
|
QRect rect = effects->clientArea(FullArea, effects->activeScreen(), effects->currentDesktop());
|
|
|
|
float point = rect.width() / 2 * tan(45.0f * M_PI / 180.0f);
|
2009-02-06 21:53:16 +03:00
|
|
|
cube_painting = true;
|
|
|
|
painting_desktop = front_desktop;
|
|
|
|
|
|
|
|
ScreenPaintData firstFaceData = data;
|
|
|
|
ScreenPaintData secondFaceData = data;
|
|
|
|
RotationDirection direction = slideRotations.head();
|
|
|
|
int secondDesktop;
|
2011-01-30 17:34:42 +03:00
|
|
|
switch(direction) {
|
|
|
|
case Left:
|
2012-06-02 23:54:18 +04:00
|
|
|
firstFaceData.setRotationAxis(Qt::YAxis);
|
|
|
|
secondFaceData.setRotationAxis(Qt::YAxis);
|
2011-01-30 17:34:42 +03:00
|
|
|
if (usePagerLayout)
|
|
|
|
secondDesktop = effects->desktopToLeft(front_desktop, true);
|
|
|
|
else {
|
|
|
|
secondDesktop = front_desktop - 1;
|
|
|
|
if (secondDesktop == 0)
|
|
|
|
secondDesktop = effects->numberOfDesktops();
|
2009-02-06 21:53:16 +03:00
|
|
|
}
|
2012-06-02 23:54:18 +04:00
|
|
|
firstFaceData.setRotationAngle(90.0f * timeLine.currentValue());
|
|
|
|
secondFaceData.setRotationAngle(-90.0f * (1.0f - timeLine.currentValue()));
|
2011-01-30 17:34:42 +03:00
|
|
|
break;
|
|
|
|
case Right:
|
2012-06-02 23:54:18 +04:00
|
|
|
firstFaceData.setRotationAxis(Qt::YAxis);
|
|
|
|
secondFaceData.setRotationAxis(Qt::YAxis);
|
2011-01-30 17:34:42 +03:00
|
|
|
if (usePagerLayout)
|
|
|
|
secondDesktop = effects->desktopToRight(front_desktop, true);
|
|
|
|
else {
|
|
|
|
secondDesktop = front_desktop + 1;
|
|
|
|
if (secondDesktop > effects->numberOfDesktops())
|
|
|
|
secondDesktop = 1;
|
|
|
|
}
|
2012-06-02 23:54:18 +04:00
|
|
|
firstFaceData.setRotationAngle(-90.0f * timeLine.currentValue());
|
|
|
|
secondFaceData.setRotationAngle(90.0f * (1.0f - timeLine.currentValue()));
|
2011-01-30 17:34:42 +03:00
|
|
|
break;
|
|
|
|
case Upwards:
|
2012-06-02 23:54:18 +04:00
|
|
|
firstFaceData.setRotationAxis(Qt::XAxis);
|
|
|
|
secondFaceData.setRotationAxis(Qt::XAxis);
|
2011-01-30 17:34:42 +03:00
|
|
|
secondDesktop = effects->desktopAbove(front_desktop, true);
|
2012-06-02 23:54:18 +04:00
|
|
|
firstFaceData.setRotationAngle(-90.0f * timeLine.currentValue());
|
|
|
|
secondFaceData.setRotationAngle(90.0f * (1.0f - timeLine.currentValue()));
|
2011-01-30 17:34:42 +03:00
|
|
|
point = rect.height() / 2 * tan(45.0f * M_PI / 180.0f);
|
|
|
|
break;
|
|
|
|
case Downwards:
|
2012-06-02 23:54:18 +04:00
|
|
|
firstFaceData.setRotationAxis(Qt::XAxis);
|
|
|
|
secondFaceData.setRotationAxis(Qt::XAxis);
|
2011-01-30 17:34:42 +03:00
|
|
|
secondDesktop = effects->desktopBelow(front_desktop, true);
|
2012-06-02 23:54:18 +04:00
|
|
|
firstFaceData.setRotationAngle(90.0f * timeLine.currentValue());
|
|
|
|
secondFaceData.setRotationAngle(-90.0f * (1.0f - timeLine.currentValue()));
|
2011-01-30 17:34:42 +03:00
|
|
|
point = rect.height() / 2 * tan(45.0f * M_PI / 180.0f);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
// totally impossible
|
|
|
|
return;
|
|
|
|
}
|
2009-02-06 21:53:16 +03:00
|
|
|
// front desktop
|
2012-06-02 23:54:18 +04:00
|
|
|
firstFaceData.setRotationOrigin(QVector3D(rect.width() / 2, rect.height() / 2, -point));
|
2009-02-18 22:14:47 +03:00
|
|
|
other_desktop = secondDesktop;
|
|
|
|
firstDesktop = true;
|
2011-01-30 17:34:42 +03:00
|
|
|
effects->paintScreen(mask, region, firstFaceData);
|
2009-02-06 21:53:16 +03:00
|
|
|
// second desktop
|
2009-02-18 22:14:47 +03:00
|
|
|
other_desktop = painting_desktop;
|
2009-02-06 21:53:16 +03:00
|
|
|
painting_desktop = secondDesktop;
|
2009-02-18 22:14:47 +03:00
|
|
|
firstDesktop = false;
|
2012-06-02 23:54:18 +04:00
|
|
|
secondFaceData.setRotationOrigin(QVector3D(rect.width() / 2, rect.height() / 2, -point));
|
2011-01-30 17:34:42 +03:00
|
|
|
effects->paintScreen(mask, region, secondFaceData);
|
2009-02-06 21:53:16 +03:00
|
|
|
cube_painting = false;
|
|
|
|
painting_desktop = effects->currentDesktop();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2009-02-06 21:53:16 +03:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void CubeSlideEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
|
|
|
|
{
|
|
|
|
if (!slideRotations.empty() && cube_painting) {
|
|
|
|
QRect rect = effects->clientArea(FullArea, effects->activeScreen(), painting_desktop);
|
|
|
|
if (dontSlidePanels && w->isDock()) {
|
|
|
|
w->setData(WindowForceBlurRole, QVariant(true));
|
|
|
|
panels.insert(w);
|
|
|
|
}
|
|
|
|
if (!w->isManaged()) {
|
|
|
|
w->setData(WindowForceBlurRole, QVariant(true));
|
|
|
|
stickyWindows.insert(w);
|
|
|
|
} else if (dontSlideStickyWindows && !w->isDock() &&
|
|
|
|
!w->isDesktop() && w->isOnAllDesktops()) {
|
|
|
|
w->setData(WindowForceBlurRole, QVariant(true));
|
|
|
|
stickyWindows.insert(w);
|
|
|
|
}
|
|
|
|
if (w->isOnDesktop(painting_desktop)) {
|
|
|
|
if (w->x() < rect.x()) {
|
|
|
|
data.quads = data.quads.splitAtX(-w->x());
|
2009-02-06 21:53:16 +03:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
if (w->x() + w->width() > rect.x() + rect.width()) {
|
|
|
|
data.quads = data.quads.splitAtX(rect.width() - w->x());
|
2009-10-14 11:22:11 +04:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
if (w->y() < rect.y()) {
|
|
|
|
data.quads = data.quads.splitAtY(-w->y());
|
2009-02-06 21:53:16 +03:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
if (w->y() + w->height() > rect.y() + rect.height()) {
|
|
|
|
data.quads = data.quads.splitAtY(rect.height() - w->y());
|
2009-02-18 22:14:47 +03:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
|
|
|
|
} else if (w->isOnDesktop(other_desktop)) {
|
2009-02-18 22:14:47 +03:00
|
|
|
RotationDirection direction = slideRotations.head();
|
|
|
|
bool enable = false;
|
2011-01-30 17:34:42 +03:00
|
|
|
if (w->x() < rect.x() &&
|
|
|
|
(direction == Left || direction == Right)) {
|
|
|
|
data.quads = data.quads.splitAtX(-w->x());
|
2009-02-18 22:14:47 +03:00
|
|
|
enable = true;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
|
|
|
if (w->x() + w->width() > rect.x() + rect.width() &&
|
|
|
|
(direction == Left || direction == Right)) {
|
|
|
|
data.quads = data.quads.splitAtX(rect.width() - w->x());
|
2009-02-18 22:14:47 +03:00
|
|
|
enable = true;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
|
|
|
if (w->y() < rect.y() &&
|
|
|
|
(direction == Upwards || direction == Downwards)) {
|
|
|
|
data.quads = data.quads.splitAtY(-w->y());
|
2009-02-18 22:14:47 +03:00
|
|
|
enable = true;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
|
|
|
if (w->y() + w->height() > rect.y() + rect.height() &&
|
|
|
|
(direction == Upwards || direction == Downwards)) {
|
|
|
|
data.quads = data.quads.splitAtY(rect.height() - w->y());
|
2009-02-18 22:14:47 +03:00
|
|
|
enable = true;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
|
|
|
if (enable) {
|
2009-02-18 22:14:47 +03:00
|
|
|
data.setTransformed();
|
|
|
|
data.setTranslucent();
|
2011-01-30 17:34:42 +03:00
|
|
|
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
|
|
|
|
} else
|
|
|
|
w->disablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
|
|
|
|
} else
|
|
|
|
w->disablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
|
2009-02-06 21:53:16 +03:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
effects->prePaintWindow(w, data, time);
|
|
|
|
}
|
2009-02-06 21:53:16 +03:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void CubeSlideEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
|
|
|
{
|
|
|
|
if (!slideRotations.empty() && cube_painting) {
|
|
|
|
if (dontSlidePanels && w->isDock())
|
2009-02-06 21:53:16 +03:00
|
|
|
return;
|
2011-01-30 17:34:42 +03:00
|
|
|
if (stickyWindows.contains(w))
|
2009-02-06 21:53:16 +03:00
|
|
|
return;
|
2009-02-18 22:14:47 +03:00
|
|
|
|
|
|
|
// filter out quads overlapping the edges
|
2011-01-30 17:34:42 +03:00
|
|
|
QRect rect = effects->clientArea(FullArea, effects->activeScreen(), painting_desktop);
|
|
|
|
if (w->isOnDesktop(painting_desktop)) {
|
|
|
|
if (w->x() < rect.x()) {
|
2009-02-18 22:14:47 +03:00
|
|
|
WindowQuadList new_quads;
|
2011-01-30 17:34:42 +03:00
|
|
|
foreach (const WindowQuad & quad, data.quads) {
|
|
|
|
if (quad.right() > -w->x()) {
|
|
|
|
new_quads.append(quad);
|
2009-02-18 22:14:47 +03:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
data.quads = new_quads;
|
|
|
|
}
|
|
|
|
if (w->x() + w->width() > rect.x() + rect.width()) {
|
2009-02-18 22:14:47 +03:00
|
|
|
WindowQuadList new_quads;
|
2011-01-30 17:34:42 +03:00
|
|
|
foreach (const WindowQuad & quad, data.quads) {
|
|
|
|
if (quad.right() <= rect.width() - w->x()) {
|
|
|
|
new_quads.append(quad);
|
2009-02-18 22:14:47 +03:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
data.quads = new_quads;
|
|
|
|
}
|
|
|
|
if (w->y() < rect.y()) {
|
2009-02-18 22:14:47 +03:00
|
|
|
WindowQuadList new_quads;
|
2011-01-30 17:34:42 +03:00
|
|
|
foreach (const WindowQuad & quad, data.quads) {
|
|
|
|
if (quad.bottom() > -w->y()) {
|
|
|
|
new_quads.append(quad);
|
2009-02-18 22:14:47 +03:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
data.quads = new_quads;
|
|
|
|
}
|
|
|
|
if (w->y() + w->height() > rect.y() + rect.height()) {
|
2009-02-18 22:14:47 +03:00
|
|
|
WindowQuadList new_quads;
|
2011-01-30 17:34:42 +03:00
|
|
|
foreach (const WindowQuad & quad, data.quads) {
|
|
|
|
if (quad.bottom() <= rect.height() - w->y()) {
|
|
|
|
new_quads.append(quad);
|
2009-02-18 22:14:47 +03:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
data.quads = new_quads;
|
2009-02-18 22:14:47 +03:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2009-02-18 22:14:47 +03:00
|
|
|
// paint windows overlapping edges from other desktop
|
2011-01-30 17:34:42 +03:00
|
|
|
if (w->isOnDesktop(other_desktop) && (mask & PAINT_WINDOW_TRANSFORMED)) {
|
2009-02-18 22:14:47 +03:00
|
|
|
RotationDirection direction = slideRotations.head();
|
2011-01-30 17:34:42 +03:00
|
|
|
if (w->x() < rect.x() &&
|
|
|
|
(direction == Left || direction == Right)) {
|
2009-02-18 22:14:47 +03:00
|
|
|
WindowQuadList new_quads;
|
2012-05-28 16:45:46 +04:00
|
|
|
data.setXTranslation(rect.width());
|
2011-01-30 17:34:42 +03:00
|
|
|
foreach (const WindowQuad & quad, data.quads) {
|
|
|
|
if (quad.right() <= -w->x()) {
|
|
|
|
new_quads.append(quad);
|
2009-02-18 22:14:47 +03:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
data.quads = new_quads;
|
|
|
|
}
|
|
|
|
if (w->x() + w->width() > rect.x() + rect.width() &&
|
|
|
|
(direction == Left || direction == Right)) {
|
2009-02-18 22:14:47 +03:00
|
|
|
WindowQuadList new_quads;
|
2012-05-28 16:45:46 +04:00
|
|
|
data.setXTranslation(-rect.width());
|
2011-01-30 17:34:42 +03:00
|
|
|
foreach (const WindowQuad & quad, data.quads) {
|
|
|
|
if (quad.right() > rect.width() - w->x()) {
|
|
|
|
new_quads.append(quad);
|
2009-02-18 22:14:47 +03:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
data.quads = new_quads;
|
|
|
|
}
|
|
|
|
if (w->y() < rect.y() &&
|
|
|
|
(direction == Upwards || direction == Downwards)) {
|
2009-02-18 22:14:47 +03:00
|
|
|
WindowQuadList new_quads;
|
2012-05-28 16:45:46 +04:00
|
|
|
data.setYTranslation(rect.height());
|
2011-01-30 17:34:42 +03:00
|
|
|
foreach (const WindowQuad & quad, data.quads) {
|
|
|
|
if (quad.bottom() <= -w->y()) {
|
|
|
|
new_quads.append(quad);
|
2009-02-18 22:14:47 +03:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
data.quads = new_quads;
|
|
|
|
}
|
|
|
|
if (w->y() + w->height() > rect.y() + rect.height() &&
|
|
|
|
(direction == Upwards || direction == Downwards)) {
|
2009-02-18 22:14:47 +03:00
|
|
|
WindowQuadList new_quads;
|
2012-05-28 16:45:46 +04:00
|
|
|
data.setYTranslation(-rect.height());
|
2011-01-30 17:34:42 +03:00
|
|
|
foreach (const WindowQuad & quad, data.quads) {
|
|
|
|
if (quad.bottom() > rect.height() - w->y()) {
|
|
|
|
new_quads.append(quad);
|
2009-02-18 22:14:47 +03:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
data.quads = new_quads;
|
|
|
|
}
|
|
|
|
if (firstDesktop)
|
2012-07-12 19:20:17 +04:00
|
|
|
data.multiplyOpacity(timeLine.currentValue());
|
2009-02-18 22:14:47 +03:00
|
|
|
else
|
2012-07-12 19:20:17 +04:00
|
|
|
data.multiplyOpacity((1.0 - timeLine.currentValue()));
|
2009-02-06 21:53:16 +03:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
effects->paintWindow(w, mask, region, data);
|
|
|
|
}
|
2009-02-06 21:53:16 +03:00
|
|
|
|
|
|
|
void CubeSlideEffect::postPaintScreen()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2009-02-06 21:53:16 +03:00
|
|
|
effects->postPaintScreen();
|
2011-01-30 17:34:42 +03:00
|
|
|
if (!slideRotations.empty()) {
|
2011-03-15 00:50:05 +03:00
|
|
|
if (timeLine.currentValue() == 1.0) {
|
2009-02-06 21:53:16 +03:00
|
|
|
RotationDirection direction = slideRotations.dequeue();
|
2011-01-30 17:34:42 +03:00
|
|
|
switch(direction) {
|
|
|
|
case Left:
|
|
|
|
if (usePagerLayout)
|
|
|
|
front_desktop = effects->desktopToLeft(front_desktop, true);
|
|
|
|
else {
|
|
|
|
front_desktop--;
|
|
|
|
if (front_desktop == 0)
|
|
|
|
front_desktop = effects->numberOfDesktops();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Right:
|
|
|
|
if (usePagerLayout)
|
|
|
|
front_desktop = effects->desktopToRight(front_desktop, true);
|
|
|
|
else {
|
|
|
|
front_desktop++;
|
|
|
|
if (front_desktop > effects->numberOfDesktops())
|
|
|
|
front_desktop = 1;
|
2009-02-06 21:53:16 +03:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
break;
|
|
|
|
case Upwards:
|
|
|
|
front_desktop = effects->desktopAbove(front_desktop, true);
|
|
|
|
break;
|
|
|
|
case Downwards:
|
|
|
|
front_desktop = effects->desktopBelow(front_desktop, true);
|
|
|
|
break;
|
|
|
|
}
|
2011-03-15 00:50:05 +03:00
|
|
|
timeLine.setCurrentTime(0);
|
2011-01-30 17:34:42 +03:00
|
|
|
if (slideRotations.count() == 1)
|
2011-03-15 00:50:05 +03:00
|
|
|
timeLine.setCurveShape(QTimeLine::EaseOutCurve);
|
2009-02-19 12:31:58 +03:00
|
|
|
else
|
2011-03-15 00:50:05 +03:00
|
|
|
timeLine.setCurveShape(QTimeLine::LinearCurve);
|
2011-01-30 17:34:42 +03:00
|
|
|
if (slideRotations.empty()) {
|
|
|
|
foreach (EffectWindow * w, panels)
|
|
|
|
w->setData(WindowForceBlurRole, QVariant(false));
|
|
|
|
foreach (EffectWindow * w, stickyWindows)
|
|
|
|
w->setData(WindowForceBlurRole, QVariant(false));
|
2010-06-13 11:36:40 +04:00
|
|
|
stickyWindows.clear();
|
|
|
|
panels.clear();
|
2011-01-30 17:34:42 +03:00
|
|
|
effects->setActiveFullScreenEffect(0);
|
2009-02-06 21:53:16 +03:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
effects->addRepaintFull();
|
2009-02-06 21:53:16 +03:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2009-02-06 21:53:16 +03:00
|
|
|
|
2011-02-25 22:41:10 +03:00
|
|
|
void CubeSlideEffect::slotDesktopChanged(int old, int current)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
|
|
|
if (effects->activeFullScreenEffect() && effects->activeFullScreenEffect() != this)
|
2009-02-06 21:53:16 +03:00
|
|
|
return;
|
2011-01-30 17:34:42 +03:00
|
|
|
if (old > effects->numberOfDesktops()) {
|
2009-06-15 00:31:08 +04:00
|
|
|
// number of desktops has been reduced -> no animation
|
|
|
|
return;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
|
|
|
if (windowMoving) {
|
2010-01-10 18:51:02 +03:00
|
|
|
desktopChangedWhileMoving = true;
|
|
|
|
progressRestriction = 1.0 - progressRestriction;
|
|
|
|
effects->addRepaintFull();
|
|
|
|
return;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2009-02-06 21:53:16 +03:00
|
|
|
bool activate = true;
|
2011-01-30 17:34:42 +03:00
|
|
|
if (!slideRotations.empty()) {
|
2009-02-06 21:53:16 +03:00
|
|
|
// last slide still in progress
|
|
|
|
activate = false;
|
|
|
|
RotationDirection direction = slideRotations.dequeue();
|
|
|
|
slideRotations.clear();
|
2011-01-30 17:34:42 +03:00
|
|
|
slideRotations.enqueue(direction);
|
|
|
|
switch(direction) {
|
|
|
|
case Left:
|
|
|
|
if (usePagerLayout)
|
|
|
|
old = effects->desktopToLeft(front_desktop, true);
|
|
|
|
else {
|
|
|
|
old = front_desktop - 1;
|
|
|
|
if (old == 0)
|
|
|
|
old = effects->numberOfDesktops();
|
2009-02-17 15:47:18 +03:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
break;
|
|
|
|
case Right:
|
|
|
|
if (usePagerLayout)
|
|
|
|
old = effects->desktopToRight(front_desktop, true);
|
|
|
|
else {
|
|
|
|
old = front_desktop + 1;
|
|
|
|
if (old > effects->numberOfDesktops())
|
|
|
|
old = 1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Upwards:
|
|
|
|
old = effects->desktopAbove(front_desktop, true);
|
|
|
|
break;
|
|
|
|
case Downwards:
|
|
|
|
old = effects->desktopBelow(front_desktop, true);
|
|
|
|
break;
|
2009-02-06 21:53:16 +03:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
|
|
|
if (usePagerLayout) {
|
2009-05-04 17:24:55 +04:00
|
|
|
// calculate distance in respect to pager
|
2011-01-30 17:34:42 +03:00
|
|
|
QPoint diff = effects->desktopGridCoords(effects->currentDesktop()) - effects->desktopGridCoords(old);
|
|
|
|
if (qAbs(diff.x()) > effects->desktopGridWidth() / 2) {
|
|
|
|
int sign = -1 * (diff.x() / qAbs(diff.x()));
|
|
|
|
diff.setX(sign *(effects->desktopGridWidth() - qAbs(diff.x())));
|
|
|
|
}
|
|
|
|
if (diff.x() > 0) {
|
|
|
|
for (int i = 0; i < diff.x(); i++) {
|
|
|
|
slideRotations.enqueue(Right);
|
2009-05-04 17:24:55 +04:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
} else if (diff.x() < 0) {
|
|
|
|
diff.setX(-diff.x());
|
|
|
|
for (int i = 0; i < diff.x(); i++) {
|
|
|
|
slideRotations.enqueue(Left);
|
2009-05-04 17:24:55 +04:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
|
|
|
if (qAbs(diff.y()) > effects->desktopGridHeight() / 2) {
|
|
|
|
int sign = -1 * (diff.y() / qAbs(diff.y()));
|
|
|
|
diff.setY(sign *(effects->desktopGridHeight() - qAbs(diff.y())));
|
|
|
|
}
|
|
|
|
if (diff.y() > 0) {
|
|
|
|
for (int i = 0; i < diff.y(); i++) {
|
|
|
|
slideRotations.enqueue(Downwards);
|
2009-05-04 17:24:55 +04:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
|
|
|
if (diff.y() < 0) {
|
|
|
|
diff.setY(-diff.y());
|
|
|
|
for (int i = 0; i < diff.y(); i++) {
|
|
|
|
slideRotations.enqueue(Upwards);
|
2009-02-06 21:53:16 +03:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
} else {
|
2009-05-04 17:24:55 +04:00
|
|
|
// ignore pager layout
|
2011-02-25 22:41:10 +03:00
|
|
|
int left = old - current;
|
2011-01-30 17:34:42 +03:00
|
|
|
if (left < 0)
|
2009-05-04 17:24:55 +04:00
|
|
|
left = effects->numberOfDesktops() + left;
|
2011-02-25 22:41:10 +03:00
|
|
|
int right = current - old;
|
2011-01-30 17:34:42 +03:00
|
|
|
if (right < 0)
|
2009-05-04 17:24:55 +04:00
|
|
|
right = effects->numberOfDesktops() + right;
|
2011-01-30 17:34:42 +03:00
|
|
|
if (left < right) {
|
|
|
|
for (int i = 0; i < left; i++) {
|
|
|
|
slideRotations.enqueue(Left);
|
2009-05-04 17:24:55 +04:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
} else {
|
|
|
|
for (int i = 0; i < right; i++) {
|
|
|
|
slideRotations.enqueue(Right);
|
2009-02-06 21:53:16 +03:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
|
|
|
timeLine.setDuration((float)rotationDuration / (float)slideRotations.count());
|
|
|
|
if (activate) {
|
|
|
|
if (slideRotations.count() == 1)
|
2011-03-15 00:50:05 +03:00
|
|
|
timeLine.setCurveShape(QTimeLine::EaseInOutCurve);
|
2009-02-19 12:31:58 +03:00
|
|
|
else
|
2011-03-15 00:50:05 +03:00
|
|
|
timeLine.setCurveShape(QTimeLine::EaseInCurve);
|
2011-01-30 17:34:42 +03:00
|
|
|
effects->setActiveFullScreenEffect(this);
|
2011-03-15 00:50:05 +03:00
|
|
|
timeLine.setCurrentTime(0);
|
2009-02-06 21:53:16 +03:00
|
|
|
front_desktop = old;
|
|
|
|
effects->addRepaintFull();
|
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2009-02-06 21:53:16 +03:00
|
|
|
|
2011-03-13 14:41:30 +03:00
|
|
|
void CubeSlideEffect::slotWindowStepUserMovedResized(EffectWindow* w)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
|
|
|
if (!useWindowMoving)
|
2010-01-10 18:51:02 +03:00
|
|
|
return;
|
2013-01-30 16:36:37 +04:00
|
|
|
if (!effects->kwinOption(SwitchDesktopOnScreenEdgeMovingWindows).toBool())
|
|
|
|
return;
|
2011-03-13 14:41:30 +03:00
|
|
|
if (w->isUserResize())
|
2010-01-10 18:51:02 +03:00
|
|
|
return;
|
2014-02-24 19:13:30 +04:00
|
|
|
const QSize screenSize = effects->virtualScreenSize();
|
2010-01-10 18:51:02 +03:00
|
|
|
const QPoint cursor = effects->cursorPos();
|
2014-02-24 19:13:30 +04:00
|
|
|
const int horizontal = screenSize.width() * 0.1;
|
|
|
|
const int vertical = screenSize.height() * 0.1;
|
|
|
|
const QRect leftRect(0, screenSize.height() * 0.1, horizontal, screenSize.height() * 0.8);
|
|
|
|
const QRect rightRect(screenSize.width() - horizontal, screenSize.height() * 0.1, horizontal, screenSize.height() * 0.8);
|
|
|
|
const QRect topRect(horizontal, 0, screenSize.width() * 0.8, vertical);
|
|
|
|
const QRect bottomRect(horizontal, screenSize.height() - vertical, screenSize.width() - horizontal * 2, vertical);
|
2011-01-30 17:34:42 +03:00
|
|
|
if (leftRect.contains(cursor)) {
|
|
|
|
if (effects->desktopToLeft(effects->currentDesktop()) != effects->currentDesktop())
|
|
|
|
windowMovingChanged(0.3 *(float)(horizontal - cursor.x()) / (float)horizontal, Left);
|
|
|
|
} else if (rightRect.contains(cursor)) {
|
|
|
|
if (effects->desktopToRight(effects->currentDesktop()) != effects->currentDesktop())
|
2014-02-24 19:13:30 +04:00
|
|
|
windowMovingChanged(0.3 *(float)(cursor.x() - screenSize.width() + horizontal) / (float)horizontal, Right);
|
2011-01-30 17:34:42 +03:00
|
|
|
} else if (topRect.contains(cursor)) {
|
|
|
|
if (effects->desktopAbove(effects->currentDesktop()) != effects->currentDesktop())
|
|
|
|
windowMovingChanged(0.3 *(float)(vertical - cursor.y()) / (float)vertical, Upwards);
|
|
|
|
} else if (bottomRect.contains(cursor)) {
|
|
|
|
if (effects->desktopBelow(effects->currentDesktop()) != effects->currentDesktop())
|
2014-02-24 19:13:30 +04:00
|
|
|
windowMovingChanged(0.3 *(float)(cursor.y() - screenSize.height() + vertical) / (float)vertical, Downwards);
|
2011-01-30 17:34:42 +03:00
|
|
|
} else {
|
2010-01-10 18:51:02 +03:00
|
|
|
// not in one of the areas
|
|
|
|
windowMoving = false;
|
|
|
|
desktopChangedWhileMoving = false;
|
2011-03-15 00:50:05 +03:00
|
|
|
timeLine.setCurrentTime(0);
|
2011-01-30 17:34:42 +03:00
|
|
|
if (!slideRotations.isEmpty())
|
2010-01-10 18:51:02 +03:00
|
|
|
slideRotations.clear();
|
2011-01-30 17:34:42 +03:00
|
|
|
effects->setActiveFullScreenEffect(0);
|
2010-01-10 18:51:02 +03:00
|
|
|
effects->addRepaintFull();
|
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-01-10 18:51:02 +03:00
|
|
|
|
2011-03-13 14:41:30 +03:00
|
|
|
void CubeSlideEffect::slotWindowFinishUserMovedResized(EffectWindow* w)
|
|
|
|
{
|
|
|
|
if (!useWindowMoving)
|
|
|
|
return;
|
2013-01-30 16:36:37 +04:00
|
|
|
if (!effects->kwinOption(SwitchDesktopOnScreenEdgeMovingWindows).toBool())
|
|
|
|
return;
|
2011-03-13 14:41:30 +03:00
|
|
|
if (w->isUserResize())
|
|
|
|
return;
|
|
|
|
if (!desktopChangedWhileMoving) {
|
|
|
|
if (slideRotations.isEmpty())
|
|
|
|
return;
|
|
|
|
const RotationDirection direction = slideRotations.dequeue();
|
|
|
|
switch(direction) {
|
|
|
|
case Left:
|
|
|
|
slideRotations.enqueue(Right);
|
|
|
|
break;
|
|
|
|
case Right:
|
|
|
|
slideRotations.enqueue(Left);
|
|
|
|
break;
|
|
|
|
case Upwards:
|
|
|
|
slideRotations.enqueue(Downwards);
|
|
|
|
break;
|
|
|
|
case Downwards:
|
|
|
|
slideRotations.enqueue(Upwards);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break; // impossible
|
|
|
|
}
|
2011-03-15 00:50:05 +03:00
|
|
|
timeLine.setCurrentTime(timeLine.duration() - timeLine.currentTime());
|
2011-03-13 14:41:30 +03:00
|
|
|
}
|
|
|
|
desktopChangedWhileMoving = false;
|
|
|
|
windowMoving = false;
|
|
|
|
effects->addRepaintFull();
|
|
|
|
}
|
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void CubeSlideEffect::windowMovingChanged(float progress, RotationDirection direction)
|
|
|
|
{
|
|
|
|
if (desktopChangedWhileMoving)
|
2010-01-10 18:51:02 +03:00
|
|
|
progressRestriction = 1.0 - progress;
|
|
|
|
else
|
|
|
|
progressRestriction = progress;
|
|
|
|
front_desktop = effects->currentDesktop();
|
2011-01-30 17:34:42 +03:00
|
|
|
if (slideRotations.isEmpty()) {
|
|
|
|
slideRotations.enqueue(direction);
|
2011-03-15 00:50:05 +03:00
|
|
|
timeLine.setCurveShape(QTimeLine::EaseInOutCurve);
|
2010-01-10 18:51:02 +03:00
|
|
|
windowMoving = true;
|
2011-01-30 17:34:42 +03:00
|
|
|
effects->setActiveFullScreenEffect(this);
|
2010-01-10 18:51:02 +03:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
effects->addRepaintFull();
|
|
|
|
}
|
2010-01-10 18:51:02 +03:00
|
|
|
|
2011-08-27 13:21:31 +04:00
|
|
|
bool CubeSlideEffect::isActive() const
|
|
|
|
{
|
|
|
|
return !slideRotations.isEmpty();
|
|
|
|
}
|
|
|
|
|
2009-02-06 21:53:16 +03:00
|
|
|
} // namespace
|