File indexing completed on 2024-04-28 16:54:34

0001 /*
0002     SPDX-FileCopyrightText: 2019 Kai Uwe Broulik <kde@privat.broulik.de>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #include "mirroredscreenstracker_p.h"
0008 
0009 #include <QRect>
0010 
0011 #include <KScreen/ConfigMonitor>
0012 #include <KScreen/GetConfigOperation>
0013 #include <KScreen/Output>
0014 
0015 #include "debug.h"
0016 
0017 using namespace NotificationManager;
0018 
0019 MirroredScreensTracker::MirroredScreensTracker()
0020     : QObject(nullptr)
0021 {
0022     connect(new KScreen::GetConfigOperation(KScreen::GetConfigOperation::NoEDID),
0023             &KScreen::ConfigOperation::finished,
0024             this,
0025             [this](KScreen::ConfigOperation *op) {
0026                 m_screenConfiguration = qobject_cast<KScreen::GetConfigOperation *>(op)->config();
0027                 checkScreensMirrored();
0028 
0029                 KScreen::ConfigMonitor::instance()->addConfig(m_screenConfiguration);
0030                 connect(KScreen::ConfigMonitor::instance(), &KScreen::ConfigMonitor::configurationChanged, this, &MirroredScreensTracker::checkScreensMirrored);
0031             });
0032 }
0033 
0034 MirroredScreensTracker::~MirroredScreensTracker() = default;
0035 
0036 MirroredScreensTracker::Ptr MirroredScreensTracker::createTracker()
0037 {
0038     static QWeakPointer<MirroredScreensTracker> s_instance;
0039     if (!s_instance) {
0040         QSharedPointer<MirroredScreensTracker> ptr(new MirroredScreensTracker());
0041         s_instance = ptr.toWeakRef();
0042         return ptr;
0043     }
0044     return s_instance.toStrongRef();
0045 }
0046 
0047 bool MirroredScreensTracker::screensMirrored() const
0048 {
0049     return m_screensMirrored;
0050 }
0051 
0052 void MirroredScreensTracker::setScreensMirrored(bool mirrored)
0053 {
0054     if (m_screensMirrored != mirrored) {
0055         m_screensMirrored = mirrored;
0056         Q_EMIT screensMirroredChanged(mirrored);
0057     }
0058 }
0059 
0060 void MirroredScreensTracker::checkScreensMirrored()
0061 {
0062     if (!m_screenConfiguration) {
0063         setScreensMirrored(false);
0064         return;
0065     }
0066 
0067     const auto outputs = m_screenConfiguration->outputs();
0068     for (const KScreen::OutputPtr &output : outputs) {
0069         if (!output->isConnected() || !output->isEnabled()) {
0070             continue;
0071         }
0072 
0073         for (const KScreen::OutputPtr &checkOutput : outputs) {
0074             if (checkOutput == output || !checkOutput->isConnected() || !checkOutput->isEnabled()) {
0075                 continue;
0076             }
0077 
0078             if (output->geometry().contains(checkOutput->geometry()) || checkOutput->geometry().contains(output->geometry())) {
0079                 qCDebug(NOTIFICATIONMANAGER) << "Screen geometry" << checkOutput->geometry() << "and" << output->geometry()
0080                                              << "are completely overlapping - considering them to be mirrored";
0081                 setScreensMirrored(true);
0082                 return;
0083             }
0084         }
0085     }
0086 
0087     setScreensMirrored(false);
0088 }