Add support to DPMS to the Wayland Backend

Moves the DpmsInputEventFilter to libkwin, so that it can be used by
other backends other than DRM.
This mostly helps develop features around DPMS.
This commit is contained in:
Aleix Pol 2021-07-09 01:13:24 +02:00
parent caa8c8fd45
commit 1012adeaf7
10 changed files with 64 additions and 15 deletions

View file

@ -41,6 +41,7 @@ set(kwin_SRCS
decorations/settings.cpp
deleted.cpp
dmabuftexture.cpp
dpmsinputeventfilter.cpp
effectloader.cpp
effects.cpp
egl_context_attribute_builder.cpp

View file

@ -6,12 +6,13 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "drm_inputeventfilter.h"
#include "drm_backend.h"
#include "dpmsinputeventfilter.h"
#include "platform.h"
#include "abstract_wayland_output.h"
#include "wayland_server.h"
#include "main.h"
#include <QApplication>
#include <QGuiApplication>
#include <QKeyEvent>
#include <KWaylandServer/seat_interface.h>
@ -19,9 +20,8 @@
namespace KWin
{
DpmsInputEventFilter::DpmsInputEventFilter(DrmBackend *backend)
DpmsInputEventFilter::DpmsInputEventFilter()
: InputEventFilter()
, m_backend(backend)
{
KSharedConfig::Ptr kwinSettings = kwinApp()->config();
m_enableDoubleTap = kwinSettings->group("Wayland").readEntry<bool>("DoubleTapWakeup", true);
@ -106,8 +106,11 @@ bool DpmsInputEventFilter::touchMotion(qint32 id, const QPointF &pos, quint32 ti
void DpmsInputEventFilter::notify()
{
// queued to not modify the list of event filters while filtering
QMetaObject::invokeMethod(m_backend, &DrmBackend::turnOutputsOn, Qt::QueuedConnection);
const QVector<AbstractOutput *> enabledOutputs = kwinApp()->platform()->enabledOutputs();
for (auto it = enabledOutputs.constBegin(), end = enabledOutputs.constEnd(); it != end; it++) {
auto waylandOutput = static_cast<AbstractWaylandOutput *>(*it);
waylandOutput->setDpmsMode(AbstractWaylandOutput::DpmsMode::On);
}
}
}

View file

@ -6,21 +6,23 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef KWIN_DRM_INPUTEVENTFILTER_H
#define KWIN_DRM_INPUTEVENTFILTER_H
#ifndef KWIN_DPMSINPUTEVENTFILTER_H
#define KWIN_DPMSINPUTEVENTFILTER_H
#include "input.h"
#include <QElapsedTimer>
#include <kwin_export.h>
namespace KWin
{
class DrmBackend;
class DpmsInputEventFilter : public InputEventFilter
class KWIN_EXPORT DpmsInputEventFilter : public InputEventFilter
{
public:
DpmsInputEventFilter(DrmBackend *backend);
DpmsInputEventFilter();
~DpmsInputEventFilter() override;
bool pointerEvent(QMouseEvent *event, quint32 nativeButton) override;
@ -32,7 +34,6 @@ public:
private:
void notify();
DrmBackend *m_backend;
QElapsedTimer m_doubleTapTimer;
QVector<qint32> m_touchPoints;
bool m_secondTap = false;

View file

@ -6,7 +6,6 @@ set(DRM_SOURCES
drm_object_plane.cpp
drm_output.cpp
drm_buffer.cpp
drm_inputeventfilter.cpp
edid.cpp
logging.cpp
scene_qpainter_drm_backend.cpp

View file

@ -94,7 +94,7 @@ void DrmBackend::createDpmsFilter()
// already another output is off
return;
}
m_dpmsFilter.reset(new DpmsInputEventFilter(this));
m_dpmsFilter.reset(new DpmsInputEventFilter);
input()->prependInputEventFilter(m_dpmsFilter.data());
}
@ -384,6 +384,10 @@ namespace KWinKScreenIntegration
QMap<DrmOutput*, QJsonObject> outputsConfig(const QVector<DrmOutput*> &outputs)
{
const QString kscreenJsonPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kscreen/") % connectedOutputsHash(outputs));
if (kscreenJsonPath.isEmpty()) {
return {};
}
QFile f(kscreenJsonPath);
if (!f.open(QIODevice::ReadOnly)) {
qCWarning(KWIN_DRM) << "Could not open file" << kscreenJsonPath;

View file

@ -10,7 +10,7 @@
#define KWIN_DRM_BACKEND_H
#include "platform.h"
#include "drm_inputeventfilter.h"
#include "dpmsinputeventfilter.h"
#include <QPointer>
#include <QSize>

View file

@ -30,6 +30,7 @@
#include "screens.h"
#include "pointer_input.h"
#include "wayland_server.h"
#include "dpmsinputeventfilter.h"
#include <KWayland/Client/buffer.h>
#include <KWayland/Client/compositor.h>
@ -860,6 +861,21 @@ DmaBufTexture *WaylandBackend::createDmaBufTexture(const QSize& size)
#endif
}
void WaylandBackend::createDpmsFilter()
{
if (m_dpmsFilter) {
// already another output is off
return;
}
m_dpmsFilter.reset(new DpmsInputEventFilter);
input()->prependInputEventFilter(m_dpmsFilter.data());
}
void WaylandBackend::clearDpmsFilter()
{
m_dpmsFilter.reset();
}
}
} // KWin

View file

@ -56,6 +56,8 @@ class XdgShell;
namespace KWin
{
class DpmsInputEventFilter;
namespace Wayland
{
@ -198,6 +200,8 @@ public:
QVector<WaylandOutput*> waylandOutputs() const {
return m_outputs;
}
void createDpmsFilter();
void clearDpmsFilter();
Q_SIGNALS:
void systemCompositorDied();
@ -234,6 +238,8 @@ private:
WaylandCursor *m_waylandCursor = nullptr;
QScopedPointer<DpmsInputEventFilter> m_dpmsFilter;
bool m_pointerLockRequested = false;
#if HAVE_GBM && HAVE_WAYLAND_EGL
int m_drmFileDescriptor = 0;

View file

@ -35,6 +35,7 @@ WaylandOutput::WaylandOutput(Surface *surface, WaylandBackend *backend)
identifier++;
setName("WL-" + QString::number(identifier));
setCapabilityInternal(Capability::Dpms);
connect(surface, &Surface::frameRendered, [this] {
m_rendered = true;
Q_EMIT frameRendered();
@ -75,6 +76,21 @@ void WaylandOutput::setGeometry(const QPoint &logicalPosition, const QSize &pixe
setGlobalPos(logicalPosition);
}
void WaylandOutput::updateEnablement(bool enable)
{
setDpmsMode(enable ? DpmsMode::On : DpmsMode::Off);
}
void WaylandOutput::setDpmsMode(KWin::AbstractWaylandOutput::DpmsMode mode)
{
setDpmsModeInternal(mode);
if (mode == DpmsMode::Off) {
m_backend->createDpmsFilter();
} else {
m_backend->clearDpmsFilter();
}
}
XdgShellOutput::XdgShellOutput(Surface *surface, XdgShell *xdgShell, WaylandBackend *backend, int number)
: WaylandOutput(surface, backend)
, m_number(number)

View file

@ -71,6 +71,9 @@ public:
m_rendered = false;
}
void updateEnablement(bool enable) override;
void setDpmsMode(KWin::AbstractWaylandOutput::DpmsMode mode) override;
Q_SIGNALS:
void sizeChanged(const QSize &size);
void frameRendered();