diff --git a/src/wayland/CMakeLists.txt b/src/wayland/CMakeLists.txt index 6b280d0e97..3b98a01b49 100644 --- a/src/wayland/CMakeLists.txt +++ b/src/wayland/CMakeLists.txt @@ -42,6 +42,7 @@ set(SERVER_LIB_SRCS pointer_interface.cpp pointerconstraints_v1_interface.cpp pointergestures_v1_interface.cpp + primaryoutput_v1_interface.cpp primaryselectiondevice_v1_interface.cpp primaryselectiondevicemanager_v1_interface.cpp primaryselectionoffer_v1_interface.cpp @@ -90,6 +91,11 @@ ecm_add_qtwayland_server_protocol_kde(SERVER_LIB_SRCS BASENAME kde-output-device-v2 ) +ecm_add_qtwayland_server_protocol_kde(SERVER_LIB_SRCS + PROTOCOL ${PLASMA_WAYLAND_PROTOCOLS_DIR}/kde-primary-output-v1.xml + BASENAME kde-primary-output-v1 +) + ecm_add_qtwayland_server_protocol_kde(SERVER_LIB_SRCS PROTOCOL ${PLASMA_WAYLAND_PROTOCOLS_DIR}/kde-output-management-v2.xml BASENAME kde-output-management-v2 @@ -363,6 +369,7 @@ set(SERVER_LIB_HEADERS pointer_interface.h pointerconstraints_v1_interface.h pointergestures_v1_interface.h + primaryoutput_v1_interface.h primaryselectiondevice_v1_interface.h primaryselectiondevicemanager_v1_interface.h primaryselectionoffer_v1_interface.h diff --git a/src/wayland/outputconfiguration_v2_interface.cpp b/src/wayland/outputconfiguration_v2_interface.cpp index 4cb24d1bd3..9c8d936410 100644 --- a/src/wayland/outputconfiguration_v2_interface.cpp +++ b/src/wayland/outputconfiguration_v2_interface.cpp @@ -14,6 +14,8 @@ #include "qwayland-server-kde-output-management-v2.h" #include "qwayland-server-kde-output-device-v2.h" +#include + namespace KWaylandServer { class OutputConfigurationV2InterfacePrivate : public QtWaylandServer::kde_output_configuration_v2 @@ -31,6 +33,7 @@ public: OutputManagementV2Interface *outputManagement; QHash changes; + std::optional primaryOutput; OutputConfigurationV2Interface *q; protected: @@ -45,6 +48,7 @@ protected: void kde_output_configuration_v2_overscan(Resource *resource, wl_resource *outputdevice, uint32_t overscan) override; void kde_output_configuration_v2_set_vrr_policy(Resource *resource, struct ::wl_resource *outputdevice, uint32_t policy) override; void kde_output_configuration_v2_set_rgb_range(Resource *resource, wl_resource *outputdevice, uint32_t rgbRange) override; + void kde_output_configuration_v2_set_primary_output(Resource *resource, struct ::wl_resource *output) override; }; void OutputConfigurationV2InterfacePrivate::kde_output_configuration_v2_enable(Resource *resource, wl_resource *outputdevice, int32_t enable) @@ -155,6 +159,12 @@ void OutputConfigurationV2InterfacePrivate::kde_output_configuration_v2_set_rgb_ pendingChanges(output)->d->rgbRange = static_cast(rgbRange); } +void OutputConfigurationV2InterfacePrivate::kde_output_configuration_v2_set_primary_output(Resource *resource, struct ::wl_resource *output) +{ + Q_UNUSED(resource); + primaryOutput = OutputDeviceV2Interface::get(output); +} + void OutputConfigurationV2InterfacePrivate::kde_output_configuration_v2_destroy(Resource *resource) { wl_resource_destroy(resource->handle); @@ -183,6 +193,17 @@ QHash OutputConfigurationV2Interfa return d->changes; } +bool OutputConfigurationV2Interface::primaryChanged() const +{ + return d->primaryOutput.has_value(); +} + +OutputDeviceV2Interface *OutputConfigurationV2Interface::primary() const +{ + Q_ASSERT(d->primaryOutput.has_value()); + return *d->primaryOutput; +} + void OutputConfigurationV2Interface::setApplied() { d->clearPendingChanges(); diff --git a/src/wayland/outputconfiguration_v2_interface.h b/src/wayland/outputconfiguration_v2_interface.h index 45251b53be..d3d300f63e 100644 --- a/src/wayland/outputconfiguration_v2_interface.h +++ b/src/wayland/outputconfiguration_v2_interface.h @@ -60,6 +60,9 @@ public: */ QHash changes() const; + bool primaryChanged() const; + OutputDeviceV2Interface *primary() const; + public Q_SLOTS: /** * Called by the compositor once the changes have successfully been applied. diff --git a/src/wayland/outputdevice_v2_interface.cpp b/src/wayland/outputdevice_v2_interface.cpp index e34c68718f..750b682883 100644 --- a/src/wayland/outputdevice_v2_interface.cpp +++ b/src/wayland/outputdevice_v2_interface.cpp @@ -19,8 +19,7 @@ namespace KWaylandServer { - -static const quint32 s_version = 1; +static const quint32 s_version = 2; class OutputDeviceV2InterfacePrivate : public QtWaylandServer::kde_output_device_v2 { @@ -49,6 +48,7 @@ public: void sendEnabled(Resource *resource); void sendScale(Resource *resource); void sendEisaId(Resource *resource); + void sendName(Resource *resource); void sendSerialNumber(Resource *resource); void sendCapabilities(Resource *resource); void sendOverscan(Resource *resource); @@ -62,6 +62,7 @@ public: qreal scale = 1.0; QString serialNumber; QString eisaId; + QString name; OutputDeviceV2Interface::SubPixel subPixel = OutputDeviceV2Interface::SubPixel::Unknown; OutputDeviceV2Interface::Transform transform = OutputDeviceV2Interface::Transform::Normal; @@ -270,6 +271,7 @@ void OutputDeviceV2InterfacePrivate::kde_output_device_v2_bind_resource(Resource sendGeometry(resource); sendScale(resource); sendEisaId(resource); + sendName(resource); sendSerialNumber(resource); auto currentModeIt = modes.end(); @@ -345,6 +347,13 @@ void OutputDeviceV2InterfacePrivate::sendEisaId(Resource *resource) send_eisa_id(resource->handle, eisaId); } +void OutputDeviceV2InterfacePrivate::sendName(Resource *resource) +{ + if (resource->version() >= KDE_OUTPUT_DEVICE_V2_NAME_SINCE_VERSION) { + send_name(resource->handle, name); + } +} + void OutputDeviceV2InterfacePrivate::sendDone(Resource *resource) { send_done(resource->handle); @@ -422,6 +431,15 @@ void OutputDeviceV2Interface::setEisaId(const QString &arg) Q_EMIT eisaIdChanged(d->eisaId); } +void OutputDeviceV2Interface::setName(const QString &arg) +{ + if (d->name == arg) { + return; + } + d->name = arg; + Q_EMIT nameChanged(d->name); +} + void OutputDeviceV2Interface::setSubPixel(SubPixel arg) { if (d->subPixel == arg) { @@ -479,6 +497,11 @@ QString OutputDeviceV2Interface::eisaId() const return d->eisaId; } +QString OutputDeviceV2Interface::name() const +{ + return d->name; +} + qreal OutputDeviceV2Interface::scale() const { return d->scale; @@ -747,6 +770,11 @@ void OutputDeviceV2InterfacePrivate::updateRgbRange() } } +wl_resource *OutputDeviceV2Interface::resource() const +{ + return d->resource()->handle; +} + OutputDeviceV2Interface *OutputDeviceV2Interface::get(wl_resource *native) { if (auto devicePrivate = resource_cast(native)) { diff --git a/src/wayland/outputdevice_v2_interface.h b/src/wayland/outputdevice_v2_interface.h index de968c71bb..f92ba3c61c 100644 --- a/src/wayland/outputdevice_v2_interface.h +++ b/src/wayland/outputdevice_v2_interface.h @@ -41,6 +41,7 @@ class KWAYLANDSERVER_EXPORT OutputDeviceV2Interface : public QObject Q_PROPERTY(QString model READ model WRITE setModel NOTIFY modelChanged) Q_PROPERTY(QString serialNumber READ serialNumber WRITE setSerialNumber NOTIFY serialNumberChanged) Q_PROPERTY(QString eisaId READ eisaId WRITE setEisaId NOTIFY eisaIdChanged) + Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged) Q_PROPERTY(QByteArray edid READ edid WRITE setEdid NOTIFY edidChanged) Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) @@ -101,6 +102,7 @@ public: QString model() const; QString serialNumber() const; QString eisaId() const; + QString name() const; QSize pixelSize() const; int refreshRate() const; @@ -123,6 +125,7 @@ public: void setModel(const QString &model); void setSerialNumber(const QString &serialNumber); void setEisaId(const QString &eisaId); + void setName(const QString &name); void setScale(qreal scale); void setSubPixel(SubPixel subPixel); @@ -146,6 +149,7 @@ public: void setVrrPolicy(VrrPolicy policy); void setRgbRange(RgbRange rgbRange); + wl_resource *resource() const; static OutputDeviceV2Interface *get(wl_resource *native); Q_SIGNALS: @@ -155,6 +159,7 @@ Q_SIGNALS: void modelChanged(const QString&); void serialNumberChanged(const QString&); void eisaIdChanged(const QString &); + void nameChanged(const QString &name); void scaleChanged(qreal); void subPixelChanged(SubPixel); void transformChanged(Transform); diff --git a/src/wayland/outputmanagement_v2_interface.cpp b/src/wayland/outputmanagement_v2_interface.cpp index 92c2294e99..8194d66cd5 100644 --- a/src/wayland/outputmanagement_v2_interface.cpp +++ b/src/wayland/outputmanagement_v2_interface.cpp @@ -15,8 +15,7 @@ namespace KWaylandServer { - -static const quint32 s_version = 1; +static const quint32 s_version = 2; class OutputManagementV2InterfacePrivate : public QtWaylandServer::kde_output_management_v2 { diff --git a/src/wayland/primaryoutput_v1_interface.cpp b/src/wayland/primaryoutput_v1_interface.cpp new file mode 100644 index 0000000000..6f009431a5 --- /dev/null +++ b/src/wayland/primaryoutput_v1_interface.cpp @@ -0,0 +1,61 @@ +/* + SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "primaryoutput_v1_interface.h" + +#include "display.h" +#include "outputconfiguration_v2_interface.h" +#include "outputmanagement_v2_interface.h" + +#include "qwayland-server-kde-primary-output-v1.h" +#include + +#include + +namespace KWaylandServer +{ +static const quint32 s_version = 1; + +class PrimaryOutputV1InterfacePrivate : public QtWaylandServer::kde_primary_output_v1 +{ +public: + PrimaryOutputV1InterfacePrivate(Display *display) + : QtWaylandServer::kde_primary_output_v1(*display, s_version) + { + } + + void kde_primary_output_v1_bind_resource(Resource *resource) override + { + if (!m_outputName.isEmpty()) { + send_primary_output(resource->handle, m_outputName); + } + } + + QString m_outputName; +}; + +PrimaryOutputV1Interface::PrimaryOutputV1Interface(KWaylandServer::Display *display, QObject *parent) + : QObject(parent) + , d(new PrimaryOutputV1InterfacePrivate(display)) +{ +} + +PrimaryOutputV1Interface::~PrimaryOutputV1Interface() = default; + +void PrimaryOutputV1Interface::setPrimaryOutput(const QString &outputName) +{ + if (outputName == d->m_outputName) { + return; + } + d->m_outputName = outputName; + + const auto resources = d->resourceMap(); + for (auto *resource : resources) { + d->send_primary_output(resource->handle, outputName); + } +} + +} diff --git a/src/wayland/primaryoutput_v1_interface.h b/src/wayland/primaryoutput_v1_interface.h new file mode 100644 index 0000000000..a0d3e66c1a --- /dev/null +++ b/src/wayland/primaryoutput_v1_interface.h @@ -0,0 +1,37 @@ +/* + SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ +#pragma once + +#include + +#include + +namespace KWaylandServer +{ +class Display; +class OutputDeviceV2Interface; +class PrimaryOutputV1InterfacePrivate; + +class KWAYLANDSERVER_EXPORT PrimaryOutputV1Interface : public QObject +{ + Q_OBJECT + +public: + explicit PrimaryOutputV1Interface(Display *display, QObject *parent = nullptr); + ~PrimaryOutputV1Interface() override; + + /** + * Sets a primary output's @p outputName for the current display configuration + * + * It's up to the compositor to decide what the semantics are for it. + */ + void setPrimaryOutput(const QString &outputName); + +private: + QScopedPointer d; +}; + +}