mirror of
https://github.com/kunkunsh/kunkun-ext-neohtop.git
synced 2025-04-11 17:29:45 +00:00
show username and id
This commit is contained in:
parent
519021e67e
commit
3e6f153bbe
11
src-tauri/Cargo.lock
generated
11
src-tauri/Cargo.lock
generated
@ -1712,6 +1712,7 @@ dependencies = [
|
|||||||
"tauri",
|
"tauri",
|
||||||
"tauri-build",
|
"tauri-build",
|
||||||
"tauri-plugin-shell",
|
"tauri-plugin-shell",
|
||||||
|
"users",
|
||||||
"windows 0.48.0",
|
"windows 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -3796,6 +3797,16 @@ dependencies = [
|
|||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "users"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "24cc0f6d6f267b73e5a2cadf007ba8f9bc39c6a6f9666f8cf25ea809a153b032"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "utf-8"
|
name = "utf-8"
|
||||||
version = "0.7.6"
|
version = "0.7.6"
|
||||||
|
@ -24,6 +24,7 @@ serde = { version = "1", features = ["derive"] }
|
|||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
sysinfo = "0.29.0"
|
sysinfo = "0.29.0"
|
||||||
base64 = "0.21"
|
base64 = "0.21"
|
||||||
|
users = "0.11"
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
cocoa = "0.25"
|
cocoa = "0.25"
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
use sysinfo::{CpuExt, SystemExt, ProcessExt, System, PidExt, ProcessStatus};
|
use sysinfo::{CpuExt, SystemExt, ProcessExt, System, PidExt, ProcessStatus};
|
||||||
use tauri::State;
|
use tauri::State;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
use users::{Users, UsersCache};
|
||||||
|
|
||||||
struct AppState {
|
struct AppState {
|
||||||
sys: Mutex<System>,
|
sys: Mutex<System>,
|
||||||
@ -35,33 +36,30 @@ async fn get_processes(state: State<'_, AppState>) -> Result<Vec<ProcessInfo>, S
|
|||||||
let mut sys = state.sys.lock().map_err(|_| "Failed to lock system state")?;
|
let mut sys = state.sys.lock().map_err(|_| "Failed to lock system state")?;
|
||||||
sys.refresh_all();
|
sys.refresh_all();
|
||||||
|
|
||||||
|
let users_cache = UsersCache::new();
|
||||||
|
|
||||||
Ok(sys.processes()
|
Ok(sys.processes()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(pid, process)| {
|
.map(|(pid, process)| {
|
||||||
let threads = if cfg!(target_os = "macos") {
|
let status = match process.status() {
|
||||||
use std::process::Command;
|
ProcessStatus::Run => "Running",
|
||||||
Command::new("ps")
|
ProcessStatus::Sleep => {
|
||||||
.args(["-o", "thcount=", "-p", &pid.as_u32().to_string()])
|
if process.cpu_usage() < 0.1 {
|
||||||
.output()
|
"Idle"
|
||||||
.ok()
|
} else {
|
||||||
.and_then(|output| {
|
"Sleeping"
|
||||||
String::from_utf8(output.stdout)
|
}
|
||||||
.ok()
|
},
|
||||||
.and_then(|s| s.trim().parse().ok())
|
_ => "Unknown"
|
||||||
})
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let status = match process.status() {
|
let user = process.user_id()
|
||||||
ProcessStatus::Run => "R", // Running
|
.and_then(|uid| {
|
||||||
ProcessStatus::Sleep => "S", // Sleeping
|
let uid_num = uid.to_string().parse::<u32>().unwrap_or(0);
|
||||||
ProcessStatus::Idle => "I", // Idle
|
users_cache.get_user_by_uid(uid_num)
|
||||||
ProcessStatus::Zombie => "Z", // Zombie
|
.map(|user| format!("{} ({})", user.name().to_string_lossy(), uid_num))
|
||||||
ProcessStatus::Stop => "T", // Stopped
|
})
|
||||||
ProcessStatus::Dead => "X", // Dead
|
.unwrap_or_else(|| "-".to_string());
|
||||||
_ => "Unknown",
|
|
||||||
};
|
|
||||||
|
|
||||||
ProcessInfo {
|
ProcessInfo {
|
||||||
pid: pid.as_u32(),
|
pid: pid.as_u32(),
|
||||||
@ -70,11 +68,9 @@ async fn get_processes(state: State<'_, AppState>) -> Result<Vec<ProcessInfo>, S
|
|||||||
cpu_usage: process.cpu_usage(),
|
cpu_usage: process.cpu_usage(),
|
||||||
memory_usage: process.memory(),
|
memory_usage: process.memory(),
|
||||||
status: status.to_string(),
|
status: status.to_string(),
|
||||||
user: process.user_id()
|
user,
|
||||||
.map(|uid| uid.to_string())
|
|
||||||
.unwrap_or_else(|| "-".to_string()),
|
|
||||||
command: process.cmd().join(" "),
|
command: process.cmd().join(" "),
|
||||||
threads,
|
threads: None,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect())
|
.collect())
|
||||||
|
@ -22,13 +22,10 @@
|
|||||||
|
|
||||||
const statusOptions = [
|
const statusOptions = [
|
||||||
{ value: "all", label: "All Statuses" },
|
{ value: "all", label: "All Statuses" },
|
||||||
{ value: "R", label: "🏃 Running" },
|
{ value: "Running", label: "🏃 Running" },
|
||||||
{ value: "S", label: "😴 Sleeping" },
|
{ value: "Sleeping", label: "😴 Sleeping" },
|
||||||
{ value: "I", label: "⌛ Idle" },
|
{ value: "Idle", label: "⌛ Idle" },
|
||||||
{ value: "Z", label: "🧟 Zombie" },
|
{ value: "Unknown", label: "🫥 Unknown" },
|
||||||
{ value: "T", label: "⛔ Stopped" },
|
|
||||||
{ value: "X", label: "💀 Dead" },
|
|
||||||
{ value: "Unknown", label: "🤔 Unknown" },
|
|
||||||
];
|
];
|
||||||
|
|
||||||
function changePage(page: number) {
|
function changePage(page: number) {
|
||||||
@ -60,7 +57,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="toolbar-group">
|
<div class="toolbar-group">
|
||||||
<span class="toolbar-label">Status:</span>
|
|
||||||
<select bind:value={statusFilter} class="select-input">
|
<select bind:value={statusFilter} class="select-input">
|
||||||
{#each statusOptions as option}
|
{#each statusOptions as option}
|
||||||
<option value={option.value}>{option.label}</option>
|
<option value={option.value}>{option.label}</option>
|
||||||
@ -364,52 +360,4 @@
|
|||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
.filter-box {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-select {
|
|
||||||
padding: 6px 12px;
|
|
||||||
font-size: 13px;
|
|
||||||
color: var(--text);
|
|
||||||
background: var(--surface0);
|
|
||||||
border: 1px solid var(--surface1);
|
|
||||||
border-radius: 6px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-select:hover {
|
|
||||||
background: var(--surface1);
|
|
||||||
}
|
|
||||||
|
|
||||||
select.btn-base {
|
|
||||||
appearance: none;
|
|
||||||
padding: 6px 28px 6px 12px;
|
|
||||||
font-size: 12px;
|
|
||||||
color: var(--text);
|
|
||||||
background: var(--surface0)
|
|
||||||
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E")
|
|
||||||
no-repeat right 8px center;
|
|
||||||
border: 1px solid var(--surface1);
|
|
||||||
border-radius: 6px;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
select.btn-base:hover {
|
|
||||||
background-color: var(--surface1);
|
|
||||||
}
|
|
||||||
|
|
||||||
select.btn-base:focus {
|
|
||||||
outline: none;
|
|
||||||
border-color: var(--blue);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure proper spacing between toolbar items */
|
|
||||||
.filter-box {
|
|
||||||
margin-left: 8px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -5,39 +5,24 @@ export interface ProcessStatus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const statusMap: Record<string, ProcessStatus> = {
|
export const statusMap: Record<string, ProcessStatus> = {
|
||||||
"R": { // Running
|
"Running": {
|
||||||
label: "Running",
|
label: "Running",
|
||||||
emoji: "🏃",
|
emoji: "🏃",
|
||||||
color: "var(--green)",
|
color: "var(--green)",
|
||||||
},
|
},
|
||||||
"S": { // Sleeping
|
"Sleeping": {
|
||||||
label: "Sleeping",
|
label: "Sleeping",
|
||||||
emoji: "😴",
|
emoji: "😴",
|
||||||
color: "var(--blue)",
|
color: "var(--blue)",
|
||||||
},
|
},
|
||||||
"I": { // Idle
|
"Idle": {
|
||||||
label: "Idle",
|
label: "Idle",
|
||||||
emoji: "⌛",
|
emoji: "⌛",
|
||||||
color: "var(--overlay0)",
|
color: "var(--overlay0)",
|
||||||
},
|
},
|
||||||
"Z": { // Zombie
|
|
||||||
label: "Zombie",
|
|
||||||
emoji: "🧟",
|
|
||||||
color: "var(--red)",
|
|
||||||
},
|
|
||||||
"T": { // Stopped
|
|
||||||
label: "Stopped",
|
|
||||||
emoji: "⛔",
|
|
||||||
color: "var(--yellow)",
|
|
||||||
},
|
|
||||||
"X": { // Dead
|
|
||||||
label: "Dead",
|
|
||||||
emoji: "💀",
|
|
||||||
color: "var(--red)",
|
|
||||||
},
|
|
||||||
"Unknown": {
|
"Unknown": {
|
||||||
label: "Unknown",
|
label: "Unknown",
|
||||||
emoji: "🤔",
|
emoji: "🫥",
|
||||||
color: "var(--overlay0)",
|
color: "var(--overlay0)",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user