Commit 52072639 authored by Alvin Wong's avatar Alvin Wong Committed by Dmitry Kazakov
Browse files

win: Work around touch docker buttons triggering twice

Hack around the issue by blocking certain mouse events in the touch
docker.

See also: https://bugreports.qt.io/browse/QTBUG-95058
BUG: 437196
parent cd8ec929
......@@ -3,6 +3,12 @@ set(KRITA_TOUCHDOCKER_SOURCES
TouchDockerDock.cpp
)
if(WIN32)
set(KRITA_TOUCHDOCKER_SOURCES ${KRITA_TOUCHDOCKER_SOURCES}
TouchDockerQQuickWidget.cpp
)
endif(WIN32)
qt5_add_resources(KRITA_TOUCHDOCKER_SOURCES touchdocker.qrc)
add_library(kritatouchdocker MODULE ${KRITA_TOUCHDOCKER_SOURCES})
......
......@@ -42,6 +42,10 @@
#include <QVersionNumber>
#ifdef Q_OS_WIN
#include "TouchDockerQQuickWidget.h"
#endif
namespace
{
......@@ -101,7 +105,11 @@ TouchDockerDock::TouchDockerDock()
}
}
#ifdef Q_OS_WIN
m_quickWidget = new TouchDockerQQuickWidget(this);
#else
m_quickWidget = new QQuickWidget(this);
#endif
if (shouldSetAcceptTouchEvents()) {
m_quickWidget->setAttribute(Qt::WA_AcceptTouchEvents);
}
......
/*
* SPDX-FileCopyrightText: 2021 Alvin Wong <alvin@alvinhc.com>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "TouchDockerQQuickWidget.h"
#include <QInputEvent>
#include "kis_debug.h"
// Block mouse events that happens within x milliseconds from the last touch
// event. 100 ms seems to be a reasonable time?
constexpr ulong MOUSE_EVENT_BLOCK_TIME = 100;
TouchDockerQQuickWidget::~TouchDockerQQuickWidget()
{
}
bool TouchDockerQQuickWidget::event(QEvent *event)
{
bool blocked = false;
switch (event->type()) {
case QEvent::TouchBegin:
case QEvent::TouchUpdate:
case QEvent::TouchEnd:
case QEvent::TouchCancel:
// Record the timestamp of the last touch event received so we can
// block mouse events initiated within a certain time.
m_lastTouchEventTimeMills = dynamic_cast<QInputEvent *>(event)->timestamp();
break;
case QEvent::MouseButtonPress:
if (dynamic_cast<QInputEvent *>(event)->timestamp() - m_lastTouchEventTimeMills
< MOUSE_EVENT_BLOCK_TIME)
{
dbgInput << "TouchDockerQQuickWidget blocking mouse press";
blocked = true;
// Start blocking mouse events until released.
m_shouldBlockUntilMouseUp = true;
// Also block the next double-click, if there is one.
m_shouldBlockNextDblClick = true;
} else {
dbgInput << "TouchDockerQQuickWidget NOT blocking mouse press";
// We don't need to block mouse events.
m_shouldBlockUntilMouseUp = false;
// We shouldn't block the next double-click either.
m_shouldBlockNextDblClick = false;
}
break;
case QEvent::MouseButtonDblClick:
if (m_shouldBlockNextDblClick) {
dbgInput << "TouchDockerQQuickWidget blocking mouse dblclick";
blocked = true;
// Start blocking mouse events until released.
m_shouldBlockUntilMouseUp = true;
// Clear this flag as we already blocked the double-click that we
// expected.
m_shouldBlockNextDblClick = false;
} else {
dbgInput << "TouchDockerQQuickWidget NOT blocking mouse dblclick";
// We don't need to block mouse events.
m_shouldBlockUntilMouseUp = false;
}
break;
case QEvent::MouseMove:
if (m_shouldBlockUntilMouseUp) {
dbgInput << "TouchDockerQQuickWidget blocking mouse move";
blocked = true;
} else {
dbgInput << "TouchDockerQQuickWidget NOT blocking mouse move";
}
break;
case QEvent::MouseButtonRelease:
if (m_shouldBlockUntilMouseUp) {
dbgInput << "TouchDockerQQuickWidget blocking mouse release";
blocked = true;
} else {
dbgInput << "TouchDockerQQuickWidget NOT blocking mouse release";
}
m_shouldBlockUntilMouseUp = false;
break;
default:
break;
}
if (blocked) {
return true;
}
return QQuickWidget::event(event);
}
/*
* SPDX-FileCopyrightText: 2021 Alvin Wong <alvin@alvinhc.com>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#ifndef TOUCH_DOCKER_QQUICKWIDGET_H
#define TOUCH_DOCKER_QQUICKWIDGET_H
#include <QtQuickWidgets/QQuickWidget>
/**
* This is a hack on top of QQuickWidget to drop mouse events that might have
* been synthesized by touch events. The aim is to work around a bug in the
* Qt Windows QPA which sometimes misclassifies such events as non-synthesized
* when handling Windows pointer input events.
*
* See also:
* - https://bugs.kde.org/show_bug.cgi?id=437196
* - https://bugreports.qt.io/browse/QTBUG-95058
*/
class TouchDockerQQuickWidget : public QQuickWidget
{
Q_OBJECT
ulong m_lastTouchEventTimeMills { 0 };
bool m_shouldBlockUntilMouseUp { false };
bool m_shouldBlockNextDblClick { false };
public:
TouchDockerQQuickWidget(QWidget *parent = nullptr)
: QQuickWidget(parent)
{
}
~TouchDockerQQuickWidget() override;
bool event(QEvent *event) override;
};
#endif // TOUCH_DOCKER_QQUICKWIDGET_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment