kwineffects: Make OffscreenQuickView generate double click events

Currently, MouseArea.doubleClicked doesn't work in QtQuick effects.
Luckily, the overview effect doesn't use it, but it's still worth making
sure that it works as expected regardless of whether it's a kwin effect.

With this change, the OffscreenQuickView will keep track of the last
mouse press event. If the second button press occurs within the mouse
double click interval, the OffscreenQuickView will generate a
QEvent::MouseButtonDblClick event, similar to what QGuiApplication would
normally do when processing window system events.
This commit is contained in:
Vlad Zahorodnii 2021-11-24 10:02:54 +02:00
parent 00273f10ff
commit 4881dd63a7
3 changed files with 18 additions and 13 deletions

View file

@ -12,12 +12,14 @@
#include "kwinglutils.h"
#include "logging_p.h"
#include <QGuiApplication>
#include <QQmlEngine>
#include <QQuickItem>
#include <QQmlContext>
#include <QQmlComponent>
#include <QQuickView>
#include <QQuickRenderControl>
#include <QStyleHints>
#include <QOffscreenSurface>
#include <QOpenGLContext>
@ -74,6 +76,9 @@ public:
Qt::TouchPointStates touchState;
QTouchDevice *touchDevice;
ulong lastMousePressTime = 0;
Qt::MouseButton lastMousePressButton = Qt::NoButton;
void releaseResources();
void updateTouchState(Qt::TouchPointState state, qint32 id, const QPointF& pos);
@ -270,13 +275,25 @@ void OffscreenQuickView::forwardMouseEvent(QEvent *e)
case QEvent::MouseMove:
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
case QEvent::MouseButtonDblClick:
{
QMouseEvent *me = static_cast<QMouseEvent *>(e);
const QPoint widgetPos = d->m_view->mapFromGlobal(me->pos());
QMouseEvent cloneEvent(me->type(), widgetPos, me->pos(), me->button(), me->buttons(), me->modifiers());
QCoreApplication::sendEvent(d->m_view, &cloneEvent);
e->setAccepted(cloneEvent.isAccepted());
if (e->type() == QEvent::MouseButtonPress) {
const ulong doubleClickInterval = static_cast<ulong>(QGuiApplication::styleHints()->mouseDoubleClickInterval());
const bool doubleClick = (me->timestamp() - d->lastMousePressTime < doubleClickInterval) && me->button() == d->lastMousePressButton;
d->lastMousePressTime = me->timestamp();
d->lastMousePressButton = me->button();
if (doubleClick) {
d->lastMousePressButton = Qt::NoButton;
QMouseEvent doubleClickEvent(QEvent::MouseButtonDblClick, me->localPos(), me->windowPos(), me->screenPos(), me->button(), me->buttons(), me->modifiers());
QCoreApplication::sendEvent(d->m_view, &doubleClickEvent);
}
}
return;
}
case QEvent::HoverEnter:

View file

@ -30,7 +30,6 @@
#include <QDirIterator>
#include <QGuiApplication>
#include <QLabel>
#include <QStyleHints>
#include <QOffscreenSurface>
#include <QOpenGLContext>
#include <QOpenGLFramebufferObject>
@ -517,13 +516,6 @@ void Decoration::mousePressEvent(QMouseEvent *event)
{
if (m_view) {
m_view->forwardMouseEvent(event);
if (event->button() == Qt::LeftButton) {
if (!m_doubleClickTimer.hasExpired(QGuiApplication::styleHints()->mouseDoubleClickInterval())) {
QMouseEvent dc(QEvent::MouseButtonDblClick, event->localPos(), event->windowPos(), event->screenPos(), event->button(), event->buttons(), event->modifiers());
m_view->forwardMouseEvent(&dc);
}
}
m_doubleClickTimer.invalidate();
}
KDecoration2::Decoration::mousePressEvent(event);
}
@ -532,9 +524,6 @@ void Decoration::mouseReleaseEvent(QMouseEvent *event)
{
if (m_view) {
m_view->forwardMouseEvent(event);
if (event->isAccepted() && event->button() == Qt::LeftButton) {
m_doubleClickTimer.start();
}
}
KDecoration2::Decoration::mouseReleaseEvent(event);
}

View file

@ -77,7 +77,6 @@ private:
QString m_themeName;
KWin::OffscreenQuickView *m_view;
QElapsedTimer m_doubleClickTimer;
};
class ThemeProvider : public KDecoration2::DecorationThemeProvider