Kickoff from our plasma-desktop fork, not a patch file
Some checks failed
Image, disk image and live ISO / iso (push) Failing after 2m12s
Some checks failed
Image, disk image and live ISO / iso (push) Failing after 2m12s
The update bar is now a commit on quine-global-labs/plasma-desktop, branch quine-v<Plasma version> (KDE's release plus our commits), and kickoff-builder builds from that branch. patches/kickoff/ goes; its standalone CMakeLists.txt moves to kickoff/. A missing branch for the image's Plasma version fails the build with a pointer to the fork's rebase workflow. Same plugin as before (built and compared on the runner). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
8bdc165476
commit
8da036e5a0
4 changed files with 14 additions and 146 deletions
|
|
@ -37,19 +37,20 @@ RUN set -eux; \
|
||||||
|
|
||||||
# --- Builds Kickoff (the start menu) with our update bar. ---
|
# --- Builds Kickoff (the start menu) with our update bar. ---
|
||||||
# Kickoff is QML packed into one plugin of plasma-desktop. This rebuilds
|
# Kickoff is QML packed into one plugin of plasma-desktop. This rebuilds
|
||||||
# just that plugin from the same plasma-desktop version the image ships
|
# just that plugin from our fork, quine-global-labs/plasma-desktop, branch
|
||||||
# (KDE's source, via the forge's mirror), with patches/kickoff/ on top, and
|
# quine-v<version>: KDE's release of the plasma-desktop version the image
|
||||||
# the final stage puts it in place of the stock one. Like kmod-builder, it's
|
# ships, plus our commits. The final stage puts it in place of the stock
|
||||||
# built FROM BASE_IMAGE so it can't drift from the Plasma it runs on; the
|
# one. Like kmod-builder, it's built FROM BASE_IMAGE so it can't drift from
|
||||||
# -devel packages are pinned to the installed versions (older ones come
|
# the Plasma it runs on; the -devel packages are pinned to the installed
|
||||||
# from Fedora's updates-archive).
|
# versions (older ones come from Fedora's updates-archive). kickoff/ holds
|
||||||
|
# the CMakeLists.txt that builds the applet outside plasma-desktop's tree.
|
||||||
FROM ${BASE_IMAGE} AS kickoff-builder
|
FROM ${BASE_IMAGE} AS kickoff-builder
|
||||||
|
|
||||||
COPY patches/kickoff/ /tmp/kickoff/
|
COPY kickoff/CMakeLists.txt /tmp/kickoff/
|
||||||
|
|
||||||
RUN set -eux; \
|
RUN set -eux; \
|
||||||
v() { rpm -q --qf '%{VERSION}-%{RELEASE}' "$1"; }; \
|
v() { rpm -q --qf '%{VERSION}-%{RELEASE}' "$1"; }; \
|
||||||
devel=(cmake gcc-c++ extra-cmake-modules patch \
|
devel=(cmake gcc-c++ extra-cmake-modules \
|
||||||
"libplasma-devel-$(v libplasma)" \
|
"libplasma-devel-$(v libplasma)" \
|
||||||
"qt6-qtbase-devel-$(v qt6-qtbase)" \
|
"qt6-qtbase-devel-$(v qt6-qtbase)" \
|
||||||
"qt6-qtdeclarative-devel-$(v qt6-qtdeclarative)"); \
|
"qt6-qtdeclarative-devel-$(v qt6-qtdeclarative)"); \
|
||||||
|
|
@ -58,15 +59,14 @@ RUN set -eux; \
|
||||||
done; \
|
done; \
|
||||||
dnf install -y --setopt=install_weak_deps=False "${devel[@]}"; \
|
dnf install -y --setopt=install_weak_deps=False "${devel[@]}"; \
|
||||||
V="$(rpm -q --qf '%{VERSION}' plasma-desktop)"; \
|
V="$(rpm -q --qf '%{VERSION}' plasma-desktop)"; \
|
||||||
echo "Building Kickoff from plasma-desktop ${V}"; \
|
echo "Building Kickoff from quine-global-labs/plasma-desktop, branch quine-v${V}"; \
|
||||||
curl -fsSL --retry 3 -o /tmp/plasma-desktop.tar.gz \
|
curl -fsSL --retry 3 -o /tmp/plasma-desktop.tar.gz \
|
||||||
"https://forge.quinefoundation.com/quine-global-labs/mirror-kde-plasma-desktop/archive/v${V}.tar.gz"; \
|
"https://forge.quinefoundation.com/quine-global-labs/plasma-desktop/archive/quine-v${V}.tar.gz" \
|
||||||
|
|| { echo "No branch quine-v${V} in quine-global-labs/plasma-desktop: the image moved to Plasma ${V}; its rebase workflow makes the branch, or failed to (check its Actions)" >&2; exit 1; }; \
|
||||||
mkdir -p /build-src; \
|
mkdir -p /build-src; \
|
||||||
tar -xzf /tmp/plasma-desktop.tar.gz -C /build-src --strip-components=2 \
|
tar -xzf /tmp/plasma-desktop.tar.gz -C /build-src --strip-components=2 \
|
||||||
mirror-kde-plasma-desktop/applets/kickoff; \
|
plasma-desktop/applets/kickoff; \
|
||||||
cp /tmp/kickoff/CMakeLists.txt /build-src/; \
|
cp /tmp/kickoff/CMakeLists.txt /build-src/; \
|
||||||
cd /build-src; \
|
|
||||||
for p in /tmp/kickoff/*.patch; do patch -p1 --fuzz=0 < "$p"; done; \
|
|
||||||
cmake -S /build-src -B /build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr; \
|
cmake -S /build-src -B /build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr; \
|
||||||
cmake --build /build -j"$(nproc)"; \
|
cmake --build /build -j"$(nproc)"; \
|
||||||
DESTDIR=/out cmake --install /build --strip; \
|
DESTDIR=/out cmake --install /build --strip; \
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/bash
|
#!/usr/bin/bash
|
||||||
# Is a newer Quine Linux available, or downloaded and waiting for a restart?
|
# Is a newer Quine Linux available, or downloaded and waiting for a restart?
|
||||||
# Writes the answer to /run/quine-linux/update-status.json, which Kickoff's
|
# Writes the answer to /run/quine-linux/update-status.json, which Kickoff's
|
||||||
# update bar reads (patches/kickoff). Run as root by
|
# update bar reads (quine-global-labs/plasma-desktop). Run as root by
|
||||||
# quine-update-check.service: bootc needs root.
|
# quine-update-check.service: bootc needs root.
|
||||||
#
|
#
|
||||||
# state: "staged" an update is downloaded; it applies at the next boot
|
# state: "staged" an update is downloaded; it applies at the next boot
|
||||||
|
|
|
||||||
|
|
@ -1,132 +0,0 @@
|
||||||
diff --git a/kickoff/CMakeLists.txt b/kickoff/CMakeLists.txt
|
|
||||||
index 70e361c..d860cb4 100644
|
|
||||||
--- a/kickoff/CMakeLists.txt
|
|
||||||
+++ b/kickoff/CMakeLists.txt
|
|
||||||
@@ -26,6 +26,7 @@ QML_SOURCES
|
|
||||||
ListOfGridsView.qml
|
|
||||||
ListOfGridsViewDelegate.qml
|
|
||||||
NormalPage.qml
|
|
||||||
+ UpdateBar.qml
|
|
||||||
PlacesPage.qml
|
|
||||||
SectionView.qml
|
|
||||||
VerticalStackView.qml
|
|
||||||
diff --git a/kickoff/FullRepresentation.qml b/kickoff/FullRepresentation.qml
|
|
||||||
index aa25d3c..7d9a6bb 100644
|
|
||||||
--- a/kickoff/FullRepresentation.qml
|
|
||||||
+++ b/kickoff/FullRepresentation.qml
|
|
||||||
@@ -77,6 +77,9 @@ EmptyPage {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+ // Quine Linux: system update status (UpdateBar.qml).
|
|
||||||
+ footer: UpdateBar {}
|
|
||||||
+
|
|
||||||
contentItem: VerticalStackView {
|
|
||||||
id: contentItemStackView
|
|
||||||
focus: true
|
|
||||||
diff --git a/kickoff/UpdateBar.qml b/kickoff/UpdateBar.qml
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..3ebe376
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/kickoff/UpdateBar.qml
|
|
||||||
@@ -0,0 +1,100 @@
|
|
||||||
+/*
|
|
||||||
+ SPDX-FileCopyrightText: 2026 Quine Foundation
|
|
||||||
+ SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
+*/
|
|
||||||
+
|
|
||||||
+// Quine Linux: a bar at the bottom of Kickoff when a newer system image is
|
|
||||||
+// available, or downloaded and waiting for a restart. It reads the status
|
|
||||||
+// that quine-update-check.service writes as root (quine-linux's overlay,
|
|
||||||
+// /usr/libexec/quine-linux/update-check), and is hidden otherwise.
|
|
||||||
+
|
|
||||||
+pragma ComponentBehavior: Bound
|
|
||||||
+
|
|
||||||
+import QtQuick
|
|
||||||
+import org.kde.kirigami as Kirigami
|
|
||||||
+import org.kde.plasma.plasma5support as P5Support
|
|
||||||
+import org.kde.plasma.private.sessions as Sessions
|
|
||||||
+
|
|
||||||
+Kirigami.InlineMessage {
|
|
||||||
+ id: root
|
|
||||||
+
|
|
||||||
+ readonly property string statusFile: "/run/quine-linux/update-status.json"
|
|
||||||
+ readonly property string readCommand: "cat " + statusFile
|
|
||||||
+ // "current", "available" or "staged"; anything else hides the bar.
|
|
||||||
+ property string updateState: ""
|
|
||||||
+ property string newBuild: ""
|
|
||||||
+
|
|
||||||
+ position: Kirigami.InlineMessage.Position.Footer
|
|
||||||
+ // Hidden, InlineMessage's implicit height is 0, so the menu doesn't keep
|
|
||||||
+ // room for it (EmptyPage sizes by the footer's implicit height).
|
|
||||||
+ visible: updateState === "available" || updateState === "staged"
|
|
||||||
+ showCloseButton: false
|
|
||||||
+ type: updateState === "staged" ? Kirigami.MessageType.Positive : Kirigami.MessageType.Information
|
|
||||||
+ icon.name: updateState === "staged" ? "system-reboot-update" : "system-software-update"
|
|
||||||
+ text: updateState === "staged"
|
|
||||||
+ ? i18nc("@info", "An update is ready. Restart to finish updating.")
|
|
||||||
+ : i18nc("@info", "A system update is available%1.",
|
|
||||||
+ newBuild ? i18nc("@info build date", " (built %1)", newBuild) : "")
|
|
||||||
+
|
|
||||||
+ actions: [
|
|
||||||
+ Kirigami.Action {
|
|
||||||
+ visible: root.updateState === "available"
|
|
||||||
+ text: i18nc("@action:button", "Update Now")
|
|
||||||
+ icon.name: "system-software-update"
|
|
||||||
+ // Aurora's System Update: `ujust update` in a terminal.
|
|
||||||
+ onTriggered: {
|
|
||||||
+ executable.connectSource("kioclient exec /usr/share/applications/dev.getaurora.system-update.desktop")
|
|
||||||
+ kickoff.expanded = false
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
+ Kirigami.Action {
|
|
||||||
+ visible: root.updateState === "staged" && sessions.canReboot
|
|
||||||
+ text: i18nc("@action:button", "Restart")
|
|
||||||
+ icon.name: "system-reboot"
|
|
||||||
+ onTriggered: {
|
|
||||||
+ kickoff.expanded = false
|
|
||||||
+ sessions.requestReboot()
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ ]
|
|
||||||
+
|
|
||||||
+ Sessions.SessionManagement {
|
|
||||||
+ id: sessions
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ P5Support.DataSource {
|
|
||||||
+ id: executable
|
|
||||||
+ engine: "executable"
|
|
||||||
+ connectedSources: []
|
|
||||||
+ onNewData: (source, data) => {
|
|
||||||
+ disconnectSource(source)
|
|
||||||
+ if (source !== root.readCommand) {
|
|
||||||
+ return
|
|
||||||
+ }
|
|
||||||
+ let status = null
|
|
||||||
+ try {
|
|
||||||
+ status = JSON.parse(data["stdout"])
|
|
||||||
+ } catch (e) {
|
|
||||||
+ // No file yet (the first check hasn't run, or a live session).
|
|
||||||
+ }
|
|
||||||
+ root.updateState = status?.state ?? ""
|
|
||||||
+ const built = status?.new?.timestamp
|
|
||||||
+ root.newBuild = built ? Qt.formatDate(new Date(built), Qt.locale(), Locale.ShortFormat) : ""
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ function refresh() {
|
|
||||||
+ executable.connectSource(readCommand)
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ Component.onCompleted: refresh()
|
|
||||||
+
|
|
||||||
+ Connections {
|
|
||||||
+ target: kickoff
|
|
||||||
+ function onExpandedChanged() {
|
|
||||||
+ if (kickoff.expanded) {
|
|
||||||
+ root.refresh()
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
Loading…
Reference in a new issue