File indexing completed on 2024-05-12 09:32:10
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 #include <KX11Extras> 0016 0017 #include <QCursor> 0018 #include <QGuiApplication> 0019 #include <QQuickItem> 0020 #include <QScreen> 0021 #include <QStandardPaths> 0022 #include <QTimer> 0023 0024 #include <QQuickView> 0025 0026 using namespace KScreen; 0027 0028 Osd::Osd(const KScreen::OutputPtr &output, QObject *parent) 0029 : QObject(parent) 0030 , m_output(output) 0031 { 0032 connect(output.data(), &KScreen::Output::isConnectedChanged, this, &Osd::onOutputAvailabilityChanged); 0033 connect(output.data(), &KScreen::Output::isEnabledChanged, this, &Osd::onOutputAvailabilityChanged); 0034 m_engine.setProperty("_kirigamiTheme", QStringLiteral("KirigamiPlasmaStyle")); 0035 } 0036 0037 Osd::~Osd() 0038 { 0039 } 0040 0041 void Osd::showActionSelector() 0042 { 0043 if (!m_osdActionSelector) { 0044 m_osdActionSelector = std::make_unique<QQuickView>(&m_engine, nullptr); 0045 m_osdActionSelector->setInitialProperties({{QLatin1String("actions"), QVariant::fromValue(OsdAction::availableActions())}}); 0046 m_osdActionSelector->setSource(QUrl(QStringLiteral("qrc:/qml/OsdSelector.qml"))); 0047 m_osdActionSelector->setColor(Qt::transparent); 0048 m_osdActionSelector->setFlag(Qt::FramelessWindowHint); 0049 0050 if (m_osdActionSelector->status() != QQuickView::Ready) { 0051 qWarning() << "Failed to load OSD QML file"; 0052 m_osdActionSelector.reset(); 0053 return; 0054 } 0055 0056 auto rootObject = m_osdActionSelector->rootObject(); 0057 connect(rootObject, SIGNAL(clicked(int)), this, SLOT(onOsdActionSelected(int))); 0058 } 0059 0060 auto screen = qGuiApp->screenAt(m_output->pos()); 0061 if (!screen) { 0062 screen = qGuiApp->primaryScreen(); 0063 } 0064 0065 if (KWindowSystem::isPlatformWayland()) { 0066 auto layerWindow = LayerShellQt::Window::get(m_osdActionSelector.get()); 0067 layerWindow->setScope(QStringLiteral("on-screen-display")); 0068 layerWindow->setLayer(LayerShellQt::Window::LayerOverlay); 0069 layerWindow->setAnchors({}); 0070 layerWindow->setKeyboardInteractivity(LayerShellQt::Window::KeyboardInteractivityOnDemand); 0071 m_osdActionSelector->setScreen(screen); 0072 } else { 0073 auto newGeometry = m_osdActionSelector->geometry(); 0074 newGeometry.moveCenter(screen->geometry().center()); 0075 m_osdActionSelector->setGeometry(newGeometry); 0076 KX11Extras::setState(m_osdActionSelector->winId(), NET::SkipPager | NET::SkipSwitcher | NET::SkipTaskbar); 0077 KX11Extras::setType(m_osdActionSelector->winId(), NET::OnScreenDisplay); 0078 m_osdActionSelector->requestActivate(); 0079 } 0080 m_osdActionSelector->setVisible(true); 0081 } 0082 0083 void Osd::onOsdActionSelected(int action) 0084 { 0085 Q_EMIT osdActionSelected(static_cast<OsdAction::Action>(action)); 0086 hideOsd(); 0087 } 0088 0089 void Osd::onOutputAvailabilityChanged() 0090 { 0091 if (!m_output || !m_output->isConnected() || !m_output->isEnabled() || !m_output->currentMode()) { 0092 hideOsd(); 0093 } 0094 } 0095 0096 void Osd::hideOsd() 0097 { 0098 if (m_osdActionSelector) { 0099 m_osdActionSelector->setVisible(false); 0100 } 0101 } 0102 0103 #include "moc_osd.cpp"