Experimental command socket support
Introduces "start-or-kill" and "toggle-visible" commands. How the command socket is used will likely change soon.
This commit is contained in:
+49
-35
@@ -17,6 +17,8 @@ use wayland_protocols::wlr::unstable::layer_shell::v1::client::{
|
|||||||
use crate::color::Color;
|
use crate::color::Color;
|
||||||
use crate::buffer::Buffer;
|
use crate::buffer::Buffer;
|
||||||
|
|
||||||
|
use crate::cmd::Cmd;
|
||||||
|
|
||||||
use crate::modules::backlight::Backlight;
|
use crate::modules::backlight::Backlight;
|
||||||
use crate::modules::battery::UpowerBattery;
|
use crate::modules::battery::UpowerBattery;
|
||||||
use crate::modules::calendar::Calendar;
|
use crate::modules::calendar::Calendar;
|
||||||
@@ -25,12 +27,9 @@ use crate::modules::launcher::Launcher;
|
|||||||
use crate::modules::module::{Input, Module};
|
use crate::modules::module::{Input, Module};
|
||||||
use crate::modules::sound::PulseAudio;
|
use crate::modules::sound::PulseAudio;
|
||||||
|
|
||||||
pub enum Cmd {
|
pub enum OutputMode {
|
||||||
Exit,
|
Active,
|
||||||
Draw,
|
All,
|
||||||
ForceDraw,
|
|
||||||
MouseInput { pos: (u32, u32), input: Input },
|
|
||||||
KeyboardInput { input: Input },
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AppInner {
|
struct AppInner {
|
||||||
@@ -41,12 +40,13 @@ struct AppInner {
|
|||||||
outputs: Vec<(u32, wl_output::WlOutput)>,
|
outputs: Vec<(u32, wl_output::WlOutput)>,
|
||||||
shell: Option<zwlr_layer_shell_v1::ZwlrLayerShellV1>,
|
shell: Option<zwlr_layer_shell_v1::ZwlrLayerShellV1>,
|
||||||
dimensions: (u32, u32),
|
dimensions: (u32, u32),
|
||||||
draw_tx: Sender<bool>,
|
draw_tx: Sender<Cmd>,
|
||||||
all_outputs: bool,
|
output_mode: OutputMode,
|
||||||
|
visible: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppInner {
|
impl AppInner {
|
||||||
fn new(tx: Sender<bool>, all_outputs: bool) -> AppInner{
|
fn new(tx: Sender<Cmd>, output_mode: OutputMode) -> AppInner{
|
||||||
AppInner{
|
AppInner{
|
||||||
compositor: None,
|
compositor: None,
|
||||||
surfaces: Vec::new(),
|
surfaces: Vec::new(),
|
||||||
@@ -56,7 +56,8 @@ impl AppInner {
|
|||||||
shell: None,
|
shell: None,
|
||||||
dimensions: (0, 0),
|
dimensions: (0, 0),
|
||||||
draw_tx: tx,
|
draw_tx: tx,
|
||||||
all_outputs: all_outputs,
|
output_mode: output_mode,
|
||||||
|
visible: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +66,7 @@ impl AppInner {
|
|||||||
shell: &zwlr_layer_shell_v1::ZwlrLayerShellV1,
|
shell: &zwlr_layer_shell_v1::ZwlrLayerShellV1,
|
||||||
dimensions: (u32, u32),
|
dimensions: (u32, u32),
|
||||||
configured_surfaces: Arc<Mutex<usize>>,
|
configured_surfaces: Arc<Mutex<usize>>,
|
||||||
tx: Sender<bool>,
|
tx: Sender<Cmd>,
|
||||||
output: Option<&wl_output::WlOutput>
|
output: Option<&wl_output::WlOutput>
|
||||||
) -> (
|
) -> (
|
||||||
wl_surface::WlSurface,
|
wl_surface::WlSurface,
|
||||||
@@ -87,7 +88,7 @@ impl AppInner {
|
|||||||
zwlr_layer_surface_v1::Event::Configure { serial, .. } => {
|
zwlr_layer_surface_v1::Event::Configure { serial, .. } => {
|
||||||
*(configured_surfaces.lock().unwrap()) += 1;
|
*(configured_surfaces.lock().unwrap()) += 1;
|
||||||
layer.ack_configure(serial);
|
layer.ack_configure(serial);
|
||||||
tx.send(false).unwrap();
|
tx.send(Cmd::ForceDraw).unwrap();
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
@@ -114,10 +115,6 @@ impl AppInner {
|
|||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
if !self.all_outputs && self.shell_surfaces.len() > 0 {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for shell_surface in self.shell_surfaces.iter() {
|
for shell_surface in self.shell_surfaces.iter() {
|
||||||
shell_surface.destroy();
|
shell_surface.destroy();
|
||||||
}
|
}
|
||||||
@@ -127,23 +124,34 @@ impl AppInner {
|
|||||||
|
|
||||||
self.configured_surfaces = Arc::new(Mutex::new(0));
|
self.configured_surfaces = Arc::new(Mutex::new(0));
|
||||||
|
|
||||||
if self.all_outputs {
|
if self.visible {
|
||||||
let mut surfaces = Vec::new();
|
match self.output_mode {
|
||||||
let mut shell_surfaces = Vec::new();
|
OutputMode::Active => {
|
||||||
for output in self.outputs.iter() {
|
if self.shell_surfaces.len() > 0 {
|
||||||
let (surface, shell_surface) = AppInner::add_shell_surface(&compositor, &shell, self.dimensions, self.configured_surfaces.clone(), self.draw_tx.clone(), Some(&output.1));
|
return;
|
||||||
surfaces.push(surface);
|
}
|
||||||
shell_surfaces.push(shell_surface);
|
let (surface, shell_surface) = AppInner::add_shell_surface(&compositor, &shell, self.dimensions, self.configured_surfaces.clone(), self.draw_tx.clone(), None);
|
||||||
}
|
self.surfaces = vec![surface];
|
||||||
self.surfaces = surfaces;
|
self.shell_surfaces = vec![shell_surface];
|
||||||
self.shell_surfaces = shell_surfaces;
|
|
||||||
} else {
|
|
||||||
let (surface, shell_surface) = AppInner::add_shell_surface(&compositor, &shell, self.dimensions, self.configured_surfaces.clone(), self.draw_tx.clone(), None);
|
|
||||||
self.surfaces = vec![surface];
|
|
||||||
self.shell_surfaces = vec![shell_surface];
|
|
||||||
}
|
|
||||||
|
|
||||||
self.draw_tx.send(false).unwrap();
|
},
|
||||||
|
OutputMode::All => {
|
||||||
|
let mut surfaces = Vec::new();
|
||||||
|
let mut shell_surfaces = Vec::new();
|
||||||
|
for output in self.outputs.iter() {
|
||||||
|
let (surface, shell_surface) = AppInner::add_shell_surface(&compositor, &shell, self.dimensions, self.configured_surfaces.clone(), self.draw_tx.clone(), Some(&output.1));
|
||||||
|
surfaces.push(surface);
|
||||||
|
shell_surfaces.push(shell_surface);
|
||||||
|
}
|
||||||
|
self.surfaces = surfaces;
|
||||||
|
self.shell_surfaces = shell_surfaces;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.draw_tx.send(Cmd::ForceDraw).unwrap();
|
||||||
|
} else {
|
||||||
|
self.surfaces = Vec::new();
|
||||||
|
self.shell_surfaces = Vec::new();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_output(&mut self, id: u32, output: wl_output::WlOutput) {
|
fn add_output(&mut self, id: u32, output: wl_output::WlOutput) {
|
||||||
@@ -249,6 +257,12 @@ impl App {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn toggle_visible(&mut self) {
|
||||||
|
let mut inner = self.inner.lock().unwrap();
|
||||||
|
inner.visible = !inner.visible;
|
||||||
|
inner.outputs_changed();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn cmd_queue(&self) -> Arc<Mutex<VecDeque<Cmd>>> {
|
pub fn cmd_queue(&self) -> Arc<Mutex<VecDeque<Cmd>>> {
|
||||||
self.cmd_queue.clone()
|
self.cmd_queue.clone()
|
||||||
}
|
}
|
||||||
@@ -291,8 +305,8 @@ impl App {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(tx: Sender<bool>, all_outputs: bool) -> App {
|
pub fn new(tx: Sender<Cmd>, output_mode: OutputMode) -> App {
|
||||||
let inner = Arc::new(Mutex::new(AppInner::new(tx.clone(), all_outputs)));
|
let inner = Arc::new(Mutex::new(AppInner::new(tx.clone(), output_mode)));
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set up modules
|
// Set up modules
|
||||||
@@ -304,7 +318,7 @@ impl App {
|
|||||||
Module::new(Box::new(Calendar::new()), (0, 368, 1232, 344)),
|
Module::new(Box::new(Calendar::new()), (0, 368, 1232, 344)),
|
||||||
];
|
];
|
||||||
|
|
||||||
if let Ok(m) = Launcher::new() {
|
if let Ok(m) = Launcher::new(tx.clone()) {
|
||||||
modules.push(Module::new(Box::new(m), (0, 728, 1232, 32)));
|
modules.push(Module::new(Box::new(m), (0, 728, 1232, 32)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+103
-15
@@ -1,7 +1,8 @@
|
|||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write, BufRead, BufReader};
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
use std::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::os::unix::net::{UnixStream, UnixListener};
|
||||||
|
|
||||||
use nix::poll::{poll, PollFd, PollFlags};
|
use nix::poll::{poll, PollFd, PollFlags};
|
||||||
use os_pipe::pipe;
|
use os_pipe::pipe;
|
||||||
@@ -11,31 +12,114 @@ mod color;
|
|||||||
mod draw;
|
mod draw;
|
||||||
mod modules;
|
mod modules;
|
||||||
mod app;
|
mod app;
|
||||||
|
mod cmd;
|
||||||
|
|
||||||
use app::{App, Cmd};
|
use app::{App, OutputMode};
|
||||||
|
use cmd::Cmd;
|
||||||
|
|
||||||
|
enum Mode {
|
||||||
|
Start,
|
||||||
|
StartOrKill,
|
||||||
|
ToggleVisible,
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let (mut rx_pipe, mut tx_pipe) = pipe().unwrap();
|
let socket_path = match env::var("XDG_RUNTIME_DIR") {
|
||||||
let (tx_draw, rx_draw) = channel();
|
Ok(dir) => dir + "/wldash",
|
||||||
|
Err(_) => "/tmp/wldash".to_string(),
|
||||||
let all_outputs = match env::var("WLDASH_ALL_OUTPUTS") {
|
|
||||||
Ok(_) => true,
|
|
||||||
Err(_) => false,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut app = App::new(tx_draw, all_outputs);
|
let args: Vec<String> = env::args().collect();
|
||||||
|
let mode = match args.len() {
|
||||||
|
1 => Mode::Start,
|
||||||
|
2 => match args[1].as_str() {
|
||||||
|
"start" => Mode::Start,
|
||||||
|
"start-or-kill" => Mode::StartOrKill,
|
||||||
|
"toggle-visible" => Mode::ToggleVisible,
|
||||||
|
s => {
|
||||||
|
eprintln!("unsupported sub-command {}", s);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
v => {
|
||||||
|
eprintln!("expected 0 or 1 arguments, got {}", v);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match mode {
|
||||||
|
Mode::ToggleVisible => {
|
||||||
|
if let Ok(mut socket) = UnixStream::connect(socket_path.clone()) {
|
||||||
|
socket.write_all(b"toggle_visible\n").unwrap();
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
eprintln!("wldash is not running");
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
Mode::StartOrKill => {
|
||||||
|
if let Ok(mut socket) = UnixStream::connect(socket_path.clone()) {
|
||||||
|
socket.write_all(b"kill\n").unwrap();
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Mode::Start => {
|
||||||
|
if let Ok(_) = UnixStream::connect(socket_path.clone()) {
|
||||||
|
eprintln!("wldash is already running");
|
||||||
|
std::process::exit(1);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = std::fs::remove_file(socket_path.clone());
|
||||||
|
|
||||||
|
let listener = UnixListener::bind(socket_path.clone()).unwrap();
|
||||||
|
|
||||||
|
let (mut rx_pipe, mut tx_pipe) = pipe().unwrap();
|
||||||
|
let ipc_pipe = tx_pipe.try_clone().unwrap();
|
||||||
|
let (tx_draw, rx_draw) = channel();
|
||||||
|
|
||||||
|
let output_mode = match env::var("WLDASH_ALL_OUTPUTS") {
|
||||||
|
Ok(_) => OutputMode::All,
|
||||||
|
Err(_) => OutputMode::Active,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut app = App::new(tx_draw, output_mode);
|
||||||
app.wipe();
|
app.wipe();
|
||||||
|
|
||||||
let worker_queue = app.cmd_queue();
|
let worker_queue = app.cmd_queue();
|
||||||
std::thread::spawn(move || loop {
|
std::thread::spawn(move || loop {
|
||||||
if rx_draw.recv().unwrap() {
|
let cmd = rx_draw.recv().unwrap();
|
||||||
worker_queue.lock().unwrap().push_back(Cmd::Draw);
|
worker_queue.lock().unwrap().push_back(cmd);
|
||||||
} else {
|
|
||||||
worker_queue.lock().unwrap().push_back(Cmd::ForceDraw);
|
|
||||||
}
|
|
||||||
tx_pipe.write_all(&[0x1]).unwrap();
|
tx_pipe.write_all(&[0x1]).unwrap();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let ipc_queue = app.cmd_queue();
|
||||||
|
std::thread::spawn(move || loop {
|
||||||
|
for stream in listener.incoming() {
|
||||||
|
match stream {
|
||||||
|
Ok(stream) => {
|
||||||
|
let client_queue = ipc_queue.clone();
|
||||||
|
let mut client_pipe = ipc_pipe.try_clone().unwrap();
|
||||||
|
std::thread::spawn(move || {
|
||||||
|
let r = BufReader::new(stream);
|
||||||
|
for line in r.lines() {
|
||||||
|
match line {
|
||||||
|
Ok(v) => match v.as_str() {
|
||||||
|
"kill" => client_queue.lock().unwrap().push_back(Cmd::Exit),
|
||||||
|
"toggle_visible" => client_queue.lock().unwrap().push_back(Cmd::ToggleVisible),
|
||||||
|
v => eprintln!("unknown command: {}", v),
|
||||||
|
},
|
||||||
|
Err(_) => return,
|
||||||
|
}
|
||||||
|
client_pipe.write_all(&[0x1]).unwrap();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Err(_) => break,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let mut fds = [
|
let mut fds = [
|
||||||
PollFd::new(app.event_queue().get_connection_fd(), PollFlags::POLLIN),
|
PollFd::new(app.event_queue().get_connection_fd(), PollFlags::POLLIN),
|
||||||
PollFd::new(rx_pipe.as_raw_fd(), PollFlags::POLLIN),
|
PollFd::new(rx_pipe.as_raw_fd(), PollFlags::POLLIN),
|
||||||
@@ -70,8 +154,12 @@ fn main() {
|
|||||||
});
|
});
|
||||||
q.lock().unwrap().push_back(Cmd::Draw);
|
q.lock().unwrap().push_back(Cmd::Draw);
|
||||||
}
|
}
|
||||||
|
Cmd::ToggleVisible => {
|
||||||
|
app.toggle_visible();
|
||||||
|
}
|
||||||
Cmd::Exit => {
|
Cmd::Exit => {
|
||||||
std::process::exit(0);
|
let _ = std::fs::remove_file(socket_path);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use crate::buffer::Buffer;
|
|||||||
use crate::color::Color;
|
use crate::color::Color;
|
||||||
use crate::draw::{draw_bar, draw_box, Font, ROBOTO_REGULAR};
|
use crate::draw::{draw_bar, draw_box, Font, ROBOTO_REGULAR};
|
||||||
use crate::modules::module::{Input, ModuleImpl};
|
use crate::modules::module::{Input, ModuleImpl};
|
||||||
|
use crate::cmd::Cmd;
|
||||||
|
|
||||||
use std::sync::mpsc::Sender;
|
use std::sync::mpsc::Sender;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
@@ -129,7 +130,7 @@ impl UpowerBattery {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(listener: Sender<bool>) -> Result<Self, ::std::io::Error> {
|
pub fn new(listener: Sender<Cmd>) -> Result<Self, ::std::io::Error> {
|
||||||
let d = UpowerBattery::from_device("BAT0")?;
|
let d = UpowerBattery::from_device("BAT0")?;
|
||||||
let path = d.device_path.clone();
|
let path = d.device_path.clone();
|
||||||
let inner = d.inner.clone();
|
let inner = d.inner.clone();
|
||||||
@@ -175,7 +176,7 @@ impl UpowerBattery {
|
|||||||
inner.state = state;
|
inner.state = state;
|
||||||
inner.capacity = capacity;
|
inner.capacity = capacity;
|
||||||
inner.dirty = true;
|
inner.dirty = true;
|
||||||
listener.send(true).unwrap();
|
listener.send(Cmd::Draw).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use crate::buffer::Buffer;
|
|||||||
use crate::color::Color;
|
use crate::color::Color;
|
||||||
use crate::draw::{Font, ROBOTO_REGULAR};
|
use crate::draw::{Font, ROBOTO_REGULAR};
|
||||||
use crate::modules::module::{Input, ModuleImpl};
|
use crate::modules::module::{Input, ModuleImpl};
|
||||||
|
use crate::cmd::Cmd;
|
||||||
|
|
||||||
use std::sync::mpsc::Sender;
|
use std::sync::mpsc::Sender;
|
||||||
|
|
||||||
@@ -15,7 +16,7 @@ pub struct Clock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Clock {
|
impl Clock {
|
||||||
pub fn new(ch: Sender<bool>) -> Clock {
|
pub fn new(ch: Sender<Cmd>) -> Clock {
|
||||||
std::thread::spawn(move || loop {
|
std::thread::spawn(move || loop {
|
||||||
let n = Local::now();
|
let n = Local::now();
|
||||||
let target = (n + Duration::seconds(60))
|
let target = (n + Duration::seconds(60))
|
||||||
@@ -27,7 +28,7 @@ impl Clock {
|
|||||||
let d = target - n;
|
let d = target - n;
|
||||||
|
|
||||||
std::thread::sleep(d.to_std().unwrap());
|
std::thread::sleep(d.to_std().unwrap());
|
||||||
ch.send(true).unwrap();
|
ch.send(Cmd::Draw).unwrap();
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut date_cache = Font::new(&ROBOTO_REGULAR, 64.0);
|
let mut date_cache = Font::new(&ROBOTO_REGULAR, 64.0);
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ use crate::buffer::Buffer;
|
|||||||
use crate::color::Color;
|
use crate::color::Color;
|
||||||
use crate::draw::{Font, ROBOTO_REGULAR};
|
use crate::draw::{Font, ROBOTO_REGULAR};
|
||||||
use crate::modules::module::{Input, ModuleImpl};
|
use crate::modules::module::{Input, ModuleImpl};
|
||||||
|
use crate::cmd::Cmd;
|
||||||
|
|
||||||
|
use std::sync::mpsc::Sender;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
@@ -20,10 +22,11 @@ pub struct Launcher {
|
|||||||
offset: usize,
|
offset: usize,
|
||||||
font: RefCell<Font>,
|
font: RefCell<Font>,
|
||||||
dirty: bool,
|
dirty: bool,
|
||||||
|
tx: Sender<Cmd>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Launcher {
|
impl Launcher {
|
||||||
pub fn new() -> Result<Launcher, ::std::io::Error> {
|
pub fn new(listener: Sender<Cmd>) -> Result<Launcher, ::std::io::Error> {
|
||||||
if !atty::is(Stream::Stdin) {
|
if !atty::is(Stream::Stdin) {
|
||||||
let mut inbuf = String::new();
|
let mut inbuf = String::new();
|
||||||
std::io::stdin().read_to_string(&mut inbuf)?;
|
std::io::stdin().read_to_string(&mut inbuf)?;
|
||||||
@@ -42,6 +45,7 @@ impl Launcher {
|
|||||||
offset: 0,
|
offset: 0,
|
||||||
font: RefCell::new(Font::new(&ROBOTO_REGULAR, 32.0)),
|
font: RefCell::new(Font::new(&ROBOTO_REGULAR, 32.0)),
|
||||||
dirty: true,
|
dirty: true,
|
||||||
|
tx: listener,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Ok(Launcher {
|
Ok(Launcher {
|
||||||
@@ -52,6 +56,7 @@ impl Launcher {
|
|||||||
offset: 0,
|
offset: 0,
|
||||||
font: RefCell::new(Font::new(&ROBOTO_REGULAR, 32.0)),
|
font: RefCell::new(Font::new(&ROBOTO_REGULAR, 32.0)),
|
||||||
dirty: true,
|
dirty: true,
|
||||||
|
tx: listener,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -313,12 +318,12 @@ impl ModuleImpl for Launcher {
|
|||||||
},
|
},
|
||||||
Some('!') => {
|
Some('!') => {
|
||||||
println!("{}", self.input.chars().skip(1).collect::<String>());
|
println!("{}", self.input.chars().skip(1).collect::<String>());
|
||||||
std::process::exit(0);
|
self.tx.send(Cmd::Exit).unwrap();
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if self.matches.len() > self.offset {
|
if self.matches.len() > self.offset {
|
||||||
println!("{}", self.matches[self.offset]);
|
println!("{}", self.matches[self.offset]);
|
||||||
std::process::exit(0);
|
self.tx.send(Cmd::Exit).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use crate::buffer::Buffer;
|
|||||||
use crate::color::Color;
|
use crate::color::Color;
|
||||||
use crate::draw::{draw_bar, draw_box, Font, ROBOTO_REGULAR};
|
use crate::draw::{draw_bar, draw_box, Font, ROBOTO_REGULAR};
|
||||||
use crate::modules::module::{Input, ModuleImpl};
|
use crate::modules::module::{Input, ModuleImpl};
|
||||||
|
use crate::cmd::Cmd;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
@@ -404,7 +405,7 @@ pub struct PulseAudio {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PulseAudio {
|
impl PulseAudio {
|
||||||
pub fn new(listener: Sender<bool>) -> Result<PulseAudio, ::std::io::Error> {
|
pub fn new(listener: Sender<Cmd>) -> Result<PulseAudio, ::std::io::Error> {
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
let mut font = Font::new(&ROBOTO_REGULAR, 24.0);
|
let mut font = Font::new(&ROBOTO_REGULAR, 24.0);
|
||||||
font.add_str_to_cache("volume");
|
font.add_str_to_cache("volume");
|
||||||
@@ -419,7 +420,7 @@ impl PulseAudio {
|
|||||||
rx.recv().unwrap();
|
rx.recv().unwrap();
|
||||||
device.lock().unwrap().get_info().unwrap();
|
device.lock().unwrap().get_info().unwrap();
|
||||||
*(dirty.lock().unwrap()) = true;
|
*(dirty.lock().unwrap()) = true;
|
||||||
listener.send(true).unwrap();
|
listener.send(Cmd::Draw).unwrap();
|
||||||
});
|
});
|
||||||
Ok(pa)
|
Ok(pa)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user