effects/desktopgrid: port to realtime gestures
This ports the Desktop Grid effect to realtime gestures, both to have the end-user result, and to demonstrate how effects can have realtime gestures.
This commit is contained in:
parent
6231699ac1
commit
0042d2d8c1
2 changed files with 136 additions and 78 deletions
|
@ -5,6 +5,7 @@
|
|||
SPDX-FileCopyrightText: 2007 Lubos Lunak <l.lunak@kde.org>
|
||||
SPDX-FileCopyrightText: 2008 Lucas Murray <lmurray@undefinedfire.com>
|
||||
SPDX-FileCopyrightText: 2009 Martin Gräßlin <mgraesslin@kde.org>
|
||||
SPDX-FileCopyrightText: 2021 Carson Black <uhhadd@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
@ -58,19 +59,60 @@ DesktopGridEffect::DesktopGridEffect()
|
|||
, scaledSize()
|
||||
, scaledOffset()
|
||||
, m_proxy(nullptr)
|
||||
, m_activateAction(new QAction(this))
|
||||
, m_gestureAction(new QAction(this))
|
||||
, m_shortcutAction(new QAction(this))
|
||||
{
|
||||
initConfig<DesktopGridConfig>();
|
||||
// Load shortcuts
|
||||
QAction* a = m_activateAction;
|
||||
a->setObjectName(QStringLiteral("ShowDesktopGrid"));
|
||||
a->setText(i18n("Show Desktop Grid"));
|
||||
KGlobalAccel::self()->setDefaultShortcut(a, QList<QKeySequence>() << Qt::CTRL + Qt::Key_F8);
|
||||
KGlobalAccel::self()->setShortcut(a, QList<QKeySequence>() << Qt::CTRL + Qt::Key_F8);
|
||||
shortcut = KGlobalAccel::self()->shortcut(a);
|
||||
effects->registerGlobalShortcut(Qt::CTRL + Qt::Key_F8, a);
|
||||
effects->registerTouchpadSwipeShortcut(SwipeDirection::Up, a);
|
||||
connect(a, &QAction::triggered, this, &DesktopGridEffect::toggle);
|
||||
|
||||
// First we set up the gestures...
|
||||
QAction* a = m_gestureAction;
|
||||
|
||||
connect(a, &QAction::triggered, this, [this]() {
|
||||
if ((qreal(timeline.currentTime()) / qreal(timeline.duration())) > 0.5) {
|
||||
activated = true;
|
||||
timeline.setDirection(QTimeLine::Forward);
|
||||
timelineRunning = true;
|
||||
} else {
|
||||
activated = false;
|
||||
timeline.setDirection(QTimeLine::Backward);
|
||||
timelineRunning = true;
|
||||
}
|
||||
});
|
||||
effects->registerRealtimeTouchpadSwipeShortcut(SwipeDirection::Up, a, [this](qreal cb) {
|
||||
if (activated) return;
|
||||
|
||||
if (timeline.currentValue() == 0) {
|
||||
activated = true;
|
||||
setup();
|
||||
activated = false;
|
||||
}
|
||||
|
||||
timeline.setDirection(QTimeLine::Forward);
|
||||
timeline.setCurrentTime(timeline.duration() * cb);
|
||||
effects->addRepaintFull();
|
||||
});
|
||||
connect(&timeline, &QTimeLine::frameChanged, this, []() {
|
||||
effects->addRepaintFull();
|
||||
});
|
||||
connect(&timeline, &QTimeLine::finished, this, [this]() {
|
||||
timelineRunning = false;
|
||||
if (timeline.currentTime() == 0) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
// Now we set up the shortcut
|
||||
QAction* s = m_shortcutAction;
|
||||
s->setObjectName(QStringLiteral("ShowDesktopGrid"));
|
||||
s->setText(i18n("Show Desktop Grid"));
|
||||
|
||||
KGlobalAccel::self()->setDefaultShortcut(s, QList<QKeySequence>() << Qt::CTRL + Qt::Key_F8);
|
||||
KGlobalAccel::self()->setShortcut(s, QList<QKeySequence>() << Qt::CTRL + Qt::Key_F8);
|
||||
shortcut = KGlobalAccel::self()->shortcut(s);
|
||||
effects->registerGlobalShortcut(Qt::CTRL + Qt::Key_F8, s);
|
||||
|
||||
connect(s, &QAction::triggered, this, &DesktopGridEffect::toggle);
|
||||
|
||||
connect(KGlobalAccel::self(), &KGlobalAccel::globalShortcutChanged, this, &DesktopGridEffect::globalShortcutChanged);
|
||||
connect(effects, &EffectsHandler::windowAdded, this, &DesktopGridEffect::slotWindowAdded);
|
||||
connect(effects, &EffectsHandler::windowClosed, this, &DesktopGridEffect::slotWindowClosed);
|
||||
|
@ -80,7 +122,7 @@ DesktopGridEffect::DesktopGridEffect()
|
|||
connect(effects, &EffectsHandler::numberScreensChanged, this, &DesktopGridEffect::setup);
|
||||
|
||||
connect(effects, &EffectsHandler::screenAboutToLock, this, [this]() {
|
||||
setActive(false);
|
||||
deactivate();
|
||||
windowMoveElevateTimer->stop();
|
||||
if (keyboardGrab) {
|
||||
effects->ungrabKeyboard();
|
||||
|
@ -130,14 +172,14 @@ void DesktopGridEffect::reconfigure(ReconfigureFlags)
|
|||
// deactivate and activate all touch border
|
||||
const QVector<ElectricBorder> relevantBorders{ElectricLeft, ElectricTop, ElectricRight, ElectricBottom};
|
||||
for (auto e : relevantBorders) {
|
||||
effects->unregisterTouchBorder(e, m_activateAction);
|
||||
effects->unregisterTouchBorder(e, m_shortcutAction);
|
||||
}
|
||||
const auto touchBorders = DesktopGridConfig::touchBorderActivate();
|
||||
for (int i : touchBorders) {
|
||||
if (!relevantBorders.contains(ElectricBorder(i))) {
|
||||
continue;
|
||||
}
|
||||
effects->registerTouchBorder(ElectricBorder(i), m_activateAction);
|
||||
effects->registerTouchBorder(ElectricBorder(i), m_shortcutAction);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,29 +196,37 @@ void DesktopGridEffect::prePaintScreen(ScreenPrePaintData& data, std::chrono::mi
|
|||
time = 1;
|
||||
}
|
||||
lastPresentTime = presentTime;
|
||||
if (timelineRunning) {
|
||||
timeline.setCurrentTime(timeline.currentTime() + (timeline.direction() == QTimeLine::Forward ? time : -time));
|
||||
|
||||
if ((timeline.currentTime() <= 0 && timeline.direction() == QTimeLine::Backward)) {
|
||||
timelineRunning = false;
|
||||
// defer until the event loop to finish
|
||||
QTimer::singleShot(0, [this]() {
|
||||
finish();
|
||||
});
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < effects->numberOfDesktops(); i++) {
|
||||
auto item = hoverTimeline[i];
|
||||
|
||||
if (i == highlightedDesktop-1) { // if this is the highlighted desktop, we want to progress the animation from "not highlighted" to "highlight"
|
||||
item->setCurrentTime(item->currentTime() + time);
|
||||
} else { // otherwise we progress from "highlighted" to "not highlighted"
|
||||
item->setCurrentTime(item->currentTime() - time);
|
||||
}
|
||||
}
|
||||
|
||||
if (timeline.currentValue() != 0 || activated || (isUsingPresentWindows() && isMotionManagerMovingWindows())) {
|
||||
if (activated)
|
||||
timeline.setCurrentTime(timeline.currentTime() + time);
|
||||
else
|
||||
timeline.setCurrentTime(timeline.currentTime() - time);
|
||||
for (int i = 0; i < effects->numberOfDesktops(); i++) {
|
||||
if (i == highlightedDesktop - 1)
|
||||
hoverTimeline[i]->setCurrentTime(hoverTimeline[i]->currentTime() + time);
|
||||
else
|
||||
hoverTimeline[i]->setCurrentTime(hoverTimeline[i]->currentTime() - time);
|
||||
}
|
||||
if (isUsingPresentWindows()) {
|
||||
QList<WindowMotionManager>::iterator i;
|
||||
for (i = m_managers.begin(); i != m_managers.end(); ++i)
|
||||
(*i).calculate(time);
|
||||
(*i).calculate(timeline.currentTime());
|
||||
}
|
||||
// PAINT_SCREEN_BACKGROUND_FIRST is needed because screen will be actually painted more than once,
|
||||
// so with normal screen painting second screen paint would erase parts of the first paint
|
||||
if (timeline.currentValue() != 0 || (isUsingPresentWindows() && isMotionManagerMovingWindows()))
|
||||
data.mask |= PAINT_SCREEN_TRANSFORMED | PAINT_SCREEN_BACKGROUND_FIRST;
|
||||
if (!activated && timeline.currentValue() == 0 && !(isUsingPresentWindows() && isMotionManagerMovingWindows()))
|
||||
finish();
|
||||
}
|
||||
|
||||
const EffectWindowList windows = effects->stackingOrder();
|
||||
|
@ -617,7 +667,7 @@ void DesktopGridEffect::windowInputMouseEvent(QEvent* e)
|
|||
if (desk > effects->numberOfDesktops())
|
||||
return; // don't quit when missing desktop
|
||||
setCurrentDesktop(desk);
|
||||
setActive(false);
|
||||
deactivate();
|
||||
}
|
||||
if (windowMove) {
|
||||
if (wasWindowMove && isUsingPresentWindows()) {
|
||||
|
@ -644,6 +694,28 @@ void DesktopGridEffect::windowInputMouseEvent(QEvent* e)
|
|||
}
|
||||
}
|
||||
|
||||
void DesktopGridEffect::activate()
|
||||
{
|
||||
activated = true;
|
||||
setup();
|
||||
timeline.setDirection(QTimeLine::Forward);
|
||||
timelineRunning = true;
|
||||
// timeline.resume();
|
||||
}
|
||||
|
||||
void DesktopGridEffect::deactivate()
|
||||
{
|
||||
activated = false;
|
||||
timeline.setDirection(QTimeLine::Backward);
|
||||
timelineRunning = true;
|
||||
// timeline.resume();
|
||||
}
|
||||
|
||||
void DesktopGridEffect::toggle()
|
||||
{
|
||||
if (activated) deactivate(); else activate();
|
||||
}
|
||||
|
||||
void DesktopGridEffect::grabbedKeyboardEvent(QKeyEvent* e)
|
||||
{
|
||||
if (timeline.currentValue() != 1) // Block user input during animations
|
||||
|
@ -654,7 +726,7 @@ void DesktopGridEffect::grabbedKeyboardEvent(QKeyEvent* e)
|
|||
// check for global shortcuts
|
||||
// HACK: keyboard grab disables the global shortcuts so we have to check for global shortcut (bug 156155)
|
||||
if (shortcut.contains(e->key() + e->modifiers())) {
|
||||
toggle();
|
||||
deactivate();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -668,7 +740,7 @@ void DesktopGridEffect::grabbedKeyboardEvent(QKeyEvent* e)
|
|||
if (desktop <= effects->numberOfDesktops()) {
|
||||
setHighlightedDesktop(desktop);
|
||||
setCurrentDesktop(desktop);
|
||||
setActive(false);
|
||||
deactivate();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -687,13 +759,13 @@ void DesktopGridEffect::grabbedKeyboardEvent(QKeyEvent* e)
|
|||
setHighlightedDesktop(desktopDown(highlightedDesktop, !e->isAutoRepeat()));
|
||||
break;
|
||||
case Qt::Key_Escape:
|
||||
setActive(false);
|
||||
deactivate();
|
||||
return;
|
||||
case Qt::Key_Enter:
|
||||
case Qt::Key_Return:
|
||||
case Qt::Key_Space:
|
||||
setCurrentDesktop(highlightedDesktop);
|
||||
setActive(false);
|
||||
deactivate();
|
||||
return;
|
||||
case Qt::Key_Plus:
|
||||
slotAddDesktop();
|
||||
|
@ -713,7 +785,7 @@ bool DesktopGridEffect::borderActivated(ElectricBorder border)
|
|||
return false;
|
||||
if (effects->activeFullScreenEffect() && effects->activeFullScreenEffect() != this)
|
||||
return true;
|
||||
toggle();
|
||||
// toggle();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -989,48 +1061,6 @@ int DesktopGridEffect::desktopDown(int desktop, bool wrap) const
|
|||
//-----------------------------------------------------------------------------
|
||||
// Activation
|
||||
|
||||
void DesktopGridEffect::toggle()
|
||||
{
|
||||
setActive(!activated);
|
||||
}
|
||||
|
||||
void DesktopGridEffect::setActive(bool active)
|
||||
{
|
||||
if (effects->activeFullScreenEffect() && effects->activeFullScreenEffect() != this)
|
||||
return; // Only one fullscreen effect at a time thanks
|
||||
if (active && isMotionManagerMovingWindows())
|
||||
return; // Still moving windows from last usage - don't activate
|
||||
if (activated == active)
|
||||
return; // Already in that state
|
||||
|
||||
activated = active;
|
||||
if (activated) {
|
||||
effects->setShowingDesktop(false);
|
||||
if (timeline.currentValue() == 0)
|
||||
setup();
|
||||
} else {
|
||||
if (isUsingPresentWindows()) {
|
||||
QList<WindowMotionManager>::iterator it;
|
||||
for (it = m_managers.begin(); it != m_managers.end(); ++it) {
|
||||
Q_FOREACH (EffectWindow * w, (*it).managedWindows()) {
|
||||
(*it).moveWindow(w, w->frameGeometry());
|
||||
}
|
||||
}
|
||||
}
|
||||
QTimer::singleShot(zoomDuration + 1, this,
|
||||
[this] {
|
||||
if (activated)
|
||||
return;
|
||||
for (EffectQuickScene *view : qAsConst(m_desktopButtons)) {
|
||||
view->hide();
|
||||
}
|
||||
}
|
||||
);
|
||||
setHighlightedDesktop(effects->currentDesktop()); // Ensure selected desktop is highlighted
|
||||
}
|
||||
effects->addRepaintFull();
|
||||
}
|
||||
|
||||
void DesktopGridEffect::setup()
|
||||
{
|
||||
if (!isActive())
|
||||
|
@ -1193,6 +1223,25 @@ void DesktopGridEffect::finish()
|
|||
desktopNames.clear();
|
||||
}
|
||||
|
||||
if (isUsingPresentWindows()) {
|
||||
QList<WindowMotionManager>::iterator it;
|
||||
for (it = m_managers.begin(); it != m_managers.end(); ++it) {
|
||||
Q_FOREACH (EffectWindow * w, (*it).managedWindows()) {
|
||||
(*it).moveWindow(w, w->frameGeometry());
|
||||
}
|
||||
}
|
||||
}
|
||||
QTimer::singleShot(zoomDuration + 1, this,
|
||||
[this] {
|
||||
if (activated)
|
||||
return;
|
||||
for (EffectQuickScene *view : qAsConst(m_desktopButtons)) {
|
||||
view->hide();
|
||||
}
|
||||
}
|
||||
);
|
||||
setHighlightedDesktop(effects->currentDesktop()); // Ensure selected desktop is highlighted
|
||||
|
||||
windowMoveElevateTimer->stop();
|
||||
|
||||
if (keyboardGrab)
|
||||
|
@ -1208,6 +1257,8 @@ void DesktopGridEffect::finish()
|
|||
}
|
||||
m_proxy = nullptr;
|
||||
}
|
||||
|
||||
effects->addRepaintFull();
|
||||
}
|
||||
|
||||
void DesktopGridEffect::globalShortcutChanged(QAction *action, const QKeySequence& seq)
|
||||
|
|
|
@ -83,7 +83,6 @@ public:
|
|||
return clickBehavior == SwitchDesktopAndActivateWindow;
|
||||
}
|
||||
private Q_SLOTS:
|
||||
void toggle();
|
||||
// slots for global shortcut changed
|
||||
// needed to toggle the effect
|
||||
void globalShortcutChanged(QAction *action, const QKeySequence& seq);
|
||||
|
@ -106,7 +105,9 @@ private:
|
|||
int desktopToLeft(int desktop, bool wrap = true) const;
|
||||
int desktopUp(int desktop, bool wrap = true) const;
|
||||
int desktopDown(int desktop, bool wrap = true) const;
|
||||
void setActive(bool active);
|
||||
void deactivate();
|
||||
void activate();
|
||||
void toggle();
|
||||
void setup();
|
||||
void setupGrid();
|
||||
void finish();
|
||||
|
@ -127,7 +128,12 @@ private:
|
|||
int clickBehavior;
|
||||
|
||||
bool activated;
|
||||
|
||||
QTimeLine timeline;
|
||||
// used to indicate whether or not the prepaint thingy should drive the
|
||||
// animation.
|
||||
bool timelineRunning = false;
|
||||
|
||||
int paintingDesktop;
|
||||
int highlightedDesktop;
|
||||
int sourceDesktop;
|
||||
|
@ -164,7 +170,8 @@ private:
|
|||
|
||||
QVector<EffectQuickScene*> m_desktopButtons;
|
||||
|
||||
QAction *m_activateAction;
|
||||
QAction *m_gestureAction;
|
||||
QAction *m_shortcutAction;
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue