File indexing completed on 2024-05-12 05:37:59

0001 /*
0002     SPDX-FileCopyrightText: 2010 Ivan Cukic <ivan.cukic(at)kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "splashwindow.h"
0008 #include "debug.h"
0009 #include "splashapp.h"
0010 
0011 #include <KConfigGroup>
0012 #include <KSharedConfig>
0013 #include <QKeyEvent>
0014 #include <QMouseEvent>
0015 #include <QQmlContext>
0016 #include <QQuickItem>
0017 #include <QStandardPaths>
0018 #include <QSurfaceFormat>
0019 #include <QTimer>
0020 
0021 #include <LayerShellQt/Window>
0022 
0023 #include <KPackage/Package>
0024 #include <KPackage/PackageLoader>
0025 
0026 #include <KWindowSystem>
0027 
0028 using namespace Qt::StringLiterals;
0029 
0030 SplashWindow::SplashWindow(bool testing, bool window, const QString &theme, QScreen *screen)
0031     : PlasmaQuick::QuickViewSharedEngine()
0032     , m_stage(0)
0033     , m_testing(testing)
0034     , m_window(window)
0035     , m_theme(theme)
0036 {
0037     if (KWindowSystem::isPlatformWayland()) {
0038         if (auto layerShellWindow = LayerShellQt::Window::get(this)) {
0039             layerShellWindow->setScope(QStringLiteral("ksplashqml"));
0040             layerShellWindow->setLayer(LayerShellQt::Window::LayerOverlay);
0041             layerShellWindow->setExclusiveZone(-1);
0042             layerShellWindow->setKeyboardInteractivity(LayerShellQt::Window::KeyboardInteractivityExclusive);
0043         }
0044     }
0045 
0046     setCursor(Qt::BlankCursor);
0047     setScreen(screen);
0048     setColor(Qt::transparent);
0049     setDefaultAlphaBuffer(true);
0050     setResizeMode(PlasmaQuick::QuickViewSharedEngine::SizeRootObjectToView);
0051 
0052     if (!m_window) {
0053         setFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
0054     }
0055 
0056     if (!m_testing && !m_window) {
0057         if (KWindowSystem::isPlatformX11()) {
0058             // X11 specific hint only on X11
0059             setFlags(Qt::BypassWindowManagerHint);
0060         } else if (!KWindowSystem::isPlatformWayland()) {
0061             // on other platforms go fullscreen
0062             // on Wayland we cannot go fullscreen due to QTBUG 54883
0063             setWindowState(Qt::WindowFullScreen);
0064         }
0065     }
0066 
0067     if (m_testing && !m_window && !KWindowSystem::isPlatformWayland()) {
0068         setWindowState(Qt::WindowFullScreen);
0069     }
0070 
0071     // be sure it will be eventually closed
0072     // FIXME: should never be stuck
0073     QTimer::singleShot(30000, this, &QWindow::close);
0074 }
0075 
0076 void SplashWindow::setStage(int stage)
0077 {
0078     m_stage = stage;
0079     Q_ASSERT(rootObject());
0080     if (rootObject()) { // could be null if source loading failed
0081         rootObject()->setProperty("stage", stage);
0082     }
0083 }
0084 
0085 void SplashWindow::keyPressEvent(QKeyEvent *event)
0086 {
0087     PlasmaQuick::QuickViewSharedEngine::keyPressEvent(event);
0088     if (m_testing && !event->isAccepted() && event->key() == Qt::Key_Escape) {
0089         close();
0090     }
0091 }
0092 
0093 void SplashWindow::mousePressEvent(QMouseEvent *event)
0094 {
0095     PlasmaQuick::QuickViewSharedEngine::mousePressEvent(event);
0096     if (m_testing && !event->isAccepted()) {
0097         close();
0098     }
0099 }
0100 
0101 void SplashWindow::setGeometry(const QRect &rect)
0102 {
0103     bool oldGeometryEmpty = geometry().isNull();
0104     PlasmaQuick::QuickViewSharedEngine::setGeometry(rect);
0105 
0106     if (oldGeometryEmpty) {
0107         KPackage::Package package = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/LookAndFeel"));
0108         const auto originalPackagePath = package.path();
0109         KConfigGroup cg(KSharedConfig::openConfig(), u"KDE"_s);
0110         const QString packageName = cg.readEntry("LookAndFeelPackage", QString());
0111         if (!packageName.isEmpty()) {
0112             package.setPath(packageName);
0113         }
0114 
0115         if (!m_theme.isEmpty()) {
0116             package.setPath(m_theme);
0117         }
0118 
0119         const auto url = QUrl::fromLocalFile(package.filePath("splashmainscript"));
0120         qCDebug(KSPLASHQML_DEBUG) << "Loading" << url << "from" << package.path();
0121         if (!package.isValid() || !url.isValid() || url.isEmpty()) {
0122             qCWarning(KSPLASHQML_DEBUG) << "Failed to resolve package url" << url //
0123                                         << "package.valid" << package.isValid() //
0124                                         << "package.path" << package.path() //
0125                                         << "originalPackagePath" << originalPackagePath //
0126                                         << "packageName" << packageName //
0127                                         << "theme" << m_theme;
0128             Q_ASSERT(package.isValid());
0129             Q_ASSERT(url.isValid());
0130             Q_ASSERT(!url.isEmpty());
0131         }
0132         setSource(url);
0133     }
0134 }