Skip to content

Commit

Permalink
only replace list items if necessary, derive hash for a bunch of enums
Browse files Browse the repository at this point in the history
clearscreen instead of cursive clear before pager yields better results
  • Loading branch information
mach-kernel committed Aug 13, 2023
1 parent a5b5922 commit 6733155
Show file tree
Hide file tree
Showing 13 changed files with 66 additions and 20 deletions.
29 changes: 29 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion launchk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ log = "0.4.20"
env_logger = "0.10.0"
notify-debouncer-mini = { version = "*", default-features = false }
sudo = "0.6.0"
clearscreen = "2.0.1"
clearscreen = "2.0.1"
git-version = "0.3.5"
2 changes: 1 addition & 1 deletion launchk/src/launchd/entry_status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ lazy_static! {
Mutex::new(HashMap::new());
}

#[derive(Debug, Clone, Eq, PartialEq)]
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct LaunchdEntryStatus {
pub plist: Option<LaunchdPlist>,
pub limit_load_to_session_type: SessionType,
Expand Down
2 changes: 1 addition & 1 deletion launchk/src/launchd/job_type_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::fmt;
use std::fmt::Formatter;

bitflags! {
#[derive(Clone, Copy, Default, Eq, PartialEq)]
#[derive(Clone, Copy, Default, Eq, PartialEq, Hash)]
/// Bitmask for filtering on the job type, which is a mix
/// of scope (where it's located), and kind (agent v. daemon)
pub struct JobTypeFilter: u32 {
Expand Down
6 changes: 3 additions & 3 deletions launchk/src/launchd/plist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ od -xc binary.plist
*/
static PLIST_MAGIC: &str = "bplist00";

#[derive(Debug, Clone, Eq, PartialEq)]
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub enum LaunchdEntryType {
/// Runs on behalf of currently logged in user
Agent,
Expand All @@ -46,7 +46,7 @@ impl fmt::Display for LaunchdEntryType {
}
}

#[derive(Debug, Clone, Eq, PartialEq)]
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub enum LaunchdEntryLocation {
/// macOS system provided agent or daemon
System,
Expand All @@ -64,7 +64,7 @@ impl fmt::Display for LaunchdEntryLocation {
}
}

#[derive(Debug, Clone, Eq, PartialEq)]
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct LaunchdPlist {
pub entry_type: LaunchdEntryType,
pub entry_location: LaunchdEntryLocation,
Expand Down
3 changes: 2 additions & 1 deletion launchk/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ extern crate plist;

use cursive::view::Resizable;
use cursive::views::{NamedView, Panel};
use git_version::git_version;
use std::process::exit;

use crate::launchd::plist::{init_plist_map, PLIST_MAP_INIT};
Expand Down Expand Up @@ -38,7 +39,7 @@ fn main() {
let root_layout = NamedView::new("root_layout", root_layout);

let panel = Panel::new(root_layout)
.title("launchk")
.title(format!("launchk ({})", git_version!()))
.full_width()
.full_height();

Expand Down
2 changes: 1 addition & 1 deletion launchk/src/tui/dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ pub fn show_csr_info() -> CbSinkMessage {
pub fn show_help() -> CbSinkMessage {
let commands = OMNIBOX_COMMANDS
.iter()
.map(|(cmd, desc, _)| format!("{}: {}", cmd, desc))
.map(|(cmd, desc, _)| format!("{:<15}: {}", cmd, desc.chars().filter(|c| c.is_ascii()).collect::<String>()))
.collect::<Vec<String>>();

Box::new(move |siv| {
Expand Down
2 changes: 1 addition & 1 deletion launchk/src/tui/omnibox/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,5 @@ pub static OMNIBOX_COMMANDS: [(&str, &str, OmniboxCommand); 12] = [
OmniboxCommand::ProcInfo,
),
("help", "🤔 Show all commands", OmniboxCommand::Help),
("exit", "🚪 see ya!", OmniboxCommand::Quit),
("exit", "🚪 see ya!", OmniboxCommand::Quit),
];
5 changes: 2 additions & 3 deletions launchk/src/tui/pager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@ use std::sync::mpsc::Sender;

use super::root::CbSinkMessage;
use cursive::Cursive;
use clearscreen;

lazy_static! {
static ref PAGER: String = env::var("PAGER").unwrap_or("less".to_string());
}

/// Show $PAGER (or less), write buf, and clear Cursive after exiting
pub fn show_pager(cbsink: &Sender<CbSinkMessage>, buf: &[u8]) -> Result<(), String> {
cbsink
.send(Box::new(Cursive::clear))
.expect("Must clear before");
clearscreen::clear().expect("Must clear screen");

let mut pager = Command::new(&*PAGER)
.stdin(Stdio::piped())
Expand Down
2 changes: 1 addition & 1 deletion launchk/src/tui/service_list/list_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::launchd::entry_status::LaunchdEntryStatus;
use crate::launchd::job_type_filter::JobTypeFilter;
use crate::tui::table::table_list_view::TableListItem;

#[derive(Debug, Clone)]
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct ServiceListItem {
pub name: String,
pub status: LaunchdEntryStatus,
Expand Down
18 changes: 17 additions & 1 deletion launchk/src/tui/table/table_list_view.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use std::cell::RefCell;
use std::hash::{Hash, Hasher};
use std::marker::PhantomData;
use std::rc::Rc;

use std::sync::Arc;
use std::collections::hash_map::DefaultHasher;

use cursive::event::{Event, EventResult};
use cursive::traits::{Resizable, Scrollable};
Expand All @@ -23,6 +26,7 @@ pub struct TableListView<T> {
linear_layout: LinearLayout,
// LinearLayout swallows T from , but we still need it
inner: PhantomData<T>,
last_hash: RefCell<u64>
}

impl<T: 'static + TableListItem> TableListView<T> {
Expand All @@ -36,6 +40,7 @@ impl<T: 'static + TableListItem> TableListView<T> {
.into_iter()
.map(|(n, _)| n.as_ref().to_string());
let column_sizer = ColumnSizer::new(columns);
let last_hash = RefCell::new(0u64);

let mut linear_layout = LinearLayout::vertical();
linear_layout.add_child(
Expand All @@ -49,16 +54,19 @@ impl<T: 'static + TableListItem> TableListView<T> {
.full_height()
.scrollable(),
);

Self {
linear_layout,
column_sizer,
inner: PhantomData::default(),
last_hash
}
}

pub fn replace_and_preserve_selection<I>(&mut self, items: I)
where
I: IntoIterator<Item = T>,
T: Hash
{
let rows: Vec<(String, T)> = items
.into_iter()
Expand All @@ -80,9 +88,17 @@ impl<T: 'static + TableListItem> TableListView<T> {
})
.collect();

let mut row_hasher = DefaultHasher::new();
rows.hash(&mut row_hasher);
let hash = row_hasher.finish();

if *self.last_hash.borrow() == hash { return }
log::trace!("Replaced listview items -- new hash {}", hash);
*self.last_hash.borrow_mut() = hash;

let sv = self.get_mut_selectview();
let current_selection = sv.selected_id().unwrap_or(0);

sv.clear();
sv.add_all(rows);
sv.set_selection(current_selection);
Expand Down
4 changes: 2 additions & 2 deletions xpc-sys/src/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::traits::xpc_value::TryXPCValue;

/// LimitLoadToSessionType key in XPC response
/// https://developer.apple.com/library/archive/technotes/tn2083/_index.html
#[derive(Debug, Clone, Eq, PartialEq)]
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub enum SessionType {
Aqua = 0,
StandardIO,
Expand Down Expand Up @@ -70,7 +70,7 @@ impl TryFrom<Arc<XPCObject>> for SessionType {
}

// Huge thanks to: https://saelo.github.io/presentations/bits_of_launchd.pdf
#[derive(Debug, Clone, Eq, PartialEq)]
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub enum DomainType {
System = 1,
User = 2,
Expand Down
8 changes: 4 additions & 4 deletions xpc-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ pub mod traits;

pub type xpc_pipe_t = *mut c_void;

/// Some extra private API definitions. Thanks:
///
/// https://developer.apple.com/documentation/kernel/mach
/// https://chromium.googlesource.com/chromium/src.git/+/47.0.2507.2/sandbox/mac/xpc_private_stubs.sig
// Some extra private API definitions. Thanks:
//
// https://developer.apple.com/documentation/kernel/mach
// https://chromium.googlesource.com/chromium/src.git/+/47.0.2507.2/sandbox/mac/xpc_private_stubs.sig
extern "C" {
// Can decode i64 returned in "errors" for XPC responses
pub fn xpc_strerror(err: c_int) -> *const c_char;
Expand Down

0 comments on commit 6733155

Please sign in to comment.