disable modules, README, warning fixes
This commit is contained in:
parent
ed68b9fd93
commit
5ad933c03b
9 changed files with 215 additions and 24 deletions
103
README.md
103
README.md
|
|
@ -32,6 +32,109 @@ imports = [ inputs.nova-shell.homeModules.default ];
|
||||||
programs.nova-shell.enable = true;
|
programs.nova-shell.enable = true;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Surprisingly, the robot managed to wire up a Home Manager module that mostly works.
|
||||||
|
Here is how to make it do things.
|
||||||
|
|
||||||
|
### Flake setup
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# flake.nix
|
||||||
|
inputs = {
|
||||||
|
nova-shell.url = "git+https://git.berlin.ccc.de/vinzenz/nova-shell";
|
||||||
|
nova-shell.inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# home.nix
|
||||||
|
imports = [ inputs.nova-shell.homeModules.default ];
|
||||||
|
```
|
||||||
|
|
||||||
|
### Turning it on
|
||||||
|
|
||||||
|
```nix
|
||||||
|
programs.nova-shell.enable = true;
|
||||||
|
```
|
||||||
|
|
||||||
|
This installs the bar, the Symbols Nerd Font, and a systemd user service that
|
||||||
|
starts with `graphical-session.target`. If you use
|
||||||
|
[stylix](https://github.com/danth/stylix), colors and fonts are populated
|
||||||
|
automatically — one fewer thing for the AI to have gotten wrong.
|
||||||
|
|
||||||
|
### Disabling modules
|
||||||
|
|
||||||
|
All modules are on by default because the robot was optimistic. Set any to
|
||||||
|
`false` to get rid of them. Disabling `weather` also skips pulling in
|
||||||
|
`wttrbar`, which is the one genuinely useful thing the module system does.
|
||||||
|
|
||||||
|
```nix
|
||||||
|
programs.nova-shell.modules = {
|
||||||
|
weather = false; # also removes the wttrbar dependency
|
||||||
|
bluetooth = false; # unless you enjoy a ghost icon on your desktop
|
||||||
|
backlight = false; # desktops don't have screens that dim, allegedly
|
||||||
|
battery = false; # see above
|
||||||
|
temperature = false; # ignorance is thermally efficient
|
||||||
|
disk = false;
|
||||||
|
wlogout = false; # if you enjoy living dangerously without a logout button
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
Full list of things you can disable: `tray`, `windowTitle`, `clock`,
|
||||||
|
`notifications`, `mpris`, `volume`, `bluetooth`, `backlight`, `network`,
|
||||||
|
`powerProfile`, `idleInhibitor`, `weather`, `temperature`, `cpu`, `memory`,
|
||||||
|
`disk`, `battery`, `wlogout`.
|
||||||
|
|
||||||
|
### Theme
|
||||||
|
|
||||||
|
Theme keys merge on top of whatever stylix provides, so you only need to
|
||||||
|
specify what you want to override. The AI picked Catppuccin Mocha as the
|
||||||
|
fallback, because of course it did.
|
||||||
|
|
||||||
|
```nix
|
||||||
|
programs.nova-shell.theme = {
|
||||||
|
barHeight = 28;
|
||||||
|
barOpacity = 0.85;
|
||||||
|
barPadding = 10;
|
||||||
|
barSpacing = 8;
|
||||||
|
radius = 6;
|
||||||
|
fontSize = 13;
|
||||||
|
fontFamily = "JetBrains Mono";
|
||||||
|
|
||||||
|
# override individual palette entries if stylix's choices offend you
|
||||||
|
colors.base00 = "#1a1a2e";
|
||||||
|
colors.base05 = "#e0e0f0";
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
Full list of theme keys and their defaults:
|
||||||
|
|
||||||
|
| Key | Default | Controls |
|
||||||
|
|-----|---------|----------|
|
||||||
|
| `colors.base00`–`base0F` | Catppuccin Mocha | Base16 palette |
|
||||||
|
| `fontFamily` | `"sans-serif"` | Bar text font |
|
||||||
|
| `iconFontFamily` | `"Symbols Nerd Font"` | Nerd font for icons |
|
||||||
|
| `fontSize` | `12` | Base font size (px) |
|
||||||
|
| `barHeight` | `32` | Bar height (px) |
|
||||||
|
| `barOpacity` | `0.9` | Bar and flyout background opacity |
|
||||||
|
| `barPadding` | `8` | Left/right bar content margin (px) |
|
||||||
|
| `barSpacing` | `12` | Gap between modules (px) |
|
||||||
|
| `moduleSpacing` | `4` | Icon-to-label gap within a module (px) |
|
||||||
|
| `radius` | `4` | Corner radius for flyouts and menus (px) |
|
||||||
|
|
||||||
|
### Systemd service
|
||||||
|
|
||||||
|
Enabled by default. To attach it to a different target or disable it entirely
|
||||||
|
because you have opinions about service management:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
programs.nova-shell.systemd = {
|
||||||
|
enable = true;
|
||||||
|
target = "niri.service";
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
Sure, why not. It can't get much worse.
|
Sure, why not. It can't get much worse.
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import "." as M
|
||||||
M.BarSection {
|
M.BarSection {
|
||||||
id: root
|
id: root
|
||||||
spacing: M.Theme.moduleSpacing
|
spacing: M.Theme.moduleSpacing
|
||||||
visible: percent > 0
|
visible: M.Modules.backlight && percent > 0
|
||||||
tooltip: "Brightness: " + root.percent + "%"
|
tooltip: "Brightness: " + root.percent + "%"
|
||||||
|
|
||||||
property int percent: 0
|
property int percent: 0
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,8 @@ PanelWindow {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
spacing: M.Theme.barSpacing
|
spacing: M.Theme.barSpacing
|
||||||
|
|
||||||
M.Clock {}
|
M.Clock { visible: M.Modules.clock }
|
||||||
M.Notifications {}
|
M.Notifications { visible: M.Modules.notifications }
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- left ----
|
// ---- left ----
|
||||||
|
|
@ -52,9 +52,11 @@ PanelWindow {
|
||||||
|
|
||||||
M.Tray {
|
M.Tray {
|
||||||
bar: bar
|
bar: bar
|
||||||
|
visible: M.Modules.tray
|
||||||
}
|
}
|
||||||
M.WindowTitle {
|
M.WindowTitle {
|
||||||
Layout.maximumWidth: 400
|
Layout.maximumWidth: 400
|
||||||
|
visible: M.Modules.windowTitle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,19 +71,19 @@ PanelWindow {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
M.Mpris {}
|
M.Mpris {}
|
||||||
M.Volume {}
|
M.Volume { visible: M.Modules.volume }
|
||||||
M.Bluetooth {}
|
M.Bluetooth {}
|
||||||
M.Backlight {}
|
M.Backlight {}
|
||||||
M.Network {}
|
M.Network { visible: M.Modules.network }
|
||||||
M.PowerProfile {}
|
M.PowerProfile { visible: M.Modules.powerProfile }
|
||||||
M.IdleInhibitor {}
|
M.IdleInhibitor { visible: M.Modules.idleInhibitor }
|
||||||
M.Weather {}
|
M.Weather { visible: M.Modules.weather }
|
||||||
M.Temperature {}
|
M.Temperature { visible: M.Modules.temperature }
|
||||||
M.Cpu {}
|
M.Cpu { visible: M.Modules.cpu }
|
||||||
M.Memory {}
|
M.Memory { visible: M.Modules.memory }
|
||||||
M.Disk {}
|
M.Disk { visible: M.Modules.disk }
|
||||||
M.Battery {}
|
M.Battery {}
|
||||||
M.Wlogout {}
|
M.Wlogout { visible: M.Modules.wlogout }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import "." as M
|
||||||
M.BarSection {
|
M.BarSection {
|
||||||
id: root
|
id: root
|
||||||
spacing: M.Theme.moduleSpacing
|
spacing: M.Theme.moduleSpacing
|
||||||
visible: UPower.displayDevice?.isLaptopBattery ?? false
|
visible: M.Modules.battery && (UPower.displayDevice?.isLaptopBattery ?? false)
|
||||||
tooltip: {
|
tooltip: {
|
||||||
const state = root.charging ? "Charging" : "Discharging";
|
const state = root.charging ? "Charging" : "Discharging";
|
||||||
const t = root.charging ? root.dev?.timeToFull : root.dev?.timeToEmpty;
|
const t = root.charging ? root.dev?.timeToFull : root.dev?.timeToEmpty;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import "." as M
|
||||||
M.BarSection {
|
M.BarSection {
|
||||||
id: root
|
id: root
|
||||||
spacing: M.Theme.moduleSpacing
|
spacing: M.Theme.moduleSpacing
|
||||||
visible: root.state !== "unavailable"
|
visible: M.Modules.bluetooth && root.state !== "unavailable"
|
||||||
tooltip: {
|
tooltip: {
|
||||||
if (root.state === "off") return "Bluetooth: off";
|
if (root.state === "off") return "Bluetooth: off";
|
||||||
if (root.state === "connected") return "Bluetooth: " + root.device;
|
if (root.state === "connected") return "Bluetooth: " + root.device;
|
||||||
|
|
@ -61,10 +61,9 @@ M.BarSection {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
TapHandler {
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onTapped: {
|
||||||
toggle.cmd = root.state === "off" ? "on" : "off";
|
toggle.cmd = root.state === "off" ? "on" : "off";
|
||||||
toggle.running = true;
|
toggle.running = true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
48
modules/Modules.qml
Normal file
48
modules/Modules.qml
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool tray: true
|
||||||
|
property bool windowTitle: true
|
||||||
|
property bool clock: true
|
||||||
|
property bool notifications: true
|
||||||
|
property bool mpris: true
|
||||||
|
property bool volume: true
|
||||||
|
property bool bluetooth: true
|
||||||
|
property bool backlight: true
|
||||||
|
property bool network: true
|
||||||
|
property bool powerProfile: true
|
||||||
|
property bool idleInhibitor: true
|
||||||
|
property bool weather: true
|
||||||
|
property bool temperature: true
|
||||||
|
property bool cpu: true
|
||||||
|
property bool memory: true
|
||||||
|
property bool disk: true
|
||||||
|
property bool battery: true
|
||||||
|
property bool wlogout: true
|
||||||
|
|
||||||
|
property FileView _file: FileView {
|
||||||
|
path: (Quickshell.env("XDG_CONFIG_HOME") || (Quickshell.env("HOME") + "/.config")) + "/nova-shell/modules.json"
|
||||||
|
watchChanges: true
|
||||||
|
onFileChanged: reload()
|
||||||
|
onLoaded: root._apply(text())
|
||||||
|
}
|
||||||
|
|
||||||
|
function _apply(raw) {
|
||||||
|
let data;
|
||||||
|
try {
|
||||||
|
data = JSON.parse(raw);
|
||||||
|
} catch (e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (const k of Object.keys(data)) {
|
||||||
|
if (k in root && typeof root[k] === "boolean")
|
||||||
|
root[k] = data[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,7 @@ import "." as M
|
||||||
M.BarSection {
|
M.BarSection {
|
||||||
id: root
|
id: root
|
||||||
spacing: M.Theme.moduleSpacing
|
spacing: M.Theme.moduleSpacing
|
||||||
visible: player !== null
|
visible: M.Modules.mpris && player !== null
|
||||||
tooltip: {
|
tooltip: {
|
||||||
const p = root.player;
|
const p = root.player;
|
||||||
if (!p)
|
if (!p)
|
||||||
|
|
@ -14,7 +14,7 @@ M.BarSection {
|
||||||
if (p.trackTitle)
|
if (p.trackTitle)
|
||||||
parts.push(p.trackTitle);
|
parts.push(p.trackTitle);
|
||||||
if (p.trackArtists?.length)
|
if (p.trackArtists?.length)
|
||||||
parts.push(p.trackArtists.join(", "));
|
parts.push(Array.isArray(p.trackArtists) ? p.trackArtists.join(", ") : p.trackArtists);
|
||||||
if (p.trackAlbum)
|
if (p.trackAlbum)
|
||||||
parts.push(p.trackAlbum);
|
parts.push(p.trackAlbum);
|
||||||
return parts.join("\n") || p.identity;
|
return parts.join("\n") || p.identity;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
module modules
|
module modules
|
||||||
singleton Theme 1.0 Theme.qml
|
singleton Theme 1.0 Theme.qml
|
||||||
singleton FlyoutState 1.0 FlyoutState.qml
|
singleton FlyoutState 1.0 FlyoutState.qml
|
||||||
|
singleton Modules 1.0 Modules.qml
|
||||||
Bar 1.0 Bar.qml
|
Bar 1.0 Bar.qml
|
||||||
BarSection 1.0 BarSection.qml
|
BarSection 1.0 BarSection.qml
|
||||||
Flyout 1.0 Flyout.qml
|
Flyout 1.0 Flyout.qml
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,39 @@ in
|
||||||
description = "nova-shell package to use.";
|
description = "nova-shell package to use.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
modules = lib.mkOption {
|
||||||
|
description = "Enable or disable individual bar modules.";
|
||||||
|
default = { };
|
||||||
|
type = lib.types.submodule {
|
||||||
|
options = lib.genAttrs
|
||||||
|
[
|
||||||
|
"tray"
|
||||||
|
"windowTitle"
|
||||||
|
"clock"
|
||||||
|
"notifications"
|
||||||
|
"mpris"
|
||||||
|
"volume"
|
||||||
|
"bluetooth"
|
||||||
|
"backlight"
|
||||||
|
"network"
|
||||||
|
"powerProfile"
|
||||||
|
"idleInhibitor"
|
||||||
|
"weather"
|
||||||
|
"temperature"
|
||||||
|
"cpu"
|
||||||
|
"memory"
|
||||||
|
"disk"
|
||||||
|
"battery"
|
||||||
|
"wlogout"
|
||||||
|
]
|
||||||
|
(name: lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Enable the ${name} module.";
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
theme = lib.mkOption {
|
theme = lib.mkOption {
|
||||||
type = lib.types.attrsOf lib.types.anything;
|
type = lib.types.attrsOf lib.types.anything;
|
||||||
default = { };
|
default = { };
|
||||||
|
|
@ -80,10 +113,15 @@ in
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
programs.nova-shell.theme = lib.mkIf stylixAvailable (lib.mkDefault stylixTheme);
|
programs.nova-shell.theme = lib.mkIf stylixAvailable (lib.mkDefault stylixTheme);
|
||||||
|
|
||||||
home.packages = [
|
home.packages =
|
||||||
|
[
|
||||||
self.packages.${pkgs.stdenv.hostPlatform.system}.nova-shell-cli
|
self.packages.${pkgs.stdenv.hostPlatform.system}.nova-shell-cli
|
||||||
pkgs.nerd-fonts.symbols-only
|
pkgs.nerd-fonts.symbols-only
|
||||||
];
|
]
|
||||||
|
++ lib.optional cfg.modules.weather pkgs.wttrbar;
|
||||||
|
|
||||||
|
xdg.configFile."nova-shell/modules.json".source =
|
||||||
|
(pkgs.formats.json { }).generate "nova-shell-modules.json" cfg.modules;
|
||||||
|
|
||||||
xdg.configFile."nova-shell/theme.json".source =
|
xdg.configFile."nova-shell/theme.json".source =
|
||||||
(pkgs.formats.json { }).generate "nova-shell-theme.json"
|
(pkgs.formats.json { }).generate "nova-shell-theme.json"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue