mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +00:00
swipearea: Add support for touchpad
This adds support for touchpad scrolling in various shell components, such as the lockscreen, homescreen and action drawer. Currently TODO because it appears to be very buggy when there is a control underneath that also accepts touchpad input (ex. flickable). The touchpad scroll start appears to get called by Qt, but not the end event, so I am unable to "let go" of the flick. Not sure if it's a wayland issue. This also appears to not work in the nested KWin session, not sure if it's because of libinput or something
This commit is contained in:
parent
cf915cae4a
commit
3adcd1d51c
6 changed files with 110 additions and 16 deletions
|
|
@ -216,6 +216,52 @@ void SwipeArea::touchUngrabEvent()
|
|||
QQuickItem::touchUngrabEvent();
|
||||
}
|
||||
|
||||
void SwipeArea::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
if (!m_interactive) {
|
||||
QQuickItem::wheelEvent(event);
|
||||
return;
|
||||
}
|
||||
|
||||
event->setAccepted(false);
|
||||
|
||||
switch (event->phase()) {
|
||||
case Qt::ScrollBegin:
|
||||
if (!m_touchpadScrolling) {
|
||||
event->accept();
|
||||
|
||||
m_touchpadScrolling = true;
|
||||
m_totalScrollDelta = QPointF{0, 0};
|
||||
Q_EMIT touchpadScrollStarted(event->points().first().position());
|
||||
}
|
||||
break;
|
||||
case Qt::ScrollEnd:
|
||||
if (m_touchpadScrolling) {
|
||||
m_touchpadScrolling = false;
|
||||
m_totalScrollDelta = QPointF{0, 0};
|
||||
Q_EMIT touchpadScrollEnded();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// HACK: if it isn't the touchpad, we never get the isBeginEvent() and isEndEvent() events
|
||||
if (!m_touchpadScrolling) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto &point : event->points()) {
|
||||
event->addPassiveGrabber(point, this);
|
||||
}
|
||||
|
||||
auto pixelDelta = event->pixelDelta();
|
||||
m_totalScrollDelta = QPointF{m_totalScrollDelta + pixelDelta};
|
||||
Q_EMIT touchpadScrollMove(m_totalScrollDelta.x(), m_totalScrollDelta.y(), pixelDelta.x(), pixelDelta.y());
|
||||
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void SwipeArea::setMoving(bool moving)
|
||||
{
|
||||
m_moving = moving;
|
||||
|
|
@ -242,6 +288,8 @@ void SwipeArea::resetSwipe()
|
|||
|
||||
void SwipeArea::handlePressEvent(QPointerEvent *event, QPointF point)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
|
||||
// ignore more touch events
|
||||
if (m_pressed) {
|
||||
return;
|
||||
|
|
@ -255,6 +303,9 @@ void SwipeArea::handlePressEvent(QPointerEvent *event, QPointF point)
|
|||
|
||||
void SwipeArea::handleReleaseEvent(QPointerEvent *event, QPointF point)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
Q_UNUSED(point);
|
||||
|
||||
// if we are in a swipe
|
||||
if (m_moving) {
|
||||
Q_EMIT swipeEnded();
|
||||
|
|
@ -265,6 +316,8 @@ void SwipeArea::handleReleaseEvent(QPointerEvent *event, QPointF point)
|
|||
|
||||
void SwipeArea::handleMoveEvent(QPointerEvent *event, QPointF point)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
|
||||
if (!m_stealMouse) {
|
||||
if (!m_skipSwipeThreshold) {
|
||||
// if we haven't reached the swipe registering threshold yet, don't start the swipe
|
||||
|
|
|
|||
|
|
@ -58,6 +58,10 @@ Q_SIGNALS:
|
|||
// totalDeltaX, totalDeltaY - amount move since startedSwipe()
|
||||
void swipeMove(qreal totalDeltaX, qreal totalDeltaY, qreal deltaX, qreal deltaY);
|
||||
|
||||
void touchpadScrollStarted(QPointF point);
|
||||
void touchpadScrollEnded();
|
||||
void touchpadScrollMove(qreal totalDeltaX, qreal totalDeltaY, qreal deltaX, qreal deltaY);
|
||||
|
||||
protected:
|
||||
bool childMouseEventFilter(QQuickItem *item, QEvent *event) override;
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
|
|
@ -66,6 +70,7 @@ protected:
|
|||
void mouseUngrabEvent() override;
|
||||
void touchEvent(QTouchEvent *event) override;
|
||||
void touchUngrabEvent() override;
|
||||
void wheelEvent(QWheelEvent *event) override;
|
||||
|
||||
private:
|
||||
void setMoving(bool moving);
|
||||
|
|
@ -82,6 +87,7 @@ private:
|
|||
Mode m_mode = Mode::BothAxis;
|
||||
bool m_interactive = true;
|
||||
bool m_pressed = false;
|
||||
bool m_touchpadScrolling = false;
|
||||
|
||||
// whether we have started a flick
|
||||
bool m_moving = false;
|
||||
|
|
@ -100,6 +106,9 @@ private:
|
|||
|
||||
// whether to skip trying to measure the swipe threshold
|
||||
bool m_skipSwipeThreshold;
|
||||
|
||||
// the total amount of distance scrolled
|
||||
QPointF m_totalScrollDelta;
|
||||
};
|
||||
|
||||
QML_DECLARE_TYPE(SwipeArea)
|
||||
|
|
|
|||
|
|
@ -267,18 +267,28 @@ Item {
|
|||
mode: MobileShell.SwipeArea.VerticalOnly
|
||||
anchors.fill: parent
|
||||
|
||||
onSwipeStarted: {
|
||||
function startSwipe() {
|
||||
root.cancelAnimations();
|
||||
root.dragging = true;
|
||||
}
|
||||
onSwipeEnded: {
|
||||
|
||||
function endSwipe() {
|
||||
root.dragging = false;
|
||||
root.updateState();
|
||||
}
|
||||
onSwipeMove: (totalDeltaX, totalDeltaY, deltaX, deltaY) => {
|
||||
|
||||
function moveSwipe(totalDeltaX, totalDeltaY, deltaX, deltaY) {
|
||||
root.offset += deltaY;
|
||||
}
|
||||
|
||||
onSwipeStarted: startSwipe()
|
||||
onSwipeEnded: endSwipe()
|
||||
onSwipeMove: (totalDeltaX, totalDeltaY, deltaX, deltaY) => moveSwipe(totalDeltaX, totalDeltaY, deltaX, deltaY)
|
||||
|
||||
onTouchpadScrollStarted: startSwipe()
|
||||
onTouchpadScrollEnded: endSwipe()
|
||||
onTouchpadScrollMove: (totalDeltaX, totalDeltaY, deltaX, deltaY) => moveSwipe(totalDeltaX, totalDeltaY, deltaX, deltaY)
|
||||
|
||||
Loader {
|
||||
id: contentContainerLoader
|
||||
anchors.fill: parent
|
||||
|
|
|
|||
|
|
@ -33,6 +33,17 @@ MobileShell.SwipeArea {
|
|||
actionDrawer.visible = true;
|
||||
}
|
||||
|
||||
function startSwipeWithPoint(point) {
|
||||
// if the user swiped from the top left, otherwise it's from the top right
|
||||
if (point.x < root.width / 2) {
|
||||
actionDrawer.openToPinnedMode = ShellSettings.Settings.actionDrawerTopLeftMode == ShellSettings.Settings.Pinned;
|
||||
} else {
|
||||
actionDrawer.openToPinnedMode = ShellSettings.Settings.actionDrawerTopRightMode == ShellSettings.Settings.Pinned;
|
||||
}
|
||||
|
||||
startSwipe();
|
||||
}
|
||||
|
||||
function endSwipe() {
|
||||
actionDrawer.dragging = false;
|
||||
actionDrawer.updateState();
|
||||
|
|
@ -44,16 +55,11 @@ MobileShell.SwipeArea {
|
|||
|
||||
anchors.fill: parent
|
||||
|
||||
onSwipeStarted: (point) => {
|
||||
// if the user swiped from the top left, otherwise it's from the top right
|
||||
if (point.x < root.width / 2) {
|
||||
actionDrawer.openToPinnedMode = ShellSettings.Settings.actionDrawerTopLeftMode == ShellSettings.Settings.Pinned;
|
||||
} else {
|
||||
actionDrawer.openToPinnedMode = ShellSettings.Settings.actionDrawerTopRightMode == ShellSettings.Settings.Pinned;
|
||||
}
|
||||
|
||||
startSwipe();
|
||||
}
|
||||
onSwipeStarted: (point) => startSwipeWithPoint(point)
|
||||
onSwipeEnded: endSwipe()
|
||||
onSwipeMove: (totalDeltaX, totalDeltaY, deltaX, deltaY) => updateOffset(deltaY);
|
||||
|
||||
onTouchpadScrollStarted: (point) => startSwipeWithPoint(point)
|
||||
onTouchpadScrollEnded: endSwipe()
|
||||
onTouchpadScrollMove: (totalDeltaX, totalDeltaY, deltaX, deltaY) => updateOffset(deltaY);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,6 +124,10 @@ Item {
|
|||
homeScreenState.swipeMoved(totalDeltaX, totalDeltaY, deltaX, deltaY);
|
||||
}
|
||||
|
||||
onTouchpadScrollStarted: homeScreenState.swipeStarted(0, 0);
|
||||
onTouchpadScrollEnded: homeScreenState.swipeEnded();
|
||||
onTouchpadScrollMove: (totalDeltaX, totalDeltaY, deltaX, deltaY) => homeScreenState.swipeMoved(totalDeltaX, totalDeltaY, deltaX, deltaY);
|
||||
|
||||
onPressedChanged: {
|
||||
if (pressed) {
|
||||
// ensures that components like the widget settings overlay close when swiping
|
||||
|
|
|
|||
|
|
@ -71,16 +71,28 @@ MobileShell.SwipeArea {
|
|||
}
|
||||
}
|
||||
|
||||
onSwipeStarted: cancelAnimations();
|
||||
onSwipeEnded: {
|
||||
function __startSwipe() {
|
||||
cancelAnimations();
|
||||
}
|
||||
|
||||
function __endSwipe() {
|
||||
if (!positionAnim.running) {
|
||||
updateState();
|
||||
}
|
||||
}
|
||||
|
||||
onSwipeMove: (totalDeltaX, totalDeltaY, deltaX, deltaY) => {
|
||||
function __moveSwipe(totalDeltaX, totalDeltaY, deltaX, deltaY) {
|
||||
position = Math.max(0, Math.min(keypadHeight, position - deltaY));
|
||||
}
|
||||
|
||||
onSwipeStarted: __startSwipe()
|
||||
onSwipeEnded: __endSwipe()
|
||||
|
||||
onSwipeMove: __moveSwipe(totalDeltaX, totalDeltaY, deltaX, deltaY)
|
||||
|
||||
onTouchpadScrollStarted: __startSwipe()
|
||||
onTouchpadScrollEnded: __endSwipe()
|
||||
onTouchpadScrollMove: __moveSwipe(totalDeltaX, totalDeltaY, deltaX, deltaY)
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue