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.
This commit is contained in:
+60
-42
@@ -21,6 +21,7 @@ use crate::widget::{DrawContext, Widget};
|
|||||||
use crate::cmd::Cmd;
|
use crate::cmd::Cmd;
|
||||||
use crate::doublemempool::DoubleMemPool;
|
use crate::doublemempool::DoubleMemPool;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum OutputMode {
|
pub enum OutputMode {
|
||||||
Active,
|
Active,
|
||||||
All,
|
All,
|
||||||
@@ -123,47 +124,49 @@ impl AppInner {
|
|||||||
|
|
||||||
self.configured_surfaces = Arc::new(Mutex::new(0));
|
self.configured_surfaces = Arc::new(Mutex::new(0));
|
||||||
|
|
||||||
if self.visible {
|
if !self.visible {
|
||||||
match self.output_mode {
|
self.surfaces = Vec::new();
|
||||||
OutputMode::Active => {
|
self.shell_surfaces = Vec::new();
|
||||||
if self.shell_surfaces.len() > 0 {
|
return;
|
||||||
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(
|
let (surface, shell_surface) = AppInner::add_shell_surface(
|
||||||
&compositor,
|
&compositor,
|
||||||
&shell,
|
&shell,
|
||||||
self.scale,
|
self.scale,
|
||||||
self.configured_surfaces.clone(),
|
self.configured_surfaces.clone(),
|
||||||
self.draw_tx.clone(),
|
self.draw_tx.clone(),
|
||||||
None,
|
Some(&output.1),
|
||||||
);
|
);
|
||||||
self.surfaces = vec![surface];
|
surfaces.push(surface);
|
||||||
self.shell_surfaces = vec![shell_surface];
|
shell_surfaces.push(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;
|
|
||||||
}
|
}
|
||||||
|
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) {
|
fn add_output(&mut self, id: u32, output: wl_output::WlOutput) {
|
||||||
@@ -210,7 +213,7 @@ pub struct App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl 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 {
|
let widget = match self.widget {
|
||||||
Some(ref mut widget) => widget,
|
Some(ref mut widget) => widget,
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
@@ -219,7 +222,9 @@ impl App {
|
|||||||
let inner = self.inner.lock().unwrap();
|
let inner = self.inner.lock().unwrap();
|
||||||
let time = Local::now();
|
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
|
// Not ready yet
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@@ -231,6 +236,7 @@ impl App {
|
|||||||
|
|
||||||
let size = widget.size();
|
let size = widget.size();
|
||||||
let size_changed = self.last_dim != size;
|
let size_changed = self.last_dim != size;
|
||||||
|
let force = force | size_changed;
|
||||||
|
|
||||||
// resize the pool if relevant
|
// resize the pool if relevant
|
||||||
pool.resize((4 * size.0 * size.1) as usize)
|
pool.resize((4 * size.0 * size.1) as usize)
|
||||||
@@ -239,8 +245,8 @@ impl App {
|
|||||||
let mut buf = Buffer::new(mmap, size);
|
let mut buf = Buffer::new(mmap, size);
|
||||||
|
|
||||||
// Copy old damage
|
// Copy old damage
|
||||||
if let Some(d) = &self.last_damage {
|
let force = match (force, &self.last_damage) {
|
||||||
if !size_changed {
|
(false, Some(d)) => {
|
||||||
let lastmmap = last.mmap();
|
let lastmmap = last.mmap();
|
||||||
let last = Buffer::new(lastmmap, size);
|
let last = Buffer::new(lastmmap, size);
|
||||||
|
|
||||||
@@ -250,12 +256,10 @@ impl App {
|
|||||||
for d in d {
|
for d in d {
|
||||||
last.copy_to(&mut buf, d.clone());
|
last.copy_to(&mut buf, d.clone());
|
||||||
}
|
}
|
||||||
} else {
|
false
|
||||||
force = true;
|
|
||||||
}
|
}
|
||||||
} else {
|
_ => true
|
||||||
force = true;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
if force {
|
if force {
|
||||||
buf.memset(&self.bg);
|
buf.memset(&self.bg);
|
||||||
@@ -272,8 +276,9 @@ impl App {
|
|||||||
|
|
||||||
mmap.flush().unwrap();
|
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
|
// Nothing to do
|
||||||
|
self.pools.never_mind();
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,6 +324,20 @@ impl App {
|
|||||||
inner.outputs_changed();
|
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<Mutex<VecDeque<Cmd>>> {
|
pub fn cmd_queue(&self) -> Arc<Mutex<VecDeque<Cmd>>> {
|
||||||
self.cmd_queue.clone()
|
self.cmd_queue.clone()
|
||||||
}
|
}
|
||||||
@@ -470,7 +489,6 @@ impl App {
|
|||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
||||||
inner.lock().unwrap().outputs_changed();
|
|
||||||
event_queue.sync_roundtrip().unwrap();
|
event_queue.sync_roundtrip().unwrap();
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ impl DoubleMemPool {
|
|||||||
pub fn pool(&mut self) -> Option<(&mut MemPool, &mut MemPool)> {
|
pub fn pool(&mut self) -> Option<(&mut MemPool, &mut MemPool)> {
|
||||||
let switch = self.switch;
|
let switch = self.switch;
|
||||||
self.switch = !self.switch;
|
self.switch = !self.switch;
|
||||||
let (last, cur) = if switch {
|
let (last, cur) = if !switch {
|
||||||
(&mut self.pool2, &mut self.pool1)
|
(&mut self.pool2, &mut self.pool1)
|
||||||
} else {
|
} else {
|
||||||
(&mut self.pool1, &mut self.pool2)
|
(&mut self.pool1, &mut self.pool2)
|
||||||
@@ -31,4 +31,8 @@ impl DoubleMemPool {
|
|||||||
Some((last, cur))
|
Some((last, cur))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn never_mind(&mut self) {
|
||||||
|
self.switch = !self.switch;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-3
@@ -25,6 +25,7 @@ use cmd::Cmd;
|
|||||||
|
|
||||||
enum Mode {
|
enum Mode {
|
||||||
Start,
|
Start,
|
||||||
|
Daemonize,
|
||||||
StartOrKill,
|
StartOrKill,
|
||||||
ToggleVisible,
|
ToggleVisible,
|
||||||
PrintConfig(bool),
|
PrintConfig(bool),
|
||||||
@@ -63,7 +64,7 @@ fn main() {
|
|||||||
let mode = match args.len() {
|
let mode = match args.len() {
|
||||||
1 => Mode::Start,
|
1 => Mode::Start,
|
||||||
2 => match args[1].as_str() {
|
2 => match args[1].as_str() {
|
||||||
"start" => Mode::Start,
|
"start" => Mode::Daemonize,
|
||||||
"start-or-kill" => Mode::StartOrKill,
|
"start-or-kill" => Mode::StartOrKill,
|
||||||
"toggle-visible" => Mode::ToggleVisible,
|
"toggle-visible" => Mode::ToggleVisible,
|
||||||
"print-config" => Mode::PrintConfig(!is_yaml),
|
"print-config" => Mode::PrintConfig(!is_yaml),
|
||||||
@@ -80,6 +81,8 @@ fn main() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut daemon = false;
|
||||||
|
|
||||||
match mode {
|
match mode {
|
||||||
Mode::ToggleVisible => {
|
Mode::ToggleVisible => {
|
||||||
if let Ok(mut socket) = UnixStream::connect(socket_path.clone()) {
|
if let Ok(mut socket) = UnixStream::connect(socket_path.clone()) {
|
||||||
@@ -101,6 +104,13 @@ fn main() {
|
|||||||
std::process::exit(1);
|
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) => {
|
Mode::PrintConfig(json) => {
|
||||||
if json {
|
if json {
|
||||||
println!("{}", serde_json::to_string_pretty(&config).unwrap());
|
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);
|
let mut app = App::new(tx_draw, output_mode, background, scale);
|
||||||
|
if daemon {
|
||||||
|
app.hide();
|
||||||
|
} else {
|
||||||
|
app.show();
|
||||||
|
}
|
||||||
let widget = mod_rx.recv().unwrap();
|
let widget = mod_rx.recv().unwrap();
|
||||||
app.set_widget(widget).unwrap();
|
app.set_widget(widget).unwrap();
|
||||||
|
|
||||||
@@ -224,10 +239,16 @@ fn main() {
|
|||||||
}
|
}
|
||||||
Cmd::ToggleVisible => {
|
Cmd::ToggleVisible => {
|
||||||
app.toggle_visible();
|
app.toggle_visible();
|
||||||
|
app.flush_display();
|
||||||
}
|
}
|
||||||
Cmd::Exit => {
|
Cmd::Exit => {
|
||||||
let _ = std::fs::remove_file(socket_path);
|
if daemon {
|
||||||
return;
|
app.hide();
|
||||||
|
app.flush_display();
|
||||||
|
} else {
|
||||||
|
let _ = std::fs::remove_file(socket_path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
|
|||||||
Reference in New Issue
Block a user