1 /**
2  * SPDX-FileCopyrightText: 2019 Aleix Pol Gonzalez <aleixpol@kde.org>
3  *
4  * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
5  */
6 
7 #include "presenterplugin.h"
8 
9 #include <KLocalizedString>
10 #include <KPluginFactory>
11 
12 #include <QDebug>
13 #include <QDBusConnection>
14 #include <QQuickView>
15 #include <QQmlError>
16 #include <QQuickItem>
17 #include <QtGlobal>
18 
19 #include <core/device.h>
20 #include <core/daemon.h>
21 #include <QScreen>
22 #include "plugin_presenter_debug.h"
23 
24 K_PLUGIN_CLASS_WITH_JSON(PresenterPlugin, "kdeconnect_presenter.json")
25 
26 class PresenterView : public QQuickView
27 {
28 public:
PresenterView()29     PresenterView() {
30         Qt::WindowFlags windowFlags = Qt::WindowFlags(Qt::WA_TranslucentBackground | Qt::WindowDoesNotAcceptFocus
31                                     | Qt::WindowFullScreen | Qt::WindowStaysOnTopHint
32                                     | Qt::FramelessWindowHint | Qt::Tool);
33 #ifdef Q_OS_WIN
34         windowFlags |= Qt::WindowTransparentForInput;
35 #endif
36         setFlags(windowFlags);
37         setClearBeforeRendering(true);
38         setColor(QColor(Qt::transparent));
39 
40         setResizeMode(QQuickView::SizeViewToRootObject);
41         setSource(QUrl(QStringLiteral("qrc:/presenter/Presenter.qml")));
42 
43         const auto ourErrors = errors();
44         for (const auto &error : ourErrors) {
45             qCWarning(KDECONNECT_PLUGIN_PRESENT) << "error" << error.description() << error.url() << error.line() << error.column();
46         }
47     }
48 };
49 
PresenterPlugin(QObject * parent,const QVariantList & args)50 PresenterPlugin::PresenterPlugin(QObject* parent, const QVariantList& args)
51     : KdeConnectPlugin(parent, args)
52     , m_view(nullptr)
53     , m_timer(new QTimer(this))
54 {
55     m_timer->setInterval(500);
56     m_timer->setSingleShot(true);
57 }
58 
~PresenterPlugin()59 PresenterPlugin::~PresenterPlugin()
60 {
61 }
62 
receivePacket(const NetworkPacket & np)63 bool PresenterPlugin::receivePacket(const NetworkPacket& np)
64 {
65     if (np.get<bool>(QStringLiteral("stop"), false)) {
66         delete m_view;
67         m_view = nullptr;
68         return true;
69     }
70 
71     if (!m_view) {
72         m_view = new PresenterView;
73         m_xPos = 0.5f;
74         m_yPos = 0.5f;
75         m_view->showFullScreen();
76         connect(this, &QObject::destroyed, m_view, &QObject::deleteLater);
77         connect(m_timer, &QTimer::timeout, m_view, &QObject::deleteLater);
78     }
79 
80     QSize screenSize = m_view->screen()->size();
81     float ratio = float(screenSize.width())/screenSize.height();
82 
83     m_xPos += np.get<float>(QStringLiteral("dx"));
84     m_yPos += np.get<float>(QStringLiteral("dy")) * ratio;
85     m_xPos = qBound(0.f, m_xPos, 1.f);
86     m_yPos = qBound(0.f, m_yPos, 1.f);
87 
88     m_timer->start();
89 
90     QQuickItem* object = m_view->rootObject();
91     object->setProperty("xPos", m_xPos);
92     object->setProperty("yPos", m_yPos);
93     return true;
94 }
95 
96 #include "presenterplugin.moc"
97 
98