Changed Waybar
This commit is contained in:
		
							
								
								
									
										157
									
								
								home/hyprland/waybar/common.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								home/hyprland/waybar/common.nix
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,157 @@
 | 
			
		||||
{
 | 
			
		||||
  widgets = {
 | 
			
		||||
    "group/media" = {
 | 
			
		||||
      orientation = "horizontal";
 | 
			
		||||
 | 
			
		||||
      modules = [
 | 
			
		||||
        "mpris"
 | 
			
		||||
        "custom/cava"
 | 
			
		||||
        "wireplumber"
 | 
			
		||||
      ];
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    mpris = {
 | 
			
		||||
      format = "{player_icon}";
 | 
			
		||||
      format-paused = "{status_icon}";
 | 
			
		||||
      max-length = 100;
 | 
			
		||||
      player-icons = {
 | 
			
		||||
        default = "||";
 | 
			
		||||
        mpv = "||";
 | 
			
		||||
      };
 | 
			
		||||
      status-icons = {
 | 
			
		||||
        paused = "▶";
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    "custom/cava" = {
 | 
			
		||||
      exec = "sh ~/.config/waybar/cava.sh";
 | 
			
		||||
      format = "{} ♪";
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    wireplumber = {
 | 
			
		||||
      format = "{volume}%";
 | 
			
		||||
      format-muted = "";
 | 
			
		||||
      max-volume = 110;
 | 
			
		||||
      scroll-step = 0.2;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    "group/hardware" = {
 | 
			
		||||
      orientation = "horizontal";
 | 
			
		||||
      modules = [
 | 
			
		||||
        "cpu"
 | 
			
		||||
        "network"
 | 
			
		||||
        "memory"
 | 
			
		||||
        "disk"
 | 
			
		||||
        "temperature"
 | 
			
		||||
      ];
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    network = {
 | 
			
		||||
      # Wifi
 | 
			
		||||
      tooltip = true;
 | 
			
		||||
      format-wifi = "{icon} ";
 | 
			
		||||
      format-icons = [
 | 
			
		||||
        ""
 | 
			
		||||
        ""
 | 
			
		||||
        ""
 | 
			
		||||
      ];
 | 
			
		||||
      rotate = 0;
 | 
			
		||||
 | 
			
		||||
      # Ethernet
 | 
			
		||||
      format-ethernet = "ᯤ";
 | 
			
		||||
      tooltip-format = "Network: <big><b>{essid}</b></big>\nSignal strength: <b>{signaldBm}dBm ({signalStrength}%)</b>\nFrequency: <b>{frequency}MHz</b>\nInterface: <b>{ifname}</b>\nIP: <b>{ipaddr}/{cidr}</b>\nGateway: <b>{gwaddr}</b>\nNetmask: <b>{netmask}</b>\nCurrent : <b>{bandwidthTotalBits}</b>\nUp : <b>{bandwidthUpBits}</b>\nDown : <b>{bandwidthDownBits}</b>";
 | 
			
		||||
      format-linked = " {ifname} (No IP)";
 | 
			
		||||
      format-disconnected = " ";
 | 
			
		||||
      tooltip-format-disconnected = "Disconnected";
 | 
			
		||||
      on-click = "/usr/local/bin/ags -t ControlPanel";
 | 
			
		||||
      interval = 2;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    memory = {
 | 
			
		||||
      interval = 1;
 | 
			
		||||
      rotate = 270;
 | 
			
		||||
      format = "{icon}";
 | 
			
		||||
      format-icons = [
 | 
			
		||||
        ""
 | 
			
		||||
        ""
 | 
			
		||||
        ""
 | 
			
		||||
        ""
 | 
			
		||||
        ""
 | 
			
		||||
        ""
 | 
			
		||||
        ""
 | 
			
		||||
        ""
 | 
			
		||||
        ""
 | 
			
		||||
      ];
 | 
			
		||||
      max-length = 10;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    cpu = {
 | 
			
		||||
      interval = 1;
 | 
			
		||||
      format = "{icon}";
 | 
			
		||||
      rotate = 270;
 | 
			
		||||
      format-icons = [
 | 
			
		||||
        ""
 | 
			
		||||
        ""
 | 
			
		||||
        ""
 | 
			
		||||
        ""
 | 
			
		||||
        ""
 | 
			
		||||
        ""
 | 
			
		||||
        ""
 | 
			
		||||
        ""
 | 
			
		||||
        ""
 | 
			
		||||
      ];
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    temperature = {
 | 
			
		||||
      format = "{temperatureC}°C ";
 | 
			
		||||
      thermal-zone = 0;
 | 
			
		||||
      hwmon-path = "/sys/class/hwmon/hwmon0/temp1_input";
 | 
			
		||||
      critical-threshold = 80;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    disk = {
 | 
			
		||||
      format = "{percentage_free}% ";
 | 
			
		||||
      tooltip = true;
 | 
			
		||||
      tooltip-format = "{free} / {total} ({percentage_free})";
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    clock = {
 | 
			
		||||
      format = "{:%a %b %d, %I:%M %p}";
 | 
			
		||||
      rotate = 0;
 | 
			
		||||
      on-click = " ";
 | 
			
		||||
      tooltip-format = "<tt>{calendar}</tt>";
 | 
			
		||||
      calendar = {
 | 
			
		||||
        mode = "month";
 | 
			
		||||
        mode-mon-col = 3;
 | 
			
		||||
        on-scroll = 1;
 | 
			
		||||
        on-click-right = "mode";
 | 
			
		||||
        format = {
 | 
			
		||||
          months = "<span color='#cba6f7'><b>{}</b></span>";
 | 
			
		||||
          weekdays = "<span color='#74c7ec'><b>{}</b></span>";
 | 
			
		||||
          today = "<span color='#f38ba8'><b>{}</b></span>";
 | 
			
		||||
        };
 | 
			
		||||
      };
 | 
			
		||||
      actions = {
 | 
			
		||||
        on-click-right = "mode";
 | 
			
		||||
        on-click-forward = "tz_up";
 | 
			
		||||
        on-click-backward = "tz_down";
 | 
			
		||||
        on-scroll-up = "shift_up";
 | 
			
		||||
        on-scroll-down = "shift_down";
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    "custom/nixicon" = {
 | 
			
		||||
      format = "";
 | 
			
		||||
      on-click = "rofi -show drun -theme $HOME/.config/rofi/custom.rasi";
 | 
			
		||||
      tooltip = false;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    "custom/weather" = {
 | 
			
		||||
      format = "{}";
 | 
			
		||||
      exec = "curl -s 'wttr.in/52.281311,10.527029?format=2'";
 | 
			
		||||
      interval = 60;
 | 
			
		||||
      tooltip = false;
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,609 +0,0 @@
 | 
			
		||||
//   --// waybar config generated by wbarconfgen.sh //--   //
 | 
			
		||||
 | 
			
		||||
[
 | 
			
		||||
{
 | 
			
		||||
  "layer": "top",
 | 
			
		||||
  "position": "top",
 | 
			
		||||
  "mod": "dock",
 | 
			
		||||
  //"width": 20,
 | 
			
		||||
  "margin-top": 7,
 | 
			
		||||
  "margin-bottom": 0,
 | 
			
		||||
  "margin-left": 10,
 | 
			
		||||
  "margin-right": 10,
 | 
			
		||||
  "exclusive": true,
 | 
			
		||||
  "passthrough": false,
 | 
			
		||||
  "gtk-layer-shell": true,
 | 
			
		||||
  "reload_style_on_change": true,
 | 
			
		||||
  "output": "Virtual-1",
 | 
			
		||||
 | 
			
		||||
	"modules-left": [],
 | 
			
		||||
	"modules-center": ["wlr/taskbar"],
 | 
			
		||||
	"modules-right": ["cpu"],
 | 
			
		||||
  
 | 
			
		||||
  "wlr/taskbar": {
 | 
			
		||||
    "all-outputs": true,
 | 
			
		||||
    "format": "{icon}",
 | 
			
		||||
    "icon-size": 20,
 | 
			
		||||
    "active-first": true
 | 
			
		||||
  }
 | 
			
		||||
},
 | 
			
		||||
 | 
			
		||||
{
 | 
			
		||||
// sourced from header module //
 | 
			
		||||
 | 
			
		||||
  "layer": "top",
 | 
			
		||||
  "position": "top",
 | 
			
		||||
  "mod": "dock",
 | 
			
		||||
  "margin-left": 10,
 | 
			
		||||
  "margin-right": 10,
 | 
			
		||||
  "margin-top": 7,
 | 
			
		||||
  "margin-bottom": 0,
 | 
			
		||||
  "exclusive": true,
 | 
			
		||||
  "passthrough": false,
 | 
			
		||||
  "gtk-layer-shell": true,
 | 
			
		||||
  "reload_style_on_change": true,
 | 
			
		||||
  "output": "DP-1",
 | 
			
		||||
 | 
			
		||||
// positions generated based on config.ctl //
 | 
			
		||||
 | 
			
		||||
	"modules-left": ["custom/smallspacer","hyprland/workspaces","custom/spacer","mpris"],
 | 
			
		||||
	"modules-center": ["custom/padd","custom/l_end","custom/r_end","hyprland/window","custom/padd"],
 | 
			
		||||
	"modules-right": ["custom/padd","custom/l_end","group/expand","network","group/expand-3","group/expand-2","group/expand-4","memory","cpu","clock","custom/notification","custom/padd"],
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// sourced from modules based on config.ctl //
 | 
			
		||||
 | 
			
		||||
"custom/led": {
 | 
			
		||||
    "format": "<span color='#021c18'></span> <span color='#313436'></span> ",
 | 
			
		||||
    "format-alt": " <span color='#bbc2c7'></span> ",
 | 
			
		||||
    "on-click": "~/mouse.sh",
 | 
			
		||||
    "tooltip": false,
 | 
			
		||||
},
 | 
			
		||||
 | 
			
		||||
"upower": {
 | 
			
		||||
     "icon-size": 20,
 | 
			
		||||
      "format": "",
 | 
			
		||||
     "format-alt": "{}<span color='orange'>[{time}]</span>",
 | 
			
		||||
     "tooltip": true,
 | 
			
		||||
     "tooltip-spacing": 20,
 | 
			
		||||
      "on-click-right": "pkill waybar & hyprctl dispatch exec waybar"
 | 
			
		||||
},
 | 
			
		||||
 | 
			
		||||
"upower#headset": {
 | 
			
		||||
"format": " {percentage}",
 | 
			
		||||
"native-path": "/org/freedesktop/UPower/devices/headset_dev_A6_98_9A_0D_D3_49",
 | 
			
		||||
"show-icon": false,
 | 
			
		||||
"tooltip": false,
 | 
			
		||||
},
 | 
			
		||||
 | 
			
		||||
"group/expand-4": {
 | 
			
		||||
     "orientation": "horizontal",
 | 
			
		||||
     "drawer": {
 | 
			
		||||
         "transition-duration": 600,
 | 
			
		||||
         "children-class": "not-power",
 | 
			
		||||
       "transition-to-left": true,
 | 
			
		||||
         "click-to-reveal": true
 | 
			
		||||
     },
 | 
			
		||||
     "modules": ["upower","upower/headset"]
 | 
			
		||||
   },
 | 
			
		||||
 | 
			
		||||
"custom/smallspacer":{
 | 
			
		||||
"format": " ",
 | 
			
		||||
},
 | 
			
		||||
"memory": {
 | 
			
		||||
    "interval": 1,
 | 
			
		||||
    "rotate": 270,
 | 
			
		||||
    "format": "{icon}",
 | 
			
		||||
    "format-icons": ["","","","","","","","",""],
 | 
			
		||||
    "max-length": 10
 | 
			
		||||
},
 | 
			
		||||
"cpu": {
 | 
			
		||||
    "interval": 1,
 | 
			
		||||
    "format": "{icon}",
 | 
			
		||||
    "rotate": 270,
 | 
			
		||||
    "format-icons": ["","","","","","","","",""],
 | 
			
		||||
},
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
"mpris": {
 | 
			
		||||
	"format": "{player_icon} {dynamic}",
 | 
			
		||||
	"format-paused": "<span color='grey'>{status_icon} {dynamic}</span>",
 | 
			
		||||
	"max-length": 100,
 | 
			
		||||
	"player-icons": {
 | 
			
		||||
		"default": "⏸",
 | 
			
		||||
		"mpv": "🎵"
 | 
			
		||||
	},
 | 
			
		||||
	"status-icons": {
 | 
			
		||||
		"paused": "▶" 
 | 
			
		||||
	},
 | 
			
		||||
	// "ignored-players": ["firefox"]
 | 
			
		||||
},
 | 
			
		||||
"tray": {
 | 
			
		||||
        "icon-size": 16,
 | 
			
		||||
        "rotate": 0,
 | 
			
		||||
        "spacing": 3
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
   "group/expand": {
 | 
			
		||||
     "orientation": "horizontal",
 | 
			
		||||
     "drawer": {
 | 
			
		||||
         "transition-duration": 600,
 | 
			
		||||
         "children-class": "not-power",
 | 
			
		||||
       "transition-to-left": true,
 | 
			
		||||
       //  "click-to-reveal": true
 | 
			
		||||
     },
 | 
			
		||||
     "modules": ["custom/menu","custom/spacer","tray"]
 | 
			
		||||
   },
 | 
			
		||||
 | 
			
		||||
 "custom/menu":{
 | 
			
		||||
 "format": "",
 | 
			
		||||
 "rotate": 90,
 | 
			
		||||
 },
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
"custom/notification": {
 | 
			
		||||
    "tooltip": false,
 | 
			
		||||
    "format": "{icon}",
 | 
			
		||||
    "format-icons": {
 | 
			
		||||
      "notification": "",
 | 
			
		||||
      "none": "",
 | 
			
		||||
      "dnd-notification": "",
 | 
			
		||||
      "dnd-none": "",
 | 
			
		||||
      "inhibited-notification": "",
 | 
			
		||||
      "inhibited-none": "",
 | 
			
		||||
      "dnd-inhibited-notification": "",
 | 
			
		||||
      "dnd-inhibited-none": ""
 | 
			
		||||
    },
 | 
			
		||||
    "return-type": "json",
 | 
			
		||||
    "exec-if": "which swaync-client",
 | 
			
		||||
    "exec": "swaync-client -swb",
 | 
			
		||||
    "on-click-right": "swaync-client -d -sw",
 | 
			
		||||
    "on-click": "swaync-client -t -sw",
 | 
			
		||||
    "escape": true
 | 
			
		||||
  },
 | 
			
		||||
  
 | 
			
		||||
  "hyprland/window": {  
 | 
			
		||||
//"format": "{}"   // <--- these is the default value  
 | 
			
		||||
"format": "<span  weight='bold' >{class}</span>",
 | 
			
		||||
 "max-length": 120,
 | 
			
		||||
 "icon": false,
 | 
			
		||||
 "icon-size": 13,
 | 
			
		||||
},
 | 
			
		||||
 | 
			
		||||
    "custom/power": {
 | 
			
		||||
        "format": "@{}",
 | 
			
		||||
        "rotate": 0,
 | 
			
		||||
        "on-click": "ags -t ControlPanel",
 | 
			
		||||
        "on-click-right": "pkill ags",
 | 
			
		||||
        "tooltip": true
 | 
			
		||||
    },
 | 
			
		||||
    
 | 
			
		||||
    "custom/spacer":{
 | 
			
		||||
    "format": "|"
 | 
			
		||||
    },
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
"hyprland/workspaces": {
 | 
			
		||||
	"format": "{icon}",
 | 
			
		||||
	"format-icons": {
 | 
			
		||||
	"default": "",
 | 
			
		||||
	"active": "",
 | 
			
		||||
	//"default": "○",
 | 
			
		||||
	//"default": "●"
 | 
			
		||||
	},
 | 
			
		||||
},
 | 
			
		||||
 | 
			
		||||
"wlr/workspaces": {
 | 
			
		||||
    "persistent-workspaces": {
 | 
			
		||||
        "3": [], // Always show a workspace with name '3', on all outputs if it does not exists
 | 
			
		||||
        "4": ["eDP-1"], // Always show a workspace with name '4', on output 'eDP-1' if it does not exists
 | 
			
		||||
        "5": ["eDP-1", "DP-2"] // Always show a workspace with name '5', on outputs 'eDP-1' and 'DP-2' if it does not exists
 | 
			
		||||
    }
 | 
			
		||||
},
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
"cava": {
 | 
			
		||||
       "cava_config": "~/.config/cava/config",
 | 
			
		||||
      "framerate": 60,
 | 
			
		||||
      "autosens": 1,
 | 
			
		||||
      "bars": 14,
 | 
			
		||||
      "lower_cutoff_freq": 50,
 | 
			
		||||
      "higher_cutoff_freq": 10000,
 | 
			
		||||
      "method": "pulse",
 | 
			
		||||
      "source": "auto",
 | 
			
		||||
      "stereo": true,
 | 
			
		||||
      "reverse": false,
 | 
			
		||||
      "bar_delimiter": 0,
 | 
			
		||||
      "monstercat": false,
 | 
			
		||||
      "waves": false,
 | 
			
		||||
      "noise_reduction": 0.77,
 | 
			
		||||
      "input_delay": 2,
 | 
			
		||||
      "format-icons" : ["▁", "▂", "▃", "▄", "▅", "▆", "▇", "█" ],
 | 
			
		||||
      "actions": {
 | 
			
		||||
                 "on-click-right": "mode"
 | 
			
		||||
                 }
 | 
			
		||||
    },
 | 
			
		||||
    
 | 
			
		||||
    "custom/script": {
 | 
			
		||||
    "on-click": "~/.config/waybar/volume.sh toggle",
 | 
			
		||||
    "format": "",
 | 
			
		||||
    
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    "custom/cliphist": {
 | 
			
		||||
        "format": "{}",
 | 
			
		||||
        "rotate": 0,
 | 
			
		||||
        "exec": "echo ; echo  clipboard history",
 | 
			
		||||
        "on-click": "sleep 0.1 && cliphist.sh c",
 | 
			
		||||
        "on-click-right": "sleep 0.1 && cliphist.sh d",
 | 
			
		||||
        "on-click-middle": "sleep 0.1 && cliphist.sh w",
 | 
			
		||||
        "interval" : 86400, // once every day
 | 
			
		||||
        "tooltip": true
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    "custom/wbar": {
 | 
			
		||||
        "format": "𐌏{}", //    //
 | 
			
		||||
        "rotate": 0,
 | 
			
		||||
        "exec": "echo ; echo show app menu",
 | 
			
		||||
        "on-click": "wofi --show drun",
 | 
			
		||||
        "on-click-right": "wbarconfgen.sh p",
 | 
			
		||||
        "on-click-middle": "sleep 0.1 && quickapps.sh kitty firefox spotify code dolphin",
 | 
			
		||||
        "interval" : 86400,
 | 
			
		||||
        "tooltip": true
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    "custom/theme": {
 | 
			
		||||
        "format": "{}",
 | 
			
		||||
        "rotate": 0,
 | 
			
		||||
        "exec": "echo ; echo  pick color",
 | 
			
		||||
        "on-click": "hyprpicker",
 | 
			
		||||
        "on-click-right": "themeswitch.sh -p",
 | 
			
		||||
        "on-click-middle": "sleep 0.1 && themeselect.sh",
 | 
			
		||||
        "interval" : 86400, // once every day
 | 
			
		||||
        "tooltip": true
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    "custom/wallchange": {
 | 
			
		||||
        "format": "{}",
 | 
			
		||||
        "rotate": 0,
 | 
			
		||||
        "exec": "echo ; echo  switch wallpaper",
 | 
			
		||||
       "on-click": "swww img --transition-type grow --transition-pos 0.071,0.988 --transition-step 255 --transition-fps 60 /home/anik/Downloads/skyway.jpg",
 | 
			
		||||
        "on-click-right": "swww img --transition-type grow --transition-pos 0.071,0.988 --transition-step 255 --transition-fps 60 /home/anik/Downloads/cloud.png",
 | 
			
		||||
        "on-click-middle": "swww img --transition-type grow --transition-pos 0.071,0.988 --transition-step 255 --transition-fps 60 /home/anik/Downloads/gradient.jpg",
 | 
			
		||||
        "on-scroll-up": "swww img --transition-type grow --transition-pos 0.071,0.988 --transition-step 255 --transition-fps 60 /home/anik/Downloads/torvalds.png",
 | 
			
		||||
        "on-scroll-down": "swww img --transition-type grow --transition-pos 0.071,0.988 --transition-step 255 --transition-fps 60 /home/anik/Downloads/night.png",
 | 
			
		||||
        "interval" : 86400, // once every day
 | 
			
		||||
        "tooltip": true
 | 
			
		||||
    },
 | 
			
		||||
    "custom/mouse":
 | 
			
		||||
    { 
 | 
			
		||||
            "format": "",
 | 
			
		||||
            "format-alt": "",
 | 
			
		||||
            
 | 
			
		||||
            "on-click": "m8mouse -dpi 1 -led 2 -speed 4",
 | 
			
		||||
        "on-click-right": "m8mouse -dpi 1 -led 4 -speed 4",
 | 
			
		||||
        "on-click-middle": "m8mouse -dpi 1 -led 7 -speed 4",
 | 
			
		||||
        "tooltip": true 
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
	"wlr/taskbar": {
 | 
			
		||||
		"format": "{icon}",
 | 
			
		||||
		"rotate": 0,
 | 
			
		||||
		"icon-size": 18,
 | 
			
		||||
		"icon-theme": "Tela-circle-dracula",
 | 
			
		||||
        "spacing": 0,
 | 
			
		||||
		"tooltip-format": "{title}",
 | 
			
		||||
		"on-click": "activate",
 | 
			
		||||
		"on-click-middle": "close",
 | 
			
		||||
		"ignore-list": [
 | 
			
		||||
			"Alacritty"
 | 
			
		||||
		],
 | 
			
		||||
		"app_ids-mapping": {
 | 
			
		||||
			"firefoxdeveloperedition": "firefox-developer-edition"
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
    "custom/spotify": {
 | 
			
		||||
        "exec": "mediaplayer.py --player spotify",
 | 
			
		||||
        "format": " {}",
 | 
			
		||||
        "rotate": 0,
 | 
			
		||||
        "return-type": "json",
 | 
			
		||||
        "on-click": "playerctl play-pause --player spotify",
 | 
			
		||||
        "on-click-right": "playerctl next --player spotify",
 | 
			
		||||
        "on-click-middle": "playerctl previous --player spotify",
 | 
			
		||||
        "on-scroll-up": "volumecontrol.sh -p spotify i",
 | 
			
		||||
        "on-scroll-down": "volumecontrol.sh -p spotify d",
 | 
			
		||||
        "max-length": 25,
 | 
			
		||||
        "escape": true,
 | 
			
		||||
        "tooltip": true
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    "idle_inhibitor": {
 | 
			
		||||
        "format": "{icon}",
 | 
			
		||||
        "rotate": 0,
 | 
			
		||||
        "format-icons": {
 | 
			
		||||
            "activated": "",
 | 
			
		||||
            "deactivated": ""
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    "clock": {
 | 
			
		||||
        "format": "{:%I:%M %p}",
 | 
			
		||||
        "rotate": 0,
 | 
			
		||||
       "on-click": "/usr/local/bin/ags -t ActivityCenter",
 | 
			
		||||
        "tooltip-format": "<tt>{calendar}</tt>",
 | 
			
		||||
        "calendar": {
 | 
			
		||||
            "mode": "month",
 | 
			
		||||
            "mode-mon-col": 3,
 | 
			
		||||
            "on-scroll": 1,
 | 
			
		||||
            "on-click-right": "mode",
 | 
			
		||||
            "format": {
 | 
			
		||||
                "months": "<span color='#ffead3'><b>{}</b></span>",
 | 
			
		||||
                "weekdays": "<span color='#ffcc66'><b>{}</b></span>",
 | 
			
		||||
                "today": "<span color='#ff6699'><b>{}</b></span>"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "actions": {
 | 
			
		||||
            "on-click-right": "mode",
 | 
			
		||||
            "on-click-forward": "tz_up",
 | 
			
		||||
            "on-click-backward": "tz_down",
 | 
			
		||||
            "on-scroll-up": "shift_up",
 | 
			
		||||
            "on-scroll-down": "shift_down"
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    "battery": {
 | 
			
		||||
        "states": {
 | 
			
		||||
            "good": 95,
 | 
			
		||||
            "warning": 30,
 | 
			
		||||
            "critical": 20
 | 
			
		||||
        },
 | 
			
		||||
        "format": "{icon}",
 | 
			
		||||
        "rotate": 0,
 | 
			
		||||
        "format-charging": "<span color='#a6d189'></span>",
 | 
			
		||||
        "format-plugged": "",
 | 
			
		||||
       // "format-alt": "<<span weight='bold' color='#c2864a'>{time} <span weight='bold' color='white'>| <span weight='bold' color='#82d457'>{capacity}%</span></span></span>",
 | 
			
		||||
        "format-icons": ["","","","","","","","",""],
 | 
			
		||||
     //  "format-icons": ["","","","","","","",""],  
 | 
			
		||||
       //"format-icons": ["", "", "", "", "", "", "", "", "", "", ""],
 | 
			
		||||
        "on-click-right": "pkill waybar & hyprctl dispatch exec waybar",
 | 
			
		||||
      //  "format-icons": [<i class='fa-solid fa-wifi-slash'></i>],
 | 
			
		||||
    
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    "backlight": {
 | 
			
		||||
        "device": "intel_backlight",
 | 
			
		||||
        "rotate": 0,
 | 
			
		||||
        "format": "{icon}",
 | 
			
		||||
        "format-icons": ["", "", "", ""],
 | 
			
		||||
        "scroll-step": 1,
 | 
			
		||||
        "min-length": 2
 | 
			
		||||
    },
 | 
			
		||||
    
 | 
			
		||||
     "group/expand-2": {
 | 
			
		||||
     "orientation": "horizontal",
 | 
			
		||||
     "drawer": {
 | 
			
		||||
         "transition-duration": 600,
 | 
			
		||||
         "children-class": "not-power",
 | 
			
		||||
       "transition-to-left": true,
 | 
			
		||||
         "click-to-reveal": true
 | 
			
		||||
     },
 | 
			
		||||
     "modules": ["backlight","backlight/slider","custom/smallspacer","custom/led"]
 | 
			
		||||
   },
 | 
			
		||||
   
 | 
			
		||||
    "group/expand-3": {
 | 
			
		||||
     "orientation": "horizontal",
 | 
			
		||||
     "drawer": {
 | 
			
		||||
         "transition-duration": 600,
 | 
			
		||||
         "children-class": "not-power",
 | 
			
		||||
       "transition-to-left": true,
 | 
			
		||||
         "click-to-reveal": true
 | 
			
		||||
     },
 | 
			
		||||
     "modules": ["pulseaudio","pulseaudio/slider"]
 | 
			
		||||
   },
 | 
			
		||||
 | 
			
		||||
    "network": {
 | 
			
		||||
        "tooltip": true,
 | 
			
		||||
        "format-wifi": "{icon} ",
 | 
			
		||||
        "format-icons": ["", "", ""],
 | 
			
		||||
      //  "format-wifi": "<i class='fa-solid fa-wifi-slash'></i>",
 | 
			
		||||
        "rotate": 0,
 | 
			
		||||
        "format-ethernet": " ",
 | 
			
		||||
        "tooltip-format": "Network: <big><b>{essid}</b></big>\nSignal strength: <b>{signaldBm}dBm ({signalStrength}%)</b>\nFrequency: <b>{frequency}MHz</b>\nInterface: <b>{ifname}</b>\nIP: <b>{ipaddr}/{cidr}</b>\nGateway: <b>{gwaddr}</b>\nNetmask: <b>{netmask}</b>",
 | 
			
		||||
        "format-linked": " {ifname} (No IP)",
 | 
			
		||||
        "format-disconnected": " ",
 | 
			
		||||
        "tooltip-format-disconnected": "Disconnected",
 | 
			
		||||
        "on-click": "/usr/local/bin/ags -t ControlPanel",
 | 
			
		||||
        "interval": 2,
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    "pulseaudio": {
 | 
			
		||||
        "format": "{icon}",
 | 
			
		||||
        "rotate": 0,
 | 
			
		||||
        "format-muted": "婢",
 | 
			
		||||
        "tooltip-format": "{icon} {desc} // {volume}%",
 | 
			
		||||
        "scroll-step": 5,
 | 
			
		||||
        "format-icons": {
 | 
			
		||||
            "headphone": "",
 | 
			
		||||
            "hands-free": "",
 | 
			
		||||
            "headset": "",
 | 
			
		||||
            "phone": "",
 | 
			
		||||
            "portable": "",
 | 
			
		||||
            "car": "",
 | 
			
		||||
         "default": ["", "", ""]
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    "pulseaudio#microphone": {
 | 
			
		||||
        "format": "{format_source}",
 | 
			
		||||
        "rotate": 0,
 | 
			
		||||
        "format-source": "",
 | 
			
		||||
        "format-source-muted": "",
 | 
			
		||||
        "on-click": "pavucontrol -t 4",
 | 
			
		||||
        "on-click-middle": "volumecontrol.sh -i m",
 | 
			
		||||
        "on-scroll-up": "volumecontrol.sh -i i",
 | 
			
		||||
        "on-scroll-down": "volumecontrol.sh -i d",
 | 
			
		||||
        "tooltip-format": "{format_source} {source_desc} // {source_volume}%",
 | 
			
		||||
        "scroll-step": 5
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    "custom/notifications": {
 | 
			
		||||
        "tooltip": false,
 | 
			
		||||
        "format": "{icon} {}",
 | 
			
		||||
        "rotate": 0,
 | 
			
		||||
        "format-icons": {
 | 
			
		||||
            "email-notification": "<span foreground='white'><sup></sup></span>",
 | 
			
		||||
            "chat-notification": "<span foreground='white'><sup></sup></span>",
 | 
			
		||||
            "warning-notification": "<span foreground='yellow'><sup></sup></span>",
 | 
			
		||||
            "error-notification": "<span foreground='red'><sup></sup></span>",
 | 
			
		||||
            "network-notification": "<span foreground='white'><sup></sup></span>",
 | 
			
		||||
            "battery-notification": "<span foreground='white'><sup></sup></span>",
 | 
			
		||||
            "update-notification": "<span foreground='white'><sup></sup></span>",
 | 
			
		||||
            "music-notification": "<span foreground='white'><sup></sup></span>",
 | 
			
		||||
            "volume-notification": "<span foreground='white'><sup></sup></span>",
 | 
			
		||||
            "notification": "<span foreground='white'><sup></sup></span>",
 | 
			
		||||
            "none": ""
 | 
			
		||||
        },
 | 
			
		||||
        "return-type": "json",
 | 
			
		||||
        "exec-if": "which dunstctl",
 | 
			
		||||
        "exec": "notifications.py",
 | 
			
		||||
        "on-click": "sleep 0.1 && dunstctl history-pop",
 | 
			
		||||
        "on-click-middle": "dunstctl history-clear",
 | 
			
		||||
        "on-click-right": "dunstctl close-all",
 | 
			
		||||
        "interval": 1,
 | 
			
		||||
        "tooltip": true,
 | 
			
		||||
        "escape": true
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    "custom/keybindhint": {
 | 
			
		||||
        "format": " ",
 | 
			
		||||
        "rotate": 0,
 | 
			
		||||
        "on-click": "keybinds_hint.sh"
 | 
			
		||||
    },
 | 
			
		||||
    
 | 
			
		||||
"custom/expand": {
 | 
			
		||||
        "on-click":"~/.config/hypr/scripts/expand_toolbar",
 | 
			
		||||
        "format":"{}",
 | 
			
		||||
        "exec":"~/.config/hypr/scripts/tools/expand arrow-icon"
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
// modules for padding //
 | 
			
		||||
 | 
			
		||||
    "custom/l_end": {
 | 
			
		||||
        "format": " ",
 | 
			
		||||
        "interval" : "once",
 | 
			
		||||
        "tooltip": false
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    "custom/r_end": {
 | 
			
		||||
        "format": " ",
 | 
			
		||||
        "interval" : "once",
 | 
			
		||||
        "tooltip": false
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    "custom/sl_end": {
 | 
			
		||||
        "format": " ",
 | 
			
		||||
        "interval" : "once",
 | 
			
		||||
        "tooltip": false
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    "custom/sr_end": {
 | 
			
		||||
        "format": " ",
 | 
			
		||||
        "interval" : "once",
 | 
			
		||||
        "tooltip": false
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    "custom/rl_end": {
 | 
			
		||||
        "format": " ",
 | 
			
		||||
        "interval" : "once",
 | 
			
		||||
        "tooltip": false
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    "custom/rr_end": {
 | 
			
		||||
        "format": " ",
 | 
			
		||||
        "interval" : "once",
 | 
			
		||||
        "tooltip": false
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    "custom/padd": {
 | 
			
		||||
        "format": "  ",
 | 
			
		||||
        "interval" : "once",
 | 
			
		||||
        "tooltip": false
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
"backlight/slider": {
 | 
			
		||||
    "min": 5,
 | 
			
		||||
    "max": 100,
 | 
			
		||||
    "rotate": 0,
 | 
			
		||||
    "device": "intel_backlight",
 | 
			
		||||
    "scroll-step": 1,
 | 
			
		||||
  },
 | 
			
		||||
  
 | 
			
		||||
  "pulseaudio/slider": {
 | 
			
		||||
    "min": 5,
 | 
			
		||||
    "max": 100,
 | 
			
		||||
    "rotate": 0,
 | 
			
		||||
    "device": "pulseaudio",
 | 
			
		||||
    "scroll-step": 1,
 | 
			
		||||
  },
 | 
			
		||||
},
 | 
			
		||||
{
 | 
			
		||||
// sourced from header module //
 | 
			
		||||
 | 
			
		||||
  "layer": "top",
 | 
			
		||||
  "position": "top",
 | 
			
		||||
  "mod": "dock",
 | 
			
		||||
  "margin-left": 10,
 | 
			
		||||
  "margin-right": 10,
 | 
			
		||||
  "margin-top": 7,
 | 
			
		||||
  "margin-bottom": 0,
 | 
			
		||||
  "exclusive": true,
 | 
			
		||||
  "passthrough": false,
 | 
			
		||||
  "gtk-layer-shell": true,
 | 
			
		||||
  "reload_style_on_change": true,
 | 
			
		||||
  "output": "HDMI-A-2",
 | 
			
		||||
 | 
			
		||||
// positions generated based on config.ctl //
 | 
			
		||||
 | 
			
		||||
	"modules-left": ["hyprland/workspaces"],
 | 
			
		||||
	"modules-center": ["custom/weather"],
 | 
			
		||||
	"modules-right": ["network"],
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// sourced from modules based on config.ctl //
 | 
			
		||||
  "hyprland/workspaces": {
 | 
			
		||||
	  "format": "{icon}",
 | 
			
		||||
	  "format-icons": {
 | 
			
		||||
	  "default": "",
 | 
			
		||||
	  "active": "",
 | 
			
		||||
	  //"default": "○",
 | 
			
		||||
	  //"default": "●"
 | 
			
		||||
	    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  "custom/weather": {
 | 
			
		||||
    "exec": "python3 ~/.config/waybar/weather.py waybar",
 | 
			
		||||
    "restart-interval": 900,
 | 
			
		||||
    "return-type": "json"
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  "network": {
 | 
			
		||||
    "tooltip": true,
 | 
			
		||||
    "format-wifi": "{icon} ",
 | 
			
		||||
    "format-icons": ["", "", ""],
 | 
			
		||||
    //  "format-wifi": "<i class='fa-solid fa-wifi-slash'></i>",
 | 
			
		||||
    "rotate": 0,
 | 
			
		||||
    "format-ethernet": "{bandwidthTotalBits}  {bandwidthUpBits}  {bandwidthDownBits}   ",
 | 
			
		||||
    "tooltip-format": "Network: <big><b>{essid}</b></big>\nSignal strength: <b>{signaldBm}dBm ({signalStrength}%)</b>\nFrequency: <b>{frequency}MHz</b>\nInterface: <b>{ifname}</b>\nIP: <b>{ipaddr}/{cidr}</b>\nGateway: <b>{gwaddr}</b>\nNetmask: <b>{netmask}</b>",
 | 
			
		||||
    "format-linked": " {ifname} (No IP)",
 | 
			
		||||
    "format-disconnected": " ",
 | 
			
		||||
    "tooltip-format-disconnected": "Disconnected",
 | 
			
		||||
    "on-click": "/usr/local/bin/ags -t ControlPanel",
 | 
			
		||||
    "interval": 1,
 | 
			
		||||
    },
 | 
			
		||||
}]
 | 
			
		||||
							
								
								
									
										42
									
								
								home/hyprland/waybar/configs/cava.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								home/hyprland/waybar/configs/cava.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
# Not my own work. Credit to original author
 | 
			
		||||
 | 
			
		||||
#----- Optimized bars animation without much CPU usage increase --------
 | 
			
		||||
bar="▁▂▃▄▅▆▇█"
 | 
			
		||||
dict="s/;//g"
 | 
			
		||||
 | 
			
		||||
# Calculate the length of the bar outside the loop
 | 
			
		||||
bar_length=${#bar}
 | 
			
		||||
 | 
			
		||||
# Create dictionary to replace char with bar
 | 
			
		||||
for ((i = 0; i < bar_length; i++)); do
 | 
			
		||||
    dict+=";s/$i/${bar:$i:1}/g"
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
# Create cava config
 | 
			
		||||
config_file="/tmp/bar_cava_config"
 | 
			
		||||
cat >"$config_file" <<EOF
 | 
			
		||||
[general]
 | 
			
		||||
# Older systems show significant CPU use with default framerate
 | 
			
		||||
# Setting maximum framerate to 30  
 | 
			
		||||
# You can increase the value if you wish
 | 
			
		||||
framerate = 60
 | 
			
		||||
bars = 14
 | 
			
		||||
 | 
			
		||||
[input]
 | 
			
		||||
method = pulse
 | 
			
		||||
source = auto
 | 
			
		||||
 | 
			
		||||
[output]
 | 
			
		||||
method = raw
 | 
			
		||||
raw_target = /dev/stdout
 | 
			
		||||
data_format = ascii
 | 
			
		||||
ascii_max_range = 7
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
# Kill cava if it's already running
 | 
			
		||||
pkill -f "cava -p $config_file"
 | 
			
		||||
 | 
			
		||||
# Read stdout from cava and perform substitution in a single sed command
 | 
			
		||||
cava -p "$config_file" | sed -u "$dict"
 | 
			
		||||
@@ -1,396 +1,151 @@
 | 
			
		||||
@import "mocha.css";
 | 
			
		||||
 | 
			
		||||
/* -- Global rules -- */
 | 
			
		||||
* {
 | 
			
		||||
    font-family: "JetBrains Mono Nerd Font";
 | 
			
		||||
    /*font-family: "JetBrainsMono Nerd Font";*/
 | 
			
		||||
    font-weight: bold; 
 | 
			
		||||
  border: none;
 | 
			
		||||
  font-family: "JetbrainsMono Nerd Font";
 | 
			
		||||
  font-size: 15px;
 | 
			
		||||
    color: @text;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#custom-notification {
 | 
			
		||||
  font-family: "JetBrains Mono Nerd Font";
 | 
			
		||||
  font-size: 17px;
 | 
			
		||||
  color: #FFFFFF;
 | 
			
		||||
 margin: 2px 0px 0px 0px;
 | 
			
		||||
  min-height: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
window#waybar {
 | 
			
		||||
	background-color: shade(@base, 0.9);
 | 
			
		||||
	border: 2px solid alpha(@crust, 0.3);
 | 
			
		||||
  background: @crust;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
tooltip {
 | 
			
		||||
        background: #171717;
 | 
			
		||||
        color: #A1BDCE;
 | 
			
		||||
        font-size: 13px;
 | 
			
		||||
        border-radius: 7px;
 | 
			
		||||
       border: 2px solid #101a24;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
window#waybar.hidden {
 | 
			
		||||
  opacity: 0.2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* - Genera rules for visible modules -- */
 | 
			
		||||
#media,
 | 
			
		||||
#clock,
 | 
			
		||||
#cpu,
 | 
			
		||||
#memory,
 | 
			
		||||
#disk,
 | 
			
		||||
#temperature,
 | 
			
		||||
#network {
 | 
			
		||||
  color: @crust;
 | 
			
		||||
  margin-top: 6px;
 | 
			
		||||
  margin-bottom: 6px;
 | 
			
		||||
  padding-left: 10px;
 | 
			
		||||
  padding-right: 10px;
 | 
			
		||||
  transition: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Separation to the left */
 | 
			
		||||
#custom-nixicon,
 | 
			
		||||
#cpu {
 | 
			
		||||
  margin-left: 5px;
 | 
			
		||||
  border-top-left-radius: 10px;
 | 
			
		||||
  border-bottom-left-radius: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Separation to the rigth */
 | 
			
		||||
#clock,
 | 
			
		||||
#temperature {
 | 
			
		||||
  margin-right: 20px;
 | 
			
		||||
  border-top-right-radius: 10px;
 | 
			
		||||
  border-bottom-right-radius: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -- Specific styles -- */
 | 
			
		||||
 | 
			
		||||
#custom-nixicon {
 | 
			
		||||
  font-size: 20px;
 | 
			
		||||
  color: @sapphire;
 | 
			
		||||
  background: @overlay1;
 | 
			
		||||
  padding: 0px;
 | 
			
		||||
  padding-right: 15px;
 | 
			
		||||
  padding-left: 10px;
 | 
			
		||||
  margin-top: 6px;
 | 
			
		||||
  margin-bottom: 6px;
 | 
			
		||||
  margin-left: 15px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Hardware Group */
 | 
			
		||||
#clock {
 | 
			
		||||
  background: @yellow;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#cpu {
 | 
			
		||||
  background: @blue;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#memory {
 | 
			
		||||
  background: @red;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#disk {
 | 
			
		||||
  background: @peach;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#temperature {
 | 
			
		||||
  background: @sky;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#network {
 | 
			
		||||
  background: @lavender;
 | 
			
		||||
  padding-right: 13px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Workspace */
 | 
			
		||||
#workspaces {
 | 
			
		||||
background: rgba(23, 23, 23, 0.0);
 | 
			
		||||
    color: #888789;
 | 
			
		||||
    box-shadow: none;
 | 
			
		||||
	text-shadow: none;
 | 
			
		||||
    border-radius: 9px;
 | 
			
		||||
    transition: 0.2s ease;
 | 
			
		||||
    padding-left: 4px;
 | 
			
		||||
    padding-right: 4px;
 | 
			
		||||
    padding-top: 1px;
 | 
			
		||||
  border-radius: 10px;
 | 
			
		||||
  margin: 6px 5px;
 | 
			
		||||
  padding: 0px 6px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#workspaces button {
 | 
			
		||||
background: rgba(23, 23, 23, 0.0);
 | 
			
		||||
    color: #A1BDCE;
 | 
			
		||||
    box-shadow: none;
 | 
			
		||||
	text-shadow: none;
 | 
			
		||||
    border-radius: 9px;
 | 
			
		||||
    transition: 0.2s ease;
 | 
			
		||||
    padding-left: 4px;
 | 
			
		||||
    padding-right: 4px;
 | 
			
		||||
 /*   animation: ws_normal 20s ease-in-out 1; */
 | 
			
		||||
  color: @text;
 | 
			
		||||
  background: transparent;
 | 
			
		||||
  padding: 4px 4px;
 | 
			
		||||
  transition: color 0.3s ease, text-shadow 0.3s ease, transform 0.3s ease;
 | 
			
		||||
  border: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#workspaces button.occupied {
 | 
			
		||||
  color: @red;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#workspaces button.active {
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
  /* background-image: url("/home/anik/Documents/bar1.png");*/
 | 
			
		||||
    color: #FF2A6D;   
 | 
			
		||||
    transition: all 0.3s ease;
 | 
			
		||||
    padding-left: 4px;
 | 
			
		||||
    padding-right: 4px;
 | 
			
		||||
  /*  transition: all 0.4s cubic-bezier(.55,0.68,.48,1.682); */
 | 
			
		||||
  color: @green;
 | 
			
		||||
  text-shadow: 0 0 4px @green;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#workspaces button:hover {
 | 
			
		||||
    background: none;
 | 
			
		||||
    color: #65DC98;
 | 
			
		||||
    animation: ws_hover 20s ease-in-out 1;
 | 
			
		||||
    transition: all 0.5s cubic-bezier(.55,-0.68,.48,1.682);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#taskbar button {
 | 
			
		||||
    box-shadow: none;
 | 
			
		||||
	text-shadow: none;
 | 
			
		||||
	font-size: 4px;
 | 
			
		||||
    padding: 0px;
 | 
			
		||||
    border-radius: 9px;
 | 
			
		||||
    margin-bottom: 3px;
 | 
			
		||||
    margin-left: 0px;
 | 
			
		||||
    padding-left: 3px;
 | 
			
		||||
    padding-right: 3px;
 | 
			
		||||
    margin-right: 0px;
 | 
			
		||||
    color: @wb-color;
 | 
			
		||||
    animation: tb_normal 20s ease-in-out 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#taskbar button.active {
 | 
			
		||||
    background: @wb-act-bg;
 | 
			
		||||
    color: @wb-act-color;
 | 
			
		||||
    margin-left: 3px;
 | 
			
		||||
    padding-left: 12px;
 | 
			
		||||
    padding-right: 12px;
 | 
			
		||||
    margin-right: 3px;
 | 
			
		||||
    animation: tb_active 20s ease-in-out 1;
 | 
			
		||||
    transition: all 0.4s cubic-bezier(.55,-0.68,.48,1.682);
 | 
			
		||||
    min-height: 9px; 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#taskbar button:hover {
 | 
			
		||||
    background: @wb-hvr-bg;
 | 
			
		||||
    color: @wb-hvr-color;
 | 
			
		||||
    animation: tb_hover 20s ease-in-out 1;
 | 
			
		||||
    transition: all 0.3s cubic-bezier(.55,-0.68,.48,1.682);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#tray menu * {
 | 
			
		||||
    min-height: 16px;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
    font-size: 13px;
 | 
			
		||||
    color: #9488e3;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#tray menu separator {
 | 
			
		||||
    min-height: 10px
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#custom-spacer{
 | 
			
		||||
opacity: 0.0;
 | 
			
		||||
}
 | 
			
		||||
#custom-smallspacer{
 | 
			
		||||
opacity: 0.0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#custom-mouse{
 | 
			
		||||
font-size: 14px;
 | 
			
		||||
margin-bottom: 6px;
 | 
			
		||||
background:  #161320;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#custom-power{
 | 
			
		||||
    font-size: 15px;
 | 
			
		||||
    color: #FFFFFF;
 | 
			
		||||
    background:  rgba(22, 19, 32, 0.9);
 | 
			
		||||
    margin: 6px 0px 6px 0px;
 | 
			
		||||
    padding-left: 4px;
 | 
			
		||||
    padding-right: 4px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#backlight{
 | 
			
		||||
    color: #2096C0;
 | 
			
		||||
    background: rgba(23, 23, 23, 0.0);
 | 
			
		||||
    font-weight: normal;
 | 
			
		||||
    font-size: 19px;
 | 
			
		||||
    margin: 1px 0px 0px 0px;
 | 
			
		||||
    padding-left: 0px;
 | 
			
		||||
    padding-right: 2px;
 | 
			
		||||
 
 | 
			
		||||
}
 | 
			
		||||
#bluetooth,
 | 
			
		||||
#custom-cliphist{
 | 
			
		||||
    color: #E6E7E7;
 | 
			
		||||
    background:  #161320;
 | 
			
		||||
    opacity: 1;
 | 
			
		||||
    margin: 4px 0px 4px 0px;
 | 
			
		||||
    padding-left: 4px;
 | 
			
		||||
    padding-right: 4px;
 | 
			
		||||
 
 | 
			
		||||
}
 | 
			
		||||
#battery{
 | 
			
		||||
    font-weight: normal;
 | 
			
		||||
    font-size: 22px;
 | 
			
		||||
    color: #a6d189;
 | 
			
		||||
    background:  rgba(23, 23, 23, 0.0);
 | 
			
		||||
    opacity: 1;
 | 
			
		||||
    margin: 0px 0px 0px 0px;
 | 
			
		||||
    padding-left: 0px;
 | 
			
		||||
    padding-right: 0px;
 | 
			
		||||
 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#idle_inhibitor{
 | 
			
		||||
color: #24966e;
 | 
			
		||||
background: @bar-bg;
 | 
			
		||||
    opacity: 1;
 | 
			
		||||
    margin: 4px 0px 4px 0px;
 | 
			
		||||
    padding-left: 4px;
 | 
			
		||||
    padding-right: 4px;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
#clock{
 | 
			
		||||
    color: #FDD870;
 | 
			
		||||
    font-size: 15px;
 | 
			
		||||
    font-weight: 900;
 | 
			
		||||
    font-family: "JetBrains Mono Nerd Font";
 | 
			
		||||
    background: rgba(23, 23, 23, 0.0);
 | 
			
		||||
    opacity: 1;
 | 
			
		||||
    margin: 3px 0px 0px 0px;
 | 
			
		||||
    padding-left: 10px;
 | 
			
		||||
    padding-right: 10px;
 | 
			
		||||
  color: @teal;
 | 
			
		||||
  border: none;
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
#pulseaudio{
 | 
			
		||||
font-weight: normal;
 | 
			
		||||
font-size: 18px;
 | 
			
		||||
color: #0A9CF5;
 | 
			
		||||
    background:  rgba(22, 19, 32, 0.0);
 | 
			
		||||
    opacity: 1;
 | 
			
		||||
    margin: 0px 0px 0px 0px;
 | 
			
		||||
    padding-left: 3px;
 | 
			
		||||
    padding-right: 3px;
 | 
			
		||||
}
 | 
			
		||||
#cpu{
 | 
			
		||||
font-weight: normal;
 | 
			
		||||
font-size: 22px;
 | 
			
		||||
color: #FF184C;
 | 
			
		||||
}
 | 
			
		||||
#custom-led{
 | 
			
		||||
background: #427287;
 | 
			
		||||
color: #FFFFFF;
 | 
			
		||||
margin-top: 7px;
 | 
			
		||||
margin-bottom: 7px;
 | 
			
		||||
padding-left: 6px;
 | 
			
		||||
border-radius: 7px;
 | 
			
		||||
margin-right: 6px;
 | 
			
		||||
}
 | 
			
		||||
#custom-gpuinfo,
 | 
			
		||||
#custom-keybindhint,
 | 
			
		||||
#language,
 | 
			
		||||
#memory{
 | 
			
		||||
font-weight: normal;
 | 
			
		||||
font-size: 22px;
 | 
			
		||||
color: #1AFE49;
 | 
			
		||||
}
 | 
			
		||||
#mpris{
 | 
			
		||||
color: white;
 | 
			
		||||
animation: repeat;
 | 
			
		||||
	animation-name: blink;
 | 
			
		||||
	animation-duration: 3s;
 | 
			
		||||
    animation-timing-function: linear;
 | 
			
		||||
    animation-iteration-count: infinite;
 | 
			
		||||
    animation-direction: alternate;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@keyframes blink {
 | 
			
		||||
    to {
 | 
			
		||||
        color: #4a4a4a;
 | 
			
		||||
#workspaces button.active:hover {}
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#network{
 | 
			
		||||
color: #FF6E27;
 | 
			
		||||
font-weight: normal;
 | 
			
		||||
font-size: 19px;
 | 
			
		||||
padding-right: 0px;
 | 
			
		||||
padding-left: 4px
 | 
			
		||||
}
 | 
			
		||||
#custom-notifications,
 | 
			
		||||
#custom-spotify,
 | 
			
		||||
#taskbar,
 | 
			
		||||
#custom-theme,
 | 
			
		||||
#custom-menu{
 | 
			
		||||
color: #E8EDF0;
 | 
			
		||||
background:  rgba(23, 23, 23, 0.0);
 | 
			
		||||
margin: 0px 0px 0px 0px;
 | 
			
		||||
    padding-left: 1px;
 | 
			
		||||
    padding-right: 1px;
 | 
			
		||||
    opacity: 0.1
 | 
			
		||||
}
 | 
			
		||||
#tray,
 | 
			
		||||
#custom-updates,
 | 
			
		||||
#custom-wallchange,
 | 
			
		||||
#custom-wbar,
 | 
			
		||||
#window{
 | 
			
		||||
color: #A1BDCE;
 | 
			
		||||
font-family: "Martian Mono";
 | 
			
		||||
}
 | 
			
		||||
#custom-l_end,
 | 
			
		||||
#custom-r_end,
 | 
			
		||||
#custom-sl_end,
 | 
			
		||||
#custom-sr_end,
 | 
			
		||||
#custom-rl_end,
 | 
			
		||||
#cava,
 | 
			
		||||
#upower#headset,
 | 
			
		||||
#upower{
 | 
			
		||||
color: #a6d189;
 | 
			
		||||
}
 | 
			
		||||
#mpris{
 | 
			
		||||
font-size: 15px;
 | 
			
		||||
font-weight: bold
 | 
			
		||||
}
 | 
			
		||||
#custom-rr_end {
 | 
			
		||||
font-weight: normal;
 | 
			
		||||
    color: #E8EDF0;
 | 
			
		||||
    background:  rgba(23, 23, 23, 0.0);
 | 
			
		||||
    opacity: 1;
 | 
			
		||||
    margin: 0px 0px 0px 0px;
 | 
			
		||||
    padding-left: 4px;
 | 
			
		||||
    padding-right: 4px;
 | 
			
		||||
  ;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Media Group */
 | 
			
		||||
#media {
 | 
			
		||||
  background: @overlay2;
 | 
			
		||||
  border-radius: 10px;
 | 
			
		||||
  margin: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#backlight-slider slider,
 | 
			
		||||
#pulseaudio-slider slider {
 | 
			
		||||
  background: #A1BDCE;
 | 
			
		||||
  background-color: transparent;
 | 
			
		||||
  box-shadow: none;
 | 
			
		||||
  margin-right: 7px;
 | 
			
		||||
#custom-cava {
 | 
			
		||||
	color: @green;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#backlight-slider trough,
 | 
			
		||||
#pulseaudio-slider trough {
 | 
			
		||||
  margin-top: -3px;
 | 
			
		||||
  min-width: 90px;
 | 
			
		||||
  min-height: 10px;
 | 
			
		||||
  margin-bottom: -4px;
 | 
			
		||||
  border-radius: 8px;
 | 
			
		||||
  background: #343434;
 | 
			
		||||
#wireplumber, #custom-cava, #mpris {
 | 
			
		||||
    margin-left: 10px;
 | 
			
		||||
    margin-right: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#backlight-slider highlight,
 | 
			
		||||
#pulseaudio-slider highlight {
 | 
			
		||||
  border-radius: 8px;
 | 
			
		||||
  background-color: #2096C0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#battery.charging, #battery.plugged {
 | 
			
		||||
	color: #E8EDF0;
 | 
			
		||||
	
 | 
			
		||||
#wireplumber {
 | 
			
		||||
    margin-right: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#battery.critical:not(.charging) {
 | 
			
		||||
    color: red;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#taskbar {
 | 
			
		||||
    padding: 1px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#custom-r_end {
 | 
			
		||||
    border-radius: 0px 7px 7px 0px;
 | 
			
		||||
    margin-right: 1px;
 | 
			
		||||
    padding-right: 3px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#custom-l_end {
 | 
			
		||||
    border-radius: 7px 0px 0px 7px;
 | 
			
		||||
    margin-left: 1px;
 | 
			
		||||
    padding-left: 3px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#custom-sr_end {
 | 
			
		||||
    border-radius: 0px;
 | 
			
		||||
    margin-right: 1px;
 | 
			
		||||
    padding-right: 3px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#custom-sl_end {
 | 
			
		||||
    border-radius: 0px;
 | 
			
		||||
    margin-left: 1px;
 | 
			
		||||
    padding-left: 3px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#custom-rr_end {
 | 
			
		||||
    border-radius: 0px 7px 7px 0px;
 | 
			
		||||
    margin-right: 1px;
 | 
			
		||||
    padding-right: 3px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#custom-rl_end {
 | 
			
		||||
    border-radius: 7px 0px 0px 7px;
 | 
			
		||||
    margin-left: 1px;
 | 
			
		||||
    padding-left: 3px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Style for launchers */
 | 
			
		||||
 | 
			
		||||
#custom-expand {
 | 
			
		||||
    min-width: 25px;
 | 
			
		||||
    color: #A1BDCE;
 | 
			
		||||
    font-size: 16px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#group-minimized {
 | 
			
		||||
    border-left: solid;
 | 
			
		||||
    border-left-width: 0.5;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#custom-quote {
 | 
			
		||||
  padding-top:0px;
 | 
			
		||||
  color: #999999;
 | 
			
		||||
  font-family: "JetBrains Mono Nerd Font";
 | 
			
		||||
  font-size: 13px;
 | 
			
		||||
/* Weather */ 
 | 
			
		||||
#custom-weather {
 | 
			
		||||
   background: @overlay2;
 | 
			
		||||
   border-radius: 10px;
 | 
			
		||||
   margin: 5px 20px;
 | 
			
		||||
   padding: 0px 10px;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,524 +0,0 @@
 | 
			
		||||
#!nix-shell python3 -p "python3.withPackages (ps: with ps; [requests])"
 | 
			
		||||
 | 
			
		||||
import datetime
 | 
			
		||||
import json
 | 
			
		||||
import requests
 | 
			
		||||
import statistics
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
# TODO
 | 
			
		||||
# - snowfall data
 | 
			
		||||
# - weather warnings
 | 
			
		||||
 | 
			
		||||
### CONSTANTS ###
 | 
			
		||||
 | 
			
		||||
# api key - get it at https://openweathermap.org/
 | 
			
		||||
API_KEY = "bfca28ca110b5595380d9aad164d5ee5"
 | 
			
		||||
 | 
			
		||||
# latitude and longitude of the city you want to query
 | 
			
		||||
# can be obtained through `./weather.py geocoding <city[,state,country]>`
 | 
			
		||||
LATITUDE  = 52.264149
 | 
			
		||||
LONGITUDE = 10.526420
 | 
			
		||||
 | 
			
		||||
# waybar colors
 | 
			
		||||
GRAY   = '#b7c1de'
 | 
			
		||||
DARK   = '#01012b'
 | 
			
		||||
GREEN  = '#65dc98'
 | 
			
		||||
YELLOW = '#ffe69d'
 | 
			
		||||
ORANGE = '#ff6e27'
 | 
			
		||||
RED    = '#ff124f'
 | 
			
		||||
PURPLE = '#7a04eb'
 | 
			
		||||
BLUE   = '#8386f5'
 | 
			
		||||
MOIST  = '#e96d5e'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### UTILITIES ###
 | 
			
		||||
 | 
			
		||||
def print_error(msg: str):
 | 
			
		||||
    '''
 | 
			
		||||
    print an error message with appropriate prefix.
 | 
			
		||||
 | 
			
		||||
    @param str: the message to print
 | 
			
		||||
    '''
 | 
			
		||||
    print('\x1b[90m[\x1b[31merr\x1b[90m]\x1b[0m', msg)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def print_help():
 | 
			
		||||
    '''
 | 
			
		||||
    print help message, to be used for the `--help` flag and as response to
 | 
			
		||||
    incorrect usage
 | 
			
		||||
    '''
 | 
			
		||||
    print('usage: \x1b[33m./weather.py <subcommand> [options]\x1b[0m')
 | 
			
		||||
    print()
 | 
			
		||||
    print('available subcommands:')
 | 
			
		||||
    print(' - \x1b[32mgeocoding\x1b[0m <city[,state][,country]> : search for city to get its coordinates')
 | 
			
		||||
    print(' - \x1b[32mcurrent\x1b[0m                            : print current weather information')
 | 
			
		||||
    print(' - \x1b[32mforecast[-daily]\x1b[0m                   : print forecast for the next ~5 days')
 | 
			
		||||
    print(' - \x1b[32mforecast-detail\x1b[0m                    : print detailed forecast in 3h intervals')
 | 
			
		||||
    print(' - \x1b[32mwaybar\x1b[0m                             : get output for usage with waybar')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def make_request(call: str) -> list | dict:
 | 
			
		||||
    '''
 | 
			
		||||
    make a request to an openweathermap api and returns the response as either
 | 
			
		||||
    a list or a dictionary. the api key is added automatically. quits on error.
 | 
			
		||||
 | 
			
		||||
    @param call: the api path, e.g. `data/2.5/weather?...`
 | 
			
		||||
 | 
			
		||||
    @return response of the api request as a list or dict
 | 
			
		||||
    '''
 | 
			
		||||
    try:
 | 
			
		||||
        req = requests.get(f'https://api.openweathermap.org/{call}&appid={API_KEY}')
 | 
			
		||||
        return req.json()
 | 
			
		||||
    except:
 | 
			
		||||
        print_error(f'failed to make request to `/{call}`')
 | 
			
		||||
        quit(1)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_wind_direction(deg: int) -> str:
 | 
			
		||||
    '''
 | 
			
		||||
    turn a wind direction specified by meteorological degrees into a
 | 
			
		||||
    human-readable form
 | 
			
		||||
 | 
			
		||||
    @param deg: degrees. expected to be in range [0..360]
 | 
			
		||||
 | 
			
		||||
    @return human-readable form (e.g. 'NE' for `deg == 45`)
 | 
			
		||||
    '''
 | 
			
		||||
    if deg < 22.5:  return 'N'
 | 
			
		||||
    if deg < 67.5:  return 'NE'
 | 
			
		||||
    if deg < 112.5: return 'E'
 | 
			
		||||
    if deg < 157.5: return 'SE'
 | 
			
		||||
    if deg < 202.5: return 'S'
 | 
			
		||||
    if deg < 247.5: return 'SW'
 | 
			
		||||
    if deg < 292.5: return 'W'
 | 
			
		||||
    if deg < 337.5: return 'NW'
 | 
			
		||||
    else:           return 'N'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def print_entry(label: str, content: str, indent: int = 0, label_width: int = 8):
 | 
			
		||||
    '''
 | 
			
		||||
    print an 'entry' that consists of a label (printed in gray) and some
 | 
			
		||||
    content. the labels are automatically filled with whitespace to align
 | 
			
		||||
    multiple lines properly.
 | 
			
		||||
 | 
			
		||||
    @param label:       the label of the line
 | 
			
		||||
    @param content:     content, printed after the label
 | 
			
		||||
    @param indent:      number of spaces to indent with
 | 
			
		||||
    @param label_width: width of label
 | 
			
		||||
    '''
 | 
			
		||||
    label_with_whitespace = label.ljust(label_width)
 | 
			
		||||
    print(f'{" " * indent}\x1b[90m{label_with_whitespace}\x1b[0m  {content}')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_weekday(date: str) -> str:
 | 
			
		||||
    '''
 | 
			
		||||
    get weekday from date
 | 
			
		||||
 | 
			
		||||
    @param date: date as ISO-8601-formatted string (YYYY-mm-dd)
 | 
			
		||||
 | 
			
		||||
    @return weekday as lowercase string (e.g. 'monday')
 | 
			
		||||
    '''
 | 
			
		||||
    return datetime.datetime.strptime(date, '%Y-%m-%d').strftime('%A').lower()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def colorize(text: str, color: str) -> str:
 | 
			
		||||
    '''
 | 
			
		||||
    wrap `text` with pango markup to colorize it for usage with waybar.
 | 
			
		||||
 | 
			
		||||
    @param text: the text to colorize
 | 
			
		||||
    @param color: the color as string ('#rrggbb')
 | 
			
		||||
    '''
 | 
			
		||||
    return f'<span foreground="{color}">{text}</span>'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def waybar_entry(label: str, content: str, indent: int = 2, label_width: int = 9):
 | 
			
		||||
    '''
 | 
			
		||||
    create an 'entry' for a waybar tooltip that consists of a label (printed in
 | 
			
		||||
    gray) and some content. the labels are automatically filled with whitespace
 | 
			
		||||
    to align multiple lines properly.
 | 
			
		||||
 | 
			
		||||
    @param label:       the label of the line
 | 
			
		||||
    @param content:     content, printed after the label
 | 
			
		||||
    @param indent:      number of spaces to indent with
 | 
			
		||||
    @param label_width: width of label
 | 
			
		||||
 | 
			
		||||
    @return the entry for use within waybar
 | 
			
		||||
    '''
 | 
			
		||||
 | 
			
		||||
    label_with_whitespace = label.ljust(label_width)
 | 
			
		||||
    return f'{" " * indent}{colorize(label_with_whitespace, GRAY)}  {content}\n'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### GEOCODING ###
 | 
			
		||||
 | 
			
		||||
def geocoding(search: str):
 | 
			
		||||
    '''
 | 
			
		||||
    call openweathermap's geocoding api to find the coordinates of cities. can
 | 
			
		||||
    be used to find the values required for the `LATITUDE` and `LONGITUDE`
 | 
			
		||||
    constants within this script. the results are printed.
 | 
			
		||||
 | 
			
		||||
    @param: search term in the format 'city[,state][,country]'
 | 
			
		||||
    '''
 | 
			
		||||
 | 
			
		||||
    res = make_request(f'geo/1.0/direct?q={search}&limit=5')
 | 
			
		||||
    num_results = len(res)
 | 
			
		||||
 | 
			
		||||
    if (num_results == 0):
 | 
			
		||||
        print_error('no results found')
 | 
			
		||||
    else:
 | 
			
		||||
        print(f'found {num_results} result{"" if num_results == 1 else "s"}:')
 | 
			
		||||
        for entry in res:
 | 
			
		||||
            # obtain data
 | 
			
		||||
            name      = entry['name']
 | 
			
		||||
            state     = entry['state'] if 'state' in entry.keys() else None
 | 
			
		||||
            country   = entry['country']
 | 
			
		||||
            latitude  = entry['lat']
 | 
			
		||||
            longitude = entry['lon']
 | 
			
		||||
 | 
			
		||||
            # print data
 | 
			
		||||
            print(f' - \x1b[32m{name}\x1b[90m',
 | 
			
		||||
                  f'({f"{state}, " if state else ""}{country})\x1b[0m:',
 | 
			
		||||
                  f'latitude = \x1b[35m{latitude}\x1b[0m,',
 | 
			
		||||
                  f'longitude = \x1b[35m{longitude}\x1b[0m')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### CURRENT WEATHER ###
 | 
			
		||||
 | 
			
		||||
def get_current_weather_data() -> dict:
 | 
			
		||||
    '''
 | 
			
		||||
    get current weather data from openweathermap api. when the `rain` is not
 | 
			
		||||
    set (due to there not being any rain), it will be added with a rain amount
 | 
			
		||||
    of 0 mm over the last hour.
 | 
			
		||||
 | 
			
		||||
    @return api response
 | 
			
		||||
    '''
 | 
			
		||||
 | 
			
		||||
    res = make_request(f'data/2.5/weather?lat={LATITUDE}&lon={LONGITUDE}&units=metric')
 | 
			
		||||
 | 
			
		||||
    if 'rain' not in res.keys():
 | 
			
		||||
        res['rain'] = { '1h': 0 }
 | 
			
		||||
 | 
			
		||||
    return res
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def current_weather():
 | 
			
		||||
    '''
 | 
			
		||||
    print current weather information
 | 
			
		||||
    '''
 | 
			
		||||
 | 
			
		||||
    data = get_current_weather_data()
 | 
			
		||||
 | 
			
		||||
    # collect relevant data
 | 
			
		||||
    weather          = data['weather'][0]['description'].lower()
 | 
			
		||||
    temperature      = round(data['main']['temp'], 1)
 | 
			
		||||
    temperature_felt = round(data['main']['feels_like'], 1)
 | 
			
		||||
    humidity         = data['main']['humidity']
 | 
			
		||||
    wind_speed       = round(data['wind']['speed'], 1)
 | 
			
		||||
    wind_direction   = get_wind_direction(data['wind']['deg'])
 | 
			
		||||
    rainfall         = data['rain']['1h']
 | 
			
		||||
 | 
			
		||||
    # print data
 | 
			
		||||
    print_entry('weather',  f'\x1b[32m{weather}\x1b[0m')
 | 
			
		||||
    print_entry('temp',     f'\x1b[33m{temperature} °C\x1b[90m, feels like \x1b[33m{temperature_felt} °C\x1b[0m')
 | 
			
		||||
    print_entry('humidity', f'\x1b[31m{humidity} % RH\x1b[0m')
 | 
			
		||||
    print_entry('wind',     f'\x1b[35m{wind_speed} m/s\x1b[90m ({wind_direction})\x1b[0m')
 | 
			
		||||
    print_entry('rain',     f'\x1b[34m{rainfall} mm\x1b[0m')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### FORECAST ###
 | 
			
		||||
 | 
			
		||||
def get_forecast_data() -> dict:
 | 
			
		||||
    '''
 | 
			
		||||
    get forecast data for the next ~5 days from the openweathermap api, with
 | 
			
		||||
    data points separated by 3 hours. the data is grouped by date (the api does
 | 
			
		||||
    not group the data by default and instead sends it as one sequence).
 | 
			
		||||
 | 
			
		||||
    @return api response grouped by date
 | 
			
		||||
    '''
 | 
			
		||||
 | 
			
		||||
    res = make_request(f'data/2.5/forecast?lat={LATITUDE}&lon={LONGITUDE}&units=metric')
 | 
			
		||||
 | 
			
		||||
    days = dict()
 | 
			
		||||
    for i in res['list']:
 | 
			
		||||
        day = i['dt_txt'].split(' ')[0]
 | 
			
		||||
        if day not in days.keys():
 | 
			
		||||
            days[day] = list()
 | 
			
		||||
        if 'rain' not in i.keys():
 | 
			
		||||
            i['rain'] = { '3h': 0 }
 | 
			
		||||
        days[day].append(i)
 | 
			
		||||
 | 
			
		||||
    return days
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_daily_forecast_data() -> dict[dict]:
 | 
			
		||||
    '''
 | 
			
		||||
    obtain forecast data for the next ~5 days, where values are grouped by day.
 | 
			
		||||
    since the api only provides the data in 3h intervals, the properties of
 | 
			
		||||
    different data points are combined in order to provide appropriate data for
 | 
			
		||||
    each day.
 | 
			
		||||
 | 
			
		||||
    @return the processed data as a dict with key = date and value = data as
 | 
			
		||||
            another dict
 | 
			
		||||
    '''
 | 
			
		||||
 | 
			
		||||
    res = get_forecast_data()
 | 
			
		||||
 | 
			
		||||
    output = dict()
 | 
			
		||||
 | 
			
		||||
    for day in sorted(res):
 | 
			
		||||
        data = res[day]
 | 
			
		||||
        number_of_data_points = len(data)
 | 
			
		||||
 | 
			
		||||
        # collect relevant from data for each day
 | 
			
		||||
        temperatures         = [i['main']['temp'] for i in data]
 | 
			
		||||
        weather_descriptions = [i['weather'][0]['description'].lower() for i in data]
 | 
			
		||||
        humidity             = [i['main']['humidity'] for i in data]
 | 
			
		||||
        rainfall             = [i['rain']['3h'] for i in data]
 | 
			
		||||
        precipitation_prob   = [i['pop'] for i in data]
 | 
			
		||||
        wind_speeds          = [i['wind']['speed'] for i in data]
 | 
			
		||||
        weekday              = get_weekday(day)
 | 
			
		||||
 | 
			
		||||
        # min and max temperature for the day
 | 
			
		||||
        min_temperature = round(min(temperatures))
 | 
			
		||||
        max_temperature = round(max(temperatures))
 | 
			
		||||
 | 
			
		||||
        # obtain the average weather by finding the weather description with the highest number of occurances in `weather_descriptions`
 | 
			
		||||
        weather_count     = {i: weather_descriptions.count(i) for i in set(weather_descriptions)}
 | 
			
		||||
        weather_count_max = max(weather_count.values())
 | 
			
		||||
        weather_average   = tuple(filter(lambda x: weather_count[x] == weather_count_max, weather_count.keys()))[0]
 | 
			
		||||
 | 
			
		||||
        # humidiy
 | 
			
		||||
        humidity_average = round(statistics.mean(humidity))
 | 
			
		||||
 | 
			
		||||
        # total rainfall and probability of precipitation. also, estimate the total rainfall if not all data points for a day are available
 | 
			
		||||
        rainfall_total           = round(sum(rainfall), 1)
 | 
			
		||||
        rainfall_total_estimated = round(rainfall_total / number_of_data_points * 8, 1)
 | 
			
		||||
        max_precipitation_prob   = round(max(precipitation_prob) * 100)
 | 
			
		||||
 | 
			
		||||
        # average wind
 | 
			
		||||
        wind_average = round(statistics.mean(wind_speeds), 1)
 | 
			
		||||
 | 
			
		||||
        output[day] = {
 | 
			
		||||
            'number_of_data_points': number_of_data_points,
 | 
			
		||||
            'min_temperature': min_temperature,
 | 
			
		||||
            'max_temperature': max_temperature,
 | 
			
		||||
            'weather_average': weather_average,
 | 
			
		||||
            'humidity_average': humidity_average,
 | 
			
		||||
            'rainfall_total': rainfall_total,
 | 
			
		||||
            'rainfall_total_estimated': rainfall_total_estimated,
 | 
			
		||||
            'max_precipitation_prob': max_precipitation_prob,
 | 
			
		||||
            'wind_average': wind_average,
 | 
			
		||||
            'weekday': weekday,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    return output
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def daily_forecast():
 | 
			
		||||
    '''
 | 
			
		||||
    print forecast data for the next ~5 days
 | 
			
		||||
    '''
 | 
			
		||||
 | 
			
		||||
    daily_data = get_daily_forecast_data()
 | 
			
		||||
 | 
			
		||||
    for day in sorted(daily_data):
 | 
			
		||||
        data = daily_data[day]
 | 
			
		||||
 | 
			
		||||
        # only display data point if at least half of the data points are available
 | 
			
		||||
        if data['number_of_data_points'] < 4:
 | 
			
		||||
            continue
 | 
			
		||||
 | 
			
		||||
        # print data
 | 
			
		||||
        print(f'\x1b[1m{day}\x1b[0m ({data["weekday"]}):')
 | 
			
		||||
        print_entry('weather',  f'\x1b[32m{data["weather_average"]}\x1b[0m', indent = 2)
 | 
			
		||||
        print_entry('temp',     f'\x1b[33m{data["max_temperature"]} °C\x1b[0m / \x1b[33m{data["min_temperature"]} °C\x1b[0m', indent = 2)
 | 
			
		||||
        print_entry('humidity', f'\x1b[31m{data["humidity_average"]} % RH\x1b[0m', indent = 2)
 | 
			
		||||
        print_entry('wind',     f'\x1b[35m{data["wind_average"]} m/s\x1b[0m', indent = 2)
 | 
			
		||||
        print_entry('rain',     f'\x1b[34m{data["rainfall_total_estimated"]} mm\x1b[0m' +
 | 
			
		||||
                                f'\x1b[90m{f""" ({data["max_precipitation_prob"]}%)""" if data["max_precipitation_prob"] > 0 else ""}' +
 | 
			
		||||
                                f'{f" (estimated)" if data["rainfall_total"] != data["rainfall_total_estimated"] else ""}\x1b[0m\n', indent = 2)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### DETAILED FORECAST ###
 | 
			
		||||
 | 
			
		||||
def detailed_forecast():
 | 
			
		||||
    '''
 | 
			
		||||
    print forecast data for the next ~5 days, where values are printed for
 | 
			
		||||
    every 3h interval provided by the api. some data (e.g. humidity or wind
 | 
			
		||||
    speeds) are omitted.
 | 
			
		||||
    '''
 | 
			
		||||
 | 
			
		||||
    res = get_forecast_data()
 | 
			
		||||
 | 
			
		||||
    for day in sorted(res):
 | 
			
		||||
        weekday = get_weekday(day)
 | 
			
		||||
        print(f'\x1b[1m{day}\x1b[0m ({weekday})')
 | 
			
		||||
 | 
			
		||||
        for entry in res[day]:
 | 
			
		||||
            # collect data
 | 
			
		||||
            weather            = entry['weather'][0]['description'].lower()
 | 
			
		||||
            temperature        = round(entry['main']['temp'], 1)
 | 
			
		||||
            rainfall           = entry['rain']['3h']
 | 
			
		||||
            precipitation_prob = round(entry['pop'] * 100)
 | 
			
		||||
            time               = f"{int(entry['dt_txt'].split(' ')[1].split(':')[0]):2}h"
 | 
			
		||||
 | 
			
		||||
            # print data
 | 
			
		||||
            output = ''
 | 
			
		||||
            output += f'\x1b[33m{temperature:4} °C\x1b[90m, '
 | 
			
		||||
            output += f'\x1b[32m{weather}\x1b[0m'
 | 
			
		||||
            if rainfall > 0:
 | 
			
		||||
                output += f'\x1b[90m: \x1b[34m{rainfall} mm \x1b[90m({precipitation_prob}%)\x1b[0m'
 | 
			
		||||
            print_entry(time, output, indent = 2, label_width = 3)
 | 
			
		||||
 | 
			
		||||
        print()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### WAYBAR ###
 | 
			
		||||
 | 
			
		||||
def waybar_widget(data: dict) -> str:
 | 
			
		||||
    '''
 | 
			
		||||
    get the widget component of the waybar output. contains the current weather
 | 
			
		||||
    group and temperature.
 | 
			
		||||
 | 
			
		||||
    @param current weather data
 | 
			
		||||
 | 
			
		||||
    @return widget component
 | 
			
		||||
    '''
 | 
			
		||||
 | 
			
		||||
    weather = data['weather'][0]['main'].lower()
 | 
			
		||||
    temperature = round(data['main']['temp'])
 | 
			
		||||
 | 
			
		||||
    return f'{colorize(weather, MOIST)} {temperature}°'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def waybar_current(data: dict) -> str:
 | 
			
		||||
    '''
 | 
			
		||||
    get the current weather overview for the tooltip of the waybar output.
 | 
			
		||||
 | 
			
		||||
    @param current weather data
 | 
			
		||||
 | 
			
		||||
    @return formatted current weather overview
 | 
			
		||||
    '''
 | 
			
		||||
 | 
			
		||||
    # retrieve relevant data
 | 
			
		||||
    weather          = data['weather'][0]['description'].lower()
 | 
			
		||||
    temperature      = round(data['main']['temp'], 1)
 | 
			
		||||
    temperature_felt = round(data['main']['feels_like'], 1)
 | 
			
		||||
    humidity         = data['main']['humidity']
 | 
			
		||||
    wind_speed       = round(data['wind']['speed'], 1)
 | 
			
		||||
    wind_direction   = get_wind_direction(data['wind']['deg'])
 | 
			
		||||
    rainfall         = data['rain']['1h']
 | 
			
		||||
 | 
			
		||||
    # generate output
 | 
			
		||||
    output = ''
 | 
			
		||||
    output += waybar_entry('weather',  colorize(weather, YELLOW))
 | 
			
		||||
    output += waybar_entry('temp',     f'{colorize(f"{temperature} °C", ORANGE)}{colorize(", feels like ", GRAY)}{colorize(f"{temperature_felt} °C", ORANGE)}')
 | 
			
		||||
    output += waybar_entry('humidity', colorize(f'{humidity} % RH', RED))
 | 
			
		||||
    output += waybar_entry('wind',     f'{colorize(f"{wind_speed} m/s", PURPLE)} {colorize(f"({wind_direction})", GRAY)}')
 | 
			
		||||
    output += waybar_entry('rain',     colorize(f"{rainfall} mm", BLUE))
 | 
			
		||||
    return output
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def waybar_forecast(data: dict) -> str:
 | 
			
		||||
    '''
 | 
			
		||||
    get the daily forecast for the tooltip of the waybar output.
 | 
			
		||||
 | 
			
		||||
    @param forecast weather data
 | 
			
		||||
 | 
			
		||||
    @return formatted daily forecast
 | 
			
		||||
    '''
 | 
			
		||||
 | 
			
		||||
    output = ''
 | 
			
		||||
 | 
			
		||||
    daily_data = get_daily_forecast_data()
 | 
			
		||||
 | 
			
		||||
    for day in sorted(daily_data):
 | 
			
		||||
        data = daily_data[day]
 | 
			
		||||
 | 
			
		||||
        line_content = colorize(f'{data["max_temperature"]:2}°', ORANGE) + \
 | 
			
		||||
                       colorize(' / ', GRAY) + \
 | 
			
		||||
                       colorize(f'{data["min_temperature"]:2}°', ORANGE) + \
 | 
			
		||||
                       colorize(', ', GRAY) + \
 | 
			
		||||
                       colorize(data['weather_average'], YELLOW)
 | 
			
		||||
 | 
			
		||||
        if data['rainfall_total_estimated'] > 0:
 | 
			
		||||
            line_content += colorize(': ', GRAY) + \
 | 
			
		||||
                            colorize(f'{data["rainfall_total_estimated"]} mm ', BLUE) + \
 | 
			
		||||
                            colorize(f'({data["max_precipitation_prob"]}%)', GRAY)
 | 
			
		||||
 | 
			
		||||
        output += waybar_entry(data['weekday'], line_content)
 | 
			
		||||
 | 
			
		||||
    return output.rstrip()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def waybar():
 | 
			
		||||
    '''
 | 
			
		||||
    get current and forecast weather data and output it formatted in a way that
 | 
			
		||||
    allows it to be included as a widget in waybar. only shows weather category
 | 
			
		||||
    and temperature in the widget, but reveals detailed weather information and
 | 
			
		||||
    a ~5 day forecast in the tooltip.
 | 
			
		||||
    '''
 | 
			
		||||
 | 
			
		||||
    current_data = get_current_weather_data()
 | 
			
		||||
    forecast_data = get_forecast_data()
 | 
			
		||||
 | 
			
		||||
    widget = waybar_widget(current_data)
 | 
			
		||||
    current = waybar_current(current_data)
 | 
			
		||||
    forecast = waybar_forecast(forecast_data)
 | 
			
		||||
    tooltip = colorize('current weather', GREEN) + '\n' + current + '\n' + \
 | 
			
		||||
              colorize('forecast', GREEN) + '\n' + forecast
 | 
			
		||||
 | 
			
		||||
    print(json.dumps({
 | 
			
		||||
        'text': widget,
 | 
			
		||||
        'tooltip': tooltip,
 | 
			
		||||
    }))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### MAIN ###
 | 
			
		||||
 | 
			
		||||
def main():
 | 
			
		||||
    '''
 | 
			
		||||
    main function
 | 
			
		||||
    '''
 | 
			
		||||
 | 
			
		||||
    # no parameters or `--help`
 | 
			
		||||
    if len(sys.argv) == 1 or sys.argv[1] in ('help', '-h', '--help'):
 | 
			
		||||
        print_help()
 | 
			
		||||
 | 
			
		||||
    # >= 1 parameter provided
 | 
			
		||||
    else:
 | 
			
		||||
        # geocoding
 | 
			
		||||
        if sys.argv[1] == 'geocoding':
 | 
			
		||||
            if len(sys.argv) == 3:
 | 
			
		||||
                geocoding(sys.argv[2])
 | 
			
		||||
            else:
 | 
			
		||||
                print_error('expected argument `<city[,state][,country]>`')
 | 
			
		||||
                print_help()
 | 
			
		||||
        # constants not set
 | 
			
		||||
        elif API_KEY is None or LATITUDE is None or LONGITUDE is None:
 | 
			
		||||
            print_error('please modify the constants within the script before use.')
 | 
			
		||||
        # current weather
 | 
			
		||||
        elif sys.argv[1] == 'current':
 | 
			
		||||
            current_weather()
 | 
			
		||||
        # daily forecast
 | 
			
		||||
        elif sys.argv[1] == 'forecast' or sys.argv[1] == 'forecast-daily':
 | 
			
		||||
            daily_forecast()
 | 
			
		||||
        # detailed forecast
 | 
			
		||||
        elif sys.argv[1] == 'forecast-detail':
 | 
			
		||||
            detailed_forecast()
 | 
			
		||||
        # waybar
 | 
			
		||||
        elif sys.argv[1] == 'waybar':
 | 
			
		||||
            waybar()
 | 
			
		||||
        # unknown command
 | 
			
		||||
        else:
 | 
			
		||||
            print_error(f'unknown command `{sys.argv[1]}`')
 | 
			
		||||
            print_help()
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    main()
 | 
			
		||||
 | 
			
		||||
@@ -1,44 +1,11 @@
 | 
			
		||||
{
 | 
			
		||||
  pkgs,
 | 
			
		||||
  config,
 | 
			
		||||
  ...
 | 
			
		||||
}:
 | 
			
		||||
{
 | 
			
		||||
  programs.waybar = {
 | 
			
		||||
    enable = true;
 | 
			
		||||
    package = pkgs.waybar;
 | 
			
		||||
    /*
 | 
			
		||||
      settings = {
 | 
			
		||||
          mainBar = {
 | 
			
		||||
              layer = "top";
 | 
			
		||||
              position = "top";
 | 
			
		||||
              height = 30;
 | 
			
		||||
              output = [
 | 
			
		||||
                  "eDP-1"
 | 
			
		||||
                  "DP-1"
 | 
			
		||||
                  "HDMI-A-1"
 | 
			
		||||
                  "Virtual-1"
 | 
			
		||||
              ];
 | 
			
		||||
 | 
			
		||||
              modules-left = [ "sway/workspaces" "sway/mode" "wlr/taskbar" ];
 | 
			
		||||
              modules-center = [ "sway/window" "custom/hello-from-waybar" ];
 | 
			
		||||
              modules-right = [ "mpd" "custom/mymodule#with-css-id" "temperature" ];
 | 
			
		||||
 | 
			
		||||
              "sway/workspaces" = {
 | 
			
		||||
                  disable-scroll = true;
 | 
			
		||||
                  all-outputs = true;
 | 
			
		||||
              };
 | 
			
		||||
              "custom/hello-from-waybar" = {
 | 
			
		||||
                  format = "hello {}";
 | 
			
		||||
                  max-length = 40;
 | 
			
		||||
                  interval = "once";
 | 
			
		||||
                  exec = pkgs.writeShellScript "hello-from-waybar" ''
 | 
			
		||||
                      echo "from within waybar $USER"
 | 
			
		||||
                  '';
 | 
			
		||||
              };
 | 
			
		||||
          };
 | 
			
		||||
      };
 | 
			
		||||
    */
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  home.file.".config/waybar" = {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,188 +1,42 @@
 | 
			
		||||
let
 | 
			
		||||
  common = import ./common.nix;
 | 
			
		||||
  hyprland = import ./hyprland.nix;
 | 
			
		||||
in
 | 
			
		||||
{
 | 
			
		||||
  enable = true;
 | 
			
		||||
  settings = {
 | 
			
		||||
    mainBar = {
 | 
			
		||||
    mainBar =
 | 
			
		||||
      {
 | 
			
		||||
        layer = "top";
 | 
			
		||||
        position = "top";
 | 
			
		||||
        height = 30;
 | 
			
		||||
        output = [ "DP-1" ];
 | 
			
		||||
 | 
			
		||||
        modules-left = [
 | 
			
		||||
        "hyprland/workspaces"
 | 
			
		||||
        "mpris"
 | 
			
		||||
      ];
 | 
			
		||||
 | 
			
		||||
      modules-center = [ ];
 | 
			
		||||
 | 
			
		||||
      modules-right = [
 | 
			
		||||
        "network"
 | 
			
		||||
        "memory"
 | 
			
		||||
        "cpu"
 | 
			
		||||
          "custom/nixicon"
 | 
			
		||||
          "clock"
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
      # Widgets
 | 
			
		||||
      "sway/workspaces" = {
 | 
			
		||||
        disable-scroll = true;
 | 
			
		||||
        all-outputs = true;
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      mpris = {
 | 
			
		||||
        format = "{player_icon} {dynamic}";
 | 
			
		||||
        format-paused = "<span color='grey'>{status_icon} {dynamic}</span>";
 | 
			
		||||
        max-length = 100;
 | 
			
		||||
 | 
			
		||||
        player-icons = {
 | 
			
		||||
          default = "⏸";
 | 
			
		||||
          mpv = "🎵";
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        status-icons = {
 | 
			
		||||
          paused = "▶";
 | 
			
		||||
        };
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      "hyprland/workspaces" = {
 | 
			
		||||
        format = "{icon}";
 | 
			
		||||
        format-icons = {
 | 
			
		||||
          default = "";
 | 
			
		||||
          active = "";
 | 
			
		||||
        };
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      network = {
 | 
			
		||||
        tooltip = true;
 | 
			
		||||
        format-wifi = "{icon} ";
 | 
			
		||||
        format-icons = [
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
        modules-center = [
 | 
			
		||||
          "hyprland/workspaces"
 | 
			
		||||
        ];
 | 
			
		||||
        rotate = 0;
 | 
			
		||||
        format-ethernet = " ";
 | 
			
		||||
        tooltip-format = "Network: <big><b>{essid}</b></big>\nSignal strength: <b>{signaldBm}dBm ({signalStrength}%)</b>\nFrequency: <b>{frequency}MHz</b>\nInterface: <b>{ifname}</b>\nIP: <b>{ipaddr}/{cidr}</b>\nGateway: <b>{gwaddr}</b>\nNetmask: <b>{netmask}</b>";
 | 
			
		||||
        format-linked = " {ifname} (No IP)";
 | 
			
		||||
        format-disconnected = " ";
 | 
			
		||||
        tooltip-format-disconnected = "Disconnected";
 | 
			
		||||
        on-click = "/usr/local/bin/ags -t ControlPanel";
 | 
			
		||||
        interval = 2;
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      memory = {
 | 
			
		||||
        interval = 1;
 | 
			
		||||
        rotate = 270;
 | 
			
		||||
        format = "{icon}";
 | 
			
		||||
        format-icons = [
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
        modules-right = [
 | 
			
		||||
          "group/hardware"
 | 
			
		||||
        ];
 | 
			
		||||
        max-length = 10;
 | 
			
		||||
      };
 | 
			
		||||
      }
 | 
			
		||||
      // common.widgets
 | 
			
		||||
      // hyprland.widgets;
 | 
			
		||||
 | 
			
		||||
      cpu = {
 | 
			
		||||
        interval = 1;
 | 
			
		||||
        format = "{icon}";
 | 
			
		||||
        rotate = 270;
 | 
			
		||||
        format-icons = [
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
        ];
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      clock = {
 | 
			
		||||
        format = "{:%I:%M %p}";
 | 
			
		||||
        rotate = 0;
 | 
			
		||||
        on-click = "/usr/local/bin/ags -t ActivityCenter";
 | 
			
		||||
        tooltip-format = "<tt>{calendar}</tt>";
 | 
			
		||||
 | 
			
		||||
        calendar = {
 | 
			
		||||
          mode = "month";
 | 
			
		||||
          mode-mon-col = 3;
 | 
			
		||||
          on-scroll = 1;
 | 
			
		||||
          on-click-right = "mode";
 | 
			
		||||
          format = {
 | 
			
		||||
            months = "<span color='#ffead3'><b>{}</b></span>";
 | 
			
		||||
            weekdays = "<span color='#ffcc66'><b>{}</b></span>";
 | 
			
		||||
            today = "<span color='#ff6699'><b>{}</b></span>";
 | 
			
		||||
          };
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        actions = {
 | 
			
		||||
          on-click-right = "mode";
 | 
			
		||||
          on-click-forward = "tz_up";
 | 
			
		||||
          on-click-backward = "tz_down";
 | 
			
		||||
          on-scroll-up = "shift_up";
 | 
			
		||||
          on-scroll-down = "shift_down";
 | 
			
		||||
        };
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    secondBar = {
 | 
			
		||||
    secondBar =
 | 
			
		||||
      {
 | 
			
		||||
        layer = "top";
 | 
			
		||||
        position = "top";
 | 
			
		||||
        height = 30;
 | 
			
		||||
      output = [
 | 
			
		||||
        "HDMI-A-2"
 | 
			
		||||
      ];
 | 
			
		||||
 | 
			
		||||
      modules-left = [
 | 
			
		||||
        "hyprland/workspaces"
 | 
			
		||||
      ];
 | 
			
		||||
 | 
			
		||||
      modules-center = [
 | 
			
		||||
      ];
 | 
			
		||||
 | 
			
		||||
      modules-right = [
 | 
			
		||||
        "network"
 | 
			
		||||
      ];
 | 
			
		||||
 | 
			
		||||
      "hyprland/workspaces" = {
 | 
			
		||||
        format = "{icon}";
 | 
			
		||||
        format-icons = {
 | 
			
		||||
          default = "";
 | 
			
		||||
          active = "";
 | 
			
		||||
        };
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      "custom/weather" = {
 | 
			
		||||
        exec = "~/.config/waybar/weather.py waybar";
 | 
			
		||||
        restart-interval = 900;
 | 
			
		||||
        return-type = "json";
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      network = {
 | 
			
		||||
        tooltip = true;
 | 
			
		||||
        format-wifi = "{icon} ";
 | 
			
		||||
        format-icons = [
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
        ];
 | 
			
		||||
        rotate = 0;
 | 
			
		||||
        format-ethernet = "{bandwidthTotalBits}  {bandwidthUpBits}  {bandwidthDownBits}   ";
 | 
			
		||||
        tooltip-format = "Network: <big><b>{essid}</b></big>\nSignal strength: <b>{signaldBm}dBm ({signalStrength}%)</b>\nFrequency: <b>{frequency}MHz</b>\nInterface: <b>{ifname}</b>\nIP: <b>{ipaddr}/{cidr}</b>\nGateway: <b>{gwaddr}</b>\nNetmask: <b>{netmask}</b>";
 | 
			
		||||
        format-linked = " {ifname} (No IP)";
 | 
			
		||||
        format-disconnected = " ";
 | 
			
		||||
        tooltip-format-disconnected = "Disconnected";
 | 
			
		||||
        on-click = "/usr/local/bin/ags -t ControlPanel";
 | 
			
		||||
        interval = 2;
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
        output = [ "HDMI-A-2" ];
 | 
			
		||||
        modules-left = [ "group/media" ];
 | 
			
		||||
        modules-center = [ "hyprland/workspaces" ];
 | 
			
		||||
        modules-right = [ "custom/weather" ];
 | 
			
		||||
      }
 | 
			
		||||
      // common.widgets
 | 
			
		||||
      // hyprland.widgets;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								home/hyprland/waybar/hyprland.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								home/hyprland/waybar/hyprland.nix
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
{
 | 
			
		||||
  widgets = {
 | 
			
		||||
    "hyprland/workspaces" = {
 | 
			
		||||
      format = "{icon}";
 | 
			
		||||
      format-icons = {
 | 
			
		||||
        default = "";
 | 
			
		||||
        active = "";
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
@@ -1,150 +1,39 @@
 | 
			
		||||
let
 | 
			
		||||
  common = import ./common.nix;
 | 
			
		||||
  hyprland = import ./hyprland.nix;
 | 
			
		||||
in
 | 
			
		||||
{
 | 
			
		||||
  enable = true;
 | 
			
		||||
  settings = {
 | 
			
		||||
    mainBar = {
 | 
			
		||||
    mainBar =
 | 
			
		||||
      {
 | 
			
		||||
        layer = "top";
 | 
			
		||||
        position = "top";
 | 
			
		||||
        height = 30;
 | 
			
		||||
        /*
 | 
			
		||||
          Waybar should use every display available if not output is specified
 | 
			
		||||
          output = [
 | 
			
		||||
            "eDP-1"
 | 
			
		||||
            "DP-1"
 | 
			
		||||
            "HDMI-A-1"
 | 
			
		||||
            "Virtual-1"
 | 
			
		||||
          ];
 | 
			
		||||
 | 
			
		||||
        */
 | 
			
		||||
        modules-left = [
 | 
			
		||||
        "hyprland/workspaces"
 | 
			
		||||
        "mpris"
 | 
			
		||||
      ];
 | 
			
		||||
 | 
			
		||||
      modules-center = [
 | 
			
		||||
        "custom/weather"
 | 
			
		||||
      ];
 | 
			
		||||
 | 
			
		||||
      modules-right = [
 | 
			
		||||
        "network"
 | 
			
		||||
        "memory"
 | 
			
		||||
        "cpu"
 | 
			
		||||
          "custom/nixicon"
 | 
			
		||||
          "clock"
 | 
			
		||||
          "group/media"
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
      # Widgets
 | 
			
		||||
      "sway/workspaces" = {
 | 
			
		||||
        disable-scroll = true;
 | 
			
		||||
        all-outputs = true;
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      mpris = {
 | 
			
		||||
        format = "{player_icon} {dynamic}";
 | 
			
		||||
        format-paused = "<span color='grey'>{status_icon} {dynamic}</span>";
 | 
			
		||||
        max-length = 100;
 | 
			
		||||
 | 
			
		||||
        player-icons = {
 | 
			
		||||
          default = "⏸";
 | 
			
		||||
          mpv = "🎵";
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        status-icons = {
 | 
			
		||||
          paused = "▶";
 | 
			
		||||
        };
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      "hyprland/workspaces" = {
 | 
			
		||||
        format = "{icon}";
 | 
			
		||||
        format-icons = {
 | 
			
		||||
          default = "";
 | 
			
		||||
          active = "";
 | 
			
		||||
        };
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      network = {
 | 
			
		||||
        tooltip = true;
 | 
			
		||||
        format-wifi = "{icon} ";
 | 
			
		||||
        format-icons = [
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
        modules-center = [
 | 
			
		||||
          "hyprland/workspaces"
 | 
			
		||||
        ];
 | 
			
		||||
        rotate = 0;
 | 
			
		||||
        format-ethernet = " ";
 | 
			
		||||
        tooltip-format = "Network = <big><b>{essid}</b></big>\nSignal strength: <b>{signaldBm}dBm ({signalStrength}%)</b>\nFrequency: <b>{frequency}MHz</b>\nInterface: <b>{ifname}</b>\nIP: <b>{ipaddr}/{cidr}</b>\nGateway: <b>{gwaddr}</b>\nNetmask: <b>{netmask}</b>";
 | 
			
		||||
        format-linked = " {ifname} (No IP)";
 | 
			
		||||
        format-disconnected = " ";
 | 
			
		||||
        tooltip-format-disconnected = "Disconnected";
 | 
			
		||||
        on-click = "/usr/local/bin/ags -t ControlPanel";
 | 
			
		||||
        interval = 2;
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      memory = {
 | 
			
		||||
        interval = 1;
 | 
			
		||||
        rotate = 270;
 | 
			
		||||
        format = "{icon}";
 | 
			
		||||
        format-icons = [
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
        modules-right = [
 | 
			
		||||
          "custom/weather"
 | 
			
		||||
          "group/hardware"
 | 
			
		||||
        ];
 | 
			
		||||
        max-length = 10;
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      cpu = {
 | 
			
		||||
        interval = 1;
 | 
			
		||||
        format = "{icon}";
 | 
			
		||||
        rotate = 270;
 | 
			
		||||
        format-icons = [
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
          ""
 | 
			
		||||
        ];
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      clock = {
 | 
			
		||||
        format = "{:%I:%M %p}";
 | 
			
		||||
        rotate = 0;
 | 
			
		||||
        on-click = "/usr/local/bin/ags -t ActivityCenter";
 | 
			
		||||
        tooltip-format = "<tt>{calendar}</tt>";
 | 
			
		||||
 | 
			
		||||
        calendar = {
 | 
			
		||||
          mode = "month";
 | 
			
		||||
          mode-mon-col = 3;
 | 
			
		||||
          on-scroll = 1;
 | 
			
		||||
          on-click-right = "mode";
 | 
			
		||||
          format = {
 | 
			
		||||
            months = "<span color='#ffead3'><b>{}</b></span>";
 | 
			
		||||
            weekdays = "<span color='#ffcc66'><b>{}</b></span>";
 | 
			
		||||
            today = "<span color='#ff6699'><b>{}</b></span>";
 | 
			
		||||
          };
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        actions = {
 | 
			
		||||
          on-click-right = "mode";
 | 
			
		||||
          on-click-forward = "tz_up";
 | 
			
		||||
          on-click-backward = "tz_down";
 | 
			
		||||
          on-scroll-up = "shift_up";
 | 
			
		||||
          on-scroll-down = "shift_down";
 | 
			
		||||
        };
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      # Custom Widgets
 | 
			
		||||
      "custom/weather" = {
 | 
			
		||||
        exec = "python3 ~/.config/waybar/weather.py waybar";
 | 
			
		||||
        restart-interval = 900;
 | 
			
		||||
        return-type = "json";
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
        # Widget configurations
 | 
			
		||||
      }
 | 
			
		||||
      // common.widgets
 | 
			
		||||
      // hyprland.widgets;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user