diff --git a/kded/osd.cpp b/kded/osd.cpp index 6e3e3bc..7ad0fa8 100644 --- a/kded/osd.cpp +++ b/kded/osd.cpp @@ -1,195 +1,138 @@ /* * Copyright 2014 (c) Martin Klapetek * Copyright 2016 Sebastian Kügler * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "osd.h" #include "utils.h" #include -#include #include #include -#include +// #include #include #include -#include -#include +// #include +// #include #include namespace KScreen { Osd::Osd(QObject *parent) : QObject(parent) , m_osdPath(QStandardPaths::locate(QStandardPaths::QStandardPaths::GenericDataLocation, QStringLiteral("kded_kscreen/qml/Osd.qml"))) + , m_osdObject(new KDeclarative::QmlObject(this)) { - init(); -} + if (m_osdPath.isEmpty()) { + qWarning() << "Failed to find OSD QML file" << m_osdPath; + } -Osd::~Osd() -{ + m_osdObject->setSource(QUrl::fromLocalFile(m_osdPath)); + + if (m_osdObject->status() != QQmlComponent::Ready) { + qWarning() << "Failed to load OSD QML file" << m_osdPath; + return; + } + + m_timeout = m_osdObject->rootObject()->property("timeout").toInt(); + + if (!m_osdTimer) { + m_osdTimer = new QTimer(this); + m_osdTimer->setSingleShot(true); + connect(m_osdTimer, &QTimer::timeout, this, &Osd::hideOsd); + } } -bool Osd::setRootProperty(const char* name, const QVariant& value) +Osd::~Osd() { - return m_osdObject->rootObject()->setProperty(name, value); } void Osd::showOutputIdentifier(const KScreen::OutputPtr output) { - m_output = output; - if (!init()) { - return; - } + m_outputGeometry = output->geometry(); auto *rootObject = m_osdObject->rootObject(); auto mode = output->currentMode(); QSize realSize; if (output->isHorizontal()) { realSize = mode->size(); } else { realSize = QSize(mode->size().height(), mode->size().width()); } rootObject->setProperty("itemSource", QStringLiteral("OutputIdentifier.qml")); rootObject->setProperty("modeName", Utils::sizeToString(realSize)); rootObject->setProperty("outputName", Utils::outputName(output)); rootObject->setProperty("icon", QStringLiteral("preferences-desktop-display-randr")); + //QTimer::singleShot(200, this, &Osd::showOsd); showOsd(); } void Osd::updatePosition() { - if (m_output == nullptr) { + if (!m_outputGeometry.isValid()) { return; } auto *rootObject = m_osdObject->rootObject(); const int dialogWidth = rootObject->property("width").toInt(); const int dialogHeight = rootObject->property("height").toInt(); - const int relx = m_output->pos().x(); - const int rely = m_output->pos().y(); - const int pos_x = relx + (m_output->geometry().width() - dialogWidth) / 2; - const int pos_y = rely + (m_output->geometry().height() - dialogHeight) / 2; + const int relx = m_outputGeometry.x(); + const int rely = m_outputGeometry.y(); + const int pos_x = relx + (m_outputGeometry.width() - dialogWidth) / 2; + const int pos_y = rely + (m_outputGeometry.height() - dialogHeight) / 2; rootObject->setProperty("x", pos_x); rootObject->setProperty("y", pos_y); } - -bool Osd::init() -{ - if (m_osdObject && m_osdObject->rootObject()) { - return true; - } - - if (m_osdPath.isEmpty()) { - return false; - } - - if (!m_osdObject) { - m_osdObject = new KDeclarative::QmlObject(this); - } - - m_osdObject->setSource(QUrl::fromLocalFile(m_osdPath)); - - if (m_osdObject->status() != QQmlComponent::Ready) { - qWarning() << "Failed to load OSD QML file" << m_osdPath; - return false; - } - - m_timeout = m_osdObject->rootObject()->property("timeout").toInt(); - - if (!m_osdTimer) { - m_osdTimer = new QTimer(this); - m_osdTimer->setSingleShot(true); - connect(m_osdTimer, &QTimer::timeout, this, &Osd::hideOsd); - } - - return true; -} - -void Osd::showProgress(const QString &icon, const int percent, const QString &additionalText) -{ - if (!init()) { - return; - } - - auto *rootObject = m_osdObject->rootObject(); - - int value = qBound(0, percent, 100); - rootObject->setProperty("osdValue", value); - rootObject->setProperty("osdAdditionalText", additionalText); - rootObject->setProperty("showingProgress", true); - rootObject->setProperty("icon", icon); - - emit osdProgress(icon, value, additionalText); - showOsd(); -} - -void Osd::showText(const QString &icon, const QString &text) -{ - if (!init()) { - return; - } - - auto *rootObject = m_osdObject->rootObject(); - - rootObject->setProperty("showingProgress", false); - rootObject->setProperty("osdValue", text); - rootObject->setProperty("icon", icon); - - emit osdText(icon, text); - showOsd(); -} - void Osd::showOsd() { m_osdTimer->stop(); auto *rootObject = m_osdObject->rootObject(); // if our OSD understands animating the opacity, do it; // otherwise just show it to not break existing lnf packages if (rootObject->property("animateOpacity").isValid()) { rootObject->setProperty("animateOpacity", false); rootObject->setProperty("opacity", 1); rootObject->setProperty("visible", true); rootObject->setProperty("animateOpacity", true); rootObject->setProperty("opacity", 0); } else { rootObject->setProperty("visible", true); } updatePosition(); m_osdTimer->start(m_timeout); } void Osd::hideOsd() { auto *rootObject = m_osdObject->rootObject(); if (!rootObject) { return; } rootObject->setProperty("visible", false); // this is needed to prevent fading from "old" values when the OSD shows up rootObject->setProperty("osdValue", 0); } } // ns diff --git a/kded/osd.h b/kded/osd.h index 449d251..b00f0be 100644 --- a/kded/osd.h +++ b/kded/osd.h @@ -1,76 +1,64 @@ /* * Copyright 2014 (c) Martin Klapetek * Copyright 2016 Sebastian Kügler * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef OSD_H -#define OSD_H +#ifndef KSCREEN_OSD_H +#define KSCREEN_OSD_H #include +#include #include #include -class QmlObject; namespace KDeclarative { class QmlObject; } -namespace Plasma { -} class QTimer; namespace KScreen { class Osd : public QObject { + Q_OBJECT public: Osd(QObject *parent = nullptr); ~Osd() override; - bool setRootProperty(const char *name, const QVariant &value); void showOutputIdentifier(const KScreen::OutputPtr output); -public Q_SLOTS: - void showText(const QString &icon, const QString &text); - -Q_SIGNALS: - void osdProgress(const QString &icon, const int percent, const QString &additionalText); - void osdText(const QString &icon, const QString &text); - private Q_SLOTS: void hideOsd(); private: - bool init(); - - void showProgress(const QString &icon, const int percent, const QString &additionalText = QString()); void showOsd(); - void updatePosition(); + QString m_osdPath; + QRect m_outputGeometry; KDeclarative::QmlObject *m_osdObject = nullptr; QTimer *m_osdTimer = nullptr; int m_timeout = 0; - KScreen::OutputPtr m_output; }; } // ns -#endif // OSD_H +#endif // KSCREEN_OSD_H diff --git a/kded/osdmanager.cpp b/kded/osdmanager.cpp index c7adc52..70fee23 100644 --- a/kded/osdmanager.cpp +++ b/kded/osdmanager.cpp @@ -1,96 +1,92 @@ /* * Copyright 2016 Sebastian Kügler * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "osdmanager.h" #include "osd.h" #include #include #include #include #include #include namespace KScreen { OsdManager* OsdManager::m_instance = 0; OsdManager::OsdManager(QObject *parent) : QObject(parent) + , m_cleanupTimer(new QTimer(this)) { + // free up memory when the osd hasn't been used for more than 1 minute + m_cleanupTimer->setInterval(60000); + m_cleanupTimer->setSingleShot(true); + connect(m_cleanupTimer, &QTimer::timeout, this, [this]() { + qDeleteAll(m_osds.begin(), m_osds.end()); + m_osds.clear(); + }); + QDBusConnection::sessionBus().registerObject(QStringLiteral("/org/kde/kscreen/osdService"), this, QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals); } OsdManager::~OsdManager() { } OsdManager* OsdManager::self() { if (!OsdManager::m_instance) { m_instance = new OsdManager(); } return m_instance; } void OsdManager::showOutputIdentifiers() { connect(new KScreen::GetConfigOperation(), &KScreen::GetConfigOperation::finished, this, &OsdManager::slotIdentifyOutputs); } void OsdManager::slotIdentifyOutputs(KScreen::ConfigOperation *op) { if (op->hasError()) { return; } const KScreen::ConfigPtr config = qobject_cast(op)->config(); Q_FOREACH (const KScreen::OutputPtr &output, config->outputs()) { - connect(output.data(), &KScreen::Output::isConnectedChanged, - this, [this](){ - KScreen::Output *output = qobject_cast(sender()); - qDebug() << "outputConnectedChanged():" << output->name(); - if (!output->isConnected() || !output->isEnabled() || !output->currentMode()) { - KScreen::Osd* osd = nullptr; - if (m_osds.keys().contains(output->name())) { - osd->deleteLater(); - m_osds.remove(output->name()); - } - } - }, Qt::UniqueConnection); - if (!output->isConnected() || !output->isEnabled() || !output->currentMode()) { continue; } - KScreen::Osd* osd = nullptr; if (m_osds.keys().contains(output->name())) { osd = m_osds.value(output->name()); } else { osd = new KScreen::Osd(this); m_osds.insert(output->name(), osd); } osd->showOutputIdentifier(output); } + m_cleanupTimer->start(); } } diff --git a/kded/osdmanager.h b/kded/osdmanager.h index 70d2400..38f8351 100644 --- a/kded/osdmanager.h +++ b/kded/osdmanager.h @@ -1,56 +1,56 @@ /* * Copyright 2016 Sebastian Kügler * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef OSDM_H #define OSDM_H #include #include #include +#include class QmlObject; namespace KScreen { class ConfigOperation; class Osd; class Output; class OsdManager : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.kscreen.osdService") + public: - OsdManager(QObject *parent = nullptr); ~OsdManager() override; - static OsdManager* self(); - public Q_SLOTS: void showOutputIdentifiers(); private: + OsdManager(QObject *parent = nullptr); void slotIdentifyOutputs(KScreen::ConfigOperation *op); QMap m_osds; static OsdManager* m_instance; - bool m_showing; + QTimer* m_cleanupTimer; }; } // ns #endif // OSDM_H