From 2006500942289adc01b1cd4524850e85cbd8e17a Mon Sep 17 00:00:00 2001 From: momen Date: Sun, 3 May 2026 23:13:10 +0800 Subject: [PATCH 1/8] Bump version 5.0.12 --- CMakeLists.txt | 2 + com.gxde.controlcenter.update.policy | 22 ++ debian/changelog | 5 +- src/frame/modules/update/updateview.cpp | 11 +- src/frame/modules/update/updatework.cpp | 210 ++++++++++++++++++ src/frame/modules/update/updatework.h | 8 + .../gxde-control-center/gxde-update-worker.sh | 139 ++++++++++++ 7 files changed, 387 insertions(+), 10 deletions(-) create mode 100644 com.gxde.controlcenter.update.policy create mode 100755 tools/gxde-control-center/gxde-update-worker.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index c1c68d8..cebbb18 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,12 +57,14 @@ install(FILES data/timezone.db DESTINATION share/gxde-control-center) #internal testing group install(DIRECTORY tools/gxde-control-center DESTINATION share/) +install(PROGRAMS tools/gxde-control-center/gxde-update-worker.sh DESTINATION lib/gxde-control-center) # conf file install(FILES ${CMAKE_CURRENT_BINARY_DIR}/files/gxde-control-center.conf DESTINATION share/gxde-control-center) # polkit policy file +install(FILES com.gxde.controlcenter.update.policy DESTINATION share/polkit-1/actions) if (OS_DEEPIN_PROFESSIONAL) if (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64") install(FILES com.deepin.controlcenter.addomain.policy DESTINATION share/polkit-1/actions) diff --git a/com.gxde.controlcenter.update.policy b/com.gxde.controlcenter.update.policy new file mode 100644 index 0000000..8b1cef7 --- /dev/null +++ b/com.gxde.controlcenter.update.policy @@ -0,0 +1,22 @@ + + + + GXDE + https://gxde.top + + + gxde-control-center + Run GXDE Control Center update helper + 运行 GXDE 控制中心更新助手 + Authentication is required to update system packages + 更新系统软件包需要认证 + + no + auth_admin + auth_admin_keep + + /usr/lib/gxde-control-center/gxde-update-worker.sh + + diff --git a/debian/changelog b/debian/changelog index 52f9655..796d019 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -gxde-control-center (5.0.11) UNRELEASED; urgency=medium +gxde-control-center (5.0.12) UNRELEASED; urgency=medium * 修复屏幕缩放调整条不对准刻度的问题 * 修复系统信息在时间异常时显示类似 ©2023-1970 等错误信息的问题 @@ -22,8 +22,9 @@ gxde-control-center (5.0.11) UNRELEASED; urgency=medium * 启用 deepin 云同步 * 修复高分屏下声音高级设置中选中图标模糊的问题 * 使 VNC 密码输入框样式与其他设置项的输入框样式统一 + * 内置更新模块,优先使用 aptss 进行系统更新 - -- gfdgd_xi <3025613752@qq.com> Sun, 03 May 2026 07:49:49 +0800 + -- gfdgd_xi <3025613752@qq.com> Sun, 03 May 2026 23:12:28 +0800 gxde-control-center (4.10.29.1) UNRELEASED; urgency=medium diff --git a/src/frame/modules/update/updateview.cpp b/src/frame/modules/update/updateview.cpp index 1ad1941..497c421 100644 --- a/src/frame/modules/update/updateview.cpp +++ b/src/frame/modules/update/updateview.cpp @@ -29,8 +29,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -59,11 +59,7 @@ UpdateView::UpdateView() // m_centralLayout->addWidget(m_settingsGroup); m_neoUpgrader = new Dtk::Widget::DPushButton; m_neoUpgrader->setText(tr("Check and perform system Upgrade")); - if (QFile::exists("/usr/bin/gxde-app-upgrader")) { - // 需要保证脚本存在才会显示按钮 - //m_centralLayout->addWidget(m_neoUpgrader); - m_centralLayout->addWidget(m_neoUpgrader); - } + m_centralLayout->addWidget(m_neoUpgrader); m_addTestingSource = new Dtk::Widget::DPushButton; m_addTestingSource->setText(tr("Internal Testing Group Settings")); @@ -106,8 +102,7 @@ void UpdateView::init() void UpdateView::ExecUpgrader() { - QProcess process; - system("/usr/bin/gxde-app-upgrader &"); + Q_EMIT pushUpdate(); } void UpdateView::ShowTesingDialog() diff --git a/src/frame/modules/update/updatework.cpp b/src/frame/modules/update/updatework.cpp index 93f4626..500f900 100644 --- a/src/frame/modules/update/updatework.cpp +++ b/src/frame/modules/update/updatework.cpp @@ -30,6 +30,8 @@ #include #include #include +#include +#include #define MIN_NM_ACTIVE 50 @@ -73,6 +75,7 @@ UpdateWorker::UpdateWorker(UpdateModel* model, QObject *parent) , m_onBattery(true) , m_batteryPercentage(0) , m_baseProgress(0) + , m_aptssProcess(nullptr) { m_managerInter->setSync(false); m_updateInter->setSync(false); @@ -127,6 +130,30 @@ void UpdateWorker::deactivate() void UpdateWorker::checkForUpdates() { + if (m_aptssProcess) { + return; + } + + m_model->setStatus(UpdatesStatus::Checking); + m_model->setUpdateProgress(0); + + m_aptssProcess = new QProcess(this); + connect(m_aptssProcess, static_cast(&QProcess::finished), this, [this](int exitCode, QProcess::ExitStatus exitStatus) { + const QByteArray errorOutput = m_aptssProcess->readAllStandardError(); + if (exitStatus != QProcess::NormalExit || exitCode != 0) { + qWarning() << "aptss update failed:" << errorOutput; + m_model->setStatus(UpdatesStatus::UpdateFailed); + clearAptssProcess(); + return; + } + + m_model->setUpdateProgress(0.5); + clearAptssProcess(); + runAptssCheckList(); + }); + m_aptssProcess->start(updateWorkerPath(), QStringList() << "update"); + return; + if (checkDbusIsValid()) { return; } @@ -324,16 +351,199 @@ void UpdateWorker::resumeDownload() void UpdateWorker::distUpgrade() { + const QStringList packages = upgradablePackages(); + if (m_aptssProcess || packages.isEmpty()) { + return; + } + + m_model->setStatus(UpdatesStatus::Installing); + m_model->setUpgradeProgress(0); + + m_aptssProcess = new QProcess(this); + connect(m_aptssProcess, &QProcess::readyReadStandardOutput, this, [this] { + const QString output = QString::fromLocal8Bit(m_aptssProcess->readAllStandardOutput()); + if (output.contains('%')) { + const QRegExp rx("(\\d+)%"); + if (rx.indexIn(output) != -1) { + m_model->setUpgradeProgress(rx.cap(1).toDouble() / 100.0); + } + } + }); + connect(m_aptssProcess, static_cast(&QProcess::finished), this, [this](int exitCode, QProcess::ExitStatus exitStatus) { + if (exitStatus == QProcess::NormalExit && exitCode == 0) { + m_model->setUpgradeProgress(1); + m_model->setStatus(UpdatesStatus::UpdateSucceeded); + + QProcess::startDetached("/usr/lib/gxde-control-center/reboot-reminder-dialog"); + + QFile file("/tmp/.dcc-update-successd"); + if (!file.exists()) { + file.open(QIODevice::WriteOnly); + file.close(); + } + } else { + qWarning() << "aptss upgrade failed:" << m_aptssProcess->readAllStandardError(); + m_model->setStatus(UpdatesStatus::UpdateFailed); + } + + clearAptssProcess(); + }); + + QStringList args; + args << "upgrade" << packages; + m_aptssProcess->start(updateWorkerPath(), args); + return; + m_baseProgress = 0; distUpgradeInstallUpdates(); } void UpdateWorker::downloadAndDistUpgrade() { + distUpgrade(); + return; + m_baseProgress = 0.5; distUpgradeDownloadUpdates(); } +QString UpdateWorker::updateWorkerPath() const +{ + const QString installedPath = QStringLiteral("/usr/lib/gxde-control-center/gxde-update-worker.sh"); + if (QFile::exists(installedPath)) { + return installedPath; + } + + const QString legacyInstalledPath = QStringLiteral("/usr/share/gxde-control-center/gxde-update-worker.sh"); + if (QFile::exists(legacyInstalledPath)) { + return legacyInstalledPath; + } + + const QString sourcePath = QDir::current().filePath("tools/gxde-control-center/gxde-update-worker.sh"); + if (QFile::exists(sourcePath)) { + return sourcePath; + } + + return installedPath; +} + +QString UpdateWorker::packageDisplayName(const QString &packageName) const +{ + QProcess process; + process.start("dpkg-query", QStringList() << "-W" << "-f=${binary:Summary}" << packageName); + process.waitForFinished(1000); + + const QString summary = QString::fromLocal8Bit(process.readAllStandardOutput()).trimmed(); + if (!summary.isEmpty()) { + return summary; + } + + return packageName; +} + +void UpdateWorker::runAptssCheckList() +{ + m_aptssProcess = new QProcess(this); + connect(m_aptssProcess, static_cast(&QProcess::finished), this, [this](int exitCode, QProcess::ExitStatus exitStatus) { + if (exitStatus != QProcess::NormalExit || exitCode != 0) { + qWarning() << "aptss list --upgradable failed:" << m_aptssProcess->readAllStandardError(); + m_model->setStatus(UpdatesStatus::UpdateFailed); + clearAptssProcess(); + return; + } + + QList infos; + m_updatablePackages.clear(); + + const QString output = QString::fromLocal8Bit(m_aptssProcess->readAllStandardOutput()); + for (const QString &line : output.split('\n', QString::SkipEmptyParts)) { + const QStringList fields = line.split('\t'); + if (fields.count() < 3) { + continue; + } + + AppUpdateInfo info; + info.m_packageId = fields.at(0); + info.m_name = packageDisplayName(info.m_packageId); + info.m_avilableVersion = fields.at(1); + info.m_currentVersion = fields.at(2); + info.m_changelog = tr("System package update"); + + infos << info; + m_updatablePackages << info.m_packageId; + } + + if (infos.isEmpty()) { + clearAptssProcess(); + m_model->setUpdateProgress(1); + m_model->setDownloadInfo(new DownloadInfo(0, infos)); + m_model->setStatus(UpdatesStatus::Updated); + return; + } + + const QStringList packages = upgradablePackages(); + clearAptssProcess(); + runAptssDownloadSize(infos, packages); + }); + m_aptssProcess->start(updateWorkerPath(), QStringList() << "upgradable-list"); +} + +void UpdateWorker::runAptssDownloadSize(const QList &infos, const QStringList &packages) +{ + if (m_aptssProcess) { + return; + } + + m_aptssProcess = new QProcess(this); + connect(m_aptssProcess, static_cast(&QProcess::finished), this, [this, infos](int exitCode, QProcess::ExitStatus exitStatus) { + qlonglong downloadSize = 1; + + if (exitStatus == QProcess::NormalExit && exitCode == 0) { + const QString output = QString::fromLocal8Bit(m_aptssProcess->readAllStandardOutput()).trimmed(); + const QStringList lines = output.split('\n', QString::SkipEmptyParts); + for (int i = lines.count() - 1; i >= 0; --i) { + bool ok = false; + const qlonglong size = lines.at(i).trimmed().toLongLong(&ok); + if (ok) { + downloadSize = size; + break; + } + } + } else { + qWarning() << "aptss download-size failed:" << m_aptssProcess->readAllStandardError(); + } + + clearAptssProcess(); + m_model->setUpdateProgress(1); + m_model->setDownloadInfo(new DownloadInfo(downloadSize, infos)); + m_model->setStatus(UpdatesStatus::UpdatesAvailable); + }); + + QStringList args; + args << "download-size" << packages; + m_aptssProcess->start(updateWorkerPath(), args); +} + +QStringList UpdateWorker::upgradablePackages() const +{ + QStringList packages; + for (const QString &package : m_updatablePackages) { + packages << package; + } + + return packages; +} + +void UpdateWorker::clearAptssProcess() +{ + if (!m_aptssProcess) { + return; + } + + m_aptssProcess->deleteLater(); + m_aptssProcess = nullptr; +} + void UpdateWorker::setAutoCheckUpdates(const bool autocheckUpdates) { m_updateInter->SetAutoCheckUpdates(autocheckUpdates); diff --git a/src/frame/modules/update/updatework.h b/src/frame/modules/update/updatework.h index 2db4dc3..4c1f325 100644 --- a/src/frame/modules/update/updatework.h +++ b/src/frame/modules/update/updatework.h @@ -29,6 +29,7 @@ #include "updatemodel.h" #include +#include #include #include #include @@ -105,6 +106,12 @@ private: void setAppUpdateInfo(const AppUpdateInfoList &list); inline bool checkDbusIsValid(); void onSmartMirrorServiceIsValid(bool isvalid); + QString updateWorkerPath() const; + QString packageDisplayName(const QString &packageName) const; + void runAptssCheckList(); + void runAptssDownloadSize(const QList &infos, const QStringList &packages); + QStringList upgradablePackages() const; + void clearAptssProcess(); private: UpdateModel* m_model; @@ -126,6 +133,7 @@ private: QList m_updatableApps; QList m_updatablePackages; + QProcess *m_aptssProcess; }; } } diff --git a/tools/gxde-control-center/gxde-update-worker.sh b/tools/gxde-control-center/gxde-update-worker.sh new file mode 100755 index 0000000..09641b8 --- /dev/null +++ b/tools/gxde-control-center/gxde-update-worker.sh @@ -0,0 +1,139 @@ +#!/bin/bash + +export DEBIAN_FRONTEND=noninteractive +export LANGUAGE=en_US + +UPDATE_LOG=/tmp/gxde-control-center-update-log.txt +UPDATE_STATUS=/tmp/gxde-control-center-update-status.txt +UPGRADE_LOG=/tmp/gxde-control-center-upgrade-log.txt +UPGRADE_STATUS=/tmp/gxde-control-center-upgrade-status.txt + +if command -v aptss >/dev/null 2>&1; then + APT_CMD=aptss +else + APT_CMD=/usr/bin/apt +fi + +run_as_root() { + if [ "$(id -u)" != "0" ]; then + exec pkexec "$0" "$@" + fi +} + +write_error_status() { + local log_file="$1" + local status_file="$2" + + if [ -f "$log_file" ]; then + awk '/^E:|Package manager quit with exit code\./ { print }' "$log_file" > "$status_file" + else + : > "$status_file" + fi + + chmod 666 "$status_file" 2>/dev/null || true +} + +size_to_bytes() { + local value="$1" + local unit="$2" + + awk -v value="$value" -v unit="$unit" ' + BEGIN { + factor = 1 + if (unit ~ /^kB$/) factor = 1000 + else if (unit ~ /^MB$/) factor = 1000 * 1000 + else if (unit ~ /^GB$/) factor = 1000 * 1000 * 1000 + else if (unit ~ /^KiB$/) factor = 1024 + else if (unit ~ /^MiB$/) factor = 1024 * 1024 + else if (unit ~ /^GiB$/) factor = 1024 * 1024 * 1024 + printf "%.0f\n", value * factor + }' +} + +validate_packages() { + local package + + for package in "$@"; do + if ! printf '%s\n' "$package" | grep -Eq '^[a-z0-9][a-z0-9+.-]+(:[a-z0-9]+)?$'; then + echo "Invalid package name: $package" >&2 + exit 2 + fi + done +} + +case "$1" in + update) + run_as_root "$@" + env LANGUAGE=en_US ${APT_CMD} update 2>&1 | tee "$UPDATE_LOG" + write_error_status "$UPDATE_LOG" "$UPDATE_STATUS" + + if [ -s "$UPDATE_STATUS" ]; then + exit 1 + fi + ;; + upgradable-list) + run_as_root "$@" + output=$(env LANGUAGE=en_US ${APT_CMD} list --upgradable 2>/dev/null | awk 'NR>1') + + IFS_OLD="$IFS" + IFS=$'\n' + for line in $output; do + PKG_NAME=$(printf '%s\n' "$line" | awk -F '/' '{print $1}') + PKG_NEW_VER=$(printf '%s\n' "$line" | awk -F ' ' '{print $2}') + PKG_CUR_VER=$(printf '%s\n' "$line" | awk -F ' ' '{print $6}' | awk -F ']' '{print $1}') + PKG_STA=$(dpkg-query -W -f='${db:Status-Want}' "$PKG_NAME" 2>/dev/null || true) + + if [ -n "$PKG_NAME" ] && [ "$PKG_STA" != "hold" ]; then + printf '%s\t%s\t%s\n' "$PKG_NAME" "$PKG_NEW_VER" "$PKG_CUR_VER" + fi + done + IFS="$IFS_OLD" + ;; + download-size) + run_as_root "$@" + shift + validate_packages "$@" + + if [ "$#" -eq 0 ]; then + echo 0 + exit 0 + fi + + output=$(env LANGUAGE=en_US DEBIAN_FRONTEND=noninteractive ${APT_CMD} install --simulate --only-upgrade "$@" 2>/dev/null || true) + need_line=$(printf '%s\n' "$output" | awk '/^Need to get / { line = $0 } END { print line }') + + if [ -z "$need_line" ]; then + echo 0 + exit 0 + fi + + amount=$(printf '%s\n' "$need_line" | awk '{ print $4 }') + unit=$(printf '%s\n' "$need_line" | awk '{ print $5 }') + size_to_bytes "$amount" "$unit" + ;; + upgrade) + run_as_root "$@" + shift + validate_packages "$@" + + if [ "$#" -gt 0 ]; then + env LANGUAGE=en_US DEBIAN_FRONTEND=noninteractive ${APT_CMD} install -y --only-upgrade "$@" 2>&1 | tee "$UPGRADE_LOG" + else + env LANGUAGE=en_US DEBIAN_FRONTEND=noninteractive ${APT_CMD} upgrade -y 2>&1 | tee "$UPGRADE_LOG" + fi + + ret=${PIPESTATUS[0]} + write_error_status "$UPGRADE_LOG" "$UPGRADE_STATUS" + + if [ "$ret" -ne 0 ] || [ -s "$UPGRADE_STATUS" ]; then + exit 1 + fi + ;; + clean-log) + rm -f "$UPDATE_LOG" "$UPDATE_STATUS" "$UPGRADE_LOG" "$UPGRADE_STATUS" + ;; + *) + echo "Usage: $0 {update|upgradable-list|download-size [package ...]|upgrade [package ...]|clean-log}" >&2 + exit 2 + ;; +esac -- Gitee From 222a8421f1ae311b8bcc41e019159faf42c2e5fd Mon Sep 17 00:00:00 2001 From: momen Date: Sun, 3 May 2026 23:31:24 +0800 Subject: [PATCH 2/8] Bump version 5.0.13 --- com.gxde.controlcenter.update.policy | 6 +++--- debian/changelog | 5 +++-- debian/control | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/com.gxde.controlcenter.update.policy b/com.gxde.controlcenter.update.policy index 8b1cef7..b6c61e2 100644 --- a/com.gxde.controlcenter.update.policy +++ b/com.gxde.controlcenter.update.policy @@ -13,9 +13,9 @@ Authentication is required to update system packages 更新系统软件包需要认证 - no - auth_admin - auth_admin_keep + yes + yes + yes /usr/lib/gxde-control-center/gxde-update-worker.sh diff --git a/debian/changelog b/debian/changelog index 796d019..843fd2e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -gxde-control-center (5.0.12) UNRELEASED; urgency=medium +gxde-control-center (5.0.13) UNRELEASED; urgency=medium * 修复屏幕缩放调整条不对准刻度的问题 * 修复系统信息在时间异常时显示类似 ©2023-1970 等错误信息的问题 @@ -23,8 +23,9 @@ gxde-control-center (5.0.12) UNRELEASED; urgency=medium * 修复高分屏下声音高级设置中选中图标模糊的问题 * 使 VNC 密码输入框样式与其他设置项的输入框样式统一 * 内置更新模块,优先使用 aptss 进行系统更新 + * 更新模块免验证提权并依赖新版 gxde-app-upgrader - -- gfdgd_xi <3025613752@qq.com> Sun, 03 May 2026 23:12:28 +0800 + -- gfdgd_xi <3025613752@qq.com> Sun, 03 May 2026 23:29:15 +0800 gxde-control-center (4.10.29.1) UNRELEASED; urgency=medium diff --git a/debian/control b/debian/control index 3f02a99..2efa135 100644 --- a/debian/control +++ b/debian/control @@ -46,7 +46,7 @@ Depends: ${shlibs:Depends}, libkf5networkmanagerqt6, libgxde-network-utils, garma, - gxde-app-installer,gxde-app-upgrader,gxde-app-uninstaller, + gxde-app-installer,gxde-app-upgrader (>= 1.6.3),gxde-app-uninstaller, gxde-shell-tools, transhell, wireplumber, -- Gitee From e0dca73ca5c021516b23ca4d73a7a61e753c6619 Mon Sep 17 00:00:00 2001 From: momen Date: Mon, 4 May 2026 01:37:33 +0800 Subject: [PATCH 3/8] Bump version 5.0.14 --- debian/changelog | 5 ++- src/frame/modules/update/updatectrlwidget.cpp | 39 +++++++++++++++++-- src/frame/modules/update/updatectrlwidget.h | 9 ++++- src/frame/modules/update/updateitem.cpp | 21 ++++++++++ src/frame/modules/update/updateitem.h | 9 +++++ src/frame/modules/update/updatemodel.cpp | 13 +++++++ src/frame/modules/update/updatemodel.h | 4 ++ src/frame/modules/update/updatemodule.cpp | 1 - src/frame/modules/update/updatework.cpp | 26 +++++++++++-- src/frame/modules/update/updatework.h | 3 +- .../gxde-control-center/gxde-update-worker.sh | 36 ++++++++++++++++- 11 files changed, 154 insertions(+), 12 deletions(-) diff --git a/debian/changelog b/debian/changelog index 843fd2e..7818530 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -gxde-control-center (5.0.13) UNRELEASED; urgency=medium +gxde-control-center (5.0.14) UNRELEASED; urgency=medium * 修复屏幕缩放调整条不对准刻度的问题 * 修复系统信息在时间异常时显示类似 ©2023-1970 等错误信息的问题 @@ -24,8 +24,9 @@ gxde-control-center (5.0.13) UNRELEASED; urgency=medium * 使 VNC 密码输入框样式与其他设置项的输入框样式统一 * 内置更新模块,优先使用 aptss 进行系统更新 * 更新模块免验证提权并依赖新版 gxde-app-upgrader + * 支持选择更新软件包,并先下载到 cache 后统一安装 - -- gfdgd_xi <3025613752@qq.com> Sun, 03 May 2026 23:29:15 +0800 + -- gfdgd_xi <3025613752@qq.com> Mon, 04 May 2026 01:35:53 +0800 gxde-control-center (4.10.29.1) UNRELEASED; urgency=medium diff --git a/src/frame/modules/update/updatectrlwidget.cpp b/src/frame/modules/update/updatectrlwidget.cpp index 9ba2713..dd32e30 100644 --- a/src/frame/modules/update/updatectrlwidget.cpp +++ b/src/frame/modules/update/updatectrlwidget.cpp @@ -118,6 +118,8 @@ UpdateCtrlWidget::~UpdateCtrlWidget() void UpdateCtrlWidget::loadAppList(const QList& infos) { qDebug() << infos.count(); + m_updateItems.clear(); + m_selectedPackages.clear(); QLayoutItem *item; while((item = m_summaryGroup->layout()->takeAt(1)) != NULL) { item->widget()->deleteLater(); @@ -128,16 +130,20 @@ void UpdateCtrlWidget::loadAppList(const QList& infos) { UpdateItem* item = new UpdateItem(); item->setAppInfo(info); + connect(item, &UpdateItem::selectionChanged, this, &UpdateCtrlWidget::updateSelectedPackages); m_summaryGroup->appendItem(item); + m_updateItems << item; } + + updateSelectedPackages(); } void UpdateCtrlWidget::onProgressBarClicked() { switch (m_status) { case UpdatesStatus::UpdatesAvailable: - Q_EMIT requestDownloadUpdates(); + Q_EMIT requestDownloadUpdates(selectedPackages()); break; case UpdatesStatus::Downloading: Q_EMIT requestPauseDownload(); @@ -178,7 +184,7 @@ void UpdateCtrlWidget::setStatus(const UpdatesStatus &status) case UpdatesStatus::UpdatesAvailable: m_progress->setVisible(true); m_summaryGroup->setVisible(true); - m_progress->setMessage(tr("Download and install updates")); + m_progress->setMessage(tr("Download and install selected updates")); setDownloadInfo(m_model->downloadInfo()); m_progress->setValue(100); setLowBattery(m_model->lowBattery()); @@ -210,7 +216,7 @@ void UpdateCtrlWidget::setStatus(const UpdatesStatus &status) case UpdatesStatus::Installing: m_progress->setVisible(true); m_summaryGroup->setVisible(true); - m_progress->setMessage(tr("Updating, please wait...")); + m_progress->setMessage(m_model->upgradeMessage().isEmpty() ? tr("Updating, please wait...") : m_model->upgradeMessage()); break; case UpdatesStatus::UpdateSucceeded: m_resultItem->setSuccess(true); @@ -295,6 +301,31 @@ void UpdateCtrlWidget::setProgressValue(const double value) } } +void UpdateCtrlWidget::setUpgradeMessage(const QString &message) +{ + if (m_status == UpdatesStatus::Installing && !message.isEmpty()) { + m_progress->setMessage(message); + } +} + +QStringList UpdateCtrlWidget::selectedPackages() const +{ + return m_selectedPackages.values(); +} + +void UpdateCtrlWidget::updateSelectedPackages() +{ + m_selectedPackages.clear(); + + for (UpdateItem *item : m_updateItems) { + if (item && item->isSelected()) { + m_selectedPackages.insert(item->packageId()); + } + } + + m_progress->setDisabled(m_selectedPackages.isEmpty() || m_model->lowBattery()); +} + void UpdateCtrlWidget::setLowBattery(const bool &lowBattery) { if (m_status == UpdatesStatus::Downloaded || m_status == UpdatesStatus::UpdatesAvailable) { @@ -322,10 +353,12 @@ void UpdateCtrlWidget::setModel(UpdateModel *model) connect(m_model, &UpdateModel::lowBatteryChanged, this, &UpdateCtrlWidget::setLowBattery); connect(m_model, &UpdateModel::downloadInfoChanged, this, &UpdateCtrlWidget::setDownloadInfo); connect(m_model, &UpdateModel::upgradeProgressChanged, this, &UpdateCtrlWidget::setProgressValue); + connect(m_model, &UpdateModel::upgradeMessageChanged, this, &UpdateCtrlWidget::setUpgradeMessage); connect(m_model, &UpdateModel::updateProgressChanged, this, &UpdateCtrlWidget::setUpdateProgress); setUpdateProgress(m_model->updateProgress()); setProgressValue(m_model->upgradeProgress()); + setUpgradeMessage(m_model->upgradeMessage()); setStatus(m_model->status()); setLowBattery(m_model->lowBattery()); setDownloadInfo(m_model->downloadInfo()); diff --git a/src/frame/modules/update/updatectrlwidget.h b/src/frame/modules/update/updatectrlwidget.h index e8a12e8..8b704d4 100644 --- a/src/frame/modules/update/updatectrlwidget.h +++ b/src/frame/modules/update/updatectrlwidget.h @@ -36,6 +36,7 @@ #include #include +#include using namespace dcc; using namespace dcc::widgets; @@ -46,6 +47,7 @@ namespace update{ class UpdateModel; class DownloadInfo; class LoadingItem; +class UpdateItem; class UpdateCtrlWidget : public ContentWidget { @@ -58,7 +60,7 @@ public: void setModel(UpdateModel *model); Q_SIGNALS: - void requestDownloadUpdates(); + void requestDownloadUpdates(const QStringList &packages); void requestPauseDownload(); void requestResumeDownload(); void requestInstallUpdates(); @@ -73,6 +75,9 @@ private: void setProgressValue(const double value); void setLowBattery(const bool &lowBattery); void setUpdateProgress(const double value); + void setUpgradeMessage(const QString &message); + QStringList selectedPackages() const; + void updateSelectedPackages(); private: UpdateModel *m_model; @@ -92,6 +97,8 @@ private: TipsLabel *m_noNetworkTip; QSettings *m_qsettings; + QList m_updateItems; + QSet m_selectedPackages; }; } diff --git a/src/frame/modules/update/updateitem.cpp b/src/frame/modules/update/updateitem.cpp index ee0d421..7929a69 100644 --- a/src/frame/modules/update/updateitem.cpp +++ b/src/frame/modules/update/updateitem.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -92,6 +93,7 @@ UpdateItem::UpdateItem(QFrame *parent) m_appName(new SmallLabel), m_appVersion(new SmallLabel), m_appChangelog(new SmallLabel), + m_checkBox(new QCheckBox), m_details(new QPushButton) { TranslucentFrame *iconContainer = new TranslucentFrame; @@ -106,6 +108,7 @@ UpdateItem::UpdateItem(QFrame *parent) iconContainer->setLayout(m_iconLayout); m_appIcon->setFixedSize(36, 36); + m_checkBox->setChecked(true); QFont changelogFont("Noto Mono"); changelogFont.setPointSize(10); @@ -149,6 +152,8 @@ UpdateItem::UpdateItem(QFrame *parent) QHBoxLayout* layout = new QHBoxLayout(); layout->setMargin(10); layout->setSpacing(0); + layout->addWidget(m_checkBox, 0, Qt::AlignCenter); + layout->addSpacing(10); layout->addWidget(iconContainer); layout->addSpacing(10); layout->addLayout(rightLayout, 1); @@ -161,6 +166,7 @@ UpdateItem::UpdateItem(QFrame *parent) // after the relayout of this item caused by the hide of details button. QTimer::singleShot(0, this, &UpdateItem::expandChangelog); }); + connect(m_checkBox, &QCheckBox::toggled, this, &UpdateItem::selectionChanged); // connect(m_openWebsite, &QPushButton::clicked, [this] { // qDebug() << QString("open website %1 to see release notes of %2").arg(m_anchorAddress).arg(m_anchorName); @@ -169,6 +175,21 @@ UpdateItem::UpdateItem(QFrame *parent) setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Expanding); } +QString UpdateItem::packageId() const +{ + return m_info.m_packageId; +} + +bool UpdateItem::isSelected() const +{ + return m_checkBox->isChecked(); +} + +void UpdateItem::setSelected(bool selected) +{ + m_checkBox->setChecked(selected); +} + void UpdateItem::setAppInfo(const AppUpdateInfo &info) { m_info = info; diff --git a/src/frame/modules/update/updateitem.h b/src/frame/modules/update/updateitem.h index fa1b0e7..c54361e 100644 --- a/src/frame/modules/update/updateitem.h +++ b/src/frame/modules/update/updateitem.h @@ -32,6 +32,8 @@ #include +class QCheckBox; + class QVBoxLayout; class QPushButton; @@ -52,12 +54,18 @@ public: explicit UpdateItem(QFrame* parent = 0); void setAppInfo(const AppUpdateInfo& info); + QString packageId() const; + bool isSelected() const; + void setSelected(bool selected); static bool isAnchor(const QString &input); static QPair parseAnchor(const QString &input); QSize sizeHint() const override; +Q_SIGNALS: + void selectionChanged(); + private: AppUpdateInfo m_info; @@ -65,6 +73,7 @@ private: dcc::widgets::SmallLabel *m_appName; dcc::widgets::SmallLabel *m_appVersion; dcc::widgets::SmallLabel *m_appChangelog; + QCheckBox *m_checkBox; QPushButton *m_details; QVBoxLayout *m_iconLayout; diff --git a/src/frame/modules/update/updatemodel.cpp b/src/frame/modules/update/updatemodel.cpp index 33f81e2..bb33694 100644 --- a/src/frame/modules/update/updatemodel.cpp +++ b/src/frame/modules/update/updatemodel.cpp @@ -165,6 +165,19 @@ double UpdateModel::upgradeProgress() const return m_upgradeProgress; } +QString UpdateModel::upgradeMessage() const +{ + return m_upgradeMessage; +} + +void UpdateModel::setUpgradeMessage(const QString &upgradeMessage) +{ + if (m_upgradeMessage != upgradeMessage) { + m_upgradeMessage = upgradeMessage; + Q_EMIT upgradeMessageChanged(upgradeMessage); + } +} + void UpdateModel::setUpgradeProgress(double upgradeProgress) { if (m_upgradeProgress != upgradeProgress) { diff --git a/src/frame/modules/update/updatemodel.h b/src/frame/modules/update/updatemodel.h index cbc3799..7044a38 100644 --- a/src/frame/modules/update/updatemodel.h +++ b/src/frame/modules/update/updatemodel.h @@ -85,6 +85,8 @@ public: double upgradeProgress() const; void setUpgradeProgress(double upgradeProgress); + QString upgradeMessage() const; + void setUpgradeMessage(const QString &upgradeMessage); bool autoCleanCache() const; void setAutoCleanCache(bool autoCleanCache); @@ -122,6 +124,7 @@ Q_SIGNALS: void downloadInfoChanged(DownloadInfo *downloadInfo); void updateProgressChanged(const double &updateProgress); void upgradeProgressChanged(const double &upgradeProgress); + void upgradeMessageChanged(const QString &upgradeMessage); void autoCleanCacheChanged(const bool autoCleanCache); void netselectExistChanged(const bool netselectExist); void autoCheckUpdatesChanged(const bool autoCheckUpdates); @@ -132,6 +135,7 @@ private: double m_updateProgress; double m_upgradeProgress; + QString m_upgradeMessage; #ifndef DISABLE_SYS_UPDATE_SOURCE_CHECK bool m_sourceCheck; diff --git a/src/frame/modules/update/updatemodule.cpp b/src/frame/modules/update/updatemodule.cpp index 673d62f..51c526b 100644 --- a/src/frame/modules/update/updatemodule.cpp +++ b/src/frame/modules/update/updatemodule.cpp @@ -167,4 +167,3 @@ void UpdateModule::onPushSettings() } } - diff --git a/src/frame/modules/update/updatework.cpp b/src/frame/modules/update/updatework.cpp index 500f900..747ac37 100644 --- a/src/frame/modules/update/updatework.cpp +++ b/src/frame/modules/update/updatework.cpp @@ -351,17 +351,35 @@ void UpdateWorker::resumeDownload() void UpdateWorker::distUpgrade() { - const QStringList packages = upgradablePackages(); + distUpgradePackages(upgradablePackages()); +} + +void UpdateWorker::distUpgradePackages(const QStringList &packages) +{ if (m_aptssProcess || packages.isEmpty()) { return; } m_model->setStatus(UpdatesStatus::Installing); m_model->setUpgradeProgress(0); + m_model->setUpgradeMessage(tr("Downloading updates...")); m_aptssProcess = new QProcess(this); connect(m_aptssProcess, &QProcess::readyReadStandardOutput, this, [this] { const QString output = QString::fromLocal8Bit(m_aptssProcess->readAllStandardOutput()); + for (const QString &line : output.split('\n', QString::SkipEmptyParts)) { + if (line.startsWith('#')) { + m_model->setUpgradeMessage(line.mid(1).trimmed()); + continue; + } + + bool ok = false; + const int progress = line.trimmed().toInt(&ok); + if (ok) { + m_model->setUpgradeProgress(progress / 100.0); + } + } + if (output.contains('%')) { const QRegExp rx("(\\d+)%"); if (rx.indexIn(output) != -1) { @@ -372,6 +390,7 @@ void UpdateWorker::distUpgrade() connect(m_aptssProcess, static_cast(&QProcess::finished), this, [this](int exitCode, QProcess::ExitStatus exitStatus) { if (exitStatus == QProcess::NormalExit && exitCode == 0) { m_model->setUpgradeProgress(1); + m_model->setUpgradeMessage(QString()); m_model->setStatus(UpdatesStatus::UpdateSucceeded); QProcess::startDetached("/usr/lib/gxde-control-center/reboot-reminder-dialog"); @@ -383,6 +402,7 @@ void UpdateWorker::distUpgrade() } } else { qWarning() << "aptss upgrade failed:" << m_aptssProcess->readAllStandardError(); + m_model->setUpgradeMessage(QString()); m_model->setStatus(UpdatesStatus::UpdateFailed); } @@ -398,9 +418,9 @@ void UpdateWorker::distUpgrade() distUpgradeInstallUpdates(); } -void UpdateWorker::downloadAndDistUpgrade() +void UpdateWorker::downloadAndDistUpgrade(const QStringList &packages) { - distUpgrade(); + distUpgradePackages(packages.isEmpty() ? upgradablePackages() : packages); return; m_baseProgress = 0.5; diff --git a/src/frame/modules/update/updatework.h b/src/frame/modules/update/updatework.h index 4c1f325..d358864 100644 --- a/src/frame/modules/update/updatework.h +++ b/src/frame/modules/update/updatework.h @@ -68,7 +68,7 @@ public Q_SLOTS: void pauseDownload(); void resumeDownload(); void distUpgrade(); - void downloadAndDistUpgrade(); + void downloadAndDistUpgrade(const QStringList &packages); void setAutoCheckUpdates(const bool autocheckUpdates); void setAutoCleanCache(const bool autoCleanCache); void setAutoDownloadUpdates(const bool &autoDownload); @@ -103,6 +103,7 @@ private: AppUpdateInfo getDDEInfo(); void distUpgradeDownloadUpdates(); void distUpgradeInstallUpdates(); + void distUpgradePackages(const QStringList &packages); void setAppUpdateInfo(const AppUpdateInfoList &list); inline bool checkDbusIsValid(); void onSmartMirrorServiceIsValid(bool isvalid); diff --git a/tools/gxde-control-center/gxde-update-worker.sh b/tools/gxde-control-center/gxde-update-worker.sh index 09641b8..39e031e 100755 --- a/tools/gxde-control-center/gxde-update-worker.sh +++ b/tools/gxde-control-center/gxde-update-worker.sh @@ -61,6 +61,29 @@ validate_packages() { done } +download_to_cache() { + env LANGUAGE=en_US DEBIAN_FRONTEND=noninteractive ${APT_CMD} install -d -y --only-upgrade "$@" 2>&1 | tr '\r' '\n' | while IFS= read -r line; do + printf '%s\n' "$line" + speed=$(printf '%s\n' "$line" | sed -n 's/.*DL:\([^ ]*\).*/\1/p') + progress=$(printf '%s\n' "$line" | sed -n 's/.*(\([0-9][0-9]*\)%).*/\1/p') + + if [ -n "$speed" ]; then + echo "# Downloading updates... ${speed}" + fi + + if [ -n "$progress" ]; then + echo "$((progress * 80 / 100))" + fi + done + return "${PIPESTATUS[0]}" +} + +install_from_cache() { + echo "# Installing updates from cache..." + echo 85 + env LANGUAGE=en_US DEBIAN_FRONTEND=noninteractive ${APT_CMD} install -y --no-download --only-upgrade "$@" +} + case "$1" in update) run_as_root "$@" @@ -117,7 +140,18 @@ case "$1" in validate_packages "$@" if [ "$#" -gt 0 ]; then - env LANGUAGE=en_US DEBIAN_FRONTEND=noninteractive ${APT_CMD} install -y --only-upgrade "$@" 2>&1 | tee "$UPGRADE_LOG" + { + download_to_cache "$@" + download_ret="$?" + if [ "$download_ret" -ne 0 ]; then + exit "$download_ret" + fi + + install_from_cache "$@" + install_ret="$?" + echo 100 + exit "$install_ret" + } 2>&1 | tee "$UPGRADE_LOG" else env LANGUAGE=en_US DEBIAN_FRONTEND=noninteractive ${APT_CMD} upgrade -y 2>&1 | tee "$UPGRADE_LOG" fi -- Gitee From 93c39b7ccf925f7983261fbf675276a633b9d449 Mon Sep 17 00:00:00 2001 From: momen Date: Tue, 5 May 2026 11:41:37 +0800 Subject: [PATCH 4/8] Bump version 5.0.15 --- debian/changelog | 6 ++- debian/control | 2 +- src/frame/modules/update/updatectrlwidget.cpp | 50 ++++++++++++++++--- src/frame/modules/update/updatectrlwidget.h | 6 +++ src/frame/modules/update/updateview.cpp | 19 +++---- src/frame/modules/update/updateview.h | 7 ++- src/frame/modules/update/updatework.cpp | 16 +++++- src/frame/modules/update/updatework.h | 2 + .../gxde-control-center/gxde-update-worker.sh | 33 ++++++++++-- 9 files changed, 111 insertions(+), 30 deletions(-) diff --git a/debian/changelog b/debian/changelog index 7818530..d3b19a3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -gxde-control-center (5.0.14) UNRELEASED; urgency=medium +gxde-control-center (5.0.15) UNRELEASED; urgency=medium * 修复屏幕缩放调整条不对准刻度的问题 * 修复系统信息在时间异常时显示类似 ©2023-1970 等错误信息的问题 @@ -25,8 +25,10 @@ gxde-control-center (5.0.14) UNRELEASED; urgency=medium * 内置更新模块,优先使用 aptss 进行系统更新 * 更新模块免验证提权并依赖新版 gxde-app-upgrader * 支持选择更新软件包,并先下载到 cache 后统一安装 + * 调整更新入口样式、增加全选并增强更新失败日志 + * 安装阶段沿用 aptss 的 apt 配置 - -- gfdgd_xi <3025613752@qq.com> Mon, 04 May 2026 01:35:53 +0800 + -- gfdgd_xi <3025613752@qq.com> Tue, 05 May 2026 11:17:58 +0800 gxde-control-center (4.10.29.1) UNRELEASED; urgency=medium diff --git a/debian/control b/debian/control index 2efa135..b580fc5 100644 --- a/debian/control +++ b/debian/control @@ -46,7 +46,7 @@ Depends: ${shlibs:Depends}, libkf5networkmanagerqt6, libgxde-network-utils, garma, - gxde-app-installer,gxde-app-upgrader (>= 1.6.3),gxde-app-uninstaller, + gxde-app-installer,gxde-app-upgrader (>= 1.6.5),gxde-app-uninstaller, gxde-shell-tools, transhell, wireplumber, diff --git a/src/frame/modules/update/updatectrlwidget.cpp b/src/frame/modules/update/updatectrlwidget.cpp index dd32e30..d6359f2 100644 --- a/src/frame/modules/update/updatectrlwidget.cpp +++ b/src/frame/modules/update/updatectrlwidget.cpp @@ -28,6 +28,8 @@ #include "widgets/translucentframe.h" #include +#include +#include #include "updatemodel.h" #include "loadingitem.h" @@ -48,7 +50,10 @@ UpdateCtrlWidget::UpdateCtrlWidget(UpdateModel *model, QWidget *parent) m_resultItem(new ResultItem), m_progress(new DownloadProgressBar), m_summaryGroup(new SettingsGroup), + m_selectAllGroup(new SettingsGroup), m_upgradeWarningGroup(new SettingsGroup), + m_selectAllItem(new SettingsItem), + m_selectAll(new QCheckBox(tr("Select all"))), m_summary(new SummaryItem), m_upgradeWarning(new SummaryItem), m_powerTip(new TipsLabel), @@ -74,6 +79,14 @@ UpdateCtrlWidget::UpdateCtrlWidget(UpdateModel *model, QWidget *parent) m_summaryGroup->setVisible(false); m_summaryGroup->appendItem(m_summary); + m_selectAllGroup->setVisible(false); + m_selectAll->setChecked(true); + QHBoxLayout *selectAllLayout = new QHBoxLayout; + selectAllLayout->setMargin(10); + selectAllLayout->addWidget(m_selectAll); + m_selectAllItem->setLayout(selectAllLayout); + m_selectAllGroup->appendItem(m_selectAllItem); + m_powerTip->setWordWrap(true); m_powerTip->setAlignment(Qt::AlignHCenter); m_powerTip->setVisible(false); @@ -96,6 +109,7 @@ UpdateCtrlWidget::UpdateCtrlWidget(UpdateModel *model, QWidget *parent) layout->addWidget(m_resultGroup); layout->addWidget(m_progress); layout->addWidget(m_upgradeWarningGroup); + layout->addWidget(m_selectAllGroup); layout->addWidget(m_summaryGroup); layout->addWidget(m_powerTip); layout->addWidget(m_reminderTip); @@ -108,6 +122,7 @@ UpdateCtrlWidget::UpdateCtrlWidget(UpdateModel *model, QWidget *parent) setModel(model); connect(m_progress, &DownloadProgressBar::clicked, this, &UpdateCtrlWidget::onProgressBarClicked); + connect(m_selectAll, &QCheckBox::toggled, this, &UpdateCtrlWidget::setAllPackagesSelected); } UpdateCtrlWidget::~UpdateCtrlWidget() @@ -167,6 +182,7 @@ void UpdateCtrlWidget::setStatus(const UpdatesStatus &status) m_noNetworkTip->setVisible(false); m_resultGroup->setVisible(false); m_progress->setVisible(false); + m_selectAllGroup->setVisible(false); m_summaryGroup->setVisible(false); m_upgradeWarningGroup->setVisible(false); m_reminderTip->setVisible(false); @@ -183,25 +199,30 @@ void UpdateCtrlWidget::setStatus(const UpdatesStatus &status) break; case UpdatesStatus::UpdatesAvailable: m_progress->setVisible(true); + m_selectAllGroup->setVisible(true); m_summaryGroup->setVisible(true); m_progress->setMessage(tr("Download and install selected updates")); setDownloadInfo(m_model->downloadInfo()); - m_progress->setValue(100); + m_progress->setValue(0); setLowBattery(m_model->lowBattery()); + updateSelectedPackages(); break; case UpdatesStatus::Downloading: m_progress->setVisible(true); + m_selectAllGroup->setVisible(true); m_summaryGroup->setVisible(true); m_progress->setValue(m_progress->minimum()); m_progress->setMessage(tr("%1% downloaded (Click to pause)").arg(m_progress->value())); break; case UpdatesStatus::DownloadPaused: m_progress->setVisible(true); + m_selectAllGroup->setVisible(true); m_summaryGroup->setVisible(true); m_progress->setMessage(tr("%1% downloaded (Click to continue)").arg(m_progress->value())); break; case UpdatesStatus::Downloaded: m_progress->setVisible(true); + m_selectAllGroup->setVisible(true); m_summaryGroup->setVisible(true); m_progress->setValue(m_progress->maximum()); m_progress->setMessage(tr("Install updates")); @@ -280,11 +301,9 @@ void UpdateCtrlWidget::setDownloadInfo(DownloadInfo *downloadInfo) } } - if (!downloadSize) - m_summary->setDetails(tr("Downloaded")); - else { - m_summary->setDetails(QString(tr("Download size: %1").arg(formatCap(downloadSize)))); + m_summary->setDetails(QString(tr("Download size: %1").arg(formatCap(downloadSize)))); + if (downloadSize) { if ((downloadSize / 1024) / 1024 >= m_qsettings->value("upgrade_waring_size", UpgradeWarningSize).toInt()) m_upgradeWarningGroup->setVisible(true); } @@ -323,9 +342,28 @@ void UpdateCtrlWidget::updateSelectedPackages() } } + const bool allSelected = !m_updateItems.isEmpty() && m_selectedPackages.count() == m_updateItems.count(); + const bool partiallySelected = !m_selectedPackages.isEmpty() && !allSelected; + m_selectAll->blockSignals(true); + m_selectAll->setTristate(partiallySelected); + m_selectAll->setCheckState(allSelected ? Qt::Checked : (partiallySelected ? Qt::PartiallyChecked : Qt::Unchecked)); + m_selectAll->setTristate(false); + m_selectAll->blockSignals(false); + m_progress->setDisabled(m_selectedPackages.isEmpty() || m_model->lowBattery()); } +void UpdateCtrlWidget::setAllPackagesSelected(bool selected) +{ + for (UpdateItem *item : m_updateItems) { + if (item) { + item->setSelected(selected); + } + } + + updateSelectedPackages(); +} + void UpdateCtrlWidget::setLowBattery(const bool &lowBattery) { if (m_status == UpdatesStatus::Downloaded || m_status == UpdatesStatus::UpdatesAvailable) { @@ -335,7 +373,7 @@ void UpdateCtrlWidget::setLowBattery(const bool &lowBattery) m_powerTip->setText(tr("Please ensure sufficient power to restart, and don't power off or unplug your machine")); } - m_progress->setDisabled(lowBattery); + m_progress->setDisabled(lowBattery || m_selectedPackages.isEmpty()); m_powerTip->setVisible(lowBattery); } } diff --git a/src/frame/modules/update/updatectrlwidget.h b/src/frame/modules/update/updatectrlwidget.h index 8b704d4..3b4022e 100644 --- a/src/frame/modules/update/updatectrlwidget.h +++ b/src/frame/modules/update/updatectrlwidget.h @@ -38,6 +38,8 @@ #include #include +class QCheckBox; + using namespace dcc; using namespace dcc::widgets; @@ -78,6 +80,7 @@ private: void setUpgradeMessage(const QString &message); QStringList selectedPackages() const; void updateSelectedPackages(); + void setAllPackagesSelected(bool selected); private: UpdateModel *m_model; @@ -89,7 +92,10 @@ private: ResultItem *m_resultItem; DownloadProgressBar* m_progress; SettingsGroup* m_summaryGroup; + SettingsGroup* m_selectAllGroup; SettingsGroup* m_upgradeWarningGroup; + SettingsItem *m_selectAllItem; + QCheckBox *m_selectAll; SummaryItem* m_summary; SummaryItem* m_upgradeWarning; TipsLabel *m_powerTip; diff --git a/src/frame/modules/update/updateview.cpp b/src/frame/modules/update/updateview.cpp index 497c421..9548b9a 100644 --- a/src/frame/modules/update/updateview.cpp +++ b/src/frame/modules/update/updateview.cpp @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -45,10 +44,10 @@ UpdateView::UpdateView() : ModuleWidget() { setObjectName("Update"); -// m_updateItem = new NextPageWidget; -// m_updateItem->setTitle(tr("Update")); m_updateGroup = new SettingsGroup; -// m_updateGroup->appendItem(m_updateItem); + m_updateItem = new NextPageWidget; + m_updateItem->setTitle(tr("Update")); + m_updateGroup->appendItem(m_updateItem); // m_settingsItem = new NextPageWidget; // m_settingsItem->setTitle(tr("Update Settings")); @@ -56,12 +55,7 @@ UpdateView::UpdateView() // m_settingsGroup->appendItem(m_settingsItem); -// m_centralLayout->addWidget(m_settingsGroup); - m_neoUpgrader = new Dtk::Widget::DPushButton; - m_neoUpgrader->setText(tr("Check and perform system Upgrade")); - m_centralLayout->addWidget(m_neoUpgrader); - - m_addTestingSource = new Dtk::Widget::DPushButton; + m_addTestingSource = new QPushButton; m_addTestingSource->setText(tr("Internal Testing Group Settings")); if (QFile::exists("/usr/share/gxde-control-center/join-testing-group.sh")) { // 需要保证脚本存在才会显示按钮 @@ -74,14 +68,13 @@ UpdateView::UpdateView() m_centralLayout->addWidget(m_updateGroup); - connect(m_addTestingSource, &Dtk::Widget::DPushButton::clicked, this, &UpdateView::ShowTesingDialog); - connect(m_neoUpgrader, &Dtk::Widget::DPushButton::clicked,this, &UpdateView::ExecUpgrader); + connect(m_addTestingSource, &QPushButton::clicked, this, &UpdateView::ShowTesingDialog); + connect(m_updateItem, &NextPageWidget::clicked,this, &UpdateView::ExecUpgrader); connect(m_disabledUpgradeNotifications, &SwitchWidget::checkedChanged, this, &UpdateView::DisabledUpgradeNotifications); setTitle(tr("Update")); - //connect(m_updateItem, &NextPageWidget::clicked, this, &UpdateView::pushUpdate); //connect(m_settingsItem, &NextPageWidget::clicked, this, &UpdateView::pushMirrors); } diff --git a/src/frame/modules/update/updateview.h b/src/frame/modules/update/updateview.h index ebc9cfa..c61878f 100644 --- a/src/frame/modules/update/updateview.h +++ b/src/frame/modules/update/updateview.h @@ -27,10 +27,9 @@ #define UPDATEVIEW_H #include "modules/modulewidget.h" -//#include "widgets/nextpagewidget.h" +#include "widgets/nextpagewidget.h" #include "widgets/settingsgroup.h" #include "widgets/switchwidget.h" -#include "dpushbutton.h" #include #include @@ -51,8 +50,8 @@ Q_SIGNALS: private: dcc::widgets::SettingsGroup* m_updateGroup; - DPushButton* m_addTestingSource; - DPushButton* m_neoUpgrader; + dcc::widgets::NextPageWidget* m_updateItem; + QPushButton* m_addTestingSource; dcc::widgets::SwitchWidget *m_disabledUpgradeNotifications; void ShowTesingDialog(); diff --git a/src/frame/modules/update/updatework.cpp b/src/frame/modules/update/updatework.cpp index 747ac37..62c4470 100644 --- a/src/frame/modules/update/updatework.cpp +++ b/src/frame/modules/update/updatework.cpp @@ -363,10 +363,13 @@ void UpdateWorker::distUpgradePackages(const QStringList &packages) m_model->setStatus(UpdatesStatus::Installing); m_model->setUpgradeProgress(0); m_model->setUpgradeMessage(tr("Downloading updates...")); + m_aptssStdout.clear(); + m_aptssStderr.clear(); m_aptssProcess = new QProcess(this); connect(m_aptssProcess, &QProcess::readyReadStandardOutput, this, [this] { const QString output = QString::fromLocal8Bit(m_aptssProcess->readAllStandardOutput()); + m_aptssStdout += output; for (const QString &line : output.split('\n', QString::SkipEmptyParts)) { if (line.startsWith('#')) { m_model->setUpgradeMessage(line.mid(1).trimmed()); @@ -387,7 +390,13 @@ void UpdateWorker::distUpgradePackages(const QStringList &packages) } } }); + connect(m_aptssProcess, &QProcess::readyReadStandardError, this, [this] { + m_aptssStderr += QString::fromLocal8Bit(m_aptssProcess->readAllStandardError()); + }); connect(m_aptssProcess, static_cast(&QProcess::finished), this, [this](int exitCode, QProcess::ExitStatus exitStatus) { + m_aptssStdout += QString::fromLocal8Bit(m_aptssProcess->readAllStandardOutput()); + m_aptssStderr += QString::fromLocal8Bit(m_aptssProcess->readAllStandardError()); + if (exitStatus == QProcess::NormalExit && exitCode == 0) { m_model->setUpgradeProgress(1); m_model->setUpgradeMessage(QString()); @@ -401,7 +410,11 @@ void UpdateWorker::distUpgradePackages(const QStringList &packages) file.close(); } } else { - qWarning() << "aptss upgrade failed:" << m_aptssProcess->readAllStandardError(); + qWarning() << "aptss upgrade failed" + << "exitCode:" << exitCode + << "exitStatus:" << exitStatus + << "stdout:" << m_aptssStdout + << "stderr:" << m_aptssStderr; m_model->setUpgradeMessage(QString()); m_model->setStatus(UpdatesStatus::UpdateFailed); } @@ -411,6 +424,7 @@ void UpdateWorker::distUpgradePackages(const QStringList &packages) QStringList args; args << "upgrade" << packages; + qDebug() << "starting aptss upgrade worker:" << updateWorkerPath() << args; m_aptssProcess->start(updateWorkerPath(), args); return; diff --git a/src/frame/modules/update/updatework.h b/src/frame/modules/update/updatework.h index d358864..f53eeb2 100644 --- a/src/frame/modules/update/updatework.h +++ b/src/frame/modules/update/updatework.h @@ -135,6 +135,8 @@ private: QList m_updatableApps; QList m_updatablePackages; QProcess *m_aptssProcess; + QString m_aptssStdout; + QString m_aptssStderr; }; } } diff --git a/tools/gxde-control-center/gxde-update-worker.sh b/tools/gxde-control-center/gxde-update-worker.sh index 39e031e..12859c3 100755 --- a/tools/gxde-control-center/gxde-update-worker.sh +++ b/tools/gxde-control-center/gxde-update-worker.sh @@ -14,6 +14,16 @@ else APT_CMD=/usr/bin/apt fi +APTSS_APT_CONF=/opt/durapps/spark-store/bin/apt-fast-conf/aptss-apt.conf + +apt_get_install_from_cache() { + if [ -f "$APTSS_APT_CONF" ]; then + env LANGUAGE=en_US DEBIAN_FRONTEND=noninteractive /usr/bin/apt-get -c "$APTSS_APT_CONF" install -y --no-download --only-upgrade "$@" + else + env LANGUAGE=en_US DEBIAN_FRONTEND=noninteractive /usr/bin/apt-get install -y --no-download --only-upgrade "$@" + fi +} + run_as_root() { if [ "$(id -u)" != "0" ]; then exec pkexec "$0" "$@" @@ -33,6 +43,14 @@ write_error_status() { chmod 666 "$status_file" 2>/dev/null || true } +fail_with_log() { + local stage="$1" + local ret="$2" + + echo "gxde-update-worker: ${stage} failed with exit code ${ret}" >&2 + exit "$ret" +} + size_to_bytes() { local value="$1" local unit="$2" @@ -81,7 +99,7 @@ download_to_cache() { install_from_cache() { echo "# Installing updates from cache..." echo 85 - env LANGUAGE=en_US DEBIAN_FRONTEND=noninteractive ${APT_CMD} install -y --no-download --only-upgrade "$@" + apt_get_install_from_cache "$@" } case "$1" in @@ -144,13 +162,17 @@ case "$1" in download_to_cache "$@" download_ret="$?" if [ "$download_ret" -ne 0 ]; then - exit "$download_ret" + fail_with_log "download" "$download_ret" fi install_from_cache "$@" install_ret="$?" echo 100 - exit "$install_ret" + if [ "$install_ret" -ne 0 ]; then + fail_with_log "install" "$install_ret" + fi + + exit 0 } 2>&1 | tee "$UPGRADE_LOG" else env LANGUAGE=en_US DEBIAN_FRONTEND=noninteractive ${APT_CMD} upgrade -y 2>&1 | tee "$UPGRADE_LOG" @@ -160,6 +182,11 @@ case "$1" in write_error_status "$UPGRADE_LOG" "$UPGRADE_STATUS" if [ "$ret" -ne 0 ] || [ -s "$UPGRADE_STATUS" ]; then + echo "gxde-update-worker: upgrade failed, ret=${ret}, status=$(cat "$UPGRADE_STATUS" 2>/dev/null)" >&2 + if [ -f "$UPGRADE_LOG" ]; then + echo "gxde-update-worker: full log from ${UPGRADE_LOG}:" >&2 + sed 's/^/ /' "$UPGRADE_LOG" >&2 + fi exit 1 fi ;; -- Gitee From c466d5bc28668bf70f895173a4dbc5b1e38579fa Mon Sep 17 00:00:00 2001 From: momen Date: Tue, 5 May 2026 12:11:47 +0800 Subject: [PATCH 5/8] Bump version 5.0.16 --- debian/changelog | 5 +++-- src/frame/CMakeLists.txt | 9 +++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index d3b19a3..5689a7c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -gxde-control-center (5.0.15) UNRELEASED; urgency=medium +gxde-control-center (5.0.16) UNRELEASED; urgency=medium * 修复屏幕缩放调整条不对准刻度的问题 * 修复系统信息在时间异常时显示类似 ©2023-1970 等错误信息的问题 @@ -27,8 +27,9 @@ gxde-control-center (5.0.15) UNRELEASED; urgency=medium * 支持选择更新软件包,并先下载到 cache 后统一安装 * 调整更新入口样式、增加全选并增强更新失败日志 * 安装阶段沿用 aptss 的 apt 配置 + * 修复并行构建时 object 依赖文件目录缺失的问题 - -- gfdgd_xi <3025613752@qq.com> Tue, 05 May 2026 11:17:58 +0800 + -- gfdgd_xi <3025613752@qq.com> Tue, 05 May 2026 11:52:19 +0800 gxde-control-center (4.10.29.1) UNRELEASED; urgency=medium diff --git a/src/frame/CMakeLists.txt b/src/frame/CMakeLists.txt index ab10f50..d680f1b 100644 --- a/src/frame/CMakeLists.txt +++ b/src/frame/CMakeLists.txt @@ -952,6 +952,15 @@ foreach(LETTER ${BUILD_MACRO}) add_build_macro(${LETTER}) endforeach() +set(OBJECT_DIR "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${BIN_NAME}.dir") +file(MAKE_DIRECTORY "${OBJECT_DIR}") +foreach(SRC_FILE ${SRCS}) + get_filename_component(SRC_DIR "${SRC_FILE}" DIRECTORY) + if (SRC_DIR) + file(MAKE_DIRECTORY "${OBJECT_DIR}/${SRC_DIR}") + endif() +endforeach() + add_executable(${BIN_NAME} ${SRCS} ${QRC}) target_include_directories(${BIN_NAME} PUBLIC ${DtkWidget_INCLUDE_DIRS} -- Gitee From 81e02b7811c0a51c8132fe81c60e6bb9ffd0b49f Mon Sep 17 00:00:00 2001 From: momen Date: Tue, 5 May 2026 12:39:53 +0800 Subject: [PATCH 6/8] Bump version 5.0.17 --- debian/changelog | 5 +- src/frame/modules/update/updatectrlwidget.cpp | 34 +++++++++++ src/frame/modules/update/updatectrlwidget.h | 9 +++ src/frame/modules/update/updatemodel.cpp | 13 ++++ src/frame/modules/update/updatemodel.h | 4 ++ src/frame/modules/update/updatemodule.cpp | 16 ++++- src/frame/modules/update/updatemodule.h | 2 + src/frame/modules/update/updateview.cpp | 9 +-- src/frame/modules/update/updatework.cpp | 59 ++++++++++++++++++- 9 files changed, 142 insertions(+), 9 deletions(-) diff --git a/debian/changelog b/debian/changelog index 5689a7c..385e5cd 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -gxde-control-center (5.0.16) UNRELEASED; urgency=medium +gxde-control-center (5.0.17) UNRELEASED; urgency=medium * 修复屏幕缩放调整条不对准刻度的问题 * 修复系统信息在时间异常时显示类似 ©2023-1970 等错误信息的问题 @@ -28,8 +28,9 @@ gxde-control-center (5.0.16) UNRELEASED; urgency=medium * 调整更新入口样式、增加全选并增强更新失败日志 * 安装阶段沿用 aptss 的 apt 配置 * 修复并行构建时 object 依赖文件目录缺失的问题 + * 调整更新页内测设置位置,避免重复检查更新并格式化显示失败日志 - -- gfdgd_xi <3025613752@qq.com> Tue, 05 May 2026 11:52:19 +0800 + -- gfdgd_xi <3025613752@qq.com> Tue, 05 May 2026 12:27:10 +0800 gxde-control-center (4.10.29.1) UNRELEASED; urgency=medium diff --git a/src/frame/modules/update/updatectrlwidget.cpp b/src/frame/modules/update/updatectrlwidget.cpp index d6359f2..5dd0e5b 100644 --- a/src/frame/modules/update/updatectrlwidget.cpp +++ b/src/frame/modules/update/updatectrlwidget.cpp @@ -26,10 +26,14 @@ #include "updatectrlwidget.h" #include "updateitem.h" #include "widgets/translucentframe.h" +#include "widgets/plantextitem.h" #include #include #include +#include +#include +#include #include "updatemodel.h" #include "loadingitem.h" @@ -46,8 +50,11 @@ UpdateCtrlWidget::UpdateCtrlWidget(UpdateModel *model, QWidget *parent) m_status(UpdatesStatus::Updated), m_checkGroup(new SettingsGroup), m_checkUpdateItem(new LoadingItem), + m_refreshButton(new QPushButton(tr("Refresh"))), m_resultGroup(new SettingsGroup), m_resultItem(new ResultItem), + m_failureLogGroup(new SettingsGroup), + m_failureLogItem(new PlainTextItem), m_progress(new DownloadProgressBar), m_summaryGroup(new SettingsGroup), m_selectAllGroup(new SettingsGroup), @@ -71,9 +78,22 @@ UpdateCtrlWidget::UpdateCtrlWidget(UpdateModel *model, QWidget *parent) m_checkGroup->setVisible(false); m_checkGroup->appendItem(m_checkUpdateItem); + QHBoxLayout *refreshLayout = new QHBoxLayout; + refreshLayout->setMargin(0); + refreshLayout->addStretch(); + refreshLayout->addWidget(m_refreshButton); + m_resultGroup->setVisible(false); m_resultGroup->appendItem(m_resultItem); + m_failureLogGroup->setVisible(false); + m_failureLogItem->plainEdit()->setReadOnly(true); + m_failureLogItem->plainEdit()->setLineWrapMode(QPlainTextEdit::NoWrap); + m_failureLogItem->plainEdit()->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); + m_failureLogItem->plainEdit()->setMinimumHeight(180); + m_failureLogItem->plainEdit()->setMaximumHeight(320); + m_failureLogGroup->appendItem(m_failureLogItem); + m_progress->setVisible(false); m_summaryGroup->setVisible(false); @@ -105,8 +125,10 @@ UpdateCtrlWidget::UpdateCtrlWidget(UpdateModel *model, QWidget *parent) m_upgradeWarningGroup->appendItem(m_upgradeWarning); layout->addSpacing(10); + layout->addLayout(refreshLayout); layout->addWidget(m_checkGroup); layout->addWidget(m_resultGroup); + layout->addWidget(m_failureLogGroup); layout->addWidget(m_progress); layout->addWidget(m_upgradeWarningGroup); layout->addWidget(m_selectAllGroup); @@ -123,6 +145,7 @@ UpdateCtrlWidget::UpdateCtrlWidget(UpdateModel *model, QWidget *parent) connect(m_progress, &DownloadProgressBar::clicked, this, &UpdateCtrlWidget::onProgressBarClicked); connect(m_selectAll, &QCheckBox::toggled, this, &UpdateCtrlWidget::setAllPackagesSelected); + connect(m_refreshButton, &QPushButton::clicked, this, &UpdateCtrlWidget::requestRefreshUpdates); } UpdateCtrlWidget::~UpdateCtrlWidget() @@ -181,6 +204,7 @@ void UpdateCtrlWidget::setStatus(const UpdatesStatus &status) m_noNetworkTip->setVisible(false); m_resultGroup->setVisible(false); + m_failureLogGroup->setVisible(false); m_progress->setVisible(false); m_selectAllGroup->setVisible(false); m_summaryGroup->setVisible(false); @@ -189,6 +213,7 @@ void UpdateCtrlWidget::setStatus(const UpdatesStatus &status) m_checkGroup->setVisible(false); m_checkUpdateItem->setVisible(false); m_checkUpdateItem->setProgressBarVisible(false); + m_refreshButton->setDisabled(status == UpdatesStatus::Checking || status == UpdatesStatus::Downloading || status == UpdatesStatus::Installing); switch (status) { case UpdatesStatus::Checking: @@ -247,6 +272,7 @@ void UpdateCtrlWidget::setStatus(const UpdatesStatus &status) case UpdatesStatus::UpdateFailed: m_resultGroup->setVisible(true); m_resultItem->setSuccess(false); + setFailureMessage(m_model->failureMessage()); break; case UpdatesStatus::NeedRestart: m_checkGroup->setVisible(true); @@ -327,6 +353,12 @@ void UpdateCtrlWidget::setUpgradeMessage(const QString &message) } } +void UpdateCtrlWidget::setFailureMessage(const QString &message) +{ + m_failureLogItem->plainEdit()->setPlainText(message); + m_failureLogGroup->setVisible(m_status == UpdatesStatus::UpdateFailed && !message.isEmpty()); +} + QStringList UpdateCtrlWidget::selectedPackages() const { return m_selectedPackages.values(); @@ -392,11 +424,13 @@ void UpdateCtrlWidget::setModel(UpdateModel *model) connect(m_model, &UpdateModel::downloadInfoChanged, this, &UpdateCtrlWidget::setDownloadInfo); connect(m_model, &UpdateModel::upgradeProgressChanged, this, &UpdateCtrlWidget::setProgressValue); connect(m_model, &UpdateModel::upgradeMessageChanged, this, &UpdateCtrlWidget::setUpgradeMessage); + connect(m_model, &UpdateModel::failureMessageChanged, this, &UpdateCtrlWidget::setFailureMessage); connect(m_model, &UpdateModel::updateProgressChanged, this, &UpdateCtrlWidget::setUpdateProgress); setUpdateProgress(m_model->updateProgress()); setProgressValue(m_model->upgradeProgress()); setUpgradeMessage(m_model->upgradeMessage()); + setFailureMessage(m_model->failureMessage()); setStatus(m_model->status()); setLowBattery(m_model->lowBattery()); setDownloadInfo(m_model->downloadInfo()); diff --git a/src/frame/modules/update/updatectrlwidget.h b/src/frame/modules/update/updatectrlwidget.h index 3b4022e..812a85f 100644 --- a/src/frame/modules/update/updatectrlwidget.h +++ b/src/frame/modules/update/updatectrlwidget.h @@ -39,11 +39,15 @@ #include class QCheckBox; +class QPushButton; using namespace dcc; using namespace dcc::widgets; namespace dcc{ +namespace widgets { +class PlainTextItem; +} namespace update{ class UpdateModel; @@ -66,6 +70,7 @@ Q_SIGNALS: void requestPauseDownload(); void requestResumeDownload(); void requestInstallUpdates(); + void requestRefreshUpdates(); private Q_SLOTS: void onProgressBarClicked(); @@ -78,6 +83,7 @@ private: void setLowBattery(const bool &lowBattery); void setUpdateProgress(const double value); void setUpgradeMessage(const QString &message); + void setFailureMessage(const QString &message); QStringList selectedPackages() const; void updateSelectedPackages(); void setAllPackagesSelected(bool selected); @@ -88,8 +94,11 @@ private: SettingsGroup* m_checkGroup; LoadingItem* m_checkUpdateItem; + QPushButton *m_refreshButton; SettingsGroup *m_resultGroup; ResultItem *m_resultItem; + SettingsGroup *m_failureLogGroup; + dcc::widgets::PlainTextItem *m_failureLogItem; DownloadProgressBar* m_progress; SettingsGroup* m_summaryGroup; SettingsGroup* m_selectAllGroup; diff --git a/src/frame/modules/update/updatemodel.cpp b/src/frame/modules/update/updatemodel.cpp index bb33694..396cd6d 100644 --- a/src/frame/modules/update/updatemodel.cpp +++ b/src/frame/modules/update/updatemodel.cpp @@ -170,6 +170,11 @@ QString UpdateModel::upgradeMessage() const return m_upgradeMessage; } +QString UpdateModel::failureMessage() const +{ + return m_failureMessage; +} + void UpdateModel::setUpgradeMessage(const QString &upgradeMessage) { if (m_upgradeMessage != upgradeMessage) { @@ -178,6 +183,14 @@ void UpdateModel::setUpgradeMessage(const QString &upgradeMessage) } } +void UpdateModel::setFailureMessage(const QString &failureMessage) +{ + if (m_failureMessage != failureMessage) { + m_failureMessage = failureMessage; + Q_EMIT failureMessageChanged(failureMessage); + } +} + void UpdateModel::setUpgradeProgress(double upgradeProgress) { if (m_upgradeProgress != upgradeProgress) { diff --git a/src/frame/modules/update/updatemodel.h b/src/frame/modules/update/updatemodel.h index 7044a38..45cf272 100644 --- a/src/frame/modules/update/updatemodel.h +++ b/src/frame/modules/update/updatemodel.h @@ -87,6 +87,8 @@ public: void setUpgradeProgress(double upgradeProgress); QString upgradeMessage() const; void setUpgradeMessage(const QString &upgradeMessage); + QString failureMessage() const; + void setFailureMessage(const QString &failureMessage); bool autoCleanCache() const; void setAutoCleanCache(bool autoCleanCache); @@ -125,6 +127,7 @@ Q_SIGNALS: void updateProgressChanged(const double &updateProgress); void upgradeProgressChanged(const double &upgradeProgress); void upgradeMessageChanged(const QString &upgradeMessage); + void failureMessageChanged(const QString &failureMessage); void autoCleanCacheChanged(const bool autoCleanCache); void netselectExistChanged(const bool netselectExist); void autoCheckUpdatesChanged(const bool autoCheckUpdates); @@ -136,6 +139,7 @@ private: double m_updateProgress; double m_upgradeProgress; QString m_upgradeMessage; + QString m_failureMessage; #ifndef DISABLE_SYS_UPDATE_SOURCE_CHECK bool m_sourceCheck; diff --git a/src/frame/modules/update/updatemodule.cpp b/src/frame/modules/update/updatemodule.cpp index 51c526b..0269575 100644 --- a/src/frame/modules/update/updatemodule.cpp +++ b/src/frame/modules/update/updatemodule.cpp @@ -37,7 +37,8 @@ UpdateModule::UpdateModule(FrameProxyInterface *frame, QObject *parent) m_updateView(nullptr), m_updatePage(nullptr), m_settingsPage(nullptr), - m_mirrorsWidget(nullptr) + m_mirrorsWidget(nullptr), + m_checkedUpdates(false) { } @@ -115,12 +116,17 @@ void UpdateModule::onPushUpdate() { if (!m_updatePage) { m_updatePage = new UpdateCtrlWidget(m_model); - m_work->checkForUpdates(); connect(m_updatePage, &UpdateCtrlWidget::requestDownloadUpdates, m_work, &UpdateWorker::downloadAndDistUpgrade); connect(m_updatePage, &UpdateCtrlWidget::requestPauseDownload, m_work, &UpdateWorker::pauseDownload); connect(m_updatePage, &UpdateCtrlWidget::requestResumeDownload, m_work, &UpdateWorker::resumeDownload); connect(m_updatePage, &UpdateCtrlWidget::requestInstallUpdates, m_work, &UpdateWorker::distUpgrade); + connect(m_updatePage, &UpdateCtrlWidget::requestRefreshUpdates, this, &UpdateModule::onRefreshUpdates); + } + + if (!m_checkedUpdates) { + m_checkedUpdates = true; + m_work->checkForUpdates(); } m_frameProxy->pushWidget(this, m_updatePage); @@ -129,6 +135,12 @@ void UpdateModule::onPushUpdate() QDBusConnection::sessionBus().registerService(OfflineUpgraderService); } +void UpdateModule::onRefreshUpdates() +{ + m_checkedUpdates = true; + m_work->checkForUpdates(); +} + void UpdateModule::onPushMirrorsView() { if(!m_mirrorsWidget) { diff --git a/src/frame/modules/update/updatemodule.h b/src/frame/modules/update/updatemodule.h index 8e66786..37d3d60 100644 --- a/src/frame/modules/update/updatemodule.h +++ b/src/frame/modules/update/updatemodule.h @@ -60,6 +60,7 @@ private: private Q_SLOTS: void onPushUpdate(); + void onRefreshUpdates(); void onPushMirrorsView(); void onPushSettings(); @@ -70,6 +71,7 @@ private: UpdateCtrlWidget* m_updatePage; UpdateSettings* m_settingsPage; MirrorsWidget* m_mirrorsWidget; + bool m_checkedUpdates; }; } diff --git a/src/frame/modules/update/updateview.cpp b/src/frame/modules/update/updateview.cpp index 9548b9a..b252359 100644 --- a/src/frame/modules/update/updateview.cpp +++ b/src/frame/modules/update/updateview.cpp @@ -57,10 +57,6 @@ UpdateView::UpdateView() m_addTestingSource = new QPushButton; m_addTestingSource->setText(tr("Internal Testing Group Settings")); - if (QFile::exists("/usr/share/gxde-control-center/join-testing-group.sh")) { - // 需要保证脚本存在才会显示按钮 - m_centralLayout->addWidget(m_addTestingSource); - } m_disabledUpgradeNotifications = new SwitchWidget(tr("Disabled Upgrade Notifications")); @@ -68,6 +64,11 @@ UpdateView::UpdateView() m_centralLayout->addWidget(m_updateGroup); + if (QFile::exists("/usr/share/gxde-control-center/join-testing-group.sh")) { + // 需要保证脚本存在才会显示按钮 + m_centralLayout->addWidget(m_addTestingSource); + } + connect(m_addTestingSource, &QPushButton::clicked, this, &UpdateView::ShowTesingDialog); connect(m_updateItem, &NextPageWidget::clicked,this, &UpdateView::ExecUpgrader); connect(m_disabledUpgradeNotifications, &SwitchWidget::checkedChanged, this, &UpdateView::DisabledUpgradeNotifications); diff --git a/src/frame/modules/update/updatework.cpp b/src/frame/modules/update/updatework.cpp index 62c4470..5a7536a 100644 --- a/src/frame/modules/update/updatework.cpp +++ b/src/frame/modules/update/updatework.cpp @@ -59,6 +59,56 @@ static int TestMirrorSpeedInternal(const QString &url) return 10000; } +static QString RemoveAnsiEscapeCodes(QString text) +{ + const QRegExp ansi(QString("%1\\[[0-9;]*[A-Za-z]").arg(QChar(27))); + text.remove(ansi); + return text; +} + +static QString FormatWorkerFailureLog(const QString &stdoutText, const QString &stderrText) +{ + QString log = stderrText; + const QString marker = QStringLiteral("gxde-update-worker: full log"); + const int markerIndex = log.indexOf(marker); + + if (markerIndex >= 0) { + const int lineEnd = log.indexOf('\n', markerIndex); + log = lineEnd >= 0 ? log.mid(lineEnd + 1) : log.mid(markerIndex + marker.length()); + } else { + log = stdoutText; + if (!stderrText.trimmed().isEmpty()) { + if (!log.endsWith('\n') && !log.isEmpty()) { + log += '\n'; + } + log += stderrText; + } + } + + log = RemoveAnsiEscapeCodes(log); + log.replace("\r\n", "\n"); + log.replace('\r', '\n'); + + QStringList lines; + for (QString line : log.split('\n')) { + if (line.startsWith(" ")) { + line = line.mid(2); + } + + lines << line; + } + + while (!lines.isEmpty() && lines.first().trimmed().isEmpty()) { + lines.removeFirst(); + } + + while (!lines.isEmpty() && lines.last().trimmed().isEmpty()) { + lines.removeLast(); + } + + return lines.join('\n'); +} + UpdateWorker::UpdateWorker(UpdateModel* model, QObject *parent) : QObject(parent) , m_model(model) @@ -135,6 +185,7 @@ void UpdateWorker::checkForUpdates() } m_model->setStatus(UpdatesStatus::Checking); + m_model->setFailureMessage(QString()); m_model->setUpdateProgress(0); m_aptssProcess = new QProcess(this); @@ -142,6 +193,7 @@ void UpdateWorker::checkForUpdates() const QByteArray errorOutput = m_aptssProcess->readAllStandardError(); if (exitStatus != QProcess::NormalExit || exitCode != 0) { qWarning() << "aptss update failed:" << errorOutput; + m_model->setFailureMessage(FormatWorkerFailureLog(QString(), QString::fromLocal8Bit(errorOutput))); m_model->setStatus(UpdatesStatus::UpdateFailed); clearAptssProcess(); return; @@ -361,6 +413,7 @@ void UpdateWorker::distUpgradePackages(const QStringList &packages) } m_model->setStatus(UpdatesStatus::Installing); + m_model->setFailureMessage(QString()); m_model->setUpgradeProgress(0); m_model->setUpgradeMessage(tr("Downloading updates...")); m_aptssStdout.clear(); @@ -400,6 +453,7 @@ void UpdateWorker::distUpgradePackages(const QStringList &packages) if (exitStatus == QProcess::NormalExit && exitCode == 0) { m_model->setUpgradeProgress(1); m_model->setUpgradeMessage(QString()); + m_model->setFailureMessage(QString()); m_model->setStatus(UpdatesStatus::UpdateSucceeded); QProcess::startDetached("/usr/lib/gxde-control-center/reboot-reminder-dialog"); @@ -416,6 +470,7 @@ void UpdateWorker::distUpgradePackages(const QStringList &packages) << "stdout:" << m_aptssStdout << "stderr:" << m_aptssStderr; m_model->setUpgradeMessage(QString()); + m_model->setFailureMessage(FormatWorkerFailureLog(m_aptssStdout, m_aptssStderr)); m_model->setStatus(UpdatesStatus::UpdateFailed); } @@ -480,7 +535,9 @@ void UpdateWorker::runAptssCheckList() m_aptssProcess = new QProcess(this); connect(m_aptssProcess, static_cast(&QProcess::finished), this, [this](int exitCode, QProcess::ExitStatus exitStatus) { if (exitStatus != QProcess::NormalExit || exitCode != 0) { - qWarning() << "aptss list --upgradable failed:" << m_aptssProcess->readAllStandardError(); + const QString errorOutput = QString::fromLocal8Bit(m_aptssProcess->readAllStandardError()); + qWarning() << "aptss list --upgradable failed:" << errorOutput; + m_model->setFailureMessage(FormatWorkerFailureLog(QString(), errorOutput)); m_model->setStatus(UpdatesStatus::UpdateFailed); clearAptssProcess(); return; -- Gitee From 079b59478db7945a76f23273ffb03a4f6f7de755 Mon Sep 17 00:00:00 2001 From: momen Date: Tue, 5 May 2026 13:43:54 +0800 Subject: [PATCH 7/8] Bump version 5.1.0 --- debian/changelog | 6 ++-- src/frame/modules/update/updatectrlwidget.cpp | 2 +- src/frame/modules/update/updatework.cpp | 7 ++++- .../gxde-control-center/gxde-update-worker.sh | 30 +++++++++++++++++-- translations/gxde-control-center_zh_CN.ts | 5 ++++ 5 files changed, 43 insertions(+), 7 deletions(-) diff --git a/debian/changelog b/debian/changelog index 385e5cd..f1f30f7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -gxde-control-center (5.0.17) UNRELEASED; urgency=medium +gxde-control-center (5.1.0) UNRELEASED; urgency=medium * 修复屏幕缩放调整条不对准刻度的问题 * 修复系统信息在时间异常时显示类似 ©2023-1970 等错误信息的问题 @@ -29,8 +29,10 @@ gxde-control-center (5.0.17) UNRELEASED; urgency=medium * 安装阶段沿用 aptss 的 apt 配置 * 修复并行构建时 object 依赖文件目录缺失的问题 * 调整更新页内测设置位置,避免重复检查更新并格式化显示失败日志 + * 调整刷新按钮位置并使用 aptss apt 配置计算下载大小 + * 为更新安装阶段补充非交互环境和 dpkg 配置策略 - -- gfdgd_xi <3025613752@qq.com> Tue, 05 May 2026 12:27:10 +0800 + -- gfdgd_xi <3025613752@qq.com> Tue, 05 May 2026 12:43:02 +0800 gxde-control-center (4.10.29.1) UNRELEASED; urgency=medium diff --git a/src/frame/modules/update/updatectrlwidget.cpp b/src/frame/modules/update/updatectrlwidget.cpp index 5dd0e5b..6b1fe3a 100644 --- a/src/frame/modules/update/updatectrlwidget.cpp +++ b/src/frame/modules/update/updatectrlwidget.cpp @@ -125,11 +125,11 @@ UpdateCtrlWidget::UpdateCtrlWidget(UpdateModel *model, QWidget *parent) m_upgradeWarningGroup->appendItem(m_upgradeWarning); layout->addSpacing(10); - layout->addLayout(refreshLayout); layout->addWidget(m_checkGroup); layout->addWidget(m_resultGroup); layout->addWidget(m_failureLogGroup); layout->addWidget(m_progress); + layout->addLayout(refreshLayout); layout->addWidget(m_upgradeWarningGroup); layout->addWidget(m_selectAllGroup); layout->addWidget(m_summaryGroup); diff --git a/src/frame/modules/update/updatework.cpp b/src/frame/modules/update/updatework.cpp index 5a7536a..1967611 100644 --- a/src/frame/modules/update/updatework.cpp +++ b/src/frame/modules/update/updatework.cpp @@ -425,7 +425,12 @@ void UpdateWorker::distUpgradePackages(const QStringList &packages) m_aptssStdout += output; for (const QString &line : output.split('\n', QString::SkipEmptyParts)) { if (line.startsWith('#')) { - m_model->setUpgradeMessage(line.mid(1).trimmed()); + const QString message = line.mid(1).trimmed(); + if (message == tr("Updates installed successfully") || message == QStringLiteral("Updates installed successfully")) { + m_model->setUpgradeProgress(1); + } else { + m_model->setUpgradeMessage(message); + } continue; } diff --git a/tools/gxde-control-center/gxde-update-worker.sh b/tools/gxde-control-center/gxde-update-worker.sh index 12859c3..8c05259 100755 --- a/tools/gxde-control-center/gxde-update-worker.sh +++ b/tools/gxde-control-center/gxde-update-worker.sh @@ -15,12 +15,33 @@ else fi APTSS_APT_CONF=/opt/durapps/spark-store/bin/apt-fast-conf/aptss-apt.conf +APT_ENV=( + LANGUAGE=en_US + DEBIAN_FRONTEND=noninteractive + DEBCONF_NONINTERACTIVE_SEEN=true + APT_LISTCHANGES_FRONTEND=none + NEEDRESTART_MODE=a + UCF_FORCE_CONFFOLD=1 +) +APT_OPTIONS=( + -o Dpkg::Use-Pty=0 + -o Dpkg::Options::=--force-confdef + -o Dpkg::Options::=--force-confold +) apt_get_install_from_cache() { if [ -f "$APTSS_APT_CONF" ]; then - env LANGUAGE=en_US DEBIAN_FRONTEND=noninteractive /usr/bin/apt-get -c "$APTSS_APT_CONF" install -y --no-download --only-upgrade "$@" + env "${APT_ENV[@]}" /usr/bin/apt-get -c "$APTSS_APT_CONF" "${APT_OPTIONS[@]}" install -y --no-download --only-upgrade "$@" else - env LANGUAGE=en_US DEBIAN_FRONTEND=noninteractive /usr/bin/apt-get install -y --no-download --only-upgrade "$@" + env "${APT_ENV[@]}" /usr/bin/apt-get "${APT_OPTIONS[@]}" install -y --no-download --only-upgrade "$@" + fi +} + +apt_get_simulate_download_size() { + if [ -f "$APTSS_APT_CONF" ]; then + env "${APT_ENV[@]}" /usr/bin/apt-get -c "$APTSS_APT_CONF" "${APT_OPTIONS[@]}" install --simulate --only-upgrade "$@" + else + env "${APT_ENV[@]}" /usr/bin/apt-get "${APT_OPTIONS[@]}" install --simulate --only-upgrade "$@" fi } @@ -140,7 +161,7 @@ case "$1" in exit 0 fi - output=$(env LANGUAGE=en_US DEBIAN_FRONTEND=noninteractive ${APT_CMD} install --simulate --only-upgrade "$@" 2>/dev/null || true) + output=$(apt_get_simulate_download_size "$@" 2>/dev/null || true) need_line=$(printf '%s\n' "$output" | awk '/^Need to get / { line = $0 } END { print line }') if [ -z "$need_line" ]; then @@ -189,6 +210,9 @@ case "$1" in fi exit 1 fi + + echo "# Updates installed successfully" + echo 100 ;; clean-log) rm -f "$UPDATE_LOG" "$UPDATE_STATUS" "$UPGRADE_LOG" "$UPGRADE_STATUS" diff --git a/translations/gxde-control-center_zh_CN.ts b/translations/gxde-control-center_zh_CN.ts index 4a02124..0699ff8 100644 --- a/translations/gxde-control-center_zh_CN.ts +++ b/translations/gxde-control-center_zh_CN.ts @@ -4332,6 +4332,11 @@ Power by fantascene-dynamic-wallpaper Network disconnected, please retry after connected 网络断开,请联网后重试 + + + Refresh + 刷新 + This update may take a long time, please do not shut down or reboot during the process -- Gitee From 5503b09d66ddc1a436fb33f707602e2740719a17 Mon Sep 17 00:00:00 2001 From: momen Date: Tue, 5 May 2026 14:14:12 +0800 Subject: [PATCH 8/8] Bump version 5.1.1 --- debian/changelog | 5 +++-- src/frame/modules/update/updatectrlwidget.cpp | 2 +- src/frame/modules/update/updatework.cpp | 10 ++++++++-- translations/gxde-control-center_zh_CN.ts | 20 +++++++++++++++++++ 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/debian/changelog b/debian/changelog index f1f30f7..d4a6b15 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -gxde-control-center (5.1.0) UNRELEASED; urgency=medium +gxde-control-center (5.1.1) UNRELEASED; urgency=medium * 修复屏幕缩放调整条不对准刻度的问题 * 修复系统信息在时间异常时显示类似 ©2023-1970 等错误信息的问题 @@ -31,8 +31,9 @@ gxde-control-center (5.1.0) UNRELEASED; urgency=medium * 调整更新页内测设置位置,避免重复检查更新并格式化显示失败日志 * 调整刷新按钮位置并使用 aptss apt 配置计算下载大小 * 为更新安装阶段补充非交互环境和 dpkg 配置策略 + * 下载大小为 0 或获取不到时隐藏,并补充更新进度状态翻译 - -- gfdgd_xi <3025613752@qq.com> Tue, 05 May 2026 12:43:02 +0800 + -- gfdgd_xi <3025613752@qq.com> Tue, 05 May 2026 13:05:48 +0800 gxde-control-center (4.10.29.1) UNRELEASED; urgency=medium diff --git a/src/frame/modules/update/updatectrlwidget.cpp b/src/frame/modules/update/updatectrlwidget.cpp index 6b1fe3a..00c38eb 100644 --- a/src/frame/modules/update/updatectrlwidget.cpp +++ b/src/frame/modules/update/updatectrlwidget.cpp @@ -327,7 +327,7 @@ void UpdateCtrlWidget::setDownloadInfo(DownloadInfo *downloadInfo) } } - m_summary->setDetails(QString(tr("Download size: %1").arg(formatCap(downloadSize)))); + m_summary->setDetails(downloadSize > 0 ? QString(tr("Download size: %1").arg(formatCap(downloadSize))) : QString()); if (downloadSize) { if ((downloadSize / 1024) / 1024 >= m_qsettings->value("upgrade_waring_size", UpgradeWarningSize).toInt()) diff --git a/src/frame/modules/update/updatework.cpp b/src/frame/modules/update/updatework.cpp index 1967611..b5f358b 100644 --- a/src/frame/modules/update/updatework.cpp +++ b/src/frame/modules/update/updatework.cpp @@ -426,8 +426,14 @@ void UpdateWorker::distUpgradePackages(const QStringList &packages) for (const QString &line : output.split('\n', QString::SkipEmptyParts)) { if (line.startsWith('#')) { const QString message = line.mid(1).trimmed(); - if (message == tr("Updates installed successfully") || message == QStringLiteral("Updates installed successfully")) { + if (message == QStringLiteral("Updates installed successfully")) { m_model->setUpgradeProgress(1); + m_model->setUpgradeMessage(tr("Updates installed successfully")); + } else if (message == QStringLiteral("Installing updates from cache...")) { + m_model->setUpgradeMessage(tr("Installing updates from cache...")); + } else if (message.startsWith(QStringLiteral("Downloading updates..."))) { + const QString speed = message.mid(QStringLiteral("Downloading updates...").length()).trimmed(); + m_model->setUpgradeMessage(speed.isEmpty() ? tr("Downloading updates...") : tr("Downloading updates... %1").arg(speed)); } else { m_model->setUpgradeMessage(message); } @@ -592,7 +598,7 @@ void UpdateWorker::runAptssDownloadSize(const QList &infos, const m_aptssProcess = new QProcess(this); connect(m_aptssProcess, static_cast(&QProcess::finished), this, [this, infos](int exitCode, QProcess::ExitStatus exitStatus) { - qlonglong downloadSize = 1; + qlonglong downloadSize = 0; if (exitStatus == QProcess::NormalExit && exitCode == 0) { const QString output = QString::fromLocal8Bit(m_aptssProcess->readAllStandardOutput()).trimmed(); diff --git a/translations/gxde-control-center_zh_CN.ts b/translations/gxde-control-center_zh_CN.ts index 0699ff8..0fa3266 100644 --- a/translations/gxde-control-center_zh_CN.ts +++ b/translations/gxde-control-center_zh_CN.ts @@ -4545,6 +4545,26 @@ Power by fantascene-dynamic-wallpaper System patches 系统补丁 + + + Downloading updates... + 正在下载更新... + + + + Downloading updates... %1 + 正在下载更新... %1 + + + + Installing updates from cache... + 正在从缓存安装更新... + + + + Updates installed successfully + 更新安装成功 + dcc::wacom::WacomModePage -- Gitee