Skip to content

Commit

Permalink
Add device property to PwNodeObject
Browse files Browse the repository at this point in the history
This can then be used to get notified when we have a PwNodeObject representing a sink/source and setup UI only when we have an associated device.
  • Loading branch information
saivert committed Jun 22, 2024
1 parent e1aa5a3 commit 2bcd2e4
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 29 deletions.
44 changes: 28 additions & 16 deletions src/backend/pwnodeobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ pub mod imp {
pub(super) block: Cell<bool>,

pub(super) om: RefCell<ObjectManager>,

#[property(get)]
pub(super) device: RefCell<Option<PwDeviceObject>>,
}

impl Default for PwNodeObject {
Expand All @@ -110,6 +113,7 @@ pub mod imp {
block: Default::default(),
om: Default::default(),
hidden: Default::default(),
device: Default::default(),
}
}
}
Expand Down Expand Up @@ -216,21 +220,38 @@ pub mod imp {
.iter().collect::<Interest<wp::pw::Link>>());

if let Ok(Some(device_id)) = node.device_id() {
om.add_interest([Constraint::compare(ConstraintType::PwGlobalProperty, "device.id", device_id, true)]
om.add_interest([Constraint::compare(ConstraintType::GProperty, "bound-id", device_id, true)]
.iter()
.collect::<Interest<wp::pw::Device>>());
}


om.connect_object_added(clone!(@weak self as widget => move |_om, obj| {
om.connect_object_added(clone!(@weak self as nodeobject => move |_om, obj| {
if let Some(link) = obj.downcast_ref::<wp::pw::Link>() {
let linked_node_id: u32 = link.pw_property("link.input.node").expect("link.input.node property");
let linked_node = PwvucontrolManager::default().get_node_by_id(linked_node_id);
pwvucontrol_info!("Node {} linked to node id {linked_node_id} ({:?})", widget.obj().name(), linked_node.map(|x|x.name()));
pwvucontrol_info!("Node {} linked to node id {linked_node_id} ({:?})", nodeobject.obj().name(), linked_node.map(|x|x.name()));
} else if let Some(device) = obj.downcast_ref::<wp::pw::Device>() {
let device_name: String = device.pw_property("device.description").unwrap();
let manager = PwvucontrolManager::default();
nodeobject.device.set(manager.get_device_by_id(device.bound_id()));
nodeobject.obj().notify_device();
pwvucontrol_info!("Node {} linked to device {device_name}", nodeobject.obj().name());
}
}));

PwvucontrolManager::default().wp_core().install_object_manager(&om);

// let manager = PwvucontrolManager::default();
// manager.device_model().connect_items_changed(clone!(@weak self as nodeobject => move |liststore, _position, _removed, _added| {
// for device in liststore.iter::<PwDeviceObject>().map_while(Result::ok) {
// let node = nodeobject.wpnode.get().expect("node");
// if let Ok(Some(id)) = node.device_id() {
// if id == device.wpdevice().bound_id() {
// nodeobject.device.set(Some(device.clone()));
// }
// }
// }
// }));
}
}

Expand Down Expand Up @@ -327,7 +348,7 @@ impl PwNodeObject {
}
}

pub(crate) fn update_format(&self) {
fn update_format(&self) {
let node = self.imp().wpnode.get().expect("node");

node.enum_params(Some("Format"), None, gtk::gio::Cancellable::NONE, clone!(@weak self as widget, @weak node => move |res| {
Expand Down Expand Up @@ -493,7 +514,7 @@ impl PwNodeObject {
}
}

pub(crate) fn set_format(&self, format: AudioFormat) {
fn set_format(&self, format: AudioFormat) {
self.imp().format.set(Some(format));

self.emit_by_name::<()>("format", &[]);
Expand All @@ -515,19 +536,10 @@ impl PwNodeObject {
};
}

pub(crate) fn get_device(&self) -> Option<PwDeviceObject> {

if let Ok(Some(device_id)) = self.wpnode().device_id() {
let manager = PwvucontrolManager::default();
return manager.get_device_by_id(device_id);
}
None
}

pub(crate) fn set_route(&self, routeobj: &PwRouteObject) {
let index = routeobj.index();
if let Ok(Some(card_profile_device)) = self.wpnode().device_index() {
if let Some(device) = self.get_device() {
if let Some(device) = self.device() {
device.set_route(index, card_profile_device as i32);

let profiles = routeobj.get_profiles();
Expand Down
8 changes: 3 additions & 5 deletions src/ui/route_dropdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ mod imp {
let nodeobject = self.nodeobject.borrow();
let nodeobject = nodeobject.as_ref().unwrap();

let Some(deviceobject) = nodeobject.get_device() else {
let Some(deviceobject) = nodeobject.device() else {
return None;
};
match nodeobject.nodetype() {
Expand All @@ -69,7 +69,7 @@ mod imp {
let nodeobject = self.nodeobject.borrow();
let nodeobject = nodeobject.as_ref().unwrap();

let deviceobject = nodeobject.get_device().expect("device");
let deviceobject = nodeobject.device().expect("device");
match nodeobject.nodetype() {
NodeType::Source => Some(deviceobject.routemodel_input()),
NodeType::Sink => Some(deviceobject.routemodel_output()),
Expand All @@ -81,9 +81,7 @@ mod imp {
self.nodeobject.replace(new_nodeobject.cloned());

if let Some(nodeobject) = new_nodeobject {
let Some(deviceobject) = nodeobject.get_device() else {
return;
};
let deviceobject = nodeobject.device().expect("nodeobject with associated device on PwRouteDropDown");

self.block_signal.set(true);
pwvucontrol_info!("self.route_dropdown.set_model({});", deviceobject.wpdevice().bound_id());
Expand Down
23 changes: 15 additions & 8 deletions src/ui/sinkbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,22 @@ mod imp {
widget.obj().default_node_changed();
}));

glib::idle_add_local_once(clone!(@weak self as widget => move || {
widget.obj().default_node_changed();
// Only set nodeobject once it has a device associated.
if let Some(node) = obj.node_object() {
node.connect_device_notify(clone!(@weak self as widget => move |nodeobject| {
widget.route_dropdown.set_nodeobject(Some(nodeobject));
}));
}

// TODO: Hack! Associated PwDeviceObject for a sink type PwNodeObject may not have been added to model yet at this time.
// Delay the set_nodeobject call as workaround for now.
if let Some(node) = widget.obj().node_object() {
widget.route_dropdown.set_nodeobject(Some(node));
}
}));
// glib::idle_add_local_once(clone!(@weak self as widget => move || {
// widget.obj().default_node_changed();

// // TODO: Hack! Associated PwDeviceObject for a sink type PwNodeObject may not have been added to model yet at this time.
// // Delay the set_nodeobject call as workaround for now.
// if let Some(node) = widget.obj().node_object() {
// widget.route_dropdown.set_nodeobject(Some(node));
// }
// }));

pwvucontrol_info!("sinkbox set_nodeobject {}", self.obj().node_object().expect("Node object").name());
}
Expand Down

0 comments on commit 2bcd2e4

Please sign in to comment.