mirror of https://github.com/bobwen-dev/hunter
kill media-previewer when image is deselected before it's done
This commit is contained in:
parent
cab23957ce
commit
d143de245a
|
@ -185,6 +185,12 @@ impl HError {
|
|||
|
||||
}
|
||||
|
||||
#[derive(Fail, Debug, Clone)]
|
||||
pub enum ErrorCause {
|
||||
#[fail(display = "{}", _0)]
|
||||
Str(String)
|
||||
}
|
||||
|
||||
|
||||
lazy_static! {
|
||||
static ref LOG: Mutex<Vec<LogEntry>> = Mutex::new(vec![]);
|
||||
|
|
|
@ -1,22 +1,25 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Command, Stdio};
|
||||
use std::io::{BufReader, BufRead};
|
||||
use std::sync::atomic::{AtomicU32, Ordering};
|
||||
|
||||
use crate::widget::{Widget, WidgetCore};
|
||||
use crate::coordinates::Coordinates;
|
||||
use crate::fail::HResult;
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use crate::fail::{HResult, ErrorCause};
|
||||
use crate::mediaview::MediaError;
|
||||
|
||||
impl std::cmp::PartialEq for ImgView {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.core == other.core &&
|
||||
self.buffer == other.buffer
|
||||
}
|
||||
|
||||
|
||||
lazy_static! {
|
||||
static ref PID: AtomicU32 = AtomicU32::new(0);
|
||||
}
|
||||
|
||||
#[derive(Derivative)]
|
||||
#[derivative(PartialEq)]
|
||||
pub struct ImgView {
|
||||
pub core: WidgetCore,
|
||||
pub buffer: Vec<String>,
|
||||
pub file: Option<PathBuf>
|
||||
pub file: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl ImgView {
|
||||
|
@ -24,7 +27,7 @@ impl ImgView {
|
|||
let mut view = ImgView {
|
||||
core: core,
|
||||
buffer: vec![],
|
||||
file: Some(file.to_path_buf())
|
||||
file: Some(file.to_path_buf()),
|
||||
};
|
||||
|
||||
view.encode_file()?;
|
||||
|
@ -40,7 +43,7 @@ impl ImgView {
|
|||
let media_previewer = self.core.config().media_previewer;
|
||||
let g_mode = self.core.config().graphics;
|
||||
|
||||
let output = std::process::Command::new(&media_previewer)
|
||||
let mut previewer = Command::new(&media_previewer)
|
||||
.arg(format!("{}", (xsize+1)))
|
||||
.arg(format!("{}", (ysize+1)))
|
||||
.arg(format!("{}", xpix))
|
||||
|
@ -51,7 +54,10 @@ impl ImgView {
|
|||
.arg(format!("true"))
|
||||
.arg(format!("{}", g_mode))
|
||||
.arg(file.to_string_lossy().to_string())
|
||||
.output()
|
||||
.stdin(Stdio::null())
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.map_err(|e| {
|
||||
let msg = format!("Couldn't run {}{}{}! Error: {:?}",
|
||||
crate::term::color_red(),
|
||||
|
@ -62,14 +68,37 @@ impl ImgView {
|
|||
self.core.show_status(&msg).ok();
|
||||
|
||||
MediaError::NoPreviewer(msg)
|
||||
})?
|
||||
.stdout;
|
||||
})?;
|
||||
|
||||
PID.store(previewer.id(), Ordering::Relaxed);
|
||||
|
||||
let output = std::str::from_utf8(&output)?;
|
||||
let output = output.lines()
|
||||
.map(|l| l.to_string())
|
||||
.collect();
|
||||
let stdout = previewer.stdout
|
||||
.take()
|
||||
.unwrap();
|
||||
|
||||
let output = BufReader::new(stdout)
|
||||
.lines()
|
||||
.collect::<Result<Vec<String>, _>>()?;
|
||||
|
||||
let stderr = previewer.stderr
|
||||
.take()
|
||||
.unwrap();
|
||||
|
||||
let stderr = BufReader::new(stderr)
|
||||
.lines()
|
||||
.collect::<Result<String, _>>()?;
|
||||
|
||||
let status = previewer.wait()?;
|
||||
|
||||
PID.store(0, Ordering::Relaxed);
|
||||
|
||||
if !status.success() {
|
||||
match status.code() {
|
||||
Some(code) => Err(MediaError::MediaViewerFailed(code,
|
||||
ErrorCause::Str(stderr)))?,
|
||||
None => Err(MediaError::MediaViewerKilled)?
|
||||
}
|
||||
}
|
||||
|
||||
self.buffer = output;
|
||||
|
||||
|
@ -83,6 +112,20 @@ impl ImgView {
|
|||
pub fn lines(&self) -> usize {
|
||||
self.buffer.len()
|
||||
}
|
||||
|
||||
pub fn kill_running() {
|
||||
use nix::{unistd::Pid,
|
||||
sys::signal::{kill, Signal}};
|
||||
|
||||
let pid = PID.load(Ordering::Relaxed);
|
||||
|
||||
if pid == 0 { return; }
|
||||
|
||||
let pid = Pid::from_raw(pid as i32);
|
||||
kill(pid, Signal::SIGTERM).ok();
|
||||
|
||||
PID.store(0, Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ use failure::{self, Fail};
|
|||
use crate::widget::{Widget, WidgetCore};
|
||||
use crate::coordinates::Coordinates;
|
||||
use crate::async_value::Stale;
|
||||
use crate::fail::{HResult, HError, ErrorLog};
|
||||
use crate::fail::{HResult, HError, ErrorLog, ErrorCause};
|
||||
use crate::imgview::ImgView;
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
@ -18,7 +18,13 @@ use std::process::Child;
|
|||
#[derive(Fail, Debug, Clone)]
|
||||
pub enum MediaError {
|
||||
#[fail(display = "{}", _0)]
|
||||
NoPreviewer(String)
|
||||
NoPreviewer(String),
|
||||
#[fail(display = "No output could be read from {}", _0)]
|
||||
NoOutput(String),
|
||||
#[fail(display = "Media viewer exited with status code: {}", _0)]
|
||||
MediaViewerFailed(i32, #[cause] ErrorCause),
|
||||
#[fail(display = "Media viewer killed!")]
|
||||
MediaViewerKilled,
|
||||
}
|
||||
|
||||
impl From<MediaError> for HError {
|
||||
|
@ -80,7 +86,7 @@ impl MediaView {
|
|||
let imgview = ImgView {
|
||||
core: core.clone(),
|
||||
buffer: vec![],
|
||||
file: None
|
||||
file: None,
|
||||
};
|
||||
|
||||
let (tx_cmd, rx_cmd) = channel();
|
||||
|
|
|
@ -23,6 +23,9 @@ lazy_static! {
|
|||
}
|
||||
|
||||
fn kill_proc() -> HResult<()> {
|
||||
// Kill media previewer if it still runs
|
||||
ImgView::kill_running();
|
||||
|
||||
let mut pid = SUBPROC.lock()?;
|
||||
pid.map(|pid|
|
||||
// Do this in another thread so we can wait on process to exit with SIGHUP
|
||||
|
@ -34,9 +37,9 @@ fn kill_proc() -> HResult<()> {
|
|||
|
||||
// Kill using process group, to clean up all child processes, too
|
||||
let pid = Pid::from_raw(pid as i32);
|
||||
killpg(pid, Signal::SIGTERM).log();
|
||||
killpg(pid, Signal::SIGTERM).ok();
|
||||
std::thread::sleep(sleep_time);
|
||||
killpg(pid, Signal::SIGKILL).log();
|
||||
killpg(pid, Signal::SIGKILL).ok();
|
||||
})
|
||||
);
|
||||
*pid = None;
|
||||
|
|
Loading…
Reference in New Issue