From 84c8dc09209632f41a3dce97112613dfbc165f8a Mon Sep 17 00:00:00 2001 From: Anthony Rodriguez Date: Tue, 26 Nov 2024 15:47:10 +0100 Subject: [PATCH] treewide: implement notifications with swaync Implemented notifications with SwayNotificationCenter, as well as theming using the custom theme module. Some Waybar code had to be updated too, and was also simplified in order to be more consistent with the new SwayNotificationCenter implementation. --- home/programs/waybar/default.nix | 273 ++++++++++--------- home/programs/waybar/style.css | 91 +++++++ home/programs/waybar/style.nix | 106 -------- home/services/swaync/default.nix | 37 +++ home/services/swaync/style.css | 450 +++++++++++++++++++++++++++++++ hosts/vamos/default.nix | 1 + lib/default.nix | 7 +- 7 files changed, 735 insertions(+), 230 deletions(-) create mode 100644 home/programs/waybar/style.css delete mode 100644 home/programs/waybar/style.nix create mode 100644 home/services/swaync/default.nix create mode 100644 home/services/swaync/style.css diff --git a/home/programs/waybar/default.nix b/home/programs/waybar/default.nix index c3fe3f0..4d446f2 100644 --- a/home/programs/waybar/default.nix +++ b/home/programs/waybar/default.nix @@ -1,152 +1,179 @@ { - osConfig, pkgs, lib, + lib', + osConfig, + config, ... }: let - inherit (lib) getExe; + inherit (lib) getExe mkMerge mkIf optionalString; + inherit (lib') generateGtkColors; + inherit (osConfig.theme.scheme) palette; + inherit (builtins) readFile; in { - imports = [./style.nix]; programs.waybar = { enable = true; systemd.enable = true; + style = + optionalString osConfig.theme.enable generateGtkColors lib palette + + readFile ./style.css; settings = { - mainBar = { - layer = "top"; - position = "top"; - height = 30; + mainBar = mkMerge [ + { + layer = "top"; + position = "top"; + height = 30; - margin-top = 6; - margin-left = 6; - margin-right = 6; - margin-bottom = 0; + margin-top = 6; + margin-left = 6; + margin-right = 6; + margin-bottom = 0; - modules-left = ["niri/workspaces" "niri/window"]; - modules-center = ["group/clock"]; - modules-right = ["tray" "group/status" "group/power"]; + modules-left = ["niri/workspaces" "niri/window"]; + modules-center = ["group/clock"]; + modules-right = + ["tray" "group/status" "group/power"] + ++ lib.optional config.services.swaync.enable "custom/notification"; - battery = { - interval = 10; - states = { - warning = 30; - critical = 15; + battery = { + interval = 10; + states = { + warning = 30; + critical = 15; + }; + format = "{icon} {capacity}%"; + format-charging = " {capacity}% - {time}"; + format-full = " {capacity}% - Full"; + format-icons = [ + "" + "" + "" + "" + "" + ]; + max-length = 25; }; - format = "{icon} {capacity}%"; - format-charging = " {capacity}% - {time}"; - format-full = " {capacity}% - Full"; - format-icons = [ - "" - "" - "" - "" - "" - ]; - max-length = 25; - }; - "niri/window" = { - icon = true; - }; - - "pulseaudio" = { - format = "{icon} {volume}%"; - format-bluetooth = "{icon} {volume}%"; - format-muted = " "; - format-icons = { - "alsa_output.pci-0000_00_1f.3.analog-stereo" = ""; - "alsa_output.pci-0000_00_1f.3.analog-stereo-muted" = ""; - headphone = ""; - hands-free = ""; - headset = ""; - phone = ""; - phone-muted = ""; - portable = ""; - car = ""; - default = [ - "" - "" + "pulseaudio" = { + format = "{icon} {volume}%"; + format-bluetooth = "{icon} {volume}%"; + format-muted = " "; + format-icons = { + "alsa_output.pci-0000_00_1f.3.analog-stereo" = ""; + "alsa_output.pci-0000_00_1f.3.analog-stereo-muted" = ""; + headphone = ""; + hands-free = ""; + headset = ""; + phone = ""; + phone-muted = ""; + portable = ""; + car = ""; + default = [ + "" + "" + ]; + }; + scroll-step = 1; + on-click = "pavucontrol"; + ignored-sinks = [ + "Easy Effects Sink" ]; }; - scroll-step = 1; - on-click = "pavucontrol"; - ignored-sinks = [ - "Easy Effects Sink" - ]; - }; - "power-profiles-daemon" = { - format-icons = { - default = ""; - performance = ""; - balanced = ""; - power-saver = ""; + "power-profiles-daemon" = { + format-icons = { + default = ""; + performance = ""; + balanced = ""; + power-saver = ""; + }; }; - }; - "group/status" = { - orientation = "inherit"; - modules = [ - "pulseaudio" - "power-profiles-daemon" - "network" - "battery" - ]; - }; + "group/status" = { + orientation = "inherit"; + modules = [ + "pulseaudio" + "power-profiles-daemon" + "network" + "battery" + ]; + }; - "group/power" = { - orientation = "inherit"; - modules = [ - "custom/power" - ]; - }; + "group/power" = { + orientation = "inherit"; + modules = [ + "custom/power" + ]; + }; - "group/clock" = { - orientation = "inherit"; - modules = [ - "clock#time" - "clock#date" - ]; - }; + "group/clock" = { + orientation = "inherit"; + modules = [ + "clock#time" + "clock#date" + ]; + }; - "custom/power" = { - format = ""; - tooltip = false; - on-click = getExe pkgs.wlogout; - }; + "custom/power" = { + format = ""; + tooltip = false; + on-click = getExe pkgs.wlogout; + }; - "clock#date" = { - format = "{:%D}"; - tooltip-format = "{calendar}"; - }; + "clock#date" = { + format = "{:%D}"; + tooltip-format = "{calendar}"; + }; - "clock#time" = { - format = "{:%H:%M}"; - tooltip-format = "{tz_list}"; - timezones = [ - osConfig.time.timeZone - "US/Eastern" - ]; - }; + "clock#time" = { + format = "{:%H:%M}"; + tooltip-format = "{tz_list}"; + timezones = [ + osConfig.time.timeZone + "US/Eastern" + ]; + }; - network = { - interface = "wlp1s0"; - format = "{ifname}"; - format-wifi = "{icon}"; - format-ethernet = "{ipaddr}/{cidr} 󰊗"; - format-disconnected = ""; - tooltip-format = "{ifname} via {gwaddr} 󰊗"; - tooltip-format-wifi = "{essid} ({signalStrength}%)"; - tooltip-format-ethernet = "{ifname} "; - tooltip-format-disconnected = "Disconnected"; - max-length = 50; - format-icons = [ - "󰤟" - "󰤢" - "󰤥" - "󰤨" - ]; - }; - }; + network = { + interface = "wlp1s0"; + format = "{ifname}"; + format-wifi = "{icon}"; + format-ethernet = "{ipaddr}/{cidr} 󰊗"; + format-disconnected = ""; + tooltip-format = "{ifname} via {gwaddr} 󰊗"; + tooltip-format-wifi = "{essid} ({signalStrength}%)"; + tooltip-format-ethernet = "{ifname} "; + tooltip-format-disconnected = "Disconnected"; + max-length = 50; + format-icons = [ + "󰤟" + "󰤢" + "󰤥" + "󰤨" + ]; + }; + } + (mkIf osConfig.programs.niri.enable { + "niri/window" = { + icon = true; + }; + }) + (mkIf config.services.swaync.enable { + "custom/notification" = { + tooltip = false; + format = "{icon}"; + format-icons = { + notification = "󱅫"; + none = "󰂚"; + dnd-notification = "󱏧"; + dnd-none = "󱏧"; + }; + return-type = "json"; + exec = "swaync-client -swb"; + on-click = "swaync-client -t -sw"; + }; + }) + ]; }; }; diff --git a/home/programs/waybar/style.css b/home/programs/waybar/style.css new file mode 100644 index 0000000..52150ec --- /dev/null +++ b/home/programs/waybar/style.css @@ -0,0 +1,91 @@ +* { + /* `otf-font-awesome` is required to be installed for icons */ + border: none; + border-radius: 0px; + min-height: 0; +} + +window#waybar { + border-radius: 2em; + font-family: "Symbols Nerd Font", Inter, sans-serif; + font-size: 16px; + font-style: normal; + background: alpha( + @base00, + 0.9999999 + ); /* niri issue workaround, thanks https://github.com/oatmealine/nix-config/blob/bfdddd2cb36ef659bcddc28e0dbb542b6db8b3bc/modules/desktop/themes/catppuccin/waybar.css#L14 */ + color: @base05; +} + +#workspaces, +.modules-right box { + background: @base02; + padding: 0.15em 0.25em; + border-radius: 1em; + margin: 0 0.25em; +} + +#workspaces { + padding: 0; + background: @base02; +} + +#workspaces button:nth-child(1) { + border-top-left-radius: 1em; + border-bottom-left-radius: 1em; +} +#workspaces button:nth-last-child(1) { + border-top-right-radius: 1em; + border-bottom-right-radius: 1em; +} + +#workspaces button { + padding: 0 0.5em; + background-color: transparent; +} + +#workspaces button:hover { + background: rgba(255, 255, 255, 0.1); + box-shadow: none; +} + +#workspaces button.active { + background: @base0E; + color: @base02; +} + +#workspaces button.urgent { + background: @base08; +} + +#window { + margin-left: 1em; +} + +.modules-left, +.modules-right { + margin: 0.4em 0.5em; +} + +#battery, +#clock, +#network, +#pulseaudio, +#tray, +#power-profiles-daemon { + padding: 0 0.5em; +} + +.modules-left, +.modules-right { + margin: 0.4em 0.5em; +} + +#custom-power { + padding: 0 1.2em; + color: @base08; +} + +#custom-notification { + padding: 0 1.2em; +} diff --git a/home/programs/waybar/style.nix b/home/programs/waybar/style.nix deleted file mode 100644 index 53c5fb7..0000000 --- a/home/programs/waybar/style.nix +++ /dev/null @@ -1,106 +0,0 @@ -{ - lib, - osConfig, - ... -}: let - inherit (osConfig.theme.scheme) palette; - inherit (lib) mapAttrsToList concatLines optionalString; - - generateGtkColors = palette: (concatLines - (mapAttrsToList - (name: color: "@define-color ${name} ${color};") - palette)); -in { - programs.waybar.style = - optionalString osConfig.theme.enable generateGtkColors palette - + '' - * { - /* `otf-font-awesome` is required to be installed for icons */ - border: none; - border-radius: 0px; - min-height: 0; - } - - window#waybar { - border-radius: 2em; - font-family: "Symbols Nerd Font", Inter, sans-serif; - font-size: 16px; - font-style: normal; - background: alpha( - @base00, - 0.9999999 - ); /* niri issue workaround, thanks https://github.com/oatmealine/nix-config/blob/bfdddd2cb36ef659bcddc28e0dbb542b6db8b3bc/modules/desktop/themes/catppuccin/waybar.css#L14 */ - color: @base05; - } - - #workspaces, - .modules-right box { - background: @base02; - padding: 0.15em 0.25em; - border-radius: 1em; - margin: 0 0.25em; - } - - #workspaces { - padding: 0; - background: @base02; - } - - #workspaces button:nth-child(1) { - border-top-left-radius: 1em; - border-bottom-left-radius: 1em; - } - #workspaces button:nth-last-child(1) { - border-top-right-radius: 1em; - border-bottom-right-radius: 1em; - } - - #workspaces button { - padding: 0 0.5em; - background-color: transparent; - } - - #workspaces button:hover { - background: rgba(255, 255, 255, 0.1); - box-shadow: none; - } - - #workspaces button.active { - background: @base0E; - color: @base02; - } - - #workspaces button.urgent { - background: @base08; - } - - #window { - margin-left: 1em; - } - - .modules-left, - .modules-right { - margin: 0.4em 0.5em; - } - - #battery, - #clock, - #network, - #pulseaudio, - #tray, - #power-profiles-daemon { - padding: 0 0.5em; - } - - .modules-left, - .modules-right { - margin: 0.4em 0.5em; - } - - - #custom-power { - padding: 0 1.2em; - color: @base08; - } - ''; -} diff --git a/home/services/swaync/default.nix b/home/services/swaync/default.nix new file mode 100644 index 0000000..aab28b4 --- /dev/null +++ b/home/services/swaync/default.nix @@ -0,0 +1,37 @@ +{ + osConfig, + lib, + lib', + ... +}: let + inherit (lib) optionalString; + inherit (lib') generateGtkColors; + inherit (osConfig.theme.scheme) palette; + inherit (builtins) readFile; +in { + services.swaync = { + enable = true; + style = + optionalString osConfig.theme.enable generateGtkColors lib palette + + readFile ./style.css; + settings = { + positionX = "right"; + positionY = "top"; + layer = "overlay"; + control-center-layer = "top"; + layer-shell = true; + cssPriority = "application"; + control-center-margin-top = 0; + control-center-margin-bottom = 0; + control-center-margin-right = 0; + control-center-margin-left = 0; + notification-2fa-action = true; + notification-inline-replies = false; + notification-icon-size = 64; + notification-body-image-height = 100; + notification-body-image-width = 200; + }; + }; + # systemd.user.services.swaync.Service.Environment = "WAYLAND_DISPLAY=wayland-1"; + systemd.user.services.swaync.Unit.ConditionEnvironment = lib.mkForce ""; +} diff --git a/home/services/swaync/style.css b/home/services/swaync/style.css new file mode 100644 index 0000000..44ddd38 --- /dev/null +++ b/home/services/swaync/style.css @@ -0,0 +1,450 @@ +* { + all: unset; + font-size: 14px; + font-family: "Ubuntu Nerd Font"; + transition: + background 200ms, + border-radius 200ms; /* exclude color from transition so it looks more natural */ +} + +trough highlight { + background: @base05; +} + +scale trough { + margin: 0rem 1rem; + background-color: @base02; + min-height: 8px; + min-width: 70px; +} + +slider { + background-color: @base0D; +} + +.floating-notifications.background .notification-row .notification-background { + box-shadow: + 0 0 8px 0 rgba(0, 0, 0, 0.8), + inset 0 0 0 1px @base02; + border-radius: 12.6px; + margin: 18px; + background-color: @base00; + color: @base05; + padding: 0; +} + +.floating-notifications.background + .notification-row + .notification-background + .notification { + padding: 7px; + border-radius: 12.6px; +} + +.floating-notifications.background + .notification-row + .notification-background + .notification.critical { + box-shadow: inset 0 0 7px 0 @base08; +} + +.floating-notifications.background + .notification-row + .notification-background + .notification + .notification-content { + margin: 7px; +} + +.floating-notifications.background + .notification-row + .notification-background + .notification + .notification-content + .summary { + color: @base05; +} + +.floating-notifications.background + .notification-row + .notification-background + .notification + .notification-content + .time { + color: @base03; +} + +.floating-notifications.background + .notification-row + .notification-background + .notification + .notification-content + .body { + color: @base05; +} + +.floating-notifications.background + .notification-row + .notification-background + .notification + > *:last-child + > * { + min-height: 3.4em; +} + +.floating-notifications.background + .notification-row + .notification-background + .notification + > *:last-child + > * + .notification-action { + border-radius: 7px; + color: @base05; + background-color: @base02; + box-shadow: inset 0 0 0 1px @base03; + margin: 7px; +} + +.floating-notifications.background + .notification-row + .notification-background + .notification + > *:last-child + > * + .notification-action:hover { + box-shadow: inset 0 0 0 1px @base03; + background-color: @base02; + color: @base05; +} + +.floating-notifications.background + .notification-row + .notification-background + .notification + > *:last-child + > * + .notification-action:active { + box-shadow: inset 0 0 0 1px @base03; + background-color: @base0C; + color: @base05; +} + +.floating-notifications.background + .notification-row + .notification-background + .close-button { + margin: 7px; + padding: 2px; + border-radius: 6.3px; + color: @base00; + background-color: @base08; +} + +.floating-notifications.background + .notification-row + .notification-background + .close-button:hover { + background-color: @base08; + color: @base00; +} + +.floating-notifications.background + .notification-row + .notification-background + .close-button:active { + background-color: @base08; + color: @base00; +} + +.control-center { + box-shadow: + 0 0 8px 0 rgba(0, 0, 0, 0.8), + inset 0 0 0 1px @base02; + border-radius: 12.6px; + margin: 18px; + background-color: @base00; + color: @base05; + padding: 14px; +} + +.control-center .widget-title > label { + color: @base05; + font-size: 1.3em; +} + +.control-center .widget-title button { + border-radius: 7px; + color: @base05; + background-color: @base02; + box-shadow: inset 0 0 0 1px @base03; + padding: 8px; +} + +.control-center .widget-title button:hover { + box-shadow: inset 0 0 0 1px @base03; + background-color: @base04; + color: @base05; +} + +.control-center .widget-title button:active { + box-shadow: inset 0 0 0 1px @base03; + background-color: @base0C; + color: @base00; +} + +.control-center .notification-row .notification-background { + border-radius: 7px; + color: @base05; + background-color: @base02; + box-shadow: inset 0 0 0 1px @base03; + margin-top: 14px; +} + +.control-center .notification-row .notification-background .notification { + padding: 7px; + border-radius: 7px; +} + +.control-center + .notification-row + .notification-background + .notification.critical { + box-shadow: inset 0 0 7px 0 @base08; +} + +.control-center + .notification-row + .notification-background + .notification + .notification-content { + margin: 7px; +} + +.control-center + .notification-row + .notification-background + .notification + .notification-content + .summary { + color: @base05; +} + +.control-center + .notification-row + .notification-background + .notification + .notification-content + .time { + color: @base03; +} + +.control-center + .notification-row + .notification-background + .notification + .notification-content + .body { + color: @base05; +} + +.control-center + .notification-row + .notification-background + .notification + > *:last-child + > * { + min-height: 3.4em; +} + +.control-center + .notification-row + .notification-background + .notification + > *:last-child + > * + .notification-action { + border-radius: 7px; + color: @base05; + background-color: @base00; + box-shadow: inset 0 0 0 1px @base03; + margin: 7px; +} + +.control-center + .notification-row + .notification-background + .notification + > *:last-child + > * + .notification-action:hover { + box-shadow: inset 0 0 0 1px @base03; + background-color: @base02; + color: @base05; +} + +.control-center + .notification-row + .notification-background + .notification + > *:last-child + > * + .notification-action:active { + box-shadow: inset 0 0 0 1px @base03; + background-color: @base0C; + color: @base05; +} + +.control-center .notification-row .notification-background .close-button { + margin: 7px; + padding: 2px; + border-radius: 6.3px; + color: @base00; + background-color: @base08; +} + +.control-center .notification-row .notification-background .close-button:hover { + background-color: @base08; + color: @base00; +} + +.control-center + .notification-row + .notification-background + .close-button:active { + background-color: @base08; + color: @base00; +} + +.control-center .notification-row .notification-background:hover { + box-shadow: inset 0 0 0 1px @base03; + background-color: @base04; + color: @base05; +} + +.control-center .notification-row .notification-background:active { + box-shadow: inset 0 0 0 1px @base03; + background-color: @base0C; + color: @base05; +} + +.notification.critical progress { + background-color: @base08; +} + +.notification.low progress, +.notification.normal progress { + background-color: @base0D; +} + +.control-center-dnd { + margin-top: 5px; + border-radius: 8px; + background: @base02; + border: 1px solid @base03; + box-shadow: none; +} + +.control-center-dnd:checked { + background: @base0C; +} + +.control-center-dnd slider { + background: @base0C; + border-radius: 8px; +} + +.widget-dnd { + margin: 0px; + font-size: 1.1rem; +} + +.widget-dnd > switch { + font-size: initial; + border-radius: 8px; + background: @base02; + border: 1px solid @base03; + box-shadow: none; +} + +.widget-dnd > switch:checked { + background: @base0C; + color: @base00; +} + +.widget-dnd > switch slider { + background: @base03; + border-radius: 8px; + border: 1px solid @base03; +} + +.widget-mpris .widget-mpris-player { + background: @base02; + padding: 7px; +} + +.widget-mpris .widget-mpris-title { + font-size: 1.2rem; +} + +.widget-mpris .widget-mpris-subtitle { + font-size: 0.8rem; +} + +.widget-menubar > box > .menu-button-bar > button > label { + font-size: 3rem; + padding: 0.5rem 2rem; +} + +.widget-menubar > box > .menu-button-bar > :last-child { + color: @base08; +} + +.power-buttons button:hover, +.powermode-buttons button:hover, +.screenshot-buttons button:hover { + background: @base02; +} + +.control-center .widget-label > label { + color: @base05; + font-size: 2rem; +} + +.widget-buttons-grid { + padding-top: 1rem; +} + +.widget-buttons-grid > flowbox > flowboxchild > button label { + font-size: 2.5rem; +} + +.widget-volume { + padding-top: 1rem; +} + +.widget-volume label { + font-size: 1.5rem; + color: @base0C; +} + +.widget-volume trough highlight { + background: @base0C; +} + +.widget-backlight trough highlight { + background: @base0A; +} + +.widget-backlight label { + font-size: 1.5rem; + color: @base0A; +} + +.widget-backlight .KB { + padding-bottom: 1rem; +} + +.image { + padding-right: 0.5rem; +} diff --git a/hosts/vamos/default.nix b/hosts/vamos/default.nix index a3a156c..b89b402 100644 --- a/hosts/vamos/default.nix +++ b/hosts/vamos/default.nix @@ -35,6 +35,7 @@ in { "${home}/programs/niri" "${home}/programs/waybar" + "${home}/services/swaync" "${home}/programs/fuzzel.nix" "${home}/programs/swaybg.nix" "${home}/programs/swaylock.nix" diff --git a/lib/default.nix b/lib/default.nix index 3f17696..35b3d3f 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -50,6 +50,11 @@ let '' magick ${path} -gaussian-blur 0x12 "$out" ''; + + generateGtkColors = lib: palette: (lib.concatLines + (lib.mapAttrsToList + (name: color: "@define-color ${name} ${color};") + palette)); in { - inherit blurImage rgba; + inherit blurImage generateGtkColors rgba; }