add crypto

This commit is contained in:
zack 2025-07-22 20:21:21 -04:00
parent 90cbe489f6
commit af6a3bce3e
Signed by: zoey
GPG key ID: 81FB9FECDD6A33E2
120 changed files with 24616 additions and 462 deletions

View file

@ -0,0 +1,80 @@
import QtQuick
import QtQuick.Shapes
import "root:/Data" as Settings
// Concave corner shape component for rounded panel edges
Shape {
id: root
property string position: "topleft" // Corner position: topleft/topright/bottomleft/bottomright
property real size: 1.0 // Scale multiplier for entire corner
property int concaveWidth: 100 * size
property int concaveHeight: 60 * size
property int offsetX: -20
property int offsetY: -20
property color fillColor: Settings.Colors.bgColor
property int arcRadius: 20 * size
// Position flags derived from position string
property bool _isTop: position.includes("top")
property bool _isLeft: position.includes("left")
property bool _isRight: position.includes("right")
property bool _isBottom: position.includes("bottom")
// Base coordinates for left corner shape
property real _baseStartX: 30 * size
property real _baseStartY: _isTop ? 20 * size : 0
property real _baseLineX: 30 * size
property real _baseLineY: _isTop ? 0 : 20 * size
property real _baseArcX: 50 * size
property real _baseArcY: _isTop ? 20 * size : 0
// Mirror coordinates for right corners
property real _startX: _isRight ? (concaveWidth - _baseStartX) : _baseStartX
property real _startY: _baseStartY
property real _lineX: _isRight ? (concaveWidth - _baseLineX) : _baseLineX
property real _lineY: _baseLineY
property real _arcX: _isRight ? (concaveWidth - _baseArcX) : _baseArcX
property real _arcY: _baseArcY
// Arc direction varies by corner to maintain proper concave shape
property int _arcDirection: {
if (_isTop && _isLeft) return PathArc.Counterclockwise
if (_isTop && _isRight) return PathArc.Clockwise
if (_isBottom && _isLeft) return PathArc.Clockwise
if (_isBottom && _isRight) return PathArc.Counterclockwise
return PathArc.Counterclockwise
}
width: concaveWidth
height: concaveHeight
// Position relative to parent based on corner type
x: _isLeft ? offsetX : (parent ? parent.width - width + offsetX : 0)
y: _isTop ? offsetY : (parent ? parent.height - height + offsetY : 0)
preferredRendererType: Shape.CurveRenderer
layer.enabled: true
layer.samples: 4
ShapePath {
strokeWidth: 0
fillColor: root.fillColor
strokeColor: root.fillColor // Use same color as fill to eliminate artifacts
startX: root._startX
startY: root._startY
PathLine {
x: root._lineX
y: root._lineY
}
PathArc {
x: root._arcX
y: root._arcY
radiusX: root.arcRadius
radiusY: root.arcRadius
useLargeArc: false
direction: root._arcDirection
}
}
}

View file

@ -0,0 +1,48 @@
import QtQuick
QtObject {
id: root
// Keep track of loaded components
property var activeLoaders: ({})
// Dynamically load a QML component
function load(componentUrl, parent, properties) {
if (!activeLoaders[componentUrl]) {
var loader = Qt.createQmlObject(`
import QtQuick
Loader {
active: false
asynchronous: true
visible: false
}
`, parent);
loader.source = componentUrl
loader.active = true
if (properties) {
for (var prop in properties) {
loader[prop] = properties[prop]
}
}
activeLoaders[componentUrl] = loader
}
return activeLoaders[componentUrl]
}
// Destroy and remove a loaded component
function unload(componentUrl) {
if (activeLoaders[componentUrl]) {
activeLoaders[componentUrl].active = false
activeLoaders[componentUrl].destroy()
delete activeLoaders[componentUrl]
}
}
// Check if a component is loaded
function isLoaded(componentUrl) {
return !!activeLoaders[componentUrl]
}
}

View file

@ -0,0 +1,175 @@
pragma Singleton
import QtQuick
import Quickshell.Io
// System process and resource monitoring
QtObject {
id: root
// System resource metrics
property real cpuUsage: 0
property real ramUsage: 0
property real totalRam: 0
property real usedRam: 0
// System control processes
property Process shutdownProcess: Process {
command: ["shutdown", "-h", "now"]
}
property Process rebootProcess: Process {
command: ["reboot"]
}
property Process lockProcess: Process {
command: ["hyprlock"]
}
property Process logoutProcess: Process {
command: ["loginctl", "terminate-user", "$USER"]
}
property Process pavucontrolProcess: Process {
command: ["pavucontrol"]
}
// Resource monitoring processes
property Process cpuProcess: Process {
command: ["sh", "-c", "grep '^cpu ' /proc/stat | awk '{usage=($2+$3+$4)*100/($2+$3+$4+$5)} END {print usage}'"]
stdout: SplitParser {
onRead: data => {
root.cpuUsage = parseFloat(data)
}
}
}
property Process ramProcess: Process {
command: ["sh", "-c", "free -b | awk '/Mem:/ {print $2\" \"$3\" \"$3/$2*100}'"]
stdout: SplitParser {
onRead: data => {
var parts = data.trim().split(/\s+/)
if (parts.length >= 3) {
root.totalRam = parseFloat(parts[0]) / (1024 * 1024 * 1024)
root.usedRam = parseFloat(parts[1]) / (1024 * 1024 * 1024)
root.ramUsage = parseFloat(parts[2])
}
}
}
}
// Monitoring timers (start manually when needed)
property Timer cpuTimer: Timer {
interval: 30000
running: false
repeat: true
onTriggered: {
cpuProcess.running = false
cpuProcess.running = true
}
}
property Timer ramTimer: Timer {
interval: 30000
running: false
repeat: true
onTriggered: {
ramProcess.running = false
ramProcess.running = true
}
}
// System control functions
function shutdown() {
console.log("Executing shutdown command")
shutdownProcess.running = true
}
function reboot() {
console.log("Executing reboot command")
rebootProcess.running = true
}
function lock() {
console.log("Executing lock command")
lockProcess.running = true
}
function logout() {
console.log("Executing logout command")
logoutProcess.running = true
}
function openPavuControl() {
console.log("Opening PavuControl")
pavucontrolProcess.running = true
}
// Performance monitoring control
function startMonitoring() {
console.log("Starting system monitoring")
cpuTimer.running = true
ramTimer.running = true
}
function stopMonitoring() {
console.log("Stopping system monitoring")
cpuTimer.running = false
ramTimer.running = false
}
function setMonitoringInterval(intervalMs) {
console.log("Setting monitoring interval to", intervalMs, "ms")
cpuTimer.interval = intervalMs
ramTimer.interval = intervalMs
}
function refreshSystemStats() {
console.log("Manually refreshing system stats")
cpuProcess.running = false
cpuProcess.running = true
ramProcess.running = false
ramProcess.running = true
}
// Process state queries
function isShutdownRunning() { return shutdownProcess.running }
function isRebootRunning() { return rebootProcess.running }
function isLockRunning() { return lockProcess.running }
function isLogoutRunning() { return logoutProcess.running }
function isPavuControlRunning() { return pavucontrolProcess.running }
function isMonitoringActive() { return cpuTimer.running && ramTimer.running }
function stopPavuControl() {
pavucontrolProcess.running = false
}
// Formatted output helpers
function getCpuUsageFormatted() {
return Math.round(cpuUsage) + "%"
}
function getRamUsageFormatted() {
return Math.round(ramUsage) + "% (" + usedRam.toFixed(1) + "GB/" + totalRam.toFixed(1) + "GB)"
}
function getRamUsageSimple() {
return Math.round(ramUsage) + "%"
}
Component.onDestruction: {
// Stop all timers
cpuTimer.running = false
ramTimer.running = false
// Stop monitoring processes
cpuProcess.running = false
ramProcess.running = false
// Stop control processes if running
if (shutdownProcess.running) shutdownProcess.running = false
if (rebootProcess.running) rebootProcess.running = false
if (lockProcess.running) lockProcess.running = false
if (logoutProcess.running) logoutProcess.running = false
if (pavucontrolProcess.running) pavucontrolProcess.running = false
}
}

View file

@ -0,0 +1,265 @@
import QtQuick
import QtQuick.Layouts
import Quickshell
import Quickshell.Wayland
import Quickshell.Io
import "root:/Data" as Data
// System version watermark display
PanelWindow {
id: systemVersion
anchors {
right: true
bottom: true
}
margins {
right: 60
bottom: 60
}
visible: false
implicitWidth: systemInfoContent.width
implicitHeight: systemInfoContent.height
color: "transparent"
mask: Region {}
WlrLayershell.layer: WlrLayer.Background
WlrLayershell.exclusiveZone: 0
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
WlrLayershell.namespace: "quickshell-version"
Timer {
id: startupTimer
interval: 1500
running: true
onTriggered: {
visible = true
}
}
component Details: QtObject {
property string version
property string commit
}
property QtObject os: QtObject {
property string name: "Loading..."
property Details details: Details {
property string generation: "?"
}
}
property QtObject wm: QtObject {
property string name: "Loading..."
property Details details: Details {}
}
Component.onCompleted: {
osFile.reload();
genProcess.running = true;
wmProcess.running = true;
niriProcess.running = true;
}
// Periodic refresh disabled - version info rarely changes
Timer {
running: false
interval: 300000
repeat: true
onTriggered: {
osFile.reload();
genProcess.running = true;
wmProcess.running = true;
niriProcess.running = true;
}
}
// Parse OS info from /etc/os-release
FileView {
id: osFile
path: "/etc/os-release"
onLoaded: {
const data = text().trim().split("\n");
const nameLine = data.find((str) => str.match(/^NAME=/));
const versionLine = data.find((str) => str.match(/^VERSION_ID=/));
const buildLine = data.find((str) => str.match(/^BUILD_ID=/));
if (nameLine) {
systemVersion.os.name = nameLine.split("=")[1].replace(/"/g, "");
}
if (versionLine) {
systemVersion.os.details.version = versionLine.split("=")[1].replace(/"/g, "");
}
if (buildLine) {
const commit = buildLine.split("=")[1].split(".")[3];
if (commit) {
systemVersion.os.details.commit = commit.replace(/"/g, "").toUpperCase();
}
}
}
}
// Get NixOS generation number
Process {
id: genProcess
running: true
command: ["sh", "-c", "nixos-rebuild list-generations"]
stdout: SplitParser {
splitMarker: ""
onRead: (data) => {
const line = data.trim().split("\n").find((str) => str.match(/current/));
if (line) {
const current = line.split(" ")[0];
systemVersion.os.details.generation = current;
}
}
}
}
// Detect desktop environment
Process {
id: wmProcess
running: true
command: ["sh", "-c", "echo $XDG_CURRENT_DESKTOP"]
stdout: SplitParser {
splitMarker: ""
onRead: (data) => {
const result = data.trim();
if (result && result !== "") {
systemVersion.wm.name = result;
}
}
}
}
// Get Niri compositor version
Process {
id: niriProcess
running: true
command: ["sh", "-c", "niri msg version"]
stdout: SplitParser {
splitMarker: ""
onRead: (data) => {
const output = data.trim();
const compositorMatch = output.match(/Compositor version: (\S+)/);
if (compositorMatch && compositorMatch[1]) {
systemVersion.wm.details.version = compositorMatch[1];
}
const commitMatch = output.match(/\((\S+)\)/);
if (commitMatch && commitMatch[1]) {
systemVersion.wm.details.commit = commitMatch[1].toUpperCase();
}
}
}
}
// macOS-inspired typography layout
ColumnLayout {
id: systemInfoContent
spacing: 6
RowLayout {
spacing: 16
Layout.alignment: Qt.AlignRight
// OS information
ColumnLayout {
spacing: 2
Layout.alignment: Qt.AlignRight
Text {
text: systemVersion.os.name
color: (Data.ThemeManager.currentTheme && Data.ThemeManager.currentTheme.type === "dark") ? "#40ffffff" : "#40000000"
font.family: "SF Pro Display, -apple-system, system-ui, sans-serif"
font.pointSize: 16
font.weight: Font.DemiBold
font.letterSpacing: -0.4
Layout.alignment: Qt.AlignRight
}
Text {
text: {
let details = [];
if (systemVersion.os.details.version) {
details.push(systemVersion.os.details.version);
}
if (systemVersion.os.details.commit) {
details.push("(" + systemVersion.os.details.commit + ")");
}
if (systemVersion.os.details.generation && systemVersion.os.details.generation !== "?") {
details.push("Gen " + systemVersion.os.details.generation);
}
return details.join(" ");
}
color: (Data.ThemeManager.currentTheme && Data.ThemeManager.currentTheme.type === "dark") ? "#30ffffff" : "#30000000"
font.family: "SF Mono, Consolas, Monaco, monospace"
font.pointSize: 10
font.weight: Font.Medium
visible: text.length > 0
Layout.alignment: Qt.AlignRight
}
}
Text {
text: "│"
color: (Data.ThemeManager.currentTheme && Data.ThemeManager.currentTheme.type === "dark") ? "#20ffffff" : "#20000000"
font.family: "SF Pro Display, -apple-system, system-ui, sans-serif"
font.pointSize: 14
font.weight: Font.Light
Layout.alignment: Qt.AlignCenter
}
// Window manager information
ColumnLayout {
spacing: 2
Layout.alignment: Qt.AlignRight
Text {
text: systemVersion.wm.name
color: (Data.ThemeManager.currentTheme && Data.ThemeManager.currentTheme.type === "dark") ? "#40ffffff" : "#40000000"
font.family: "SF Pro Display, -apple-system, system-ui, sans-serif"
font.pointSize: 16
font.weight: Font.DemiBold
font.letterSpacing: -0.4
Layout.alignment: Qt.AlignRight
}
Text {
text: {
let details = [];
if (systemVersion.wm.details.version) {
details.push(systemVersion.wm.details.version);
}
if (systemVersion.wm.details.commit) {
details.push("(" + systemVersion.wm.details.commit + ")");
}
return details.join(" ");
}
color: (Data.ThemeManager.currentTheme && Data.ThemeManager.currentTheme.type === "dark") ? "#30ffffff" : "#30000000"
font.family: "SF Mono, Consolas, Monaco, monospace"
font.pointSize: 10
font.weight: Font.Medium
visible: text.length > 0
Layout.alignment: Qt.AlignRight
}
}
}
}
Component.onDestruction: {
if (genProcess.running) genProcess.running = false
if (wmProcess.running) wmProcess.running = false
if (niriProcess.running) niriProcess.running = false
}
}

View file

@ -0,0 +1,47 @@
import QtQuick
import Quickshell
import Quickshell.Wayland
import "root:/Data" as Data
// Wallpaper background layer
PanelWindow {
id: wallpaperWindow
required property var screen
anchors {
top: true
left: true
right: true
bottom: true
}
margins.top: 0
margins.left: 0
margins.right: 0
margins.bottom: 0
exclusiveZone: 0
WlrLayershell.layer: WlrLayer.Background
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
WlrLayershell.namespace: "quickshell-wallpaper"
color: "transparent"
visible: true
Image {
id: wallpaperImage
anchors.fill: parent
source: Data.WallpaperManager.currentWallpaper
fillMode: Image.PreserveAspectCrop
asynchronous: true
cache: false // Reduce memory usage
visible: true
// Fallback when wallpaper fails to load
Rectangle {
id: fallbackBackground
anchors.fill: parent
color: Data.ThemeManager.bgColor
visible: wallpaperImage.status !== Image.Ready || !wallpaperImage.source
}
}
}