Publish tool cleanup and Framework monitoring refinements
This commit is contained in:
@@ -15,10 +15,11 @@ include(KDEInstallDirs)
|
||||
include(KDECMakeSettings)
|
||||
include(KDECompilerSettings NO_POLICY_SCOPE)
|
||||
|
||||
find_package(Qt6 6.8 REQUIRED COMPONENTS Core Quick Test)
|
||||
find_package(Qt6 6.8 REQUIRED COMPONENTS Core Quick)
|
||||
find_package(KF6 6.0 REQUIRED COMPONENTS Auth Config CoreAddons I18n KCMUtils)
|
||||
|
||||
add_subdirectory(src)
|
||||
if(BUILD_TESTING)
|
||||
find_package(Qt6 6.8 REQUIRED COMPONENTS Test)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Name: fedora-tools-settings
|
||||
Version: 0.1.0
|
||||
Release: 12%{?dist}
|
||||
Release: 13%{?dist}
|
||||
Summary: Plasma System Settings module for Fedora Tools
|
||||
|
||||
License: MIT
|
||||
@@ -74,6 +74,10 @@ done
|
||||
%{_datadir}/polkit-1/actions/se.ajpanton.fedoratools.policy
|
||||
|
||||
%changelog
|
||||
* Sat Sep 12 2026 fedora-tools contributors - 0.1.0-13
|
||||
- Share settings validation and report failed configuration writes
|
||||
- Simplify ordering and source packaging
|
||||
|
||||
* Tue Sep 08 2026 fedora-tools contributors - 0.1.0-12
|
||||
- Hide unsupported Framework hardware tools and flag incompatible local installs
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include <KSharedConfig>
|
||||
|
||||
#include <QFile>
|
||||
#include <QRegularExpression>
|
||||
#include <QTimer>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -212,7 +211,10 @@ void FedoraToolsKcm::saveShortcutSettings(bool startWithFirst,
|
||||
group.writeEntry("StartWithFirstWindow", startWithFirst);
|
||||
group.writeEntry("InitialShiftOpensNewInstance", initialShiftOpensNew);
|
||||
group.writeEntry("ShiftCyclesBackward", shiftCyclesBackward);
|
||||
group.sync();
|
||||
if (!group.sync()) {
|
||||
setMessage(i18n("Could not save shortcut settings."), true);
|
||||
return;
|
||||
}
|
||||
loadToolSettings();
|
||||
setMessage(i18n("Shortcut settings were saved."));
|
||||
}
|
||||
@@ -222,7 +224,10 @@ void FedoraToolsKcm::resetShortcutSettings()
|
||||
const auto config = KSharedConfig::openConfig(QStringLiteral("plasma-task-group-shortcutsrc"));
|
||||
KConfigGroup group(config, QStringLiteral("Settings"));
|
||||
group.deleteGroup();
|
||||
group.sync();
|
||||
if (!group.sync()) {
|
||||
setMessage(i18n("Could not reset shortcut settings."), true);
|
||||
return;
|
||||
}
|
||||
loadToolSettings();
|
||||
setMessage(i18n("Shortcut settings were reset to their defaults."));
|
||||
}
|
||||
@@ -233,15 +238,10 @@ void FedoraToolsKcm::saveTouchpadSettings(int minimumAnchorAge,
|
||||
int maximumTap,
|
||||
const QString &outputEvent)
|
||||
{
|
||||
static const QRegularExpression eventName(QStringLiteral("^(BTN|KEY)_[A-Z0-9_]+$"));
|
||||
if (m_busy) {
|
||||
return;
|
||||
}
|
||||
if (minimumAnchorAge < 0 || minimumAnchorAge > 2000
|
||||
|| minimumPause < 0 || minimumPause > 2000
|
||||
|| minimumTap < 0 || minimumTap > maximumTap
|
||||
|| maximumTap < 1 || maximumTap > 2000
|
||||
|| !eventName.match(outputEvent).hasMatch()) {
|
||||
if (!validTouchpadSettings(minimumAnchorAge, minimumPause, minimumTap, maximumTap, outputEvent)) {
|
||||
setMessage(i18n("Enter valid timing values and an evdev BTN_* or KEY_* output event."), true);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <QFileInfo>
|
||||
#include <QObject>
|
||||
#include <QProcess>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
@@ -192,17 +191,14 @@ public Q_SLOTS:
|
||||
return KAuth::ActionReply::InvalidActionReply();
|
||||
}
|
||||
|
||||
const int minimumAnchorAge = arguments.value(QStringLiteral("minimumAnchorAge")).toInt();
|
||||
const int minimumPause = arguments.value(QStringLiteral("minimumPause")).toInt();
|
||||
const int minimumTap = arguments.value(QStringLiteral("minimumTap")).toInt();
|
||||
const int maximumTap = arguments.value(QStringLiteral("maximumTap")).toInt();
|
||||
bool ageValid, pauseValid, tapValid, maximumValid;
|
||||
const int minimumAnchorAge = arguments.value(QStringLiteral("minimumAnchorAge")).toInt(&ageValid);
|
||||
const int minimumPause = arguments.value(QStringLiteral("minimumPause")).toInt(&pauseValid);
|
||||
const int minimumTap = arguments.value(QStringLiteral("minimumTap")).toInt(&tapValid);
|
||||
const int maximumTap = arguments.value(QStringLiteral("maximumTap")).toInt(&maximumValid);
|
||||
const QString outputEvent = arguments.value(QStringLiteral("outputEvent")).toString();
|
||||
static const QRegularExpression eventName(QStringLiteral("^(BTN|KEY)_[A-Z0-9_]+$"));
|
||||
if (minimumAnchorAge < 0 || minimumAnchorAge > 2000
|
||||
|| minimumPause < 0 || minimumPause > 2000
|
||||
|| minimumTap < 0 || minimumTap > maximumTap
|
||||
|| maximumTap < 1 || maximumTap > 2000
|
||||
|| !eventName.match(outputEvent).hasMatch()) {
|
||||
if (!ageValid || !pauseValid || !tapValid || !maximumValid
|
||||
|| !validTouchpadSettings(minimumAnchorAge, minimumPause, minimumTap, maximumTap, outputEvent)) {
|
||||
KAuth::ActionReply reply = KAuth::ActionReply::HelperErrorReply();
|
||||
reply.addData(QStringLiteral("message"), QStringLiteral("The requested touchpad settings are invalid."));
|
||||
return reply;
|
||||
|
||||
@@ -36,7 +36,7 @@ QList<PackageRecord> parsePackageRecords(const QByteArray &output)
|
||||
|
||||
bool isValidPackageName(const QString &name)
|
||||
{
|
||||
static const QRegularExpression expression(QStringLiteral("^[a-z0-9][a-z0-9+._-]*$"));
|
||||
static const QRegularExpression expression(QStringLiteral("\\A[a-z0-9][a-z0-9+._-]*\\z"));
|
||||
return expression.match(name).hasMatch();
|
||||
}
|
||||
|
||||
@@ -51,3 +51,14 @@ QString packageCompatibilityError(const QString &name, const QString &sys)
|
||||
&& read(sys + QStringLiteral("/class/dmi/id/product_name")) == QLatin1String("Laptop 13 Pro (Intel Core Ultra Series 3)")) return {};
|
||||
return QStringLiteral("Incompatible: requires Framework Laptop 13 Pro (Intel Core Ultra Series 3).");
|
||||
}
|
||||
|
||||
bool validTouchpadSettings(int minimumAnchorAge, int minimumPause, int minimumTap,
|
||||
int maximumTap, const QString &outputEvent)
|
||||
{
|
||||
static const QRegularExpression eventName(QStringLiteral("\\A(BTN|KEY)_[A-Z0-9_]+\\z"));
|
||||
return minimumAnchorAge >= 0 && minimumAnchorAge <= 2000
|
||||
&& minimumPause >= 0 && minimumPause <= 2000
|
||||
&& minimumTap >= 0 && minimumTap <= maximumTap
|
||||
&& maximumTap >= 1 && maximumTap <= 2000
|
||||
&& eventName.match(outputEvent).hasMatch();
|
||||
}
|
||||
|
||||
@@ -16,4 +16,6 @@ struct PackageRecord
|
||||
|
||||
QList<PackageRecord> parsePackageRecords(const QByteArray &output);
|
||||
bool isValidPackageName(const QString &name);
|
||||
bool validTouchpadSettings(int minimumAnchorAge, int minimumPause, int minimumTap,
|
||||
int maximumTap, const QString &outputEvent);
|
||||
QString packageCompatibilityError(const QString &name, const QString &sys = QStringLiteral("/sys"));
|
||||
|
||||
@@ -150,13 +150,8 @@ void ToolModel::setPackages(const QList<PackageRecord> &installed,
|
||||
tool.updateAvailable = tool.available && tool.installed && updates.contains(package.name);
|
||||
}
|
||||
|
||||
QList<Tool> merged = tools.values();
|
||||
std::ranges::sort(merged, [](const Tool &left, const Tool &right) {
|
||||
return left.packageName < right.packageName;
|
||||
});
|
||||
|
||||
beginResetModel();
|
||||
m_tools = std::move(merged);
|
||||
m_tools = tools.values(); // QMap already orders entries by package name.
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,17 @@ class PackageUtilsTest : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
private Q_SLOTS:
|
||||
void validatesTouchpadSettings()
|
||||
{
|
||||
QVERIFY(validTouchpadSettings(100, 100, 10, 150, QStringLiteral("BTN_MIDDLE")));
|
||||
QVERIFY(validTouchpadSettings(0, 0, 0, 2000, QStringLiteral("KEY_F13")));
|
||||
QVERIFY(!validTouchpadSettings(-1, 100, 10, 150, QStringLiteral("BTN_MIDDLE")));
|
||||
QVERIFY(!validTouchpadSettings(100, 2001, 10, 150, QStringLiteral("BTN_MIDDLE")));
|
||||
QVERIFY(!validTouchpadSettings(100, 100, 151, 150, QStringLiteral("BTN_MIDDLE")));
|
||||
QVERIFY(!validTouchpadSettings(100, 100, 0, 0, QStringLiteral("BTN_MIDDLE")));
|
||||
QVERIFY(!validTouchpadSettings(100, 100, 10, 150, QStringLiteral("BTN_MIDDLE\n")));
|
||||
QVERIFY(!validTouchpadSettings(100, 100, 10, 150, QStringLiteral("BTN_MIDDLE; reboot")));
|
||||
}
|
||||
void frameworkCompatibility() {
|
||||
QTemporaryDir root;
|
||||
QVERIFY(packageCompatibilityError(QStringLiteral("touchpad-hold-tap"), root.path()).isEmpty());
|
||||
@@ -43,6 +54,7 @@ private Q_SLOTS:
|
||||
QVERIFY(!isValidPackageName(QStringLiteral("--installroot=/tmp")));
|
||||
QVERIFY(!isValidPackageName(QStringLiteral("tool; reboot")));
|
||||
QVERIFY(!isValidPackageName(QStringLiteral("Tool")));
|
||||
QVERIFY(!isValidPackageName(QStringLiteral("touchpad-hold-tap\n")));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user