KWin
Loading...
Searching...
No Matches
outputlocator.cpp
Go to the documentation of this file.
1/*
2 SPDX-FileCopyrightText: 2022 David Redondo <kde@david-redondo.de>
3
4 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
5*/
6
7#include "outputlocator.h"
8#include "core/output.h"
11
12#include <algorithm>
13
14#include <KLocalizedString>
15
16#include <QDBusConnection>
17#include <QQuickItem>
18
19namespace KWin
20{
21
22static QString outputName(const Output *screen)
23{
24 const auto screens = effects->screens();
25 const bool shouldShowSerialNumber = std::any_of(screens.cbegin(), screens.cend(), [screen](const Output *other) {
26 return other != screen && other->manufacturer() == screen->manufacturer() && other->model() == screen->model();
27 });
28 const bool shouldShowConnector = shouldShowSerialNumber && std::any_of(screens.cbegin(), screens.cend(), [screen](const Output *other) {
29 return other != screen && other->serialNumber() == screen->serialNumber();
30 });
31
32 QStringList parts;
33 if (!screen->manufacturer().isEmpty()) {
34 parts.append(screen->manufacturer());
35 }
36
37 if (!screen->model().isEmpty()) {
38 parts.append(screen->model());
39 }
40
41 if (shouldShowSerialNumber && !screen->serialNumber().isEmpty()) {
42 parts.append(screen->serialNumber());
43 }
44
45 if (shouldShowConnector) {
46 parts.append(screen->name());
47 }
48
49 if (parts.isEmpty()) {
50 return i18nc("@label", "Unknown");
51 } else {
52 return parts.join(QLatin1Char(' '));
53 }
54}
55
57 : Effect(parent)
58 , m_qmlUrl(QUrl::fromLocalFile(QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kwin/effects/outputlocator/qml/OutputLabel.qml")))
59{
60 QDBusConnection::sessionBus().registerObject(QStringLiteral("/org/kde/KWin/Effect/OutputLocator1"),
61 QStringLiteral("org.kde.KWin.Effect.OutputLocator1"),
62 this,
63 QDBusConnection::ExportAllSlots);
64 connect(&m_showTimer, &QTimer::timeout, this, &OutputLocatorEffect::hide);
65}
66
68{
69 return m_showTimer.isActive();
70}
71
73{
74 if (isActive()) {
75 m_showTimer.start(std::chrono::milliseconds(2500));
76 return;
77 }
78
79 const auto screens = effects->screens();
80 for (const auto screen : screens) {
81 auto scene = new OffscreenQuickScene();
82 scene->setSource(m_qmlUrl, {{QStringLiteral("outputName"), outputName(screen)}, {QStringLiteral("resolution"), screen->geometry().size()}, {QStringLiteral("scale"), screen->scale()}});
83 QRectF geometry(0, 0, scene->rootItem()->implicitWidth(), scene->rootItem()->implicitHeight());
84 geometry.moveCenter(screen->geometry().center());
85 scene->setGeometry(geometry.toRect());
86 connect(scene, &OffscreenQuickView::repaintNeeded, this, [scene] {
87 effects->addRepaint(scene->geometry());
88 });
89 m_scenesByScreens[screen].reset(scene);
90 }
91
92 m_showTimer.start(std::chrono::milliseconds(2500));
93}
94
96{
97 m_showTimer.stop();
98
99 QRegion repaintRegion;
100 for (const auto &[screen, scene] : m_scenesByScreens) {
101 repaintRegion += scene->geometry();
102 }
103
104 m_scenesByScreens.clear();
105 effects->addRepaint(repaintRegion);
106}
107
108void OutputLocatorEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion &region, KWin::Output *screen)
109{
110 effects->paintScreen(renderTarget, viewport, mask, region, screen);
111 // On X11 all screens are painted at once
112 if (effects->waylandDisplay()) {
113 if (auto it = m_scenesByScreens.find(screen); it != m_scenesByScreens.end()) {
114 effects->renderOffscreenQuickView(renderTarget, viewport, it->second.get());
115 }
116 } else {
117 for (const auto &[screen, scene] : m_scenesByScreens) {
118 effects->renderOffscreenQuickView(renderTarget, viewport, scene.get());
119 }
120 }
121}
122}
123
124#include "moc_outputlocator.cpp"
Base class for all KWin effects.
Definition effect.h:535
Display * waylandDisplay() const
void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion &region, Output *screen)
Q_SCRIPTABLE void addRepaint(const QRectF &r)
QList< Output * > screens() const
void renderOffscreenQuickView(const RenderTarget &renderTarget, const RenderViewport &viewport, OffscreenQuickView *effectQuickView) const
void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion &region, KWin::Output *screen) override
OutputLocatorEffect(QObject *parent=nullptr)
bool isActive() const override
EffectsHandler * effects