nix
This commit is contained in:
@@ -0,0 +1,15 @@
|
|||||||
|
import qs.Config
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
property real fill
|
||||||
|
property int grade: DynamicColors.light ? 0 : -25
|
||||||
|
|
||||||
|
font.family: "Material Symbols Rounded"
|
||||||
|
font.pointSize: 15
|
||||||
|
font.variableAxes: ({
|
||||||
|
FILL: fill.toFixed(1),
|
||||||
|
GRAD: grade,
|
||||||
|
opsz: fontInfo.pixelSize,
|
||||||
|
wght: fontInfo.weight
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
import qs.Config
|
||||||
|
import Caelestia.Services
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Services.Pipewire
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
Singleton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property string previousSinkName: ""
|
||||||
|
property string previousSourceName: ""
|
||||||
|
|
||||||
|
readonly property var nodes: Pipewire.nodes.values.reduce((acc, node) => {
|
||||||
|
if (!node.isStream) {
|
||||||
|
if (node.isSink)
|
||||||
|
acc.sinks.push(node);
|
||||||
|
else if (node.audio)
|
||||||
|
acc.sources.push(node);
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, {
|
||||||
|
sources: [],
|
||||||
|
sinks: []
|
||||||
|
})
|
||||||
|
|
||||||
|
readonly property list<PwNode> sinks: nodes.sinks
|
||||||
|
readonly property list<PwNode> sources: nodes.sources
|
||||||
|
|
||||||
|
readonly property PwNode sink: Pipewire.defaultAudioSink
|
||||||
|
readonly property PwNode source: Pipewire.defaultAudioSource
|
||||||
|
|
||||||
|
readonly property bool muted: !!sink?.audio?.muted
|
||||||
|
readonly property real volume: sink?.audio?.volume ?? 0
|
||||||
|
|
||||||
|
readonly property bool sourceMuted: !!source?.audio?.muted
|
||||||
|
readonly property real sourceVolume: source?.audio?.volume ?? 0
|
||||||
|
|
||||||
|
readonly property alias beatTracker: beatTracker
|
||||||
|
|
||||||
|
function setVolume(newVolume: real): void {
|
||||||
|
if (sink?.ready && sink?.audio) {
|
||||||
|
sink.audio.muted = false;
|
||||||
|
sink.audio.volume = Math.max(0, Math.min(100, newVolume));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function incrementVolume(amount: real): void {
|
||||||
|
setVolume(volume + (amount || 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
function decrementVolume(amount: real): void {
|
||||||
|
setVolume(volume - (amount || 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSourceVolume(newVolume: real): void {
|
||||||
|
if (source?.ready && source?.audio) {
|
||||||
|
source.audio.muted = false;
|
||||||
|
source.audio.volume = Math.max(0, Math.min(100, newVolume));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function incrementSourceVolume(amount: real): void {
|
||||||
|
setSourceVolume(sourceVolume + (amount || 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
function decrementSourceVolume(amount: real): void {
|
||||||
|
setSourceVolume(sourceVolume - (amount || 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
function setAudioSink(newSink: PwNode): void {
|
||||||
|
Pipewire.preferredDefaultAudioSink = newSink;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setAudioSource(newSource: PwNode): void {
|
||||||
|
Pipewire.preferredDefaultAudioSource = newSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
onSinkChanged: {
|
||||||
|
if (!sink?.ready)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const newSinkName = sink.description || sink.name || qsTr("Unknown Device");
|
||||||
|
|
||||||
|
previousSinkName = newSinkName;
|
||||||
|
}
|
||||||
|
|
||||||
|
onSourceChanged: {
|
||||||
|
if (!source?.ready)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const newSourceName = source.description || source.name || qsTr("Unknown Device");
|
||||||
|
|
||||||
|
previousSourceName = newSourceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
previousSinkName = sink?.description || sink?.name || qsTr("Unknown Device");
|
||||||
|
previousSourceName = source?.description || source?.name || qsTr("Unknown Device");
|
||||||
|
}
|
||||||
|
|
||||||
|
PwObjectTracker {
|
||||||
|
objects: [...root.sinks, ...root.sources]
|
||||||
|
}
|
||||||
|
|
||||||
|
BeatTracker {
|
||||||
|
id: beatTracker
|
||||||
|
}
|
||||||
|
}
|
||||||
+34
-10
@@ -7,12 +7,36 @@ import QtQuick.Layouts
|
|||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import qs.Config
|
import qs.Config
|
||||||
import qs.Components
|
import qs.Components
|
||||||
|
import qs.Daemons
|
||||||
|
|
||||||
Item {
|
CustomRect {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
implicitWidth: layout.implicitWidth + 10 * 2
|
implicitWidth: layout.implicitWidth + 10 * 2
|
||||||
implicitHeight: layout.implicitHeight + 10 * 2
|
implicitHeight: 0
|
||||||
|
color: Config.useDynamicColors ? DynamicColors.tPalette.m3surface : "#40000000"
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
property alias expanded: root.isExpanded
|
||||||
|
property bool isExpanded: false
|
||||||
|
|
||||||
|
Anim {
|
||||||
|
id: expandAnim
|
||||||
|
running: root.isExpanded
|
||||||
|
target: root
|
||||||
|
property: "implicitHeight"
|
||||||
|
to: layout.implicitHeight + 10 * 2
|
||||||
|
duration: MaterialEasing.standardTime
|
||||||
|
}
|
||||||
|
|
||||||
|
Anim {
|
||||||
|
id: collapseAnim
|
||||||
|
running: !root.isExpanded
|
||||||
|
target: root
|
||||||
|
property: "implicitHeight"
|
||||||
|
to: 0
|
||||||
|
duration: MaterialEasing.standardTime
|
||||||
|
}
|
||||||
|
|
||||||
ButtonGroup {
|
ButtonGroup {
|
||||||
id: sinks
|
id: sinks
|
||||||
@@ -58,7 +82,7 @@ Item {
|
|||||||
Repeater {
|
Repeater {
|
||||||
model: Audio.sources
|
model: Audio.sources
|
||||||
|
|
||||||
StyledRadioButton {
|
CustomRadioButton {
|
||||||
required property PwNode modelData
|
required property PwNode modelData
|
||||||
|
|
||||||
ButtonGroup.group: sources
|
ButtonGroup.group: sources
|
||||||
@@ -114,7 +138,7 @@ Item {
|
|||||||
color: DynamicColors.palette.m3onPrimaryContainer
|
color: DynamicColors.palette.m3onPrimaryContainer
|
||||||
|
|
||||||
function onClicked(): void {
|
function onClicked(): void {
|
||||||
root.wrapper.hasCurrent = false;
|
root.isExpanded = !root.isExpanded;
|
||||||
Quickshell.execDetached(["app2unit", "--", "pavucontrol"]);
|
Quickshell.execDetached(["app2unit", "--", "pavucontrol"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,18 +147,18 @@ Item {
|
|||||||
id: expandBtn
|
id: expandBtn
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: Appearance.spacing.small
|
spacing: 7
|
||||||
|
|
||||||
StyledText {
|
CustomText {
|
||||||
Layout.leftMargin: Appearance.padding.smaller
|
Layout.leftMargin: 7
|
||||||
text: qsTr("Open settings")
|
text: qsTr("Open settings")
|
||||||
color: Colours.palette.m3onPrimaryContainer
|
color: DynamicColors.palette.m3onPrimaryContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
text: "chevron_right"
|
text: "chevron_right"
|
||||||
color: Colours.palette.m3onPrimaryContainer
|
color: DynamicColors.palette.m3onPrimaryContainer
|
||||||
font.pointSize: Appearance.font.size.large
|
font.pointSize: 18
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,13 +53,20 @@ Item {
|
|||||||
border.width: 0
|
border.width: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AudioPopup {
|
||||||
|
id: audioPopup
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.top: parent.bottom
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onEntered: root.expanded = true
|
onEntered: audioPopup.expanded = true
|
||||||
onExited: root.expanded = false
|
onExited: audioPopup.expanded = false
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
anchors {
|
anchors {
|
||||||
fill: parent
|
fill: parent
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ Item {
|
|||||||
text: root.currentTitle
|
text: root.currentTitle
|
||||||
color: root.textColor
|
color: root.textColor
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
|
font.family: "Rubik"
|
||||||
font.pixelSize: 16
|
font.pixelSize: 16
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
{
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||||
|
|
||||||
|
quickshell = {
|
||||||
|
url = "git+https://git.outfoxxed.me/outfoxxed/quickshell";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = {
|
||||||
|
self,
|
||||||
|
nixpkgs,
|
||||||
|
...
|
||||||
|
} @ inputs: let
|
||||||
|
forAllSystems = fn:
|
||||||
|
nixpkgs.lib.genAttrs nixpkgs.lib.platforms.linux (
|
||||||
|
system: fn nixpkgs.legacyPackages.${system}
|
||||||
|
);
|
||||||
|
in {
|
||||||
|
formatter = forAllSystems (pkgs: pkgs.alejandra);
|
||||||
|
|
||||||
|
packages = forAllSystems (pkgs: rec {
|
||||||
|
zshell = pkgs.callPackage ./nix {
|
||||||
|
rev = self.rev or self.dirtyRev;
|
||||||
|
stdenv = pkgs.clangStdenv;
|
||||||
|
quickshell = inputs.quickshell.packages.${pkgs.stdenv.hostPlatform.system}.default.override {
|
||||||
|
withX11 = false;
|
||||||
|
withI3 = false;
|
||||||
|
};
|
||||||
|
app2unit = pkgs.callPackage ./nix/app2unit.nix {inherit pkgs;};
|
||||||
|
};
|
||||||
|
debug = zshell.override {debug = true;};
|
||||||
|
default = zshell;
|
||||||
|
});
|
||||||
|
|
||||||
|
devShells = forAllSystems (pkgs: {
|
||||||
|
default = let
|
||||||
|
shell = self.packages.${pkgs.stdenv.hostPlatform.system}.zshell;
|
||||||
|
in
|
||||||
|
pkgs.mkShell.override {stdenv = shell.stdenv;} {
|
||||||
|
inputsFrom = [shell shell.plugin shell.extras];
|
||||||
|
packages = with pkgs; [clazy material-symbols rubik nerd-fonts.caskaydia-cove];
|
||||||
|
CAELESTIA_XKB_RULES_PATH = "${pkgs.xkeyboard-config}/share/xkeyboard-config-2/rules/base.lst";
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
pkgs, # To ensure the nixpkgs version of app2unit
|
||||||
|
fetchFromGitHub,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
pkgs.app2unit.overrideAttrs (final: prev: rec {
|
||||||
|
version = "1.0.3"; # Fix old issue related to missing env var
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "Vladimir-csp";
|
||||||
|
repo = "app2unit";
|
||||||
|
tag = "v${version}";
|
||||||
|
hash = "sha256-7eEVjgs+8k+/NLteSBKgn4gPaPLHC+3Uzlmz6XB0930=";
|
||||||
|
};
|
||||||
|
})
|
||||||
+103
@@ -0,0 +1,103 @@
|
|||||||
|
{
|
||||||
|
rev,
|
||||||
|
lib,
|
||||||
|
stdenv,
|
||||||
|
makeWrapper,
|
||||||
|
makeFontsConf,
|
||||||
|
app2unit,
|
||||||
|
lm_sensors,
|
||||||
|
swappy,
|
||||||
|
wl-clipboard,
|
||||||
|
libqalculate,
|
||||||
|
bash,
|
||||||
|
hyprland,
|
||||||
|
material-symbols,
|
||||||
|
rubik,
|
||||||
|
nerd-fonts,
|
||||||
|
qt6,
|
||||||
|
quickshell,
|
||||||
|
aubio,
|
||||||
|
fftw,
|
||||||
|
pipewire,
|
||||||
|
xkeyboard-config,
|
||||||
|
cmake,
|
||||||
|
ninja,
|
||||||
|
pkg-config,
|
||||||
|
debug ? false,
|
||||||
|
withCli ? false,
|
||||||
|
extraRuntimeDeps ? [],
|
||||||
|
}: let
|
||||||
|
version = "1.0.0";
|
||||||
|
|
||||||
|
runtimeDeps =
|
||||||
|
[
|
||||||
|
ddcutil
|
||||||
|
brightnessctl
|
||||||
|
app2unit
|
||||||
|
networkmanager
|
||||||
|
lm_sensors
|
||||||
|
swappy
|
||||||
|
wl-clipboard
|
||||||
|
libqalculate
|
||||||
|
bash
|
||||||
|
hyprland
|
||||||
|
]
|
||||||
|
++ extraRuntimeDeps
|
||||||
|
|
||||||
|
fontconfig = makeFontsConf {
|
||||||
|
fontDirectories = [material-symbols rubik nerd-fonts.caskaydia-cove];
|
||||||
|
};
|
||||||
|
|
||||||
|
cmakeBuildType =
|
||||||
|
if debug
|
||||||
|
then "Debug"
|
||||||
|
else "RelWithDebInfo";
|
||||||
|
|
||||||
|
plugin = stdenv.mkDerivation {
|
||||||
|
inherit cmakeBuildType;
|
||||||
|
name = "zshell-qml-plugin${lib.optionalString debug "-debug"}";
|
||||||
|
src = lib.fileset.toSource {
|
||||||
|
root = ./..;
|
||||||
|
fileset = lib.fileset.union ./../CMakeLists.txt ./../Plugins;
|
||||||
|
};
|
||||||
|
|
||||||
|
nativeBuildInputs = [cmake ninja pkg-config];
|
||||||
|
buildInputs = [qt6.qtbase qt6.qtdeclarative libqalculate pipewire aubio libcava fftw];
|
||||||
|
|
||||||
|
dontWrapQtApps = true;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
inherit version cmakeBuildType;
|
||||||
|
pname = "zshell${lib.optionalString debug "-debug"}";
|
||||||
|
src = ./..;
|
||||||
|
|
||||||
|
nativeBuildInputs = [cmake ninja makeWrapper qt6.wrapQtAppsHook];
|
||||||
|
buildInputs = [quickshell extras plugin xkeyboard-config qt6.qtbase];
|
||||||
|
propagatedBuildInputs = runtimeDeps;
|
||||||
|
|
||||||
|
cmakeFlags =
|
||||||
|
[
|
||||||
|
(lib.cmakeFeature "ENABLE_MODULES" "shell")
|
||||||
|
(lib.cmakeFeature "INSTALL_QSCONFDIR" "${placeholder "out"}/share/zshell")
|
||||||
|
]
|
||||||
|
++ cmakeVersionFlags;
|
||||||
|
|
||||||
|
dontStrip = debug;
|
||||||
|
|
||||||
|
prePatch = ''
|
||||||
|
substituteInPlace assets/pam.d/fprint \
|
||||||
|
--replace-fail pam_fprintd.so /run/current-system/sw/lib/security/pam_fprintd.so
|
||||||
|
substituteInPlace shell.qml \
|
||||||
|
--replace-fail 'ShellRoot {' 'ShellRoot { settings.watchFiles: false'
|
||||||
|
'';
|
||||||
|
|
||||||
|
postInstall = ''
|
||||||
|
mkdir -p $out/lib
|
||||||
|
ln -s ${extras}/lib/* $out/lib/
|
||||||
|
'';
|
||||||
|
|
||||||
|
passthru = {
|
||||||
|
inherit plugin;
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user