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 decorations/settings.cpp
deleted.cpp deleted.cpp
dmabuftexture.cpp dmabuftexture.cpp
dpmsinputeventfilter.cpp
effectloader.cpp effectloader.cpp
effects.cpp effects.cpp
egl_context_attribute_builder.cpp egl_context_attribute_builder.cpp

View file

@ -6,12 +6,13 @@
SPDX-License-Identifier: GPL-2.0-or-later SPDX-License-Identifier: GPL-2.0-or-later
*/ */
#include "drm_inputeventfilter.h" #include "dpmsinputeventfilter.h"
#include "drm_backend.h" #include "platform.h"
#include "abstract_wayland_output.h"
#include "wayland_server.h" #include "wayland_server.h"
#include "main.h" #include "main.h"
#include <QApplication> #include <QGuiApplication>
#include <QKeyEvent> #include <QKeyEvent>
#include <KWaylandServer/seat_interface.h> #include <KWaylandServer/seat_interface.h>
@ -19,9 +20,8 @@
namespace KWin namespace KWin
{ {
DpmsInputEventFilter::DpmsInputEventFilter(DrmBackend *backend) DpmsInputEventFilter::DpmsInputEventFilter()
: InputEventFilter() : InputEventFilter()
, m_backend(backend)
{ {
KSharedConfig::Ptr kwinSettings = kwinApp()->config(); KSharedConfig::Ptr kwinSettings = kwinApp()->config();
m_enableDoubleTap = kwinSettings->group("Wayland").readEntry<bool>("DoubleTapWakeup", true); 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() void DpmsInputEventFilter::notify()
{ {
// queued to not modify the list of event filters while filtering const QVector<AbstractOutput *> enabledOutputs = kwinApp()->platform()->enabledOutputs();
QMetaObject::invokeMethod(m_backend, &DrmBackend::turnOutputsOn, Qt::QueuedConnection); 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 SPDX-License-Identifier: GPL-2.0-or-later
*/ */
#ifndef KWIN_DRM_INPUTEVENTFILTER_H #ifndef KWIN_DPMSINPUTEVENTFILTER_H
#define KWIN_DRM_INPUTEVENTFILTER_H #define KWIN_DPMSINPUTEVENTFILTER_H
#include "input.h" #include "input.h"
#include <QElapsedTimer> #include <QElapsedTimer>
#include <kwin_export.h>
namespace KWin namespace KWin
{ {
class DrmBackend; class DrmBackend;
class DpmsInputEventFilter : public InputEventFilter class KWIN_EXPORT DpmsInputEventFilter : public InputEventFilter
{ {
public: public:
DpmsInputEventFilter(DrmBackend *backend); DpmsInputEventFilter();
~DpmsInputEventFilter() override; ~DpmsInputEventFilter() override;
bool pointerEvent(QMouseEvent *event, quint32 nativeButton) override; bool pointerEvent(QMouseEvent *event, quint32 nativeButton) override;
@ -32,7 +34,6 @@ public:
private: private:
void notify(); void notify();
DrmBackend *m_backend;
QElapsedTimer m_doubleTapTimer; QElapsedTimer m_doubleTapTimer;
QVector<qint32> m_touchPoints; QVector<qint32> m_touchPoints;
bool m_secondTap = false; bool m_secondTap = false;

View file

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

View file

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

View file

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

View file

@ -30,6 +30,7 @@
#include "screens.h" #include "screens.h"
#include "pointer_input.h" #include "pointer_input.h"
#include "wayland_server.h" #include "wayland_server.h"
#include "dpmsinputeventfilter.h"
#include <KWayland/Client/buffer.h> #include <KWayland/Client/buffer.h>
#include <KWayland/Client/compositor.h> #include <KWayland/Client/compositor.h>
@ -860,6 +861,21 @@ DmaBufTexture *WaylandBackend::createDmaBufTexture(const QSize& size)
#endif #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 } // KWin

View file

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

View file

@ -35,6 +35,7 @@ WaylandOutput::WaylandOutput(Surface *surface, WaylandBackend *backend)
identifier++; identifier++;
setName("WL-" + QString::number(identifier)); setName("WL-" + QString::number(identifier));
setCapabilityInternal(Capability::Dpms);
connect(surface, &Surface::frameRendered, [this] { connect(surface, &Surface::frameRendered, [this] {
m_rendered = true; m_rendered = true;
Q_EMIT frameRendered(); Q_EMIT frameRendered();
@ -75,6 +76,21 @@ void WaylandOutput::setGeometry(const QPoint &logicalPosition, const QSize &pixe
setGlobalPos(logicalPosition); 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) XdgShellOutput::XdgShellOutput(Surface *surface, XdgShell *xdgShell, WaylandBackend *backend, int number)
: WaylandOutput(surface, backend) : WaylandOutput(surface, backend)
, m_number(number) , m_number(number)

View file

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