File indexing completed on 2024-04-28 16:49:41
0001 /* 0002 * SPDX-FileCopyrightText: 2014 Sebastian Kügler <sebas@kde.org> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.1-or-later 0005 */ 0006 0007 #include "qscreenconfig.h" 0008 #include "qscreenbackend.h" 0009 #include "qscreenoutput.h" 0010 #include "qscreenscreen.h" 0011 0012 #include <config.h> 0013 #include <mode.h> 0014 #include <output.h> 0015 0016 #include <QGuiApplication> 0017 #include <QRect> 0018 0019 #include <utility> 0020 0021 using namespace KScreen; 0022 0023 QScreenConfig::QScreenConfig(QObject *parent) 0024 : QObject(parent) 0025 , m_screen(new QScreenScreen(this)) 0026 , m_blockSignals(true) 0027 { 0028 for (const QScreen *qscreen : QGuiApplication::screens()) { 0029 screenAdded(qscreen); 0030 } 0031 m_blockSignals = false; 0032 connect(qApp, &QGuiApplication::screenAdded, this, &QScreenConfig::screenAdded); 0033 connect(qApp, &QGuiApplication::screenRemoved, this, &QScreenConfig::screenRemoved); 0034 } 0035 0036 QScreenConfig::~QScreenConfig() 0037 { 0038 qDeleteAll(m_outputMap); 0039 } 0040 0041 ConfigPtr QScreenConfig::toKScreenConfig() const 0042 { 0043 ConfigPtr config(new Config); 0044 config->setScreen(m_screen->toKScreenScreen()); 0045 updateKScreenConfig(config); 0046 return config; 0047 } 0048 0049 int QScreenConfig::outputId(const QScreen *qscreen) 0050 { 0051 for (auto output : std::as_const(m_outputMap)) { 0052 if (qscreen == output->qscreen()) { 0053 return output->id(); 0054 } 0055 } 0056 m_lastOutputId++; 0057 return m_lastOutputId; 0058 } 0059 0060 void QScreenConfig::screenAdded(const QScreen *qscreen) 0061 { 0062 qCDebug(KSCREEN_QSCREEN) << "Screen added" << qscreen << qscreen->name(); 0063 QScreenOutput *qscreenoutput = new QScreenOutput(qscreen, this); 0064 qscreenoutput->setId(outputId(qscreen)); 0065 m_outputMap.insert(qscreenoutput->id(), qscreenoutput); 0066 0067 if (!m_blockSignals) { 0068 Q_EMIT configChanged(toKScreenConfig()); 0069 } 0070 } 0071 0072 void QScreenConfig::screenRemoved(QScreen *qscreen) 0073 { 0074 qCDebug(KSCREEN_QSCREEN) << "Screen removed" << qscreen << QGuiApplication::screens().count(); 0075 // Find output matching the QScreen object and remove it 0076 int removedOutputId = -1; 0077 for (auto output : m_outputMap) { 0078 if (output->qscreen() == qscreen) { 0079 removedOutputId = output->id(); 0080 m_outputMap.remove(removedOutputId); 0081 delete output; 0082 } 0083 } 0084 Q_EMIT configChanged(toKScreenConfig()); 0085 } 0086 0087 void QScreenConfig::updateKScreenConfig(ConfigPtr &config) const 0088 { 0089 KScreen::ScreenPtr screen = config->screen(); 0090 m_screen->updateKScreenScreen(screen); 0091 config->setScreen(screen); 0092 0093 // Removing removed outputs 0094 KScreen::OutputList outputs = config->outputs(); 0095 for (const KScreen::OutputPtr &output : outputs) { 0096 if (!m_outputMap.contains(output->id())) { 0097 config->removeOutput(output->id()); 0098 } 0099 } 0100 0101 // Add KScreen::Outputs that aren't in the list yet, handle primaryOutput 0102 for (QScreenOutput *output : m_outputMap) { 0103 KScreen::OutputPtr kscreenOutput; 0104 if (config->outputs().contains(output->id())) { 0105 kscreenOutput = config->outputs()[output->id()]; 0106 output->updateKScreenOutput(kscreenOutput); 0107 } else { 0108 kscreenOutput = output->toKScreenOutput(); 0109 config->addOutput(kscreenOutput); 0110 } 0111 if (QGuiApplication::primaryScreen() == output->qscreen()) { 0112 config->setPrimaryOutput(kscreenOutput); 0113 } 0114 } 0115 } 0116 0117 QMap<int, QScreenOutput *> QScreenConfig::outputMap() const 0118 { 0119 return m_outputMap; 0120 }