state: cull redraws of floating notifications
Cull redraws by keeping track of whether the floating box has been initialised and whether its area has been drawn over by other dirty areas.jmap-eventsource
parent
4c1a9b2485
commit
393c5d0d53
68
src/state.rs
68
src/state.rs
|
@ -190,7 +190,10 @@ pub struct State {
|
||||||
display_messages: SmallVec<[DisplayMessage; 8]>,
|
display_messages: SmallVec<[DisplayMessage; 8]>,
|
||||||
display_messages_expiration_start: Option<UnixTimestamp>,
|
display_messages_expiration_start: Option<UnixTimestamp>,
|
||||||
display_messages_active: bool,
|
display_messages_active: bool,
|
||||||
|
display_messages_dirty: bool,
|
||||||
|
display_messages_initialised: bool,
|
||||||
display_messages_pos: usize,
|
display_messages_pos: usize,
|
||||||
|
display_messages_area: Area,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -335,7 +338,9 @@ impl State {
|
||||||
display_messages_expiration_start: None,
|
display_messages_expiration_start: None,
|
||||||
display_messages_pos: 0,
|
display_messages_pos: 0,
|
||||||
display_messages_active: false,
|
display_messages_active: false,
|
||||||
|
display_messages_dirty: false,
|
||||||
|
display_messages_initialised: false,
|
||||||
|
display_messages_area: ((0, 0), (0, 0)),
|
||||||
context: Context {
|
context: Context {
|
||||||
accounts,
|
accounts,
|
||||||
settings: settings.clone(),
|
settings: settings.clone(),
|
||||||
|
@ -522,6 +527,9 @@ impl State {
|
||||||
.resize(self.cols, self.rows, Cell::with_char(' '));
|
.resize(self.cols, self.rows, Cell::with_char(' '));
|
||||||
|
|
||||||
self.rcv_event(UIEvent::Resize);
|
self.rcv_event(UIEvent::Resize);
|
||||||
|
self.display_messages_dirty = true;
|
||||||
|
self.display_messages_initialised = false;
|
||||||
|
self.display_messages_area = ((0, 0), (0, 0));
|
||||||
|
|
||||||
// Invalidate dirty areas.
|
// Invalidate dirty areas.
|
||||||
self.context.dirty_areas.clear();
|
self.context.dirty_areas.clear();
|
||||||
|
@ -546,6 +554,8 @@ impl State {
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
{
|
{
|
||||||
self.display_messages_active = false;
|
self.display_messages_active = false;
|
||||||
|
self.display_messages_dirty = true;
|
||||||
|
self.display_messages_initialised = false;
|
||||||
self.display_messages_expiration_start = None;
|
self.display_messages_expiration_start = None;
|
||||||
areas.push((
|
areas.push((
|
||||||
(0, 0),
|
(0, 0),
|
||||||
|
@ -556,6 +566,18 @@ impl State {
|
||||||
|
|
||||||
/* Sort by x_start, ie upper_left corner's x coordinate */
|
/* Sort by x_start, ie upper_left corner's x coordinate */
|
||||||
areas.sort_by(|a, b| (a.0).0.partial_cmp(&(b.0).0).unwrap());
|
areas.sort_by(|a, b| (a.0).0.partial_cmp(&(b.0).0).unwrap());
|
||||||
|
|
||||||
|
if self.display_messages_active {
|
||||||
|
/* Check if any dirty area intersects with the area occupied by floating notification
|
||||||
|
* box */
|
||||||
|
let (displ_top, displ_bot) = self.display_messages_area;
|
||||||
|
for &((top_x, top_y), (bottom_x, bottom_y)) in &areas {
|
||||||
|
self.display_messages_dirty |= !(bottom_y < displ_top.1
|
||||||
|
|| displ_bot.1 < top_y
|
||||||
|
|| bottom_x < displ_top.0
|
||||||
|
|| displ_bot.0 < top_x);
|
||||||
|
}
|
||||||
|
}
|
||||||
/* draw each dirty area */
|
/* draw each dirty area */
|
||||||
let rows = self.rows;
|
let rows = self.rows;
|
||||||
for y in 0..rows {
|
for y in 0..rows {
|
||||||
|
@ -613,13 +635,27 @@ impl State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.display_messages_active {
|
if self.display_messages_dirty && self.display_messages_active {
|
||||||
if let Some(DisplayMessage {
|
if let Some(DisplayMessage {
|
||||||
ref timestamp,
|
ref timestamp,
|
||||||
ref msg,
|
ref msg,
|
||||||
..
|
..
|
||||||
}) = self.display_messages.get(self.display_messages_pos)
|
}) = self.display_messages.get(self.display_messages_pos)
|
||||||
{
|
{
|
||||||
|
if !self.display_messages_initialised {
|
||||||
|
{
|
||||||
|
/* Clear area previously occupied by floating notification box */
|
||||||
|
let displ_area = self.display_messages_area;
|
||||||
|
for y in get_y(upper_left!(displ_area))..=get_y(bottom_right!(displ_area)) {
|
||||||
|
(self.draw_horizontal_segment_fn)(
|
||||||
|
&mut self.grid,
|
||||||
|
self.stdout.as_mut().unwrap(),
|
||||||
|
get_x(upper_left!(displ_area)),
|
||||||
|
get_x(bottom_right!(displ_area)),
|
||||||
|
y,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
let noto_colors = crate::conf::value(&self.context, "status.notification");
|
let noto_colors = crate::conf::value(&self.context, "status.notification");
|
||||||
use crate::melib::text_processing::{Reflow, TextProcessing};
|
use crate::melib::text_processing::{Reflow, TextProcessing};
|
||||||
|
|
||||||
|
@ -684,16 +720,34 @@ impl State {
|
||||||
Some(x),
|
Some(x),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
for y in get_y(upper_left!(displ_area))..=get_y(bottom_right!(displ_area)) {
|
self.display_messages_area = displ_area;
|
||||||
|
}
|
||||||
|
for y in get_y(upper_left!(self.display_messages_area))
|
||||||
|
..=get_y(bottom_right!(self.display_messages_area))
|
||||||
|
{
|
||||||
(self.draw_horizontal_segment_fn)(
|
(self.draw_horizontal_segment_fn)(
|
||||||
&mut self.overlay_grid,
|
&mut self.overlay_grid,
|
||||||
self.stdout.as_mut().unwrap(),
|
self.stdout.as_mut().unwrap(),
|
||||||
|
get_x(upper_left!(self.display_messages_area)),
|
||||||
|
get_x(bottom_right!(self.display_messages_area)),
|
||||||
|
y,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.display_messages_dirty = false;
|
||||||
|
} else if self.display_messages_dirty {
|
||||||
|
/* Clear area previously occupied by floating notification box */
|
||||||
|
let displ_area = self.display_messages_area;
|
||||||
|
for y in get_y(upper_left!(displ_area))..=get_y(bottom_right!(displ_area)) {
|
||||||
|
(self.draw_horizontal_segment_fn)(
|
||||||
|
&mut self.grid,
|
||||||
|
self.stdout.as_mut().unwrap(),
|
||||||
get_x(upper_left!(displ_area)),
|
get_x(upper_left!(displ_area)),
|
||||||
get_x(bottom_right!(displ_area)),
|
get_x(bottom_right!(displ_area)),
|
||||||
y,
|
y,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
self.display_messages_dirty = false;
|
||||||
}
|
}
|
||||||
if !self.overlay.is_empty() {
|
if !self.overlay.is_empty() {
|
||||||
let area = center_area(
|
let area = center_area(
|
||||||
|
@ -1092,12 +1146,16 @@ impl State {
|
||||||
UIEvent::Input(Key::Alt('<')) => {
|
UIEvent::Input(Key::Alt('<')) => {
|
||||||
self.display_messages_expiration_start = Some(melib::datetime::now());
|
self.display_messages_expiration_start = Some(melib::datetime::now());
|
||||||
self.display_messages_active = true;
|
self.display_messages_active = true;
|
||||||
|
self.display_messages_initialised = false;
|
||||||
|
self.display_messages_dirty = true;
|
||||||
self.display_messages_pos = self.display_messages_pos.saturating_sub(1);
|
self.display_messages_pos = self.display_messages_pos.saturating_sub(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
UIEvent::Input(Key::Alt('>')) => {
|
UIEvent::Input(Key::Alt('>')) => {
|
||||||
self.display_messages_expiration_start = Some(melib::datetime::now());
|
self.display_messages_expiration_start = Some(melib::datetime::now());
|
||||||
self.display_messages_active = true;
|
self.display_messages_active = true;
|
||||||
|
self.display_messages_initialised = false;
|
||||||
|
self.display_messages_dirty = true;
|
||||||
self.display_messages_pos = std::cmp::min(
|
self.display_messages_pos = std::cmp::min(
|
||||||
self.display_messages.len().saturating_sub(1),
|
self.display_messages.len().saturating_sub(1),
|
||||||
self.display_messages_pos + 1,
|
self.display_messages_pos + 1,
|
||||||
|
@ -1110,6 +1168,8 @@ impl State {
|
||||||
msg: msg.clone(),
|
msg: msg.clone(),
|
||||||
});
|
});
|
||||||
self.display_messages_active = true;
|
self.display_messages_active = true;
|
||||||
|
self.display_messages_initialised = false;
|
||||||
|
self.display_messages_dirty = true;
|
||||||
self.display_messages_expiration_start = None;
|
self.display_messages_expiration_start = None;
|
||||||
self.display_messages_pos = self.display_messages.len() - 1;
|
self.display_messages_pos = self.display_messages.len() - 1;
|
||||||
self.redraw();
|
self.redraw();
|
||||||
|
|
Loading…
Reference in New Issue