updated pi, quickshell, and ollama

This commit is contained in:
2026-08-31 20:17:31 -07:00
parent 1f3dde6de2
commit e09304b0b6
16 changed files with 2290 additions and 315 deletions

193
flake.lock generated
View File

@@ -7,11 +7,11 @@
]
},
"locked": {
"lastModified": 1786829626,
"narHash": "sha256-Yg4SMZkoln6bEwAUPDhqCU7XWC1REPtHaerrhKf9eew=",
"lastModified": 1787879739,
"narHash": "sha256-F8R8x75eBMGox1Z9pmLhwEH2bjlZDeUGDIkOtzAOVq0=",
"owner": "Hy4ri",
"repo": "antigravity-flake",
"rev": "bf9c75d727c829794599434cbb29db774dd9ce77",
"rev": "d8581e462a2dde4469e056b736b352978ec7db98",
"type": "github"
},
"original": {
@@ -20,17 +20,45 @@
"type": "github"
}
},
"bun2nix": {
"inputs": {
"flake-parts": "flake-parts_2",
"nixpkgs": [
"pi",
"nixpkgs"
],
"systems": [
"pi",
"systems"
],
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1778446047,
"narHash": "sha256-oQvcadh2BCkrog+SGrG6YffKJrveYpjj3TdQJWaKhaM=",
"owner": "nix-community",
"repo": "bun2nix",
"rev": "f2bc12af1a6369648aac41041ceeaa0b866599c6",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "2.1.0",
"repo": "bun2nix",
"type": "github"
}
},
"comfy-ui": {
"inputs": {
"flake-parts": "flake-parts",
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1786714237,
"narHash": "sha256-XnXKBpaidykfCegAqBGI7/F61IFtMSKUibQct/dP2Zw=",
"lastModified": 1787851822,
"narHash": "sha256-xLLT67dZFyhNTmPTtpQvaruFHrv0ENB5B082C1NvDmA=",
"owner": "utensils",
"repo": "comfyui-nix",
"rev": "4501c5fe8dd93530d856866ba8bc4b585b508d41",
"rev": "9c0c693afe7e355b69fdc73dc0b28a628426a814",
"type": "github"
},
"original": {
@@ -77,6 +105,28 @@
"type": "github"
}
},
"flake-parts_2": {
"inputs": {
"nixpkgs-lib": [
"pi",
"bun2nix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1777988971,
"narHash": "sha256-qIoWPDs+0/8JecyYgE3gpKQxW/4bLW/gp45vow9ioCQ=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "0678d8986be1661af6bb555f3489f2fdfc31f6ff",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"herdr": {
"inputs": {
"nixpkgs": [
@@ -85,11 +135,11 @@
"rust-overlay": "rust-overlay"
},
"locked": {
"lastModified": 1787017031,
"narHash": "sha256-FeF4eZhxRl4jBbAkMaEzDCmMcaitV6GZapjaeeNZy7A=",
"lastModified": 1788211360,
"narHash": "sha256-8wrp7NLYPRaZ9hL7QiqSDQFRme/1UrVwoEDs278aOUA=",
"owner": "herdrdev",
"repo": "herdr",
"rev": "2d24950ad9a02096921bc764e2e3dcd8900c3366",
"rev": "5158adab10b6dcfea9370782043392f80fa0643c",
"type": "github"
},
"original": {
@@ -105,11 +155,11 @@
]
},
"locked": {
"lastModified": 1785119570,
"narHash": "sha256-Rgs2xKnGLFWQscxUaXX07oyZeuMDOHEbqDOsgliLFGM=",
"lastModified": 1787377438,
"narHash": "sha256-Sxu1NLTD/Ern6hFGLlZmtKCSct3YQXZI/lls8RE1XeM=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "d4fd24667c8cbef124bb70a20380cab75ec8474d",
"rev": "65258d5c65a250189fde2e35f490d15e064c4c62",
"type": "github"
},
"original": {
@@ -119,16 +169,31 @@
"type": "github"
}
},
"jail-nix": {
"locked": {
"lastModified": 1776230864,
"narHash": "sha256-YsEjjdOsGEzTeD+iT7ONh071BqWAOQWpzYVei3okAXE=",
"owner": "~alexdavid",
"repo": "jail.nix",
"rev": "404e7da9da5ab9aa643666682b2ba1312fa5fbe8",
"type": "sourcehut"
},
"original": {
"owner": "~alexdavid",
"repo": "jail.nix",
"type": "sourcehut"
}
},
"nixos-hardware": {
"inputs": {
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1786717298,
"narHash": "sha256-asdPlqtM0AweQ5YNLad6eY4tSYW55YNr1uyayf7mOMQ=",
"lastModified": 1788044418,
"narHash": "sha256-cmOd3iGoE140M2GidgQMQbyxHZ4dT7C0QZq2+CrXQyA=",
"owner": "NixOS",
"repo": "nixos-hardware",
"rev": "2dda192987ab6815e44df0130f03d6c907b79134",
"rev": "dc3f0cfde2050172abf6c3cdb684f735c15a57c5",
"type": "github"
},
"original": {
@@ -171,11 +236,11 @@
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1786862985,
"narHash": "sha256-FBJRXmbGXiSUDvYEbfLYRkckayyZ6SK1UEqhCrIZ2Cs=",
"lastModified": 1788179007,
"narHash": "sha256-hn1oU2rue2SYK8dAr8+WNZWtbsz1S2W5mnHlSEuh3bo=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e5bdc4a41d4c072fe1e3787eaa0320a384741d44",
"rev": "34ab99075ac4f7e40cf037eef32cb1c360bb85e9",
"type": "github"
},
"original": {
@@ -200,11 +265,11 @@
},
"nixpkgs_3": {
"locked": {
"lastModified": 1786711500,
"narHash": "sha256-QvnceIGTBeDvDd9oCn+GvdsnkquliuwbVgpiRH68qaQ=",
"lastModified": 1787962033,
"narHash": "sha256-u6z9VTZA4Kf3RkHQo9sQI7NI4Ei/uiU9vrMqOiwWP1Y=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "02e08985a27c65ffd33d434eeb2e660a2e4dc84d",
"rev": "c5c4a43b0e8056328ec4529f735cabdb8f1942bb",
"type": "github"
},
"original": {
@@ -214,24 +279,41 @@
"type": "github"
}
},
"quickshell": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"nixpkgs_4": {
"locked": {
"lastModified": 1786864924,
"narHash": "sha256-9nqIJWuSlAwy4Vs98N9ffoVeU2dmsWcAJ7/DyIDihqM=",
"ref": "refs/heads/master",
"rev": "532a0606cafb05851a203e65be22c9a057447ee2",
"revCount": 844,
"type": "git",
"url": "https://git.outfoxxed.me/outfoxxed/quickshell"
"lastModified": 1773646010,
"narHash": "sha256-iYrs97hS7p5u4lQzuNWzuALGIOdkPXvjz7bviiBjUu8=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "5b2c2d84341b2afb5647081c1386a80d7a8d8605",
"type": "github"
},
"original": {
"type": "git",
"url": "https://git.outfoxxed.me/outfoxxed/quickshell"
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"pi": {
"inputs": {
"bun2nix": "bun2nix",
"jail-nix": "jail-nix",
"nixpkgs": "nixpkgs_4",
"systems": "systems"
},
"locked": {
"lastModified": 1788173678,
"narHash": "sha256-u0YZmQ8Z5luYELFHA6GAQ68HT2Dh5kU3sMFLQ68+2P0=",
"owner": "lukasl-dev",
"repo": "pi.nix",
"rev": "2a11906417b5f2bd9e8f9130da31dfbdfeffecda",
"type": "github"
},
"original": {
"owner": "lukasl-dev",
"repo": "pi.nix",
"type": "github"
}
},
"root": {
@@ -244,7 +326,7 @@
"nixos-hardware": "nixos-hardware",
"nixpkgs": "nixpkgs_3",
"nixpkgs-unstable": "nixpkgs-unstable",
"quickshell": "quickshell"
"pi": "pi"
}
},
"rust-overlay": {
@@ -267,6 +349,43 @@
"repo": "rust-overlay",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"pi",
"bun2nix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1775636079,
"narHash": "sha256-pc20NRoMdiar8oPQceQT47UUZMBTiMdUuWrYu2obUP0=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "790751ff7fd3801feeaf96d7dc416a8d581265ba",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
}
},
"root": "root",

View File

@@ -25,15 +25,15 @@
url = "github:utensils/comfyui-nix";
};
quickshell = {
url = "git+https://git.outfoxxed.me/outfoxxed/quickshell";
inputs.nixpkgs.follows = "nixpkgs";
};
herdr = {
url = "github:herdrdev/herdr";
inputs.nixpkgs.follows = "nixpkgs";
};
pi = {
url = "github:lukasl-dev/pi.nix";
};
};
outputs =
@@ -48,6 +48,12 @@
inputs.home-manager.nixosModules.home-manager
{
nixpkgs.overlays = [
(final: prev: {
unstable = import inputs.nixpkgs-unstable {
inherit (final) system;
config.allowUnfree = true;
};
})
inputs.antigravity.overlays.default
inputs.comfy-ui.overlays.default
];

View File

@@ -7,6 +7,8 @@
./brave.nix
./zsh.nix
./nvim
./pi.nix
];
xdg.portal.config.common.default = "*";

View File

@@ -47,6 +47,20 @@ QtObject {
property bool batteryCharging: false
property string batteryStatus: "Full"
// GPU VRAM Monitoring (NVIDIA)
property string gpuVramUsed: "0"
property string gpuVramTotal: "0"
property int gpuVramPercent: 0
// System HUD state (replaces individual popup states)
property bool systemHudVisible: false
property string systemHudActiveSection: "" // "volume", "wifi", "calendar", etc.
// Workspace tracking
property int activeWorkspace: 1
property var workspaceList: [1, 2, 3, 4, 5]
property var workspaceNames: ({1: "main", 2: "browser", 3: "code", 4: "media", 5: "misc"})
// Media Player State (MPRIS)
property string mediaTitle: ""
property string mediaArtist: ""
@@ -60,6 +74,7 @@ QtObject {
wifiPopupVisible = false;
batteryPopupVisible = false;
calendarPopupVisible = false;
systemHudVisible = false;
}
function toggleSpotlight() {
@@ -77,12 +92,25 @@ QtObject {
aboutMacVisible = !aboutMacVisible;
}
function toggleSystemHud() {
closeAllPopups();
systemHudVisible = !systemHudVisible;
}
function switchWorkspace(n) {
Hyprland.dispatch("workspace " + n);
}
// Hyprland raw event processing
readonly property Connections hyprConn: Connections {
target: Hyprland
function onRawEvent(event) {
function onRawEvent(event) { console.log(JSON.stringify(event), event.name, event.event, event.data);
if (!event) return;
if (event.startsWith("activewindow>>")) {
if (event.startsWith("workspace>>")) {
const data = event.substring(11);
const wsNum = parseInt(data);
if (!isNaN(wsNum)) root.activeWorkspace = wsNum;
} else if (event.startsWith("activewindow>>")) {
const data = event.substring(14);
const parts = data.split(",");
const title = parts[1] ? parts[1].trim() : (parts[0] ? parts[0].trim() : "");
@@ -127,6 +155,7 @@ QtObject {
audioProc.running = true;
brightProc.running = true;
mprisProc.running = true;
gpuProc.running = true;
}
}
@@ -135,7 +164,7 @@ QtObject {
command: ["bash", "-c", "read -r c u n s i io ir st g gn < /proc/stat; t1=$((u+n+s+i+io+ir+st+g+gn)); i1=$((i+io)); sleep 0.15; read -r c u n s i io ir st g gn < /proc/stat; t2=$((u+n+s+i+io+ir+st+g+gn)); i2=$((i+io)); td=$((t2-t1)); id=$((i2-i1)); [ $td -gt 0 ] && echo $(( (td-id)*100/td )) || echo 0"]
stdout: StdioCollector {
onDataChanged: {
const val = parseInt(data.trim());
const val = parseInt(String(data).trim());
if (!isNaN(val)) root.cpuPercent = Math.max(0, Math.min(100, val));
}
}
@@ -145,7 +174,7 @@ QtObject {
command: ["bash", "-c", "t=$(grep MemTotal /proc/meminfo | awk '{print $2}'); a=$(grep MemAvailable /proc/meminfo | awk '{print $2}'); if [ -n \"$t\" ] && [ -n \"$a\" ] && [ \"$t\" -gt 0 ]; then u=$((t-a)); p=$((u*100/t)); ug=$(awk \"BEGIN {printf \\\"%.1f\\\", $u/1048576}\"); tg=$(awk \"BEGIN {printf \\\"%.1f\\\", $t/1048576}\"); echo \"$p $ug $tg\"; fi"]
stdout: StdioCollector {
onDataChanged: {
const parts = data.trim().split(" ");
const parts = String(data).trim().split(" ");
if (parts.length >= 3) {
root.memPercent = parseInt(parts[0]) || 0;
root.memUsedGb = parts[1];
@@ -159,7 +188,7 @@ QtObject {
command: ["bash", "-c", "b=$(find /sys/class/power_supply/ -name 'BAT*' 2>/dev/null | head -n 1); if [ -n \"$b\" ]; then cap=$(cat $b/capacity 2>/dev/null || echo 100); st=$(cat $b/status 2>/dev/null || echo Full); echo \"1 $cap $st\"; else echo \"0 100 AC\"; fi"]
stdout: StdioCollector {
onDataChanged: {
const parts = data.trim().split(" ");
const parts = String(data).trim().split(" ");
if (parts.length >= 3) {
root.batteryPresent = parts[0] === "1";
root.batteryPercent = parseInt(parts[1]) || 100;
@@ -174,7 +203,7 @@ QtObject {
command: ["bash", "-c", "ssid=\"\"; if command -v nmcli &>/dev/null; then ssid=$(nmcli -t -f active,ssid dev wifi 2>/dev/null | grep '^yes:' | cut -d':' -f2); fi; [ -z \"$ssid\" ] && [ -f /proc/net/wireless ] && ssid=$(iwgetid -r 2>/dev/null); ip=$(ip -4 route get 1.1.1.1 2>/dev/null | awk '{print $7; exit}'); echo \"${ssid:-Ethernet} ${ip:-Offline}\""]
stdout: StdioCollector {
onDataChanged: {
const str = data.trim();
const str = String(data).trim();
const parts = str.split(" ");
if (parts.length >= 2) {
root.wifiSsid = parts[0];
@@ -189,7 +218,7 @@ QtObject {
command: ["bash", "-c", "if command -v pactl &>/dev/null; then v=$(pactl get-sink-volume @DEFAULT_SINK@ 2>/dev/null | grep -Po '[0-9]+(?=%)' | head -n 1); m=$(pactl get-sink-mute @DEFAULT_SINK@ 2>/dev/null | grep -q yes && echo 1 || echo 0); echo \"${v:-50} $m\"; fi"]
stdout: StdioCollector {
onDataChanged: {
const parts = data.trim().split(" ");
const parts = String(data).trim().split(" ");
if (parts.length >= 2) {
root.volume = parseInt(parts[0]) || 50;
root.volumeMuted = parts[1] === "1";
@@ -202,7 +231,7 @@ QtObject {
command: ["bash", "-c", "if command -v brightnessctl &>/dev/null; then b=$(brightnessctl -m 2>/dev/null | cut -d, -f4 | tr -d '%'); echo \"${b:-100}\"; else echo 100; fi"]
stdout: StdioCollector {
onDataChanged: {
const val = parseInt(data.trim());
const val = parseInt(String(data).trim());
if (!isNaN(val)) root.brightness = val;
}
}
@@ -212,7 +241,7 @@ QtObject {
command: ["bash", "-c", "if command -v playerctl &>/dev/null; then t=$(playerctl metadata title 2>/dev/null); a=$(playerctl metadata artist 2>/dev/null); s=$(playerctl status 2>/dev/null); echo \"$s|$t|$a\"; fi"]
stdout: StdioCollector {
onDataChanged: {
const parts = data.trim().split("|");
const parts = String(data).trim().split("|");
if (parts.length >= 3) {
root.mediaPlaying = parts[0] === "Playing";
root.mediaTitle = parts[1] || "";
@@ -226,12 +255,30 @@ QtObject {
}
}
readonly property Process gpuProc: Process {
command: ["bash", "-c", "nvidia-smi --query-gpu=memory.used,memory.total --format=csv,noheader,nounits 2>/dev/null || echo '0, 0'"]
stdout: StdioCollector {
onDataChanged: {
const parts = String(data).trim().split(",");
if (parts.length >= 2) {
const usedMiB = parseInt(parts[0].trim());
const totalMiB = parseInt(parts[1].trim());
if (!isNaN(usedMiB) && !isNaN(totalMiB) && totalMiB > 0) {
root.gpuVramUsed = (usedMiB / 1024).toFixed(1);
root.gpuVramTotal = (totalMiB / 1024).toFixed(1);
root.gpuVramPercent = Math.round((usedMiB / totalMiB) * 100);
}
}
}
}
}
readonly property Process clientsProc: Process {
command: ["bash", "-c", "if command -v hyprctl &>/dev/null; then hyprctl -j clients 2>/dev/null; else echo '[]'; fi"]
stdout: StdioCollector {
onDataChanged: {
try {
const parsed = JSON.parse(data.trim());
const parsed = JSON.parse(String(data).trim());
if (Array.isArray(parsed)) {
root.runningApps = parsed;
}

View File

@@ -0,0 +1,190 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Quickshell
import Quickshell.Wayland
import Quickshell.Io
import "../theme"
import ".."
PanelWindow {
id: quickMenu
WlrLayershell.layer: WlrLayer.Overlay
WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
anchors {
top: true
left: true
}
margins {
top: 0
left: Theme.sidebarWidth
}
visible: GlobalState.appleMenuVisible
implicitWidth: 220
implicitHeight: menuContainer.implicitHeight
color: "transparent"
// Close on escape
Item {
anchors.fill: parent
focus: true
Keys.onEscapePressed: GlobalState.appleMenuVisible = false
}
Rectangle {
id: menuContainer
anchors.fill: parent
color: Theme.glassBg
border.color: Theme.glassBorder
border.width: 1
Column {
width: parent.width
padding: 8
component MenuItem: Item {
id: menuItem
width: parent.width
height: 28
property string text: ""
property string shortcut: ""
signal triggered()
Rectangle {
anchors.fill: parent
color: menuItemMouseArea.containsMouse ? Qt.rgba(Theme.accentVolt.r, Theme.accentVolt.g, Theme.accentVolt.b, 0.1) : "transparent"
}
Rectangle {
anchors.left: parent.left
anchors.top: parent.top
anchors.bottom: parent.bottom
width: 2
color: Theme.accentVolt
visible: menuItemMouseArea.containsMouse
}
Text {
anchors.left: parent.left
anchors.leftMargin: 12
anchors.verticalCenter: parent.verticalCenter
text: menuItem.text
font.family: Theme.fontSans
font.pixelSize: 13
color: menuItemMouseArea.containsMouse ? Theme.textPrimary : Theme.textSecondary
}
Text {
anchors.right: parent.right
anchors.rightMargin: 12
anchors.verticalCenter: parent.verticalCenter
text: menuItem.shortcut
font.family: Theme.fontMono
font.pixelSize: 11
color: Theme.textMuted
visible: text !== ""
}
MouseArea {
id: menuItemMouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: {
menuItem.triggered()
GlobalState.appleMenuVisible = false
}
}
}
component MenuSeparator: Item {
width: parent.width
height: 17
Rectangle {
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 12
anchors.rightMargin: 12
height: 1
color: Theme.glassBorder
}
}
MenuItem {
text: "System Info..."
onTriggered: GlobalState.aboutMacVisible = true
}
MenuItem {
text: "System Preferences..."
onTriggered: {
let p = Qt.createQmlObject('import Quickshell.Io; Process { command: ["pavucontrol"] }', quickMenu)
p.running = true
}
}
MenuItem {
text: "Activity Monitor"
shortcut: "btop"
onTriggered: {
let p = Qt.createQmlObject('import Quickshell.Io; Process { command: ["foot", "-e", "btop"] }', quickMenu)
p.running = true
}
}
MenuSeparator {}
MenuItem {
text: "Sleep"
onTriggered: {
let p = Qt.createQmlObject('import Quickshell.Io; Process { command: ["systemctl", "suspend"] }', quickMenu)
p.running = true
}
}
MenuItem {
text: "Restart..."
onTriggered: {
let p = Qt.createQmlObject('import Quickshell.Io; Process { command: ["systemctl", "reboot"] }', quickMenu)
p.running = true
}
}
MenuItem {
text: "Shut Down..."
onTriggered: {
let p = Qt.createQmlObject('import Quickshell.Io; Process { command: ["systemctl", "poweroff"] }', quickMenu)
p.running = true
}
}
MenuSeparator {}
MenuItem {
text: "Lock Screen"
shortcut: "Super+L"
onTriggered: {
let p = Qt.createQmlObject('import Quickshell.Io; Process { command: ["hyprlock"] }', quickMenu)
p.running = true
}
}
MenuItem {
text: "Log Out"
shortcut: "Super+Shift+Q"
onTriggered: {
let p = Qt.createQmlObject('import Quickshell.Io; Process { command: ["hyprctl", "dispatch", "exit"] }', quickMenu)
p.running = true
}
}
}
}
}

View File

@@ -0,0 +1,531 @@
import QtQuick
import QtQuick.Layouts
import Quickshell
import Quickshell.Hyprland
import Quickshell.Wayland
import "../theme"
import ".."
PanelWindow {
id: root
property var screen
WlrLayershell.layer: WlrLayer.Top
WlrLayershell.namespace: "quickshell-sidepanel"
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
anchors {
top: true
bottom: true
left: true
right: false
}
exclusiveZone: Theme.sidebarWidth
implicitWidth: Theme.sidebarWidth
color: Theme.bgPrimary
// Right edge hairline border
Rectangle {
width: 1
color: Theme.glassBorder
anchors {
right: parent.right
top: parent.top
bottom: parent.bottom
}
}
component Separator: Rectangle {
width: 36
height: 1
color: Theme.glassBorder
Layout.alignment: Qt.AlignHCenter
}
component DockIcon: Item {
id: dockIconRoot
width: 36
height: 36
Layout.alignment: Qt.AlignHCenter
property string appClass: ""
property string execCmd: ""
property string iconSource: ""
property string tooltipText: ""
property bool isRunning: (appClass !== "" && GlobalState.activeWindowClass === appClass) || (GlobalState.runningApps && GlobalState.runningApps.indexOf(appClass) !== -1)
Image {
id: img
anchors.centerIn: parent
width: 24
height: 24
source: iconSource ? Qt.resolvedUrl("../assets/" + iconSource) : ""
sourceSize: Qt.size(24, 24)
fillMode: Image.PreserveAspectFit
opacity: mouseArea.containsMouse ? 1.0 : 0.8
scale: mouseArea.containsMouse ? 1.15 : 1.0
Behavior on scale {
NumberAnimation { duration: Theme.animFast; easing.type: Easing.OutCubic }
}
Behavior on opacity {
NumberAnimation { duration: Theme.animFast; easing.type: Easing.OutCubic }
}
}
Rectangle {
id: runningDot
width: 4
height: 4
radius: 2
color: Theme.accentVolt
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
visible: isRunning
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: {
if (execCmd !== "") {
GlobalState.launchApp(execCmd)
}
}
}
// Tooltip
Rectangle {
id: tooltip
visible: mouseArea.containsMouse && tooltipText !== ""
color: Theme.glassBg
radius: 4
width: tooltipLabel.implicitWidth + 16
height: tooltipLabel.implicitHeight + 8
anchors.left: parent.right
anchors.leftMargin: 24
anchors.verticalCenter: parent.verticalCenter
Text {
id: tooltipLabel
anchors.centerIn: parent
text: tooltipText
color: Theme.textPrimary
font.family: Theme.fontSans
font.pixelSize: 11
}
}
}
ColumnLayout {
anchors.fill: parent
spacing: 8
// Top spacer
Item { height: 4; Layout.fillWidth: true }
// 1. AG Logo Button
Rectangle {
width: 36
height: 36
radius: 4
color: logoMouse.containsMouse ? Qt.rgba(1,1,1,0.05) : "transparent"
Layout.alignment: Qt.AlignHCenter
Behavior on color {
ColorAnimation { duration: Theme.animFast; easing.type: Easing.OutCubic }
}
Text {
anchors.centerIn: parent
text: "AG"
font.family: Theme.fontSerif
font.italic: true
font.pixelSize: 16
color: Theme.accentVolt
}
MouseArea {
id: logoMouse
anchors.fill: parent
hoverEnabled: true
onClicked: GlobalState.appleMenuVisible = !GlobalState.appleMenuVisible
}
}
Separator {}
// 3. Workspace Indicators
Column {
Layout.alignment: Qt.AlignHCenter
spacing: 2
Repeater {
model: GlobalState.workspaceList
delegate: Rectangle {
width: 52
height: 36
color: wsMouse.containsMouse ? Qt.rgba(1,1,1,0.04) : "transparent"
property bool isActive: GlobalState.activeWorkspace === modelData
Behavior on color {
ColorAnimation { duration: Theme.animFast; easing.type: Easing.OutCubic }
}
Rectangle {
width: 2
height: 20
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
color: Theme.accentVolt
visible: isActive
}
Column {
anchors.centerIn: parent
spacing: 2
Text {
anchors.horizontalCenter: parent.horizontalCenter
text: (modelData < 10 ? "0" : "") + modelData
color: isActive ? Theme.accentVolt : Theme.textMuted
font.family: Theme.fontMono
font.pixelSize: 12
Behavior on color {
ColorAnimation { duration: Theme.animFast; easing.type: Easing.OutCubic }
}
}
Text {
anchors.horizontalCenter: parent.horizontalCenter
text: (GlobalState.workspaceNames && GlobalState.workspaceNames[modelData]) ? GlobalState.workspaceNames[modelData] : ""
color: Theme.textMuted
font.family: Theme.fontSans
font.pixelSize: 8
opacity: 0.7
}
}
MouseArea {
id: wsMouse
anchors.fill: parent
hoverEnabled: true
onClicked: GlobalState.switchWorkspace(modelData)
}
}
}
}
Separator {}
// 5. Spotlight trigger
Item {
width: 36
height: 36
Layout.alignment: Qt.AlignHCenter
Text {
anchors.centerIn: parent
text: "⌕"
font.pixelSize: 20
color: spotlightMouse.containsMouse ? Theme.accentVolt : Theme.textMuted
Behavior on color {
ColorAnimation { duration: Theme.animFast; easing.type: Easing.OutCubic }
}
}
MouseArea {
id: spotlightMouse
anchors.fill: parent
hoverEnabled: true
onClicked: GlobalState.toggleSpotlight()
}
}
Separator {}
// 7. Pinned Apps
Column {
Layout.alignment: Qt.AlignHCenter
spacing: 8
DockIcon {
appClass: ""
execCmd: "nautilus"
iconSource: "finder.svg"
tooltipText: "Finder"
}
DockIcon {
appClass: "brave-browser"
execCmd: "brave"
iconSource: "browser.svg"
tooltipText: "Brave Browser"
}
DockIcon {
appClass: "foot"
execCmd: "foot"
iconSource: "terminal.svg"
tooltipText: "Terminal"
}
DockIcon {
appClass: "nvim"
execCmd: "foot -e nvim"
iconSource: "code.svg"
tooltipText: "Code"
}
DockIcon {
appClass: "pavucontrol"
execCmd: "pavucontrol"
iconSource: "preferences.svg"
tooltipText: "Settings"
}
DockIcon {
appClass: ""
execCmd: "spotify"
iconSource: "music.svg"
tooltipText: "Music"
}
}
Separator {}
// 9. Running Apps (non-pinned)
Column {
Layout.alignment: Qt.AlignHCenter
spacing: 8
Repeater {
model: {
var pinned = ["foot", "brave-browser", "pavucontrol", "nvim", "nautilus", "spotify", ""]
var running = []
var seen = {}
if (GlobalState.runningApps) {
for (var i = 0; i < GlobalState.runningApps.length; i++) {
var cls = GlobalState.runningApps[i]
if (cls && pinned.indexOf(cls) === -1 && !seen[cls]) {
seen[cls] = true
running.push(cls)
}
}
}
return running
}
delegate: Item {
width: 36
height: 36
Rectangle {
anchors.centerIn: parent
width: 24
height: 24
radius: 12
color: Qt.rgba(1, 1, 1, 0.1)
Text {
anchors.centerIn: parent
text: modelData.charAt(0).toUpperCase()
color: Theme.textPrimary
font.family: Theme.fontSans
font.pixelSize: 12
}
}
Rectangle {
width: 4
height: 4
radius: 2
color: Theme.accentVolt
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onClicked: {
// Focus app logic here
}
}
}
}
}
// 10. Flexible spacer
Item { Layout.fillHeight: true }
Separator {}
// 12. Telemetry mini-readouts
Column {
Layout.alignment: Qt.AlignHCenter
spacing: 2
Text {
anchors.horizontalCenter: parent.horizontalCenter
text: "CPU" + (GlobalState.cpuPercent !== undefined ? GlobalState.cpuPercent : "0") + "%"
font.family: Theme.fontMono
font.pixelSize: 11
color: (GlobalState.cpuPercent !== undefined && GlobalState.cpuPercent > 80) ? Theme.accentCoral : Theme.textMuted
Behavior on color { ColorAnimation { duration: Theme.animFast; easing.type: Easing.OutCubic } }
}
Text {
anchors.horizontalCenter: parent.horizontalCenter
text: "RAM" + (GlobalState.memUsedGb !== undefined ? GlobalState.memUsedGb : "0") + "G"
font.family: Theme.fontMono
font.pixelSize: 11
color: (GlobalState.memPercent !== undefined && GlobalState.memPercent > 85) ? Theme.accentCoral : Theme.textMuted
Behavior on color { ColorAnimation { duration: Theme.animFast; easing.type: Easing.OutCubic } }
}
Text {
anchors.horizontalCenter: parent.horizontalCenter
text: "VRM" + (GlobalState.gpuVramUsed !== undefined ? GlobalState.gpuVramUsed : "0") + "G"
font.family: Theme.fontMono
font.pixelSize: 11
color: Theme.textMuted
}
}
Separator {}
// 14. System tray icons
Column {
Layout.alignment: Qt.AlignHCenter
spacing: 8
// Volume
Item {
width: 36
height: 36
Image {
anchors.centerIn: parent
width: 16
height: 16
source: Qt.resolvedUrl("../assets/volume.svg")
sourceSize: Qt.size(16, 16)
opacity: volMouse.containsMouse ? 1.0 : 0.7
Behavior on opacity { NumberAnimation { duration: Theme.animFast; easing.type: Easing.OutCubic } }
}
MouseArea {
id: volMouse
anchors.fill: parent
hoverEnabled: true
onClicked: {
GlobalState.systemHudActiveSection = "volume"
GlobalState.systemHudVisible = true
}
}
}
// WiFi
Item {
width: 36
height: 36
Image {
anchors.centerIn: parent
width: 16
height: 16
source: Qt.resolvedUrl("../assets/wifi.svg")
sourceSize: Qt.size(16, 16)
opacity: GlobalState.wifiConnected ? 0.7 : 0.3
Behavior on opacity { NumberAnimation { duration: Theme.animFast; easing.type: Easing.OutCubic } }
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onClicked: {
GlobalState.systemHudActiveSection = "network"
GlobalState.systemHudVisible = true
}
}
}
// Battery
Item {
width: 36
height: 44
visible: GlobalState.batteryPresent !== undefined ? GlobalState.batteryPresent : false
Column {
anchors.centerIn: parent
spacing: 2
Image {
anchors.horizontalCenter: parent.horizontalCenter
width: 16
height: 16
source: Qt.resolvedUrl("../assets/battery.svg")
sourceSize: Qt.size(16, 16)
opacity: (GlobalState.batteryPercent !== undefined && GlobalState.batteryPercent < 20) ? 1.0 : 0.7
}
Text {
anchors.horizontalCenter: parent.horizontalCenter
text: (GlobalState.batteryPercent !== undefined ? GlobalState.batteryPercent : "100") + "%"
font.family: Theme.fontMono
font.pixelSize: 9
color: (GlobalState.batteryPercent !== undefined && GlobalState.batteryPercent < 20) ? Theme.accentCoral : Theme.textSecondary
}
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onClicked: {
GlobalState.systemHudActiveSection = "battery"
GlobalState.systemHudVisible = true
}
}
}
}
Separator {}
// 16. Clock
Item {
width: 36
height: 44
Layout.alignment: Qt.AlignHCenter
Column {
anchors.centerIn: parent
spacing: 2
Text {
anchors.horizontalCenter: parent.horizontalCenter
text: GlobalState.timeString !== undefined ? GlobalState.timeString : "00:00"
font.family: Theme.fontMono
font.pixelSize: 12
color: Theme.textPrimary
}
Text {
anchors.horizontalCenter: parent.horizontalCenter
text: GlobalState.dateString !== undefined ? GlobalState.dateString : "Jan 01"
font.family: Theme.fontMono
font.pixelSize: 9
color: Theme.textMuted
}
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onClicked: {
GlobalState.systemHudActiveSection = "calendar"
GlobalState.systemHudVisible = true
}
}
}
// Bottom spacer
Item { height: 4; Layout.fillWidth: true }
}
}

View File

@@ -18,7 +18,7 @@ PanelWindow {
bottom: true
}
color: Qt.rgba(0, 0, 0, 0.35)
color: Qt.rgba(0, 0, 0, 0.45)
WlrLayershell.layer: WlrLayer.Overlay
WlrLayershell.namespace: "quickshell-spotlight"
WlrLayershell.keyboardFocus: visible ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
@@ -35,7 +35,7 @@ PanelWindow {
stdout: StdioCollector {
onDataChanged: {
try {
const parsed = JSON.parse(data.trim());
const parsed = JSON.parse(String(data).trim());
if (Array.isArray(parsed)) {
spotWindow.allApps = parsed;
}
@@ -67,15 +67,30 @@ PanelWindow {
}
// Centered Spotlight Search Modal
Rectangle {
id: modalBox
Item {
id: modalContainer
anchors.horizontalCenter: parent.horizontalCenter
y: 140
width: 640
implicitHeight: searchBarRow.height + (resultsListView.count > 0 || mathResultText !== "" ? 340 : 0)
radius: Theme.radiusModal
color: Theme.windowBg
border.color: Theme.windowBorder
height: modalBox.implicitHeight
scale: spotWindow.visible ? 1.0 : 0.96
opacity: spotWindow.visible ? 1.0 : 0.0
Behavior on scale {
NumberAnimation { duration: Theme.animSmooth; easing.type: Easing.OutQuint }
}
Behavior on opacity {
NumberAnimation { duration: Theme.animSmooth; easing.type: Easing.OutQuint }
}
Rectangle {
id: modalBox
anchors.fill: parent
implicitHeight: searchBarRowContainer.height + (resultsListView.count > 0 || mathResultText !== "" ? 340 : 0)
radius: 0
color: Theme.bgPrimary
border.color: Theme.glassBorder
border.width: 1
Behavior on implicitHeight {
@@ -89,30 +104,35 @@ PanelWindow {
}
ColumnLayout {
anchors.fill: parent
spacing: 0
// Top Search Bar Area
Item {
id: searchBarRowContainer
Layout.fillWidth: true
Layout.preferredHeight: 64
RowLayout {
id: searchBarRow
anchors.fill: parent
anchors.margins: 14
spacing: 12
// Top Search Bar
RowLayout {
id: searchBarRow
Layout.fillWidth: true
Layout.preferredHeight: 44
spacing: 12
Image {
width: 24
height: 24
source: "../assets/spotlight.svg"
sourceSize: Qt.size(24, 24)
Text {
text: "⌕"
font.family: Theme.fontSans
font.pixelSize: 24
color: Theme.accentVolt
Layout.alignment: Qt.AlignVCenter
}
TextInput {
id: searchInput
Layout.fillWidth: true
font.family: Theme.fontFamily
font.pixelSize: Theme.fontSizeSpotlight
font.weight: Font.Light
Layout.alignment: Qt.AlignVCenter
font.family: Theme.fontSans
font.pixelSize: 20
color: Theme.textPrimary
focus: true
clip: true
@@ -121,10 +141,9 @@ PanelWindow {
anchors.fill: parent
visible: searchInput.text === ""
text: "Spotlight Search"
font.family: Theme.fontFamily
font.pixelSize: Theme.fontSizeSpotlight
font.weight: Font.Light
color: Theme.textTertiary
font.family: Theme.fontSans
font.pixelSize: 20
color: Theme.textMuted
}
Keys.onEscapePressed: GlobalState.spotlightVisible = false
@@ -149,35 +168,45 @@ PanelWindow {
// Clear button
Rectangle {
visible: searchInput.text !== ""
width: 20
height: 20
radius: 10
color: Qt.rgba(1.0, 1.0, 1.0, 0.2)
width: 24
height: 24
radius: 0
color: "transparent"
Text {
anchors.centerIn: parent
text: "✕"
font.pixelSize: 11
color: Theme.textPrimary
font.pixelSize: 16
color: clearMouseArea.containsMouse ? Theme.textPrimary : Theme.textMuted
}
MouseArea {
id: clearMouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: searchInput.text = ""
}
}
}
Rectangle {
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
height: 1
color: Theme.glassBorder
}
}
// Math Calculation Result Banner (if valid formula)
Rectangle {
visible: mathResultText !== ""
Layout.fillWidth: true
Layout.preferredHeight: 36
radius: Theme.radiusSmall
color: Qt.rgba(0.04, 0.52, 1.0, 0.2)
border.color: Theme.accentBlue
border.width: 1
Layout.margins: 14
radius: 0
color: "transparent"
RowLayout {
anchors.fill: parent
@@ -186,38 +215,31 @@ PanelWindow {
Text {
text: "="
font.family: Theme.fontFamily
font.family: Theme.fontMono
font.pixelSize: 16
font.weight: Font.Bold
color: Theme.accentBlue
color: Theme.accentVolt
}
Text {
text: mathResultText
font.family: Theme.fontFamily
font.family: Theme.fontMono
font.pixelSize: 16
font.weight: Font.DemiBold
color: "#FFFFFF"
color: Theme.accentVolt
Layout.fillWidth: true
}
}
}
// Divider Line
Rectangle {
visible: resultsListView.count > 0
Layout.fillWidth: true
Layout.preferredHeight: 1
color: Qt.rgba(1.0, 1.0, 1.0, 0.12)
}
// Search Results List View
ListView {
id: resultsListView
visible: count > 0
Layout.fillWidth: true
Layout.preferredHeight: Math.min(270, count * 42)
Layout.preferredHeight: Math.min(270, count * 40)
Layout.topMargin: 8
Layout.bottomMargin: 8
clip: true
spacing: 2
spacing: 0
model: filteredModel
delegate: Rectangle {
@@ -229,42 +251,42 @@ PanelWindow {
width: resultsListView.width
height: 40
radius: Theme.radiusSmall
color: spotWindow.selectedIndex === index ? Theme.menuHoverBlue : "transparent"
radius: 0
color: spotWindow.selectedIndex === index ? Qt.rgba(0.812, 0.988, 0.0, 0.08) : "transparent"
Rectangle {
anchors.left: parent.left
anchors.top: parent.top
anchors.bottom: parent.bottom
width: 2
color: Theme.accentVolt
visible: spotWindow.selectedIndex === index
}
RowLayout {
anchors.fill: parent
anchors.leftMargin: 10
anchors.rightMargin: 10
spacing: 10
Image {
width: 22
height: 22
source: "../assets/terminal.svg"
sourceSize: Qt.size(22, 22)
}
anchors.leftMargin: 14
anchors.rightMargin: 14
spacing: 12
ColumnLayout {
Layout.fillWidth: true
spacing: 1
spacing: 2
Text {
text: itemDelegate.name
font.family: Theme.fontFamily
font.pixelSize: Theme.fontSizeNormal
font.weight: Font.Medium
color: "#FFFFFF"
font.family: Theme.fontSans
font.pixelSize: 14
color: Theme.textPrimary
elide: Text.ElideRight
Layout.fillWidth: true
}
Text {
text: itemDelegate.comment || itemDelegate.exec
font.family: Theme.fontFamily
font.pixelSize: Theme.fontSizeSmall
color: spotWindow.selectedIndex === itemDelegate.index
? Qt.rgba(1,1,1,0.85) : Theme.textTertiary
font.family: Theme.fontMono
font.pixelSize: 11
color: Theme.textMuted
elide: Text.ElideRight
Layout.fillWidth: true
}
@@ -274,7 +296,7 @@ PanelWindow {
text: "↩"
font.pixelSize: 14
color: spotWindow.selectedIndex === itemDelegate.index
? "#FFFFFF" : "transparent"
? Theme.textPrimary : "transparent"
}
}
@@ -289,6 +311,7 @@ PanelWindow {
}
}
}
}
// Math calculation evaluator property
readonly property string mathResultText: {

View File

@@ -0,0 +1,685 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Quickshell
import Quickshell.Wayland
import Quickshell.Io
import "../theme"
import ".."
PanelWindow {
id: root
anchors {
top: true
bottom: true
left: true
}
margins {
left: Theme.sidebarWidth
top: Theme.topStripHeight
}
implicitWidth: Theme.hudWidth
WlrLayershell.layer: WlrLayer.Overlay
WlrLayershell.namespace: "quickshell-systemhud"
WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
visible: GlobalState.systemHudVisible
color: "transparent"
property real slideOffset: GlobalState.systemHudVisible ? 0 : -Theme.hudWidth
Behavior on slideOffset {
NumberAnimation {
duration: Theme.animSmooth
easing.type: Easing.OutQuint
}
}
Shortcut {
sequence: "Escape"
onActivated: GlobalState.systemHudVisible = false
}
component SectionHeader: Item {
property string sectionNum: "00"
property string title: "Section"
implicitWidth: parent.width
implicitHeight: 24
RowLayout {
anchors.fill: parent
spacing: 8
Text {
text: sectionNum + " //"
font.family: Theme.fontMono
font.pixelSize: 12
color: Theme.accentVolt
}
Text {
text: title
font.family: Theme.fontSerif
font.italic: true
font.pixelSize: 16
color: Theme.textPrimary
Layout.fillWidth: true
}
}
}
component ToggleCard: Rectangle {
property string title: ""
property string icon: ""
property bool active: false
signal clicked()
Layout.preferredWidth: 160
Layout.preferredHeight: 56
color: Theme.bgPrimary
border.color: active ? Qt.rgba(Theme.accentVolt.r, Theme.accentVolt.g, Theme.accentVolt.b, 0.3) : Theme.glassBorder
border.width: 1
radius: 4
Behavior on border.color { ColorAnimation { duration: Theme.animFast } }
MouseArea {
anchors.fill: parent
hoverEnabled: true
onClicked: clicked()
onEntered: if (!active) border.color = Theme.glassBorderHover
onExited: if (!active) border.color = Theme.glassBorder
}
RowLayout {
anchors.fill: parent
anchors.margins: 12
spacing: 12
Image {
source: icon ? Qt.resolvedUrl("../" + icon) : ""
Layout.preferredWidth: 24
Layout.preferredHeight: 24
sourceSize: Qt.size(24, 24)
visible: parent.icon !== ""
}
Text {
text: title
color: Theme.textPrimary
font.family: Theme.fontSans
font.pixelSize: 13
Layout.fillWidth: true
elide: Text.ElideRight
}
}
}
component CustomSlider: Item {
property real value: 0
signal valueChangedUser(real newVal)
implicitWidth: parent.width
implicitHeight: 24
Rectangle {
id: track
anchors.verticalCenter: parent.verticalCenter
width: parent.width - 40
height: 6
color: Theme.bgSecondary
radius: 3
Rectangle {
id: fill
width: track.width * (parent.parent.value / 100)
height: track.height
color: Theme.accentVolt
radius: 3
}
Rectangle {
width: 14
height: 14
radius: 7
color: Theme.textPrimary
anchors.verticalCenter: parent.verticalCenter
x: Math.max(0, fill.width - 7)
}
MouseArea {
anchors.fill: parent
anchors.margins: -10
function updateValue(mouseX) {
let p = Math.max(0, Math.min(1, mouseX / track.width))
parent.parent.valueChangedUser(p * 100)
}
onPressed: (mouse) => updateValue(mouse.x)
onPositionChanged: (mouse) => updateValue(mouse.x)
}
}
Text {
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
text: Math.round(parent.value) + "%"
color: Theme.textPrimary
font.family: Theme.fontMono
font.pixelSize: 12
}
}
component ProgressBarItem: ColumnLayout {
property string label: ""
property real percent: 0
property string valueText: ""
property color barColor: Theme.accentVolt
Layout.fillWidth: true
spacing: 4
RowLayout {
Layout.fillWidth: true
Text {
text: parent.parent.label
color: Theme.textPrimary
font.family: Theme.fontMono
font.pixelSize: 12
}
Item { Layout.fillWidth: true }
Text {
text: parent.parent.valueText
color: Theme.textSecondary
font.family: Theme.fontMono
font.pixelSize: 12
}
}
Rectangle {
Layout.fillWidth: true
height: 8
color: Theme.bgSecondary
radius: 4
Rectangle {
width: parent.width * (parent.parent.percent / 100)
height: parent.height
color: parent.parent.barColor
radius: 4
Behavior on width { NumberAnimation { duration: Theme.animFast; easing.type: Easing.OutCubic } }
Behavior on color { ColorAnimation { duration: Theme.animFast } }
}
}
}
Rectangle {
id: panelContent
anchors.fill: parent
color: Theme.glassBg
opacity: GlobalState.systemHudVisible ? 1 : 0
transform: Translate { x: slideOffset }
Behavior on opacity {
NumberAnimation {
duration: Theme.animSmooth
easing.type: Easing.OutQuint
}
}
Rectangle {
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
width: 1
color: Theme.glassBorder
}
Item {
id: header
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
height: 60
Rectangle {
anchors.bottom: parent.bottom
width: parent.width
height: 1
color: Theme.glassBorder
}
RowLayout {
anchors.fill: parent
anchors.leftMargin: 20
anchors.rightMargin: 20
Text {
text: "System HUD"
font.family: Theme.fontSerif
font.italic: true
font.pixelSize: 19
color: Theme.textPrimary
Layout.fillWidth: true
}
Text {
text: "✕"
color: Theme.textMuted
font.pixelSize: 16
MouseArea {
anchors.fill: parent
anchors.margins: -10
hoverEnabled: true
onEntered: parent.color = Theme.textPrimary
onExited: parent.color = Theme.textMuted
onClicked: GlobalState.systemHudVisible = false
}
}
}
}
ScrollView {
id: scrollView
anchors.top: header.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
contentWidth: availableWidth
clip: true
ColumnLayout {
id: contentLayout
width: parent.width - 40
x: 20
spacing: 32
Item { Layout.preferredHeight: 16 } // Top padding
// Section 1: Toggles
ColumnLayout {
id: sectionToggles
Layout.fillWidth: true
spacing: 16
SectionHeader { sectionNum: "01"; title: "Toggles" }
GridLayout {
columns: 2
columnSpacing: 12
rowSpacing: 12
Layout.fillWidth: true
ToggleCard {
title: GlobalState.wifiSsid !== "" ? GlobalState.wifiSsid : "Wi-Fi"
icon: "assets/wifi.svg"
active: GlobalState.wifiConnected
onClicked: {
let proc = Quickshell.createProcess("sh", ["-c", "nm-connection-editor || foot -e nmtui"])
proc.start()
}
}
ToggleCard {
title: "Bluetooth"
icon: "assets/bluetooth.svg"
active: false // Adjust if there's a bluetooth state
onClicked: {
let proc = Quickshell.createProcess("sh", ["-c", "foot -e bluetoothctl"])
proc.start()
}
}
ToggleCard {
property bool dndActive: false
title: "Do Not Disturb"
icon: "" // Optional DND icon
active: dndActive
onClicked: dndActive = !dndActive
}
ToggleCard {
title: GlobalState.volumeMuted ? "Muted" : "Sound"
icon: "" // Optional sound icon
active: !GlobalState.volumeMuted
onClicked: GlobalState.toggleVolumeMute()
}
}
}
// Section 2: Volume
ColumnLayout {
id: sectionVolume
Layout.fillWidth: true
spacing: 16
SectionHeader { sectionNum: "02"; title: "Volume" }
CustomSlider {
Layout.fillWidth: true
value: GlobalState.volume
onValueChangedUser: (val) => GlobalState.volume = val // Adjust to actual volume setter if needed
}
RowLayout {
Layout.fillWidth: true
Text {
text: GlobalState.volumeMuted ? "Unmute" : "Mute"
color: Theme.textSecondary
font.family: Theme.fontSans
font.pixelSize: 13
MouseArea {
anchors.fill: parent
onClicked: GlobalState.toggleVolumeMute()
}
}
Item { Layout.fillWidth: true }
Text {
text: "Sound Preferences..."
color: Theme.textMuted
font.family: Theme.fontSans
font.pixelSize: 13
MouseArea {
anchors.fill: parent
hoverEnabled: true
onEntered: parent.color = Theme.textPrimary
onExited: parent.color = Theme.textMuted
onClicked: {
let proc = Quickshell.createProcess("pavucontrol", [])
proc.start()
}
}
}
}
}
// Section 3: Brightness
ColumnLayout {
id: sectionBrightness
Layout.fillWidth: true
spacing: 16
SectionHeader { sectionNum: "03"; title: "Brightness" }
CustomSlider {
Layout.fillWidth: true
value: GlobalState.brightness
onValueChangedUser: (val) => GlobalState.setBrightness(val)
}
}
// Section 4: Performance
ColumnLayout {
id: sectionPerformance
Layout.fillWidth: true
spacing: 16
SectionHeader { sectionNum: "04"; title: "Performance" }
ProgressBarItem {
label: "CPU"
percent: GlobalState.cpuPercent
valueText: GlobalState.cpuPercent + "%"
barColor: GlobalState.cpuPercent > 80 ? Theme.accentCoral : Theme.accentVolt
}
ProgressBarItem {
label: "RAM"
percent: (GlobalState.memUsedGb / Math.max(1, GlobalState.memTotalGb)) * 100
valueText: GlobalState.memUsedGb + " / " + GlobalState.memTotalGb + " GB"
}
ProgressBarItem {
label: "VRAM"
percent: (GlobalState.gpuVramUsed / Math.max(1, GlobalState.gpuVramTotal)) * 100
valueText: GlobalState.gpuVramUsed + " / " + GlobalState.gpuVramTotal + " GB"
}
}
// Section 5: Network
ColumnLayout {
id: sectionNetwork
Layout.fillWidth: true
spacing: 16
SectionHeader { sectionNum: "05"; title: "Network" }
RowLayout {
spacing: 8
Rectangle {
width: 8
height: 8
radius: 4
color: GlobalState.wifiConnected ? Theme.accentVolt : Theme.accentCoral
}
Text {
text: GlobalState.wifiConnected ? "Connected" : "Disconnected"
color: Theme.textPrimary
font.family: Theme.fontSans
font.pixelSize: 14
}
}
Text {
text: "SSID: " + (GlobalState.wifiSsid !== "" ? GlobalState.wifiSsid : "None")
color: Theme.textSecondary
font.family: Theme.fontSans
font.pixelSize: 13
}
Text {
text: "IP: " + GlobalState.ipAddress
color: Theme.textSecondary
font.family: Theme.fontMono
font.pixelSize: 13
}
Text {
text: "Network Preferences..."
color: Theme.textMuted
font.family: Theme.fontSans
font.pixelSize: 13
MouseArea {
anchors.fill: parent
hoverEnabled: true
onEntered: parent.color = Theme.textPrimary
onExited: parent.color = Theme.textMuted
onClicked: {
let proc = Quickshell.createProcess("sh", ["-c", "nm-connection-editor || foot -e nmtui"])
proc.start()
}
}
}
}
// Section 6: Battery
ColumnLayout {
id: sectionBattery
Layout.fillWidth: true
spacing: 16
visible: GlobalState.batteryPresent
SectionHeader { sectionNum: "06"; title: "Battery" }
RowLayout {
spacing: 16
Text {
text: GlobalState.batteryPercent + "%"
font.family: Theme.fontMono
font.pixelSize: 24
color: GlobalState.batteryStatus === "Charging" ? Theme.accentVolt :
(GlobalState.batteryPercent < 20 ? Theme.accentCoral : Theme.textPrimary)
}
Text {
text: GlobalState.batteryStatus
color: Theme.textSecondary
font.family: Theme.fontSans
font.pixelSize: 14
}
}
}
// Section 7: Now Playing
ColumnLayout {
id: sectionNowPlaying
Layout.fillWidth: true
spacing: 16
visible: GlobalState.mediaTitle !== ""
SectionHeader { sectionNum: "07"; title: "Now Playing" }
ColumnLayout {
spacing: 4
Text {
text: GlobalState.mediaTitle
color: Theme.textPrimary
font.family: Theme.fontSans
font.bold: true
font.pixelSize: 14
Layout.fillWidth: true
elide: Text.ElideRight
}
Text {
text: GlobalState.mediaArtist
color: Theme.textSecondary
font.family: Theme.fontSans
font.pixelSize: 12
Layout.fillWidth: true
elide: Text.ElideRight
}
}
RowLayout {
Layout.alignment: Qt.AlignHCenter
spacing: 16
Text {
text: "⏮"
font.pixelSize: 20
color: Theme.textSecondary
MouseArea {
anchors.fill: parent
anchors.margins: -10
hoverEnabled: true
onEntered: parent.color = Theme.accentVolt
onExited: parent.color = Theme.textSecondary
onClicked: GlobalState.mediaPrevious()
}
}
Text {
text: GlobalState.mediaStatus === "Playing" ? "⏸" : "▶"
font.pixelSize: 24
color: Theme.textSecondary
MouseArea {
anchors.fill: parent
anchors.margins: -10
hoverEnabled: true
onEntered: parent.color = Theme.accentVolt
onExited: parent.color = Theme.textSecondary
onClicked: GlobalState.mediaPlayPause()
}
}
Text {
text: "⏭"
font.pixelSize: 20
color: Theme.textSecondary
MouseArea {
anchors.fill: parent
anchors.margins: -10
hoverEnabled: true
onEntered: parent.color = Theme.accentVolt
onExited: parent.color = Theme.textSecondary
onClicked: GlobalState.mediaNext()
}
}
}
}
// Section 8: Calendar
ColumnLayout {
id: sectionCalendar
Layout.fillWidth: true
spacing: 16
SectionHeader { sectionNum: "08"; title: "Calendar" }
RowLayout {
spacing: 12
Text {
text: GlobalState.timeString
font.family: Theme.fontMono
font.pixelSize: 22
color: Theme.accentVolt
}
Text {
text: GlobalState.fullDateString
font.family: Theme.fontSans
font.pixelSize: 13
color: Theme.textSecondary
}
}
GridLayout {
columns: 7
columnSpacing: 4
rowSpacing: 4
Layout.alignment: Qt.AlignHCenter
Repeater {
model: ["S", "M", "T", "W", "T", "F", "S"]
Text {
text: modelData
font.family: Theme.fontMono
font.pixelSize: 11
color: Theme.textMuted
horizontalAlignment: Text.AlignHCenter
Layout.preferredWidth: 32
}
}
Repeater {
model: 31
Rectangle {
property bool isToday: (index + 1) === new Date().getDate()
Layout.preferredWidth: 32
Layout.preferredHeight: 32
color: isToday ? Theme.accentVolt : "transparent"
radius: isToday ? 0 : 4
Text {
anchors.centerIn: parent
text: index + 1
color: parent.isToday ? "#ffffff" : Theme.textSecondary
font.family: Theme.fontMono
font.pixelSize: 12
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onEntered: if (!parent.isToday) parent.color = Qt.rgba(1, 1, 1, 0.04)
onExited: if (!parent.isToday) parent.color = "transparent"
}
}
}
}
}
Item { Layout.preferredHeight: 20 } // Bottom padding
}
}
}
// Auto-scroll to active section when changed
Connections {
target: GlobalState
function onSystemHudActiveSectionChanged() {
if (!GlobalState.systemHudVisible) return;
let targetY = 0;
if (GlobalState.systemHudActiveSection === "volume") targetY = sectionVolume.y;
else if (GlobalState.systemHudActiveSection === "brightness") targetY = sectionBrightness.y;
else if (GlobalState.systemHudActiveSection === "performance") targetY = sectionPerformance.y;
else if (GlobalState.systemHudActiveSection === "network") targetY = sectionNetwork.y;
else if (GlobalState.systemHudActiveSection === "battery") targetY = sectionBattery.y;
else if (GlobalState.systemHudActiveSection === "nowplaying") targetY = sectionNowPlaying.y;
else if (GlobalState.systemHudActiveSection === "calendar") targetY = sectionCalendar.y;
if (targetY > 0) {
// Ensure targetY doesn't scroll past max possible scroll
let maxY = Math.max(0, contentLayout.height - scrollView.height);
scrollView.ScrollBar.vertical.position = Math.min(targetY, maxY) / contentLayout.height;
}
}
}
}

View File

@@ -0,0 +1,257 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Quickshell
import Quickshell.Wayland
import Quickshell.Io
import "../theme"
import ".."
PanelWindow {
id: systemInfoDialog
WlrLayershell.layer: WlrLayer.Overlay
WlrLayershell.keyboardFocus: visible ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
anchors {
top: true
bottom: true
left: true
right: true
}
visible: GlobalState.aboutMacVisible
color: Qt.rgba(0, 0, 0, 0.35)
// Close on click outside or Escape
MouseArea {
anchors.fill: parent
onClicked: GlobalState.aboutMacVisible = false
}
Item {
anchors.fill: parent
focus: true
Keys.onEscapePressed: GlobalState.aboutMacVisible = false
}
property string cpuName: ""
property string gpuName: ""
// Process to get CPU info
Process {
id: cpuProcess
command: ["sh", "-c", "grep 'model name' /proc/cpuinfo | head -n1 | cut -d':' -f2 | xargs"]
running: true
stdout: StdioCollector {
onDataChanged: {
const val = String(data).trim();
if (val.length > 0) systemInfoDialog.cpuName = val;
}
}
}
// Process to get GPU info
Process {
id: gpuProcess
command: ["sh", "-c", "nvidia-smi --query-gpu=name --format=csv,noheader | head -n1"]
running: true
stdout: StdioCollector {
onDataChanged: {
const val = String(data).trim();
if (val.length > 0) systemInfoDialog.gpuName = val;
}
}
}
Rectangle {
id: dialogBox
width: 480
height: 320
anchors.centerIn: parent
color: Theme.glassBg
border.color: Theme.glassBorder
border.width: 1
radius: 0
MouseArea {
anchors.fill: parent
// Eat clicks so they don't close the dialog
}
ColumnLayout {
anchors.fill: parent
spacing: 0
// Header bar
Item {
Layout.fillWidth: true
Layout.preferredHeight: 40
Rectangle {
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
height: 1
color: Theme.glassBorder
}
Rectangle {
id: closeBtn
width: 40
height: 40
anchors.left: parent.left
color: closeMouseArea.containsMouse ? Theme.accentCoral : "transparent"
Text {
anchors.centerIn: parent
text: "✕"
color: closeMouseArea.containsMouse ? Theme.textPrimary : Theme.textSecondary
font.pixelSize: 14
}
MouseArea {
id: closeMouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: GlobalState.aboutMacVisible = false
}
}
Text {
anchors.centerIn: parent
text: "System Info"
font.family: Theme.fontSerif
font.italic: true
font.pixelSize: 15
color: Theme.textPrimary
}
}
// Body
Item {
Layout.fillWidth: true
Layout.fillHeight: true
Column {
anchors.centerIn: parent
spacing: 8
Text {
anchors.horizontalCenter: parent.horizontalCenter
text: "Silicon Volt"
font.family: Theme.fontSerif
font.italic: true
font.pixelSize: 24
color: Theme.accentVolt
}
Text {
anchors.horizontalCenter: parent.horizontalCenter
text: "NixOS // Hyprland"
font.family: Theme.fontMono
font.pixelSize: 12
color: Theme.textMuted
bottomPadding: 16
}
Grid {
anchors.horizontalCenter: parent.horizontalCenter
columns: 2
spacing: 12
rowSpacing: 8
// HOST
Text { width: 100; horizontalAlignment: Text.AlignRight; text: "HOST"; font.family: Theme.fontMono; font.pixelSize: 11; color: Theme.textMuted }
Text { text: "hades"; font.family: Theme.fontSans; font.pixelSize: 13; color: Theme.textSecondary }
// CPU
Text { width: 100; horizontalAlignment: Text.AlignRight; text: "CPU"; font.family: Theme.fontMono; font.pixelSize: 11; color: Theme.textMuted }
Text { id: cpuText; text: systemInfoDialog.cpuName || "Loading..."; font.family: Theme.fontSans; font.pixelSize: 13; color: Theme.textSecondary }
// MEMORY
Text { width: 100; horizontalAlignment: Text.AlignRight; text: "MEMORY"; font.family: Theme.fontMono; font.pixelSize: 11; color: Theme.textMuted }
Text { text: GlobalState.memUsedGb + " / " + GlobalState.memTotalGb + " GB"; font.family: Theme.fontSans; font.pixelSize: 13; color: Theme.textSecondary }
// GPU
Text { width: 100; horizontalAlignment: Text.AlignRight; text: "GPU"; font.family: Theme.fontMono; font.pixelSize: 11; color: Theme.textMuted }
Text { id: gpuText; text: systemInfoDialog.gpuName || "Loading..."; font.family: Theme.fontSans; font.pixelSize: 13; color: Theme.textSecondary }
// VRAM
Text { width: 100; horizontalAlignment: Text.AlignRight; text: "VRAM"; font.family: Theme.fontMono; font.pixelSize: 11; color: Theme.textMuted }
Text { text: GlobalState.gpuVramUsed + " / " + GlobalState.gpuVramTotal + " GB"; font.family: Theme.fontSans; font.pixelSize: 13; color: Theme.textSecondary }
// WM
Text { width: 100; horizontalAlignment: Text.AlignRight; text: "WM"; font.family: Theme.fontMono; font.pixelSize: 11; color: Theme.textMuted }
Text { text: "Hyprland"; font.family: Theme.fontSans; font.pixelSize: 13; color: Theme.textSecondary }
// OS
Text { width: 100; horizontalAlignment: Text.AlignRight; text: "OS"; font.family: Theme.fontMono; font.pixelSize: 11; color: Theme.textMuted }
Text { text: "NixOS"; font.family: Theme.fontSans; font.pixelSize: 13; color: Theme.textSecondary }
}
}
}
// Footer bar
Item {
Layout.fillWidth: true
Layout.preferredHeight: 44
Rectangle {
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
height: 1
color: Theme.glassBorder
}
component FooterButton: Rectangle {
id: btn
property string text: ""
property alias command: proc.command
width: btnText.width + 24
height: 28
anchors.verticalCenter: parent.verticalCenter
color: btnMouse.containsMouse ? Qt.rgba(Theme.accentVolt.r, Theme.accentVolt.g, Theme.accentVolt.b, 0.1) : "transparent"
border.color: Theme.glassBorder
border.width: 1
radius: 0
Text {
id: btnText
anchors.centerIn: parent
text: btn.text
font.family: Theme.fontSans
font.pixelSize: 12
color: btnMouse.containsMouse ? Theme.accentVolt : Theme.textMuted
}
MouseArea {
id: btnMouse
anchors.fill: parent
hoverEnabled: true
onClicked: proc.running = true
}
Process {
id: proc
}
}
FooterButton {
anchors.left: parent.left
anchors.leftMargin: 16
text: "System Report..."
command: ["foot", "-e", "btop"]
}
FooterButton {
anchors.right: parent.right
anchors.rightMargin: 16
text: "Software Update..."
command: ["foot", "-e", "sudo", "nixos-rebuild", "dry-activate"]
}
}
}
}
}

View File

@@ -0,0 +1,101 @@
import QtQuick
import QtQuick.Layouts
import Quickshell
import Quickshell.Wayland
import "../theme"
import ".."
PanelWindow {
id: root
property var modelData
screen: modelData
anchors {
top: true
left: true
right: true
}
margins.left: Theme.sidebarWidth
implicitHeight: Theme.topStripHeight
color: Qt.rgba(Theme.bgPrimary.r, Theme.bgPrimary.g, Theme.bgPrimary.b, 0.92)
exclusiveZone: Theme.topStripHeight
WlrLayershell.layer: WlrLayer.Top
WlrLayershell.namespace: "quickshell-topstrip"
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
Rectangle {
id: bottomBorder
anchors {
bottom: parent.bottom
left: parent.left
right: parent.right
}
height: 1
color: Theme.glassBorder
}
RowLayout {
anchors.fill: parent
anchors.leftMargin: 16
anchors.rightMargin: 16
spacing: 16
// Left Section
Text {
id: workspaceIndicator
Layout.alignment: Qt.AlignVCenter
font.family: Theme.fontMono
font.pixelSize: 12
color: Theme.textMuted
function pad(num) {
if (num === undefined || num === null) return "00";
return num < 10 ? "0" + num : num.toString();
}
text: pad(GlobalState.activeWorkspace) + " // " + (GlobalState.workspaceNames[GlobalState.activeWorkspace] !== undefined ? GlobalState.workspaceNames[GlobalState.activeWorkspace] : "main")
Behavior on color {
ColorAnimation { duration: 150 }
}
}
// Center Section
Text {
id: windowTitle
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
horizontalAlignment: Text.AlignHCenter
font.family: Theme.fontSerif
font.italic: true
font.pixelSize: Theme.fontSizeLarge
color: Theme.textSecondary
elide: Text.ElideRight
maximumLineCount: 1
text: GlobalState.activeWindowTitle
Behavior on color {
ColorAnimation { duration: 150 }
}
}
// Right Section
Text {
id: clock
Layout.alignment: Qt.AlignVCenter
font.family: Theme.fontMono
font.pixelSize: 12
color: Theme.textPrimary
text: GlobalState.timeString
Behavior on color {
ColorAnimation { duration: 150 }
}
}
}
}

View File

@@ -25,55 +25,60 @@ Scope {
}
IpcHandler {
target: "controlCenter"
target: "systemHud"
function toggle() {
GlobalState.toggleControlCenter();
GlobalState.toggleSystemHud();
}
function open() {
GlobalState.controlCenterVisible = true;
GlobalState.systemHudVisible = true;
}
function close() {
GlobalState.controlCenterVisible = false;
GlobalState.systemHudVisible = false;
}
}
IpcHandler {
target: "aboutMac"
target: "systemInfo"
function toggle() {
GlobalState.toggleAboutMac();
}
}
// =========================================================================
// MULTI-MONITOR BARS & DOCKS
// LEFT SIDEBAR (Primary monitor only)
// =========================================================================
// 1. macOS Catalina Top Menu Bar (Spawned per monitor)
Variants {
model: Quickshell.screens
MenuBar {}
SidePanel {
screen: Quickshell.screens[0]
}
// 2. macOS Catalina Floating Dock (Spawned per monitor)
// =========================================================================
// TOP STATUS STRIP (All monitors)
// =========================================================================
Variants {
model: Quickshell.screens
Dock {}
TopStrip {}
}
// =========================================================================
// GLOBAL MODAL OVERLAYS
// =========================================================================
// 3. Spotlight Search Overlay
// Spotlight Search Overlay
Spotlight {
id: spotlightOverlay
}
// 4. Control Center & Notification Center Sidebar
ControlCenter {
id: controlCenterSidebar
// System HUD Flyout Panel
SystemHUD {
id: systemHudPanel
}
// 5. About This Mac Dialog
AboutMac {
id: aboutMacDialog
// Quick Menu (Power/Session Menu)
QuickMenu {
id: quickMenuOverlay
}
// System Info Dialog
SystemInfo {
id: systemInfoDialog
}
}

View File

@@ -2,56 +2,45 @@ pragma Singleton
import QtQuick
QtObject {
// macOS Catalina Color Palette
readonly property color menuBarBg: Qt.rgba(0.12, 0.12, 0.14, 0.88)
readonly property color menuBarBorder: Qt.rgba(1.0, 1.0, 1.0, 0.12)
readonly property color dockBg: Qt.rgba(0.15, 0.16, 0.18, 0.72)
readonly property color dockBorder: Qt.rgba(1.0, 1.0, 1.0, 0.22)
readonly property color dockHighlight: Qt.rgba(1.0, 1.0, 1.0, 0.35)
readonly property color dockShadow: Qt.rgba(0.0, 0.0, 0.0, 0.45)
readonly property color dockDot: Qt.rgba(1.0, 1.0, 1.0, 0.95)
readonly property color windowBg: Qt.rgba(0.14, 0.14, 0.16, 0.94)
readonly property color windowBorder: Qt.rgba(1.0, 1.0, 1.0, 0.15)
readonly property color cardBg: Qt.rgba(0.22, 0.22, 0.26, 0.65)
readonly property color cardBorder: Qt.rgba(1.0, 1.0, 1.0, 0.10)
readonly property color menuDropdownBg: Qt.rgba(0.16, 0.16, 0.18, 0.96)
readonly property color menuDropdownBorder: Qt.rgba(1.0, 1.0, 1.0, 0.18)
readonly property color menuHoverBlue: "#0062E3"
readonly property color menuTextHover: "#FFFFFF"
readonly property color accentBlue: "#0A84FF"
readonly property color accentGreen: "#30D158"
readonly property color accentRed: "#FF453A"
readonly property color accentYellow: "#FFD60A"
readonly property color accentOrange: "#FF9F0A"
// Colors
readonly property color bgPrimary: "#131313"
readonly property color bgSecondary: "#0e0e0e"
readonly property color glassBg: "#1c1b1b"
readonly property color glassBorder: Qt.rgba(1.0, 1.0, 1.0, 0.08)
readonly property color glassBorderHover: Qt.rgba(1.0, 1.0, 1.0, 0.18)
readonly property color accentVolt: "#CFFC00"
readonly property color accentVoltGlow: Qt.rgba(0.812, 0.988, 0.0, 0.25)
readonly property color accentVoltLight: "#e3ff66"
readonly property color accentBlue: "#00BFFF"
readonly property color accentCoral: "#FF7A59"
readonly property color textPrimary: "#FFFFFF"
readonly property color textSecondary: Qt.rgba(1.0, 1.0, 1.0, 0.72)
readonly property color textTertiary: Qt.rgba(1.0, 1.0, 1.0, 0.45)
readonly property color textSecondary: "#e5e2e1"
readonly property color textMuted: "#ADAAAA"
readonly property color textDisabled: Qt.rgba(1.0, 1.0, 1.0, 0.25)
// Typography
readonly property string fontFamily: "SF Pro Display, SF Pro Text, Helvetica Neue, Cantarell, Liberation Sans, sans-serif"
readonly property int fontSizeMenuBar: 13
readonly property string fontSerif: "Instrument Serif, Georgia, serif"
readonly property string fontSans: "IBM Plex Sans, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif"
readonly property string fontMono: "Nanum Gothic Coding, JetBrains Mono, monospace"
readonly property int fontSizeSmall: 11
readonly property int fontSizeNormal: 13
readonly property int fontSizeLarge: 15
readonly property int fontSizeTitle: 19
readonly property int fontSizeSpotlight: 20
readonly property int fontSizeDisplay: 24
readonly property int fontSizeWorkspace: 12
// Geometry & Radii
readonly property int menuBarHeight: 26
readonly property int radiusSmall: 4
readonly property int radiusMedium: 8
readonly property int radiusLarge: 14
readonly property int radiusDock: 18
readonly property int radiusModal: 16
// Geometry
readonly property int radiusNone: 0
readonly property int sidebarWidth: 52
readonly property int topStripHeight: 28
readonly property int hudWidth: 360
readonly property int iconSize: 36
readonly property int iconSizeSmall: 20
readonly property int workspaceIndicatorWidth: 2
// Animation Durations
readonly property int animFast: 120
readonly property int animNormal: 220
readonly property int animSmooth: 320
readonly property int animSmooth: 400
readonly property int animFast: 200
readonly property int animBounce: 600
}

7
home/pi.nix Normal file
View File

@@ -0,0 +1,7 @@
{ inputs, config, ... }:
{
imports = [ inputs.pi.homeModules.default ];
programs.pi.coding-agent = {
enable = true;
};
}

View File

@@ -5,7 +5,6 @@
# Core Editors & AI Agents
neovim
antigravity-cli
pi-coding-agent
# Languages & Toolchains
uv

View File

@@ -32,7 +32,6 @@
};
environment.systemPackages = with pkgs; [
comfy-ui-cuda
unstable.ollama-cuda
];
}

View File

@@ -8,8 +8,23 @@
"flakes"
];
auto-optimise-store = true;
substituters = [ "https://cache.nixos-cuda.org" ];
trusted-public-keys = [ "cache.nixos-cuda.org:74DUi4Ye579gUqzH4ziL9IyiJBlDpMRn9MBN8oNan9M=" ];
extra-substituters = [
"https://cache.nixos-cuda.org"
"https://pi.cachix.org"
"https://comfyui.cachix.org"
"https://nix-community.cachix.org"
];
extra-trusted-public-keys = [
"cache.nixos-cuda.org:74DUi4Ye579gUqzH4ziL9IyiJBlDpMRn9MBN8oNan9M="
"pi.cachix.org-1:lGeoGJaZ5ZDabuRzkcD5EBTNnDM4HJ1vqeOxlWk1Flk="
"comfyui.cachix.org-1:33mf9VzoIjzVbp0zwj+fT51HG0y31ZTK3nzYZAX0rec="
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
];
trusted-users = [
"root"
"@wheel"
"anish"
];
};
gc = {