File indexing completed on 2024-05-12 17:07:45

0001 /*
0002  *   SPDX-FileCopyrightText: 2021 Aleix Pol <apol@kde.org>
0003  *   SPDX-FileCopyrightText: 2021 Devin Lin <devin@kde.org>
0004  *
0005  *   SPDX-License-Identifier: GPL-2.0-or-later
0006  */
0007 
0008 #include "displaysmodel.h"
0009 
0010 #include <QGuiApplication>
0011 
0012 DisplaysModel::DisplaysModel(QObject *parent)
0013     : QAbstractListModel(parent)
0014 {
0015     if (!QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) {
0016         return;
0017     }
0018 
0019     using namespace KWayland::Client;
0020     ConnectionThread *connection = ConnectionThread::fromApplication(this);
0021 
0022     if (!connection) {
0023         return;
0024     }
0025 
0026     auto *registry = new Registry(this);
0027     registry->create(connection);
0028 
0029     connect(registry, &Registry::outputAnnounced, this, [this, registry](quint32 name, quint32 version) {
0030         createOutput(registry->bindOutput(name, version));
0031     });
0032     connect(registry, &Registry::plasmaWindowManagementAnnounced, this, [this, registry](quint32 name, quint32 version) {
0033         m_windowManagement = registry->createPlasmaWindowManagement(name, version, this);
0034     });
0035 
0036     registry->setup();
0037     connection->roundtrip();
0038 }
0039 
0040 QHash<int, QByteArray> DisplaysModel::roleNames() const
0041 {
0042     return {
0043         {Model, "modelName"},
0044         {Geometry, "geometry"},
0045         {Position, "position"},
0046         {Output, "output"},
0047     };
0048 }
0049 
0050 void DisplaysModel::createOutput(wl_output *output)
0051 {
0052     auto newOutput = new KWayland::Client::Output(this);
0053     connect(newOutput, &KWayland::Client::Output::removed, this, [this, newOutput] {
0054         auto i = m_outputs.indexOf(newOutput);
0055         Q_ASSERT(i >= 0);
0056         beginRemoveRows({}, i, i);
0057         m_outputs.removeAt(i);
0058         endRemoveRows();
0059     });
0060     newOutput->setup(output);
0061     beginInsertRows({}, m_outputs.count(), m_outputs.count());
0062     m_outputs.append(newOutput);
0063     endInsertRows();
0064 }
0065 
0066 void DisplaysModel::sendWindowToOutput(const QString &uuid, KWayland::Client::Output *output)
0067 {
0068     const auto windows = m_windowManagement->windows();
0069     for (auto w : windows) {
0070         if (w->uuid() == uuid) {
0071             w->sendToOutput(output);
0072         }
0073     }
0074 }
0075 
0076 int DisplaysModel::rowCount(const QModelIndex &parent) const
0077 {
0078     return parent.isValid() ? 0 : m_outputs.count();
0079 }
0080 
0081 QVariant DisplaysModel::data(const QModelIndex &index, int role) const
0082 {
0083     if (index.row() >= m_outputs.count()) {
0084         return {};
0085     }
0086 
0087     auto o = m_outputs[index.row()];
0088     switch (role) {
0089     case Model:
0090         return o->model();
0091     case Geometry:
0092         return o->geometry();
0093     case Position:
0094         return o->globalPosition();
0095     case Output:
0096         return QVariant::fromValue<QObject *>(o);
0097     }
0098     return {};
0099 }