[backends/hwcomposer] Use input event filter for turning screen on/off
Like in the drm backend we use an InputEventFilter to turn the backlight on and off. In this case the filter needs to be always installed as key event should also turn the screen off. We cannot use a global shortcut as it would not trigger while the screen is locked. Unlike the filter in DRM backend only the power key can toggle the backlight, other key events are ignored. For pointer we are optimistic and already support enabling the backlight. Double tap to wake is also implemented, but at least on reference hardware (Nexus 5) doesn't work as disabling the backlight also disables touch input. Reviewed-By: Bhushan Shah
This commit is contained in:
parent
a33c2730ba
commit
1c4c5caf65
2 changed files with 130 additions and 10 deletions
|
@ -29,6 +29,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include <KWayland/Server/display.h>
|
||||
#include <KWayland/Server/output_interface.h>
|
||||
#include <KWayland/Server/seat_interface.h>
|
||||
// Qt
|
||||
#include <QKeyEvent>
|
||||
// hybris/android
|
||||
#include <hardware/hardware.h>
|
||||
#include <hardware/hwcomposer.h>
|
||||
|
@ -41,6 +43,103 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
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);
|
||||
|
|
|
@ -20,7 +20,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#ifndef KWIN_HWCOMPOSER_BACKEND_H
|
||||
#define KWIN_HWCOMPOSER_BACKEND_H
|
||||
#include "abstract_backend.h"
|
||||
#include "input.h"
|
||||
|
||||
#include <QElapsedTimer>
|
||||
#include <QMutex>
|
||||
#include <QWaitCondition>
|
||||
|
||||
|
@ -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<BacklightInputEventFilter> 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<qint32> m_touchPoints;
|
||||
bool m_secondTap = false;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue