File indexing completed on 2024-04-28 16:45:09
0001 /* 0002 SPDX-FileCopyrightText: 2014 Martin Klapetek <mklapetek@kde.org> 0003 SPDX-FileCopyrightText: 2016 Sebastian Kügler <sebas@kde.org> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "osd.h" 0009 0010 #include <KScreen/Mode> 0011 0012 #include <LayerShellQt/Window> 0013 0014 #include <KWindowSystem> 0015 0016 #include <QCursor> 0017 #include <QGuiApplication> 0018 #include <QQuickItem> 0019 #include <QScreen> 0020 #include <QStandardPaths> 0021 #include <QTimer> 0022 0023 #include <QQuickView> 0024 0025 using namespace KScreen; 0026 0027 Osd::Osd(const KScreen::OutputPtr &output, QObject *parent) 0028 : QObject(parent) 0029 , m_output(output) 0030 { 0031 connect(output.data(), &KScreen::Output::isConnectedChanged, this, &Osd::onOutputAvailabilityChanged); 0032 connect(output.data(), &KScreen::Output::isEnabledChanged, this, &Osd::onOutputAvailabilityChanged); 0033 } 0034 0035 Osd::~Osd() 0036 { 0037 } 0038 0039 void Osd::showActionSelector() 0040 { 0041 if (!m_osdActionSelector) { 0042 m_osdActionSelector = std::make_unique<QQuickView>(&m_engine, nullptr); 0043 m_osdActionSelector->setInitialProperties({{QLatin1String("actions"), QVariant::fromValue(OsdAction::availableActions())}}); 0044 m_osdActionSelector->setSource(QUrl(QStringLiteral("qrc:/qml/OsdSelector.qml"))); 0045 m_osdActionSelector->setColor(Qt::transparent); 0046 m_osdActionSelector->setFlag(Qt::FramelessWindowHint); 0047 0048 if (m_osdActionSelector->status() != QQuickView::Ready) { 0049 qWarning() << "Failed to load OSD QML file"; 0050 m_osdActionSelector.reset(); 0051 return; 0052 } 0053 0054 auto rootObject = m_osdActionSelector->rootObject(); 0055 connect(rootObject, SIGNAL(clicked(int)), this, SLOT(onOsdActionSelected(int))); 0056 } 0057 0058 if (KWindowSystem::isPlatformWayland()) { 0059 auto layerWindow = LayerShellQt::Window::get(m_osdActionSelector.get()); 0060 layerWindow->setScope(QStringLiteral("on-screen-display")); 0061 layerWindow->setLayer(LayerShellQt::Window::LayerOverlay); 0062 layerWindow->setAnchors({}); 0063 layerWindow->setDesiredOutput(qGuiApp->screenAt(m_output->pos())); 0064 } else { 0065 auto newGeometry = m_osdActionSelector->geometry(); 0066 auto screen = qGuiApp->screenAt(m_output->pos()); 0067 newGeometry.moveCenter(screen ? screen->geometry().center() : qGuiApp->primaryScreen()->geometry().center()); 0068 m_osdActionSelector->setGeometry(newGeometry); 0069 KWindowSystem::setState(m_osdActionSelector->winId(), NET::SkipPager | NET::SkipSwitcher | NET::SkipTaskbar); 0070 KWindowSystem::setType(m_osdActionSelector->winId(), NET::OnScreenDisplay); 0071 m_osdActionSelector->requestActivate(); 0072 } 0073 m_osdActionSelector->setVisible(true); 0074 } 0075 0076 void Osd::onOsdActionSelected(int action) 0077 { 0078 Q_EMIT osdActionSelected(static_cast<OsdAction::Action>(action)); 0079 hideOsd(); 0080 } 0081 0082 void Osd::onOutputAvailabilityChanged() 0083 { 0084 if (!m_output || !m_output->isConnected() || !m_output->isEnabled() || !m_output->currentMode()) { 0085 hideOsd(); 0086 } 0087 } 0088 0089 void Osd::hideOsd() 0090 { 0091 if (m_osdActionSelector) { 0092 m_osdActionSelector->setVisible(false); 0093 } 0094 }