Kde: add kinfocenter patches

This commit is contained in:
Toast 2025-03-04 14:31:15 +01:00
parent f3ee33177f
commit 92a6c20c18
2 changed files with 498 additions and 0 deletions

View file

@ -0,0 +1,426 @@
From f44af69b07ed19d076819fe4cc84e5777747d957 Mon Sep 17 00:00:00 2001
From: Oliver Beard <olib141@outlook.com>
Date: Thu, 20 Feb 2025 22:43:47 +0000
Subject: [PATCH 1/2] kcms/about-distro: Add help property to Entry & show
total amount of installed memory in MemoryEntry This provides additional
information to the user, with a new help tooltip that clarifies the displayed
values as is contextually appropriate. For example, if the shown message is
"32 GB of RAM (31.3 GB usable)", the tooltip will elucidate that some memory
is reserved for use by system hardware. BUG: 500412
---
CMakeLists.txt | 4 +
kcms/about-distro/src/CMakeLists.txt | 5 +
kcms/about-distro/src/Entry.cpp | 5 +
kcms/about-distro/src/Entry.h | 3 +
kcms/about-distro/src/MemoryEntry.cpp | 144 +++++++++++++++++++++++---
kcms/about-distro/src/MemoryEntry.h | 9 +-
kcms/about-distro/src/ui/main.qml | 5 +
7 files changed, 157 insertions(+), 18 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 51f940789..e3005878a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -41,6 +41,10 @@ find_package(KF6 ${KF6_MIN_VERSION} REQUIRED COMPONENTS
find_package(PkgConfig)
pkg_check_modules(libdrm REQUIRED IMPORTED_TARGET libdrm)
+if(CMAKE_SYSTEM_NAME MATCHES "Linux")
+ find_package(UDev REQUIRED COMPONENTS UDev)
+endif()
+
ecm_find_qmlmodule(org.kde.kirigami 2.5)
macro(kinfocenter_add_kcm target)
diff --git a/kcms/about-distro/src/CMakeLists.txt b/kcms/about-distro/src/CMakeLists.txt
index 13ad8d0af..d731d81a1 100644
--- a/kcms/about-distro/src/CMakeLists.txt
+++ b/kcms/about-distro/src/CMakeLists.txt
@@ -43,6 +43,11 @@ target_link_libraries(kcm_about-distro PRIVATE
PkgConfig::libdrm
)
+if(UDev_FOUND)
+ target_link_libraries(kcm_about-distro PRIVATE UDev::UDev)
+ target_compile_definitions(kcm_about-distro PRIVATE UDEV_FOUND)
+endif()
+
cmake_path(RELATIVE_PATH KDE_INSTALL_FULL_LIBEXECDIR BASE_DIRECTORY "${KDE_INSTALL_FULL_PLUGINDIR}/plasma/kcms/" OUTPUT_VARIABLE LIBEXECDIR_FROM_KCM)
target_compile_options(
diff --git a/kcms/about-distro/src/Entry.cpp b/kcms/about-distro/src/Entry.cpp
index a4077efda..63dc71fbb 100644
--- a/kcms/about-distro/src/Entry.cpp
+++ b/kcms/about-distro/src/Entry.cpp
@@ -82,4 +82,9 @@ Hint Entry::localizedHint(Language) const
return {};
}
+QString Entry::localizedHelp(Language) const
+{
+ return {};
+}
+
#include "moc_Entry.cpp"
diff --git a/kcms/about-distro/src/Entry.h b/kcms/about-distro/src/Entry.h
index e5c3f6f17..bc053a4f4 100644
--- a/kcms/about-distro/src/Entry.h
+++ b/kcms/about-distro/src/Entry.h
@@ -78,6 +78,9 @@ public:
// Returns a hint for the user to consider when interpreting the value.
Q_INVOKABLE [[nodiscard]] virtual Hint localizedHint(Language language = Language::System) const;
+ // Returns a help string for the entry, shown with a ContextualHelpButton
+ Q_SCRIPTABLE [[nodiscard]] virtual QString localizedHelp(Language language = Language::System) const;
+
protected:
// Returns localized QString for the given language.
QString localize(const KLocalizedString &string, Language language) const;
diff --git a/kcms/about-distro/src/MemoryEntry.cpp b/kcms/about-distro/src/MemoryEntry.cpp
index 1baaea2ac..b58b55237 100644
--- a/kcms/about-distro/src/MemoryEntry.cpp
+++ b/kcms/about-distro/src/MemoryEntry.cpp
@@ -9,6 +9,9 @@
#ifdef Q_OS_LINUX
#include <sys/sysinfo.h>
+#ifdef UDEV_FOUND
+#include <libudev.h>
+#endif
#elif defined(Q_OS_FREEBSD)
// clang-format off
#include <sys/types.h>
@@ -21,34 +24,141 @@ MemoryEntry::MemoryEntry()
{
}
-qlonglong MemoryEntry::calculateTotalRam()
+std::optional<qlonglong> MemoryEntry::calculateTotalRam()
+{
+#if defined(Q_OS_LINUX) && defined(UDEV_FOUND)
+ std::unique_ptr<struct udev, decltype(&udev_unref)> udev(udev_new(), &udev_unref);
+ if (!udev) {
+ return {};
+ }
+
+ std::unique_ptr<struct udev_device, decltype(&udev_device_unref)> dmi(udev_device_new_from_syspath(udev.get(), "/sys/class/dmi/id/"), &udev_device_unref);
+ if (!dmi) {
+ return {};
+ }
+
+ const char *numMemoryDevicesCStr = udev_device_get_property_value(dmi.get(), "MEMORY_ARRAY_NUM_DEVICES");
+ if (!numMemoryDevicesCStr) {
+ return {};
+ }
+
+ bool ok;
+ int numMemoryDevices = QByteArray(numMemoryDevicesCStr).toInt(&ok);
+ if (!ok) {
+ return {};
+ }
+
+ qlonglong totalBytes = 0;
+ for (int i = 0; i < numMemoryDevices; ++i) {
+ const char *memoryBytesCStr = udev_device_get_property_value(dmi.get(), QStringLiteral("MEMORY_DEVICE_%1_SIZE").arg(i).toLatin1());
+ qlonglong memoryBytes = QByteArray(memoryBytesCStr).toLongLong(&ok);
+ if (ok) {
+ totalBytes += memoryBytes;
+ }
+ }
+
+ return totalBytes;
+#endif
+
+ /*
+ * TODO: A FreeBSD impl is likely possible, but it appears that
+ * sysctlbyname() cannot get what we want with either "hw.physmem",
+ * "hw.usermem" or "hw.realmem".
+ * On a system with 2 x 4 GiB memory modules installed, we would need
+ * to return a value of 8 GiB in bytes.
+ */
+
+ return {};
+}
+
+std::optional<qlonglong> MemoryEntry::calculateAvailableRam()
{
- qlonglong ret = -1;
#ifdef Q_OS_LINUX
struct sysinfo info;
- if (sysinfo(&info) == 0)
- // manpage "sizes are given as multiples of mem_unit bytes"
- ret = qlonglong(info.totalram) * info.mem_unit;
+ if (sysinfo(&info) == 0) {
+ // manpage: "sizes are given as multiples of mem_unit bytes"
+ return qlonglong(info.totalram) * info.mem_unit;
+ }
#elif defined(Q_OS_FREEBSD)
/* Stuff for sysctl */
- size_t len;
-
unsigned long memory;
- len = sizeof(memory);
- sysctlbyname("hw.physmem", &memory, &len, NULL, 0);
-
- ret = memory;
+ size_t len = sizeof(memory);
+ if (sysctlbyname("hw.physmem", &memory, &len, NULL, 0) == 0) {
+ return memory;
+ }
#endif
- return ret;
+
+ return {};
}
QString MemoryEntry::localizedValue(Language language) const
{
- const qlonglong totalRam = calculateTotalRam();
- if (totalRam > 0) {
- const auto string = ki18nc("@label %1 is the formatted amount of system memory (e.g. 7,7 GiB)", "%1 of RAM")
- .subs(KFormat(localeForLanguage(language)).formatByteSize(totalRam));
+ auto precisionForGiB = [](std::optional<qlonglong> bytes) -> int {
+ if (!bytes.has_value()) {
+ return 0;
+ }
+
+ constexpr qlonglong GiB = 1024 * 1024 * 1024;
+ return (bytes.value() % GiB == 0) ? 0 : 1;
+ };
+
+ const int totalRamPrecision = precisionForGiB(m_totalRam);
+ const int availableRamPrecision = precisionForGiB(m_availableRam);
+
+ if (m_totalRam.has_value() && m_availableRam.has_value()) {
+ // Both known
+ const auto string = ki18nc("@label, %1 is the total amount of installed system memory, %2 is the amount of which is usable, both expressed as 7.7 GiB",
+ "%1 of RAM (%2 usable)")
+ .subs(KFormat(localeForLanguage(language)).formatByteSize(m_totalRam.value(), totalRamPrecision))
+ .subs(KFormat(localeForLanguage(language)).formatByteSize(m_availableRam.value(), availableRamPrecision));
+ return localize(string, language);
+ }
+
+ if (m_totalRam.has_value() && !m_availableRam.has_value()) {
+ // Known total, unknown available
+ const auto string = ki18nc("@label, %1 is the amount of installed system memory expressed as 7.7 GiB", "%1 of RAM")
+ .subs(KFormat(localeForLanguage(language)).formatByteSize(m_totalRam.value(), totalRamPrecision));
+ return localize(string, language);
+ }
+
+ if (!m_totalRam.has_value() && m_availableRam.has_value()) {
+ // Unknown total, known available
+ const auto string = ki18nc("@label, %1 is the amount of usable system memory expressed as 7.7 GiB", "%1 of usable RAM")
+ .subs(KFormat(localeForLanguage(language)).formatByteSize(m_availableRam.value(), availableRamPrecision));
return localize(string, language);
}
- return localize(ki18nc("Unknown amount of RAM", "Unknown"), language);
+
+ // Both unknown
+ return localize(ki18nc("@label, Unknown amount of system memory", "Unknown"), language);
+}
+
+QString MemoryEntry::localizedHelp(Language language) const
+{
+ if (m_totalRam.has_value() && m_availableRam.has_value()) {
+ // Both known
+ return localize(ki18nc("@info:tooltip, referring to system memory or RAM",
+ "Some memory is reserved for use by the kernel or system hardware such as integrated graphics memory."),
+ language);
+ }
+
+ if (m_totalRam.has_value() && !m_availableRam.has_value()) {
+ // Known total, unknown available
+ return localize(
+ ki18nc("@info:tooltip, referring to system memory or RAM",
+ "The amount of usable memory may be lower than the displayed amount because some memory is reserved for use by the kernel or system "
+ "hardware, such as integrated graphics memory."),
+ language);
+ }
+
+ if (!m_totalRam.has_value() && m_availableRam.has_value()) {
+ // Unknown total, known available
+ return localize(
+ ki18nc("@info:tooltip, referring to system memory or RAM",
+ "The amount of memory displayed may be lower than the installed amount because some memory is reserved for use by the kernel or system "
+ "hardware, such as integrated graphics memory."),
+ language);
+ }
+
+ // Both unknown
+ return QString();
}
diff --git a/kcms/about-distro/src/MemoryEntry.h b/kcms/about-distro/src/MemoryEntry.h
index 43beb2e87..d0757651f 100644
--- a/kcms/about-distro/src/MemoryEntry.h
+++ b/kcms/about-distro/src/MemoryEntry.h
@@ -12,10 +12,17 @@ class MemoryEntry : public Entry
{
public:
MemoryEntry();
- static qlonglong calculateTotalRam();
// Overwrite to get correct localization for the value.
QString localizedValue(Language language = Language::System) const final;
+ QString localizedHelp(Language language = Language::System) const final;
+
+private:
+ static std::optional<qlonglong> calculateTotalRam();
+ static std::optional<qlonglong> calculateAvailableRam();
+
+ std::optional<qlonglong> m_totalRam = calculateTotalRam();
+ std::optional<qlonglong> m_availableRam = calculateAvailableRam();
};
#endif // MEMORYENTRY_H
diff --git a/kcms/about-distro/src/ui/main.qml b/kcms/about-distro/src/ui/main.qml
index 80fbc2c13..e80b7fe93 100644
--- a/kcms/about-distro/src/ui/main.qml
+++ b/kcms/about-distro/src/ui/main.qml
@@ -167,6 +167,11 @@ KCMUtils.SimpleKCM {
}
}
+ Kirigami.ContextualHelpButton {
+ visible: toolTipText.length > 0
+ toolTipText: entry.localizedHelp()
+ }
+
QQC2.Button {
visible: hidden
property var dialog: null
--
GitLab
From fc2e540dc6f4784c2602a520f4b3285355213f5a Mon Sep 17 00:00:00 2001
From: Oliver Beard <olib141@outlook.com>
Date: Mon, 24 Feb 2025 23:17:48 +0000
Subject: [PATCH 2/2] kcms/about-distro: Clean-up and refactoring - Spacing
specified on RowLayout - Instead of specifying properties up-front for each
entry, entries use them as needed. - Use .length > 0 instead of !== "" -
[[nodiscard]] and Q_INVOKABLE specified on virtual Entry methods
---
kcms/about-distro/src/Entry.h | 8 +++---
kcms/about-distro/src/ui/main.qml | 42 +++++++++++++++----------------
2 files changed, 25 insertions(+), 25 deletions(-)
diff --git a/kcms/about-distro/src/Entry.h b/kcms/about-distro/src/Entry.h
index bc053a4f4..3c7dd8491 100644
--- a/kcms/about-distro/src/Entry.h
+++ b/kcms/about-distro/src/Entry.h
@@ -66,20 +66,20 @@ public:
// Returns textual representation of entry.
QString diagnosticLine(Language language = Language::System) const;
- Q_SCRIPTABLE virtual QString localizedLabel(Language language = Language::System) const;
+ Q_INVOKABLE [[nodiscard]] virtual QString localizedLabel(Language language = Language::System) const;
// Returns the value by default. Needs to be overridden in subclasses if localization
// is needed for the value.
- Q_SCRIPTABLE virtual QString localizedValue(Language language = Language::System) const;
+ Q_INVOKABLE [[nodiscard]] virtual QString localizedValue(Language language = Language::System) const;
// Returns whether this Entry should be hidden by default (i.e. only shown upon user request)
- Q_INVOKABLE virtual bool isHidden() const;
+ Q_INVOKABLE [[nodiscard]] virtual bool isHidden() const;
// Returns a hint for the user to consider when interpreting the value.
Q_INVOKABLE [[nodiscard]] virtual Hint localizedHint(Language language = Language::System) const;
// Returns a help string for the entry, shown with a ContextualHelpButton
- Q_SCRIPTABLE [[nodiscard]] virtual QString localizedHelp(Language language = Language::System) const;
+ Q_INVOKABLE [[nodiscard]] virtual QString localizedHelp(Language language = Language::System) const;
protected:
// Returns localized QString for the given language.
diff --git a/kcms/about-distro/src/ui/main.qml b/kcms/about-distro/src/ui/main.qml
index e80b7fe93..547f4b665 100644
--- a/kcms/about-distro/src/ui/main.qml
+++ b/kcms/about-distro/src/ui/main.qml
@@ -54,14 +54,14 @@ KCMUtils.SimpleKCM {
}
Kirigami.Heading {
- visible: kcm.distroVariant !== ""
+ visible: kcm.distroVariant.length > 0
text: kcm.distroVariant
level: 2
type: Kirigami.Heading.Type.Secondary
}
QQC2.Label {
- visible: kcm.distroUrl !== ""
+ visible: kcm.distroUrl.length > 0
text: "<a href='%1'>%1</a>".arg(kcm.distroUrl)
textFormat: Text.RichText
onLinkActivated: link => Qt.openUrlExternally(link)
@@ -82,23 +82,11 @@ KCMUtils.SimpleKCM {
Kirigami.FormData.label: entry.localizedLabel()
Kirigami.FormData.labelAlignment: idealAlignment
Layout.alignment: idealAlignment
+
readonly property int idealAlignment: valueLabel.lineCount > 1 ? Qt.AlignTop : Qt.AlignVCenter // looks tidier this way
readonly property bool hidden: entry.isHidden()
- readonly property string hint: entry.localizedHint().text
- readonly property color hintColorForeground: {
- switch (entry.localizedHint().color) {
- case Private.Hint.Color.One: return Kirigami.Theme.linkColor
- case Private.Hint.Color.Two: return Kirigami.Theme.positiveTextColor
- case Private.Hint.Color.Three: return Kirigami.Theme.alternateTextColor
- }
- }
- readonly property color hintColorBackground: {
- switch (entry.localizedHint().color) {
- case Private.Hint.Color.One: return Kirigami.Theme.linkBackgroundColor
- case Private.Hint.Color.Two: return Kirigami.Theme.positiveBackgroundColor
- case Private.Hint.Color.Three: return Kirigami.Theme.alternateBackgroundColor
- }
- }
+
+ spacing: Kirigami.Units.smallSpacing
Component {
id: unhideDialog
@@ -138,7 +126,7 @@ KCMUtils.SimpleKCM {
QQC2.Label {
Kirigami.Theme.colorSet: Kirigami.Theme.Window
- visible: hint !== ""
+ visible: text.length > 0
// Vertical padding accounts for the difference in normal label height and the content height of this small label
readonly property real verticalPadding: (hintMetrics.height - contentHeight) / 2
@@ -156,13 +144,25 @@ KCMUtils.SimpleKCM {
leftPadding: horizontalPadding
rightPadding: horizontalPadding
- text: hint
- color: hintColorForeground
+ text: entry.localizedHint().text
+ color: {
+ switch (entry.localizedHint().color) {
+ case Private.Hint.Color.One: return Kirigami.Theme.linkColor
+ case Private.Hint.Color.Two: return Kirigami.Theme.positiveTextColor
+ case Private.Hint.Color.Three: return Kirigami.Theme.alternateTextColor
+ }
+ }
font.bold: true
font.pixelSize: Kirigami.Theme.smallFont.pixelSize
background: Rectangle {
- color: hintColorBackground
+ color: {
+ switch (entry.localizedHint().color) {
+ case Private.Hint.Color.One: return Kirigami.Theme.linkBackgroundColor
+ case Private.Hint.Color.Two: return Kirigami.Theme.positiveBackgroundColor
+ case Private.Hint.Color.Three: return Kirigami.Theme.alternateBackgroundColor
+ }
+ }
radius: Kirigami.Units.cornerRadius
}
}
--
GitLab