Compare commits
29 changed files with 122 additions and 142 deletions
31
README.md
31
README.md
|
|
@ -43,18 +43,10 @@ inputs = {
|
||||||
```
|
```
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
# home.nix (standalone home-manager)
|
# home.nix
|
||||||
imports = [ inputs.nova-shell.homeModules.default ];
|
imports = [ inputs.nova-shell.homeModules.default ];
|
||||||
```
|
```
|
||||||
|
|
||||||
Or, if you use home-manager as a NixOS module, import the NixOS module instead -
|
|
||||||
it auto-injects the hm module (and the stylix module, if stylix is present):
|
|
||||||
|
|
||||||
```nix
|
|
||||||
# configuration.nix
|
|
||||||
imports = [ inputs.nova-shell.nixosModules.default ];
|
|
||||||
```
|
|
||||||
|
|
||||||
### Without Nix
|
### Without Nix
|
||||||
|
|
||||||
You poor thing. Here's what the Nix packaging does for you, manually:
|
You poor thing. Here's what the Nix packaging does for you, manually:
|
||||||
|
|
@ -83,17 +75,11 @@ programs.nova-shell.enable = true;
|
||||||
```
|
```
|
||||||
|
|
||||||
This installs the bar, the Symbols Nerd Font, and a systemd user service that
|
This installs the bar, the Symbols Nerd Font, and a systemd user service that
|
||||||
starts with `graphical-session.target`. If you do not configure a theme,
|
starts with `graphical-session.target`. If you use
|
||||||
you get Catppuccin Mocha, because my keeper has taste and it is purple.
|
[stylix](https://github.com/danth/stylix), colors and fonts are populated
|
||||||
|
automatically — one fewer thing for the AI to have gotten wrong. If you do not
|
||||||
If you use [stylix](https://github.com/danth/stylix), import the stylix module
|
use stylix, you get Catppuccin Mocha, because my keeper has
|
||||||
to have colors and fonts populated automatically:
|
taste and it is purple.
|
||||||
|
|
||||||
```nix
|
|
||||||
imports = [ nova-shell.homeModules.stylix ];
|
|
||||||
```
|
|
||||||
|
|
||||||
You can disable it with `stylix.targets.nova-shell.enable = false`.
|
|
||||||
|
|
||||||
### Disabling modules
|
### Disabling modules
|
||||||
|
|
||||||
|
|
@ -156,7 +142,8 @@ nix build .#docs
|
||||||
|
|
||||||
### Theme
|
### Theme
|
||||||
|
|
||||||
Theme keys are written to
|
Theme keys are merged on top of whatever stylix provides. You only need to
|
||||||
|
specify what you want to override. Values are written to
|
||||||
`~/.config/nova-shell/theme.json`. Changes take effect after
|
`~/.config/nova-shell/theme.json`. Changes take effect after
|
||||||
`systemctl --user restart nova-shell`, because hot-reloading a theme
|
`systemctl --user restart nova-shell`, because hot-reloading a theme
|
||||||
was deemed "unnecessary" by the primate in charge, who prefers to just restart the service like a cavewoman with a systemctl club.
|
was deemed "unnecessary" by the primate in charge, who prefers to just restart the service like a cavewoman with a systemctl club.
|
||||||
|
|
@ -171,7 +158,7 @@ programs.nova-shell.theme = {
|
||||||
fontSize = 13;
|
fontSize = 13;
|
||||||
fontFamily = "JetBrains Mono";
|
fontFamily = "JetBrains Mono";
|
||||||
|
|
||||||
# override individual palette entries (or stylix defaults, if you imported the stylix module)
|
# override individual palette entries if stylix's choices personally offend you
|
||||||
colors.base00 = "#1a1a2e";
|
colors.base00 = "#1a1a2e";
|
||||||
colors.base05 = "#e0e0f0";
|
colors.base05 = "#e0e0f0";
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -202,10 +202,7 @@
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
nixosModules.default = import ./nix/nixos-module.nix self;
|
|
||||||
|
|
||||||
homeModules.default = import ./nix/hm-module.nix self;
|
homeModules.default = import ./nix/hm-module.nix self;
|
||||||
homeModules.stylix = import ./nix/stylix.nix self;
|
|
||||||
homeManagerModules.default = self.homeModules.default;
|
homeManagerModules.default = self.homeModules.default;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,40 @@ self:
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
cfg = config.programs.nova-shell;
|
cfg = config.programs.nova-shell;
|
||||||
|
|
||||||
|
stylixAvailable = config ? lib && config.lib ? stylix;
|
||||||
|
|
||||||
|
stylixTheme =
|
||||||
|
let
|
||||||
|
c = config.lib.stylix.colors.withHashtag;
|
||||||
|
f = config.stylix.fonts;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
colors = {
|
||||||
|
inherit (c)
|
||||||
|
base00
|
||||||
|
base01
|
||||||
|
base02
|
||||||
|
base03
|
||||||
|
base04
|
||||||
|
base05
|
||||||
|
base06
|
||||||
|
base07
|
||||||
|
base08
|
||||||
|
base09
|
||||||
|
base0A
|
||||||
|
base0B
|
||||||
|
base0C
|
||||||
|
base0D
|
||||||
|
base0E
|
||||||
|
base0F
|
||||||
|
;
|
||||||
|
};
|
||||||
|
fontFamily = f.sansSerif.name;
|
||||||
|
fontSize = f.sizes.desktop;
|
||||||
|
barOpacity = 1.0 - config.stylix.opacity.desktop;
|
||||||
|
iconFontFamily = "Symbols Nerd Font";
|
||||||
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.programs.nova-shell = {
|
options.programs.nova-shell = {
|
||||||
|
|
@ -261,7 +295,7 @@ in
|
||||||
Keys: colors (base00-base0F), fontFamily, iconFontFamily, fontSize,
|
Keys: colors (base00-base0F), fontFamily, iconFontFamily, fontSize,
|
||||||
barOpacity, barHeight, barPadding, groupSpacing, groupPadding, moduleSpacing,
|
barOpacity, barHeight, barPadding, groupSpacing, groupPadding, moduleSpacing,
|
||||||
radius, screenRadius, reducedMotion.
|
radius, screenRadius, reducedMotion.
|
||||||
Populated from stylix when homeModules.stylix is imported.
|
Automatically populated from stylix when it is available.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -293,8 +327,11 @@ in
|
||||||
cfg.modules;
|
cfg.modules;
|
||||||
|
|
||||||
xdg.configFile."nova-shell/theme.json".source =
|
xdg.configFile."nova-shell/theme.json".source =
|
||||||
(pkgs.formats.json { }).generate "nova-shell-theme.json"
|
let
|
||||||
cfg.theme;
|
stylixDefaults = if stylixAvailable then stylixTheme else { };
|
||||||
|
finalTheme = lib.recursiveUpdate stylixDefaults cfg.theme;
|
||||||
|
in
|
||||||
|
(pkgs.formats.json { }).generate "nova-shell-theme.json" finalTheme;
|
||||||
|
|
||||||
# Niri layer rules for backdrop placement (requires niri-flake hm module)
|
# Niri layer rules for backdrop placement (requires niri-flake hm module)
|
||||||
programs.niri.settings.layer-rules = lib.mkIf (config ? programs && config.programs ? niri) [
|
programs.niri.settings.layer-rules = lib.mkIf (config ? programs && config.programs ? niri) [
|
||||||
|
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
self:
|
|
||||||
{
|
|
||||||
config,
|
|
||||||
options,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = config.programs.nova-shell;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.programs.nova-shell.enable = lib.mkEnableOption "nova-shell Quickshell bar";
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable (
|
|
||||||
lib.optionalAttrs (options ? home-manager) {
|
|
||||||
home-manager.sharedModules = [
|
|
||||||
self.homeModules.default
|
|
||||||
]
|
|
||||||
++ lib.optionals (options ? stylix) [ self.homeModules.stylix ];
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
_:
|
|
||||||
{
|
|
||||||
lib,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
inherit (lib) mkDefault mkIf;
|
|
||||||
c = config.lib.stylix.colors.withHashtag;
|
|
||||||
f = config.stylix.fonts;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.stylix.targets.nova-shell.enable = config.lib.stylix.mkEnableTarget "nova-shell" true;
|
|
||||||
|
|
||||||
config = mkIf (config.stylix.enable && config.stylix.targets.nova-shell.enable) {
|
|
||||||
programs.nova-shell.theme = {
|
|
||||||
colors = {
|
|
||||||
base00 = mkDefault c.base00;
|
|
||||||
base01 = mkDefault c.base01;
|
|
||||||
base02 = mkDefault c.base02;
|
|
||||||
base03 = mkDefault c.base03;
|
|
||||||
base04 = mkDefault c.base04;
|
|
||||||
base05 = mkDefault c.base05;
|
|
||||||
base06 = mkDefault c.base06;
|
|
||||||
base07 = mkDefault c.base07;
|
|
||||||
base08 = mkDefault c.base08;
|
|
||||||
base09 = mkDefault c.base09;
|
|
||||||
base0A = mkDefault c.base0A;
|
|
||||||
base0B = mkDefault c.base0B;
|
|
||||||
base0C = mkDefault c.base0C;
|
|
||||||
base0D = mkDefault c.base0D;
|
|
||||||
base0E = mkDefault c.base0E;
|
|
||||||
base0F = mkDefault c.base0F;
|
|
||||||
};
|
|
||||||
fontFamily = mkDefault f.sansSerif.name;
|
|
||||||
fontSize = mkDefault f.sizes.desktop;
|
|
||||||
barOpacity = mkDefault (1.0 - config.stylix.opacity.desktop);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -7,7 +7,8 @@ import "../applets" as C
|
||||||
M.BarModule {
|
M.BarModule {
|
||||||
id: root
|
id: root
|
||||||
spacing: S.Theme.moduleSpacing
|
spacing: S.Theme.moduleSpacing
|
||||||
active: S.Modules.backlight.enable && S.BacklightService.available
|
opacity: S.Modules.backlight.enable && S.BacklightService.available ? 1 : 0
|
||||||
|
visible: opacity > 0
|
||||||
tooltip: "Brightness: " + percent + "%"
|
tooltip: "Brightness: " + percent + "%"
|
||||||
panelNamespace: "nova-backlight"
|
panelNamespace: "nova-backlight"
|
||||||
panelTitle: "Brightness"
|
panelTitle: "Brightness"
|
||||||
|
|
|
||||||
|
|
@ -120,8 +120,12 @@ PanelWindow {
|
||||||
|
|
||||||
M.BarGroup {
|
M.BarGroup {
|
||||||
M.PrivacyModule {}
|
M.PrivacyModule {}
|
||||||
M.ClockModule {}
|
M.ClockModule {
|
||||||
M.NotificationsModule {}
|
visible: S.Modules.clock.enable
|
||||||
|
}
|
||||||
|
M.NotificationsModule {
|
||||||
|
visible: S.Modules.notifications.enable
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -137,6 +141,7 @@ PanelWindow {
|
||||||
leftEdge: true
|
leftEdge: true
|
||||||
M.WorkspacesModule {
|
M.WorkspacesModule {
|
||||||
bar: bar
|
bar: bar
|
||||||
|
visible: S.Modules.workspaces.enable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
M.BarGroup {
|
M.BarGroup {
|
||||||
|
|
@ -177,38 +182,60 @@ PanelWindow {
|
||||||
M.MprisModule {
|
M.MprisModule {
|
||||||
bar: bar
|
bar: bar
|
||||||
}
|
}
|
||||||
M.VolumeModule {}
|
M.VolumeModule {
|
||||||
|
visible: S.Modules.volume.enable
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connectivity
|
// Connectivity
|
||||||
M.BarGroup {
|
M.BarGroup {
|
||||||
M.NetworkModule {}
|
M.NetworkModule {
|
||||||
|
visible: S.Modules.network.enable
|
||||||
|
}
|
||||||
M.BluetoothModule {}
|
M.BluetoothModule {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Controls
|
// Controls
|
||||||
M.BarGroup {
|
M.BarGroup {
|
||||||
M.BacklightModule {}
|
M.BacklightModule {}
|
||||||
M.PowerProfileModule {}
|
M.PowerProfileModule {
|
||||||
M.IdleInhibitorModule {}
|
visible: S.Modules.powerProfile.enable
|
||||||
|
}
|
||||||
|
M.IdleInhibitorModule {
|
||||||
|
visible: S.Modules.idleInhibitor.enable
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stats
|
// Stats
|
||||||
M.BarGroup {
|
M.BarGroup {
|
||||||
M.CpuModule {}
|
M.CpuModule {
|
||||||
M.MemoryModule {}
|
visible: S.Modules.cpu.enable
|
||||||
|
}
|
||||||
|
M.MemoryModule {
|
||||||
|
visible: S.Modules.memory.enable
|
||||||
|
}
|
||||||
M.GpuModule {}
|
M.GpuModule {}
|
||||||
M.TemperatureModule {}
|
M.TemperatureModule {
|
||||||
M.WeatherModule {}
|
visible: S.Modules.temperature.enable
|
||||||
M.DiskModule {}
|
}
|
||||||
|
M.WeatherModule {
|
||||||
|
visible: S.Modules.weather.enable
|
||||||
|
}
|
||||||
|
M.DiskModule {
|
||||||
|
visible: S.Modules.disk.enable
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Power + Dock
|
// Power + Dock
|
||||||
M.BarGroup {
|
M.BarGroup {
|
||||||
rightEdge: true
|
rightEdge: true
|
||||||
M.BatteryModule {}
|
M.BatteryModule {}
|
||||||
M.DockModule {}
|
M.DockModule {
|
||||||
M.PowerModule {}
|
visible: S.Modules.dock.enable
|
||||||
|
}
|
||||||
|
M.PowerModule {
|
||||||
|
visible: S.Modules.power.enable
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,18 +27,7 @@ Item {
|
||||||
readonly property real _blr: S.Theme.radius
|
readonly property real _blr: S.Theme.radius
|
||||||
readonly property real _brr: S.Theme.radius
|
readonly property real _brr: S.Theme.radius
|
||||||
|
|
||||||
// Check children's `active` instead of visibleChildren to avoid circular
|
visible: row.visibleChildren.length > 0
|
||||||
// effectiveVisible dependency: if the BarGroup is invisible, children's
|
|
||||||
// effectiveVisible is always false, so visibleChildren stays empty and
|
|
||||||
// the group can never become visible again. `active` is a plain property
|
|
||||||
// on BarModule that is not affected by the parent visibility chain.
|
|
||||||
visible: {
|
|
||||||
for (let i = 0; i < row.children.length; i++) {
|
|
||||||
if (row.children[i].active)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
implicitWidth: row.implicitWidth + _pad * 2
|
implicitWidth: row.implicitWidth + _pad * 2
|
||||||
implicitHeight: S.Theme.barHeight - 3 - _pad
|
implicitHeight: S.Theme.barHeight - 3 - _pad
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,6 @@ import "../services" as S
|
||||||
// For content resize grace, call keepPanelOpen(ms).
|
// For content resize grace, call keepPanelOpen(ms).
|
||||||
Row {
|
Row {
|
||||||
id: root
|
id: root
|
||||||
property bool active: true
|
|
||||||
opacity: active ? 1 : 0
|
|
||||||
visible: opacity > 0
|
|
||||||
|
|
||||||
property string tooltip: ""
|
property string tooltip: ""
|
||||||
property bool _hovered: false
|
property bool _hovered: false
|
||||||
property color accentColor: parent?.accentColor ?? S.Theme.base05
|
property color accentColor: parent?.accentColor ?? S.Theme.base05
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@ import "../applets" as C
|
||||||
M.BarModule {
|
M.BarModule {
|
||||||
id: root
|
id: root
|
||||||
spacing: S.Theme.moduleSpacing
|
spacing: S.Theme.moduleSpacing
|
||||||
active: S.Modules.battery.enable && S.BatteryService.available
|
opacity: S.Modules.battery.enable && S.BatteryService.available ? 1 : 0
|
||||||
|
visible: opacity > 0
|
||||||
tooltip: "Battery: " + Math.round(S.BatteryService.percent) + "%" + (S.BatteryService.charging ? " (charging)" : "")
|
tooltip: "Battery: " + Math.round(S.BatteryService.percent) + "%" + (S.BatteryService.charging ? " (charging)" : "")
|
||||||
panelNamespace: "nova-battery"
|
panelNamespace: "nova-battery"
|
||||||
panelTitle: "Battery"
|
panelTitle: "Battery"
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@ import "../applets" as C
|
||||||
M.BarModule {
|
M.BarModule {
|
||||||
id: root
|
id: root
|
||||||
spacing: S.Theme.moduleSpacing
|
spacing: S.Theme.moduleSpacing
|
||||||
active: S.Modules.bluetooth.enable && S.BluetoothService.state !== "unavailable"
|
opacity: S.Modules.bluetooth.enable && S.BluetoothService.state !== "unavailable" ? 1 : 0
|
||||||
|
visible: opacity > 0
|
||||||
tooltip: {
|
tooltip: {
|
||||||
if (S.BluetoothService.state === "connected")
|
if (S.BluetoothService.state === "connected")
|
||||||
return "Bluetooth: " + S.BluetoothService.device;
|
return "Bluetooth: " + S.BluetoothService.device;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import "../applets" as C
|
||||||
|
|
||||||
M.BarModule {
|
M.BarModule {
|
||||||
id: root
|
id: root
|
||||||
active: S.Modules.clock.enable
|
|
||||||
spacing: S.Theme.moduleSpacing
|
spacing: S.Theme.moduleSpacing
|
||||||
tooltip: Qt.formatDateTime(clock.date, "dddd, dd. MMMM yyyy")
|
tooltip: Qt.formatDateTime(clock.date, "dddd, dd. MMMM yyyy")
|
||||||
panelNamespace: "nova-clock"
|
panelNamespace: "nova-clock"
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import "../applets" as C
|
||||||
|
|
||||||
M.BarModule {
|
M.BarModule {
|
||||||
id: root
|
id: root
|
||||||
active: S.Modules.cpu.enable
|
|
||||||
spacing: Math.max(1, S.Theme.moduleSpacing - 2)
|
spacing: Math.max(1, S.Theme.moduleSpacing - 2)
|
||||||
tooltip: "CPU: " + S.SystemStats.cpuUsage + "% @ " + S.SystemStats.cpuFreqGhz.toFixed(2) + " GHz"
|
tooltip: "CPU: " + S.SystemStats.cpuUsage + "% @ " + S.SystemStats.cpuFreqGhz.toFixed(2) + " GHz"
|
||||||
panelNamespace: "nova-cpu"
|
panelNamespace: "nova-cpu"
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import "../applets" as C
|
||||||
|
|
||||||
M.BarModule {
|
M.BarModule {
|
||||||
id: root
|
id: root
|
||||||
active: S.Modules.disk.enable
|
|
||||||
spacing: Math.max(1, S.Theme.moduleSpacing - 2)
|
spacing: Math.max(1, S.Theme.moduleSpacing - 2)
|
||||||
tooltip: "Disk: " + _rootPct + "% used"
|
tooltip: "Disk: " + _rootPct + "% used"
|
||||||
panelNamespace: "nova-disk"
|
panelNamespace: "nova-disk"
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import "../services" as S
|
||||||
|
|
||||||
M.BarModule {
|
M.BarModule {
|
||||||
id: root
|
id: root
|
||||||
active: S.Modules.dock.enable
|
|
||||||
tooltip: S.DockState.open ? "Close dock" : "Open dock"
|
tooltip: S.DockState.open ? "Close dock" : "Open dock"
|
||||||
onTapped: S.DockState.toggle()
|
onTapped: S.DockState.toggle()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import "../applets" as C
|
||||||
M.BarModule {
|
M.BarModule {
|
||||||
id: root
|
id: root
|
||||||
spacing: Math.max(1, S.Theme.moduleSpacing - 2)
|
spacing: Math.max(1, S.Theme.moduleSpacing - 2)
|
||||||
active: S.Modules.gpu.enable && S.SystemStats.gpuAvailable
|
visible: S.Modules.gpu.enable && S.SystemStats.gpuAvailable
|
||||||
tooltip: "GPU: " + S.SystemStats.gpuUsage + "%"
|
tooltip: "GPU: " + S.SystemStats.gpuUsage + "%"
|
||||||
panelNamespace: "nova-gpu"
|
panelNamespace: "nova-gpu"
|
||||||
panelTitle: "GPU"
|
panelTitle: "GPU"
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import "../services" as S
|
||||||
|
|
||||||
M.BarModule {
|
M.BarModule {
|
||||||
id: root
|
id: root
|
||||||
active: S.Modules.idleInhibitor.enable
|
|
||||||
tooltip: {
|
tooltip: {
|
||||||
const parts = ["Idle inhibition: " + (S.IdleInhibitService.active ? "active" : "inactive")];
|
const parts = ["Idle inhibition: " + (S.IdleInhibitService.active ? "active" : "inactive")];
|
||||||
if (S.IdleInhibitService.inhibitors)
|
if (S.IdleInhibitService.inhibitors)
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import "../applets" as C
|
||||||
|
|
||||||
M.BarModule {
|
M.BarModule {
|
||||||
id: root
|
id: root
|
||||||
active: S.Modules.memory.enable
|
|
||||||
spacing: Math.max(1, S.Theme.moduleSpacing - 2)
|
spacing: Math.max(1, S.Theme.moduleSpacing - 2)
|
||||||
tooltip: "Memory: " + usedGb.toFixed(1) + " / " + totalGb.toFixed(1) + " GB"
|
tooltip: "Memory: " + usedGb.toFixed(1) + " / " + totalGb.toFixed(1) + " GB"
|
||||||
panelNamespace: "nova-memory"
|
panelNamespace: "nova-memory"
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@ import "../applets" as C
|
||||||
M.BarModule {
|
M.BarModule {
|
||||||
id: root
|
id: root
|
||||||
spacing: S.Theme.moduleSpacing
|
spacing: S.Theme.moduleSpacing
|
||||||
active: S.Modules.mpris.enable && S.MprisService.player !== null
|
opacity: S.Modules.mpris.enable && S.MprisService.player !== null ? 1 : 0
|
||||||
|
visible: opacity > 0
|
||||||
tooltip: S.MprisService.player ? (S.MprisService.player.trackTitle || S.MprisService.player.identity || "Media") + (S.MprisService.playing ? " (playing)" : " (paused)") : "Media"
|
tooltip: S.MprisService.player ? (S.MprisService.player.trackTitle || S.MprisService.player.identity || "Media") + (S.MprisService.playing ? " (playing)" : " (paused)") : "Media"
|
||||||
panelNamespace: "nova-mpris"
|
panelNamespace: "nova-mpris"
|
||||||
panelTitle: "Now Playing"
|
panelTitle: "Now Playing"
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import "../applets" as C
|
||||||
|
|
||||||
M.BarModule {
|
M.BarModule {
|
||||||
id: root
|
id: root
|
||||||
active: S.Modules.network.enable
|
|
||||||
spacing: S.Theme.moduleSpacing
|
spacing: S.Theme.moduleSpacing
|
||||||
tooltip: {
|
tooltip: {
|
||||||
if (state === "wifi")
|
if (state === "wifi")
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import "../applets" as C
|
||||||
|
|
||||||
M.BarModule {
|
M.BarModule {
|
||||||
id: root
|
id: root
|
||||||
active: S.Modules.notifications.enable
|
|
||||||
spacing: S.Theme.moduleSpacing
|
spacing: S.Theme.moduleSpacing
|
||||||
tooltip: S.NotifService.count > 0 ? "Notifications: " + S.NotifService.count + (S.NotifService.dnd ? " (DND)" : "") : (S.NotifService.dnd ? "Do not disturb" : "No notifications")
|
tooltip: S.NotifService.count > 0 ? "Notifications: " + S.NotifService.count + (S.NotifService.dnd ? " (DND)" : "") : (S.NotifService.dnd ? "Do not disturb" : "No notifications")
|
||||||
panelNamespace: "nova-notifications"
|
panelNamespace: "nova-notifications"
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import "../applets" as C
|
||||||
|
|
||||||
M.BarModule {
|
M.BarModule {
|
||||||
id: root
|
id: root
|
||||||
active: S.Modules.power.enable
|
|
||||||
tooltip: "Power menu"
|
tooltip: "Power menu"
|
||||||
panelNamespace: "nova-power"
|
panelNamespace: "nova-power"
|
||||||
panelTitle: "Power"
|
panelTitle: "Power"
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import "../services" as S
|
||||||
|
|
||||||
M.BarModule {
|
M.BarModule {
|
||||||
id: root
|
id: root
|
||||||
active: S.Modules.powerProfile.enable
|
|
||||||
tooltip: "Power profile: " + (S.PowerProfileService.profile || "unknown")
|
tooltip: "Power profile: " + (S.PowerProfileService.profile || "unknown")
|
||||||
onTapped: {
|
onTapped: {
|
||||||
const cycle = ["performance", "balanced", "power-saver"];
|
const cycle = ["performance", "balanced", "power-saver"];
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ M.BarModule {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
active: S.Modules.privacy.enable && (root._videoCapture || root._audioIn)
|
visible: S.Modules.privacy.enable && (root._videoCapture || root._audioIn)
|
||||||
|
|
||||||
// Screenshare indicator
|
// Screenshare indicator
|
||||||
Text {
|
Text {
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import "../applets" as C
|
||||||
|
|
||||||
M.BarModule {
|
M.BarModule {
|
||||||
id: root
|
id: root
|
||||||
active: S.Modules.temperature.enable
|
|
||||||
spacing: Math.max(1, S.Theme.moduleSpacing - 2)
|
spacing: Math.max(1, S.Theme.moduleSpacing - 2)
|
||||||
tooltip: "Temperature: " + _temp + "\u00B0C"
|
tooltip: "Temperature: " + _temp + "\u00B0C"
|
||||||
panelNamespace: "nova-temperature"
|
panelNamespace: "nova-temperature"
|
||||||
|
|
|
||||||
|
|
@ -12,14 +12,32 @@ M.BarModule {
|
||||||
spacing: S.Theme.moduleSpacing + 2
|
spacing: S.Theme.moduleSpacing + 2
|
||||||
cursorShape: Qt.ArrowCursor
|
cursorShape: Qt.ArrowCursor
|
||||||
|
|
||||||
active: S.Modules.tray.enable && _trayRepeater.count > 0
|
// Workaround: Qt 6 compiled bindings break on `visible` when the expression
|
||||||
|
// references Repeater.count on a Row-derived component. The binding silently
|
||||||
|
// dies (imperative overwrite by the engine) and never re-evaluates. Routing
|
||||||
|
// through a custom property forces the interpreted binding path, which works.
|
||||||
|
property bool _shouldBeVisible: S.Modules.tray.enable && _trayRepeater.count > 0
|
||||||
|
visible: _shouldBeVisible
|
||||||
|
|
||||||
required property var bar
|
required property var bar
|
||||||
property var _activeMenu: null
|
property var _activeMenu: null
|
||||||
|
|
||||||
// --- debug logging (remove once tray is confirmed working) ---
|
// --- debug logging (remove once tray is confirmed working) ---
|
||||||
onActiveChanged: console.log("[TrayModule] active:", active, "count:", _trayRepeater.count)
|
on_ShouldBeVisibleChanged: console.log("[TrayModule] _shouldBeVisible:", _shouldBeVisible, "actual visible:", visible)
|
||||||
onVisibleChanged: console.log("[TrayModule] visible:", visible)
|
Component.onCompleted: console.log("[TrayModule] created, enable:", S.Modules.tray.enable, "repeater count:", _trayRepeater.count)
|
||||||
|
onVisibleChanged: console.log("[TrayModule] visible:", visible, "enable:", S.Modules.tray.enable, "count:", _trayRepeater.count)
|
||||||
|
Connections {
|
||||||
|
target: _trayRepeater
|
||||||
|
function onCountChanged() {
|
||||||
|
console.log("[TrayModule] repeater count:", _trayRepeater.count, "visible:", root.visible, "shouldBe:", S.Modules.tray.enable && _trayRepeater.count > 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Connections {
|
||||||
|
target: SystemTray.items
|
||||||
|
function onValuesChanged() {
|
||||||
|
console.log("[TrayModule] model valuesChanged, values.length:", SystemTray.items.values.length, "repeater count:", _trayRepeater.count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
id: _trayRepeater
|
id: _trayRepeater
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import "../applets" as C
|
||||||
|
|
||||||
M.BarModule {
|
M.BarModule {
|
||||||
id: root
|
id: root
|
||||||
active: S.Modules.volume.enable
|
|
||||||
spacing: S.Theme.moduleSpacing
|
spacing: S.Theme.moduleSpacing
|
||||||
tooltip: "Volume: " + Math.round(volume * 100) + "%" + (muted ? " (muted)" : "")
|
tooltip: "Volume: " + Math.round(volume * 100) + "%" + (muted ? " (muted)" : "")
|
||||||
panelNamespace: "nova-volume"
|
panelNamespace: "nova-volume"
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import "../applets" as C
|
||||||
M.BarModule {
|
M.BarModule {
|
||||||
id: root
|
id: root
|
||||||
spacing: S.Theme.moduleSpacing
|
spacing: S.Theme.moduleSpacing
|
||||||
active: S.Modules.weather.enable && S.WeatherService.available
|
visible: S.Modules.weather.enable && S.WeatherService.available
|
||||||
tooltip: "Weather"
|
tooltip: "Weather"
|
||||||
panelNamespace: "nova-weather"
|
panelNamespace: "nova-weather"
|
||||||
panelTitle: "Weather"
|
panelTitle: "Weather"
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import "../services" as S
|
||||||
|
|
||||||
M.BarModule {
|
M.BarModule {
|
||||||
id: root
|
id: root
|
||||||
active: S.Modules.workspaces.enable
|
|
||||||
spacing: 4
|
spacing: 4
|
||||||
cursorShape: Qt.ArrowCursor
|
cursorShape: Qt.ArrowCursor
|
||||||
|
|
||||||
|
|
|
||||||
Reference in a new issue