merge dev

* cargo fmt

* deps: bump clap to 4.6.0

* deps: cargo update

* Fix daemon autostart issue caused by sync pipewire retry loop (#43) (#44)

At boot time, PipeWire takes some time to register the `pwsp-daemon` and `pwsp-virtual-mic` devices. Previously, the daemon's retry loop for `link_player_to_virtual_mic()` was synchronous and limited to 5 attempts (1.5 seconds total). This caused systemd autostarts to fail with a code 1 if the devices were not yet available.

This change replaces the synchronous wait with an asynchronous `tokio::spawn` task. It will retry the link attempt up to 60 times with a 1-second delay without blocking the startup of the rest of the daemon. This prevents it from exiting abruptly during autostart.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>

* deps: bump egui & eframe version to 0.34.1

* feat: replaced App::update with new App::logic and App::ui

* deps: bump egui_material_icons to 0.6.0

* deps: bump egui_dnd to 0.15.0

* fix: use .codepoint for icons

* refactor

* refactor: replaced deprecated CentralPanel::show with CentralPanel::show_inside

* refactor

* change version to 1.6.3

* update rust toolchain in github actions

* update freedesktop platform version to 25.08 for flaptak

* update github actions for flatpak builds

* add flatpak-builder installation inside actions

* add flathub configuration to actions

* add --user flag to flathub configuration

* remove sudo from flatpak actions

* Fix/dev flatpak actions 6082245116761610541 (#47)

* remove sudo

* remove steps

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
This commit is contained in:
Tarasov Aleksandr
2026-03-27 15:46:06 +03:00
committed by GitHub
parent f01a0e656c
commit b2b83f5c32
12 changed files with 570 additions and 205 deletions
+2 -2
View File
@@ -33,7 +33,7 @@ jobs:
- name: Setup Rust toolchain - name: Setup Rust toolchain
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:
toolchain: stable toolchain: 1.94.1
- name: Extract all binary names - name: Extract all binary names
id: cargo-meta id: cargo-meta
@@ -103,7 +103,7 @@ jobs:
flatpak-build: flatpak-build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: container:
image: bilelmoussaoui/flatpak-github-actions:freedesktop-24.08 image: ghcr.io/flathub-infra/flatpak-github-actions:freedesktop-25.08
options: --privileged options: --privileged
steps: steps:
+2 -2
View File
@@ -85,7 +85,7 @@ jobs:
- name: Setup Rust toolchain - name: Setup Rust toolchain
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:
toolchain: stable toolchain: 1.94.1
- name: Extract all binary names - name: Extract all binary names
id: cargo-meta id: cargo-meta
@@ -158,7 +158,7 @@ jobs:
needs: prepare needs: prepare
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: container:
image: bilelmoussaoui/flatpak-github-actions:freedesktop-24.08 image: ghcr.io/flathub-infra/flatpak-github-actions:freedesktop-25.08
options: --privileged options: --privileged
steps: steps:
Generated
+526 -169
View File
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "pwsp" name = "pwsp"
version = "1.6.2" version = "1.6.3"
edition = "2024" edition = "2024"
authors = ["arabian"] authors = ["arabian"]
description = "PWSP lets you play audio files through your microphone. Has both CLI and GUI clients." description = "PWSP lets you play audio files through your microphone. Has both CLI and GUI clients."
@@ -18,7 +18,7 @@ async-trait = "0.1.89"
serde = { version = "1.0.228", features = ["derive"] } serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0.149" serde_json = "1.0.149"
clap = { version = "4.5.60", default-features = false, features = [ clap = { version = "4.6.0", default-features = false, features = [
"std", "std",
"suggestions", "suggestions",
"help", "help",
@@ -39,18 +39,18 @@ rfd = { version = "0.17.2", default-features = false, features = [
] } ] }
opener = { version = "0.8.4", features = ["reveal"] } opener = { version = "0.8.4", features = ["reveal"] }
egui = { version = "0.33.3", default-features = false, features = [ egui = { version = "0.34.1", default-features = false, features = [
"default_fonts", "default_fonts",
"rayon", "rayon",
] } ] }
eframe = { version = "0.33.3", default-features = false, features = [ eframe = { version = "0.34.1", default-features = false, features = [
"default_fonts", "default_fonts",
"glow", "glow",
"x11", "x11",
"wayland", "wayland",
] } ] }
egui_material_icons = "0.5.0" egui_material_icons = "0.6.0"
egui_dnd = "0.14.0" egui_dnd = "0.15.0"
[[bin]] [[bin]]
name = "pwsp-daemon" name = "pwsp-daemon"
+3 -3
View File
@@ -1,6 +1,6 @@
pkgbase = pwsp-bin pkgbase = pwsp-bin
pkgdesc = Lets you play audio files through your microphone (Pre-built binaries) pkgdesc = Lets you play audio files through your microphone (Pre-built binaries)
pkgver = 1.6.2 pkgver = 1.6.3
pkgrel = 2 pkgrel = 2
url = https://github.com/arabianq/pipewire-soundpad url = https://github.com/arabianq/pipewire-soundpad
arch = x86_64 arch = x86_64
@@ -9,8 +9,8 @@ depends = pipewire
depends = alsa-lib depends = alsa-lib
provides = pwsp provides = pwsp
conflicts = pwsp conflicts = pwsp
source = pwsp-bin-1.6.2.zip :: https://github.com/arabianq/pipewire-soundpad/releases/download/v1.6.2/pwsp-v1.6.2-linux-x64.zip source = pwsp-bin-1.6.3.zip :: https://github.com/arabianq/pipewire-soundpad/releases/download/v1.6.3/pwsp-v1.6.3-linux-x64.zip
source = pipewire-soundpad-1.6.2.tar.gz :: https://github.com/arabianq/pipewire-soundpad/archive/refs/tags/v1.6.2.tar.gz source = pipewire-soundpad-1.6.3.tar.gz :: https://github.com/arabianq/pipewire-soundpad/archive/refs/tags/v1.6.3.tar.gz
sha256sums = SKIP sha256sums = SKIP
sha256sums = SKIP sha256sums = SKIP
+1 -1
View File
@@ -1,7 +1,7 @@
# Maintainer: Alexander Tarasov <a.tevg@ya.ru> # Maintainer: Alexander Tarasov <a.tevg@ya.ru>
pkgname=pwsp-bin pkgname=pwsp-bin
_pkgname=pipewire-soundpad _pkgname=pipewire-soundpad
pkgver=1.6.2 pkgver=1.6.3
pkgrel=2 pkgrel=2
pkgdesc="Lets you play audio files through your microphone (Pre-built binaries)" pkgdesc="Lets you play audio files through your microphone (Pre-built binaries)"
arch=('x86_64') arch=('x86_64')
+2 -2
View File
@@ -1,6 +1,6 @@
pkgbase = pwsp pkgbase = pwsp
pkgdesc = Lets you play audio files through your microphone pkgdesc = Lets you play audio files through your microphone
pkgver = 1.6.2 pkgver = 1.6.3
pkgrel = 1 pkgrel = 1
url = https://github.com/arabianq/pipewire-soundpad url = https://github.com/arabianq/pipewire-soundpad
arch = any arch = any
@@ -10,7 +10,7 @@ pkgbase = pwsp
makedepends = cargo makedepends = cargo
makedepends = pipewire makedepends = pipewire
makedepends = alsa-lib makedepends = alsa-lib
source = https://github.com/arabianq/pipewire-soundpad/archive/refs/tags/v1.6.2.tar.gz source = https://github.com/arabianq/pipewire-soundpad/archive/refs/tags/v1.6.3.tar.gz
sha256sums = SKIP sha256sums = SKIP
pkgname = pwsp pkgname = pwsp
+1 -1
View File
@@ -1,7 +1,7 @@
# Maintainer: Alexander Tarasov <a.tevg@ya.ru> # Maintainer: Alexander Tarasov <a.tevg@ya.ru>
pkgsubn=pwsp pkgsubn=pwsp
pkgname=pwsp pkgname=pwsp
pkgver=1.6.2 pkgver=1.6.3
pkgrel=1 pkgrel=1
pkgdesc="Lets you play audio files through your microphone" pkgdesc="Lets you play audio files through your microphone"
arch=('any') arch=('any')
+1 -1
View File
@@ -1,6 +1,6 @@
app-id: ru.arabianq.pwsp app-id: ru.arabianq.pwsp
runtime: org.freedesktop.Platform runtime: org.freedesktop.Platform
runtime-version: "24.08" runtime-version: "25.08"
sdk: org.freedesktop.Sdk sdk: org.freedesktop.Sdk
sdk-extensions: sdk-extensions:
- org.freedesktop.Sdk.Extension.rust-stable - org.freedesktop.Sdk.Extension.rust-stable
+1 -1
View File
@@ -4,7 +4,7 @@
%global cargo_install_lib 0 %global cargo_install_lib 0
Name: pwsp Name: pwsp
Version: 1.6.2 Version: 1.6.3
Release: %autorelease Release: %autorelease
Summary: Lets you play audio files through your microphone Summary: Lets you play audio files through your microphone
+18 -12
View File
@@ -19,13 +19,13 @@ enum TrackAction {
impl SoundpadGui { impl SoundpadGui {
fn get_volume_icon(volume: f32) -> &'static str { fn get_volume_icon(volume: f32) -> &'static str {
if volume > 0.7 { if volume > 0.7 {
ICON_VOLUME_UP ICON_VOLUME_UP.codepoint
} else if volume <= 0.0 { } else if volume <= 0.0 {
ICON_VOLUME_OFF ICON_VOLUME_OFF.codepoint
} else if volume < 0.3 { } else if volume < 0.3 {
ICON_VOLUME_MUTE ICON_VOLUME_MUTE.codepoint
} else { } else {
ICON_VOLUME_DOWN ICON_VOLUME_DOWN.codepoint
} }
} }
@@ -313,7 +313,7 @@ impl SoundpadGui {
let path = item.clone(); let path = item.clone();
ui.horizontal(|ui| { ui.horizontal(|ui| {
handle.ui(ui, |ui| { handle.ui(ui, |ui| {
ui.label(ICON_DRAG_INDICATOR); ui.label(ICON_DRAG_INDICATOR.codepoint);
}); });
let name = path let name = path
.file_name() .file_name()
@@ -345,7 +345,7 @@ impl SoundpadGui {
// Context menu // Context menu
dir_button_response.context_menu(|ui| { dir_button_response.context_menu(|ui| {
if ui if ui
.button(format!("{} {}", ICON_OPEN_IN_NEW, "Show")) .button(format!("{} {}", ICON_OPEN_IN_NEW.codepoint, "Show"))
.clicked() .clicked()
{ {
self.open_dir(&path); self.open_dir(&path);
@@ -354,7 +354,7 @@ impl SoundpadGui {
if ui if ui
.button(format!( .button(format!(
"{} {}", "{} {}",
ICON_OPEN_IN_BROWSER, "Open in File Manager" ICON_OPEN_IN_BROWSER.codepoint, "Open in File Manager"
)) ))
.clicked() .clicked()
{ {
@@ -365,7 +365,10 @@ impl SoundpadGui {
ui.separator(); ui.separator();
if ui.button(format!("{} {}", ICON_DELETE, "Remove")).clicked() { if ui
.button(format!("{} {}", ICON_DELETE.codepoint, "Remove"))
.clicked()
{
self.app_state.dirs_to_remove.insert(path.clone()); self.app_state.dirs_to_remove.insert(path.clone());
} }
}); });
@@ -452,20 +455,23 @@ impl SoundpadGui {
// Context menu // Context menu
file_button_response.context_menu(|ui| { file_button_response.context_menu(|ui| {
if ui if ui
.button(format!("{} {}", ICON_BOLT, "Play Solo")) .button(format!("{} {}", ICON_BOLT.codepoint, "Play Solo"))
.clicked() .clicked()
{ {
self.play_file(&entry_path, false); self.play_file(&entry_path, false);
self.app_state.selected_file = Some(entry_path.clone()); self.app_state.selected_file = Some(entry_path.clone());
} }
if ui.button(format!("{} {}", ICON_ADD, "Add New")).clicked() { if ui
.button(format!("{} {}", ICON_ADD.codepoint, "Add New"))
.clicked()
{
self.play_file(&entry_path, true); self.play_file(&entry_path, true);
self.app_state.selected_file = Some(entry_path.clone()); self.app_state.selected_file = Some(entry_path.clone());
} }
if ui if ui
.button(format!("{} {}", ICON_SWAP_HORIZ, "Replace Last")) .button(format!("{} {}", ICON_SWAP_HORIZ.codepoint, "Replace Last"))
.clicked() .clicked()
&& let Some(last_track) = self.audio_player_state.tracks.last() && let Some(last_track) = self.audio_player_state.tracks.last()
{ {
@@ -479,7 +485,7 @@ impl SoundpadGui {
if ui if ui
.button(format!( .button(format!(
"{} {}", "{} {}",
ICON_OPEN_IN_BROWSER, "Show in File Manager" ICON_OPEN_IN_BROWSER.codepoint, "Show in File Manager"
)) ))
.clicked() .clicked()
{ {
+5 -3
View File
@@ -8,7 +8,7 @@ use pwsp::{
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
impl App for SoundpadGui { impl App for SoundpadGui {
fn update(&mut self, ctx: &Context, _frame: &mut EFrame) { fn logic(&mut self, ctx: &Context, _frame: &mut EFrame) {
// Remove directories // Remove directories
for path in self.app_state.dirs_to_remove.drain() { for path in self.app_state.dirs_to_remove.drain() {
self.app_state.dirs.retain(|x| x != &path); self.app_state.dirs.retain(|x| x != &path);
@@ -97,9 +97,11 @@ impl App for SoundpadGui {
// Handle input // Handle input
self.handle_input(ctx); self.handle_input(ctx);
}
fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut EFrame) {
// Draw UI // Draw UI
CentralPanel::default().show(ctx, |ui| { CentralPanel::default().show_inside(ui, |ui| {
if !self.audio_player_state.is_daemon_running { if !self.audio_player_state.is_daemon_running {
self.draw_waiting_for_daemon(ui); self.draw_waiting_for_daemon(ui);
return; return;
@@ -114,6 +116,6 @@ impl App for SoundpadGui {
}); });
// Request repaint // Request repaint
ctx.request_repaint_after_secs(1.0 / 60.0); ui.request_repaint_after_secs(1.0 / 60.0);
} }
} }