Implement desktopSwitching() interface for realtime animations

Added this interface to the VirtualDesktopManager. Realtime touchpad gestures update the interface to allow for mac os style desktop switching.
This commit is contained in:
Eric Edlund 2022-03-16 15:42:42 -04:00
parent ddaa2a3784
commit c7c1ac78ea
7 changed files with 151 additions and 3 deletions

View file

@ -35,8 +35,16 @@ void InputRedirection::registerAxisShortcut(Qt::KeyboardModifiers modifiers, Poi
void InputRedirection::registerTouchpadSwipeShortcut(SwipeDirection, uint fingerCount, QAction*)
{
Q_UNUSED(fingerCount)
}
void InputRedirection::registerRealtimeTouchpadSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action, std::function<void(qreal)> cb)
{
Q_UNUSED(direction)
Q_UNUSED(fingerCount)
Q_UNUSED(action)
Q_UNUSED(cb)
}
}
Q_DECLARE_METATYPE(Qt::Orientation)

View file

@ -155,6 +155,16 @@ EffectsHandlerImpl::EffectsHandlerImpl(Compositor *compositor, Scene *scene)
}
}
);
connect(ws, &Workspace::currentDesktopChanging, this,
[this](uint currentDesktop, QPointF offset, KWin::AbstractClient* c){
Q_EMIT desktopChanging(currentDesktop, offset, c ? c->effectWindow() : nullptr);
}
);
connect(ws, &Workspace::currentDesktopChangingCancelled, this,
[this](){
Q_EMIT desktopChangingCancelled();
}
);
connect(ws, &Workspace::desktopPresenceChanged, this,
[this](AbstractClient *c, int old) {
if (!c->effectWindow()) {

View file

@ -1468,6 +1468,17 @@ Q_SIGNALS:
* @since 4.9
*/
void desktopChanged(int oldDesktop, int newDesktop, KWin::EffectWindow *with);
/**
* Signal emmitted while desktop is changing for animation.
* @param currentDesktop The current desktop untiotherwise.
* @param offset The current desktop offset.
* offset.x() = .6 means 60% of the way to the desktop to the right.
* Positive Values means Up and Right.
*/
void desktopChanging(uint currentDesktop, QPointF offset, KWin::EffectWindow *with);
void desktopChangingCancelled();
/**
* @since 4.7
* @deprecated

View file

@ -22,9 +22,11 @@
#include <algorithm>
#include <QDebug>
namespace KWin {
static bool s_loadingDesktopSettings = false;
static const double GESTURE_SWITCH_THRESHOLD = .25;
static QString generateDesktopId()
{
@ -535,7 +537,7 @@ VirtualDesktop *VirtualDesktopManager::currentDesktop() const
bool VirtualDesktopManager::setCurrent(uint newDesktop)
{
if (newDesktop < 1 || newDesktop > count() || newDesktop == current()) {
if (newDesktop < 1 || newDesktop > count()) {
return false;
}
auto d = desktopForX11Id(newDesktop);
@ -800,9 +802,11 @@ void VirtualDesktopManager::initShortcuts()
initSwitchToShortcuts();
QAction *nextAction = addAction(QStringLiteral("Switch to Next Desktop"), i18n("Switch to Next Desktop"), &VirtualDesktopManager::slotNext);
input()->registerTouchpadSwipeShortcut(SwipeDirection::Right, 4, nextAction);
QAction *previousAction = addAction(QStringLiteral("Switch to Previous Desktop"), i18n("Switch to Previous Desktop"), &VirtualDesktopManager::slotPrevious);
input()->registerTouchpadSwipeShortcut(SwipeDirection::Left, 4, previousAction);
Q_UNUSED(nextAction)
Q_UNUSED(previousAction)
//shortcuts
QAction *slotRightAction = addAction(QStringLiteral("Switch One Desktop to the Right"), i18n("Switch One Desktop to the Right"), &VirtualDesktopManager::slotRight);
KGlobalAccel::setGlobalShortcut(slotRightAction, QKeySequence(Qt::CTRL | Qt::META | Qt::Key_Right));
QAction *slotLeftAction = addAction(QStringLiteral("Switch One Desktop to the Left"), i18n("Switch One Desktop to the Left"), &VirtualDesktopManager::slotLeft);
@ -812,6 +816,39 @@ void VirtualDesktopManager::initShortcuts()
QAction *slotDownAction = addAction(QStringLiteral("Switch One Desktop Down"), i18n("Switch One Desktop Down"), &VirtualDesktopManager::slotDown);
KGlobalAccel::setGlobalShortcut(slotDownAction, QKeySequence(Qt::CTRL | Qt::META | Qt::Key_Down));
// Gestures
// These connections decide which desktop to end on after gesture ends
connect(m_swipeGestureReleasedRight, &QAction::triggered, this, &VirtualDesktopManager::gestureReleasedRight);
connect(m_swipeGestureReleasedLeft, &QAction::triggered, this, &VirtualDesktopManager::gestureReleasedLeft);
connect(m_swipeGestureReleasedUp, &QAction::triggered, this, &VirtualDesktopManager::gestureReleasedUp);
connect(m_swipeGestureReleasedDown, &QAction::triggered, this, &VirtualDesktopManager::gestureReleasedDown);
//These take the live feedback from a gesture
input()->registerRealtimeTouchpadSwipeShortcut(SwipeDirection::Right, 3, m_swipeGestureReleasedRight, [this](qreal cb) {
m_currentDesktopOffset.setX(cb);
Q_EMIT currentChanging(current(), m_currentDesktopOffset);
});
input()->registerRealtimeTouchpadSwipeShortcut(SwipeDirection::Left, 3, m_swipeGestureReleasedLeft, [this](qreal cb) {
m_currentDesktopOffset.setX(-cb);
Q_EMIT currentChanging(current(), m_currentDesktopOffset);
});
input()->registerRealtimeTouchpadSwipeShortcut(SwipeDirection::Right, 4, m_swipeGestureReleasedRight, [this](qreal cb) {
m_currentDesktopOffset.setX(cb);
Q_EMIT currentChanging(current(), m_currentDesktopOffset);
});
input()->registerRealtimeTouchpadSwipeShortcut(SwipeDirection::Left, 4, m_swipeGestureReleasedLeft, [this](qreal cb) {
m_currentDesktopOffset.setX(-cb);
Q_EMIT currentChanging(current(), m_currentDesktopOffset);
});
input()->registerRealtimeTouchpadSwipeShortcut(SwipeDirection::Up, 3, m_swipeGestureReleasedUp, [this](qreal cb) {
m_currentDesktopOffset.setY(-cb);
Q_EMIT currentChanging(current(), m_currentDesktopOffset);
});
input()->registerRealtimeTouchpadSwipeShortcut(SwipeDirection::Down, 3, m_swipeGestureReleasedDown, [this](qreal cb) {
m_currentDesktopOffset.setY(cb);
Q_EMIT currentChanging(current(), m_currentDesktopOffset);
});
// axis events
input()->registerAxisShortcut(Qt::ControlModifier | Qt::AltModifier, PointerAxisDown,
findChild<QAction*>(QStringLiteral("Switch to Next Desktop")));
@ -819,6 +856,44 @@ void VirtualDesktopManager::initShortcuts()
findChild<QAction*>(QStringLiteral("Switch to Previous Desktop")));
}
void VirtualDesktopManager::gestureReleasedUp()
{
if (m_currentDesktopOffset.y() <= -GESTURE_SWITCH_THRESHOLD) {
slotUp();
} else {
Q_EMIT currentChangingCancelled();
}
m_currentDesktopOffset = QPointF(0, 0);
}
void VirtualDesktopManager::gestureReleasedDown()
{
if (m_currentDesktopOffset.y() >= GESTURE_SWITCH_THRESHOLD) {
slotDown();
} else {
Q_EMIT currentChangingCancelled();
}
m_currentDesktopOffset = QPointF(0, 0);
}
void VirtualDesktopManager::gestureReleasedLeft()
{
if (m_currentDesktopOffset.x() <= -GESTURE_SWITCH_THRESHOLD) {
slotLeft();
} else {
Q_EMIT currentChangingCancelled();
}
m_currentDesktopOffset = QPointF(0, 0);
}
void VirtualDesktopManager::gestureReleasedRight()
{
if (m_currentDesktopOffset.x() >= GESTURE_SWITCH_THRESHOLD) {
slotRight();
} else {
setCurrent(current());
Q_EMIT currentChangingCancelled();
}
m_currentDesktopOffset = QPointF(0, 0);
}
void VirtualDesktopManager::initSwitchToShortcuts()
{
const QString toDesktop = QStringLiteral("Switch to Desktop %1");

View file

@ -16,6 +16,7 @@
#include <QPoint>
#include <QPointer>
#include <QSize>
#include <QAction>
// KDE includes
#include <KConfig>
@ -24,6 +25,7 @@
class KLocalizedString;
class NETRootInfo;
class QAction;
class Options;
namespace KWaylandServer
{
@ -390,6 +392,17 @@ Q_SIGNALS:
* @param newDesktop The virtual desktop changed to
*/
void currentChanged(uint previousDesktop, uint newDesktop);
/**
* Signal emmitted for realtime desktop switching animations.
* @param currentDesktop The current virtual desktop
* @param offset The current total change in desktop coordinate
* Offset x and y are negative if switching Left and Down.
* Example: x = 0.6 means 60% of the way to the desktop to the right.
*/
void currentChanging(uint currentDesktop, QPointF offset);
void currentChangingCancelled();
/**
* Signal emitted whenever the desktop layout changes.
* @param columns The new number of columns in the layout
@ -433,6 +446,14 @@ private Q_SLOTS:
*/
void slotDown();
/* For gestured desktopSwitching
* Called when gesture ended, the thing that actually switches the desktop.
*/
void gestureReleasedUp();
void gestureReleasedDown();
void gestureReleasedLeft();
void gestureReleasedRight();
private:
/**
* Generate a desktop layout from EWMH _NET_DESKTOP_LAYOUT property parameters.
@ -477,6 +498,12 @@ private:
KWaylandServer::PlasmaVirtualDesktopManagementInterface *m_virtualDesktopManagement = nullptr;
KSharedConfig::Ptr m_config;
QAction *m_swipeGestureReleasedUp = new QAction();
QAction *m_swipeGestureReleasedDown = new QAction();
QAction *m_swipeGestureReleasedLeft = new QAction();
QAction *m_swipeGestureReleasedRight = new QAction();
QPointF m_currentDesktopOffset = QPointF(0, 0);
KWIN_SINGLETON_VARIABLE(VirtualDesktopManager, s_manager)
};

View file

@ -236,6 +236,8 @@ void Workspace::init()
connect(vds, &VirtualDesktopManager::desktopCreated, this, &Workspace::slotDesktopAdded);
connect(vds, &VirtualDesktopManager::desktopRemoved, this, &Workspace::slotDesktopRemoved);
connect(vds, &VirtualDesktopManager::currentChanged, this, &Workspace::slotCurrentDesktopChanged);
connect(vds, &VirtualDesktopManager::currentChanging, this, &Workspace::slotCurrentDesktopChanging);
connect(vds, &VirtualDesktopManager::currentChangingCancelled, this, &Workspace::slotCurrentDesktopChangingCancelled);
vds->setNavigationWrappingAround(options->isRollOverDesktops());
connect(options, &Options::rollOverDesktopsChanged, vds, &VirtualDesktopManager::setNavigationWrappingAround);
vds->setConfig(config);
@ -1022,6 +1024,17 @@ void Workspace::slotCurrentDesktopChanged(uint oldDesktop, uint newDesktop)
Q_EMIT currentDesktopChanged(oldDesktop, movingClient);
}
void Workspace::slotCurrentDesktopChanging(uint currentDesktop, QPointF offset)
{
closeActivePopup();
Q_EMIT currentDesktopChanging(currentDesktop, offset, movingClient);
}
void Workspace::slotCurrentDesktopChangingCancelled()
{
Q_EMIT currentDesktopChangingCancelled();
}
void Workspace::updateClientVisibilityOnDesktopChange(VirtualDesktop *newDesktop)
{
for (auto it = stacking_order.constBegin();

View file

@ -491,6 +491,8 @@ private Q_SLOTS:
void updateCurrentActivity(const QString &new_activity);
// virtual desktop handling
void slotCurrentDesktopChanged(uint oldDesktop, uint newDesktop);
void slotCurrentDesktopChanging(uint currentDesktop, QPointF delta);
void slotCurrentDesktopChangingCancelled();
void slotDesktopAdded(VirtualDesktop *desktop);
void slotDesktopRemoved(VirtualDesktop *desktop);
void slotOutputEnabled(AbstractOutput *output);
@ -508,6 +510,8 @@ Q_SIGNALS:
void desktopPresenceChanged(KWin::AbstractClient*, int);
void currentActivityChanged();
void currentDesktopChanged(int, KWin::AbstractClient*);
void currentDesktopChanging(uint currentDesktop, QPointF delta, KWin::AbstractClient*);//for realtime animations
void currentDesktopChangingCancelled();
void clientAdded(KWin::AbstractClient *);
void clientRemoved(KWin::AbstractClient*);
void clientActivated(KWin::AbstractClient*);