File indexing completed on 2024-11-10 04:57:04
0001 /* 0002 SPDX-FileCopyrightText: 2022 David Redondo <kde@david-redondo.de> 0003 0004 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "outputlocator.h" 0008 #include "core/output.h" 0009 #include "effect/effecthandler.h" 0010 #include "effect/offscreenquickview.h" 0011 0012 #include <algorithm> 0013 0014 #include <KLocalizedString> 0015 0016 #include <QDBusConnection> 0017 #include <QQuickItem> 0018 0019 namespace KWin 0020 { 0021 0022 static QString outputName(const Output *screen) 0023 { 0024 const auto screens = effects->screens(); 0025 const bool shouldShowSerialNumber = std::any_of(screens.cbegin(), screens.cend(), [screen](const Output *other) { 0026 return other != screen && other->manufacturer() == screen->manufacturer() && other->model() == screen->model(); 0027 }); 0028 const bool shouldShowConnector = shouldShowSerialNumber && std::any_of(screens.cbegin(), screens.cend(), [screen](const Output *other) { 0029 return other != screen && other->serialNumber() == screen->serialNumber(); 0030 }); 0031 0032 QStringList parts; 0033 if (!screen->manufacturer().isEmpty()) { 0034 parts.append(screen->manufacturer()); 0035 } 0036 0037 if (!screen->model().isEmpty()) { 0038 parts.append(screen->model()); 0039 } 0040 0041 if (shouldShowSerialNumber && !screen->serialNumber().isEmpty()) { 0042 parts.append(screen->serialNumber()); 0043 } 0044 0045 if (shouldShowConnector) { 0046 parts.append(screen->name()); 0047 } 0048 0049 if (parts.isEmpty()) { 0050 return i18nc("@label", "Unknown"); 0051 } else { 0052 return parts.join(QLatin1Char(' ')); 0053 } 0054 } 0055 0056 OutputLocatorEffect::OutputLocatorEffect(QObject *parent) 0057 : Effect(parent) 0058 , m_qmlUrl(QUrl::fromLocalFile(QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kwin/effects/outputlocator/qml/OutputLabel.qml"))) 0059 { 0060 QDBusConnection::sessionBus().registerObject(QStringLiteral("/org/kde/KWin/Effect/OutputLocator1"), 0061 QStringLiteral("org.kde.KWin.Effect.OutputLocator1"), 0062 this, 0063 QDBusConnection::ExportAllSlots); 0064 connect(&m_showTimer, &QTimer::timeout, this, &OutputLocatorEffect::hide); 0065 } 0066 0067 bool OutputLocatorEffect::isActive() const 0068 { 0069 return m_showTimer.isActive(); 0070 } 0071 0072 void OutputLocatorEffect::show() 0073 { 0074 if (isActive()) { 0075 m_showTimer.start(std::chrono::milliseconds(2500)); 0076 return; 0077 } 0078 0079 const auto screens = effects->screens(); 0080 for (const auto screen : screens) { 0081 auto scene = new OffscreenQuickScene(); 0082 scene->setSource(m_qmlUrl, {{QStringLiteral("outputName"), outputName(screen)}, {QStringLiteral("resolution"), screen->geometry().size()}, {QStringLiteral("scale"), screen->scale()}}); 0083 QRectF geometry(0, 0, scene->rootItem()->implicitWidth(), scene->rootItem()->implicitHeight()); 0084 geometry.moveCenter(screen->geometry().center()); 0085 scene->setGeometry(geometry.toRect()); 0086 connect(scene, &OffscreenQuickView::repaintNeeded, this, [scene] { 0087 effects->addRepaint(scene->geometry()); 0088 }); 0089 m_scenesByScreens[screen].reset(scene); 0090 } 0091 0092 m_showTimer.start(std::chrono::milliseconds(2500)); 0093 } 0094 0095 void OutputLocatorEffect::hide() 0096 { 0097 m_showTimer.stop(); 0098 0099 QRegion repaintRegion; 0100 for (const auto &[screen, scene] : m_scenesByScreens) { 0101 repaintRegion += scene->geometry(); 0102 } 0103 0104 m_scenesByScreens.clear(); 0105 effects->addRepaint(repaintRegion); 0106 } 0107 0108 void OutputLocatorEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion ®ion, KWin::Output *screen) 0109 { 0110 effects->paintScreen(renderTarget, viewport, mask, region, screen); 0111 // On X11 all screens are painted at once 0112 if (effects->waylandDisplay()) { 0113 if (auto it = m_scenesByScreens.find(screen); it != m_scenesByScreens.end()) { 0114 effects->renderOffscreenQuickView(renderTarget, viewport, it->second.get()); 0115 } 0116 } else { 0117 for (const auto &[screen, scene] : m_scenesByScreens) { 0118 effects->renderOffscreenQuickView(renderTarget, viewport, scene.get()); 0119 } 0120 } 0121 } 0122 } 0123 0124 #include "moc_outputlocator.cpp"