Merge pull request #110 from Abdenasser/rust-refactor

Rust refactor
This commit is contained in:
Abdenasser Elidrissi 2024-11-13 03:25:50 +01:00 committed by GitHub
commit dea6d2a5ae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 821 additions and 533 deletions

367
package-lock.json generated
View File

@ -1,11 +1,11 @@
{
"name": "macos-task-manager",
"name": "neohtop",
"version": "1.1.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "macos-task-manager",
"name": "neohtop",
"version": "1.1.0",
"license": "MIT",
"dependencies": {
@ -525,9 +525,9 @@
"license": "MIT"
},
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.3.tgz",
"integrity": "sha512-ufb2CH2KfBWPJok95frEZZ82LtDl0A6QKTa8MoM+cWwDZvVGl5/jNb79pIhRvAalUu+7LD91VYR0nwRD799HkQ==",
"version": "4.25.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.25.0.tgz",
"integrity": "sha512-CC/ZqFZwlAIbU1wUPisHyV/XRc5RydFrNLtgl3dGYskdwPZdt4HERtKm50a/+DtTlKeCq9IXFEWR+P6blwjqBA==",
"cpu": [
"arm"
],
@ -539,9 +539,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
"version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.3.tgz",
"integrity": "sha512-iAHpft/eQk9vkWIV5t22V77d90CRofgR2006UiCjHcHJFVI1E0oBkQIAbz+pLtthFw3hWEmVB4ilxGyBf48i2Q==",
"version": "4.25.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.25.0.tgz",
"integrity": "sha512-/Y76tmLGUJqVBXXCfVS8Q8FJqYGhgH4wl4qTA24E9v/IJM0XvJCGQVSW1QZ4J+VURO9h8YCa28sTFacZXwK7Rg==",
"cpu": [
"arm64"
],
@ -553,9 +553,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.3.tgz",
"integrity": "sha512-QPW2YmkWLlvqmOa2OwrfqLJqkHm7kJCIMq9kOz40Zo9Ipi40kf9ONG5Sz76zszrmIZZ4hgRIkez69YnTHgEz1w==",
"version": "4.25.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.25.0.tgz",
"integrity": "sha512-YVT6L3UrKTlC0FpCZd0MGA7NVdp7YNaEqkENbWQ7AOVOqd/7VzyHpgIpc1mIaxRAo1ZsJRH45fq8j4N63I/vvg==",
"cpu": [
"arm64"
],
@ -567,9 +567,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
"version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.3.tgz",
"integrity": "sha512-KO0pN5x3+uZm1ZXeIfDqwcvnQ9UEGN8JX5ufhmgH5Lz4ujjZMAnxQygZAVGemFWn+ZZC0FQopruV4lqmGMshow==",
"version": "4.25.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.25.0.tgz",
"integrity": "sha512-ZRL+gexs3+ZmmWmGKEU43Bdn67kWnMeWXLFhcVv5Un8FQcx38yulHBA7XR2+KQdYIOtD0yZDWBCudmfj6lQJoA==",
"cpu": [
"x64"
],
@ -581,9 +581,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.24.3.tgz",
"integrity": "sha512-CsC+ZdIiZCZbBI+aRlWpYJMSWvVssPuWqrDy/zi9YfnatKKSLFCe6fjna1grHuo/nVaHG+kiglpRhyBQYRTK4A==",
"version": "4.25.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.25.0.tgz",
"integrity": "sha512-xpEIXhiP27EAylEpreCozozsxWQ2TJbOLSivGfXhU4G1TBVEYtUPi2pOZBnvGXHyOdLAUUhPnJzH3ah5cqF01g==",
"cpu": [
"arm64"
],
@ -595,9 +595,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.24.3.tgz",
"integrity": "sha512-F0nqiLThcfKvRQhZEzMIXOQG4EeX61im61VYL1jo4eBxv4aZRmpin6crnBJQ/nWnCsjH5F6J3W6Stdm0mBNqBg==",
"version": "4.25.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.25.0.tgz",
"integrity": "sha512-sC5FsmZGlJv5dOcURrsnIK7ngc3Kirnx3as2XU9uER+zjfyqIjdcMVgzy4cOawhsssqzoAX19qmxgJ8a14Qrqw==",
"cpu": [
"x64"
],
@ -609,9 +609,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.3.tgz",
"integrity": "sha512-KRSFHyE/RdxQ1CSeOIBVIAxStFC/hnBgVcaiCkQaVC+EYDtTe4X7z5tBkFyRoBgUGtB6Xg6t9t2kulnX6wJc6A==",
"version": "4.25.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.25.0.tgz",
"integrity": "sha512-uD/dbLSs1BEPzg564TpRAQ/YvTnCds2XxyOndAO8nJhaQcqQGFgv/DAVko/ZHap3boCvxnzYMa3mTkV/B/3SWA==",
"cpu": [
"arm"
],
@ -623,9 +623,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.3.tgz",
"integrity": "sha512-h6Q8MT+e05zP5BxEKz0vi0DhthLdrNEnspdLzkoFqGwnmOzakEHSlXfVyA4HJ322QtFy7biUAVFPvIDEDQa6rw==",
"version": "4.25.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.25.0.tgz",
"integrity": "sha512-ZVt/XkrDlQWegDWrwyC3l0OfAF7yeJUF4fq5RMS07YM72BlSfn2fQQ6lPyBNjt+YbczMguPiJoCfaQC2dnflpQ==",
"cpu": [
"arm"
],
@ -637,9 +637,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.3.tgz",
"integrity": "sha512-fKElSyXhXIJ9pqiYRqisfirIo2Z5pTTve5K438URf08fsypXrEkVmShkSfM8GJ1aUyvjakT+fn2W7Czlpd/0FQ==",
"version": "4.25.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.25.0.tgz",
"integrity": "sha512-qboZ+T0gHAW2kkSDPHxu7quaFaaBlynODXpBVnPxUgvWYaE84xgCKAPEYE+fSMd3Zv5PyFZR+L0tCdYCMAtG0A==",
"cpu": [
"arm64"
],
@ -651,9 +651,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.3.tgz",
"integrity": "sha512-YlddZSUk8G0px9/+V9PVilVDC6ydMz7WquxozToozSnfFK6wa6ne1ATUjUvjin09jp34p84milxlY5ikueoenw==",
"version": "4.25.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.25.0.tgz",
"integrity": "sha512-ndWTSEmAaKr88dBuogGH2NZaxe7u2rDoArsejNslugHZ+r44NfWiwjzizVS1nUOHo+n1Z6qV3X60rqE/HlISgw==",
"cpu": [
"arm64"
],
@ -665,9 +665,9 @@
]
},
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
"version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.3.tgz",
"integrity": "sha512-yNaWw+GAO8JjVx3s3cMeG5Esz1cKVzz8PkTJSfYzE5u7A+NvGmbVFEHP+BikTIyYWuz0+DX9kaA3pH9Sqxp69g==",
"version": "4.25.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.25.0.tgz",
"integrity": "sha512-BVSQvVa2v5hKwJSy6X7W1fjDex6yZnNKy3Kx1JGimccHft6HV0THTwNtC2zawtNXKUu+S5CjXslilYdKBAadzA==",
"cpu": [
"ppc64"
],
@ -679,9 +679,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.3.tgz",
"integrity": "sha512-lWKNQfsbpv14ZCtM/HkjCTm4oWTKTfxPmr7iPfp3AHSqyoTz5AgLemYkWLwOBWc+XxBbrU9SCokZP0WlBZM9lA==",
"version": "4.25.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.25.0.tgz",
"integrity": "sha512-G4hTREQrIdeV0PE2JruzI+vXdRnaK1pg64hemHq2v5fhv8C7WjVaeXc9P5i4Q5UC06d/L+zA0mszYIKl+wY8oA==",
"cpu": [
"riscv64"
],
@ -693,9 +693,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.3.tgz",
"integrity": "sha512-HoojGXTC2CgCcq0Woc/dn12wQUlkNyfH0I1ABK4Ni9YXyFQa86Fkt2Q0nqgLfbhkyfQ6003i3qQk9pLh/SpAYw==",
"version": "4.25.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.25.0.tgz",
"integrity": "sha512-9T/w0kQ+upxdkFL9zPVB6zy9vWW1deA3g8IauJxojN4bnz5FwSsUAD034KpXIVX5j5p/rn6XqumBMxfRkcHapQ==",
"cpu": [
"s390x"
],
@ -707,9 +707,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.3.tgz",
"integrity": "sha512-mnEOh4iE4USSccBOtcrjF5nj+5/zm6NcNhbSEfR3Ot0pxBwvEn5QVUXcuOwwPkapDtGZ6pT02xLoPaNv06w7KQ==",
"version": "4.25.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.25.0.tgz",
"integrity": "sha512-ThcnU0EcMDn+J4B9LD++OgBYxZusuA7iemIIiz5yzEcFg04VZFzdFjuwPdlURmYPZw+fgVrFzj4CA64jSTG4Ig==",
"cpu": [
"x64"
],
@ -721,9 +721,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.3.tgz",
"integrity": "sha512-rMTzawBPimBQkG9NKpNHvquIUTQPzrnPxPbCY1Xt+mFkW7pshvyIS5kYgcf74goxXOQk0CP3EoOC1zcEezKXhw==",
"version": "4.25.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.25.0.tgz",
"integrity": "sha512-zx71aY2oQxGxAT1JShfhNG79PnjYhMC6voAjzpu/xmMjDnKNf6Nl/xv7YaB/9SIa9jDYf8RBPWEnjcdlhlv1rQ==",
"cpu": [
"x64"
],
@ -735,9 +735,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.3.tgz",
"integrity": "sha512-2lg1CE305xNvnH3SyiKwPVsTVLCg4TmNCF1z7PSHX2uZY2VbUpdkgAllVoISD7JO7zu+YynpWNSKAtOrX3AiuA==",
"version": "4.25.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.25.0.tgz",
"integrity": "sha512-JT8tcjNocMs4CylWY/CxVLnv8e1lE7ff1fi6kbGocWwxDq9pj30IJ28Peb+Y8yiPNSF28oad42ApJB8oUkwGww==",
"cpu": [
"arm64"
],
@ -749,9 +749,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.3.tgz",
"integrity": "sha512-9SjYp1sPyxJsPWuhOCX6F4jUMXGbVVd5obVpoVEi8ClZqo52ViZewA6eFz85y8ezuOA+uJMP5A5zo6Oz4S5rVQ==",
"version": "4.25.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.25.0.tgz",
"integrity": "sha512-dRLjLsO3dNOfSN6tjyVlG+Msm4IiZnGkuZ7G5NmpzwF9oOc582FZG05+UdfTbz5Jd4buK/wMb6UeHFhG18+OEg==",
"cpu": [
"ia32"
],
@ -763,9 +763,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.3.tgz",
"integrity": "sha512-HGZgRFFYrMrP3TJlq58nR1xy8zHKId25vhmm5S9jETEfDf6xybPxsavFTJaufe2zgOGYJBskGlj49CwtEuFhWQ==",
"version": "4.25.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.25.0.tgz",
"integrity": "sha512-/RqrIFtLB926frMhZD0a5oDa4eFIbyNEwLLloMTEjmqfwZWXywwVVOVmwTsuyhC9HKkVEZcOOi+KV4U9wmOdlg==",
"cpu": [
"x64"
],
@ -787,9 +787,9 @@
}
},
"node_modules/@sveltejs/kit": {
"version": "2.7.3",
"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.7.3.tgz",
"integrity": "sha512-Vx7nq5MJ86I8qXYsVidC5PX6xm+uxt8DydvOdmJoyOK7LvGP18OFEG359yY+aa51t6pENvqZAMqAREQQx1OI2Q==",
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.8.0.tgz",
"integrity": "sha512-HCiWupCuKJQ3aPaC4Xc6lpPdjOOnoGzEiYjOqMqppdtfGtY2ABrx932Vw66ZwS2RGXc0BmZvFvNq5SzqlmDVLg==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
@ -860,9 +860,9 @@
}
},
"node_modules/@tauri-apps/api": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.0.3.tgz",
"integrity": "sha512-840qk6n8rbXBXMA5/aAgTYsg5JAubKO0nXw5wf7IzGnUuYKGbB4oFBIZtXOIWy+E0kNTDI3qhq5iqsoMJfwp8g==",
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.1.1.tgz",
"integrity": "sha512-fzUfFFKo4lknXGJq8qrCidkUcKcH2UHhfaaCNt4GzgzGaW2iS26uFOg4tS3H4P8D6ZEeUxtiD5z0nwFF0UN30A==",
"license": "Apache-2.0 OR MIT",
"funding": {
"type": "opencollective",
@ -870,9 +870,9 @@
}
},
"node_modules/@tauri-apps/cli": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.0.4.tgz",
"integrity": "sha512-Hl9eFXz+O366+6su9PfaSzu2EJdFe1p8K8ghkWmi40dz8VmSE7vsMTaOStD0I71ckSOkh2ICDX7FQTBgjlpjWw==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.1.0.tgz",
"integrity": "sha512-K2VhcKqBhAeS5pNOVdnR/xQRU6jwpgmkSL2ejHXcl0m+kaTggT0WRDQnFtPq6NljA7aE03cvwsbCAoFG7vtkJw==",
"dev": true,
"license": "Apache-2.0 OR MIT",
"bin": {
@ -886,22 +886,22 @@
"url": "https://opencollective.com/tauri"
},
"optionalDependencies": {
"@tauri-apps/cli-darwin-arm64": "2.0.4",
"@tauri-apps/cli-darwin-x64": "2.0.4",
"@tauri-apps/cli-linux-arm-gnueabihf": "2.0.4",
"@tauri-apps/cli-linux-arm64-gnu": "2.0.4",
"@tauri-apps/cli-linux-arm64-musl": "2.0.4",
"@tauri-apps/cli-linux-x64-gnu": "2.0.4",
"@tauri-apps/cli-linux-x64-musl": "2.0.4",
"@tauri-apps/cli-win32-arm64-msvc": "2.0.4",
"@tauri-apps/cli-win32-ia32-msvc": "2.0.4",
"@tauri-apps/cli-win32-x64-msvc": "2.0.4"
"@tauri-apps/cli-darwin-arm64": "2.1.0",
"@tauri-apps/cli-darwin-x64": "2.1.0",
"@tauri-apps/cli-linux-arm-gnueabihf": "2.1.0",
"@tauri-apps/cli-linux-arm64-gnu": "2.1.0",
"@tauri-apps/cli-linux-arm64-musl": "2.1.0",
"@tauri-apps/cli-linux-x64-gnu": "2.1.0",
"@tauri-apps/cli-linux-x64-musl": "2.1.0",
"@tauri-apps/cli-win32-arm64-msvc": "2.1.0",
"@tauri-apps/cli-win32-ia32-msvc": "2.1.0",
"@tauri-apps/cli-win32-x64-msvc": "2.1.0"
}
},
"node_modules/@tauri-apps/cli-darwin-arm64": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.0.4.tgz",
"integrity": "sha512-siH7rOHobb16rPbc11k64p1mxIpiRCkWmzs2qmL5IX21Gx9K5onI3Tk67Oqpf2uNupbYzItrOttaDT4NHFC7tw==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.1.0.tgz",
"integrity": "sha512-ESc6J6CE8hl1yKH2vJ+ALF+thq4Be+DM1mvmTyUCQObvezNCNhzfS6abIUd3ou4x5RGH51ouiANeT3wekU6dCw==",
"cpu": [
"arm64"
],
@ -916,9 +916,9 @@
}
},
"node_modules/@tauri-apps/cli-darwin-x64": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.0.4.tgz",
"integrity": "sha512-zIccfbCoZMfmUpnk6PFCV0keFyfVj1A9XV3Oiiitj/dkTZ9CQvzjhX3XC0XcK4rsTWegfr2PjSrK06aiPAROAw==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.1.0.tgz",
"integrity": "sha512-TasHS442DFs8cSH2eUQzuDBXUST4ECjCd0yyP+zZzvAruiB0Bg+c8A+I/EnqCvBQ2G2yvWLYG8q/LI7c87A5UA==",
"cpu": [
"x64"
],
@ -933,9 +933,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-arm-gnueabihf": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.0.4.tgz",
"integrity": "sha512-fgQqJzefOGWCBNg4yrVA82Rg4s1XQr5K0dc2rCxBhJfa696e8dQ1LDrnWq/AiO5r+uHfVaoQTIUvxxpFicYRSA==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.1.0.tgz",
"integrity": "sha512-aP7ZBGNL4ny07Cbb6kKpUOSrmhcIK2KhjviTzYlh+pPhAptxnC78xQGD3zKQkTi2WliJLPmBYbOHWWQa57lQ9w==",
"cpu": [
"arm"
],
@ -950,9 +950,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-arm64-gnu": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.0.4.tgz",
"integrity": "sha512-u8wbt5tPA9pI6j+d7jGrfOz9UVCiTp+IYzKNiIqlrDsAjqAUFaNXYHKqOUboeFWEmI4zoCWj6LgpS2OJTQ5FKg==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.1.0.tgz",
"integrity": "sha512-ZTdgD5gLeMCzndMT2f358EkoYkZ5T+Qy6zPzU+l5vv5M7dHVN9ZmblNAYYXmoOuw7y+BY4X/rZvHV9pcGrcanQ==",
"cpu": [
"arm64"
],
@ -967,9 +967,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-arm64-musl": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.0.4.tgz",
"integrity": "sha512-hntF1V8e3V1hlrESm93PsghDhf3lA5pbvFrRfYxU1c+fVD/jRXGVw8BH3O1lW8MWwhEg1YdhKk01oAgsuHLuig==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.1.0.tgz",
"integrity": "sha512-NzwqjUCilhnhJzusz3d/0i0F1GFrwCQbkwR6yAHUxItESbsGYkZRJk0yMEWkg3PzFnyK4cWTlQJMEU52TjhEzA==",
"cpu": [
"arm64"
],
@ -984,9 +984,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-x64-gnu": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.0.4.tgz",
"integrity": "sha512-Iq1GGJb+oT1T0ZV8izrgf0cBtlzPCJaWcNueRbf1ZXquMf+FSTyQv+/Lo8rq5T6buOIJOH7cAOTuEWWqiCZteg==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.1.0.tgz",
"integrity": "sha512-TyiIpMEtZxNOQmuFyfJwaaYbg3movSthpBJLIdPlKxSAB2BW0VWLY3/ZfIxm/G2YGHyREkjJvimzYE0i37PnMA==",
"cpu": [
"x64"
],
@ -1001,9 +1001,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-x64-musl": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.0.4.tgz",
"integrity": "sha512-9NTk6Pf0bSwXqCBdAA+PDYts9HeHebZzIo8mbRzRyUbER6QngG5HZb9Ka36Z1QWtJjdRy6uxSb4zb/9NuTeHfA==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.1.0.tgz",
"integrity": "sha512-/dQd0TlaxBdJACrR72DhynWftzHDaX32eBtS5WBrNJ+nnNb+znM3gON6nJ9tSE9jgDa6n1v2BkI/oIDtypfUXw==",
"cpu": [
"x64"
],
@ -1018,9 +1018,9 @@
}
},
"node_modules/@tauri-apps/cli-win32-arm64-msvc": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.0.4.tgz",
"integrity": "sha512-OF2e9oxiBFR8A8wVMOhUx9QGN/I1ZkquWC7gVQBnA56nx9PabJlDT08QBy5UD8USqZFVznnfNr2ehlheQahb3g==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.1.0.tgz",
"integrity": "sha512-NdQJO7SmdYqOcE+JPU7bwg7+odfZMWO6g8xF9SXYCMdUzvM2Gv/AQfikNXz5yS7ralRhNFuW32i5dcHlxh4pDg==",
"cpu": [
"arm64"
],
@ -1035,9 +1035,9 @@
}
},
"node_modules/@tauri-apps/cli-win32-ia32-msvc": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.0.4.tgz",
"integrity": "sha512-T+hCKB3rFP6q0saHHtR02hm6wr1ZPJ0Mkii3oRTxjPG6BBXoVzHNCYzvdgEGJPTA2sFuAQtJH764NRtNlDMifw==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.1.0.tgz",
"integrity": "sha512-f5h8gKT/cB8s1ticFRUpNmHqkmaLutT62oFDB7N//2YTXnxst7EpMIn1w+QimxTvTk2gcx6EcW6bEk/y2hZGzg==",
"cpu": [
"ia32"
],
@ -1052,9 +1052,9 @@
}
},
"node_modules/@tauri-apps/cli-win32-x64-msvc": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.0.4.tgz",
"integrity": "sha512-GVaiI3KWRFLomjJmApHqihhYlkJ+7FqhumhVfBO6Z2tWzZjQyVQgTdNp0kYEuW2WoAYEj0dKY6qd4YM33xYcUA==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.1.0.tgz",
"integrity": "sha512-P/+LrdSSb5Xbho1LRP4haBjFHdyPdjWvGgeopL96OVtrFpYnfC+RctB45z2V2XxqFk3HweDDxk266btjttfjGw==",
"cpu": [
"x64"
],
@ -1081,6 +1081,7 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.0.1.tgz",
"integrity": "sha512-akU1b77sw3qHiynrK0s930y8zKmcdrSD60htjH+mFZqv5WaakZA/XxHR3/sF1nNv9Mgmt/Shls37HwnOr00aSw==",
"license": "MIT OR Apache-2.0",
"dependencies": {
"@tauri-apps/api": "^2.0.0"
}
@ -1437,21 +1438,6 @@
"url": "https://github.com/sindresorhus/execa?sponsor=1"
}
},
"node_modules/fdir": {
"version": "6.4.2",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.2.tgz",
"integrity": "sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==",
"dev": true,
"license": "MIT",
"peerDependencies": {
"picomatch": "^3 || ^4"
},
"peerDependenciesMeta": {
"picomatch": {
"optional": true
}
}
},
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
@ -1581,12 +1567,12 @@
}
},
"node_modules/is-reference": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz",
"integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==",
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz",
"integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==",
"license": "MIT",
"dependencies": {
"@types/estree": "*"
"@types/estree": "^1.0.6"
}
},
"node_modules/is-stream": {
@ -1767,19 +1753,6 @@
"node": ">=8.6"
}
},
"node_modules/micromatch/node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8.6"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/mimic-fn": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
@ -1915,15 +1888,13 @@
"license": "ISC"
},
"node_modules/picomatch": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"engines": {
"node": ">=12"
"node": ">=8.6"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
@ -1943,9 +1914,9 @@
}
},
"node_modules/postcss": {
"version": "8.4.47",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
"integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
"version": "8.4.49",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
"integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
"dev": true,
"funding": [
{
@ -1964,7 +1935,7 @@
"license": "MIT",
"dependencies": {
"nanoid": "^3.3.7",
"picocolors": "^1.1.0",
"picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
"engines": {
@ -1988,9 +1959,9 @@
}
},
"node_modules/prettier-plugin-svelte": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-3.2.7.tgz",
"integrity": "sha512-/Dswx/ea0lV34If1eDcG3nulQ63YNr5KPDfMsjbdtpSWOxKKJ7nAc2qlVuYwEvCr4raIuredNoR7K4JCkmTGaQ==",
"version": "3.2.8",
"resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-3.2.8.tgz",
"integrity": "sha512-PAHmmU5cGZdnhW4mWhmvxuG2PVbbHIxUuPOdUKvfE+d4Qt2d29iU5VWrPdsaW5YqVEE0nqhlvN4eoKmVMpIF3Q==",
"dev": true,
"license": "MIT",
"peerDependencies": {
@ -2053,9 +2024,9 @@
"license": "MIT"
},
"node_modules/rollup": {
"version": "4.24.3",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.3.tgz",
"integrity": "sha512-HBW896xR5HGmoksbi3JBDtmVzWiPAYqp7wip50hjQ67JbDz61nyoMPdqu1DvVW9asYb2M65Z20ZHsyJCMqMyDg==",
"version": "4.25.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.25.0.tgz",
"integrity": "sha512-uVbClXmR6wvx5R1M3Od4utyLUxrmOcEm3pAtMphn73Apq19PDtHpgZoEvqH2YnnaNUuvKmg2DgRd2Sqv+odyqg==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -2069,24 +2040,24 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.24.3",
"@rollup/rollup-android-arm64": "4.24.3",
"@rollup/rollup-darwin-arm64": "4.24.3",
"@rollup/rollup-darwin-x64": "4.24.3",
"@rollup/rollup-freebsd-arm64": "4.24.3",
"@rollup/rollup-freebsd-x64": "4.24.3",
"@rollup/rollup-linux-arm-gnueabihf": "4.24.3",
"@rollup/rollup-linux-arm-musleabihf": "4.24.3",
"@rollup/rollup-linux-arm64-gnu": "4.24.3",
"@rollup/rollup-linux-arm64-musl": "4.24.3",
"@rollup/rollup-linux-powerpc64le-gnu": "4.24.3",
"@rollup/rollup-linux-riscv64-gnu": "4.24.3",
"@rollup/rollup-linux-s390x-gnu": "4.24.3",
"@rollup/rollup-linux-x64-gnu": "4.24.3",
"@rollup/rollup-linux-x64-musl": "4.24.3",
"@rollup/rollup-win32-arm64-msvc": "4.24.3",
"@rollup/rollup-win32-ia32-msvc": "4.24.3",
"@rollup/rollup-win32-x64-msvc": "4.24.3",
"@rollup/rollup-android-arm-eabi": "4.25.0",
"@rollup/rollup-android-arm64": "4.25.0",
"@rollup/rollup-darwin-arm64": "4.25.0",
"@rollup/rollup-darwin-x64": "4.25.0",
"@rollup/rollup-freebsd-arm64": "4.25.0",
"@rollup/rollup-freebsd-x64": "4.25.0",
"@rollup/rollup-linux-arm-gnueabihf": "4.25.0",
"@rollup/rollup-linux-arm-musleabihf": "4.25.0",
"@rollup/rollup-linux-arm64-gnu": "4.25.0",
"@rollup/rollup-linux-arm64-musl": "4.25.0",
"@rollup/rollup-linux-powerpc64le-gnu": "4.25.0",
"@rollup/rollup-linux-riscv64-gnu": "4.25.0",
"@rollup/rollup-linux-s390x-gnu": "4.25.0",
"@rollup/rollup-linux-x64-gnu": "4.25.0",
"@rollup/rollup-linux-x64-musl": "4.25.0",
"@rollup/rollup-win32-arm64-msvc": "4.25.0",
"@rollup/rollup-win32-ia32-msvc": "4.25.0",
"@rollup/rollup-win32-x64-msvc": "4.25.0",
"fsevents": "~2.3.2"
}
},
@ -2147,9 +2118,9 @@
}
},
"node_modules/simple-icons": {
"version": "13.15.0",
"resolved": "https://registry.npmjs.org/simple-icons/-/simple-icons-13.15.0.tgz",
"integrity": "sha512-8SzFj9CvPlDnjDLISsAWTvpCs7om2zbSJZ1hNLRo6quWKLqFwjCD9opS24Q/yD0bdsnVHPpF0N3hitpHrY5u9w==",
"version": "13.16.0",
"resolved": "https://registry.npmjs.org/simple-icons/-/simple-icons-13.16.0.tgz",
"integrity": "sha512-aMg1efZ0IvYPKdvqUW0woVGSJwb199y9z7j1+6D5zPMn95eMQN0xzKAHefsqQW2K/5LwfgtFK3Gxn9n1eafX0A==",
"license": "CC0-1.0",
"engines": {
"node": ">=0.12.18"
@ -2259,9 +2230,9 @@
}
},
"node_modules/svelte": {
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.1.6.tgz",
"integrity": "sha512-bYS/DpkqXk0j5UZgiNXrEjZYPRZ4Ncd87w4KUSbcZGyojA0+i/Ls9OGUjETHmdLe8RcQ0G8SX/T0PypPpAA/ew==",
"version": "5.1.15",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.1.15.tgz",
"integrity": "sha512-cs2JYADrEorRCB4AUCHMvwperwAKcn/mz7w1xzVOv3fG6TmAS2n13JYHH8/uDCFbqVyRSXXlL+vA5RDwGUXEZg==",
"license": "MIT",
"dependencies": {
"@ampproject/remapping": "^2.3.0",
@ -2283,9 +2254,9 @@
}
},
"node_modules/svelte-check": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.0.5.tgz",
"integrity": "sha512-icBTBZ3ibBaywbXUat3cK6hB5Du+Kq9Z8CRuyLmm64XIe2/r+lQcbuBx/IQgsbrC+kT2jQ0weVpZSSRIPwB6jQ==",
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.0.7.tgz",
"integrity": "sha512-24hwo+D5L35HOXsh3Z2sU4WhdDLavlHquYaJhrEqAt+mV1xOVzoMVYThW80n99osDJxyuH+vxjNFkNRL4EvwTg==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -2306,6 +2277,36 @@
"typescript": ">=5.0.0"
}
},
"node_modules/svelte-check/node_modules/fdir": {
"version": "6.4.2",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.2.tgz",
"integrity": "sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==",
"dev": true,
"license": "MIT",
"peerDependencies": {
"picomatch": "^3 || ^4"
},
"peerDependenciesMeta": {
"picomatch": {
"optional": true
}
}
},
"node_modules/svelte-check/node_modules/picomatch": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/svelte-fa": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/svelte-fa/-/svelte-fa-4.0.3.tgz",
@ -2364,9 +2365,9 @@
}
},
"node_modules/vite": {
"version": "5.4.10",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.10.tgz",
"integrity": "sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==",
"version": "5.4.11",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz",
"integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==",
"dev": true,
"license": "MIT",
"dependencies": {

View File

@ -1,5 +1,5 @@
{
"name": "macos-task-manager",
"name": "neohtop",
"version": "1.1.0",
"description": "",
"type": "module",

28
src-tauri/Cargo.lock generated
View File

@ -1660,20 +1660,6 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
[[package]]
name = "macos-task-manager"
version = "1.1.0"
dependencies = [
"serde",
"serde_json",
"sysinfo",
"tauri",
"tauri-build",
"tauri-plugin-os",
"tauri-plugin-shell",
"window-vibrancy",
]
[[package]]
name = "malloc_buf"
version = "0.0.6"
@ -1796,6 +1782,20 @@ dependencies = [
"jni-sys",
]
[[package]]
name = "neohtop"
version = "1.1.0"
dependencies = [
"serde",
"serde_json",
"sysinfo",
"tauri",
"tauri-build",
"tauri-plugin-os",
"tauri-plugin-shell",
"window-vibrancy",
]
[[package]]
name = "new_debug_unreachable"
version = "1.0.6"

View File

@ -1,7 +1,7 @@
[package]
name = "macos-task-manager"
name = "neohtop"
version = "1.1.0"
description = "A Tauri App"
description = "A cross-platform system monitor"
authors = ["you"]
edition = "2021"

66
src-tauri/src/commands.rs Normal file
View File

@ -0,0 +1,66 @@
//! Tauri command handlers
//!
//! This module contains the command handlers that are exposed to the frontend
//! through Tauri's IPC mechanism. These commands provide the interface between
//! the frontend and the system monitoring functionality.
use crate::monitoring::{ProcessInfo, ProcessMonitor, SystemStats};
use crate::state::AppState;
use sysinfo::SystemExt;
use tauri::State;
/// Retrieves the current list of processes and system statistics
///
/// # Arguments
///
/// * `state` - The application state containing system monitoring components
///
/// # Returns
///
/// A tuple containing:
/// * A vector of process information
/// * Current system statistics
///
/// # Errors
///
/// Returns an error string if:
/// * Failed to acquire locks on system state
/// * Failed to collect process information
#[tauri::command]
pub async fn get_processes(
state: State<'_, AppState>,
) -> Result<(Vec<ProcessInfo>, SystemStats), String> {
let mut sys = state.sys.lock().map_err(|e| e.to_string())?;
sys.refresh_all();
sys.refresh_networks_list();
sys.refresh_disks_list();
let mut process_monitor = state.process_monitor.lock().map_err(|e| e.to_string())?;
let mut system_monitor = state.system_monitor.lock().map_err(|e| e.to_string())?;
let processes = process_monitor.collect_processes(&sys)?;
let system_stats = system_monitor.collect_stats(&sys);
Ok((processes, system_stats))
}
/// Attempts to kill a process with the specified PID
///
/// # Arguments
///
/// * `pid` - Process ID to kill
/// * `state` - The application state
///
/// # Returns
///
/// * `true` if the process was successfully killed
/// * `false` if the process couldn't be killed or wasn't found
///
/// # Errors
///
/// Returns an error string if failed to acquire lock on system state
#[tauri::command]
pub async fn kill_process(pid: u32, state: State<'_, AppState>) -> Result<bool, String> {
let sys = state.sys.lock().map_err(|e| e.to_string())?;
Ok(ProcessMonitor::kill_process(&sys, pid))
}

View File

@ -1,338 +1,39 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
//! NeoHtop - A modern system monitor built with Tauri
//!
//! This is the main entry point for the application. It sets up the Tauri
//! application, initializes plugins, and configures window effects.
use std::collections::HashMap;
use std::sync::Mutex;
use std::time::{Instant, SystemTime, UNIX_EPOCH};
use sysinfo::{
CpuExt, Disk, DiskExt, NetworkExt, NetworksExt, PidExt, ProcessExt, ProcessStatus, System,
SystemExt,
};
use tauri::{Manager, State};
#[cfg(target_os = "windows")]
use window_vibrancy::apply_acrylic;
#[cfg(target_os = "macos")]
use window_vibrancy::{apply_vibrancy, NSVisualEffectMaterial, NSVisualEffectState};
mod commands;
mod monitoring;
mod state;
mod ui;
struct AppState {
sys: Mutex<System>,
process_cache: Mutex<HashMap<u32, ProcessStaticInfo>>,
last_network_update: Mutex<(Instant, u64, u64)>,
}
impl AppState {
pub fn new() -> Self {
let mut sys = System::new();
sys.refresh_all();
// Initialize network stats
let initial_rx = sys
.networks()
.iter()
.map(|(_, data)| data.total_received())
.sum();
let initial_tx = sys
.networks()
.iter()
.map(|(_, data)| data.total_transmitted())
.sum();
Self {
sys: Mutex::new(sys),
process_cache: Mutex::new(HashMap::new()),
last_network_update: Mutex::new((Instant::now(), initial_rx, initial_tx)),
}
}
}
#[derive(Clone)]
struct ProcessStaticInfo {
name: String,
command: String,
user: String,
}
#[derive(serde::Serialize)]
struct ProcessInfo {
pid: u32,
ppid: u32,
name: String,
cpu_usage: f32,
memory_usage: u64,
status: String,
user: String,
command: String,
threads: Option<u32>,
environ: Vec<String>,
root: String,
virtual_memory: u64,
start_time: u64,
run_time: u64,
disk_usage: (u64, u64), // (read_bytes, written_bytes)
session_id: Option<u32>,
}
#[derive(serde::Serialize)]
pub struct SystemStats {
pub cpu_usage: Vec<f32>,
pub memory_total: u64,
pub memory_used: u64,
pub memory_free: u64,
pub memory_cached: u64,
pub uptime: u64,
pub load_avg: [f64; 3],
pub network_rx_bytes: u64,
pub network_tx_bytes: u64,
pub disk_total_bytes: u64,
pub disk_used_bytes: u64,
pub disk_free_bytes: u64,
}
// Assume MacOS or Linux
#[cfg(not(target_os = "windows"))]
fn filter_disks(disks: &[Disk]) -> Vec<&sysinfo::Disk> {
disks
.iter()
.filter(|disk| {
// Filter for physical disks - typically those mounted at "/"
disk.mount_point() == std::path::Path::new("/")
})
.collect()
}
#[cfg(target_os = "windows")]
fn filter_disks(disks: &[Disk]) -> Vec<&sysinfo::Disk> {
disks.iter().collect()
}
#[tauri::command]
async fn get_processes(
state: State<'_, AppState>,
) -> Result<(Vec<ProcessInfo>, SystemStats), String> {
let processes_data;
let system_stats;
// Get current time once for all calculations
let current_time = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map_err(|e| e.to_string())?
.as_secs();
// Scope for system lock
{
let mut sys = state
.sys
.lock()
.map_err(|_| "Failed to lock system state")?;
sys.refresh_all();
sys.refresh_networks_list();
sys.refresh_disks_list();
// Collect all the process data we need while holding sys lock
processes_data = sys
.processes()
.iter()
.map(|(pid, process)| {
let start_time = process.start_time();
let run_time = if start_time > 0 {
current_time.saturating_sub(start_time)
} else {
0
};
(
pid.as_u32(),
process.name().to_string(),
process.cmd().to_vec(),
process.user_id().map(|uid| uid.to_string()),
process.cpu_usage(),
process.memory(),
process.status(),
process.parent().map(|p| p.as_u32()),
process.environ().to_vec(),
process.root().to_string_lossy().into_owned(),
process.virtual_memory(),
start_time,
run_time, // Use calculated run_time
process.disk_usage().read_bytes,
process.disk_usage().written_bytes,
process.session_id().map(|id| id.as_u32()),
)
})
.collect::<Vec<_>>();
// Calculate total network I/O
let mut last_update = state
.last_network_update
.lock()
.map_err(|_| "Failed to lock network state")?;
let elapsed = last_update.0.elapsed().as_secs_f64();
let current_time = Instant::now();
let current_rx: u64 = sys
.networks()
.iter()
.map(|(_, data)| data.total_received())
.sum();
let current_tx: u64 = sys
.networks()
.iter()
.map(|(_, data)| data.total_transmitted())
.sum();
let network_stats = (
((current_rx - last_update.1) as f64 / elapsed) as u64,
((current_tx - last_update.2) as f64 / elapsed) as u64,
);
*last_update = (current_time, current_rx, current_tx);
// Calculate total disk usage
let disk_stats = filter_disks(&sys.disks())
.iter()
.fold((0, 0, 0), |acc, disk| {
(
acc.0 + disk.total_space(),
acc.1 + disk.total_space() - disk.available_space(),
acc.2 + disk.available_space(),
)
});
system_stats = SystemStats {
cpu_usage: sys.cpus().iter().map(|cpu| cpu.cpu_usage()).collect(),
memory_total: sys.total_memory(),
memory_used: sys.used_memory(),
memory_free: sys.total_memory() - sys.used_memory(),
memory_cached: sys.total_memory()
- (sys.used_memory() + (sys.total_memory() - sys.used_memory())),
uptime: sys.uptime(),
load_avg: [
sys.load_average().one,
sys.load_average().five,
sys.load_average().fifteen,
],
network_rx_bytes: network_stats.0,
network_tx_bytes: network_stats.1,
disk_total_bytes: disk_stats.0,
disk_used_bytes: disk_stats.1,
disk_free_bytes: disk_stats.2,
};
} // sys lock is automatically dropped here
// Now lock the process cache
let mut process_cache = state
.process_cache
.lock()
.map_err(|_| "Failed to lock process cache")?;
// Build the process info list
let processes = processes_data
.into_iter()
.map(
|(
pid,
name,
cmd,
user_id,
cpu_usage,
memory,
status,
ppid,
environ,
root,
virtual_memory,
start_time,
run_time,
disk_read,
disk_written,
session_id,
)| {
let static_info = process_cache
.entry(pid)
.or_insert_with(|| ProcessStaticInfo {
name: name.clone(),
command: cmd.join(" "),
user: user_id.unwrap_or_else(|| "-".to_string()),
});
let status_str = match status {
ProcessStatus::Run => "Running",
ProcessStatus::Sleep => "Sleeping",
ProcessStatus::Idle => "Idle",
_ => "Unknown",
};
ProcessInfo {
pid,
ppid: ppid.unwrap_or(0),
name: static_info.name.clone(),
cpu_usage,
memory_usage: memory,
status: status_str.to_string(),
user: static_info.user.clone(),
command: static_info.command.clone(),
threads: None,
environ,
root,
virtual_memory,
start_time,
run_time,
disk_usage: (disk_read, disk_written),
session_id,
}
},
)
.collect();
Ok((processes, system_stats))
}
#[tauri::command]
async fn kill_process(pid: u32, state: State<'_, AppState>) -> Result<bool, String> {
let sys = state
.sys
.lock()
.map_err(|_| "Failed to lock system state")?;
if let Some(process) = sys.process(sysinfo::Pid::from(pid as usize)) {
Ok(process.kill())
} else {
Ok(false)
}
}
#[cfg(target_os = "windows")]
fn setup_window_effects(window: &tauri::WebviewWindow) -> Result<(), Box<dyn std::error::Error>> {
apply_acrylic(window, Some((0, 0, 25, 125)))?;
Ok(())
}
#[cfg(target_os = "macos")]
fn setup_window_effects(window: &tauri::WebviewWindow) -> Result<(), Box<dyn std::error::Error>> {
apply_vibrancy(
window,
NSVisualEffectMaterial::HudWindow,
Some(NSVisualEffectState::Active),
None,
)?;
Ok(())
}
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
fn setup_window_effects(_window: &tauri::WebviewWindow) -> Result<(), Box<dyn std::error::Error>> {
// No-op for other platforms
Ok(())
}
use state::AppState;
use tauri::Manager;
/// Main entry point for the application
///
/// # Panics
///
/// Will panic if:
/// - Unable to create the main window
/// - Failed to apply window effects
/// - Failed to initialize the application state
fn main() {
tauri::Builder::default()
.setup(|app| {
let window = app.get_webview_window("main").unwrap();
setup_window_effects(&window).expect("Failed to apply window effects");
ui::setup_window_effects(&window).expect("Failed to apply window effects");
Ok(())
})
.plugin(tauri_plugin_shell::init())
.plugin(tauri_plugin_os::init())
.manage(AppState::new())
.invoke_handler(tauri::generate_handler![get_processes, kill_process])
.invoke_handler(tauri::generate_handler![
commands::get_processes,
commands::kill_process,
])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}

View File

@ -0,0 +1,13 @@
//! System monitoring functionality
//!
//! This module provides types and functionality for monitoring system resources
//! and processes. It includes process monitoring, system statistics collection,
//! and data structures for representing system state.
mod process_monitor;
mod system_monitor;
mod types;
pub use process_monitor::ProcessMonitor;
pub use system_monitor::SystemMonitor;
pub use types::*; // Re-export all types

View File

@ -0,0 +1,167 @@
//! Process monitoring functionality
//!
//! This module handles monitoring and managing system processes, including
//! collecting process information and managing process lifecycle.
use super::{ProcessData, ProcessInfo, ProcessStaticInfo};
use std::collections::HashMap;
use std::fmt::Debug;
use std::time::{SystemTime, UNIX_EPOCH};
use sysinfo::{PidExt, ProcessExt, ProcessStatus, SystemExt};
/// Monitors and manages system processes
#[derive(Debug)]
pub struct ProcessMonitor {
/// Cache for static process information to avoid redundant allocations
process_cache: HashMap<u32, ProcessStaticInfo>,
}
impl ProcessMonitor {
/// Creates a new process monitor instance
pub fn new() -> Self {
Self {
process_cache: HashMap::new(),
}
}
/// Collects information about all running processes
///
/// # Arguments
///
/// * `sys` - System information provider
///
/// # Returns
///
/// A vector of process information, or an error string if collection failed
pub fn collect_processes(&mut self, sys: &sysinfo::System) -> Result<Vec<ProcessInfo>, String> {
let current_time = Self::get_current_time()?;
let processes_data = self.collect_process_data(sys, current_time);
Ok(self.build_process_info(processes_data))
}
/// Attempts to kill a process
///
/// # Arguments
///
/// * `sys` - System information provider
/// * `pid` - Process ID to kill
///
/// # Returns
///
/// Boolean indicating whether the process was successfully killed
pub fn kill_process(sys: &sysinfo::System, pid: u32) -> bool {
sys.process(sysinfo::Pid::from(pid as usize))
.map(|process| process.kill())
.unwrap_or(false)
}
/// Gets the current system time in seconds since UNIX epoch
fn get_current_time() -> Result<u64, String> {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|d| d.as_secs())
.map_err(|e| format!("Failed to get system time: {}", e))
}
/// Collects raw process data from the system
fn collect_process_data(&self, sys: &sysinfo::System, current_time: u64) -> Vec<ProcessData> {
sys.processes()
.iter()
.map(|(pid, process)| {
let start_time = process.start_time();
ProcessData {
pid: pid.as_u32(),
name: process.name().to_string(),
cmd: process.cmd().to_vec(),
user_id: process.user_id().map(|uid| uid.to_string()),
cpu_usage: process.cpu_usage(),
memory: process.memory(),
status: process.status(),
ppid: process.parent().map(|p| p.as_u32()),
environ: process.environ().to_vec(),
root: process.root().to_string_lossy().into_owned(),
virtual_memory: process.virtual_memory(),
start_time,
run_time: if start_time > 0 {
current_time.saturating_sub(start_time)
} else {
0
},
disk_usage: process.disk_usage(),
session_id: process.session_id().map(|id| id.as_u32()),
}
})
.collect()
}
/// Builds process information from raw process data
fn build_process_info(&mut self, processes: Vec<ProcessData>) -> Vec<ProcessInfo> {
processes
.into_iter()
.map(|data| {
let cached_info =
self.process_cache
.entry(data.pid)
.or_insert_with(|| ProcessStaticInfo {
name: data.name.clone(),
command: data.cmd.join(" "),
user: data.user_id.unwrap_or_else(|| "-".to_string()),
});
ProcessInfo {
pid: data.pid,
ppid: data.ppid.unwrap_or(0),
name: cached_info.name.clone(),
cpu_usage: data.cpu_usage,
memory_usage: data.memory,
status: Self::format_status(data.status),
user: cached_info.user.clone(),
command: cached_info.command.clone(),
threads: None,
environ: data.environ,
root: data.root,
virtual_memory: data.virtual_memory,
start_time: data.start_time,
run_time: data.run_time,
disk_usage: (data.disk_usage.read_bytes, data.disk_usage.written_bytes),
session_id: data.session_id,
}
})
.collect()
}
/// Formats process status into a human-readable string
pub fn format_status(status: ProcessStatus) -> String {
match status {
ProcessStatus::Run => "Running",
ProcessStatus::Sleep => "Sleeping",
ProcessStatus::Idle => "Idle",
_ => "Unknown",
}
.to_string()
}
}
#[cfg(test)]
mod tests {
use super::*;
use sysinfo::System;
/// Tests creation of a new process monitor
#[test]
fn test_process_monitor_creation() {
let monitor = ProcessMonitor::new();
assert!(monitor.process_cache.is_empty());
}
/// Tests process collection functionality
#[test]
fn test_process_collection() {
let mut monitor = ProcessMonitor::new();
let mut sys = System::new();
sys.refresh_all();
let result = monitor.collect_processes(&sys);
assert!(result.is_ok());
}
}

View File

@ -0,0 +1,146 @@
//! System statistics monitoring
//!
//! This module handles collection and monitoring of system-wide statistics
//! including CPU, memory, network, and disk usage.
use super::SystemStats;
use std::fmt::Debug;
use std::path::Path;
use std::time::Instant;
use sysinfo::{CpuExt, Disk, DiskExt, NetworkExt, NetworksExt, SystemExt};
/// Monitors system-wide statistics
#[derive(Debug)]
pub struct SystemMonitor {
/// Tracks network usage between updates
last_network_update: (Instant, u64, u64),
}
impl SystemMonitor {
/// Creates a new system monitor instance
///
/// # Arguments
///
/// * `sys` - System information provider for initial readings
pub fn new(sys: &sysinfo::System) -> Self {
let initial_rx: u64 = sys
.networks()
.iter()
.map(|(_, data)| data.total_received())
.sum();
let initial_tx: u64 = sys
.networks()
.iter()
.map(|(_, data)| data.total_transmitted())
.sum();
Self {
last_network_update: (Instant::now(), initial_rx, initial_tx),
}
}
/// Collects current system statistics
///
/// # Arguments
///
/// * `sys` - System information provider
pub fn collect_stats(&mut self, sys: &sysinfo::System) -> SystemStats {
let (network_rx, network_tx) = self.calculate_network_stats(sys);
let (disk_total, disk_used, disk_free) = self.calculate_disk_stats(sys);
SystemStats {
cpu_usage: sys.cpus().iter().map(|cpu| cpu.cpu_usage()).collect(),
memory_total: sys.total_memory(),
memory_used: sys.used_memory(),
memory_free: sys.total_memory() - sys.used_memory(),
memory_cached: sys.total_memory()
- (sys.used_memory() + (sys.total_memory() - sys.used_memory())),
uptime: sys.uptime(),
load_avg: [
sys.load_average().one,
sys.load_average().five,
sys.load_average().fifteen,
],
network_rx_bytes: network_rx,
network_tx_bytes: network_tx,
disk_total_bytes: disk_total,
disk_used_bytes: disk_used,
disk_free_bytes: disk_free,
}
}
/// Filters disks based on platform-specific criteria
#[cfg(not(target_os = "windows"))]
fn filter_disks(disks: &[Disk]) -> Vec<&Disk> {
disks
.iter()
.filter(|disk| disk.mount_point() == Path::new("/"))
.collect()
}
/// Windows-specific disk filtering
#[cfg(target_os = "windows")]
fn filter_disks(disks: &[Disk]) -> Vec<&Disk> {
disks.iter().collect()
}
/// Calculates network usage rates
fn calculate_network_stats(&mut self, sys: &sysinfo::System) -> (u64, u64) {
let current_rx: u64 = sys
.networks()
.iter()
.map(|(_, data)| data.total_received())
.sum();
let current_tx: u64 = sys
.networks()
.iter()
.map(|(_, data)| data.total_transmitted())
.sum();
let elapsed = self.last_network_update.0.elapsed().as_secs_f64();
let rx_rate = ((current_rx - self.last_network_update.1) as f64 / elapsed) as u64;
let tx_rate = ((current_tx - self.last_network_update.2) as f64 / elapsed) as u64;
self.last_network_update = (Instant::now(), current_rx, current_tx);
(rx_rate, tx_rate)
}
/// Calculates disk usage statistics
fn calculate_disk_stats(&self, sys: &sysinfo::System) -> (u64, u64, u64) {
let disks = Self::filter_disks(sys.disks());
let total: u64 = disks.iter().map(|disk| disk.total_space()).sum();
let used: u64 = disks
.iter()
.map(|disk| disk.total_space() - disk.available_space())
.sum();
let free: u64 = disks.iter().map(|disk| disk.available_space()).sum();
(total, used, free)
}
}
#[cfg(test)]
mod tests {
use super::*;
use sysinfo::System;
/// Tests creation of system monitor
#[test]
fn test_system_monitor_creation() {
let sys = System::new();
let monitor = SystemMonitor::new(&sys);
assert!(monitor.last_network_update.1 >= 0);
assert!(monitor.last_network_update.2 >= 0);
}
/// Tests system statistics collection
#[test]
fn test_stats_collection() {
let mut sys = System::new();
let mut monitor = SystemMonitor::new(&sys);
sys.refresh_all();
let stats = monitor.collect_stats(&sys);
assert!(!stats.cpu_usage.is_empty());
assert!(stats.memory_total > 0);
}
}

View File

@ -0,0 +1,119 @@
use serde::Serialize;
use std::fmt::Debug;
use sysinfo::{DiskUsage, ProcessStatus};
/// Internal representation of process data collected from the system
/// This struct is used internally and not exposed directly to the frontend
#[derive(Clone, Debug)]
pub(crate) struct ProcessData {
/// Process ID
pub pid: u32,
/// Name of the process
pub name: String,
/// Complete command line arguments
pub cmd: Vec<String>,
/// User ID that owns the process
pub user_id: Option<String>,
/// CPU usage as percentage (0-100)
pub cpu_usage: f32,
/// Physical memory usage in bytes
pub memory: u64,
/// Current process status
pub status: ProcessStatus,
/// Parent process ID
pub ppid: Option<u32>,
/// Environment variables
pub environ: Vec<String>,
/// Root directory of the process
pub root: String,
/// Virtual memory usage in bytes
pub virtual_memory: u64,
/// Process start time (Unix timestamp)
pub start_time: u64,
/// Process running time in seconds
pub run_time: u64,
/// Disk I/O statistics
pub disk_usage: DiskUsage,
/// Session ID of the process
pub session_id: Option<u32>,
}
/// Static information about a process that doesn't change frequently
/// Used for caching purposes to avoid frequent updates of stable data
#[derive(Clone, Debug)]
pub struct ProcessStaticInfo {
/// Process name
pub name: String,
/// Full command string
pub command: String,
/// Username of the process owner
pub user: String,
}
/// Process information exposed to the frontend via Tauri
/// Contains formatted and filtered process data for UI consumption
#[derive(Serialize, Debug)]
pub struct ProcessInfo {
/// Process ID
pub pid: u32,
/// Parent process ID
pub ppid: u32,
/// Process name
pub name: String,
/// CPU usage as percentage (0-100)
pub cpu_usage: f32,
/// Physical memory usage in bytes
pub memory_usage: u64,
/// Process status as string
pub status: String,
/// Username of the process owner
pub user: String,
/// Full command string
pub command: String,
/// Number of threads (if available)
pub threads: Option<u32>,
/// Environment variables
pub environ: Vec<String>,
/// Root directory of the process
pub root: String,
/// Virtual memory usage in bytes
pub virtual_memory: u64,
/// Process start time (Unix timestamp)
pub start_time: u64,
/// Process running time in seconds
pub run_time: u64,
/// Disk I/O statistics (read bytes, written bytes)
pub disk_usage: (u64, u64),
/// Session ID of the process
pub session_id: Option<u32>,
}
/// System-wide statistics exposed to the frontend
/// Provides overall system resource usage and performance metrics
#[derive(Serialize, Debug)]
pub struct SystemStats {
/// CPU usage per core as percentage (0-100)
pub cpu_usage: Vec<f32>,
/// Total physical memory in bytes
pub memory_total: u64,
/// Used physical memory in bytes
pub memory_used: u64,
/// Free physical memory in bytes
pub memory_free: u64,
/// Cached memory in bytes
pub memory_cached: u64,
/// System uptime in seconds
pub uptime: u64,
/// Load averages for 1, 5, and 15 minutes
pub load_avg: [f64; 3],
/// Total bytes received over network
pub network_rx_bytes: u64,
/// Total bytes transmitted over network
pub network_tx_bytes: u64,
/// Total disk space in bytes
pub disk_total_bytes: u64,
/// Used disk space in bytes
pub disk_used_bytes: u64,
/// Free disk space in bytes
pub disk_free_bytes: u64,
}

41
src-tauri/src/state.rs Normal file
View File

@ -0,0 +1,41 @@
//! Application state management
//!
//! This module handles the global application state, including system monitoring
//! and process tracking capabilities.
use crate::monitoring::{ProcessMonitor, SystemMonitor};
use std::sync::Mutex;
use sysinfo::{System, SystemExt};
/// Global application state
///
/// Maintains thread-safe access to system information and monitoring components
#[derive(Debug)]
pub struct AppState {
/// System information handler
pub sys: Mutex<System>,
/// Process monitoring component
pub process_monitor: Mutex<ProcessMonitor>,
/// System statistics monitoring component
pub system_monitor: Mutex<SystemMonitor>,
}
impl AppState {
/// Creates a new instance of the application state
///
/// Initializes system monitoring and process tracking components
///
/// # Returns
///
/// A new `AppState` instance with initialized monitors
pub fn new() -> Self {
let mut sys = System::new();
sys.refresh_all();
Self {
process_monitor: Mutex::new(ProcessMonitor::new()),
system_monitor: Mutex::new(SystemMonitor::new(&sys)),
sys: Mutex::new(sys),
}
}
}

7
src-tauri/src/ui/mod.rs Normal file
View File

@ -0,0 +1,7 @@
//! User interface functionality
//!
//! This module handles UI-specific functionality, including window effects
//! and platform-specific visual customizations.
mod window;
pub use window::setup_window_effects;

View File

@ -0,0 +1,35 @@
//! Window effects and customization
//!
//! Provides platform-specific window effects like transparency and vibrancy.
use tauri::WebviewWindow;
#[cfg(target_os = "windows")]
use window_vibrancy::apply_acrylic;
#[cfg(target_os = "macos")]
use window_vibrancy::{apply_vibrancy, NSVisualEffectMaterial, NSVisualEffectState};
/// Applies Windows-specific window effects
#[cfg(target_os = "windows")]
pub fn setup_window_effects(window: &WebviewWindow) -> Result<(), Box<dyn std::error::Error>> {
apply_acrylic(window, Some((0, 0, 25, 125)))?;
Ok(())
}
/// Applies macOS-specific window effects
#[cfg(target_os = "macos")]
pub fn setup_window_effects(window: &WebviewWindow) -> Result<(), Box<dyn std::error::Error>> {
apply_vibrancy(
window,
NSVisualEffectMaterial::HudWindow,
Some(NSVisualEffectState::Active),
None,
)?;
Ok(())
}
/// No-op for platforms without specific window effects
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
pub fn setup_window_effects(_window: &WebviewWindow) -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}

View File

@ -255,18 +255,11 @@
selectedProcessPid = null;
}
let minLoadingTimer: ReturnType<typeof setTimeout>;
const MIN_LOADING_TIME = 2000; // Show loading screen for at least 2 seconds
onMount(async () => {
const loadingPromise = Promise.all([getProcesses()]);
const timerPromise = new Promise((resolve) => {
minLoadingTimer = setTimeout(resolve, MIN_LOADING_TIME);
});
try {
// Wait for both the data to load AND the minimum time to pass
await Promise.all([loadingPromise, timerPromise]);
await getProcesses();
} catch (error) {
console.error("Failed to load processes:", error);
} finally {
isLoading = false;
}
@ -277,7 +270,6 @@
onDestroy(() => {
if (intervalId) clearInterval(intervalId);
if (minLoadingTimer) clearTimeout(minLoadingTimer);
});
</script>