Repository navigation
Enhanced build scripts with progress bar and platform migration #30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
fa2239c
aff8382
aa15949
b4d38fc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,37 +1,55 @@ | ||
| #!/bin/bash | ||
| #!/usr/bin/env bash | ||
| set -euo pipefail | ||
|
|
||
| if command -v apt >/dev/null; then | ||
| echo "installing dependencies" | ||
| if command -v apt-get >/dev/null; then | ||
| echo "Detected Debian/Ubuntu-based system, installing dependencies..." | ||
| sudo apt-get update | ||
| sudo apt-get install -y \ | ||
| build-essential \ | ||
| desktop-file-utils \ | ||
| dpkg-dev \ | ||
| libqt6svg6-dev \ | ||
| qt6-base-dev \ | ||
| qt6-tools-dev-tools \ | ||
| qt6-webengine-dev \ | ||
| libwebkit2gtk-4.1-dev \ | ||
| libgtk-3-dev \ | ||
| shared-mime-info \ | ||
| zlib1g-dev \ | ||
| libssl-dev \ | ||
| file \ | ||
| libatomic1 \ | ||
| libdeflate0 \ | ||
| libjbig0 \ | ||
| liblerc4 \ | ||
| libngtcp2-dev \ | ||
| libngtcp2-crypto-gnutls-dev \ | ||
| libqt6pdf6 \ | ||
| libqt6qmlworkerscript6 \ | ||
| libnss3 \ | ||
| libssh2-1 \ | ||
| libssl3 \ | ||
| libtiff-dev \ | ||
| libxcb-cursor0 \ | ||
| libxcb-xinput0 \ | ||
| libjpeg62 | ||
| build-essential \ | ||
| desktop-file-utils \ | ||
| dpkg-dev \ | ||
| libqt6svg6-dev \ | ||
| qt6-base-dev \ | ||
| qt6-tools-dev-tools \ | ||
| qt6-webengine-dev \ | ||
| libwebkit2gtk-4.1-dev \ | ||
| libgtk-3-dev \ | ||
| shared-mime-info \ | ||
| zlib1g-dev \ | ||
| libssl-dev \ | ||
| file \ | ||
| libatomic1 \ | ||
| libdeflate0 \ | ||
| libjbig0 \ | ||
| liblerc4 \ | ||
| libngtcp2-dev \ | ||
| libngtcp2-crypto-gnutls-dev \ | ||
| libqt6pdf6 \ | ||
| libqt6qmlworkerscript6 \ | ||
| libnss3 \ | ||
| libssh2-1 \ | ||
| libssl3 \ | ||
| libtiff-dev \ | ||
| libxcb-cursor0 \ | ||
| libxcb-xinput0 \ | ||
| libjpeg62 | ||
| elif command -v pacman >/dev/null; then | ||
| echo "Detected Arch Linux-based system, installing dependencies..." | ||
| sudo pacman -Syu --needed --noconfirm \ | ||
| gcc \ | ||
| make \ | ||
| pkgconf \ | ||
| qt6-base \ | ||
| qt6-webengine \ | ||
| webkit2gtk-4.1 \ | ||
| gtk3 \ | ||
| zlib \ | ||
| hicolor-icon-theme \ | ||
| shared-mime-info \ | ||
| desktop-file-utils \ | ||
| polkit \ | ||
| qt6-tools | ||
| else | ||
| echo "detected non-debian system, skipping dependency install" | ||
| echo "Detected unsupported package manager. Please manually install the Qt6 and WebEngine dependencies." | ||
| exit 1 | ||
| fi |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,5 @@ | ||
| #include "audio_controller.h" | ||
|
|
||
| #include "command_helper.h" | ||
|
|
||
| #include <QRegularExpression> | ||
| #include <QTimer> | ||
|
|
||
|
|
@@ -23,17 +21,33 @@ const AudioState &AudioController::state() const | |
| } | ||
|
|
||
| void AudioController::refresh() | ||
| { | ||
| if (getVolumeProcess_ && getVolumeProcess_->state() != QProcess::NotRunning) { | ||
| return; | ||
| } | ||
|
|
||
| if (!getVolumeProcess_) { | ||
| getVolumeProcess_ = new QProcess(this); | ||
| connect(getVolumeProcess_, &QProcess::finished, this, &AudioController::onGetVolumeFinished); | ||
| } | ||
|
|
||
| getVolumeProcess_->start(QStringLiteral("wpctl"), {QStringLiteral("get-volume"), QStringLiteral("@DEFAULT_AUDIO_SINK@")}); | ||
| } | ||
|
Comment on lines
+24
to
+35
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -eu
file="src/shell/taskbar/platform/audio_controller.cpp"
printf '%s\n' '--- target file ---'
cat -n "$file" | sed -n '1,130p'
printf '%s\n' '--- related declarations and call sites ---'
rg -n -C 4 \
'AudioController|refresh\(|onGetVolumeFinished|errorOccurred|state_\.available|stateChanged|wpctl|QRegularExpression' \
src/shell/taskbar \
-g '*.{cpp,h,hpp}'Repository: Jvr2022/seb-linux Length of output: 25033 🏁 Script executed: #!/bin/bash
set -eu
python3 - <<'PY'
from pathlib import Path
path = Path("src/shell/taskbar/platform/audio_controller.cpp")
text = path.read_text()
refresh = text[text.index("void AudioController::refresh()"):text.index("void AudioController::onGetVolumeFinished")]
finish = text[text.index("void AudioController::onGetVolumeFinished"):text.index("void AudioController::setMuted")]
print("finished connection:", "&QProcess::finished" in refresh)
print("errorOccurred connection:", "errorOccurred" in refresh)
print("failed-start invalidation:", "FailedToStart" in text and "available = false" in text)
print("success path marks available before parsing:", "next.available = true" in finish)
print("success path requires a numeric match:", "if (match.hasMatch())" in finish)
PYRepository: Jvr2022/seb-linux Length of output: 340 🌐 Web query:
💡 Result: In Qt 6, the QProcess::errorOccurred and QProcess::finished signals serve distinct purposes regarding the lifecycle of a process [1][2]. The errorOccurred(QProcess::ProcessError error) signal is emitted whenever an error occurs with the process [1]. This includes failures during the startup phase, such as when an executable cannot be found or permissions are denied, which triggers the QProcess::FailedToStart error [3][4]. The finished(int exitCode, QProcess::ExitStatus exitStatus) signal is emitted only when a process that has successfully started subsequently finishes (either normally or by crashing) [1][4]. If a process fails to start (i.e., it never enters the Running state), the finished signal will not be emitted, because the process never reached a state where it could "finish" [5]. Key takeaways for implementation: - If a process fails to start (e.g., QProcess::FailedToStart), only errorOccurred will be triggered [5]. - Do not rely on finished to detect startup failures [5]. - The errorOccurred signal is the correct mechanism to catch and handle startup-related errors [1][4]. - On some platforms (notably Windows), startup signals may be emitted synchronously before the start function returns, while on other platforms, these signals may be delayed [2]. Always ensure you connect your slots before calling start [4]. Citations:
Handle When 🤖 Prompt for AI AgentsSource: MCP tools |
||
|
|
||
| void AudioController::onGetVolumeFinished(int exitCode, QProcess::ExitStatus exitStatus) | ||
| { | ||
| AudioState next; | ||
| const QString output = runCommand(QStringLiteral("wpctl"), {QStringLiteral("get-volume"), QStringLiteral("@DEFAULT_AUDIO_SINK@")}); | ||
| if (!output.isEmpty()) { | ||
| if (exitStatus == QProcess::NormalExit && exitCode == 0) { | ||
| next.available = true; | ||
| const QString output = QString::fromUtf8(getVolumeProcess_->readAllStandardOutput()).trimmed(); | ||
| next.muted = output.contains(QStringLiteral("[MUTED]"), Qt::CaseInsensitive); | ||
| const QRegularExpression regex(QStringLiteral("([0-9]+(?:\\.[0-9]+)?)")); | ||
| const auto match = regex.match(output); | ||
| if (match.hasMatch()) { | ||
| next.volumePercent = qBound(0, qRound(match.captured(1).toDouble() * 100.0), 100); | ||
| } | ||
| } else { | ||
| next.available = false; | ||
|
Comment on lines
+37
to
+50
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- target files ---'
fd -i 'audio_controller' . || true
printf '%s\n' '--- target source ---'
target="$(fd -i -t f 'audio_controller.cpp' . | head -n 1)"
if [ -n "${target}" ]; then
nl -ba "$target" | sed -n '1,150p'
fi
printf '%s\n' '--- declarations and state consumers ---'
rg -n -C 3 'onGetVolumeFinished|AudioState|available|volumePercent|wpctl|QRegularExpression' src/shell/taskbar . --glob '!build/**' --glob '!dist/**' | head -n 350Repository: Jvr2022/seb-linux Length of output: 25198 🏁 Script executed: #!/bin/bash
set -eu
python3 - <<'PY'
import re
pattern = re.compile(r'([0-9]+(?:\.[0-9]+)?)')
samples = [
("empty output", ""),
("normal output", "Volume: 0.50"),
("muted output", "Volume: 0.50 [MUTED]"),
("integer output", "Volume: 1.00"),
("unexpected text", "wpctl: unexpected output"),
("unexpected text with number", "error 123"),
("malformed decimal", "Volume: .50"),
("multiple numbers", "Volume: 0.50 (100%)"),
]
for name, output in samples:
match = pattern.search(output.strip())
if match:
value = round(float(match.group(1)) * 100)
value = max(0, min(value, 100))
available = True
else:
value = 0
available = True # current successful-exit branch
print(f"{name}: match={match.group(1) if match else None!r}, "
f"available={available}, volumePercent={value}")
PY
printf '%s\n' '--- project references to wpctl ---'
rg -n -C 2 'get-volume|set-volume|set-mute' . --glob '!build/**' --glob '!dist/**'Repository: Jvr2022/seb-linux Length of output: 2135 🌐 Web query:
💡 Result: The wpctl get-volume command is used to display volume information, including the current volume level and mute state, for a specified node [1][2]. According to the official WirePlumber documentation, the command structure is: wpctl get-volume ID In this command: - ID refers to the Node ID or a special identifier (such as Citations:
Validate the complete If 🤖 Prompt for AI Agents🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -eu
file="src/shell/taskbar/platform/audio_controller.cpp"
printf '%s\n' '--- target file ---'
cat -n "$file" | sed -n '1,130p'
printf '%s\n' '--- related declarations and call sites ---'
rg -n -C 4 'AudioController|onGetVolumeFinished|setMuted|setVolume|valueChanged|readyReadStandardOutput|errorOccurred|startDetached|start\(' src/shell/taskbarRepository: Jvr2022/seb-linux Length of output: 15401 🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- audio controller header ---'
cat -n src/shell/taskbar/platform/audio_controller.h | sed -n '1,100p'
printf '%s\n' '--- all AudioController consumers ---'
rg -n -C 6 'audioController|setMuted\(|setVolume\(|AudioState|stateChanged' src
printf '%s\n' '--- relevant project and test references ---'
rg -n -i -C 3 'audio|wpctl|get-volume|set-volume|set-mute' CMakeLists.txt src tests 2>/dev/null || true
printf '%s\n' '--- concise history summary for the target file ---'
git log --oneline -8 -- src/shell/taskbar/platform/audio_controller.cppRepository: Jvr2022/seb-linux Length of output: 50373 🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- AudioControl state synchronization ---'
cat -n src/ui/taskbar/controls/audio_control.cpp | sed -n '80,115p'
printf '%s\n' '--- executable interleaving verifier ---'
python3 - <<'PY'
from dataclasses import dataclass
`@dataclass`
class AudioState:
available: bool = False
muted: bool = False
volume_percent: int = 0
def finish_read(state, output, exit_code=0, normal_exit=True):
next_state = AudioState()
if normal_exit and exit_code == 0:
next_state.available = True
next_state.muted = "[MUTED]" in output.upper()
number = next((token for token in output.replace("%", " ").split()
if token.replace(".", "", 1).isdigit()), None)
if number is not None:
next_state.volume_percent = max(0, min(100, round(float(number) * 100)))
else:
next_state.available = False
return next_state
# This is the ordering implemented by onGetVolumeFinished and setVolume.
state = AudioState(available=True, volume_percent=30)
read_result = finish_read(state, "0.30")
state.volume_percent = 80 # setVolume(80), optimistic update
state = read_result # stale finished read publishes 30
assert state.volume_percent == 30
print("stale read overwrites optimistic setVolume update: reproduced")
# Separate detached setter launches have no acknowledgement or ordering barrier.
commands = [
("set-volume", "80%"),
("set-volume", "90%"),
]
completion_order = [commands[1], commands[0]]
assert completion_order[-1] == commands[0]
print("detached setter completion order is not constrained by call order: race remains")
PYRepository: Jvr2022/seb-linux Length of output: 1606 Serialize audio reads and writes before publishing state. An in-flight 🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
| if (next.available != state_.available || next.muted != state_.muted || next.volumePercent != state_.volumePercent) { | ||
|
|
@@ -47,8 +61,13 @@ void AudioController::setMuted(bool muted) | |
| if (!state_.available) { | ||
| return; | ||
| } | ||
| runCommand(QStringLiteral("wpctl"), {QStringLiteral("set-mute"), QStringLiteral("@DEFAULT_AUDIO_SINK@"), muted ? QStringLiteral("1") : QStringLiteral("0")}); | ||
| refresh(); | ||
|
|
||
| QProcess::startDetached(QStringLiteral("wpctl"), {QStringLiteral("set-mute"), QStringLiteral("@DEFAULT_AUDIO_SINK@"), muted ? QStringLiteral("1") : QStringLiteral("0")}); | ||
|
|
||
| if (state_.muted != muted) { | ||
| state_.muted = muted; | ||
| emit stateChanged(); | ||
| } | ||
| } | ||
|
|
||
| void AudioController::setVolume(int volumePercent) | ||
|
|
@@ -57,8 +76,13 @@ void AudioController::setVolume(int volumePercent) | |
| return; | ||
| } | ||
| const int bounded = qBound(0, volumePercent, 100); | ||
| runCommand(QStringLiteral("wpctl"), {QStringLiteral("set-volume"), QStringLiteral("@DEFAULT_AUDIO_SINK@"), QStringLiteral("%1%").arg(bounded)}); | ||
| refresh(); | ||
|
|
||
| QProcess::startDetached(QStringLiteral("wpctl"), {QStringLiteral("set-volume"), QStringLiteral("@DEFAULT_AUDIO_SINK@"), QStringLiteral("%1%").arg(bounded)}); | ||
|
|
||
| if (state_.volumePercent != bounded) { | ||
| state_.volumePercent = bounded; | ||
| emit stateChanged(); | ||
| } | ||
| } | ||
|
|
||
| } // namespace seb::shell::taskbar::platform | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: Jvr2022/seb-linux
Length of output: 6789
🏁 Script executed:
Repository: Jvr2022/seb-linux
Length of output: 4580
Match the reported target to the final qmake configuration.
Process exact
CONFIG+=dev_bypassandCONFIG-=dev_bypassarguments in order. Selectsafe-exam-browser_devonly whendev_bypassremains enabled.🤖 Prompt for AI Agents