diff --git a/README.md b/README.md index d06c4c0..353cc18 100644 --- a/README.md +++ b/README.md @@ -69,20 +69,25 @@ frankly more than it deserves. ```nix programs.nova-shell.modules = { - weather = false; # also evicts wttrbar from your system - bluetooth = false; # for people whose computers have ethernet ports and opinions - backlight = false; # your desktop monitor does not have a backlight slider, probably - battery = false; # see above, but for power - temperature = false; # what you don't measure can't alarm you - disk = false; # the number will only make you anxious - power = false; # if you enjoy living dangerously without a logout button + weather.enable = false; # also evicts wttrbar from your system + bluetooth.enable = false; # for people whose computers have ethernet ports and opinions + backlight.enable = false; # your desktop monitor does not have a backlight slider, probably + battery.enable = false; # see above, but for power + temperature.enable = false; # what you don't measure can't alarm you + disk.enable = false; # the number will only make you anxious + power.enable = false; # if you enjoy living dangerously without a logout button + + # modules with extra config + backlight.step = 2; # brightness adjustment % + weather.args = [ "--nerd" "--location" "Berlin" ]; # wttrbar arguments }; ``` -Full list of things you can disable: `workspaces`, `tray`, `windowTitle`, -`clock`, `notifications`, `mpris`, `volume`, `bluetooth`, `backlight`, -`network`, `powerProfile`, `idleInhibitor`, `weather`, `temperature`, `cpu`, -`memory`, `disk`, `battery`, `power`. +Each module is an object with `enable` (default `true`) and optional extra +settings. Full list: `workspaces`, `tray`, `windowTitle`, `clock`, +`notifications`, `mpris`, `volume`, `bluetooth`, `backlight`, `network`, +`powerProfile`, `idleInhibitor`, `weather`, `temperature`, `cpu`, `memory`, +`disk`, `battery`, `power`. ### Theme @@ -124,16 +129,6 @@ Full list of theme keys and their defaults: | `radius` | `4` | Corner radius for flyouts and menus (px) | | `screenRadius` | `15` | Screen corner rounding, 0 to disable (px) | -### Weather - -Wttrbar arguments are configurable. The default is `["--nerd"]` which gives -you nerd font weather icons, which is the only acceptable way to display -meteorological data. - -```nix -programs.nova-shell.weatherArgs = [ "--nerd" "--location" "Berlin" ]; -``` - ### Systemd service Enabled by default, bound to `graphical-session.target`. To attach it to diff --git a/modules/Backlight.qml b/modules/Backlight.qml index 6ad1a52..626081f 100644 --- a/modules/Backlight.qml +++ b/modules/Backlight.qml @@ -5,7 +5,7 @@ import "." as M M.BarSection { id: root spacing: M.Theme.moduleSpacing - opacity: M.Modules.backlight && percent > 0 ? 1 : 0 + opacity: M.Modules.backlight.enable && percent > 0 ? 1 : 0 visible: opacity > 0 tooltip: "Brightness: " + root.percent + "%" @@ -22,7 +22,8 @@ M.BarSection { } function adjust(delta) { - adjProc.cmd = delta > 0 ? "light -A 5" : "light -U 5"; + const step = M.Modules.backlight.step || 5; + adjProc.cmd = delta > 0 ? "light -A " + step : "light -U " + step; adjProc.running = true; } diff --git a/modules/Bar.qml b/modules/Bar.qml index f492ba5..e7e7f91 100644 --- a/modules/Bar.qml +++ b/modules/Bar.qml @@ -53,8 +53,8 @@ PanelWindow { M.BarGroup { borderColor: M.Theme.base0D - M.Clock { visible: M.Modules.clock } - M.Notifications { visible: M.Modules.notifications } + M.Clock { visible: M.Modules.clock.enable } + M.Notifications { visible: M.Modules.notifications.enable } } } @@ -67,17 +67,17 @@ PanelWindow { M.BarGroup { borderColor: M.Theme.base0D - M.Workspaces { bar: bar; visible: M.Modules.workspaces } + M.Workspaces { bar: bar; visible: M.Modules.workspaces.enable } } M.BarGroup { borderColor: M.Theme.base0D - M.Tray { bar: bar; visible: M.Modules.tray } + M.Tray { bar: bar; visible: M.Modules.tray.enable } } M.BarGroup { borderColor: M.Theme.base0D M.WindowTitle { Layout.maximumWidth: 400 - visible: M.Modules.windowTitle + visible: M.Modules.windowTitle.enable } } Item { Layout.fillWidth: true } @@ -96,13 +96,13 @@ PanelWindow { M.BarGroup { borderColor: M.Theme.base0E M.Mpris {} - M.Volume { visible: M.Modules.volume } + M.Volume { visible: M.Modules.volume.enable } } // Connectivity M.BarGroup { borderColor: M.Theme.base0D - M.Network { visible: M.Modules.network } + M.Network { visible: M.Modules.network.enable } M.Bluetooth {} } @@ -110,25 +110,25 @@ PanelWindow { M.BarGroup { borderColor: M.Theme.base0A M.Backlight {} - M.PowerProfile { visible: M.Modules.powerProfile } - M.IdleInhibitor { visible: M.Modules.idleInhibitor } + M.PowerProfile { visible: M.Modules.powerProfile.enable } + M.IdleInhibitor { visible: M.Modules.idleInhibitor.enable } } // Stats M.BarGroup { borderColor: M.Theme.base08 - M.Cpu { visible: M.Modules.cpu } - M.Memory { visible: M.Modules.memory } - M.Temperature { visible: M.Modules.temperature } - M.Weather { visible: M.Modules.weather } - M.Disk { visible: M.Modules.disk } + M.Cpu { visible: M.Modules.cpu.enable } + M.Memory { visible: M.Modules.memory.enable } + M.Temperature { visible: M.Modules.temperature.enable } + M.Weather { visible: M.Modules.weather.enable } + M.Disk { visible: M.Modules.disk.enable } } // Power M.BarGroup { borderColor: M.Theme.base08 M.Battery {} - M.Power { bar: bar; visible: M.Modules.power } + M.Power { bar: bar; visible: M.Modules.power.enable } } } } diff --git a/modules/Battery.qml b/modules/Battery.qml index 2b450b1..5bc6cfb 100644 --- a/modules/Battery.qml +++ b/modules/Battery.qml @@ -6,7 +6,7 @@ import "." as M M.BarSection { id: root spacing: M.Theme.moduleSpacing - opacity: M.Modules.battery && (UPower.displayDevice?.isLaptopBattery ?? false) ? 1 : 0 + opacity: M.Modules.battery.enable && (UPower.displayDevice?.isLaptopBattery ?? false) ? 1 : 0 visible: opacity > 0 tooltip: { const state = root.charging ? "Charging" : "Discharging"; diff --git a/modules/Bluetooth.qml b/modules/Bluetooth.qml index a90fc62..3a84414 100644 --- a/modules/Bluetooth.qml +++ b/modules/Bluetooth.qml @@ -5,7 +5,7 @@ import "." as M M.BarSection { id: root spacing: M.Theme.moduleSpacing - opacity: M.Modules.bluetooth && root.state !== "unavailable" ? 1 : 0 + opacity: M.Modules.bluetooth.enable && root.state !== "unavailable" ? 1 : 0 visible: opacity > 0 tooltip: { if (root.state === "off") diff --git a/modules/Modules.qml b/modules/Modules.qml index d8a5d04..e645ac0 100644 --- a/modules/Modules.qml +++ b/modules/Modules.qml @@ -7,27 +7,25 @@ import Quickshell.Io QtObject { id: root - property bool workspaces: true - 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 power: true - - property var weatherArgs: ["--nerd"] + property var workspaces: ({ enable: true }) + property var tray: ({ enable: true }) + property var windowTitle: ({ enable: true }) + property var clock: ({ enable: true }) + property var notifications: ({ enable: true }) + property var mpris: ({ enable: true }) + property var volume: ({ enable: true }) + property var bluetooth: ({ enable: true }) + property var backlight: ({ enable: true, step: 5 }) + property var network: ({ enable: true }) + property var powerProfile: ({ enable: true }) + property var idleInhibitor: ({ enable: true }) + property var weather: ({ enable: true, args: ["--nerd"] }) + property var temperature: ({ enable: true }) + property var cpu: ({ enable: true }) + property var memory: ({ enable: true }) + property var disk: ({ enable: true }) + property var battery: ({ enable: true }) + property var power: ({ enable: true }) property FileView _file: FileView { path: (Quickshell.env("XDG_CONFIG_HOME") || (Quickshell.env("HOME") + "/.config")) + "/nova-shell/modules.json" @@ -44,10 +42,12 @@ QtObject { return; } for (const k of Object.keys(data)) { - if (k in root && typeof root[k] === "boolean") - root[k] = data[k]; + if (!(k in root)) continue; + const v = data[k]; + if (typeof v === "object" && v !== null) + root[k] = Object.assign({}, root[k], v); + else if (typeof v === "boolean") + root[k] = Object.assign({}, root[k], { enable: v }); } - if (Array.isArray(data.weatherArgs)) - root.weatherArgs = data.weatherArgs; } } diff --git a/modules/Mpris.qml b/modules/Mpris.qml index 6f4628f..f4fbd2a 100644 --- a/modules/Mpris.qml +++ b/modules/Mpris.qml @@ -5,7 +5,7 @@ import "." as M M.BarSection { id: root spacing: M.Theme.moduleSpacing - opacity: M.Modules.mpris && player !== null ? 1 : 0 + opacity: M.Modules.mpris.enable && player !== null ? 1 : 0 visible: opacity > 0 tooltip: { const p = root.player; diff --git a/modules/Weather.qml b/modules/Weather.qml index a2bc162..dc56dd3 100644 --- a/modules/Weather.qml +++ b/modules/Weather.qml @@ -12,7 +12,7 @@ M.BarSection { Process { id: proc running: true - command: ["wttrbar"].concat(M.Modules.weatherArgs) + command: ["wttrbar"].concat(M.Modules.weather.args) stdout: StdioCollector { onStreamFinished: { try { diff --git a/nix/hm-module.nix b/nix/hm-module.nix index d2b37d2..e3fcbb8 100644 --- a/nix/hm-module.nix +++ b/nix/hm-module.nix @@ -52,54 +52,65 @@ in description = "nova-shell package to use."; }; - modules = lib.mkOption { - description = "Enable or disable individual bar modules."; - default = { }; - type = lib.types.submodule { - options = - lib.genAttrs - [ - "workspaces" - "tray" - "windowTitle" - "clock" - "notifications" - "mpris" - "volume" - "bluetooth" - "backlight" - "network" - "powerProfile" - "idleInhibitor" - "weather" - "temperature" - "cpu" - "memory" - "disk" - "battery" - "power" - ] - ( - name: - lib.mkOption { - type = lib.types.bool; - default = true; - description = "Enable the ${name} module."; - } - ); + modules = + let + moduleOpt = + name: extra: + lib.mkOption { + default = { }; + description = "Configuration for the ${name} module."; + type = lib.types.submodule { + options = { + enable = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Enable the ${name} module."; + }; + } // extra; + }; + }; + simpleModules = lib.genAttrs [ + "workspaces" + "tray" + "windowTitle" + "clock" + "notifications" + "mpris" + "volume" + "bluetooth" + "network" + "powerProfile" + "idleInhibitor" + "temperature" + "cpu" + "memory" + "disk" + "battery" + "power" + ] (name: moduleOpt name { }); + in + simpleModules + // { + backlight = moduleOpt "backlight" { + step = lib.mkOption { + type = lib.types.int; + default = 5; + description = "Brightness adjustment step (%)."; + }; + }; + weather = moduleOpt "weather" { + args = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ "--nerd" ]; + description = "Arguments passed to wttrbar."; + example = [ + "--nerd" + "--location" + "Berlin" + ]; + }; + }; }; - }; - - weatherArgs = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = [ "--nerd" ]; - description = "Arguments passed to wttrbar."; - example = [ - "--nerd" - "--location" - "Berlin" - ]; - }; theme = lib.mkOption { type = lib.types.attrsOf lib.types.anything; @@ -131,11 +142,10 @@ in self.packages.${pkgs.stdenv.hostPlatform.system}.nova-shell-cli pkgs.nerd-fonts.symbols-only ] - ++ lib.optional cfg.modules.weather pkgs.wttrbar; + ++ lib.optional cfg.modules.weather.enable pkgs.wttrbar; xdg.configFile."nova-shell/modules.json".source = - (pkgs.formats.json { }).generate "nova-shell-modules.json" - (cfg.modules // { weatherArgs = cfg.weatherArgs; }); + (pkgs.formats.json { }).generate "nova-shell-modules.json" cfg.modules; xdg.configFile."nova-shell/theme.json".source = let