I am attaching patches to update helvum and would like to upload to Experimental.
Jonas, the Salsa repo is a little jumbled. Could you push your pristine-tar branch? And update debian/latest to include your latest upload? Thank you, Jeremy Bícha
From fd91245564f7b71a9f6e88106b425af56c15b0c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jeremy=20B=C3=ADcha?= <jeremy.bi...@canonical.com> Date: Sat, 20 Apr 2024 07:14:35 -0400 Subject: [PATCH 3/3] Update Build-Depends --- debian/control | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/debian/control b/debian/control index 5450b7e..0d0f4c2 100644 --- a/debian/control +++ b/debian/control @@ -7,13 +7,14 @@ Build-Depends: debhelper-compat (= 13), desktop-file-utils, dh-cargo, - librust-glib-0.18+default-dev, - librust-glib-0.18+log-dev, - librust-libadwaita-0.5+default-dev, - librust-libadwaita-0.5+v1-3-dev, + librust-async-channel+default-dev, + librust-glib-0.19+default-dev, + librust-glib-0.19+log-dev, + librust-libadwaita-0.6+default-dev, + librust-libadwaita-0.6+v1-3-dev, librust-log-0.4+default-dev, librust-once-cell-1+default-dev, - librust-pipewire-0.7+default-dev, + librust-pipewire-0.8+default-dev, libstring-shellquote-perl, meson, Standards-Version: 4.6.2 -- 2.43.0
From 189c8a94ab4dba723ae063c1ac43dafdc507f54c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jeremy=20B=C3=ADcha?= <jeremy.bi...@canonical.com> Date: Fri, 19 Apr 2024 20:03:14 -0400 Subject: [PATCH 1/3] Cherry-pick several patches to switch to latest GNOME Rust crates Closes: #1063026 --- .../Update-to-latest-gtk-rs-crates.patch | 401 ++++++++++++++++++ debian/patches/Use-responsive-design.patch | 158 +++++++ ...t-media.category-property-to-manager.patch | 28 ++ debian/patches/series | 6 + ...isplay-node-media-name-in-graph-view.patch | 304 +++++++++++++ ...um-to-track-the-latest-pipewire0.8.0.patch | 300 +++++++++++++ debian/patches/use-AdwToolbarView.patch | 87 ++++ 7 files changed, 1284 insertions(+) create mode 100644 debian/patches/Update-to-latest-gtk-rs-crates.patch create mode 100644 debian/patches/Use-responsive-design.patch create mode 100644 debian/patches/pw-Set-media.category-property-to-manager.patch create mode 100644 debian/patches/series create mode 100644 debian/patches/ui-Display-node-media-name-in-graph-view.patch create mode 100644 debian/patches/update-Helvum-to-track-the-latest-pipewire0.8.0.patch create mode 100644 debian/patches/use-AdwToolbarView.patch diff --git a/debian/patches/Update-to-latest-gtk-rs-crates.patch b/debian/patches/Update-to-latest-gtk-rs-crates.patch new file mode 100644 index 0000000..1be6793 --- /dev/null +++ b/debian/patches/Update-to-latest-gtk-rs-crates.patch @@ -0,0 +1,401 @@ +From: Tom Wagner <tom.a.wag...@protonmail.com> +Date: Sat, 23 Mar 2024 11:51:04 +0100 +Subject: Update to latest gtk-rs crates + +(cherry picked from commit f32559511d5e950bf5fde965de47c9caec6eabba) +--- + Cargo.toml | 7 ++-- + src/application.rs | 7 ++-- + src/graph_manager.rs | 94 ++++++++++++++++++++++++++---------------- + src/main.rs | 2 +- + src/pipewire_connection/mod.rs | 38 ++++++++--------- + src/ui/graph/port.rs | 4 +- + 6 files changed, 89 insertions(+), 63 deletions(-) + +diff --git a/Cargo.toml b/Cargo.toml +index a9a220c..f839bfc 100644 +--- a/Cargo.toml ++++ b/Cargo.toml +@@ -15,11 +15,12 @@ categories = ["gui", "multimedia"] + + [dependencies] + pipewire = "0.8.0" +-adw = { version = "0.5", package = "libadwaita", features = ["v1_4"] } +-glib = { version = "0.18", features = ["log"] } ++adw = { version = "0.6", package = "libadwaita", features = ["v1_4"] } ++glib = { version = "0.19", features = ["log"] } ++async-channel = "2.2" + + log = "0.4.11" + +-once_cell = "1.7.2" ++once_cell = "1.19" + + libc = "0.2" +diff --git a/src/application.rs b/src/application.rs +index 97aa21b..a40ac30 100644 +--- a/src/application.rs ++++ b/src/application.rs +@@ -16,7 +16,7 @@ + + use adw::{ + gio, +- glib::{self, clone, Receiver}, ++ glib::{self, clone}, + gtk, + prelude::*, + subclass::prelude::*, +@@ -33,8 +33,9 @@ static AUTHORS: &str = env!("CARGO_PKG_AUTHORS"); + mod imp { + use super::*; + ++ use std::cell::OnceCell; ++ + use adw::subclass::prelude::AdwApplicationImpl; +- use once_cell::unsync::OnceCell; + + #[derive(Default)] + pub struct Application { +@@ -140,7 +141,7 @@ impl Application { + /// Create the view. + /// This will set up the entire user interface and prepare it for being run. + pub(super) fn new( +- gtk_receiver: Receiver<PipewireMessage>, ++ gtk_receiver: async_channel::Receiver<PipewireMessage>, + pw_sender: Sender<GtkMessage>, + ) -> Self { + let app: Application = glib::Object::builder() +diff --git a/src/graph_manager.rs b/src/graph_manager.rs +index 4b00cba..b80f0d3 100644 +--- a/src/graph_manager.rs ++++ b/src/graph_manager.rs +@@ -23,9 +23,7 @@ use crate::{ui::graph::GraphView, GtkMessage, PipewireMessage}; + mod imp { + use super::*; + +- use std::{cell::RefCell, collections::HashMap}; +- +- use once_cell::unsync::OnceCell; ++ use std::{cell::OnceCell, cell::RefCell, collections::HashMap}; + + use crate::{ui::graph, MediaType, NodeType}; + +@@ -53,36 +51,58 @@ mod imp { + impl ObjectImpl for GraphManager {} + + impl GraphManager { +- pub fn attach_receiver(&self, receiver: glib::Receiver<crate::PipewireMessage>) { +- receiver.attach(None, glib::clone!( +- @weak self as imp => @default-return glib::ControlFlow::Continue, +- move |msg| { +- match msg { +- PipewireMessage::NodeAdded { id, name, node_type } => imp.add_node(id, name.as_str(), node_type), +- PipewireMessage::NodeNameChanged { id, name, media_name } => imp.node_name_changed(id, &name, &media_name), +- PipewireMessage::PortAdded { id, node_id, name, direction } => imp.add_port(id, name.as_str(), node_id, direction), +- PipewireMessage::PortFormatChanged { id, media_type } => imp.port_media_type_changed(id, media_type), +- PipewireMessage::LinkAdded { +- id, port_from, port_to, active, media_type +- } => imp.add_link(id, port_from, port_to, active, media_type), +- PipewireMessage::LinkStateChanged { id, active } => imp.link_state_changed(id, active), +- PipewireMessage::LinkFormatChanged { id, media_type } => imp.link_format_changed(id, media_type), +- PipewireMessage::NodeRemoved { id } => imp.remove_node(id), +- PipewireMessage::PortRemoved { id, node_id } => imp.remove_port(id, node_id), +- PipewireMessage::LinkRemoved { id } => imp.remove_link(id), +- PipewireMessage::Connecting => { +- imp.obj().connection_banner().set_revealed(true); +- } +- PipewireMessage::Connected => { +- imp.obj().connection_banner().set_revealed(false); +- }, +- PipewireMessage::Disconnected => { +- imp.clear(); +- }, +- }; +- glib::ControlFlow::Continue +- } +- )); ++ pub async fn receive(&self, receiver: async_channel::Receiver<crate::PipewireMessage>) { ++ loop { ++ let Ok(msg) = receiver.recv().await else { ++ continue; ++ }; ++ match msg { ++ PipewireMessage::NodeAdded { ++ id, ++ name, ++ node_type, ++ } => self.add_node(id, name.as_str(), node_type), ++ PipewireMessage::NodeNameChanged { ++ id, ++ name, ++ media_name, ++ } => self.node_name_changed(id, &name, &media_name), ++ PipewireMessage::PortAdded { ++ id, ++ node_id, ++ name, ++ direction, ++ } => self.add_port(id, name.as_str(), node_id, direction), ++ PipewireMessage::PortFormatChanged { id, media_type } => { ++ self.port_media_type_changed(id, media_type) ++ } ++ PipewireMessage::LinkAdded { ++ id, ++ port_from, ++ port_to, ++ active, ++ media_type, ++ } => self.add_link(id, port_from, port_to, active, media_type), ++ PipewireMessage::LinkStateChanged { id, active } => { ++ self.link_state_changed(id, active) ++ } ++ PipewireMessage::LinkFormatChanged { id, media_type } => { ++ self.link_format_changed(id, media_type) ++ } ++ PipewireMessage::NodeRemoved { id } => self.remove_node(id), ++ PipewireMessage::PortRemoved { id, node_id } => self.remove_port(id, node_id), ++ PipewireMessage::LinkRemoved { id } => self.remove_link(id), ++ PipewireMessage::Connecting => { ++ self.obj().connection_banner().set_revealed(true); ++ } ++ PipewireMessage::Connected => { ++ self.obj().connection_banner().set_revealed(false); ++ } ++ PipewireMessage::Disconnected => { ++ self.clear(); ++ } ++ }; ++ } + } + + /// Add a new node to the view. +@@ -332,19 +352,23 @@ glib::wrapper! { + pub struct GraphManager(ObjectSubclass<imp::GraphManager>); + } + ++async fn receive(graph_manager: GraphManager, receiver: async_channel::Receiver<PipewireMessage>) { ++ graph_manager.imp().receive(receiver).await ++} ++ + impl GraphManager { + pub fn new( + graph: &GraphView, + connection_banner: &adw::Banner, + sender: PwSender<GtkMessage>, +- receiver: glib::Receiver<PipewireMessage>, ++ receiver: async_channel::Receiver<PipewireMessage>, + ) -> Self { + let res: Self = glib::Object::builder() + .property("graph", graph) + .property("connection-banner", connection_banner) + .build(); + +- res.imp().attach_receiver(receiver); ++ glib::MainContext::default().spawn_local(receive(res.clone(), receiver)); + assert!( + res.imp().pw_sender.set(sender).is_ok(), + "Should be able to set pw_sender)" +diff --git a/src/main.rs b/src/main.rs +index 467c544..1f3b1b7 100644 +--- a/src/main.rs ++++ b/src/main.rs +@@ -120,7 +120,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { + + // Start the pipewire thread with channels in both directions. + +- let (gtk_sender, gtk_receiver) = glib::MainContext::channel(glib::Priority::DEFAULT); ++ let (gtk_sender, gtk_receiver) = async_channel::unbounded(); + let (pw_sender, pw_receiver) = pipewire::channel::channel(); + let pw_thread = + std::thread::spawn(move || pipewire_connection::thread_main(gtk_sender, pw_receiver)); +diff --git a/src/pipewire_connection/mod.rs b/src/pipewire_connection/mod.rs +index c554d67..ba2d77f 100644 +--- a/src/pipewire_connection/mod.rs ++++ b/src/pipewire_connection/mod.rs +@@ -63,7 +63,7 @@ enum ProxyItem { + + /// The "main" function of the pipewire thread. + pub(super) fn thread_main( +- gtk_sender: glib::Sender<PipewireMessage>, ++ gtk_sender: async_channel::Sender<PipewireMessage>, + mut pw_receiver: pipewire::channel::Receiver<GtkMessage>, + ) { + let mainloop = MainLoop::new(None).expect("Failed to create mainloop"); +@@ -81,7 +81,7 @@ pub(super) fn thread_main( + if !is_connecting { + is_connecting = true; + gtk_sender +- .send(PipewireMessage::Connecting) ++ .send_blocking(PipewireMessage::Connecting) + .expect("Failed to send message"); + } + +@@ -116,7 +116,7 @@ pub(super) fn thread_main( + if is_connecting { + is_connecting = false; + gtk_sender +- .send(PipewireMessage::Connected) ++ .send_blocking(PipewireMessage::Connected) + .expect("Failed to send message"); + } + +@@ -145,7 +145,7 @@ pub(super) fn thread_main( + } + + if res == -libc::EPIPE { +- gtk_sender.send(PipewireMessage::Disconnected) ++ gtk_sender.send_blocking(PipewireMessage::Disconnected) + .expect("Failed to send message"); + mainloop.quit(); + } else { +@@ -169,7 +169,7 @@ pub(super) fn thread_main( + )) + .global_remove(clone!(@strong proxies, @strong state => move |id| { + if let Some(item) = state.borrow_mut().remove(id) { +- gtk_sender.send(match item { ++ gtk_sender.send_blocking(match item { + Item::Node { .. } => PipewireMessage::NodeRemoved {id}, + Item::Port { node_id } => PipewireMessage::PortRemoved {id, node_id}, + Item::Link { .. } => PipewireMessage::LinkRemoved {id}, +@@ -202,7 +202,7 @@ fn get_node_name(props: &DictRef) -> &str { + /// Handle a new node being added + fn handle_node( + node: &GlobalObject<&DictRef>, +- sender: &glib::Sender<PipewireMessage>, ++ sender: &async_channel::Sender<PipewireMessage>, + registry: &Rc<Registry>, + proxies: &Rc<RefCell<HashMap<u32, ProxyItem>>>, + state: &Rc<RefCell<State>>, +@@ -237,7 +237,7 @@ fn handle_node( + state.borrow_mut().insert(node.id, Item::Node); + + sender +- .send(PipewireMessage::NodeAdded { ++ .send_blocking(PipewireMessage::NodeAdded { + id: node.id, + name, + node_type, +@@ -263,7 +263,7 @@ fn handle_node( + + fn handle_node_info( + info: &NodeInfoRef, +- sender: &glib::Sender<PipewireMessage>, ++ sender: &async_channel::Sender<PipewireMessage>, + proxies: &Rc<RefCell<HashMap<u32, ProxyItem>>>, + ) { + debug!("Received node info: {:?}", info); +@@ -280,7 +280,7 @@ fn handle_node_info( + let name = get_node_name(props).to_string(); + + sender +- .send(PipewireMessage::NodeNameChanged { ++ .send_blocking(PipewireMessage::NodeNameChanged { + id, + name, + media_name: media_name.to_string(), +@@ -292,7 +292,7 @@ fn handle_node_info( + /// Handle a new port being added + fn handle_port( + port: &GlobalObject<&DictRef>, +- sender: &glib::Sender<PipewireMessage>, ++ sender: &async_channel::Sender<PipewireMessage>, + registry: &Rc<Registry>, + proxies: &Rc<RefCell<HashMap<u32, ProxyItem>>>, + state: &Rc<RefCell<State>>, +@@ -326,7 +326,7 @@ fn handle_port_info( + info: &PortInfoRef, + proxies: &Rc<RefCell<HashMap<u32, ProxyItem>>>, + state: &Rc<RefCell<State>>, +- sender: &glib::Sender<PipewireMessage>, ++ sender: &async_channel::Sender<PipewireMessage>, + ) { + debug!("Received port info: {:?}", info); + +@@ -367,7 +367,7 @@ fn handle_port_info( + } + + sender +- .send(PipewireMessage::PortAdded { ++ .send_blocking(PipewireMessage::PortAdded { + id, + node_id, + name, +@@ -380,7 +380,7 @@ fn handle_port_info( + fn handle_port_enum_format( + port_id: u32, + param: Option<&pipewire::spa::pod::Pod>, +- sender: &glib::Sender<PipewireMessage>, ++ sender: &async_channel::Sender<PipewireMessage>, + ) { + let media_type = param + .and_then(|param| pipewire::spa::param::format_utils::parse_format(param).ok()) +@@ -388,7 +388,7 @@ fn handle_port_enum_format( + .unwrap_or(MediaType::Unknown); + + sender +- .send(PipewireMessage::PortFormatChanged { ++ .send_blocking(PipewireMessage::PortFormatChanged { + id: port_id, + media_type, + }) +@@ -398,7 +398,7 @@ fn handle_port_enum_format( + /// Handle a new link being added + fn handle_link( + link: &GlobalObject<&DictRef>, +- sender: &glib::Sender<PipewireMessage>, ++ sender: &async_channel::Sender<PipewireMessage>, + registry: &Rc<Registry>, + proxies: &Rc<RefCell<HashMap<u32, ProxyItem>>>, + state: &Rc<RefCell<State>>, +@@ -428,7 +428,7 @@ fn handle_link( + fn handle_link_info( + info: &LinkInfoRef, + state: &Rc<RefCell<State>>, +- sender: &glib::Sender<PipewireMessage>, ++ sender: &async_channel::Sender<PipewireMessage>, + ) { + debug!("Received link info: {:?}", info); + +@@ -439,7 +439,7 @@ fn handle_link_info( + // Info was an update - figure out if we should notify the gtk thread + if info.change_mask().contains(LinkChangeMask::STATE) { + sender +- .send(PipewireMessage::LinkStateChanged { ++ .send_blocking(PipewireMessage::LinkStateChanged { + id, + active: matches!(info.state(), LinkState::Active), + }) +@@ -447,7 +447,7 @@ fn handle_link_info( + } + if info.change_mask().contains(LinkChangeMask::FORMAT) { + sender +- .send(PipewireMessage::LinkFormatChanged { ++ .send_blocking(PipewireMessage::LinkFormatChanged { + id, + media_type: get_link_media_type(info), + }) +@@ -461,7 +461,7 @@ fn handle_link_info( + state.insert(id, Item::Link { port_from, port_to }); + + sender +- .send(PipewireMessage::LinkAdded { ++ .send_blocking(PipewireMessage::LinkAdded { + id, + port_from, + port_to, +diff --git a/src/ui/graph/port.rs b/src/ui/graph/port.rs +index 4189cd9..5826e3a 100644 +--- a/src/ui/graph/port.rs ++++ b/src/ui/graph/port.rs +@@ -28,9 +28,9 @@ use super::PortHandle; + mod imp { + use super::*; + +- use std::cell::Cell; ++ use std::cell::{Cell, OnceCell}; + +- use once_cell::{sync::Lazy, unsync::OnceCell}; ++ use once_cell::sync::Lazy; + use pipewire::spa::{param::format::MediaType, utils::Direction}; + + /// Graphical representation of a pipewire port. diff --git a/debian/patches/Use-responsive-design.patch b/debian/patches/Use-responsive-design.patch new file mode 100644 index 0000000..5d726aa --- /dev/null +++ b/debian/patches/Use-responsive-design.patch @@ -0,0 +1,158 @@ +From: Angelo Verlain Shema <geoangerc...@gmail.com> +Date: Tue, 10 Oct 2023 18:16:23 +0000 +Subject: Use responsive design + +(cherry picked from commit e1f63ddd28c216b955a624b215e0d367f513db51) +--- + src/style.css | 17 +++++++++++++++++ + src/ui/graph/zoomentry.rs | 1 + + src/ui/graph/zoomentry.ui | 31 +++++++++++++++++++++---------- + src/ui/window.ui | 37 ++++++++++++++++++++----------------- + 4 files changed, 59 insertions(+), 27 deletions(-) + +diff --git a/src/style.css b/src/style.css +index fb8e8a3..f8fa650 100644 +--- a/src/style.css ++++ b/src/style.css +@@ -53,3 +53,20 @@ port-handle { + border-radius: 50%; + background-color: @media-type-unknown; + } ++ ++button.rounded { ++ padding: 6px; ++ border-radius: 9999px; ++} ++ ++entry.rounded { ++ border-radius: 9999px; ++} ++ ++entry.rounded > :first-child { ++ padding-left: 12px; ++} ++ ++entry.rounded > :nth-child(2) { ++ padding-right: 12px; ++} +diff --git a/src/ui/graph/zoomentry.rs b/src/ui/graph/zoomentry.rs +index 6c6a951..667236b 100644 +--- a/src/ui/graph/zoomentry.rs ++++ b/src/ui/graph/zoomentry.rs +@@ -34,6 +34,7 @@ mod imp { + menu.append(Some("200%"), Some("win.set-zoom(2.0)")); + menu.append(Some("300%"), Some("win.set-zoom(3.0)")); + let popover = gtk::PopoverMenu::from_model(Some(&menu)); ++ popover.set_position(gtk::PositionType::Top); + + ZoomEntry { + graphview: Default::default(), +diff --git a/src/ui/graph/zoomentry.ui b/src/ui/graph/zoomentry.ui +index 975e971..def1a6a 100644 +--- a/src/ui/graph/zoomentry.ui ++++ b/src/ui/graph/zoomentry.ui +@@ -1,26 +1,37 @@ + <?xml version="1.0" encoding="UTF-8"?> + <interface> + <template class="HelvumZoomEntry" parent="GtkBox"> +- <child> +- <object class="GtkButton" id="zoom_out_button"> +- <property name="icon-name">zoom-out-symbolic</property> +- <property name="tooltip-text">Zoom out</property> +- </object> +- </child> ++ <property name="spacing">12</property> + <child> + <object class="GtkEntry" id="entry"> + <property name="secondary-icon-name">go-down-symbolic</property> + <property name="input-purpose">digits</property> ++ <property name="max-width-chars">5</property> ++ <style> ++ <class name="osd"/> ++ <class name="rounded"/> ++ </style> ++ </object> ++ </child> ++ <child> ++ <object class="GtkButton" id="zoom_out_button"> ++ <property name="icon-name">zoom-out-symbolic</property> ++ <property name="tooltip-text">Zoom out</property> ++ <style> ++ <class name="osd"/> ++ <class name="rounded"/> ++ </style> + </object> + </child> + <child> + <object class="GtkButton" id="zoom_in_button"> + <property name="icon-name">zoom-in-symbolic</property> + <property name="tooltip-text">Zoom in</property> ++ <style> ++ <class name="osd"/> ++ <class name="rounded"/> ++ </style> + </object> + </child> +- <style> +- <class name="linked"/> +- </style> + </template> +-</interface> +\ No newline at end of file ++</interface> +diff --git a/src/ui/window.ui b/src/ui/window.ui +index ef2b72b..22d72f1 100644 +--- a/src/ui/window.ui ++++ b/src/ui/window.ui +@@ -20,19 +20,9 @@ + <child> + <object class="AdwHeaderBar" id="header_bar"> + <child type="end"> +- <object class="GtkBox"> +- <property name="spacing">6</property> +- <child> +- <object class="HelvumZoomEntry"> +- <property name="zoomed-widget">graph</property> +- </object> +- </child> +- <child> +- <object class="GtkMenuButton"> +- <property name="icon-name">open-menu-symbolic</property> +- <property name="menu-model">primary_menu</property> +- </object> +- </child> ++ <object class="GtkMenuButton"> ++ <property name="icon-name">open-menu-symbolic</property> ++ <property name="menu-model">primary_menu</property> + </object> + </child> + </object> +@@ -44,11 +34,24 @@ + </object> + </child> + <child> +- <object class="GtkScrolledWindow"> ++ <object class="GtkOverlay"> + <child> +- <object class="HelvumGraphView" id="graph"> +- <property name="hexpand">true</property> +- <property name="vexpand">true</property> ++ <object class="GtkScrolledWindow"> ++ <child> ++ <object class="HelvumGraphView" id="graph"> ++ <property name="hexpand">true</property> ++ <property name="vexpand">true</property> ++ </object> ++ </child> ++ </object> ++ </child> ++ <child type="overlay"> ++ <object class="HelvumZoomEntry"> ++ <property name="zoomed-widget">graph</property> ++ <property name="halign">end</property> ++ <property name="valign">end</property> ++ <property name="margin-end">24</property> ++ <property name="margin-bottom">24</property> + </object> + </child> + </object> diff --git a/debian/patches/pw-Set-media.category-property-to-manager.patch b/debian/patches/pw-Set-media.category-property-to-manager.patch new file mode 100644 index 0000000..45565d7 --- /dev/null +++ b/debian/patches/pw-Set-media.category-property-to-manager.patch @@ -0,0 +1,28 @@ +From: "Tom A. Wagner" <tom.a.wag...@protonmail.com> +Date: Thu, 12 Oct 2023 10:29:42 +0200 +Subject: pw: Set media.category property to manager + +This will make the session manager give Helvum full permissions even when +used from flatpak or otherwise restricted, so that we can always change +the graph even if permissions become more restricted in the future. + +(cherry picked from commit 5d4931b4184634788663498564bdc3a73c564c30) +--- + src/pipewire_connection/mod.rs | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/pipewire_connection/mod.rs b/src/pipewire_connection/mod.rs +index f7ba1a0..a0cf429 100644 +--- a/src/pipewire_connection/mod.rs ++++ b/src/pipewire_connection/mod.rs +@@ -65,7 +65,9 @@ pub(super) fn thread_main( + + while !is_stopped.get() { + // Try to connect +- let core = match context.connect(None) { ++ let core = match context.connect(Some(properties! { ++ "media.category" => "Manager" ++ })) { + Ok(core) => Rc::new(core), + Err(_) => { + if !is_connecting { diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 0000000..a7d1c8d --- /dev/null +++ b/debian/patches/series @@ -0,0 +1,6 @@ +Use-responsive-design.patch +use-AdwToolbarView.patch +pw-Set-media.category-property-to-manager.patch +ui-Display-node-media-name-in-graph-view.patch +update-Helvum-to-track-the-latest-pipewire0.8.0.patch +Update-to-latest-gtk-rs-crates.patch diff --git a/debian/patches/ui-Display-node-media-name-in-graph-view.patch b/debian/patches/ui-Display-node-media-name-in-graph-view.patch new file mode 100644 index 0000000..2ca6f6b --- /dev/null +++ b/debian/patches/ui-Display-node-media-name-in-graph-view.patch @@ -0,0 +1,304 @@ +From: Denis Drakhnia <numa...@gmail.com> +Date: Wed, 11 Oct 2023 11:17:30 +0300 +Subject: ui: Display node media name in graph view + +(cherry picked from commit 96c079d29e26f85207eb31252013b4b571a7c774) +--- + src/graph_manager.rs | 18 +++++++++++ + src/main.rs | 5 +++ + src/pipewire_connection/mod.rs | 73 ++++++++++++++++++++++++++++++++++++------ + src/style.css | 2 +- + src/ui/graph/node.rs | 25 +++++++++++---- + src/ui/graph/node.ui | 34 ++++++++++++++++---- + 6 files changed, 133 insertions(+), 24 deletions(-) + +diff --git a/src/graph_manager.rs b/src/graph_manager.rs +index e438552..34b2868 100644 +--- a/src/graph_manager.rs ++++ b/src/graph_manager.rs +@@ -59,6 +59,7 @@ mod imp { + move |msg| { + match msg { + PipewireMessage::NodeAdded { id, name, node_type } => imp.add_node(id, name.as_str(), node_type), ++ PipewireMessage::NodeNameChanged { id, name, media_name } => imp.node_name_changed(id, &name, &media_name), + PipewireMessage::PortAdded { id, node_id, name, direction } => imp.add_port(id, name.as_str(), node_id, direction), + PipewireMessage::PortFormatChanged { id, media_type } => imp.port_media_type_changed(id, media_type), + PipewireMessage::LinkAdded { +@@ -95,6 +96,23 @@ mod imp { + self.obj().graph().add_node(node, node_type); + } + ++ /// Update a node tooltip to the view. ++ fn node_name_changed(&self, id: u32, node_name: &str, media_name: &str) { ++ let items = self.items.borrow(); ++ ++ let Some(node) = items.get(&id) else { ++ log::warn!("Node (id: {id}) for changed name not found in graph manager"); ++ return; ++ }; ++ let Some(node) = node.dynamic_cast_ref::<graph::Node>() else { ++ log::warn!("Graph Manager item under node (id: {id}) is not a node"); ++ return; ++ }; ++ ++ node.set_node_name(node_name); ++ node.set_media_name(media_name); ++ } ++ + /// Remove the node with the specified id from the view. + fn remove_node(&self, id: u32) { + log::info!("Removing node from graph: id {}", id); +diff --git a/src/main.rs b/src/main.rs +index b147c96..610c175 100644 +--- a/src/main.rs ++++ b/src/main.rs +@@ -39,6 +39,11 @@ pub enum PipewireMessage { + name: String, + node_type: Option<NodeType>, + }, ++ NodeNameChanged { ++ id: u32, ++ name: String, ++ media_name: String, ++ }, + PortAdded { + id: u32, + node_id: u32, +diff --git a/src/pipewire_connection/mod.rs b/src/pipewire_connection/mod.rs +index a0cf429..768f737 100644 +--- a/src/pipewire_connection/mod.rs ++++ b/src/pipewire_connection/mod.rs +@@ -26,7 +26,9 @@ use std::{ + use adw::glib::{self, clone}; + use log::{debug, error, info, warn}; + use pipewire::{ ++ keys, + link::{Link, LinkChangeMask, LinkInfo, LinkListener, LinkState}, ++ node::{Node, NodeInfo, NodeListener}, + port::{Port, PortChangeMask, PortInfo, PortListener}, + prelude::*, + properties, +@@ -43,6 +45,10 @@ use crate::{GtkMessage, MediaType, NodeType, PipewireMessage}; + use state::{Item, State}; + + enum ProxyItem { ++ Node { ++ _proxy: Node, ++ _listener: NodeListener, ++ }, + Port { + proxy: Port, + _listener: PortListener, +@@ -149,7 +155,7 @@ pub(super) fn thread_main( + .add_listener_local() + .global(clone!(@strong gtk_sender, @weak registry, @strong proxies, @strong state => + move |global| match global.type_ { +- ObjectType::Node => handle_node(global, >k_sender, &state), ++ ObjectType::Node => handle_node(global, >k_sender, ®istry, &proxies, &state), + ObjectType::Port => handle_port(global, >k_sender, ®istry, &proxies, &state), + ObjectType::Link => handle_link(global, >k_sender, ®istry, &proxies, &state), + _ => { +@@ -180,10 +186,21 @@ pub(super) fn thread_main( + } + } + ++/// Get the nicest possible name for the node, using a fallback chain of possible name attributes ++fn get_node_name(props: &ForeignDict) -> &str { ++ props ++ .get(&keys::NODE_DESCRIPTION) ++ .or_else(|| props.get(&keys::NODE_NICK)) ++ .or_else(|| props.get(&keys::NODE_NAME)) ++ .unwrap_or_default() ++} ++ + /// Handle a new node being added + fn handle_node( + node: &GlobalObject<ForeignDict>, + sender: &glib::Sender<PipewireMessage>, ++ registry: &Rc<Registry>, ++ proxies: &Rc<RefCell<HashMap<u32, ProxyItem>>>, + state: &Rc<RefCell<State>>, + ) { + let props = node +@@ -191,15 +208,7 @@ fn handle_node( + .as_ref() + .expect("Node object is missing properties"); + +- // Get the nicest possible name for the node, using a fallback chain of possible name attributes. +- let name = String::from( +- props +- .get("node.description") +- .or_else(|| props.get("node.nick")) +- .or_else(|| props.get("node.name")) +- .unwrap_or_default(), +- ); +- ++ let name = get_node_name(props).to_string(); + let media_class = |class: &str| { + if class.contains("Sink") || class.contains("Input") { + Some(NodeType::Input) +@@ -230,6 +239,50 @@ fn handle_node( + node_type, + }) + .expect("Failed to send message"); ++ ++ let proxy: Node = registry.bind(node).expect("Failed to bind to node proxy"); ++ let listener = proxy ++ .add_listener_local() ++ .info(clone!(@strong sender, @strong proxies => move |info| { ++ handle_node_info(info, &sender, &proxies); ++ })) ++ .register(); ++ ++ proxies.borrow_mut().insert( ++ node.id, ++ ProxyItem::Node { ++ _proxy: proxy, ++ _listener: listener, ++ }, ++ ); ++} ++ ++fn handle_node_info( ++ info: &NodeInfo, ++ sender: &glib::Sender<PipewireMessage>, ++ proxies: &Rc<RefCell<HashMap<u32, ProxyItem>>>, ++) { ++ debug!("Received node info: {:?}", info); ++ ++ let id = info.id(); ++ let proxies = proxies.borrow(); ++ let Some(ProxyItem::Node { .. }) = proxies.get(&id) else { ++ error!("Received info on unknown node with id {id}"); ++ return; ++ }; ++ ++ let props = info.props().expect("NodeInfo object is missing properties"); ++ if let Some(media_name) = props.get(&keys::MEDIA_NAME) { ++ let name = get_node_name(props).to_string(); ++ ++ sender ++ .send(PipewireMessage::NodeNameChanged { ++ id, ++ name, ++ media_name: media_name.to_string(), ++ }) ++ .expect("Failed to send message"); ++ } + } + + /// Handle a new port being added +diff --git a/src/style.css b/src/style.css +index f8fa650..397fedb 100644 +--- a/src/style.css ++++ b/src/style.css +@@ -41,7 +41,7 @@ node { + background-color: @headerbar_bg_color; + } + +-node label.heading { ++node .node-title { + padding: 4px 7px; + } + +diff --git a/src/ui/graph/node.rs b/src/ui/graph/node.rs +index bb41ba8..54d71c6 100644 +--- a/src/ui/graph/node.rs ++++ b/src/ui/graph/node.rs +@@ -34,15 +34,26 @@ mod imp { + #[property(get, set, construct_only)] + pub(super) pipewire_id: Cell<u32>, + #[property( +- name = "name", type = String, +- get = |this: &Self| this.label.text().to_string(), ++ name = "node-name", type = String, ++ get = |this: &Self| this.node_name.text().to_string(), + set = |this: &Self, val| { +- this.label.set_text(val); +- this.label.set_tooltip_text(Some(val)); ++ this.node_name.set_text(val); ++ this.node_name.set_tooltip_text(Some(val)); + } + )] + #[template_child] +- pub(super) label: TemplateChild<gtk::Label>, ++ pub(super) node_name: TemplateChild<gtk::Label>, ++ #[property( ++ name = "media-name", type = String, ++ get = |this: &Self| this.media_name.text().to_string(), ++ set = |this: &Self, val| { ++ this.media_name.set_text(val); ++ this.media_name.set_tooltip_text(Some(val)); ++ this.media_name.set_visible(!val.is_empty()); ++ } ++ )] ++ #[template_child] ++ pub(super) media_name: TemplateChild<gtk::Label>, + #[template_child] + pub(super) separator: TemplateChild<gtk::Separator>, + #[template_child] +@@ -75,7 +86,7 @@ mod imp { + self.parent_constructed(); + + // Display a grab cursor when the mouse is over the label so the user knows the node can be dragged. +- self.label ++ self.node_name + .set_cursor(gtk::gdk::Cursor::from_name("grab", None).as_ref()); + } + +@@ -141,7 +152,7 @@ glib::wrapper! { + impl Node { + pub fn new(name: &str, pipewire_id: u32) -> Self { + glib::Object::builder() +- .property("name", name) ++ .property("node-name", name) + .property("pipewire-id", pipewire_id) + .build() + } +diff --git a/src/ui/graph/node.ui b/src/ui/graph/node.ui +index 8c53ada..9a80c56 100644 +--- a/src/ui/graph/node.ui ++++ b/src/ui/graph/node.ui +@@ -9,14 +9,36 @@ + <object class="GtkBox"> + <property name="orientation">vertical</property> + <child> +- <object class="GtkLabel" id="label"> ++ <object class="GtkBox"> + <style> +- <class name="heading"></class> ++ <class name="node-title"></class> + </style> +- <property name="wrap">true</property> +- <property name="ellipsize">PANGO_ELLIPSIZE_END</property> +- <property name="lines">2</property> +- <property name="max-width-chars">20</property> ++ <property name="orientation">vertical</property> ++ <property name="spacing">1</property> ++ <child> ++ <object class="GtkLabel" id="node_name"> ++ <style> ++ <class name="heading"></class> ++ </style> ++ <property name="wrap">true</property> ++ <property name="ellipsize">PANGO_ELLIPSIZE_END</property> ++ <property name="lines">2</property> ++ <property name="max-width-chars">20</property> ++ </object> ++ </child> ++ <child> ++ <object class="GtkLabel" id="media_name"> ++ <style> ++ <class name="dim-label"></class> ++ <class name="caption"></class> ++ </style> ++ <property name="visible">false</property> ++ <property name="wrap">true</property> ++ <property name="ellipsize">PANGO_ELLIPSIZE_END</property> ++ <property name="lines">2</property> ++ <property name="max-width-chars">20</property> ++ </object> ++ </child> + </object> + </child> + <child> diff --git a/debian/patches/update-Helvum-to-track-the-latest-pipewire0.8.0.patch b/debian/patches/update-Helvum-to-track-the-latest-pipewire0.8.0.patch new file mode 100644 index 0000000..365d12e --- /dev/null +++ b/debian/patches/update-Helvum-to-track-the-latest-pipewire0.8.0.patch @@ -0,0 +1,300 @@ +From: Dorinda Bassey <dbas...@redhat.com> +Date: Tue, 19 Mar 2024 14:06:57 +0100 +Subject: update Helvum to track the latest pipewire0.8.0 + +update Helvum to track the latest pipewire0.8.0 + +(cherry picked from commit d1b9b0f11f3f9d86f74b643c3aca024489165d7c) +--- + Cargo.toml | 2 +- + src/graph_manager.rs | 14 ++++++++++-- + src/main.rs | 2 +- + src/pipewire_connection/mod.rs | 50 +++++++++++++++++++++++------------------- + src/ui/graph/graph_view.rs | 4 ++-- + src/ui/graph/link.rs | 2 +- + src/ui/graph/node.rs | 2 +- + src/ui/graph/port.rs | 4 ++-- + 8 files changed, 47 insertions(+), 33 deletions(-) + +diff --git a/Cargo.toml b/Cargo.toml +index e72f4fd..a9a220c 100644 +--- a/Cargo.toml ++++ b/Cargo.toml +@@ -14,7 +14,7 @@ categories = ["gui", "multimedia"] + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + + [dependencies] +-pipewire = "0.7.1" ++pipewire = "0.8.0" + adw = { version = "0.5", package = "libadwaita", features = ["v1_4"] } + glib = { version = "0.18", features = ["log"] } + +diff --git a/src/graph_manager.rs b/src/graph_manager.rs +index 34b2868..4b00cba 100644 +--- a/src/graph_manager.rs ++++ b/src/graph_manager.rs +@@ -130,7 +130,13 @@ mod imp { + } + + /// Add a new port to the view. +- fn add_port(&self, id: u32, name: &str, node_id: u32, direction: pipewire::spa::Direction) { ++ fn add_port( ++ &self, ++ id: u32, ++ name: &str, ++ node_id: u32, ++ direction: pipewire::spa::utils::Direction, ++ ) { + log::info!("Adding port to graph: id {}", id); + + let mut items = self.items.borrow_mut(); +@@ -273,7 +279,11 @@ mod imp { + link.set_active(active); + } + +- fn link_format_changed(&self, id: u32, media_type: pipewire::spa::format::MediaType) { ++ fn link_format_changed( ++ &self, ++ id: u32, ++ media_type: pipewire::spa::param::format::MediaType, ++ ) { + let items = self.items.borrow(); + + let Some(link) = items.get(&id) else { +diff --git a/src/main.rs b/src/main.rs +index 610c175..467c544 100644 +--- a/src/main.rs ++++ b/src/main.rs +@@ -20,7 +20,7 @@ mod pipewire_connection; + mod ui; + + use adw::{gtk, prelude::*}; +-use pipewire::spa::{format::MediaType, Direction}; ++use pipewire::spa::{param::format::MediaType, utils::Direction}; + + /// Messages sent by the GTK thread to notify the pipewire thread. + #[derive(Debug, Clone)] +diff --git a/src/pipewire_connection/mod.rs b/src/pipewire_connection/mod.rs +index 768f737..c554d67 100644 +--- a/src/pipewire_connection/mod.rs ++++ b/src/pipewire_connection/mod.rs +@@ -26,19 +26,21 @@ use std::{ + use adw::glib::{self, clone}; + use log::{debug, error, info, warn}; + use pipewire::{ ++ context::Context, ++ core::{Core, PW_ID_CORE}, + keys, +- link::{Link, LinkChangeMask, LinkInfo, LinkListener, LinkState}, +- node::{Node, NodeInfo, NodeListener}, +- port::{Port, PortChangeMask, PortInfo, PortListener}, +- prelude::*, +- properties, ++ link::{Link, LinkChangeMask, LinkInfoRef, LinkListener, LinkState}, ++ main_loop::MainLoop, ++ node::{Node, NodeInfoRef, NodeListener}, ++ port::{Port, PortChangeMask, PortInfoRef, PortListener}, ++ properties::properties, + registry::{GlobalObject, Registry}, + spa::{ + param::{ParamInfoFlags, ParamType}, +- ForeignDict, SpaResult, ++ utils::dict::DictRef, ++ utils::result::SpaResult, + }, + types::ObjectType, +- Context, Core, MainLoop, + }; + + use crate::{GtkMessage, MediaType, NodeType, PipewireMessage}; +@@ -64,7 +66,7 @@ pub(super) fn thread_main( + gtk_sender: glib::Sender<PipewireMessage>, + mut pw_receiver: pipewire::channel::Receiver<GtkMessage>, + ) { +- let mainloop = MainLoop::new().expect("Failed to create mainloop"); ++ let mainloop = MainLoop::new(None).expect("Failed to create mainloop"); + let context = Rc::new(Context::new(&mainloop).expect("Failed to create context")); + let is_stopped = Rc::new(Cell::new(false)); + let mut is_connecting = false; +@@ -86,13 +88,15 @@ pub(super) fn thread_main( + // If connection is failed, try to connect again in 200ms + let interval = Some(Duration::from_millis(200)); + +- let timer = mainloop.add_timer(clone!(@strong mainloop => move |_| { +- mainloop.quit(); +- })); ++ let timer = mainloop ++ .loop_() ++ .add_timer(clone!(@strong mainloop => move |_| { ++ mainloop.quit(); ++ })); + + timer.update_timer(interval, None).into_result().unwrap(); + +- let receiver = pw_receiver.attach(&mainloop, { ++ let receiver = pw_receiver.attach(mainloop.loop_(), { + clone!(@strong mainloop, @strong is_stopped => move |msg| + if let GtkMessage::Terminate = msg { + // main thread requested stop +@@ -122,7 +126,7 @@ pub(super) fn thread_main( + let proxies = Rc::new(RefCell::new(HashMap::new())); + let state = Rc::new(RefCell::new(State::new())); + +- let receiver = pw_receiver.attach(&mainloop, { ++ let receiver = pw_receiver.attach(mainloop.loop_(), { + clone!(@strong mainloop, @weak core, @weak registry, @strong state, @strong is_stopped => move |msg| match msg { + GtkMessage::ToggleLink { port_from, port_to } => toggle_link(port_from, port_to, &core, ®istry, &state), + GtkMessage::Terminate => { +@@ -136,7 +140,7 @@ pub(super) fn thread_main( + let gtk_sender = gtk_sender.clone(); + let _listener = core.add_listener_local() + .error(clone!(@strong mainloop, @strong gtk_sender, @strong is_stopped => move |id, _seq, res, message| { +- if id != pipewire::PW_ID_CORE { ++ if id != PW_ID_CORE { + return; + } + +@@ -187,7 +191,7 @@ pub(super) fn thread_main( + } + + /// Get the nicest possible name for the node, using a fallback chain of possible name attributes +-fn get_node_name(props: &ForeignDict) -> &str { ++fn get_node_name(props: &DictRef) -> &str { + props + .get(&keys::NODE_DESCRIPTION) + .or_else(|| props.get(&keys::NODE_NICK)) +@@ -197,7 +201,7 @@ fn get_node_name(props: &ForeignDict) -> &str { + + /// Handle a new node being added + fn handle_node( +- node: &GlobalObject<ForeignDict>, ++ node: &GlobalObject<&DictRef>, + sender: &glib::Sender<PipewireMessage>, + registry: &Rc<Registry>, + proxies: &Rc<RefCell<HashMap<u32, ProxyItem>>>, +@@ -258,7 +262,7 @@ fn handle_node( + } + + fn handle_node_info( +- info: &NodeInfo, ++ info: &NodeInfoRef, + sender: &glib::Sender<PipewireMessage>, + proxies: &Rc<RefCell<HashMap<u32, ProxyItem>>>, + ) { +@@ -287,7 +291,7 @@ fn handle_node_info( + + /// Handle a new port being added + fn handle_port( +- port: &GlobalObject<ForeignDict>, ++ port: &GlobalObject<&DictRef>, + sender: &glib::Sender<PipewireMessage>, + registry: &Rc<Registry>, + proxies: &Rc<RefCell<HashMap<u32, ProxyItem>>>, +@@ -319,7 +323,7 @@ fn handle_port( + } + + fn handle_port_info( +- info: &PortInfo, ++ info: &PortInfoRef, + proxies: &Rc<RefCell<HashMap<u32, ProxyItem>>>, + state: &Rc<RefCell<State>>, + sender: &glib::Sender<PipewireMessage>, +@@ -393,7 +397,7 @@ fn handle_port_enum_format( + + /// Handle a new link being added + fn handle_link( +- link: &GlobalObject<ForeignDict>, ++ link: &GlobalObject<&DictRef>, + sender: &glib::Sender<PipewireMessage>, + registry: &Rc<Registry>, + proxies: &Rc<RefCell<HashMap<u32, ProxyItem>>>, +@@ -422,7 +426,7 @@ fn handle_link( + } + + fn handle_link_info( +- info: &LinkInfo, ++ info: &LinkInfoRef, + state: &Rc<RefCell<State>>, + sender: &glib::Sender<PipewireMessage>, + ) { +@@ -495,7 +499,7 @@ fn toggle_link( + .get_node_of_port(port_to) + .expect("Requested port not in state"); + +- if let Err(e) = core.create_object::<Link, _>( ++ if let Err(e) = core.create_object::<Link>( + "link-factory", + &properties! { + "link.output.node" => node_from.to_string(), +@@ -510,7 +514,7 @@ fn toggle_link( + } + } + +-fn get_link_media_type(link_info: &LinkInfo) -> MediaType { ++fn get_link_media_type(link_info: &LinkInfoRef) -> MediaType { + let media_type = link_info + .format() + .and_then(|format| pipewire::spa::param::format_utils::parse_format(format).ok()) +diff --git a/src/ui/graph/graph_view.rs b/src/ui/graph/graph_view.rs +index 549a4c5..d1ec5da 100644 +--- a/src/ui/graph/graph_view.rs ++++ b/src/ui/graph/graph_view.rs +@@ -42,8 +42,8 @@ mod imp { + use adw::gtk::gdk::{self}; + use log::warn; + use once_cell::sync::Lazy; +- use pipewire::spa::format::MediaType; +- use pipewire::spa::Direction; ++ use pipewire::spa::param::format::MediaType; ++ use pipewire::spa::utils::Direction; + + pub struct Colors { + audio: gdk::RGBA, +diff --git a/src/ui/graph/link.rs b/src/ui/graph/link.rs +index 140c74c..eb1343b 100644 +--- a/src/ui/graph/link.rs ++++ b/src/ui/graph/link.rs +@@ -15,7 +15,7 @@ + // SPDX-License-Identifier: GPL-3.0-only + + use adw::{glib, prelude::*, subclass::prelude::*}; +-use pipewire::spa::format::MediaType; ++use pipewire::spa::param::format::MediaType; + + use super::Port; + +diff --git a/src/ui/graph/node.rs b/src/ui/graph/node.rs +index 54d71c6..8233e62 100644 +--- a/src/ui/graph/node.rs ++++ b/src/ui/graph/node.rs +@@ -15,7 +15,7 @@ + // SPDX-License-Identifier: GPL-3.0-only + + use adw::{glib, gtk, prelude::*, subclass::prelude::*}; +-use pipewire::spa::Direction; ++use pipewire::spa::utils::Direction; + + use super::Port; + +diff --git a/src/ui/graph/port.rs b/src/ui/graph/port.rs +index b79e4d7..4189cd9 100644 +--- a/src/ui/graph/port.rs ++++ b/src/ui/graph/port.rs +@@ -21,7 +21,7 @@ use adw::{ + prelude::*, + subclass::prelude::*, + }; +-use pipewire::spa::Direction; ++use pipewire::spa::utils::Direction; + + use super::PortHandle; + +@@ -31,7 +31,7 @@ mod imp { + use std::cell::Cell; + + use once_cell::{sync::Lazy, unsync::OnceCell}; +- use pipewire::spa::{format::MediaType, Direction}; ++ use pipewire::spa::{param::format::MediaType, utils::Direction}; + + /// Graphical representation of a pipewire port. + #[derive(gtk::CompositeTemplate, glib::Properties)] diff --git a/debian/patches/use-AdwToolbarView.patch b/debian/patches/use-AdwToolbarView.patch new file mode 100644 index 0000000..c4abed9 --- /dev/null +++ b/debian/patches/use-AdwToolbarView.patch @@ -0,0 +1,87 @@ +From: Angelo Verlain <geoangerc...@gmail.com> +Date: Fri, 6 Oct 2023 18:02:01 +0200 +Subject: use AdwToolbarView + +(cherry picked from commit 94d5e956952a071818dff6a7ef18996552b8363d) +--- + Cargo.toml | 2 +- + meson.build | 2 +- + src/ui/window.ui | 13 ++++++------- + 3 files changed, 8 insertions(+), 9 deletions(-) + +diff --git a/Cargo.toml b/Cargo.toml +index b10c546..e72f4fd 100644 +--- a/Cargo.toml ++++ b/Cargo.toml +@@ -15,7 +15,7 @@ categories = ["gui", "multimedia"] + + [dependencies] + pipewire = "0.7.1" +-adw = { version = "0.5", package = "libadwaita", features = ["v1_3"] } ++adw = { version = "0.5", package = "libadwaita", features = ["v1_4"] } + glib = { version = "0.18", features = ["log"] } + + log = "0.4.11" +diff --git a/meson.build b/meson.build +index 2ecbebc..34bf0fa 100644 +--- a/meson.build ++++ b/meson.build +@@ -12,7 +12,7 @@ base_id = 'org.pipewire.Helvum' + + dependency('glib-2.0', version: '>= 2.66') + dependency('gtk4', version: '>= 4.4.0') +-dependency('libadwaita-1', version: '>= 1.3') ++dependency('libadwaita-1', version: '>= 1.4') + dependency('libpipewire-0.3') + + desktop_file_validate = find_program('desktop-file-validate', required: false) +diff --git a/src/ui/window.ui b/src/ui/window.ui +index 22d72f1..f40432a 100644 +--- a/src/ui/window.ui ++++ b/src/ui/window.ui +@@ -1,7 +1,7 @@ + <?xml version="1.0" encoding="UTF-8"?> + <interface> + <requires lib="gtk" version="4.0"/> +- <requires lib="Adw" version="1.0"/> ++ <requires lib="Adw" version="1.4"/> + <menu id="primary_menu"> + <section> + <item> +@@ -15,9 +15,8 @@ + <property name="default-height">720</property> + <property name="title">Helvum - Pipewire Patchbay</property> + <child> +- <object class="GtkBox"> +- <property name="orientation">vertical</property> +- <child> ++ <object class="AdwToolbarView"> ++ <child type="top"> + <object class="AdwHeaderBar" id="header_bar"> + <child type="end"> + <object class="GtkMenuButton"> +@@ -27,13 +26,13 @@ + </child> + </object> + </child> +- <child> ++ <child type="top"> + <object class="AdwBanner" id="connection_banner"> + <property name="title" translatable="yes">Disconnected</property> + <property name="revealed">false</property> + </object> + </child> +- <child> ++ <property name="content"> + <object class="GtkOverlay"> + <child> + <object class="GtkScrolledWindow"> +@@ -55,7 +54,7 @@ + </object> + </child> + </object> +- </child> ++ </property> + </object> + </child> + </template> -- 2.43.0
From bdc1a1410074188cebd7634b5d0bc3e99c9eb92c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jeremy=20B=C3=ADcha?= <jeremy.bi...@canonical.com> Date: Sat, 20 Apr 2024 07:14:06 -0400 Subject: [PATCH 2/3] Add patch to relax rust-async-channel dependency --- debian/patches/relax-deps.patch | 22 ++++++++++++++++++++++ debian/patches/series | 1 + 2 files changed, 23 insertions(+) create mode 100644 debian/patches/relax-deps.patch diff --git a/debian/patches/relax-deps.patch b/debian/patches/relax-deps.patch new file mode 100644 index 0000000..9705fe2 --- /dev/null +++ b/debian/patches/relax-deps.patch @@ -0,0 +1,22 @@ +From: =?utf-8?q?Jeremy_B=C3=ADcha?= <jeremy.bi...@canonical.com> +Date: Sat, 20 Apr 2024 07:07:47 -0400 +Subject: Relax deps + +Forwarded: not-needed +--- + Cargo.toml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Cargo.toml b/Cargo.toml +index f839bfc..d584c14 100644 +--- a/Cargo.toml ++++ b/Cargo.toml +@@ -17,7 +17,7 @@ categories = ["gui", "multimedia"] + pipewire = "0.8.0" + adw = { version = "0.6", package = "libadwaita", features = ["v1_4"] } + glib = { version = "0.19", features = ["log"] } +-async-channel = "2.2" ++async-channel = "1.9" + + log = "0.4.11" + diff --git a/debian/patches/series b/debian/patches/series index a7d1c8d..05bacba 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -4,3 +4,4 @@ pw-Set-media.category-property-to-manager.patch ui-Display-node-media-name-in-graph-view.patch update-Helvum-to-track-the-latest-pipewire0.8.0.patch Update-to-latest-gtk-rs-crates.patch +relax-deps.patch -- 2.43.0