File indexing completed on 2024-12-08 13:21:58

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2011 Arthur Arlt <a.arlt@stud.uni-heidelberg.de>
0006     SPDX-FileCopyrightText: 2013 Martin Gräßlin <mgraesslin@kde.org>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 // own
0011 #include "outline.h"
0012 // KWin
0013 #include "composite.h"
0014 #include "main.h"
0015 #include "scripting/scripting.h"
0016 #include "utils/common.h"
0017 // Frameworks
0018 #include <KConfigGroup>
0019 // Qt
0020 #include <QDebug>
0021 #include <QQmlComponent>
0022 #include <QQmlContext>
0023 #include <QQmlEngine>
0024 #include <QQuickWindow>
0025 #include <QStandardPaths>
0026 
0027 namespace KWin
0028 {
0029 
0030 Outline::Outline()
0031     : m_active(false)
0032 {
0033     connect(Compositor::self(), &Compositor::compositingToggled, this, &Outline::compositingChanged);
0034 }
0035 
0036 Outline::~Outline() = default;
0037 
0038 void Outline::show()
0039 {
0040     if (!m_visual) {
0041         createHelper();
0042     }
0043     if (!m_visual) {
0044         // something went wrong
0045         return;
0046     }
0047     m_visual->show();
0048     m_active = true;
0049     Q_EMIT activeChanged();
0050 }
0051 
0052 void Outline::hide()
0053 {
0054     if (!m_active) {
0055         return;
0056     }
0057     m_active = false;
0058     Q_EMIT activeChanged();
0059     if (!m_visual) {
0060         return;
0061     }
0062     m_visual->hide();
0063 }
0064 
0065 void Outline::show(const QRect &outlineGeometry)
0066 {
0067     show(outlineGeometry, QRect());
0068 }
0069 
0070 void Outline::show(const QRect &outlineGeometry, const QRect &visualParentGeometry)
0071 {
0072     setGeometry(outlineGeometry);
0073     setVisualParentGeometry(visualParentGeometry);
0074     show();
0075 }
0076 
0077 void Outline::setGeometry(const QRect &outlineGeometry)
0078 {
0079     if (m_outlineGeometry == outlineGeometry) {
0080         return;
0081     }
0082     m_outlineGeometry = outlineGeometry;
0083     Q_EMIT geometryChanged();
0084     Q_EMIT unifiedGeometryChanged();
0085 }
0086 
0087 void Outline::setVisualParentGeometry(const QRect &visualParentGeometry)
0088 {
0089     if (m_visualParentGeometry == visualParentGeometry) {
0090         return;
0091     }
0092     m_visualParentGeometry = visualParentGeometry;
0093     Q_EMIT visualParentGeometryChanged();
0094     Q_EMIT unifiedGeometryChanged();
0095 }
0096 
0097 QRect Outline::unifiedGeometry() const
0098 {
0099     return m_outlineGeometry | m_visualParentGeometry;
0100 }
0101 
0102 void Outline::createHelper()
0103 {
0104     if (m_visual) {
0105         return;
0106     }
0107     m_visual = kwinApp()->createOutline(this);
0108 }
0109 
0110 void Outline::compositingChanged()
0111 {
0112     m_visual.reset();
0113     if (m_active) {
0114         show();
0115     }
0116 }
0117 
0118 const QRect &Outline::geometry() const
0119 {
0120     return m_outlineGeometry;
0121 }
0122 
0123 const QRect &Outline::visualParentGeometry() const
0124 {
0125     return m_visualParentGeometry;
0126 }
0127 
0128 bool Outline::isActive() const
0129 {
0130     return m_active;
0131 }
0132 
0133 OutlineVisual::OutlineVisual(Outline *outline)
0134     : m_outline(outline)
0135 {
0136 }
0137 
0138 OutlineVisual::~OutlineVisual()
0139 {
0140 }
0141 
0142 CompositedOutlineVisual::CompositedOutlineVisual(Outline *outline)
0143     : OutlineVisual(outline)
0144     , m_qmlContext()
0145     , m_qmlComponent()
0146     , m_mainItem()
0147 {
0148 }
0149 
0150 CompositedOutlineVisual::~CompositedOutlineVisual()
0151 {
0152 }
0153 
0154 void CompositedOutlineVisual::hide()
0155 {
0156     if (QQuickWindow *w = qobject_cast<QQuickWindow *>(m_mainItem.get())) {
0157         w->hide();
0158         w->destroy();
0159     }
0160 }
0161 
0162 void CompositedOutlineVisual::show()
0163 {
0164     if (!m_qmlContext) {
0165         m_qmlContext = std::make_unique<QQmlContext>(Scripting::self()->qmlEngine());
0166         m_qmlContext->setContextProperty(QStringLiteral("outline"), m_outline);
0167     }
0168     if (!m_qmlComponent) {
0169         m_qmlComponent = std::make_unique<QQmlComponent>(Scripting::self()->qmlEngine());
0170         const QString fileName = QStandardPaths::locate(QStandardPaths::GenericDataLocation,
0171                                                         kwinApp()->config()->group(QStringLiteral("Outline")).readEntry("QmlPath", QStringLiteral("kwin/outline/plasma/outline.qml")));
0172         if (fileName.isEmpty()) {
0173             qCDebug(KWIN_CORE) << "Could not locate outline.qml";
0174             return;
0175         }
0176         m_qmlComponent->loadUrl(QUrl::fromLocalFile(fileName));
0177         if (m_qmlComponent->isError()) {
0178             qCDebug(KWIN_CORE) << "Component failed to load: " << m_qmlComponent->errors();
0179         } else {
0180             m_mainItem.reset(m_qmlComponent->create(m_qmlContext.get()));
0181         }
0182         if (auto w = qobject_cast<QQuickWindow *>(m_mainItem.get())) {
0183             w->setProperty("__kwin_outline", true);
0184         }
0185     }
0186 }
0187 
0188 } // namespace