From 1012adeaf72188f46d26ff6c7ed9620a523024b6 Mon Sep 17 00:00:00 2001 From: Aleix Pol Date: Fri, 9 Jul 2021 01:13:24 +0200 Subject: [PATCH] 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. --- src/CMakeLists.txt | 1 + ...eventfilter.cpp => dpmsinputeventfilter.cpp} | 17 ++++++++++------- ...nputeventfilter.h => dpmsinputeventfilter.h} | 11 ++++++----- src/plugins/platforms/drm/CMakeLists.txt | 1 - src/plugins/platforms/drm/drm_backend.cpp | 6 +++++- src/plugins/platforms/drm/drm_backend.h | 2 +- .../platforms/wayland/wayland_backend.cpp | 16 ++++++++++++++++ src/plugins/platforms/wayland/wayland_backend.h | 6 ++++++ .../platforms/wayland/wayland_output.cpp | 16 ++++++++++++++++ src/plugins/platforms/wayland/wayland_output.h | 3 +++ 10 files changed, 64 insertions(+), 15 deletions(-) rename src/{plugins/platforms/drm/drm_inputeventfilter.cpp => dpmsinputeventfilter.cpp} (83%) rename src/{plugins/platforms/drm/drm_inputeventfilter.h => dpmsinputeventfilter.h} (81%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dd54a7ae4a..3fa9c8d7b2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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 diff --git a/src/plugins/platforms/drm/drm_inputeventfilter.cpp b/src/dpmsinputeventfilter.cpp similarity index 83% rename from src/plugins/platforms/drm/drm_inputeventfilter.cpp rename to src/dpmsinputeventfilter.cpp index 4b58423e2f..95a3104e6e 100644 --- a/src/plugins/platforms/drm/drm_inputeventfilter.cpp +++ b/src/dpmsinputeventfilter.cpp @@ -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 +#include #include #include @@ -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("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 enabledOutputs = kwinApp()->platform()->enabledOutputs(); + for (auto it = enabledOutputs.constBegin(), end = enabledOutputs.constEnd(); it != end; it++) { + auto waylandOutput = static_cast(*it); + waylandOutput->setDpmsMode(AbstractWaylandOutput::DpmsMode::On); + } } } diff --git a/src/plugins/platforms/drm/drm_inputeventfilter.h b/src/dpmsinputeventfilter.h similarity index 81% rename from src/plugins/platforms/drm/drm_inputeventfilter.h rename to src/dpmsinputeventfilter.h index 998aa1fa7a..46e9b039db 100644 --- a/src/plugins/platforms/drm/drm_inputeventfilter.h +++ b/src/dpmsinputeventfilter.h @@ -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 +#include + 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 m_touchPoints; bool m_secondTap = false; diff --git a/src/plugins/platforms/drm/CMakeLists.txt b/src/plugins/platforms/drm/CMakeLists.txt index 2f4f336f45..b07afe8071 100644 --- a/src/plugins/platforms/drm/CMakeLists.txt +++ b/src/plugins/platforms/drm/CMakeLists.txt @@ -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 diff --git a/src/plugins/platforms/drm/drm_backend.cpp b/src/plugins/platforms/drm/drm_backend.cpp index e9f7ba0811..0a9a102720 100644 --- a/src/plugins/platforms/drm/drm_backend.cpp +++ b/src/plugins/platforms/drm/drm_backend.cpp @@ -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 outputsConfig(const QVector &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; diff --git a/src/plugins/platforms/drm/drm_backend.h b/src/plugins/platforms/drm/drm_backend.h index 4995631ab2..f636e2542d 100644 --- a/src/plugins/platforms/drm/drm_backend.h +++ b/src/plugins/platforms/drm/drm_backend.h @@ -10,7 +10,7 @@ #define KWIN_DRM_BACKEND_H #include "platform.h" -#include "drm_inputeventfilter.h" +#include "dpmsinputeventfilter.h" #include #include diff --git a/src/plugins/platforms/wayland/wayland_backend.cpp b/src/plugins/platforms/wayland/wayland_backend.cpp index 14409be457..d460166db7 100644 --- a/src/plugins/platforms/wayland/wayland_backend.cpp +++ b/src/plugins/platforms/wayland/wayland_backend.cpp @@ -30,6 +30,7 @@ #include "screens.h" #include "pointer_input.h" #include "wayland_server.h" +#include "dpmsinputeventfilter.h" #include #include @@ -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 diff --git a/src/plugins/platforms/wayland/wayland_backend.h b/src/plugins/platforms/wayland/wayland_backend.h index 5e057c39e3..83b6e9ade2 100644 --- a/src/plugins/platforms/wayland/wayland_backend.h +++ b/src/plugins/platforms/wayland/wayland_backend.h @@ -56,6 +56,8 @@ class XdgShell; namespace KWin { +class DpmsInputEventFilter; + namespace Wayland { @@ -198,6 +200,8 @@ public: QVector waylandOutputs() const { return m_outputs; } + void createDpmsFilter(); + void clearDpmsFilter(); Q_SIGNALS: void systemCompositorDied(); @@ -234,6 +238,8 @@ private: WaylandCursor *m_waylandCursor = nullptr; + QScopedPointer m_dpmsFilter; + bool m_pointerLockRequested = false; #if HAVE_GBM && HAVE_WAYLAND_EGL int m_drmFileDescriptor = 0; diff --git a/src/plugins/platforms/wayland/wayland_output.cpp b/src/plugins/platforms/wayland/wayland_output.cpp index db6d0f5d95..b2898266ad 100644 --- a/src/plugins/platforms/wayland/wayland_output.cpp +++ b/src/plugins/platforms/wayland/wayland_output.cpp @@ -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) diff --git a/src/plugins/platforms/wayland/wayland_output.h b/src/plugins/platforms/wayland/wayland_output.h index 9f3bfde9ec..0ec6a10634 100644 --- a/src/plugins/platforms/wayland/wayland_output.h +++ b/src/plugins/platforms/wayland/wayland_output.h @@ -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();