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();