File indexing completed on 2024-12-08 13:22:27

0001 /*
0002 *  Copyright 2016  Smith AR <audoban@openmailbox.org>
0003 *                  Michail Vourlakos <mvourlakos@gmail.com>
0004 *
0005 *  This file is part of Latte-Dock
0006 *
0007 *  Latte-Dock is free software; you can redistribute it and/or
0008 *  modify it under the terms of the GNU General Public License as
0009 *  published by the Free Software Foundation; either version 2 of
0010 *  the License, or (at your option) any later version.
0011 *
0012 *  Latte-Dock is distributed in the hope that it will be useful,
0013 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0014 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0015 *  GNU General Public License for more details.
0016 *
0017 *  You should have received a copy of the GNU General Public License
0018 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
0019 */
0020 
0021 #include "infoview.h"
0022 
0023 // local
0024 #include <config-latte.h>
0025 #include "wm/abstractwindowinterface.h"
0026 #include "view/panelshadows_p.h"
0027 
0028 // Qt
0029 #include <QQuickItem>
0030 #include <QQmlContext>
0031 #include <QQmlEngine>
0032 #include <QScreen>
0033 
0034 // KDE
0035 #include <KLocalizedContext>
0036 #include <KDeclarative/KDeclarative>
0037 #include <KWindowSystem>
0038 #include <KWayland/Client/plasmashell.h>
0039 #include <KWayland/Client/surface.h>
0040 
0041 // Plasma
0042 #include <Plasma/Package>
0043 
0044 namespace Latte {
0045 
0046 InfoView::InfoView(Latte::Corona *corona, QString message, QScreen *screen, QWindow *parent)
0047     : QQuickView(parent),
0048       m_corona(corona),
0049       m_message(message),
0050       m_screen(screen)
0051 {
0052     setupWaylandIntegration();
0053 
0054     setResizeMode(QQuickView::SizeViewToRootObject);
0055     setColor(QColor(Qt::transparent));
0056     setDefaultAlphaBuffer(true);
0057 
0058     setIcon(qGuiApp->windowIcon());
0059 
0060     setScreen(screen);
0061     setFlags(wFlags());
0062 
0063     init();
0064 }
0065 
0066 InfoView::~InfoView()
0067 {
0068     PanelShadows::self()->removeWindow(this);
0069 
0070     qDebug() << "InfoView deleting ...";
0071 
0072     if (m_shellSurface) {
0073         delete m_shellSurface;
0074         m_shellSurface = nullptr;
0075     }
0076 }
0077 
0078 void InfoView::init()
0079 {
0080     rootContext()->setContextProperty(QStringLiteral("infoWindow"), this);
0081 
0082     KDeclarative::KDeclarative kdeclarative;
0083     kdeclarative.setDeclarativeEngine(engine());
0084     kdeclarative.setTranslationDomain(QStringLiteral("latte-dock"));
0085 #if KF5_VERSION_MINOR >= 45
0086     kdeclarative.setupContext();
0087     kdeclarative.setupEngine(engine());
0088 #else
0089     kdeclarative.setupBindings();
0090 #endif
0091 
0092     auto source = QUrl::fromLocalFile(m_corona->kPackage().filePath("infoviewui"));
0093     setSource(source);
0094 
0095     rootObject()->setProperty("message", m_message);
0096 
0097     syncGeometry();
0098 }
0099 
0100 Plasma::FrameSvg::EnabledBorders InfoView::enabledBorders() const
0101 {
0102     return m_borders;
0103 }
0104 
0105 
0106 inline Qt::WindowFlags InfoView::wFlags() const
0107 {
0108     return (flags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint) & ~Qt::WindowDoesNotAcceptFocus;
0109 }
0110 
0111 void InfoView::syncGeometry()
0112 {
0113     const QSize size(rootObject()->width(), rootObject()->height());
0114     const auto sGeometry = screen()->geometry();
0115 
0116     setMaximumSize(size);
0117     setMinimumSize(size);
0118     resize(size);
0119 
0120     QPoint position{sGeometry.center().x() - size.width() / 2, sGeometry.center().y() - size.height() / 2 };
0121 
0122     setPosition(position);
0123 
0124     if (m_shellSurface) {
0125         m_shellSurface->setPosition(position);
0126     }
0127 }
0128 
0129 void InfoView::showEvent(QShowEvent *ev)
0130 {
0131     QQuickWindow::showEvent(ev);
0132 
0133     m_corona->wm()->setViewExtraFlags(*this);
0134     setFlags(wFlags());
0135 
0136     m_corona->wm()->enableBlurBehind(*this);
0137 
0138     syncGeometry();
0139 
0140     QTimer::singleShot(400, this, &InfoView::syncGeometry);
0141 
0142     PanelShadows::self()->addWindow(this);
0143     PanelShadows::self()->setEnabledBorders(this, m_borders);
0144 }
0145 
0146 void InfoView::setupWaylandIntegration()
0147 {
0148     if (m_shellSurface) {
0149         // already setup
0150         return;
0151     }
0152 
0153     if (m_corona) {
0154         using namespace KWayland::Client;
0155         PlasmaShell *interface = m_corona->waylandCoronaInterface();
0156 
0157         if (!interface) {
0158             return;
0159         }
0160 
0161         Surface *s = Surface::fromWindow(this);
0162 
0163         if (!s) {
0164             return;
0165         }
0166 
0167         qDebug() << "wayland dock window surface was created...";
0168 
0169         m_shellSurface = interface->createSurface(s, this);
0170     }
0171 }
0172 
0173 bool InfoView::event(QEvent *e)
0174 {
0175     if (e->type() == QEvent::PlatformSurface) {
0176         if (auto pe = dynamic_cast<QPlatformSurfaceEvent *>(e)) {
0177             switch (pe->surfaceEventType()) {
0178                 case QPlatformSurfaceEvent::SurfaceCreated:
0179 
0180                     if (m_shellSurface) {
0181                         break;
0182                     }
0183 
0184                     setupWaylandIntegration();
0185                     break;
0186 
0187                 case QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed:
0188                     if (m_shellSurface) {
0189                         delete m_shellSurface;
0190                         m_shellSurface = nullptr;
0191                     }
0192 
0193                     PanelShadows::self()->removeWindow(this);
0194                     break;
0195             }
0196         }
0197     }
0198 
0199     return QQuickWindow::event(e);
0200 }
0201 
0202 void InfoView::setOnActivities(QStringList activities)
0203 {
0204     KWindowSystem::setOnActivities(winId(), activities);
0205 }
0206 
0207 }
0208 // kate: indent-mode cstyle; indent-width 4; replace-tabs on;