diff --git a/backends/hwcomposer/hwcomposer_backend.cpp b/backends/hwcomposer/hwcomposer_backend.cpp
index 1af78c2345..bfbd205000 100644
--- a/backends/hwcomposer/hwcomposer_backend.cpp
+++ b/backends/hwcomposer/hwcomposer_backend.cpp
@@ -29,6 +29,8 @@ along with this program. If not, see .
#include
#include
#include
+// Qt
+#include
// hybris/android
#include
#include
@@ -41,6 +43,103 @@ along with this program. If not, see .
namespace KWin
{
+BacklightInputEventFilter::BacklightInputEventFilter(HwcomposerBackend *backend)
+ : InputEventFilter()
+ , m_backend(backend)
+{
+}
+
+BacklightInputEventFilter::~BacklightInputEventFilter() = default;
+
+bool BacklightInputEventFilter::pointerEvent(QMouseEvent *event, quint32 nativeButton)
+{
+ Q_UNUSED(event)
+ Q_UNUSED(nativeButton)
+ if (!m_backend->isBacklightOff()) {
+ return false;
+ }
+ toggleBacklight();
+ return true;
+}
+
+bool BacklightInputEventFilter::wheelEvent(QWheelEvent *event)
+{
+ Q_UNUSED(event)
+ if (!m_backend->isBacklightOff()) {
+ return false;
+ }
+ toggleBacklight();
+ return true;
+}
+
+bool BacklightInputEventFilter::keyEvent(QKeyEvent *event)
+{
+ if (event->key() == Qt::Key_PowerOff && event->type() == QEvent::KeyRelease) {
+ toggleBacklight();
+ return true;
+ }
+ return m_backend->isBacklightOff();
+}
+
+bool BacklightInputEventFilter::touchDown(quint32 id, const QPointF &pos, quint32 time)
+{
+ Q_UNUSED(pos)
+ Q_UNUSED(time)
+ if (!m_backend->isBacklightOff()) {
+ return false;
+ }
+ if (m_touchPoints.isEmpty()) {
+ if (!m_doubleTapTimer.isValid()) {
+ // this is the first tap
+ m_doubleTapTimer.start();
+ } else {
+ if (m_doubleTapTimer.elapsed() < qApp->doubleClickInterval()) {
+ m_secondTap = true;
+ } else {
+ // took too long. Let's consider it a new click
+ m_doubleTapTimer.restart();
+ }
+ }
+ } else {
+ // not a double tap
+ m_doubleTapTimer.invalidate();
+ m_secondTap = false;
+ }
+ m_touchPoints << id;
+ return true;
+}
+
+bool BacklightInputEventFilter::touchUp(quint32 id, quint32 time)
+{
+ Q_UNUSED(time)
+ m_touchPoints.removeAll(id);
+ if (!m_backend->isBacklightOff()) {
+ return false;
+ }
+ if (m_touchPoints.isEmpty() && m_doubleTapTimer.isValid() && m_secondTap) {
+ if (m_doubleTapTimer.elapsed() < qApp->doubleClickInterval()) {
+ toggleBacklight();
+ }
+ m_doubleTapTimer.invalidate();
+ m_secondTap = false;
+ }
+ return true;
+}
+
+bool BacklightInputEventFilter::touchMotion(quint32 id, const QPointF &pos, quint32 time)
+{
+ Q_UNUSED(id)
+ Q_UNUSED(pos)
+ Q_UNUSED(time)
+ return m_backend->isBacklightOff();
+}
+
+void BacklightInputEventFilter::toggleBacklight()
+{
+ // queued to not modify the list of event filters while filtering
+ QMetaObject::invokeMethod(m_backend, "toggleBlankOutput", Qt::QueuedConnection);
+}
+
HwcomposerBackend::HwcomposerBackend(QObject *parent)
: AbstractBackend(parent)
{
@@ -137,16 +236,8 @@ void HwcomposerBackend::init()
initLights();
toggleBlankOutput();
- connect(input(), &InputRedirection::keyStateChanged, this,
- [this] (quint32 key, InputRedirection::KeyboardKeyState state) {
- if (state != InputRedirection::KeyboardKeyState::KeyboardKeyReleased) {
- return;
- }
- if (key == KEY_POWER) {
- toggleBlankOutput();
- }
- }
- );
+ m_filter.reset(new BacklightInputEventFilter(this));
+ input()->prepandInputEventFilter(m_filter.data());
// get display configuration
auto output = createOutput(hwcDevice);
diff --git a/backends/hwcomposer/hwcomposer_backend.h b/backends/hwcomposer/hwcomposer_backend.h
index f4b1477962..5c8fc24e5e 100644
--- a/backends/hwcomposer/hwcomposer_backend.h
+++ b/backends/hwcomposer/hwcomposer_backend.h
@@ -20,7 +20,9 @@ along with this program. If not, see .
#ifndef KWIN_HWCOMPOSER_BACKEND_H
#define KWIN_HWCOMPOSER_BACKEND_H
#include "abstract_backend.h"
+#include "input.h"
+#include
#include
#include
@@ -40,6 +42,7 @@ namespace KWin
{
class HwcomposerWindow;
+class BacklightInputEventFilter;
class HwcomposerBackend : public AbstractBackend
{
@@ -74,6 +77,10 @@ public:
void waitVSync();
void wakeVSync();
+ bool isBacklightOff() const {
+ return m_outputBlank;
+ }
+
Q_SIGNALS:
void outputBlankChanged();
@@ -92,6 +99,7 @@ private:
bool m_hasVsync = false;
QMutex m_vsyncMutex;
QWaitCondition m_vsyncWaitCondition;
+ QScopedPointer m_filter;
};
class HwcomposerWindow : public HWComposerNativeWindow
@@ -108,6 +116,27 @@ private:
hwc_display_contents_1_t **m_list;
};
+class BacklightInputEventFilter : public InputEventFilter
+{
+public:
+ BacklightInputEventFilter(HwcomposerBackend *backend);
+ virtual ~BacklightInputEventFilter();
+
+ bool pointerEvent(QMouseEvent *event, quint32 nativeButton) override;
+ bool wheelEvent(QWheelEvent *event) override;
+ bool keyEvent(QKeyEvent *event) override;
+ bool touchDown(quint32 id, const QPointF &pos, quint32 time) override;
+ bool touchMotion(quint32 id, const QPointF &pos, quint32 time) override;
+ bool touchUp(quint32 id, quint32 time) override;
+
+private:
+ void toggleBacklight();
+ HwcomposerBackend *m_backend;
+ QElapsedTimer m_doubleTapTimer;
+ QVector m_touchPoints;
+ bool m_secondTap = false;
+};
+
}
#endif