diff --git a/kded/osd.cpp b/kded/osd.cpp index 051c515..6227f0d 100644 --- a/kded/osd.cpp +++ b/kded/osd.cpp @@ -1,133 +1,147 @@ /* * Copyright 2014 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 "debug.h" #include #include #include #include #include namespace KScreen { -Osd::Osd(QObject *parent) +Osd::Osd(const KScreen::OutputPtr output, QObject *parent) : QObject(parent) + , m_output(output) , m_osdPath(QStandardPaths::locate(QStandardPaths::QStandardPaths::GenericDataLocation, QStringLiteral("kded_kscreen/qml/Osd.qml"))) , m_osdObject(new KDeclarative::QmlObject(this)) { if (m_osdPath.isEmpty()) { qCWarning(KSCREEN_KDED) << "Failed to find OSD QML file" << m_osdPath; } m_osdObject->setSource(QUrl::fromLocalFile(m_osdPath)); if (m_osdObject->status() != QQmlComponent::Ready) { qCWarning(KSCREEN_KDED) << "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); } } Osd::~Osd() { } +void Osd::showGenericOsd(const QString &icon, const QString &text) +{ + m_outputGeometry = m_output->geometry(); + auto *rootObject = m_osdObject->rootObject(); + rootObject->setProperty("itemSource", QStringLiteral("OsdItem.qml")); + rootObject->setProperty("infoText", text); + rootObject->setProperty("icon", icon); + qCDebug(KSCREEN_KDED) << "icon / text:" << icon << text; + + showOsd(); +} + void Osd::showOutputIdentifier(const KScreen::OutputPtr output) { 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")); + //rootObject->setProperty("icon", QStringLiteral("preferences-desktop-display-randr")); showOsd(); } void Osd::updatePosition() { 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_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); + + qCDebug(KSCREEN_KDED) << "pos:" << QPoint(pos_x, pos_y); } void Osd::showOsd() { m_osdTimer->stop(); auto *rootObject = m_osdObject->rootObject(); // only animate on X11, wayland plugin doesn't support this and // pukes loads of warnings into our logs if (qGuiApp->platformName() == QStringLiteral("xcb")) { + qCDebug(KSCREEN_KDED) << "vibsible"; 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 164bcc2..244fb61 100644 --- a/kded/osd.h +++ b/kded/osd.h @@ -1,64 +1,67 @@ /* * Copyright 2014 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 KSCREEN_OSD_H #define KSCREEN_OSD_H #include #include #include #include namespace KDeclarative { class QmlObject; } class QTimer; namespace KScreen { class Osd : public QObject { Q_OBJECT public: - Osd(QObject *parent = nullptr); + Osd(const KScreen::OutputPtr output, QObject *parent = nullptr); ~Osd() override; + void showGenericOsd(const QString &icon, const QString &text); void showOutputIdentifier(const KScreen::OutputPtr output); + private Q_SLOTS: void hideOsd(); private: void showOsd(); void updatePosition(); + KScreen::OutputPtr m_output; QString m_osdPath; QRect m_outputGeometry; KDeclarative::QmlObject *m_osdObject = nullptr; QTimer *m_osdTimer = nullptr; int m_timeout = 0; }; } // ns #endif // KSCREEN_OSD_H diff --git a/kded/osdmanager.cpp b/kded/osdmanager.cpp index f792643..c9e2189 100644 --- a/kded/osdmanager.cpp +++ b/kded/osdmanager.cpp @@ -1,91 +1,120 @@ /* * 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 "debug.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()) { 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); + osd = new KScreen::Osd(output, this); m_osds.insert(output->name(), osd); } osd->showOutputIdentifier(output); } m_cleanupTimer->start(); } +void OsdManager::showOsd(const QString& icon, const QString& text) +{ + connect(new KScreen::GetConfigOperation(), &KScreen::GetConfigOperation::finished, + this, [this, icon, text] (KScreen::ConfigOperation *op) { + qCDebug(KSCREEN_KDED) << "whoooooopwhoooooopwhoooooop"; + if (op->hasError()) { + return; + } + + const KScreen::ConfigPtr config = qobject_cast(op)->config(); + + Q_FOREACH (const KScreen::OutputPtr &output, config->outputs()) { + 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(output, this); + m_osds.insert(output->name(), osd); + } + osd->showGenericOsd(icon, text); + } + m_cleanupTimer->start(); + }); +} + } diff --git a/kded/osdmanager.h b/kded/osdmanager.h index 38f8351..8cdb8cb 100644 --- a/kded/osdmanager.h +++ b/kded/osdmanager.h @@ -1,56 +1,57 @@ /* * 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() override; static OsdManager* self(); public Q_SLOTS: void showOutputIdentifiers(); + void showOsd(const QString &icon, const QString &text); private: OsdManager(QObject *parent = nullptr); void slotIdentifyOutputs(KScreen::ConfigOperation *op); QMap m_osds; static OsdManager* m_instance; QTimer* m_cleanupTimer; }; } // ns #endif // OSDM_H diff --git a/kded/qml/Osd.qml b/kded/qml/Osd.qml index 65db294..7406910 100644 --- a/kded/qml/Osd.qml +++ b/kded/qml/Osd.qml @@ -1,61 +1,62 @@ /* * Copyright 2014 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, see . */ import QtQuick 2.0 import QtQuick.Window 2.2 import org.kde.plasma.core 2.0 as PlasmaCore PlasmaCore.Dialog { id: root location: PlasmaCore.Types.Floating type: PlasmaCore.Dialog.OnScreenDisplay outputOnly: true // OSD Timeout in msecs - how long it will stay on the screen property int timeout: 5000 // Icon name to display property string icon + property string infoText property string outputName property string modeName property bool animateOpacity: false property string itemSource Behavior on opacity { SequentialAnimation { // prevent press and hold from flickering PauseAnimation { duration: root.timeout * 0.8 } NumberAnimation { duration: root.timeout * 0.2 easing.type: Easing.InQuad } } enabled: root.animateOpacity } mainItem: Loader { source: itemSource onItemChanged: { if (item != undefined) { item.rootItem = root; } } } } diff --git a/kded/qml/OsdItem.qml b/kded/qml/OsdItem.qml index 7d239e3..5f9d673 100644 --- a/kded/qml/OsdItem.qml +++ b/kded/qml/OsdItem.qml @@ -1,52 +1,53 @@ /* * Copyright 2014 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, see . */ import QtQuick 2.5 import QtQuick.Window 2.2 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.extras 2.0 as PlasmaExtra Item { property QtObject rootItem PlasmaCore.IconItem { id: icon height: parent.height - label.height - ((units.smallSpacing/2) * 3) width: parent.width source: rootItem.icon } PlasmaExtra.Heading { id: label anchors { bottom: parent.bottom left: parent.left right: parent.right margins: Math.floor(units.smallSpacing / 2) } - text: outputName + text: rootItem.infoText horizontalAlignment: Text.AlignHCenter wrapMode: Text.WordWrap maximumLineCount: 2 elide: Text.ElideLeft minimumPointSize: theme.defaultFont.pointSize fontSizeMode: Text.HorizontalFit } + Component.onCompleted: print("osditem loaded..." + root.infoText); } diff --git a/tests/osd/osdtest.cpp b/tests/osd/osdtest.cpp index 0a3872b..6f25720 100644 --- a/tests/osd/osdtest.cpp +++ b/tests/osd/osdtest.cpp @@ -1,44 +1,45 @@ /************************************************************************************* * Copyright 2016 Sebastian Kügler * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * * License as published by the Free Software Foundation; either * * version 2.1 of the License, or (at your option) any later version. * * * * This library 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 * * Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with this library; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *************************************************************************************/ #include "osdtest.h" #include "../../kded/osdmanager.h" #include #include Q_LOGGING_CATEGORY(KSCREEN_KDED, "kscreen.kded") namespace KScreen { OsdTest::OsdTest(QObject *parent) : QObject(parent) { } OsdTest::~OsdTest() { } void OsdTest::start() { QTimer::singleShot(5500, qApp, &QCoreApplication::quit); - KScreen::OsdManager::self()->showOutputIdentifiers(); +// KScreen::OsdManager::self()->showOutputIdentifiers(); + KScreen::OsdManager::self()->showOsd(QStringLiteral("preferences-desktop-display-randr"), QStringLiteral("OSD Showing Up")); } } // ns