ui: avoid full renders when worker threads return StartupChecks
Now listings only re-render when their folder gets a StartupCheck event, account menu always re-renders to update new mail counts closes #76embed
parent
d19bda8977
commit
551db51b00
|
@ -121,7 +121,7 @@ impl RefreshEventConsumer {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct NotifyFn(Box<Fn() -> ()>);
|
||||
pub struct NotifyFn(Box<Fn(FolderHash) -> ()>);
|
||||
unsafe impl Send for NotifyFn {}
|
||||
unsafe impl Sync for NotifyFn {}
|
||||
|
||||
|
@ -131,18 +131,18 @@ impl fmt::Debug for NotifyFn {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<Box<Fn() -> ()>> for NotifyFn {
|
||||
fn from(kind: Box<Fn() -> ()>) -> Self {
|
||||
impl From<Box<Fn(FolderHash) -> ()>> for NotifyFn {
|
||||
fn from(kind: Box<Fn(FolderHash) -> ()>) -> Self {
|
||||
NotifyFn(kind)
|
||||
}
|
||||
}
|
||||
|
||||
impl NotifyFn {
|
||||
pub fn new(b: Box<Fn() -> ()>) -> Self {
|
||||
pub fn new(b: Box<Fn(FolderHash) -> ()>) -> Self {
|
||||
NotifyFn(b)
|
||||
}
|
||||
pub fn notify(&self) {
|
||||
self.0();
|
||||
pub fn notify(&self, f: FolderHash) {
|
||||
self.0(f);
|
||||
}
|
||||
}
|
||||
pub trait MailBackend: ::std::fmt::Debug {
|
||||
|
|
18
src/bin.rs
18
src/bin.rs
|
@ -171,24 +171,6 @@ fn main() {
|
|||
break 'inner; // `goto` 'reap loop, and wait on child.
|
||||
}
|
||||
}
|
||||
ThreadEvent::UIEvent(UIEventType::StartupCheck) => {
|
||||
let mut render_flag = false;
|
||||
for idx_a in 0..state.context.accounts.len() {
|
||||
let len = state.context.accounts[idx_a].len();
|
||||
for idx_m in 0..len {
|
||||
|
||||
match state.context.account_status(idx_a, idx_m) {
|
||||
Ok(_) => {
|
||||
render_flag = true;
|
||||
},
|
||||
Err(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
if render_flag {
|
||||
state.render();
|
||||
}
|
||||
}
|
||||
ThreadEvent::UIEvent(e) => {
|
||||
state.rcv_event(UIEvent { id: 0, event_type: e});
|
||||
state.render();
|
||||
|
|
|
@ -247,9 +247,7 @@ impl Component for AccountMenu {
|
|||
}
|
||||
clear_area(grid, area);
|
||||
let upper_left = upper_left!(area);
|
||||
let x = get_x(upper_left);
|
||||
let bottom_right = bottom_right!(area);
|
||||
let x_max = get_x(bottom_right);
|
||||
self.dirty = false;
|
||||
let mut y = get_y(upper_left);
|
||||
for a in &self.accounts {
|
||||
|
@ -275,6 +273,9 @@ impl Component for AccountMenu {
|
|||
self.visible = !self.visible;
|
||||
self.dirty = true;
|
||||
}
|
||||
UIEventType::StartupCheck(_) => {
|
||||
self.dirty = true;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
false
|
||||
|
|
|
@ -479,11 +479,13 @@ impl Component for CompactListing {
|
|||
self.view = None;
|
||||
self.dirty = true;
|
||||
}
|
||||
UIEventType::MailboxUpdate((ref idxa, ref idxf)) => {
|
||||
if *idxa == self.new_cursor_pos.0 && *idxf == self.new_cursor_pos.1 {
|
||||
self.refresh_mailbox(context);
|
||||
self.set_dirty();
|
||||
}
|
||||
UIEventType::MailboxUpdate((ref idxa, ref idxf)) if *idxa == self.new_cursor_pos.0 && *idxf == self.new_cursor_pos.1 => {
|
||||
self.refresh_mailbox(context);
|
||||
self.set_dirty();
|
||||
}
|
||||
UIEventType::StartupCheck(ref f) if context.mailbox_hashes[f] == (self.new_cursor_pos.0, self.new_cursor_pos.1) => {
|
||||
self.refresh_mailbox(context);
|
||||
self.set_dirty();
|
||||
}
|
||||
UIEventType::ChangeMode(UIMode::Normal) => {
|
||||
self.dirty = true;
|
||||
|
|
|
@ -512,11 +512,13 @@ impl Component for PlainListing {
|
|||
self.dirty = true;
|
||||
self.view = None;
|
||||
}
|
||||
UIEventType::MailboxUpdate((ref idxa, ref idxf)) => {
|
||||
if *idxa == self.new_cursor_pos.0 && *idxf == self.new_cursor_pos.1 {
|
||||
self.dirty = true;
|
||||
self.refresh_mailbox(context);
|
||||
}
|
||||
UIEventType::MailboxUpdate((ref idxa, ref idxf)) if *idxa == self.new_cursor_pos.0 && *idxf == self.new_cursor_pos.1 => {
|
||||
self.refresh_mailbox(context);
|
||||
self.set_dirty();
|
||||
}
|
||||
UIEventType::StartupCheck(ref f) if context.mailbox_hashes[f] == (self.new_cursor_pos.0, self.new_cursor_pos.1) => {
|
||||
self.refresh_mailbox(context);
|
||||
self.set_dirty();
|
||||
}
|
||||
UIEventType::ChangeMode(UIMode::Normal) => {
|
||||
self.dirty = true;
|
||||
|
|
|
@ -651,14 +651,13 @@ impl Component for ThreadListing {
|
|||
self.dirty = true;
|
||||
self.view = None;
|
||||
}
|
||||
UIEventType::MailboxUpdate((ref idxa, ref idxf)) => {
|
||||
if *idxa == self.new_cursor_pos.0 && *idxf == self.new_cursor_pos.1 {
|
||||
self.dirty = true;
|
||||
self.refresh_mailbox(context);
|
||||
if cfg!(feature = "debug_log") {
|
||||
eprintln!("mailboxupdate");
|
||||
}
|
||||
}
|
||||
UIEventType::MailboxUpdate((ref idxa, ref idxf)) if *idxa == self.new_cursor_pos.0 && *idxf == self.new_cursor_pos.1 => {
|
||||
self.refresh_mailbox(context);
|
||||
self.set_dirty();
|
||||
}
|
||||
UIEventType::StartupCheck(ref f) if context.mailbox_hashes[f] == (self.new_cursor_pos.0, self.new_cursor_pos.1) => {
|
||||
self.refresh_mailbox(context);
|
||||
self.set_dirty();
|
||||
}
|
||||
UIEventType::ChangeMode(UIMode::Normal) => {
|
||||
self.dirty = true;
|
||||
|
|
|
@ -140,9 +140,10 @@ impl Account {
|
|||
work.compute();
|
||||
handle.join();
|
||||
let envelopes = handle.extract();
|
||||
let hash = folder.hash();
|
||||
let ret = Mailbox::new(folder, envelopes);
|
||||
tx.send(AsyncStatus::Payload(ret));
|
||||
notify_fn.notify();
|
||||
notify_fn.notify(hash);
|
||||
})))
|
||||
}
|
||||
pub fn reload(&mut self, event: RefreshEvent, idx: usize) -> Option<UIEventType> {
|
||||
|
|
|
@ -75,7 +75,7 @@ impl InputHandler {
|
|||
/// A context container for loaded settings, accounts, UI changes, etc.
|
||||
pub struct Context {
|
||||
pub accounts: Vec<Account>,
|
||||
mailbox_hashes: FnvHashMap<FolderHash, (usize, usize)>,
|
||||
pub mailbox_hashes: FnvHashMap<FolderHash, (usize, usize)>,
|
||||
pub settings: Settings,
|
||||
|
||||
pub runtime_settings: Settings,
|
||||
|
@ -185,8 +185,8 @@ impl State {
|
|||
n.to_string(),
|
||||
a_s.clone(),
|
||||
&backends,
|
||||
NotifyFn::new(Box::new(move || {
|
||||
sender.send(ThreadEvent::UIEvent(UIEventType::StartupCheck))
|
||||
NotifyFn::new(Box::new(move |f: FolderHash| {
|
||||
sender.send(ThreadEvent::UIEvent(UIEventType::StartupCheck(f)))
|
||||
})),
|
||||
)
|
||||
})
|
||||
|
@ -279,7 +279,7 @@ impl State {
|
|||
if let Some(notification) = self.context.accounts[idxa].reload(event, idxm) {
|
||||
self.context
|
||||
.sender
|
||||
.send(ThreadEvent::UIEvent(UIEventType::StartupCheck));
|
||||
.send(ThreadEvent::UIEvent(UIEventType::StartupCheck(hash)));
|
||||
self.context.replies.push_back(UIEvent {
|
||||
id: 0,
|
||||
event_type: notification,
|
||||
|
|
|
@ -27,6 +27,7 @@ use super::execute::Action;
|
|||
use super::terminal::*;
|
||||
|
||||
use melib::RefreshEvent;
|
||||
use melib::backends::FolderHash;
|
||||
use std;
|
||||
use std::fmt;
|
||||
use std::thread;
|
||||
|
@ -83,7 +84,7 @@ pub enum UIEventType {
|
|||
StatusEvent(StatusEvent),
|
||||
MailboxUpdate((usize, usize)), // (account_idx, mailbox_idx)
|
||||
EntityKill(Uuid),
|
||||
StartupCheck,
|
||||
StartupCheck(FolderHash),
|
||||
RefreshEvent(Box<RefreshEvent>),
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue