From 4ca4fa307a75e2cfc763b6e999ce3ed504affbac Mon Sep 17 00:00:00 2001 From: Kenny Levinsen Date: Tue, 17 Sep 2019 16:32:51 +0200 Subject: [PATCH] Fix various toggle-visible issues - Track "start" command internally as a special mode. - Ensure that DoubleMemPool is in good state if draw bails. - Ensure that Launcher does not terminate daemonized session. - Ensure that size changes cause full force redraw. --- src/app.rs | 102 +++++++++++++++++++++++++------------------ src/doublemempool.rs | 6 ++- src/main.rs | 27 ++++++++++-- 3 files changed, 89 insertions(+), 46 deletions(-) diff --git a/src/app.rs b/src/app.rs index 9438519..c8dc414 100644 --- a/src/app.rs +++ b/src/app.rs @@ -21,6 +21,7 @@ use crate::widget::{DrawContext, Widget}; use crate::cmd::Cmd; use crate::doublemempool::DoubleMemPool; +#[derive(Debug)] pub enum OutputMode { Active, All, @@ -123,47 +124,49 @@ impl AppInner { self.configured_surfaces = Arc::new(Mutex::new(0)); - if self.visible { - match self.output_mode { - OutputMode::Active => { - if self.shell_surfaces.len() > 0 { - return; - } + if !self.visible { + self.surfaces = Vec::new(); + self.shell_surfaces = Vec::new(); + return; + } + + match self.output_mode { + OutputMode::Active => { + if self.shell_surfaces.len() > 0 { + return; + } + + let (surface, shell_surface) = AppInner::add_shell_surface( + &compositor, + &shell, + self.scale, + self.configured_surfaces.clone(), + self.draw_tx.clone(), + None, + ); + self.surfaces = vec![surface]; + self.shell_surfaces = vec![shell_surface]; + } + 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.scale, self.configured_surfaces.clone(), self.draw_tx.clone(), - None, + Some(&output.1), ); - self.surfaces = vec![surface]; - self.shell_surfaces = vec![shell_surface]; - } - 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.scale, - 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; + 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(); } + self.draw_tx.send(Cmd::ForceDraw).unwrap(); } fn add_output(&mut self, id: u32, output: wl_output::WlOutput) { @@ -210,7 +213,7 @@ pub struct App { } impl App { - pub fn redraw(&mut self, mut force: bool) -> Result<(), ::std::io::Error> { + pub fn redraw(&mut self, force: bool) -> Result<(), ::std::io::Error> { let widget = match self.widget { Some(ref mut widget) => widget, None => return Ok(()), @@ -219,7 +222,9 @@ impl App { let inner = self.inner.lock().unwrap(); let time = Local::now(); - if inner.shell_surfaces.len() != *inner.configured_surfaces.lock().unwrap() { + if !inner.visible || + inner.shell_surfaces.len() != *inner.configured_surfaces.lock().unwrap() || + inner.surfaces.len() == 0 { // Not ready yet return Ok(()); } @@ -231,6 +236,7 @@ impl App { let size = widget.size(); let size_changed = self.last_dim != size; + let force = force | size_changed; // resize the pool if relevant pool.resize((4 * size.0 * size.1) as usize) @@ -239,8 +245,8 @@ impl App { let mut buf = Buffer::new(mmap, size); // Copy old damage - if let Some(d) = &self.last_damage { - if !size_changed { + let force = match (force, &self.last_damage) { + (false, Some(d)) => { let lastmmap = last.mmap(); let last = Buffer::new(lastmmap, size); @@ -250,12 +256,10 @@ impl App { for d in d { last.copy_to(&mut buf, d.clone()); } - } else { - force = true; + false } - } else { - force = true; - } + _ => true + }; if force { buf.memset(&self.bg); @@ -272,8 +276,9 @@ impl App { mmap.flush().unwrap(); - if !size_changed && !report.full_damage && report.damage.len() == 0 { + if !force && !report.full_damage && report.damage.len() == 0 { // Nothing to do + self.pools.never_mind(); return Ok(()); } @@ -319,6 +324,20 @@ impl App { inner.outputs_changed(); } + pub fn hide(&mut self) { + let mut inner = self.inner.lock().unwrap(); + inner.visible = false; + self.last_dim = (0, 0); + inner.outputs_changed(); + } + + pub fn show(&mut self) { + let mut inner = self.inner.lock().unwrap(); + inner.visible = true; + self.last_dim = (0, 0); + inner.outputs_changed(); + } + pub fn cmd_queue(&self) -> Arc>> { self.cmd_queue.clone() } @@ -470,7 +489,6 @@ impl App { }, )); - inner.lock().unwrap().outputs_changed(); event_queue.sync_roundtrip().unwrap(); // diff --git a/src/doublemempool.rs b/src/doublemempool.rs index 990f863..f2e9cd6 100644 --- a/src/doublemempool.rs +++ b/src/doublemempool.rs @@ -19,7 +19,7 @@ impl DoubleMemPool { pub fn pool(&mut self) -> Option<(&mut MemPool, &mut MemPool)> { let switch = self.switch; self.switch = !self.switch; - let (last, cur) = if switch { + let (last, cur) = if !switch { (&mut self.pool2, &mut self.pool1) } else { (&mut self.pool1, &mut self.pool2) @@ -31,4 +31,8 @@ impl DoubleMemPool { Some((last, cur)) } } + + pub fn never_mind(&mut self) { + self.switch = !self.switch; + } } diff --git a/src/main.rs b/src/main.rs index 4d70427..ea011e1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,6 +25,7 @@ use cmd::Cmd; enum Mode { Start, + Daemonize, StartOrKill, ToggleVisible, PrintConfig(bool), @@ -63,7 +64,7 @@ fn main() { let mode = match args.len() { 1 => Mode::Start, 2 => match args[1].as_str() { - "start" => Mode::Start, + "start" => Mode::Daemonize, "start-or-kill" => Mode::StartOrKill, "toggle-visible" => Mode::ToggleVisible, "print-config" => Mode::PrintConfig(!is_yaml), @@ -80,6 +81,8 @@ fn main() { } }; + let mut daemon = false; + match mode { Mode::ToggleVisible => { if let Ok(mut socket) = UnixStream::connect(socket_path.clone()) { @@ -101,6 +104,13 @@ fn main() { std::process::exit(1); }; } + Mode::Daemonize => { + if let Ok(_) = UnixStream::connect(socket_path.clone()) { + eprintln!("wldash is already running"); + std::process::exit(1); + }; + daemon = true; + } Mode::PrintConfig(json) => { if json { println!("{}", serde_json::to_string_pretty(&config).unwrap()); @@ -133,6 +143,11 @@ fn main() { }); let mut app = App::new(tx_draw, output_mode, background, scale); + if daemon { + app.hide(); + } else { + app.show(); + } let widget = mod_rx.recv().unwrap(); app.set_widget(widget).unwrap(); @@ -224,10 +239,16 @@ fn main() { } Cmd::ToggleVisible => { app.toggle_visible(); + app.flush_display(); } Cmd::Exit => { - let _ = std::fs::remove_file(socket_path); - return; + if daemon { + app.hide(); + app.flush_display(); + } else { + let _ = std::fs::remove_file(socket_path); + return; + } } }, None => {