fix: end async work on soft-shutdown
This commit is contained in:
4
Cargo.lock
generated
4
Cargo.lock
generated
@@ -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",
|
||||||
|
|||||||
@@ -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]
|
||||||
|
|||||||
@@ -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()?;
|
||||||
|
|||||||
@@ -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
|
||||||
|
.poll_unpin(&mut Context::from_waker(futures::task::noop_waker_ref()))
|
||||||
|
{
|
||||||
|
Poll::Ready(result) => result,
|
||||||
|
Poll::Pending => {
|
||||||
self.selector = Some(selector);
|
self.selector = Some(selector);
|
||||||
return Ok(());
|
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(),
|
||||||
|
|||||||
Reference in New Issue
Block a user