Commit 5751e862 authored by Aleix Pol Gonzalez's avatar Aleix Pol Gonzalez 🐧
Browse files

Do not prevent closing the main window while busy

Instead now we will hide the main window and let discover finish
performing the remaining transactions in the background.
Thus, now when we close we will:
- Hide the main window
- Show a SNI to restore the window
- Expose the transaction state in KUiServerJobTracker

BUG: 419622
parent a2c0e9b8
Pipeline #180422 passed with stage
in 1 minute and 15 seconds
......@@ -32,7 +32,7 @@ endif()
find_package(PkgConfig REQUIRED)
find_package(KF5 ${KF5_MIN_VERSION} REQUIRED CoreAddons Config Crash DBusAddons I18n Archive XmlGui ItemModels KIO Declarative KCMUtils IdleTime)
find_package(KF5 ${KF5_MIN_VERSION} REQUIRED CoreAddons Config Crash DBusAddons I18n Archive XmlGui ItemModels KIO Declarative KCMUtils IdleTime Notifications)
find_package(KF5Kirigami2 2.7.0)
find_package(packagekitqt5 1.0.1 CONFIG)
......@@ -66,7 +66,6 @@ endif()
option(WITH_NOTIFIER "Build and install the notifier plasmoid" ON)
if(WITH_NOTIFIER)
find_package(KF5 REQUIRED Notifications KIO)
add_subdirectory(notifier)
endif()
......
......@@ -44,6 +44,8 @@ target_link_libraries(plasma-discover PUBLIC
KF5::ConfigGui
KF5::KIOCore
KF5::WindowSystem
KF5::Notifications
KF5::JobWidgets
Qt::Widgets
Qt::Quick
Discover::Common
......
......@@ -11,6 +11,7 @@
#include "FeaturedModel.h"
#include "PaginateModel.h"
#include "UnityLauncher.h"
#include <Transaction/TransactionModel.h>
// Qt includes
#include "discover_debug.h"
......@@ -39,6 +40,8 @@
#include <KLocalizedContext>
#include <KLocalizedString>
#include <KSharedConfig>
#include <KStatusNotifierItem>
#include <KUiServerV2JobTracker>
#include <kcoreaddons_version.h>
// #include <KSwitchLanguageDialog>
......@@ -320,6 +323,84 @@ void DiscoverObject::openApplication(const QUrl &url)
}
}
class TransactionsJob : public KJob
{
public:
void start() override
{
// no-op, this is just observing
setTotalAmount(Items, TransactionModel::global()->rowCount());
setPercent(TransactionModel::global()->progress());
connect(TransactionModel::global(), &TransactionModel::lastTransactionFinished, this, &TransactionsJob::emitResult);
connect(TransactionModel::global(), &TransactionModel::transactionRemoved, this, &TransactionsJob::refreshInfo);
connect(TransactionModel::global(), &TransactionModel::progressChanged, this, [this] {
setPercent(TransactionModel::global()->progress());
});
refreshInfo();
}
void refreshInfo()
{
if (TransactionModel::global()->rowCount() == 0) {
return;
}
setProcessedAmount(Items, totalAmount(Items) - TransactionModel::global()->rowCount());
auto firstTransaction = TransactionModel::global()->transactions().constFirst();
Q_EMIT description(this, firstTransaction->name());
}
};
bool DiscoverObject::quitWhenIdle()
{
if (!ResourcesModel::global()->isBusy()) {
return true;
}
if (!m_sni) {
auto tracker = new KUiServerV2JobTracker(m_sni);
auto job = new TransactionsJob;
tracker->registerJob(job);
job->start();
m_sni = new KStatusNotifierItem(this);
m_sni->setStatus(KStatusNotifierItem::Active);
m_sni->setIconByName("plasmadiscover");
m_sni->setTitle(i18n("Discover"));
m_sni->setToolTip("process-working-symbolic", i18n("Discover"), i18n("Discover was closed before certain tasks were done, waiting for it to finish."));
m_sni->setStandardActionsEnabled(false);
connect(TransactionModel::global(), &TransactionModel::countChanged, this, &DiscoverObject::reconsiderQuit);
connect(m_sni, &KStatusNotifierItem::activateRequested, this, &DiscoverObject::restore);
rootObject()->hide();
}
return false;
}
void DiscoverObject::restore()
{
disconnect(TransactionModel::global(), &TransactionModel::countChanged, this, &DiscoverObject::reconsiderQuit);
disconnect(m_sni, &KStatusNotifierItem::activateRequested, this, &DiscoverObject::restore);
rootObject()->show();
m_sni->deleteLater();
m_sni = nullptr;
}
void DiscoverObject::reconsiderQuit()
{
if (ResourcesModel::global()->isBusy()) {
return;
}
m_sni->deleteLater();
// Let the job UI to finalise properly
QTimer::singleShot(20, qGuiApp, &QCoreApplication::quit);
}
void DiscoverObject::integrateObject(QObject *object)
{
if (!object) {
......@@ -349,8 +430,7 @@ void DiscoverObject::integrateObject(QObject *object)
object->setParent(m_engine);
connect(qGuiApp, &QGuiApplication::commitDataRequest, this, [this](QSessionManager &sessionManager) {
if (ResourcesModel::global()->isBusy()) {
Q_EMIT preventedClose();
if (!quitWhenIdle()) {
sessionManager.cancel();
}
});
......@@ -362,9 +442,7 @@ bool DiscoverObject::eventFilter(QObject *object, QEvent *event)
return false;
if (event->type() == QEvent::Close) {
if (ResourcesModel::global()->isBusy()) {
qCWarning(DISCOVER_LOG) << "not closing because there's still pending tasks";
Q_EMIT preventedClose();
if (!quitWhenIdle()) {
return true;
}
......
......@@ -13,6 +13,7 @@
class AbstractResource;
class Category;
class KStatusNotifierItem;
class QWindow;
class QQmlApplicationEngine;
class CachedNetworkAccessManagerFactory;
......@@ -56,6 +57,7 @@ public:
QRect initialGeometry() const;
QString describeSources() const;
Q_SCRIPTABLE void restore();
public Q_SLOTS:
void openApplication(const QUrl &app);
......@@ -77,13 +79,14 @@ Q_SIGNALS:
void listCategoryInternal(Category *cat);
void compactModeChanged(DiscoverObject::CompactMode compactMode);
void preventedClose();
void unableToFind(const QString &resid);
void openErrorPage(const QString &errorMessage);
private:
void showLoadingPage();
void integrateObject(QObject *object);
bool quitWhenIdle();
void reconsiderQuit();
QQmlApplicationEngine *engine() const
{
return m_engine;
......@@ -93,6 +96,7 @@ private:
CompactMode m_mode;
QScopedPointer<CachedNetworkAccessManagerFactory> m_networkAccessManagerFactory;
KStatusNotifierItem *m_sni = nullptr;
};
#endif // DISCOVEROBJECT_H
......@@ -144,9 +144,6 @@ Kirigami.ApplicationWindow
window.stack.push(errorPageComponent, { error: errorMessage, title: i18n("Error") })
}
function onPreventedClose() {
showPassiveNotification(i18n("Could not close Discover because some tasks are still in progress."), 20000, i18n("Quit Anyway"), function() { Qt.quit() })
}
function onUnableToFind(resid) {
showPassiveNotification(i18n("Unable to find resource: %1", resid));
Navigation.openHome()
......@@ -324,13 +321,16 @@ Kirigami.ApplicationWindow
function onProceedRequest(title, description) {
var dialog = proceedDialog.createObject(window, {transaction: transaction, title: title, description: description})
dialog.open()
app.restore()
}
function onPassiveMessage(message) {
window.showPassiveNotification(message)
app.restore()
}
function onDistroErrorMessage(message, actions) {
var dialog = distroErrorMessageDialog.createObject(window, {transaction: transaction, title: i18n("Error"), message: message})
dialog.open()
app.restore()
}
}
}
......
......@@ -39,14 +39,15 @@ void DummyTransaction::iterateTransaction()
} else if (status() == DownloadingStatus) {
setStatus(CommittingStatus);
QTimer::singleShot(/*KRandom::random()%*/ 100, this, &DummyTransaction::iterateTransaction);
} else
#ifdef TEST_PROCEED
} else if (resource()->name() == "Dummy 101") {
Q_EMIT proceedRequest(QStringLiteral("yadda yadda"),
QStringLiteral("Biii BOooo<ul><li>A</li><li>A</li>") + QStringLiteral("<li>A</li>").repeated(2)
+ QStringLiteral("<li>A</li></ul>"));
#else
finishTransaction();
#endif
} else {
finishTransaction();
}
}
void DummyTransaction::proceed()
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment