1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
/*
SPDX-FileCopyrightText: 2014 Martin Klapetek <mklapetek@kde.org>
SPDX-FileCopyrightText: 2016 Sebastian Kügler <sebas@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "osd.h"
#include <KScreen/Mode>
#include <LayerShellQt/Window>
#include <KWindowSystem>
#include <KX11Extras>
#include <QCursor>
#include <QGuiApplication>
#include <QQuickItem>
#include <QScreen>
#include <QStandardPaths>
#include <QTimer>
#include <QQuickView>
using namespace KScreen;
Osd::Osd(const KScreen::OutputPtr &output, QObject *parent)
: QObject(parent)
, m_output(output)
{
connect(output.data(), &KScreen::Output::isConnectedChanged, this, &Osd::onOutputAvailabilityChanged);
connect(output.data(), &KScreen::Output::isEnabledChanged, this, &Osd::onOutputAvailabilityChanged);
m_engine.setProperty("_kirigamiTheme", QStringLiteral("KirigamiPlasmaStyle"));
}
Osd::~Osd()
{
}
void Osd::showActionSelector()
{
if (!m_osdActionSelector) {
m_osdActionSelector = std::make_unique<QQuickView>(&m_engine, nullptr);
m_osdActionSelector->setInitialProperties({{QLatin1String("actions"), QVariant::fromValue(OsdAction::availableActions())}});
m_osdActionSelector->loadFromModule("org.kde.kscreen.osd", "OsdSelector");
m_osdActionSelector->setColor(Qt::transparent);
m_osdActionSelector->setFlag(Qt::FramelessWindowHint);
if (m_osdActionSelector->status() != QQuickView::Ready) {
qWarning() << "Failed to load OSD QML file";
m_osdActionSelector.reset();
return;
}
auto rootObject = m_osdActionSelector->rootObject();
connect(rootObject, SIGNAL(clicked(int)), this, SLOT(onOsdActionSelected(int)));
}
auto screen = qGuiApp->screenAt(m_output->pos());
if (!screen) {
screen = qGuiApp->primaryScreen();
}
if (m_osdActionSelector->isVisible()) {
QMetaObject::invokeMethod(m_osdActionSelector->rootObject(), "moveRight");
}
if (KWindowSystem::isPlatformWayland()) {
auto layerWindow = LayerShellQt::Window::get(m_osdActionSelector.get());
layerWindow->setScope(QStringLiteral("on-screen-display"));
layerWindow->setLayer(LayerShellQt::Window::LayerOverlay);
layerWindow->setAnchors({});
layerWindow->setKeyboardInteractivity(LayerShellQt::Window::KeyboardInteractivityOnDemand);
m_osdActionSelector->setScreen(screen);
m_osdActionSelector->setVisible(true);
} else {
auto newGeometry = m_osdActionSelector->geometry();
newGeometry.moveCenter(screen->geometry().center());
KX11Extras::setState(m_osdActionSelector->winId(), NET::SkipPager | NET::SkipSwitcher | NET::SkipTaskbar);
KX11Extras::setType(m_osdActionSelector->winId(), NET::OnScreenDisplay);
m_osdActionSelector->setVisible(true);
// Workaround wrong geometry by setting geometry after it is visible, not before.
// Because KWin replace OSD at lower area of the screen.
m_osdActionSelector->setGeometry(newGeometry);
m_osdActionSelector->requestActivate();
}
}
void Osd::onOsdActionSelected(int action)
{
Q_EMIT osdActionSelected(static_cast<OsdAction::Action>(action));
hideOsd();
}
void Osd::onOutputAvailabilityChanged()
{
if (!m_output || !m_output->isConnected() || !m_output->isEnabled() || !m_output->currentMode()) {
hideOsd();
}
}
void Osd::hideOsd()
{
if (m_osdActionSelector) {
m_osdActionSelector->setVisible(false);
}
}
#include "moc_osd.cpp"
|