fix: end async work on soft-shutdown

This commit is contained in:
galister
2024-03-23 15:35:01 +01:00
parent 9fe9832a8d
commit a1d3b9684d
4 changed files with 44 additions and 19 deletions

4
Cargo.lock generated
View File

@@ -3602,8 +3602,8 @@ dependencies = [
[[package]] [[package]]
name = "wlx-capture" name = "wlx-capture"
version = "0.3.0" version = "0.3.1"
source = "git+https://github.com/galister/wlx-capture?tag=v0.3.0#bbe232c207c7d6cfca26efe02e8bc6ce85ee764a" source = "git+https://github.com/galister/wlx-capture?tag=v0.3.1#f9c9c98e0752bfbdaa2af69b59376c697c223915"
dependencies = [ dependencies = [
"ashpd", "ashpd",
"drm-fourcc", "drm-fourcc",

View File

@@ -43,7 +43,7 @@ strum = { version = "0.25.0", features = ["derive"] }
thiserror = "1.0.56" thiserror = "1.0.56"
vulkano = { git = "https://github.com/vulkano-rs/vulkano", rev = "94f50f1" } vulkano = { git = "https://github.com/vulkano-rs/vulkano", rev = "94f50f1" }
vulkano-shaders = { git = "https://github.com/vulkano-rs/vulkano", rev = "94f50f1" } vulkano-shaders = { git = "https://github.com/vulkano-rs/vulkano", rev = "94f50f1" }
wlx-capture = { git = "https://github.com/galister/wlx-capture", tag = "v0.3.0", default-features = false } wlx-capture = { git = "https://github.com/galister/wlx-capture", tag = "v0.3.1", default-features = false }
xdg = "2.5.2" xdg = "2.5.2"
[features] [features]

View File

@@ -2,7 +2,10 @@ use dbus::{blocking::Connection, channel::MatchingReceiver, message::MatchRule};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{ use std::{
path::PathBuf, path::PathBuf,
sync::{mpsc, Arc}, sync::{
atomic::{AtomicBool, Ordering},
mpsc, Arc,
},
time::Duration, time::Duration,
}; };
@@ -12,6 +15,7 @@ pub struct NotificationManager {
rx_toast: mpsc::Receiver<Toast>, rx_toast: mpsc::Receiver<Toast>,
tx_toast: mpsc::SyncSender<Toast>, tx_toast: mpsc::SyncSender<Toast>,
dbus_data: Option<Connection>, dbus_data: Option<Connection>,
running: Arc<AtomicBool>,
} }
impl NotificationManager { impl NotificationManager {
@@ -21,6 +25,7 @@ impl NotificationManager {
rx_toast, rx_toast,
tx_toast, tx_toast,
dbus_data: None, dbus_data: None,
running: Arc::new(AtomicBool::new(true)),
} }
} }
@@ -125,7 +130,7 @@ impl NotificationManager {
pub fn run_udp(&mut self) { pub fn run_udp(&mut self) {
let sender = self.tx_toast.clone(); let sender = self.tx_toast.clone();
// NOTE: We're detaching the thread, as there's no simple way to gracefully stop it other than app shutdown. let running = self.running.clone();
let _ = std::thread::spawn(move || { let _ = std::thread::spawn(move || {
let addr = "127.0.0.1:42069"; let addr = "127.0.0.1:42069";
let socket = match std::net::UdpSocket::bind(addr) { let socket = match std::net::UdpSocket::bind(addr) {
@@ -135,9 +140,13 @@ impl NotificationManager {
return; return;
} }
}; };
if let Err(err) = socket.set_read_timeout(Some(Duration::from_millis(200))) {
log::error!("Failed to set read timeout: {:?}", err);
}
let mut buf = [0u8; 1024 * 16]; // vrcx embeds icons as b64 let mut buf = [0u8; 1024 * 16]; // vrcx embeds icons as b64
loop { while running.load(Ordering::Relaxed) {
if let Ok((num_bytes, _)) = socket.recv_from(&mut buf) { if let Ok((num_bytes, _)) = socket.recv_from(&mut buf) {
let json_str = match std::str::from_utf8(&buf[..num_bytes]) { let json_str = match std::str::from_utf8(&buf[..num_bytes]) {
Ok(s) => s, Ok(s) => s,
@@ -170,10 +179,17 @@ impl NotificationManager {
} }
} }
} }
log::info!("Notification listener stopped.");
}); });
} }
} }
impl Drop for NotificationManager {
fn drop(&mut self) {
self.running.store(false, Ordering::Relaxed);
}
}
fn parse_dbus(msg: &dbus::Message) -> anyhow::Result<Toast> { fn parse_dbus(msg: &dbus::Message) -> anyhow::Result<Toast> {
let mut args = msg.iter_init(); let mut args = msg.iter_init();
let app_name: String = args.read()?; let app_name: String = args.read()?;

View File

@@ -1,6 +1,9 @@
use std::{sync::Arc, thread::JoinHandle}; use std::{
sync::Arc,
task::{Context, Poll},
};
use futures::executor; use futures::{Future, FutureExt};
use glam::vec3a; use glam::vec3a;
use wlx_capture::pipewire::{pipewire_select_screen, PipewireCapture, PipewireSelectScreenResult}; use wlx_capture::pipewire::{pipewire_select_screen, PipewireCapture, PipewireSelectScreenResult};
@@ -15,21 +18,23 @@ use crate::{
}; };
use super::screen::ScreenRenderer; use super::screen::ScreenRenderer;
type PinnedSelectorFuture = core::pin::Pin<
Box<dyn Future<Output = Result<PipewireSelectScreenResult, wlx_capture::pipewire::AshpdError>>>,
>;
pub struct MirrorRenderer { pub struct MirrorRenderer {
name: Arc<str>, name: Arc<str>,
renderer: Option<ScreenRenderer>, renderer: Option<ScreenRenderer>,
selector: Option<JoinHandle<Option<PipewireSelectScreenResult>>>, selector: Option<PinnedSelectorFuture>,
last_extent: [u32; 3], last_extent: [u32; 3],
} }
impl MirrorRenderer { impl MirrorRenderer {
pub fn new(name: Arc<str>) -> Self { pub fn new(name: Arc<str>) -> Self {
let selector = Box::pin(pipewire_select_screen(None, false, false, false));
Self { Self {
name, name,
renderer: None, renderer: None,
selector: Some(std::thread::spawn(|| { selector: Some(selector),
executor::block_on(pipewire_select_screen(None, false, false, false)).ok()
})),
last_extent: [0; 3], last_extent: [0; 3],
} }
} }
@@ -40,14 +45,18 @@ impl OverlayRenderer for MirrorRenderer {
Ok(()) Ok(())
} }
fn render(&mut self, app: &mut AppState) -> anyhow::Result<()> { fn render(&mut self, app: &mut AppState) -> anyhow::Result<()> {
if let Some(selector) = self.selector.take() { if let Some(mut selector) = self.selector.take() {
if !selector.is_finished() { let maybe_pw_result = match selector
self.selector = Some(selector); .poll_unpin(&mut Context::from_waker(futures::task::noop_waker_ref()))
return Ok(()); {
} Poll::Ready(result) => result,
Poll::Pending => {
self.selector = Some(selector);
return Ok(());
}
};
// safe unwrap because we know it's finished if let Ok(pw_result) = maybe_pw_result {
if let Some(pw_result) = selector.join().unwrap() {
log::info!( log::info!(
"{}: PipeWire node selected: {}", "{}: PipeWire node selected: {}",
self.name.clone(), self.name.clone(),