From e985d6e10482fa1f8ebe49a75f5411983c527d1e Mon Sep 17 00:00:00 2001 From: mjallen18 Date: Mon, 24 Nov 2025 18:45:35 -0600 Subject: [PATCH] power menu --- echo | 1 + modules/home/programs/waybar/default.nix | 96 ++++++++++++++++++- modules/home/programs/waybar/options.nix | 2 + .../programs/waybar/scripts/notifications.nix | 95 ++++++++++++++++++ .../home/programs/waybar/scripts/weather.nix | 96 +++++++++---------- 5 files changed, 240 insertions(+), 50 deletions(-) create mode 100644 echo create mode 100644 modules/home/programs/waybar/scripts/notifications.nix diff --git a/echo b/echo new file mode 100644 index 0000000..e115f23 --- /dev/null +++ b/echo @@ -0,0 +1 @@ +{"text": "\ue312 49\u00b0F", "tooltip": " Overcast 49\u00b0\n .--. Feels like: 49\u00b0\n .-( ). Wind: 2mph \u2199\n (___.__)__) Humidity: 80%\n Moon phase: Waxing Crescent \ud83c\udf12\n\nToday, Mon Nov 24 2025\n\uf2c7 53\u00b0F \uf2ca 38\u00b0F\ue34c 07:23 AM \ue34d 04:36 PM\n03 PM \udb81\udd95 52\u00b0 Partly Cloudy , Overcast 33%, Sunshine 73%\n06 PM \ue313 44\u00b0 Mist, Overcast 83%, Sunshine 8%\n09 PM \ue313 43\u00b0 Fog, Overcast 93%, Sunshine 5%\nTomorrow, Tue Nov 25 2025\n\uf2c7 43\u00b0F \uf2ca 34\u00b0F\ue34c 07:24 AM \ue34d 04:36 PM\n12 AM \ue313 43\u00b0 Fog, Fog 6%, Overcast 81%, Sunshine 19%\n03 AM \ue313 42\u00b0 Fog, Overcast 89%, Sunshine 8%\n06 AM \ue313 41\u00b0 Fog, Fog 6%, Overcast 92%, Sunshine 11%\n09 AM \ue313 40\u00b0 Fog, Fog 6%, Overcast 88%, Sunshine 5%\n12 PM \ue317 39\u00b0 Moderate rain at times, Overcast 90%, Rain 100%\n03 PM \ue308 34\u00b0 Light rain, Overcast 93%, Rain 100%\n06 PM \ue318 31\u00b0 Moderate rain, Overcast 88%, Rain 100%\n09 PM \ue31a 24\u00b0 Moderate snow, Overcast 89%, Rain 100%, Snow 100%\nWed Nov 26 2025\n\uf2c7 36\u00b0F \uf2ca 25\u00b0F\ue34c 07:26 AM \ue34d 04:35 PM\n12 AM \ue312 21\u00b0 Overcast , Overcast 87%, Sunshine 8%\n03 AM \ue312 14\u00b0 Overcast , Frost 25%, Overcast 94%, Sunshine 13%\n06 AM \ue312 11\u00b0 Overcast , Frost 80%, Overcast 89%, Sunshine 8%\n09 AM \ue312 13\u00b0 Overcast , Frost 79%, Overcast 80%, Sunshine 5%\n12 PM \ue33d 18\u00b0 Cloudy , Frost 77%, Overcast 89%, Sunshine 17%\n03 PM \ue30d 24\u00b0 Sunny, Frost 29%, Sunshine 90%\n06 PM \udb81\udd94 22\u00b0 Clear , Frost 78%, Sunshine 94%\n09 PM \udb83\udf31 15\u00b0 Partly Cloudy , Frost 85%, Overcast 39%, Sunshine 83%\n"} diff --git a/modules/home/programs/waybar/default.nix b/modules/home/programs/waybar/default.nix index 4c71204..505bfea 100755 --- a/modules/home/programs/waybar/default.nix +++ b/modules/home/programs/waybar/default.nix @@ -122,6 +122,23 @@ let background-color: transparent; } + #custom-power { + color: ${palette.colors.primary}; + background-color: ${palette.colors.bg}; + ${defaultOpacity} + ${defaultCenterOptions} + border-radius: 0; + } + + menu { + border-radius: 15px; + background: ${palette.colors.bg}; + color: ${palette.colors.text}; + } + menuitem { + border-radius: 15px; + } + #custom-weather { color: ${palette.colors.primary}; background-color: ${palette.colors.bg}; @@ -130,6 +147,25 @@ let border-radius: 0; } + #custom-notifications { + color: ${palette.colors.primary}; + background-color: ${palette.colors.bg}; + ${defaultOpacity} + ${defaultCenterOptions} + border-radius: 0; + } + + #custom-notifications.notify { + color: ${palette.colors.danger}; + } + + #custom-notifications.alert { + animation-name: blinker; + animation-duration: 3s; + animation-timing-function: linear; + animation-iteration-count: infinite; + } + #battery { color: ${palette.colors.accent}; background-color: ${palette.colors.bg}; @@ -292,6 +328,7 @@ in ./options.nix ./scripts/audio-control.nix ./scripts/hass.nix + ./scripts/notifications.nix ./scripts/weather.nix ]; @@ -299,6 +336,39 @@ in # https://github.com/Alexays/Waybar/wiki/Module:-Hyprland # https://www.nerdfonts.com/cheat-sheet + home.file = { + ".config/waybar/power_menu.xml".text = '' + + + + + + Suspend + + + + + Hibernate + + + + + Shutdown + + + + + + + + Reboot + + + + + ''; + }; + programs.waybar = { enable = true; systemd.enable = true; @@ -377,15 +447,37 @@ in }; }; + "custom/notifications" = { + interval = 30; + format = { }; + tooltip = true; + exec = "waybar-notifications"; + return-type = "json"; + on-click-middle = "makoctl restore && makoctl dismiss --all --no-history"; # todo + }; + "custom/left-end" = { - format = " "; + format = "&nbsp"; tooltip = false; }; "custom/right-end" = { - format = " "; + format = "&nbsp"; tooltip = false; }; + + "custom/power" = { + format = "⏻ "; + tooltip = false; + menu = "on-click"; + menu-file = "~/.config/waybar/power_menu.xml"; + menu-actions = { + shutdown = "shutdown"; + reboot = "reboot"; + suspend = "systemctl suspend"; + hibernate = "systemctl hibernate"; + }; + }; } (mkIf cfg.features.tray.enable { diff --git a/modules/home/programs/waybar/options.nix b/modules/home/programs/waybar/options.nix index 6b9b28e..c5db66a 100644 --- a/modules/home/programs/waybar/options.nix +++ b/modules/home/programs/waybar/options.nix @@ -87,7 +87,9 @@ in "custom/left-end" "clock" "battery" + "custom/notifications" "custom/weather" + "custom/power" "custom/right-end" ]; description = "Modules shown on the right."; diff --git a/modules/home/programs/waybar/scripts/notifications.nix b/modules/home/programs/waybar/scripts/notifications.nix new file mode 100644 index 0000000..f34d208 --- /dev/null +++ b/modules/home/programs/waybar/scripts/notifications.nix @@ -0,0 +1,95 @@ +{ + config, + lib, + namespace, + pkgs, + ... +}: +let + cfg = config.${namespace}.programs.waybar; + + waybar-notifications = pkgs.writeScriptBin "waybar-notifications" '' + #!/usr/bin/env python + + import subprocess + import json + import codecs + import re + + def check_notifications(args = "history"): + notifications = [] + number = None + content = None + appname = None + urgency = None + cmd = "makoctl" + temp = subprocess.Popen([cmd, args], stdout = subprocess.PIPE) + output = str(temp.communicate()).replace("(b\'", "").replace("\', None)", "") + lines = output.split("\\n") + for line in lines: + if "Notification" in line: + number = line.split(":")[0].replace("Notification ", "") + content = re.sub(r"[\u2066\u2067\u2068\u2069, \u00e2\u0081\u00a8]", "", codecs.decode(line.split(": ")[-1].encode("latin1").decode("utf-8"), "unicode_escape")) + content = re.sub(r"[\u00a9]", " ", content) + + if "App name" in line: + appname = line.split(": ")[-1] + if "Urgency" in line: + urgency = line.split(": ")[-1] + + if number is not None and content is not None and appname is not None and urgency is not None: + notifications.append((number, content, appname, urgency)) + number = None + content = None + appname = None + urgency = None + + return notifications + + def get_icon(notifications): + status = "" + icon = "" + + for number, content, appname, urgency in notifications: + status = "notify" + if urgency != "normal": + status = "alert" + break + + if status == "notify": + icon = "󰂞" + if status == "alert": + icon = "󰵙" + + return icon, status + + def build_tooltip(notifications): + tooltip = "" + for number, content, appname, urgency in notifications: + tooltip += "{0}: {1}\n".format(appname, content) + + return tooltip + + def main(): + notifications = check_notifications() + data = {} + + icon, status = get_icon(notifications) + + data["text"] = icon + data["tooltip"] = build_tooltip(notifications) + data["class"] = status + + print(json.dumps(data, ensure_ascii=False)) + + main() + + ''; +in +{ + imports = [ ../options.nix ]; + + config = lib.mkIf cfg.enable { + home.packages = [ waybar-notifications ]; + }; +} diff --git a/modules/home/programs/waybar/scripts/weather.nix b/modules/home/programs/waybar/scripts/weather.nix index cb8390d..76e0545 100644 --- a/modules/home/programs/waybar/scripts/weather.nix +++ b/modules/home/programs/waybar/scripts/weather.nix @@ -189,100 +189,100 @@ let ' '], "VeryCloudy": [ ' ', - ' .--. ', - ' .-( ). ', - ' (___.__)__) ', + ' .--. ', + ' .-( ). ', + ' (___.__)__) ', ' '], "LightShowers": [ ' _`/\'\'".-. ', ' ,\\_"( ). ', ' /"(___(__) ', - ' ‘ ‘ ‘ ‘ ', - ' ‘ ‘ ‘ ‘ '], + ' ‘ ‘ ‘ ‘ ', + ' ‘ ‘ ‘ ‘ '], "HeavyShowers": [ - ' _`/\'\'".-. ', - ' ,\\_"( ). ', - ' /"(___(__) ', - ' ‚‘‚‘‚‘‚‘ ', - ' ‚’‚’‚’‚’ '], + ' _`/\'\'".-. ', + ' ,\\_"( ). ', + ' /"(___(__) ', + ' ‚‘‚‘‚‘‚‘ ', + ' ‚’‚’‚’‚’ '], "LightSnowShowers": [ ' _`/\'\'".-. ', ' ,\\_"( ). ', ' /"(___(__) ', - ' * * * ', - ' * * * '], + ' * * * ', + ' * * * '], "HeavySnowShowers": [ - ' _`/\'\'".-. ', - ' ,\\_"( ). ', - ' /"(___(__) ', - ' * * * * ', - ' * * * * '], + ' _`/\'\'".-. ', + ' ,\\_"( ). ', + ' /"(___(__) ', + ' * * * * ', + ' * * * * '], "LightSleetShowers": [ ' _`/\'\'".-. ', ' ,\\_"( ). ', ' /"(___(__) ', - '"*""* ', - ' *""*"'], + '"*""* ', + ' *""*"'], "ThunderyShowers": [ ' _`/\'\'".-. ', ' ,\\_"( ). ', ' /"(___(__) ', - ' ⚡\\"‘ ‘"⚡\\"‘ ‘ ', - ' ‘ ‘ ‘ ‘ '], + ' ⚡\\"‘ ‘"⚡\\"‘ ‘ ', + ' ‘ ‘ ‘ ‘ '], "ThunderyHeavyRain": [ - ' .-. ', - ' ( ). ', - ' (___(__) ', - ' ‚‘"⚡\\"‘‚"⚡\\"‚‘ ', - ' ‚’‚’"⚡\\"’‚’ '], + ' .-. ', + ' ( ). ', + ' (___(__) ', + ' ‚‘"⚡\\"‘‚"⚡\\"‚‘ ', + ' ‚’‚’"⚡\\"’‚’ '], "ThunderySnowShowers": [ ' _`/\'\'".-. ', ' ,\\_"( ). ', ' /"(___(__) ', - ' *"⚡\\"*"⚡\\"* ', - ' * * * '], + ' *"⚡\\"*"⚡\\"* ', + ' * * * '], "LightRain": [ ' .-. ', ' ( ). ', ' (___(__) ', - ' ‘ ‘ ‘ ‘ ', - ' ‘ ‘ ‘ ‘ '], + ' ‘ ‘ ‘ ‘ ', + ' ‘ ‘ ‘ ‘ '], "HeavyRain": [ - ' .-. ', - ' ( ). ', - ' (___(__) ', - ' ‚‘‚‘‚‘‚‘ ', - ' ‚’‚’‚’‚’ '], + ' .-. ', + ' ( ). ', + ' (___(__) ', + ' ‚‘‚‘‚‘‚‘ ', + ' ‚’‚’‚’‚’ '], "LightSnow": [ ' .-. ', ' ( ). ', ' (___(__) ', - ' * * * ', - ' * * * '], + ' * * * ', + ' * * * '], "HeavySnow": [ - ' .-. ', - ' ( ). ', - ' (___(__) ', - ' * * * * ', - ' * * * * '], + ' .-. ', + ' ( ). ', + ' (___(__) ', + ' * * * * ', + ' * * * * '], "LightSleet": [ ' .-. ', ' ( ). ', ' (___(__) ', - '"*""* ', - ' *""*"'], + '"*""* ', + ' *""*"'], "Fog": [ ' ', - ' _ - _ - _ - ', - ' _ - _ - _ ', - ' _ - _ - _ - ', + ' _ - _ - _ - ', + ' _ - _ - _ ', + ' _ - _ - _ - ', ' '], } WEATHER_CODES_WEGO = {key: WEATHER_SYMBOL_WEGO[value] for key, value in WWO_CODE.items()} data = {} - + data["text"] = "" def format_time(time): """get the time formatted"""