소스 검색

Add MPRIS player event listener

This allows the status bar to react to track changes in the active
player.
Frans Bergman 1 년 전
부모
커밋
a60741c70a
2개의 변경된 파일39개의 추가작업 그리고 1개의 파일을 삭제
  1. 1 1
      Cargo.toml
  2. 38 0
      src/main.rs

+ 1 - 1
Cargo.toml

@@ -11,5 +11,5 @@ itertools = "0.11.0"
 mpris = "2.0.1"
 pulsectl-rs = "0.3.2"
 systemstat = "0.2.3"
-tokio = { version = "1.29.1", features = ["signal", "time", "rt-multi-thread", "macros", "tokio-macros"] }
+tokio = { version = "1.29.1", features = ["signal", "sync", "time", "rt-multi-thread", "macros", "tokio-macros"] }
 xcb = "1.2.1"

+ 38 - 0
src/main.rs

@@ -2,12 +2,48 @@ mod block;
 
 use tokio::signal::unix::{signal, SignalKind};
 use tokio::time::{sleep, Duration};
+use tokio::sync::mpsc;
+use tokio::task;
 
 use itertools::Itertools;
 use xcb::x;
+use mpris::PlayerFinder;
 
 use block::*;
 
+fn setup_mpris_event_listener() -> mpsc::Receiver<()> {
+    let (tx, rx) = mpsc::channel::<()>(10);
+
+    task::spawn_blocking(move || {
+        let finder = PlayerFinder::new().expect("Could not create finder");
+
+        loop {
+            let player = match finder.find_active() {
+                Ok(player) => player,
+                Err(_) => {
+                    std::thread::sleep(std::time::Duration::from_secs(5));
+                    continue;
+                },
+            };
+
+            println!("Player found: {}", player.identity());
+
+            let mut events = player.events().expect("Could not listen for events");
+
+            loop {
+                if let Some(_event) = events.next() {
+                    tx.blocking_send(()).expect("Can't send");
+                } else {
+                    println!("Player lost");
+                    break;
+                }
+            }
+        }
+    });
+
+    rx
+}
+
 #[tokio::main]
 async fn main() -> Result<(), Box<dyn std::error::Error>> {
     let (conn, screen_num) = xcb::Connection::connect(None)?;
@@ -27,6 +63,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
     ];
 
     let mut sigusr1 = signal(SignalKind::user_defined1())?;
+    let mut mpris_rx = setup_mpris_event_listener();
 
     loop {
         let status_bar: String = blocks
@@ -50,6 +87,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
         tokio::select! {
             _ = sleep(Duration::from_secs(1)) => {},
             _ = sigusr1.recv() => {},
+            _ = mpris_rx.recv() => {},
         }
     }
 }