first commit

This commit is contained in:
Daniel Bulant 2024-10-12 18:25:13 +02:00
commit a8800d9a68
No known key found for this signature in database
18 changed files with 28974 additions and 0 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
target
result
http-cacache

5772
Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

21630
Cargo.nix Normal file

File diff suppressed because one or more lines are too long

21
Cargo.toml Normal file
View file

@ -0,0 +1,21 @@
[package]
name = "rshell"
description = "Another GUI shell"
version = "0.1.0"
edition = "2021"
[dependencies]
# cushy = { version = "0.4.0", features=["tokio", "tokio-multi-thread", "plotters", "roboto-flex"], default-features = false }
cushy = { git = "https://github.com/khonsulabs/cushy.git", branch = "main", features=["tokio", "tokio-multi-thread", "plotters", "roboto-flex"] }
tokio = { version = "1.40.0", features = ["rt", "rt-multi-thread"] }
plotters = { version = "0.3.7", default-features = false }
image = { version = "0.25.0", features = ["png"] }
mpris = "2.0.1"
reqwest = "0.12.8"
reqwest-middleware="0.3.3"
http-cache-reqwest = "0.14.0"
color_quant = "1.0"
hsl = "0.1.1"
itertools = "0.10.0"
palette = "0.7.3"
clap = { version = "4.5.20", features = ["derive"] }

6
crate-hashes.json Normal file
View file

@ -0,0 +1,6 @@
{
"git+https://github.com/khonsulabs/appit#0.4.0": "0cx7byzrbdjhd1a985hh7amjcb1zj3q1dbwjv4w9w5dfz6nxn3xp",
"git+https://github.com/khonsulabs/cushy.git?branch=main#cushy-macros@0.4.0": "0pfrsrc79fxip511hc18si1xgzakx0x6b5ib7x7a1dwa5ja8sx15",
"git+https://github.com/khonsulabs/cushy.git?branch=main#cushy@0.4.0": "0pfrsrc79fxip511hc18si1xgzakx0x6b5ib7x7a1dwa5ja8sx15",
"git+https://github.com/khonsulabs/kludgine#0.11.0": "0cga9iav663an86waf2kj98mmhppbxavfpbhmmhbrcdcn0i4fiv6"
}

937
flake.lock Normal file
View file

@ -0,0 +1,937 @@
{
"nodes": {
"cachix": {
"inputs": {
"devenv": [
"crate2nix"
],
"flake-compat": [
"crate2nix"
],
"nixpkgs": "nixpkgs",
"pre-commit-hooks": [
"crate2nix"
]
},
"locked": {
"lastModified": 1709700175,
"narHash": "sha256-A0/6ZjLmT9qdYzKHmevnEIC7G+GiZ4UCr8v0poRPzds=",
"owner": "cachix",
"repo": "cachix",
"rev": "be97b37989f11b724197b5f4c7ffd78f12c8c4bf",
"type": "github"
},
"original": {
"owner": "cachix",
"ref": "latest",
"repo": "cachix",
"type": "github"
}
},
"cachix_2": {
"inputs": {
"devenv": [
"crate2nix",
"crate2nix_stable"
],
"flake-compat": [
"crate2nix",
"crate2nix_stable"
],
"nixpkgs": "nixpkgs_2",
"pre-commit-hooks": [
"crate2nix",
"crate2nix_stable"
]
},
"locked": {
"lastModified": 1716549461,
"narHash": "sha256-lHy5kgx6J8uD+16SO47dPrbob98sh+W1tf4ceSqPVK4=",
"owner": "cachix",
"repo": "cachix",
"rev": "e2bb269fb8c0828d5d4d2d7b8d09ea85abcacbd4",
"type": "github"
},
"original": {
"owner": "cachix",
"ref": "latest",
"repo": "cachix",
"type": "github"
}
},
"cachix_3": {
"inputs": {
"devenv": [
"crate2nix",
"crate2nix_stable",
"crate2nix_stable"
],
"flake-compat": [
"crate2nix",
"crate2nix_stable",
"crate2nix_stable"
],
"nixpkgs": "nixpkgs_3",
"pre-commit-hooks": [
"crate2nix",
"crate2nix_stable",
"crate2nix_stable"
]
},
"locked": {
"lastModified": 1716549461,
"narHash": "sha256-lHy5kgx6J8uD+16SO47dPrbob98sh+W1tf4ceSqPVK4=",
"owner": "cachix",
"repo": "cachix",
"rev": "e2bb269fb8c0828d5d4d2d7b8d09ea85abcacbd4",
"type": "github"
},
"original": {
"owner": "cachix",
"ref": "latest",
"repo": "cachix",
"type": "github"
}
},
"crate2nix": {
"inputs": {
"cachix": "cachix",
"crate2nix_stable": "crate2nix_stable",
"devshell": "devshell_3",
"flake-compat": "flake-compat_3",
"flake-parts": "flake-parts_3",
"nix-test-runner": "nix-test-runner_3",
"nixpkgs": "nixpkgs_6",
"pre-commit-hooks": "pre-commit-hooks_3"
},
"locked": {
"lastModified": 1723311214,
"narHash": "sha256-xdGZQBEa1AC2us/sY3igS/CucWY6jErXsAvCFRhB2LI=",
"owner": "nix-community",
"repo": "crate2nix",
"rev": "236f6addfd452a48be805819e3216af79e988fd5",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "crate2nix",
"type": "github"
}
},
"crate2nix_stable": {
"inputs": {
"cachix": "cachix_2",
"crate2nix_stable": "crate2nix_stable_2",
"devshell": "devshell_2",
"flake-compat": "flake-compat_2",
"flake-parts": "flake-parts_2",
"nix-test-runner": "nix-test-runner_2",
"nixpkgs": "nixpkgs_5",
"pre-commit-hooks": "pre-commit-hooks_2"
},
"locked": {
"lastModified": 1719760004,
"narHash": "sha256-esWhRnt7FhiYq0CcIxw9pvH+ybOQmWBfHYMtleaMhBE=",
"owner": "nix-community",
"repo": "crate2nix",
"rev": "1dee214bb20855fa3e1e7bb98d28922ddaff8c57",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "0.14.1",
"repo": "crate2nix",
"type": "github"
}
},
"crate2nix_stable_2": {
"inputs": {
"cachix": "cachix_3",
"crate2nix_stable": "crate2nix_stable_3",
"devshell": "devshell",
"flake-compat": "flake-compat",
"flake-parts": "flake-parts",
"nix-test-runner": "nix-test-runner",
"nixpkgs": "nixpkgs_4",
"pre-commit-hooks": "pre-commit-hooks"
},
"locked": {
"lastModified": 1712821484,
"narHash": "sha256-rGT3CW64cJS9nlnWPFWSc1iEa3dNZecVVuPVGzcsHe8=",
"owner": "nix-community",
"repo": "crate2nix",
"rev": "42883afcad3823fa5811e967fb7bff54bc3c9d6d",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "0.14.0",
"repo": "crate2nix",
"type": "github"
}
},
"crate2nix_stable_3": {
"inputs": {
"flake-utils": "flake-utils"
},
"locked": {
"lastModified": 1702842982,
"narHash": "sha256-A9AowkHIjsy1a4LuiPiVP88FMxyCWK41flZEZOUuwQM=",
"owner": "nix-community",
"repo": "crate2nix",
"rev": "75ac2973affa6b9b4f661a7b592cba6e4f51d426",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "0.12.0",
"repo": "crate2nix",
"type": "github"
}
},
"devshell": {
"inputs": {
"flake-utils": "flake-utils_2",
"nixpkgs": [
"crate2nix",
"crate2nix_stable",
"crate2nix_stable",
"nixpkgs"
]
},
"locked": {
"lastModified": 1717408969,
"narHash": "sha256-Q0OEFqe35fZbbRPPRdrjTUUChKVhhWXz3T9ZSKmaoVY=",
"owner": "numtide",
"repo": "devshell",
"rev": "1ebbe68d57457c8cae98145410b164b5477761f4",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "devshell",
"type": "github"
}
},
"devshell_2": {
"inputs": {
"flake-utils": "flake-utils_3",
"nixpkgs": [
"crate2nix",
"crate2nix_stable",
"nixpkgs"
]
},
"locked": {
"lastModified": 1717408969,
"narHash": "sha256-Q0OEFqe35fZbbRPPRdrjTUUChKVhhWXz3T9ZSKmaoVY=",
"owner": "numtide",
"repo": "devshell",
"rev": "1ebbe68d57457c8cae98145410b164b5477761f4",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "devshell",
"type": "github"
}
},
"devshell_3": {
"inputs": {
"flake-utils": "flake-utils_4",
"nixpkgs": [
"crate2nix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1711099426,
"narHash": "sha256-HzpgM/wc3aqpnHJJ2oDqPBkNsqWbW0WfWUO8lKu8nGk=",
"owner": "numtide",
"repo": "devshell",
"rev": "2d45b54ca4a183f2fdcf4b19c895b64fbf620ee8",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "devshell",
"type": "github"
}
},
"devshell_4": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1728330715,
"narHash": "sha256-xRJ2nPOXb//u1jaBnDP56M7v5ldavjbtR6lfGqSvcKg=",
"owner": "numtide",
"repo": "devshell",
"rev": "dd6b80932022cea34a019e2bb32f6fa9e494dfef",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "devshell",
"type": "github"
}
},
"flake-compat": {
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"revCount": 57,
"type": "tarball",
"url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"
}
},
"flake-compat_2": {
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"revCount": 57,
"type": "tarball",
"url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"
}
},
"flake-compat_3": {
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"revCount": 57,
"type": "tarball",
"url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
"crate2nix",
"crate2nix_stable",
"crate2nix_stable",
"nixpkgs"
]
},
"locked": {
"lastModified": 1719745305,
"narHash": "sha256-xwgjVUpqSviudEkpQnioeez1Uo2wzrsMaJKJClh+Bls=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "c3c5ecc05edc7dafba779c6c1a61cd08ac6583e9",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_2": {
"inputs": {
"nixpkgs-lib": [
"crate2nix",
"crate2nix_stable",
"nixpkgs"
]
},
"locked": {
"lastModified": 1719745305,
"narHash": "sha256-xwgjVUpqSviudEkpQnioeez1Uo2wzrsMaJKJClh+Bls=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "c3c5ecc05edc7dafba779c6c1a61cd08ac6583e9",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_3": {
"inputs": {
"nixpkgs-lib": [
"crate2nix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1712014858,
"narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "9126214d0a59633752a136528f5f3b9aa8565b7d",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_4": {
"inputs": {
"nixpkgs-lib": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1727826117,
"narHash": "sha256-K5ZLCyfO/Zj9mPFldf3iwS6oZStJcU4tSpiXTMYaaL0=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "3d04084d54bedc3d6b8b736c70ef449225c361b1",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1694529238,
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_2": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1701680307,
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_3": {
"inputs": {
"systems": "systems_3"
},
"locked": {
"lastModified": 1701680307,
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_4": {
"inputs": {
"systems": "systems_4"
},
"locked": {
"lastModified": 1701680307,
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_5": {
"inputs": {
"systems": "systems_5"
},
"locked": {
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
"crate2nix",
"crate2nix_stable",
"crate2nix_stable",
"pre-commit-hooks",
"nixpkgs"
]
},
"locked": {
"lastModified": 1709087332,
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "gitignore.nix",
"type": "github"
}
},
"gitignore_2": {
"inputs": {
"nixpkgs": [
"crate2nix",
"crate2nix_stable",
"pre-commit-hooks",
"nixpkgs"
]
},
"locked": {
"lastModified": 1709087332,
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "gitignore.nix",
"type": "github"
}
},
"gitignore_3": {
"inputs": {
"nixpkgs": [
"crate2nix",
"pre-commit-hooks",
"nixpkgs"
]
},
"locked": {
"lastModified": 1709087332,
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "gitignore.nix",
"type": "github"
}
},
"nix-test-runner": {
"flake": false,
"locked": {
"lastModified": 1588761593,
"narHash": "sha256-FKJykltAN/g3eIceJl4SfDnnyuH2jHImhMrXS2KvGIs=",
"owner": "stoeffel",
"repo": "nix-test-runner",
"rev": "c45d45b11ecef3eb9d834c3b6304c05c49b06ca2",
"type": "github"
},
"original": {
"owner": "stoeffel",
"repo": "nix-test-runner",
"type": "github"
}
},
"nix-test-runner_2": {
"flake": false,
"locked": {
"lastModified": 1588761593,
"narHash": "sha256-FKJykltAN/g3eIceJl4SfDnnyuH2jHImhMrXS2KvGIs=",
"owner": "stoeffel",
"repo": "nix-test-runner",
"rev": "c45d45b11ecef3eb9d834c3b6304c05c49b06ca2",
"type": "github"
},
"original": {
"owner": "stoeffel",
"repo": "nix-test-runner",
"type": "github"
}
},
"nix-test-runner_3": {
"flake": false,
"locked": {
"lastModified": 1588761593,
"narHash": "sha256-FKJykltAN/g3eIceJl4SfDnnyuH2jHImhMrXS2KvGIs=",
"owner": "stoeffel",
"repo": "nix-test-runner",
"rev": "c45d45b11ecef3eb9d834c3b6304c05c49b06ca2",
"type": "github"
},
"original": {
"owner": "stoeffel",
"repo": "nix-test-runner",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1700612854,
"narHash": "sha256-yrQ8osMD+vDLGFX7pcwsY/Qr5PUd6OmDMYJZzZi0+zc=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "19cbff58383a4ae384dea4d1d0c823d72b49d614",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1715534503,
"narHash": "sha256-5ZSVkFadZbFP1THataCaSf0JH2cAH3S29hU9rrxTEqk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "2057814051972fa1453ddfb0d98badbea9b83c06",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1715534503,
"narHash": "sha256-5ZSVkFadZbFP1THataCaSf0JH2cAH3S29hU9rrxTEqk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "2057814051972fa1453ddfb0d98badbea9b83c06",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_4": {
"locked": {
"lastModified": 1719506693,
"narHash": "sha256-C8e9S7RzshSdHB7L+v9I51af1gDM5unhJ2xO1ywxNH8=",
"path": "/nix/store/4p0avw1s3vf27hspgqsrqs37gxk4i83i-source",
"rev": "b2852eb9365c6de48ffb0dc2c9562591f652242a",
"type": "path"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"nixpkgs_5": {
"locked": {
"lastModified": 1719506693,
"narHash": "sha256-C8e9S7RzshSdHB7L+v9I51af1gDM5unhJ2xO1ywxNH8=",
"path": "/nix/store/4p0avw1s3vf27hspgqsrqs37gxk4i83i-source",
"rev": "b2852eb9365c6de48ffb0dc2c9562591f652242a",
"type": "path"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"nixpkgs_6": {
"locked": {
"lastModified": 1712026416,
"narHash": "sha256-N/3VR/9e1NlN49p7kCiATiEY6Tzdo+CbrAG8kqCQKcI=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "080a4a27f206d07724b88da096e27ef63401a504",
"type": "github"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"nixpkgs_7": {
"locked": {
"lastModified": 0,
"narHash": "sha256-yumd4fBc/hi8a9QgA9IT8vlQuLZ2oqhkJXHPKxH/tRw=",
"path": "/nix/store/rs4fjbnw4qx7ns2hzzrz2iz52va7vs5z-source",
"type": "path"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"nixpkgs_8": {
"locked": {
"lastModified": 1718428119,
"narHash": "sha256-WdWDpNaq6u1IPtxtYHHWpl5BmabtpmLnMAx0RdJ/vo8=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e6cea36f83499eb4e9cd184c8a8e823296b50ad5",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"pre-commit-hooks": {
"inputs": {
"flake-compat": [
"crate2nix",
"crate2nix_stable",
"crate2nix_stable",
"flake-compat"
],
"gitignore": "gitignore",
"nixpkgs": [
"crate2nix",
"crate2nix_stable",
"crate2nix_stable",
"nixpkgs"
],
"nixpkgs-stable": [
"crate2nix",
"crate2nix_stable",
"crate2nix_stable",
"nixpkgs"
]
},
"locked": {
"lastModified": 1719259945,
"narHash": "sha256-F1h+XIsGKT9TkGO3omxDLEb/9jOOsI6NnzsXFsZhry4=",
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"rev": "0ff4381bbb8f7a52ca4a851660fc7a437a4c6e07",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"type": "github"
}
},
"pre-commit-hooks_2": {
"inputs": {
"flake-compat": [
"crate2nix",
"crate2nix_stable",
"flake-compat"
],
"gitignore": "gitignore_2",
"nixpkgs": [
"crate2nix",
"crate2nix_stable",
"nixpkgs"
],
"nixpkgs-stable": [
"crate2nix",
"crate2nix_stable",
"nixpkgs"
]
},
"locked": {
"lastModified": 1719259945,
"narHash": "sha256-F1h+XIsGKT9TkGO3omxDLEb/9jOOsI6NnzsXFsZhry4=",
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"rev": "0ff4381bbb8f7a52ca4a851660fc7a437a4c6e07",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"type": "github"
}
},
"pre-commit-hooks_3": {
"inputs": {
"flake-compat": [
"crate2nix",
"flake-compat"
],
"flake-utils": "flake-utils_5",
"gitignore": "gitignore_3",
"nixpkgs": [
"crate2nix",
"nixpkgs"
],
"nixpkgs-stable": [
"crate2nix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1712055707,
"narHash": "sha256-4XLvuSIDZJGS17xEwSrNuJLL7UjDYKGJSbK1WWX2AK8=",
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"rev": "e35aed5fda3cc79f88ed7f1795021e559582093a",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"type": "github"
}
},
"root": {
"inputs": {
"crate2nix": "crate2nix",
"devshell": "devshell_4",
"flake-parts": "flake-parts_4",
"nixpkgs": "nixpkgs_7",
"rust-overlay": "rust-overlay"
}
},
"rust-overlay": {
"inputs": {
"nixpkgs": "nixpkgs_8"
},
"locked": {
"lastModified": 1728354625,
"narHash": "sha256-r+Sa1NRRT7LXKzCaVaq75l1GdZcegODtF06uaxVVVbI=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "d216ade5a0091ce60076bf1f8bc816433a1fc5da",
"type": "github"
},
"original": {
"owner": "oxalica",
"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"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_3": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_4": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_5": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

113
flake.nix Normal file
View file

@ -0,0 +1,113 @@
{
description = "Rshell wayland bar";
inputs = {
flake-parts = {
url = "github:hercules-ci/flake-parts";
inputs.nixpkgs-lib.follows = "nixpkgs";
};
rust-overlay.url = "github:oxalica/rust-overlay";
crate2nix.url = "github:nix-community/crate2nix";
# Development
devshell = {
url = "github:numtide/devshell";
inputs.nixpkgs.follows = "nixpkgs";
};
};
nixConfig = {
extra-trusted-public-keys = "eigenvalue.cachix.org-1:ykerQDDa55PGxU25CETy9wF6uVDpadGGXYrFNJA3TUs=";
extra-substituters = "https://eigenvalue.cachix.org";
allow-import-from-derivation = true;
};
outputs =
inputs @ { self
, nixpkgs
, flake-parts
, rust-overlay
, crate2nix
, ...
}: flake-parts.lib.mkFlake { inherit inputs; } {
systems = [
"x86_64-linux"
"aarch64-linux"
"x86_64-darwin"
"aarch64-darwin"
];
imports = [
./nix/rust-overlay/flake-module.nix
./nix/devshell/flake-module.nix
];
perSystem = { system, pkgs, lib, inputs', ... }:
let
# If you dislike IFD, you can also generate it with `crate2nix generate`
# on each dependency change and import it here with `import ./Cargo.nix`.
# cargoNix = inputs.crate2nix.tools.${system}.appliedCargoNix {
# name = "rustnix";
# src = ./.;
# };
cargoNix = pkgs.callPackage ./Cargo.nix {
release = false;
defaultCrateOverrides = pkgs.defaultCrateOverrides // {
rav1e = attrs: {
env = {
CARGO_ENCODED_RUSTFLAGS = " ";
};
};
rshell = attrs: rec {
buildInputs = with pkgs; [
openssl
pkg-config
cmake
zlib
# common glutin
libxkbcommon
libGL
dbus
# winit wayland
wayland
# winit x11
xorg.libXcursor
xorg.libXrandr
xorg.libXi
xorg.libX11
];
nativeBuildInputs = with pkgs; [
pkg-config
fontconfig
];
LD_LIBRARY_PATH = lib.makeLibraryPath buildInputs;
RUST_SRC_PATH = pkgs.rust.packages.stable.rustPlatform.rustLibSrc;
};
};
};
in
rec {
checks = {
rshell = cargoNix.rootCrate.build.override {
runTests = true;
};
};
packages = {
rshell = cargoNix.rootCrate.build;
default = packages.rshell;
inherit (pkgs) rust-toolchain;
rust-toolchain-versions = pkgs.writeScriptBin "rust-toolchain-versions" ''
${pkgs.rust-toolchain}/bin/cargo --version
${pkgs.rust-toolchain}/bin/rustc --version
'';
};
};
};
}

View file

@ -0,0 +1,62 @@
{ inputs, lib, ... }: {
imports = [
inputs.devshell.flakeModule
];
config.perSystem =
{ pkgs
, ...
}: let
packages = with pkgs; [
libxkbcommon
libGL
dbus
wayland
xorg.libXcursor
xorg.libXrandr
xorg.libXi
xorg.libX11
openssl
alsa-lib
];
in {
config.devshells.default = {
imports = [
"${inputs.devshell}/extra/language/c.nix"
# "${inputs.devshell}/extra/language/rust.nix"
];
devshell = {
name = "rshell devshell";
packages = packages ++ [ pkgs.pkg-config ];
};
env = [{
name = "LD_LIBRARY_PATH";
value = lib.makeLibraryPath packages;
} {
name = "PKG_CONFIG_PATH";
value = lib.concatStringsSep ":"
( map
( pkg: "${pkg.dev}/lib/pkgconfig" )
( packages )
);
#"${pkgs.openssl.dev}/lib/pkgconfig";
}];
commands = with pkgs; [
{ package = rust-toolchain; category = "rust"; }
];
language.c = {
libraries =
packages ++
(lib.optional pkgs.stdenv.isDarwin pkgs.libiconv);
};
};
};
}

View file

@ -0,0 +1,20 @@
{ inputs, ... }:
let
overlays = [
(import inputs.rust-overlay)
(self: super: assert !(super ? rust-toolchain); rec {
rust-toolchain =
super.rust-bin.fromRustupToolchainFile ../../rust-toolchain.toml;
# super.rust-bin.selectLatestNightlyWith (toolchain: toolchain.default);
# buildRustCrate/crate2nix depend on this.
# rustc = rust-toolchain;
# cargo = rust-toolchain;
})
];
in
{
perSystem = { system, ... }: {
_module.args.pkgs = import inputs.nixpkgs { inherit system overlays; config = { }; };
};
}

3
rust-toolchain.toml Normal file
View file

@ -0,0 +1,3 @@
[toolchain]
channel = "stable"
components = ["rust-src"]

7
src/cli.rs Normal file
View file

@ -0,0 +1,7 @@
use clap::{Parser, Subcommand};
/// Simple program to greet a person
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
pub struct Args {
}

14
src/main.rs Normal file
View file

@ -0,0 +1,14 @@
use clap::Parser;
use cli::Args;
use cushy::{PendingApp, Run, TokioRuntime};
mod vibrancy;
mod theme;
mod cli;
fn main() -> cushy::Result {
let args = Args::parse();
let mut app = PendingApp::new(TokioRuntime::default());
app.run()
}

5
src/theme.rs Normal file
View file

@ -0,0 +1,5 @@
use cushy::styles::Color;
pub const TEXT_SPOTIFY: Color = Color(0x1DB954FF);
pub const BG_DEFAULT: Color = Color(0x191724FF);

1
src/vibrancy/README.md Normal file
View file

@ -0,0 +1 @@
Adapted from https://github.com/killercup/vibrant-rs. MIT License

7
src/vibrancy/mod.rs Normal file
View file

@ -0,0 +1,7 @@
mod settings;
mod palette;
mod vibrant;
pub use vibrant::Vibrancy;
pub use palette::Palette;

114
src/vibrancy/palette.rs Normal file
View file

@ -0,0 +1,114 @@
use std::fmt;
use std::collections::BTreeMap;
use itertools::Itertools;
use image::{GenericImage, Pixel, Rgb, Rgba};
use color_quant::NeuQuant;
/// Palette of colors.
#[derive(Debug, Hash, PartialEq, Eq, Default)]
pub struct Palette {
/// Palette of Colors represented in RGB
pub palette: Vec<Rgb<u8>>,
/// A map of indices in the palette to a count of pixels in approximately that color in the
/// original image.
pub pixel_counts: BTreeMap<usize, usize>,
}
impl Palette {
/// Create a new palett from an image
///
/// Color count and quality are given straight to [color_quant], values should be between
/// 8...512 and 1...30 respectively. (By the way: 10 is a good default quality.)
///
/// [color_quant]: https://github.com/PistonDevelopers/color_quant
pub fn new<P, G>(image: &G, color_count: usize, quality: i32) -> Palette
where P: Sized + Pixel<Subpixel = u8>,
G: Sized + GenericImage<Pixel = P>
{
let pixels: Vec<Rgba<u8>> = image.pixels()
.map(|(_, _, pixel)| pixel.to_rgba())
.collect();
let mut flat_pixels: Vec<u8> = Vec::with_capacity(pixels.len());
for rgba in &pixels {
if is_boring_pixel(&rgba) {
continue;
}
for subpixel in rgba.channels() {
flat_pixels.push(*subpixel);
}
}
let quant = NeuQuant::new(quality, color_count, &flat_pixels);
let pixel_counts = pixels.iter()
.map(|rgba| quant.index_of(&rgba.channels()))
.fold(BTreeMap::new(),
|mut acc, pixel| {
*acc.entry(pixel).or_insert(0) += 1;
acc
});
let palette: Vec<Rgb<u8>> = quant.color_map_rgba()
.iter()
.chunks(4)
.into_iter()
.map(|rgba_iter| {
let rgba_slice: Vec<u8> = rgba_iter.cloned().collect();
Rgba::from_slice(&rgba_slice).clone().to_rgb()
})
.unique()
.collect();
Palette {
palette: palette,
pixel_counts: pixel_counts,
}
}
fn frequency_of(&self, color: &Rgb<u8>) -> usize {
let index = self.palette.iter().position(|x| x.channels() == color.channels());
if let Some(index) = index {
*self.pixel_counts.get(&index).unwrap_or(&0)
} else {
0
}
}
/// Change ordering of colors in palette to be of frequency using the pixel count.
pub fn sort_by_frequency(&self) -> Self {
let mut colors = self.palette.clone();
colors.sort_by(|a, b| self.frequency_of(&a).cmp(&self.frequency_of(&b)));
Palette {
palette: colors,
pixel_counts: self.pixel_counts.clone(),
}
}
}
fn is_boring_pixel(pixel: &Rgba<u8>) -> bool {
let (r, g, b, a) = (pixel[0], pixel[1], pixel[2], pixel[3]);
// If pixel is mostly opaque and not white
const MIN_ALPHA: u8 = 125;
const MAX_COLOR: u8 = 250;
let interesting = (a >= MIN_ALPHA) && !(r > MAX_COLOR && g > MAX_COLOR && b > MAX_COLOR);
!interesting
}
impl fmt::Display for Palette {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use itertools::Itertools;
let color_list = self.palette
.iter()
.map(|rgb| format!("#{:02X}{:02X}{:02X}", rgb[0], rgb[1], rgb[2]))
.join(", ");
write!(f, "Color Palette {{ {} }}", color_list)
}
}

21
src/vibrancy/settings.rs Normal file
View file

@ -0,0 +1,21 @@
#![allow(dead_code)]
pub const TARGET_DARK_LUMA: f64 = 0.26;
pub const MAX_DARK_LUMA: f64 = 0.45;
pub const MIN_LIGHT_LUMA: f64 = 0.55;
pub const TARGET_LIGHT_LUMA: f64 = 0.74;
pub const MIN_NORMAL_LUMA: f64 = 0.3;
pub const TARGET_NORMAL_LUMA: f64 = 0.5;
pub const MAX_NORMAL_LUMA: f64 = 0.7;
pub const TARGET_MUTED_SATURATION: f64 = 0.3;
pub const MAX_MUTED_SATURATION: f64 = 0.4;
pub const TARGET_VIBRANT_SATURATION: f64 = 1.0;
pub const MIN_VIBRANT_SATURATION: f64 = 0.35;
pub const WEIGHT_SATURATION: f64 = 3.0;
pub const WEIGHT_LUMA: f64 = 6.0;
pub const WEIGHT_POPULATION: f64 = 1.0;

238
src/vibrancy/vibrant.rs Normal file
View file

@ -0,0 +1,238 @@
use std::fmt;
use std::collections::BTreeMap;
use image::{GenericImage, Pixel, Rgb};
use hsl::HSL;
// tf is rust on?????
use crate::vibrancy::settings;
// I have no idea why it's imported like this
use super::palette::Palette;
/// Vibrancy
///
/// 6 vibrant colors: primary, dark, light, dark muted and light muted.
#[derive(Debug, Hash, PartialEq, Eq, Default)]
pub struct Vibrancy {
pub primary: Option<Rgb<u8>>,
pub dark: Option<Rgb<u8>>,
pub light: Option<Rgb<u8>>,
pub muted: Option<Rgb<u8>>,
pub dark_muted: Option<Rgb<u8>>,
pub light_muted: Option<Rgb<u8>>,
}
impl Vibrancy {
/// Create new vibrancy map from an image
pub fn new<P, G>(image: &G) -> Vibrancy
where P: Sized + Pixel<Subpixel = u8>,
G: Sized + GenericImage<Pixel = P>
{
generate_varation_colors(&Palette::new(image, 256, 10))
}
fn color_already_set(&self, color: &Rgb<u8>) -> bool {
let color = Some(*color);
self.primary == color || self.dark == color || self.light == color ||
self.muted == color || self.dark_muted == color || self.light_muted == color
}
fn find_color_variation(&self,
palette: &[Rgb<u8>],
pixel_counts: &BTreeMap<usize, usize>,
luma: &MTM<f64>,
saturation: &MTM<f64>)
-> Option<Rgb<u8>> {
let mut max = None;
let mut max_value = 0_f64;
let complete_population = pixel_counts.values().fold(0, |acc, c| acc + c);
for (index, swatch) in palette.iter().enumerate() {
let HSL {h: _, s, l} = HSL::from_rgb(swatch.channels());
if s >= saturation.min && s <= saturation.max && l >= luma.min && l <= luma.max &&
!self.color_already_set(swatch) {
let population = *pixel_counts.get(&index).unwrap_or(&0) as f64;
if population == 0_f64 {
continue;
}
let value = create_comparison_value(s,
saturation.target,
l,
luma.target,
population,
complete_population as f64);
if max.is_none() || value > max_value {
max = Some(swatch.clone());
max_value = value;
}
}
}
max
}
// fn fill_empty_swatches(self) {
// if self.primary.is_none() {
// // If we do not have a vibrant color...
// if let Some(dark) = self.dark {
// // ...but we do have a dark vibrant, generate the value by modifying the luma
// let hsl = HSL::from_pixel(&dark).clone()
// hsl.l = settings::TARGET_NORMAL_LUMA;
// }
// }
// }
}
impl fmt::Display for Vibrancy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
(write!(f, "Vibrant Colors {{\n"))?;
macro_rules! display_color {
($formatter:expr, $name:expr, $color:expr) => {
{
(write!($formatter, "\t"))?;
(write!($formatter, $name))?;
if let Some(c) = $color {
let rgb = c.channels();
(write!($formatter,
" Color: #{:02X}{:02X}{:02X}\n",
rgb[0], rgb[1], rgb[2]
))?;
} else {
(write!($formatter, " Color: None\n"))?;
}
}
};
}
display_color!(f, "Primary Vibrant", self.primary);
display_color!(f, "Dark Vibrant", self.dark);
display_color!(f, "Light Vibrant", self.light);
display_color!(f, "Muted", self.muted);
display_color!(f, "Dark Muted", self.dark_muted);
display_color!(f, "Light Muted", self.light_muted);
write!(f, "}}")
}
}
fn generate_varation_colors(p: &Palette) -> Vibrancy {
let mut vibrancy = Vibrancy::default();
vibrancy.primary =
vibrancy.find_color_variation(&p.palette,
&p.pixel_counts,
&MTM {
min: settings::MIN_NORMAL_LUMA,
target: settings::TARGET_NORMAL_LUMA,
max: settings::MAX_NORMAL_LUMA,
},
&MTM {
min: settings::MIN_VIBRANT_SATURATION,
target: settings::TARGET_VIBRANT_SATURATION,
max: 1_f64,
});
vibrancy.light = vibrancy.find_color_variation(&p.palette,
&p.pixel_counts,
&MTM {
min: settings::MIN_LIGHT_LUMA,
target: settings::TARGET_LIGHT_LUMA,
max: 1_f64,
},
&MTM {
min: settings::MIN_VIBRANT_SATURATION,
target: settings::TARGET_VIBRANT_SATURATION,
max: 1_f64,
});
vibrancy.dark = vibrancy.find_color_variation(&p.palette,
&p.pixel_counts,
&MTM {
min: 0_f64,
target: settings::TARGET_DARK_LUMA,
max: settings::MAX_DARK_LUMA,
},
&MTM {
min: settings::MIN_VIBRANT_SATURATION,
target: settings::TARGET_VIBRANT_SATURATION,
max: 1_f64,
});
vibrancy.muted = vibrancy.find_color_variation(&p.palette,
&p.pixel_counts,
&MTM {
min: settings::MIN_NORMAL_LUMA,
target: settings::TARGET_NORMAL_LUMA,
max: settings::MAX_NORMAL_LUMA,
},
&MTM {
min: 0_f64,
target: settings::TARGET_MUTED_SATURATION,
max: settings::MAX_MUTED_SATURATION,
});
vibrancy.light_muted = vibrancy.find_color_variation(&p.palette,
&p.pixel_counts,
&MTM {
min: settings::MIN_LIGHT_LUMA,
target: settings::TARGET_LIGHT_LUMA,
max: 1_f64,
},
&MTM {
min: 0_f64,
target: settings::TARGET_MUTED_SATURATION,
max: settings::MAX_MUTED_SATURATION,
});
vibrancy.dark_muted = vibrancy.find_color_variation(&p.palette,
&p.pixel_counts,
&MTM {
min: 0_f64,
target: settings::TARGET_DARK_LUMA,
max: settings::MAX_DARK_LUMA,
},
&MTM {
min: 0_f64,
target: settings::TARGET_MUTED_SATURATION,
max: settings::MAX_MUTED_SATURATION,
});
vibrancy
}
fn invert_diff(val: f64, target_val: f64) -> f64 {
1_f64 - (val - target_val).abs()
}
fn weighted_mean(vals: &[(f64, f64)]) -> f64 {
let (sum, sum_weight) = vals.iter().fold((0_f64, 0_f64),
|(sum, sum_weight), &(val, weight)| {
(sum + val * weight, sum_weight + weight)
});
sum / sum_weight
}
fn create_comparison_value(sat: f64,
target_sat: f64,
luma: f64,
target_uma: f64,
population: f64,
max_population: f64)
-> f64 {
weighted_mean(&[(invert_diff(sat, target_sat),
settings::WEIGHT_SATURATION),
(invert_diff(luma, target_uma), settings::WEIGHT_LUMA),
(population / max_population,
settings::WEIGHT_POPULATION)])
}
/// Minimum, Maximum, Target
#[derive(Debug, Hash)]
struct MTM<T> {
min: T,
target: T,
max: T,
}