diff --git a/ksplash/ksplashqml/splashapp.cpp b/ksplash/ksplashqml/splashapp.cpp index facf7f094..3b2b730ee 100644 --- a/ksplash/ksplashqml/splashapp.cpp +++ b/ksplash/ksplashqml/splashapp.cpp @@ -1,169 +1,171 @@ /* * Copyright (C) 2010 Ivan Cukic * Copyright (C) 2013 Martin Klapetek * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * or (at your option) any later version, as published by the Free * Software Foundation * * 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 "splashwindow.h" #include "splashapp.h" #include #include #include #include #include #include #include #include #include #include #include #define TEST_STEP_INTERVAL 2000 /** * There are 6 used stages in ksplash * - initial * - kinit * - ksmserver * - wm * - ready * - desktop */ SplashApp::SplashApp(int &argc, char ** argv) : QGuiApplication(argc, argv), m_stage(0), m_testing(false), m_window(false) { QCommandLineParser parser; parser.addOption(QCommandLineOption(QStringLiteral("test"), QStringLiteral("Run in test mode"))); parser.addOption(QCommandLineOption(QStringLiteral("window"), QStringLiteral("Run in windowed mode"))); parser.addOption(QCommandLineOption(QStringLiteral("nofork"), QStringLiteral("Don't fork"))); parser.addOption(QCommandLineOption(QStringLiteral("pid"), QStringLiteral("Print the pid of the child process"))); + parser.addPositionalArgument(QStringLiteral("theme"), QStringLiteral("Path to the theme to test")); parser.addHelpOption(); parser.process(*this); m_testing = parser.isSet(QStringLiteral("test")); m_window = parser.isSet(QStringLiteral("window")); + m_theme = parser.positionalArguments().value(0); setupWaylandIntegration(); foreach(QScreen* screen, screens()) adoptScreen(screen); setStage(QStringLiteral("initial")); if (KWindowSystem::isPlatformWayland()) { setStage(QStringLiteral("wm")); } QPixmap cursor(32, 32); cursor.fill(Qt::transparent); setOverrideCursor(QCursor(cursor)); if (m_testing) { m_timer.start(TEST_STEP_INTERVAL, this); } connect(this, &QGuiApplication::screenAdded, this, &SplashApp::adoptScreen); QDBusConnection dbus = QDBusConnection::sessionBus(); dbus.registerObject(QStringLiteral("/KSplash"), this, QDBusConnection::ExportScriptableSlots); dbus.registerService(QStringLiteral("org.kde.KSplash")); } SplashApp::~SplashApp() { qDeleteAll(m_windows); } void SplashApp::timerEvent(QTimerEvent * event) { if (event->timerId() == m_timer.timerId()) { m_timer.stop(); setStage(m_stage + 1); m_timer.start(TEST_STEP_INTERVAL, this); } } void SplashApp::setStage(const QString &stage) { //filter out startup events from KDED as they will be removed in a future release if (stage == QLatin1String("kded") || stage == QLatin1String("confupdate")) { return; } if (m_stages.contains(stage)) { return; } m_stages.append(stage); setStage(m_stages.count()); } void SplashApp::setStage(int stage) { if (m_stage == 6) { QGuiApplication::exit(EXIT_SUCCESS); } m_stage = stage; foreach (SplashWindow *w, m_windows) { w->setStage(stage); } } void SplashApp::adoptScreen(QScreen* screen) { - SplashWindow *w = new SplashWindow(m_testing, m_window); + SplashWindow *w = new SplashWindow(m_testing, m_window, m_theme); w->setGeometry(screen->geometry()); w->setStage(m_stage); w->setVisible(true); m_windows << w; connect(screen, &QScreen::geometryChanged, w, &SplashWindow::setGeometry); connect(screen, &QObject::destroyed, w, [this, w](){ m_windows.removeAll(w); w->deleteLater(); }); } void SplashApp::setupWaylandIntegration() { if (!KWindowSystem::isPlatformWayland()) { return; } using namespace KWayland::Client; ConnectionThread *connection = ConnectionThread::fromApplication(this); if (!connection) { return; } Registry *registry = new Registry(this); registry->create(connection); connect(registry, &Registry::plasmaShellAnnounced, this, [this, registry] (quint32 name, quint32 version) { m_waylandPlasmaShell = registry->createPlasmaShell(name, version, this); } ); registry->setup(); connection->roundtrip(); } diff --git a/ksplash/ksplashqml/splashapp.h b/ksplash/ksplashqml/splashapp.h index ae95be7b7..1cef922aa 100644 --- a/ksplash/ksplashqml/splashapp.h +++ b/ksplash/ksplashqml/splashapp.h @@ -1,74 +1,75 @@ /* * Copyright (C) 2010 Ivan Cukic * Copyright (C) 2013 Martin Klapetek * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * or (at your option) any later version, as published by the Free * Software Foundation * * 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 SPLASH_APP_H_ #define SPLASH_APP_H_ #include #include #include class SplashWindow; namespace KWayland { namespace Client { class PlasmaShell; } } class SplashApp: public QGuiApplication { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.KSplash") public: explicit SplashApp(int &argc, char ** argv); ~SplashApp() override; KWayland::Client::PlasmaShell *waylandPlasmaShellInterface() const { return m_waylandPlasmaShell; } public Q_SLOTS: Q_SCRIPTABLE void setStage(const QString &messgae); protected: void timerEvent(QTimerEvent *event) override; void setStage(int stage); private: void setupWaylandIntegration(); int m_stage; QList m_windows; bool m_testing; bool m_window; QStringList m_stages; QBasicTimer m_timer; + QString m_theme; KWayland::Client::PlasmaShell *m_waylandPlasmaShell = nullptr; private Q_SLOTS: void adoptScreen(QScreen*); }; #endif // SPLASH_APP_H_ diff --git a/ksplash/ksplashqml/splashwindow.cpp b/ksplash/ksplashqml/splashwindow.cpp index 5df357b8b..0ba65dfe2 100644 --- a/ksplash/ksplashqml/splashwindow.cpp +++ b/ksplash/ksplashqml/splashwindow.cpp @@ -1,166 +1,166 @@ /* * Copyright (C) 2010 Ivan Cukic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * or (at your option) any later version, as published by the Free * Software Foundation * * 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 "splashwindow.h" #include "splashapp.h" -#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -SplashWindow::SplashWindow(bool testing, bool window) +SplashWindow::SplashWindow(bool testing, bool window, const QString &theme) : KQuickAddons::QuickViewSharedEngine(), m_stage(0), m_testing(testing), - m_window(window) + m_window(window), + m_theme(theme) { setColor(Qt::transparent); setDefaultAlphaBuffer(true); setClearBeforeRendering(true); setResizeMode(KQuickAddons::QuickViewSharedEngine::SizeRootObjectToView); if (!m_window) { setFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); } if (!m_testing && !m_window) { if (KWindowSystem::isPlatformX11()) { // X11 specific hint only on X11 setFlags(Qt::BypassWindowManagerHint); } else if (!KWindowSystem::isPlatformWayland()) { // on other platforms go fullscreen // on Wayland we cannot go fullscreen due to QTBUG 54883 setWindowState(Qt::WindowFullScreen); } } if (m_testing && !m_window && !KWindowSystem::isPlatformWayland()) { setWindowState(Qt::WindowFullScreen); } //be sure it will be eventually closed //FIXME: should never be stuck QTimer::singleShot(30000, this, &QWindow::close); } void SplashWindow::setStage(int stage) { m_stage = stage; rootObject()->setProperty("stage", stage); } bool SplashWindow::event(QEvent *e) { if (e->type() == QEvent::PlatformSurface) { if (auto pe = dynamic_cast(e)) { switch (pe->surfaceEventType()) { case QPlatformSurfaceEvent::SurfaceCreated: setupWaylandIntegration(); break; case QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed: delete m_shellSurface; m_shellSurface = nullptr; break; } } } return KQuickAddons::QuickViewSharedEngine::event(e); } void SplashWindow::keyPressEvent(QKeyEvent *event) { KQuickAddons::QuickViewSharedEngine::keyPressEvent(event); if (m_testing && !event->isAccepted() && event->key() == Qt::Key_Escape) { close(); } } void SplashWindow::mousePressEvent(QMouseEvent *event) { KQuickAddons::QuickViewSharedEngine::mousePressEvent(event); if (m_testing && !event->isAccepted()) { close(); } } void SplashWindow::setGeometry(const QRect& rect) { bool oldGeometryEmpty = geometry().isNull(); KQuickAddons::QuickViewSharedEngine::setGeometry(rect); if (oldGeometryEmpty) { KPackage::Package package = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/LookAndFeel")); KConfigGroup cg(KSharedConfig::openConfig(QStringLiteral("kdeglobals")), "KDE"); const QString packageName = cg.readEntry("LookAndFeelPackage", QString()); if (!packageName.isEmpty()) { package.setPath(packageName); - }; + } - const QString theme = QGuiApplication::arguments().at(1); - if (!theme.startsWith(QLatin1String("--"))) { - package.setPath(theme); + if (!m_theme.isEmpty()) { + package.setPath(m_theme); } + Q_ASSERT(package.isValid()); setSource(QUrl::fromLocalFile(package.filePath("splashmainscript"))); } if (m_shellSurface) { m_shellSurface->setPosition(geometry().topLeft()); } } void SplashWindow::setupWaylandIntegration() { if (m_shellSurface) { // already setup return; } if (SplashApp *a = qobject_cast(qApp)) { using namespace KWayland::Client; PlasmaShell *interface = a->waylandPlasmaShellInterface(); if (!interface) { return; } Surface *s = Surface::fromWindow(this); if (!s) { return; } m_shellSurface = interface->createSurface(s, this); // Use OSD to make it go above all other windows // that's the closest we have to the X11 unmanged layer we have on Wayland m_shellSurface->setRole(PlasmaShellSurface::Role::OnScreenDisplay); m_shellSurface->setPosition(geometry().topLeft()); } } diff --git a/ksplash/ksplashqml/splashwindow.h b/ksplash/ksplashqml/splashwindow.h index 253676428..d26c8c2d0 100644 --- a/ksplash/ksplashqml/splashwindow.h +++ b/ksplash/ksplashqml/splashwindow.h @@ -1,58 +1,59 @@ /* * Copyright (C) 2010 Ivan Cukic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * or (at your option) any later version, as published by the Free * Software Foundation * * 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 SPLASH_WINDOW_H_ #define SPLASH_WINDOW_H_ #include class QResizeEvent; class QMouseEvent; class QKeyEvent; namespace KWayland { namespace Client { class PlasmaShellSurface; } } class SplashWindow: public KQuickAddons::QuickViewSharedEngine { public: - SplashWindow(bool testing = false, bool window = false); + SplashWindow(bool testing, bool window, const QString &theme); void setStage(int stage); virtual void setGeometry(const QRect &rect); protected: bool event(QEvent *e) override; void keyPressEvent(QKeyEvent *event) override; void mousePressEvent(QMouseEvent *event) override; private: void setupWaylandIntegration(); int m_stage; - bool m_testing; - bool m_window; + const bool m_testing; + const bool m_window; + const QString m_theme; KWayland::Client::PlasmaShellSurface *m_shellSurface = nullptr; }; #endif // SPLASH_WINDOW_H_