Reorganized

This commit is contained in:
Tyler Mayoff 2025-02-15 10:55:48 -05:00
parent 4cd0255ba4
commit e42e996e75
21 changed files with 2397 additions and 965 deletions

View file

@ -0,0 +1,218 @@
{...}: let
mod = "Mod4";
term = "kitty";
menu = "wmenu-run";
in {
wayland.windowManager.sway = {
enable = true;
checkConfig = true;
config = rec {
output."*" = {
scale = "1";
# bg = "${image} fill";
};
startup = [
# {command = "swaybg -i .config/flake/wallpaper.jpg";}
];
# Home row direction keys, like vim
up = "k";
left = "h";
down = "j";
right = "l";
### Idle configuration
#
# Example configuration:
#
# exec swayidle -w \
# timeout 300 'swaylock -f -c 000000' \
# timeout 600 'swaymsg "output * power off"' resume 'swaymsg "output * power on"' \
# before-sleep 'swaylock -f -c 000000'
#
# This will lock your screen after 300 seconds of inactivity, then turn off
# your displays after another 300 seconds, and turn your screens back on when
# resumed. It will also lock your screen before your computer goes to sleep.
### Input configuration
#
# Example configuration:
#
# input "2:14:SynPS/2_Synaptics_TouchPad" {
# dwt enabled
# tap enabled
# natural_scroll enabled
# middle_emulation enabled
# }
#
# You can get the names of your inputs by running: swaymsg -t get_inputs
# Read `man 5 sway-input` for more information about this section.
input = {
"*" = {
tap = "enabled";
natural_scroll = "enabled";
};
};
keybindings = {
### Key bindings
#
# Basics:
# Start a terminal
"${mod}+Return" = "exec ${term}";
# Kill focused window
"${mod}+q" = "kill";
# Start launcher
"${mod}+d" = "exec ${menu}";
# Reload the configuration file
"${mod}+Shift+c" = "reload";
"${mod}+r" = "mode resize";
#### Moving around:
# Move your focus around
"${mod}+Left" = "focus left";
"${mod}+Down" = "focus down";
"${mod}+Up" = "focus up";
"${mod}+Right" = "focus right";
# Exit sway (logs you out of your Wayland session)
"${mod}+Shift+e" = "exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -B 'Yes, exit sway' 'swaymsg exit'";
## Window
# Move the focused window with the same, but add Shift
"${mod}+Shift+${left}" = "move left";
"${mod}+Shift+${down}" = "move down";
"${mod}+Shift+${up}" = "move up";
"${mod}+Shift+${right}" = "move right";
# Ditto, with arrow keys
"${mod}+Shift+Left" = "move left";
"${mod}+Shift+Down" = "move down";
"${mod}+Shift+Up" = "move up";
"${mod}+Shift+Right" = "move right";
## Workspaces
# Switch to workspace
"${mod}+1" = "workspace number 1";
"${mod}+2" = "workspace number 2";
"${mod}+3" = "workspace number 3";
"${mod}+4" = "workspace number 4";
"${mod}+5" = "workspace number 5";
"${mod}+6" = "workspace number 6";
"${mod}+7" = "workspace number 7";
"${mod}+8" = "workspace number 8";
"${mod}+9" = "workspace number 9";
"${mod}+0" = "workspace number 10";
# Move focused container to workspace
"${mod}+Shift+1" = "move container to workspace number 1";
"${mod}+Shift+2" = "move container to workspace number 2";
"${mod}+Shift+3" = "move container to workspace number 3";
"${mod}+Shift+4" = "move container to workspace number 4";
"${mod}+Shift+5" = "move container to workspace number 5";
"${mod}+Shift+6" = "move container to workspace number 6";
"${mod}+Shift+7" = "move container to workspace number 7";
"${mod}+Shift+8" = "move container to workspace number 8";
"${mod}+Shift+9" = "move container to workspace number 9";
"${mod}+Shift+0" = "move container to workspace number 10";
## Layout
# You can "split" the current object of your focus with
# $mod+b or $mod+v, for horizontal and vertical splits
# respectively.
"${mod}+b" = "splith";
"${mod}+v" = "splitv";
# Switch the current container between different layout styles
"${mod}+s" = "layout stacking";
"${mod}+w" = "layout tabbed";
"${mod}+e" = "layout toggle split";
# Make the current focus fullscreen
"${mod}+f" = "fullscreen";
};
# Drag floating windows by holding down $mod and left mouse button.
# Resize them with right mouse button + $mod.
# Despite the name, also works for non-floating windows.
# Change normal to inverse to use left mouse button for resizing and right
# mouse button for dragging.
# floating_modifier $mod normal
# # Layout stuff:
# #
# # Toggle the current focus between tiling and floating mode
# bindsym $mod+Shift+space floating toggle
# # Swap focus between the tiling area and the floating area
# bindsym $mod+space focus mode_toggle
# # Move focus to the parent container
# bindsym $mod+a focus parent
# #
# # Scratchpad:
# #
# # Sway has a "scratchpad", which is a bag of holding for windows.
# # You can send windows there and get them back later.
# # Move the currently focused window to the scratchpad
# bindsym $mod+Shift+minus move scratchpad
# # Show the next scratchpad window or hide the focused scratchpad window.
# # If there are multiple scratchpad windows, this command cycles through them.
# bindsym $mod+minus scratchpad show
# #
# # Resizing containers:
# #
# mode "resize" {
# # left will shrink the containers width
# # right will grow the containers width
# # up will shrink the containers height
# # down will grow the containers height
# bindsym $left resize shrink width 10px
# bindsym $down resize grow height 10px
# bindsym $up resize shrink height 10px
# bindsym $right resize grow width 10px
# # Ditto, with arrow keys
# bindsym Left resize shrink width 10px
# bindsym Down resize grow height 10px
# bindsym Up resize shrink height 10px
# bindsym Right resize grow width 10px
# # Return to default mode
# bindsym Return mode "default"
# bindsym Escape mode "default"
# }
# #
# # Utilities:
# #
# # Special keys to adjust volume via PulseAudio
# bindsym --locked XF86AudioMute exec pactl set-sink-mute \@DEFAULT_SINK@ toggle
# bindsym --locked XF86AudioLowerVolume exec pactl set-sink-volume \@DEFAULT_SINK@ -5%
# bindsym --locked XF86AudioRaiseVolume exec pactl set-sink-volume \@DEFAULT_SINK@ +5%
# bindsym --locked XF86AudioMicMute exec pactl set-source-mute \@DEFAULT_SOURCE@ toggle
# # Special keys to adjust brightness via brightnessctl
# bindsym --locked XF86MonBrightnessDown exec brightnessctl set 5%-
# bindsym --locked XF86MonBrightnessUp exec brightnessctl set 5%+
# # Special key to take a screenshot with grim
# bindsym Print exec grim
bars = [
{
command = "waybar";
position = "top";
}
];
};
};
}

View file

@ -1,968 +1,14 @@
{ {pkgs, ...}: {
config, imports = [
pkgs, ../stylix.nix
... ../common.nix
}: let
mod = "Mod4";
term = "kitty";
menu = "wmenu-run";
image = pkgs.fetchurl {
url = "https://www.pixelstalk.net/wp-content/uploads/image11/Get-Glittery-blue-4K-wallpaper-with-a-calm-cool-sparkle.jpg";
sha256 = "sha256-inZkyQsiF+aqgj2IK2AKN9STYLJBzG+QQCzw/X7cdcw=";
};
in {
imports = [../stylix.nix ../common.nix ../gnome.nix ../home-backup.nix ../gui.nix];
programs.waybar = { ../waybar/mechabar
enable = true; ../sway
style = ''
@define-color main-fg #cdd6f4;
@define-color main-bg #11111b;
@define-color main-br #cdd6f4;
@define-color active-bg #9399b2; ../home-backup.nix
@define-color active-fg #11111b; ../gui.nix
@define-color hover-bg #313244;
@define-color hover-fg rgba(205, 214, 244, 0.75);
@define-color white #ffffff;
@define-color black #000000;
/* Module Colors */
@define-color module-fg #f5e0dc;
@define-color workspaces #181825;
@define-color cpuinfo #181825;
@define-color memory #1e1e2e;
@define-color cpu #313244;
@define-color distro-fg #000000;
@define-color distro-bg #9399b2;
@define-color time #313244;
@define-color date #1e1e2e;
@define-color tray #181825;
@define-color pulseaudio #181825;
@define-color backlight #1e1e2e;
@define-color battery #313244;
@define-color power #9399b2;
/* State Colors */
@define-color warning #f9e2af;
@define-color critical #f38ba8;
@define-color charging #cdd6f4;
* {
font-size: 15px;
font-family: "JetBrainsMono Nerd Font";
font-weight: bold;
min-height: 0;
padding: 0;
border: none;
margin: 0;
}
window#waybar {
background: @main-bg;
}
window#waybar > box {
background-color: transparent;
box-shadow: 0 0 2px 1px rgba(0, 0, 0, 1);
margin: 2px;
}
/* === Tooltip === */
tooltip {
background: @main-bg;
border: solid;
border-width: 1.5px;
border-radius: 8px;
border-color: @main-br;
}
tooltip label {
color: @main-fg;
font-weight: normal;
margin: -1.5px 3px;
}
/* === Workspace Buttons === */
#workspaces button {
color: @main-fg;
border-radius: 8px;
box-shadow: none;
margin: 2px 0;
padding: 0 2px;
transition: none;
}
#workspaces button:hover {
color: @hover-fg;
background: @hover-bg;
text-shadow: none;
box-shadow: none;
}
#workspaces button.active {
color: @active-fg;
background: @hover-bg;
text-shadow: 0 0 2px rgba(0, 0, 0, 0.6);
box-shadow: 0 0 2px 1px rgba(0, 0, 0, 0.4);
margin: 2px;
padding: 0 6px;
}
/* === General === */
#custom-ws,
#workspaces,
#window,
#custom-cpuinfo,
#memory,
/* #custom-cpu, */
#cpu,
#idle_inhibitor,
#clock,
#custom-wifi,
#bluetooth,
#custom-update,
#custom-media,
#pulseaudio,
/* #custom-backlight, */
#backlight,
#battery,
#custom-power {
opacity: 1;
color: @module-fg;
padding: 0 4px;
text-shadow: 0 0 2px rgba(0, 0, 0, 0.6);
}
#custom-left1,
#custom-left2,
#custom-left3,
#custom-left4,
#custom-left5,
#custom-left6,
#custom-left7,
#custom-left8 {
margin-bottom: 0;
text-shadow: -2px 0 2px rgba(0, 0, 0, 0.5);
}
#custom-right1,
#custom-right2,
#custom-right3,
#custom-right4,
#custom-right5 {
margin-bottom: 0;
padding-right: 3px;
text-shadow: 2px 0 2px rgba(0, 0, 0, 0.5);
}
/* === Modules === */
/* == Window Icon == */
#custom-ws {
background: @main-bg;
}
/* == Workspaces == */
#custom-left1 {
color: @workspaces;
background: @main-bg;
margin-bottom: 0;
padding-left: 2px;
}
#workspaces {
background: @workspaces;
}
#custom-right1 {
color: @workspaces;
background: @main-bg;
text-shadow: 3px 0 2px rgba(0, 0, 0, 0.4);
margin-bottom: 0;
}
/* == Temperature == */
#custom-paddc {
padding-right: 22px;
}
#custom-left2 {
color: @cpuinfo;
background: @main-bg;
padding-left: 3px;
}
#custom-cpuinfo {
background: @cpuinfo;
padding-left: 1px;
padding-right: 0;
}
/* == Memory == */
#custom-left3 {
color: @memory;
background: @cpuinfo;
padding-left: 3px;
}
#memory {
background: @memory;
padding-left: 1px;
padding-right: 0;
}
#memory.warning {
color: @warning;
}
#memory.critical {
color: @critical;
}
/* == CPU == */
#custom-left4 {
color: @cpu;
background: @memory;
padding-left: 3px;
}
#custom-cpu {
background: @cpu;
}
#custom-leftin1 {
color: @cpu;
margin-bottom: -1px;
}
/* == Distro Icon == */
#custom-left5 {
color: @distro-bg;
background: @main-bg;
text-shadow: -2px 0 2px rgba(0, 0, 0, 0.6);
margin-bottom: -2px;
padding-left: 3px;
}
#custom-distro {
color: @distro-fg;
background: @distro-bg;
margin: 0 -1px -2px 0;
padding: 0 0 0 3px;
text-shadow: 0 0 1.5px rgba(0, 0, 0, 1);
}
#custom-right2 {
color: @distro-bg;
background: @main-bg;
margin-bottom: -2px;
}
/* == Time == */
#custom-rightin1 {
color: @time;
margin-bottom: -1px;
}
#idle_inhibitor {
background: @time;
margin-right: -2px;
padding: 0 0 0 7px;
}
#idle_inhibitor:hover {
color: @hover-fg;
text-shadow: none;
box-shadow: none;
}
#clock.time {
background: @time;
padding: 0 3px 0 0;
}
#custom-right3 {
color: @time;
background: @date;
}
/* == Date == */
#clock.date {
background: @date;
}
#clock.date:hover {
color: @hover-fg;
text-shadow: none;
box-shadow: none;
}
#custom-right4 {
color: @date;
background: @tray;
}
/* == Tray == */
#custom-wifi {
padding-left: 5px;
padding-right: 8px;
background: @tray;
}
#custom-wifi:hover {
color: @hover-fg;
text-shadow: none;
box-shadow: none;
}
#bluetooth {
padding-right: 5px;
background: @tray;
}
#bluetooth:hover {
color: @hover-fg;
text-shadow: none;
box-shadow: none;
}
#custom-update {
padding-right: 8px;
background: @tray;
}
#custom-update:hover {
color: @hover-fg;
text-shadow: none;
box-shadow: none;
}
#custom-right5 {
color: @tray;
background: @main-bg;
}
/* == Output Device == */
#custom-left6 {
color: @pulseaudio;
background: @main-bg;
padding-left: 3px;
}
#pulseaudio {
background: @pulseaudio;
}
#pulseaudio:hover {
color: @hover-fg;
text-shadow: none;
box-shadow: none;
}
/* == Brightness == */
#custom-left7 {
color: @backlight;
background: @pulseaudio;
padding-left: 2px;
}
#custom-backlight {
background: @backlight;
}
/* == Battery == */
#custom-left8 {
color: @battery;
background: @backlight;
padding-left: 2px;
}
#battery {
color: @module-fg;
background: @battery;
}
#battery.warning {
color: @warning;
}
#battery.critical {
color: @critical;
}
#battery.charging {
color: @charging;
}
/* == Power Button == */
#custom-leftin2 {
color: @battery;
background: @main-bg;
margin-bottom: -1px;
}
#custom-power {
color: @main-bg;
background: @power;
text-shadow: 0 0 2px rgba(0, 0, 0, 0.6);
box-shadow: 1px 0 2px 1px rgba(0, 0, 0, 0.6);
border-radius: 10px;
margin: 2px 4px 2px 0;
padding: 0 6px 0 9px;
}
#custom-power:hover {
color: @hover-fg;
background: @hover-bg;
text-shadow: none;
box-shadow: none;
}
/* <<--< FONT SIZES >-->> */
* {
font-size: 15px;
}
/* left and right arrows */
#custom-left1,
#custom-left2,
#custom-left3,
#custom-left4,
#custom-left5,
#custom-left6,
#custom-left7,
#custom-left8,
#custom-right1,
#custom-right2,
#custom-right3,
#custom-right4,
#custom-right5 {
font-size: 19.68px;
}
/* left and right inverse */
#custom-leftin1,
#custom-leftin2,
#custom-rightin1 {
font-size: 20.5px;
}
/* distro icon */
#custom-distro {
font-size: 19.6px;
}
/* distro arrows override */
#custom-left5,
#custom-right2 {
font-size: 20.68px;
}
'';
settings = {
mainBar = {
layer = "top";
position = "top";
reload_style_on_change = true;
modules-left = [
"custom/ws"
"custom/left1"
"sway/workspaces"
"custom/right1"
"custom/paddw"
"sway/window"
]; ];
modules-center = [
"custom/paddc"
"custom/left2"
"custom/cpuinfo"
"custom/left3"
"memory"
"custom/left4"
"custom/cpu"
"custom/leftin1"
"custom/left5"
"custom/distro"
"custom/right2"
"custom/rightin1"
"idle_inhibitor"
"clock#time"
"custom/right3"
"clock#date"
"custom/right4"
"custom/wifi"
"bluetooth"
"custom/update"
"custom/right5"
];
modules-right = [
"custom/media"
"custom/left6"
"pulseaudio"
"custom/left7"
"custom/backlight"
"custom/left8"
"battery"
"custom/leftin2"
"custom/power"
];
"custom/ws" = {
format = "  ";
tooltip = false;
min-length = 3;
max-length = 3;
};
"sway/workspaces" = {
format = "{icon}";
persistent-workspaces = {
"1" = [];
"2" = [];
"3" = [];
"4" = [];
};
};
"custom/cpuinfo" = {
exec = "~/.config/waybar/scripts/cpu-temp.sh";
return-type = "json";
format = "{}";
tooltip = true;
interval = 5;
min-length = 8;
max-length = 8;
};
memory = {
states = {
warning = 75;
critical = 90;
};
format = "󰘚 {percentage}%";
format-critical = "󰀦 {percentage}%";
tooltip = true;
tooltip-format = "Memory Used: {used:0.1f} GB / {total:0.1f} GB";
interval = 5;
min-length = 7;
max-length = 7;
};
"custom/cpu" = {
exec = "~/.config/waybar/scripts/cpu-usage.sh";
return-type = "json";
tooltip = true;
interval = 5;
min-length = 6;
max-length = 6;
};
"custom/distro" = {
format = " ";
tooltip = false;
};
"idle_inhibitor" = {
format = "{icon}";
format-icons = {
activated = "󱑎 ";
deactivated = "󱑂 ";
};
tooltip = true;
tooltip-format-activated = "Presentation Mode";
tooltip-format-deactivated = "Idle Mode";
start-activated = false;
};
"clock#time" = {
format = "{:%H:%M}";
tooltip = true;
tooltip-format = "Standard Time: {:%I:%M %p}";
min-length = 6;
max-length = 6;
};
"clock#date" = {
format = "󰨳 {:%m-%d}";
tooltip-format = "<tt>{calendar}</tt>";
calendar = {
mode = "month";
mode-mon-col = 6;
on-clock-right = "mode";
format = {
months = "<span color='#b4befe'><b>{}</b></span>";
weekdays = "<span color='#a6adc8' font='7'>{}</span>";
today = "<span color='#f38ba8'><b>{}</b></span>";
};
};
actions = {
on-click = "mode";
on-click-right = "mode";
};
min-length = 8;
max-length = 8;
};
"custom/wifi" = {
exec = "~/.config/waybar/scripts/wifi-status.sh";
return-type = "json";
format = "{}";
tooltip = true;
on-click = "~/.config/waybar/scripts/wifi-menu.sh";
on-clock-right = "kitty --title '󰤨 Network Manager TUI' bash -c nmtui";
interval = 1;
min-length = 1;
max-length = 2;
};
bluetooth = {
format = "󰂰";
format-disabled = "󰂲";
format-connected = "󰂱";
format-connected-battery = "󰂱";
tooltip-format = "{num_connections} connected";
tooltip-format-disabled = "Bluetooth disabled";
tooltip-format-connected = "{num_connections} connected\n{device_enumerate}";
tooltip-format-enumerate-connected = "{device_alias}";
tooltip-format-enumerate-connected-battery = "{device_alias}: {device_battery_percentage}%";
on-click = "~/.config/waybar/scripts/bluetooth-menu.sh";
on-click-right = "kitty --title '󰂯 Bluetooth TUI' bash -c bluetui";
interval = 1;
min-length = 1;
max-length = 1;
};
"custom/update" = {
min-length = 1;
max-length = 1;
};
battery = {
states = {
warning = 20;
critical = 10;
};
format = "{icon} {capacity}%";
format-icons = ["󰂎" "󰁻" "󰁼" "󰁽" "󰁾" "󰁿" "󰂀" "󰂁" "󰂂" "󰁹"];
format-charging = "󱘖 {capacity}%";
tooltip-format = "Discharging: {time}";
tooltip-format-charging = "Charging: {time}";
interval = 1;
min-length = 6;
max-length = 6;
};
"custom/power" = {
format = " ";
tooltip = true;
tooltip-format = "Power Menu";
on-click = "~/.config/waybar/scripts/power-menu.sh";
};
# Padding
"custom/paddw" = {
format = " ";
tooltip = false;
};
"custom/paddc" = {
format = " ";
tooltip = false;
};
##### Arrows
# Left
"custom/left1" = {
format = "";
tooltip = false;
};
"custom/left2" = {
format = "";
tooltip = false;
};
"custom/left3" = {
format = "";
tooltip = false;
};
"custom/left4" = {
format = "";
tooltip = false;
};
"custom/left5" = {
format = "";
tooltip = false;
};
"custom/left6" = {
format = "";
tooltip = false;
};
"custom/left7" = {
format = "";
tooltip = false;
};
"custom/left8" = {
format = "";
tooltip = false;
};
# Right
"custom/right1" = {
format = "";
tooltip = false;
};
"custom/right2" = {
format = "";
tooltip = false;
};
"custom/right3" = {
format = "";
tooltip = false;
};
"custom/right4" = {
format = "";
tooltip = false;
};
"custom/right5" = {
format = "";
tooltip = false;
};
"custom/leftin1" = {
"format" = "";
"tooltip" = false;
};
"custom/leftin2" = {
"format" = "";
"tooltip" = false;
};
"custom/rightin1" = {
format = "";
tooltip = false;
};
};
};
};
wayland.windowManager.sway = {
enable = true;
checkConfig = true;
config = rec {
output."*" = {
scale = "1";
bg = "${image} fill";
};
startup = [
# {command = "swaybg -i .config/flake/wallpaper.jpg";}
];
# Home row direction keys, like vim
up = "k";
left = "h";
down = "j";
right = "l";
### Idle configuration
#
# Example configuration:
#
# exec swayidle -w \
# timeout 300 'swaylock -f -c 000000' \
# timeout 600 'swaymsg "output * power off"' resume 'swaymsg "output * power on"' \
# before-sleep 'swaylock -f -c 000000'
#
# This will lock your screen after 300 seconds of inactivity, then turn off
# your displays after another 300 seconds, and turn your screens back on when
# resumed. It will also lock your screen before your computer goes to sleep.
### Input configuration
#
# Example configuration:
#
# input "2:14:SynPS/2_Synaptics_TouchPad" {
# dwt enabled
# tap enabled
# natural_scroll enabled
# middle_emulation enabled
# }
#
# You can get the names of your inputs by running: swaymsg -t get_inputs
# Read `man 5 sway-input` for more information about this section.
input = {
"*" = {
tap = "enabled";
natural_scroll = "enabled";
};
};
keybindings = {
### Key bindings
#
# Basics:
# Start a terminal
"${mod}+Return" = "exec ${term}";
# Kill focused window
"${mod}+q" = "kill";
# Start launcher
"${mod}+d" = "exec ${menu}";
# Reload the configuration file
"${mod}+Shift+c" = "reload";
"${mod}+r" = "mode resize";
#### Moving around:
# Move your focus around
"${mod}+Left" = "focus left";
"${mod}+Down" = "focus down";
"${mod}+Up" = "focus up";
"${mod}+Right" = "focus right";
# Exit sway (logs you out of your Wayland session)
"${mod}+Shift+e" = "exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -B 'Yes, exit sway' 'swaymsg exit'";
## Window
# Move the focused window with the same, but add Shift
"${mod}+Shift+${left}" = "move left";
"${mod}+Shift+${down}" = "move down";
"${mod}+Shift+${up}" = "move up";
"${mod}+Shift+${right}" = "move right";
# Ditto, with arrow keys
"${mod}+Shift+Left" = "move left";
"${mod}+Shift+Down" = "move down";
"${mod}+Shift+Up" = "move up";
"${mod}+Shift+Right" = "move right";
## Workspaces
# Switch to workspace
"${mod}+1" = "workspace number 1";
"${mod}+2" = "workspace number 2";
"${mod}+3" = "workspace number 3";
"${mod}+4" = "workspace number 4";
"${mod}+5" = "workspace number 5";
"${mod}+6" = "workspace number 6";
"${mod}+7" = "workspace number 7";
"${mod}+8" = "workspace number 8";
"${mod}+9" = "workspace number 9";
"${mod}+0" = "workspace number 10";
# Move focused container to workspace
"${mod}+Shift+1" = "move container to workspace number 1";
"${mod}+Shift+2" = "move container to workspace number 2";
"${mod}+Shift+3" = "move container to workspace number 3";
"${mod}+Shift+4" = "move container to workspace number 4";
"${mod}+Shift+5" = "move container to workspace number 5";
"${mod}+Shift+6" = "move container to workspace number 6";
"${mod}+Shift+7" = "move container to workspace number 7";
"${mod}+Shift+8" = "move container to workspace number 8";
"${mod}+Shift+9" = "move container to workspace number 9";
"${mod}+Shift+0" = "move container to workspace number 10";
## Layout
# You can "split" the current object of your focus with
# $mod+b or $mod+v, for horizontal and vertical splits
# respectively.
"${mod}+b" = "splith";
"${mod}+v" = "splitv";
# Switch the current container between different layout styles
"${mod}+s" = "layout stacking";
"${mod}+w" = "layout tabbed";
"${mod}+e" = "layout toggle split";
# Make the current focus fullscreen
"${mod}+f" = "fullscreen";
};
# Drag floating windows by holding down $mod and left mouse button.
# Resize them with right mouse button + $mod.
# Despite the name, also works for non-floating windows.
# Change normal to inverse to use left mouse button for resizing and right
# mouse button for dragging.
# floating_modifier $mod normal
# # Layout stuff:
# #
# # Toggle the current focus between tiling and floating mode
# bindsym $mod+Shift+space floating toggle
# # Swap focus between the tiling area and the floating area
# bindsym $mod+space focus mode_toggle
# # Move focus to the parent container
# bindsym $mod+a focus parent
# #
# # Scratchpad:
# #
# # Sway has a "scratchpad", which is a bag of holding for windows.
# # You can send windows there and get them back later.
# # Move the currently focused window to the scratchpad
# bindsym $mod+Shift+minus move scratchpad
# # Show the next scratchpad window or hide the focused scratchpad window.
# # If there are multiple scratchpad windows, this command cycles through them.
# bindsym $mod+minus scratchpad show
# #
# # Resizing containers:
# #
# mode "resize" {
# # left will shrink the containers width
# # right will grow the containers width
# # up will shrink the containers height
# # down will grow the containers height
# bindsym $left resize shrink width 10px
# bindsym $down resize grow height 10px
# bindsym $up resize shrink height 10px
# bindsym $right resize grow width 10px
# # Ditto, with arrow keys
# bindsym Left resize shrink width 10px
# bindsym Down resize grow height 10px
# bindsym Up resize shrink height 10px
# bindsym Right resize grow width 10px
# # Return to default mode
# bindsym Return mode "default"
# bindsym Escape mode "default"
# }
# #
# # Utilities:
# #
# # Special keys to adjust volume via PulseAudio
# bindsym --locked XF86AudioMute exec pactl set-sink-mute \@DEFAULT_SINK@ toggle
# bindsym --locked XF86AudioLowerVolume exec pactl set-sink-volume \@DEFAULT_SINK@ -5%
# bindsym --locked XF86AudioRaiseVolume exec pactl set-sink-volume \@DEFAULT_SINK@ +5%
# bindsym --locked XF86AudioMicMute exec pactl set-source-mute \@DEFAULT_SOURCE@ toggle
# # Special keys to adjust brightness via brightnessctl
# bindsym --locked XF86MonBrightnessDown exec brightnessctl set 5%-
# bindsym --locked XF86MonBrightnessUp exec brightnessctl set 5%+
# # Special key to take a screenshot with grim
# bindsym Print exec grim
bars = [
{
command = "waybar";
position = "top";
}
];
};
};
home = { home = {
username = "tyler"; username = "tyler";
@ -970,8 +16,7 @@ in {
packages = with pkgs; [ packages = with pkgs; [
ventoy ventoy
swaybg # (config.lib.nixGL.wrap renderdoc)
(config.lib.nixGL.wrap renderdoc)
]; ];
stateVersion = "23.11"; stateVersion = "23.11";

View file

@ -0,0 +1,761 @@
{pkgs, ...}: {
imports = [
./scripts.nix
./rofi.nix
];
home.packages = with pkgs; [
rofi
];
programs.waybar = {
enable = true;
style = ''
@define-color main-fg #cdd6f4;
@define-color main-bg #11111b;
@define-color main-br #cdd6f4;
@define-color active-bg #9399b2;
@define-color active-fg #11111b;
@define-color hover-bg #313244;
@define-color hover-fg rgba(205, 214, 244, 0.75);
@define-color white #ffffff;
@define-color black #000000;
/* Module Colors */
@define-color module-fg #f5e0dc;
@define-color workspaces #181825;
@define-color cpuinfo #181825;
@define-color memory #1e1e2e;
@define-color cpu #313244;
@define-color distro-fg #000000;
@define-color distro-bg #9399b2;
@define-color time #313244;
@define-color date #1e1e2e;
@define-color tray #181825;
@define-color pulseaudio #181825;
@define-color backlight #1e1e2e;
@define-color battery #313244;
@define-color power #9399b2;
/* State Colors */
@define-color warning #f9e2af;
@define-color critical #f38ba8;
@define-color charging #cdd6f4;
* {
font-size: 15px;
font-family: "JetBrainsMono Nerd Font";
font-weight: bold;
min-height: 0;
padding: 0;
border: none;
margin: 0;
}
window#waybar {
background: @main-bg;
}
window#waybar > box {
background-color: transparent;
box-shadow: 0 0 2px 1px rgba(0, 0, 0, 1);
margin: 2px;
}
/* === Tooltip === */
tooltip {
background: @main-bg;
border: solid;
border-width: 1.5px;
border-radius: 8px;
border-color: @main-br;
}
tooltip label {
color: @main-fg;
font-weight: normal;
margin: -1.5px 3px;
}
/* === Workspace Buttons === */
#workspaces button {
color: @main-fg;
border-radius: 8px;
box-shadow: none;
margin: 2px 0;
padding: 0 2px;
transition: none;
}
#workspaces button:hover {
color: @hover-fg;
background: @hover-bg;
text-shadow: none;
box-shadow: none;
}
#workspaces button.active {
color: @active-fg;
background: @hover-bg;
text-shadow: 0 0 2px rgba(0, 0, 0, 0.6);
box-shadow: 0 0 2px 1px rgba(0, 0, 0, 0.4);
margin: 2px;
padding: 0 6px;
}
/* === General === */
#custom-ws,
#workspaces,
#window,
#custom-cpuinfo,
#memory,
/* #custom-cpu, */
#cpu,
#idle_inhibitor,
#clock,
#custom-wifi,
#bluetooth,
#custom-update,
#custom-media,
#pulseaudio,
/* #custom-backlight, */
#backlight,
#battery,
#custom-power {
opacity: 1;
color: @module-fg;
padding: 0 4px;
text-shadow: 0 0 2px rgba(0, 0, 0, 0.6);
}
#custom-left1,
#custom-left2,
#custom-left3,
#custom-left4,
#custom-left5,
#custom-left6,
#custom-left7,
#custom-left8 {
margin-bottom: 0;
text-shadow: -2px 0 2px rgba(0, 0, 0, 0.5);
}
#custom-right1,
#custom-right2,
#custom-right3,
#custom-right4,
#custom-right5 {
margin-bottom: 0;
padding-right: 3px;
text-shadow: 2px 0 2px rgba(0, 0, 0, 0.5);
}
/* === Modules === */
/* == Window Icon == */
#custom-ws {
background: @main-bg;
}
/* == Workspaces == */
#custom-left1 {
color: @workspaces;
background: @main-bg;
margin-bottom: 0;
padding-left: 2px;
}
#workspaces {
background: @workspaces;
}
#custom-right1 {
color: @workspaces;
background: @main-bg;
text-shadow: 3px 0 2px rgba(0, 0, 0, 0.4);
margin-bottom: 0;
}
/* == Temperature == */
#custom-paddc {
padding-right: 22px;
}
#custom-left2 {
color: @cpuinfo;
background: @main-bg;
padding-left: 3px;
}
#custom-cpuinfo {
background: @cpuinfo;
padding-left: 1px;
padding-right: 0;
}
/* == Memory == */
#custom-left3 {
color: @memory;
background: @cpuinfo;
padding-left: 3px;
}
#memory {
background: @memory;
padding-left: 1px;
padding-right: 0;
}
#memory.warning {
color: @warning;
}
#memory.critical {
color: @critical;
}
/* == CPU == */
#custom-left4 {
color: @cpu;
background: @memory;
padding-left: 3px;
}
#cpu {
background: @cpu;
}
#custom-cpu {
background: @cpu;
}
#custom-leftin1 {
color: @cpu;
margin-bottom: -1px;
}
/* == Distro Icon == */
#custom-left5 {
color: @distro-bg;
background: @main-bg;
text-shadow: -2px 0 2px rgba(0, 0, 0, 0.6);
margin-bottom: -2px;
padding-left: 3px;
}
#custom-distro {
color: @distro-fg;
background: @distro-bg;
margin: 0 -1px -2px 0;
padding: 0 0 0 3px;
text-shadow: 0 0 1.5px rgba(0, 0, 0, 1);
}
#custom-right2 {
color: @distro-bg;
background: @main-bg;
margin-bottom: -2px;
}
/* == Time == */
#custom-rightin1 {
color: @time;
margin-bottom: -1px;
}
#idle_inhibitor {
background: @time;
margin-right: -2px;
padding: 0 0 0 7px;
}
#idle_inhibitor:hover {
color: @hover-fg;
text-shadow: none;
box-shadow: none;
}
#clock.time {
background: @time;
padding: 0 3px 0 0;
}
#custom-right3 {
color: @time;
background: @date;
}
/* == Date == */
#clock.date {
background: @date;
}
#clock.date:hover {
color: @hover-fg;
text-shadow: none;
box-shadow: none;
}
#custom-right4 {
color: @date;
background: @tray;
}
/* == Tray == */
#custom-wifi {
padding-left: 5px;
padding-right: 8px;
background: @tray;
}
#custom-wifi:hover {
color: @hover-fg;
text-shadow: none;
box-shadow: none;
}
#bluetooth {
padding-right: 5px;
background: @tray;
}
#bluetooth:hover {
color: @hover-fg;
text-shadow: none;
box-shadow: none;
}
#custom-update {
padding-right: 8px;
background: @tray;
}
#custom-update:hover {
color: @hover-fg;
text-shadow: none;
box-shadow: none;
}
#custom-right5 {
color: @tray;
background: @main-bg;
}
/* == Output Device == */
#custom-left6 {
color: @pulseaudio;
background: @main-bg;
padding-left: 3px;
}
#pulseaudio {
background: @pulseaudio;
}
#pulseaudio:hover {
color: @hover-fg;
text-shadow: none;
box-shadow: none;
}
/* == Brightness == */
#custom-left7 {
color: @backlight;
background: @pulseaudio;
padding-left: 2px;
}
#custom-backlight {
background: @backlight;
}
/* == Battery == */
#custom-left8 {
color: @battery;
background: @backlight;
padding-left: 2px;
}
#battery {
color: @module-fg;
background: @battery;
}
#battery.warning {
color: @warning;
}
#battery.critical {
color: @critical;
}
#battery.charging {
color: @charging;
}
/* == Power Button == */
#custom-leftin2 {
color: @battery;
background: @main-bg;
margin-bottom: -1px;
}
#custom-power {
color: @main-bg;
background: @power;
text-shadow: 0 0 2px rgba(0, 0, 0, 0.6);
box-shadow: 1px 0 2px 1px rgba(0, 0, 0, 0.6);
border-radius: 10px;
margin: 2px 4px 2px 0;
padding: 0 6px 0 9px;
}
#custom-power:hover {
color: @hover-fg;
background: @hover-bg;
text-shadow: none;
box-shadow: none;
}
/* <<--< FONT SIZES >-->> */
* {
font-size: 15px;
}
/* left and right arrows */
#custom-left1,
#custom-left2,
#custom-left3,
#custom-left4,
#custom-left5,
#custom-left6,
#custom-left7,
#custom-left8,
#custom-right1,
#custom-right2,
#custom-right3,
#custom-right4,
#custom-right5 {
font-size: 19.68px;
}
/* left and right inverse */
#custom-leftin1,
#custom-leftin2,
#custom-rightin1 {
font-size: 20.5px;
}
/* distro icon */
#custom-distro {
font-size: 19.6px;
}
/* distro arrows override */
#custom-left5,
#custom-right2 {
font-size: 20.68px;
}
'';
settings = {
mainBar = {
layer = "top";
position = "top";
gtk-layer-shell = true;
reload_style_on_change = true;
modules-left = [
"custom/ws"
"custom/left1"
"sway/workspaces"
"custom/right1"
"custom/paddw"
"sway/window"
];
modules-center = [
"custom/paddc"
"custom/left2"
"custom/cpuinfo"
"custom/left3"
"memory"
"custom/left4"
"cpu"
# "custom/cpu"
"custom/leftin1"
"custom/left5"
"custom/distro"
"custom/right2"
"custom/rightin1"
"idle_inhibitor"
"clock#time"
"custom/right3"
"clock#date"
"custom/right4"
"custom/wifi"
"bluetooth"
"custom/update"
"custom/right5"
];
modules-right = [
"custom/media"
"custom/left6"
"pulseaudio"
"custom/left7"
"custom/backlight"
"custom/left8"
"battery"
"custom/leftin2"
"custom/power"
];
"custom/ws" = {
format = "  ";
tooltip = false;
min-length = 3;
max-length = 3;
};
"sway/workspaces" = {
format = "{icon}";
persistent-workspaces = {
"1" = [];
"2" = [];
"3" = [];
"4" = [];
};
};
"custom/cpuinfo" = {
exec = "~/.config/waybar/scripts/cpu-temp.sh";
return-type = "json";
format = "{}";
tooltip = true;
interval = 5;
min-length = 8;
max-length = 8;
};
memory = {
states = {
warning = 75;
critical = 90;
};
format = "󰘚 {percentage}%";
format-critical = "󰀦 {percentage}%";
tooltip = true;
tooltip-format = "Memory Used: {used:0.1f} GB / {total:0.1f} GB";
interval = 5;
min-length = 7;
max-length = 7;
};
cpu = {
format = "󰻠 {usage}%";
tooltip = false;
interval = 5;
min-length = 6;
max-length = 6;
};
# "custom/cpu" = {
# exec = "~/.config/waybar/scripts/cpu-usage.sh";
# return-type = "json";
# tooltip = true;
# interval = 5;
# min-length = 6;
# max-length = 6;
# };
"custom/distro" = {
format = " ";
tooltip = false;
};
"idle_inhibitor" = {
format = "{icon}";
format-icons = {
activated = "󱑎 ";
deactivated = "󱑂 ";
};
tooltip = true;
tooltip-format-activated = "Presentation Mode";
tooltip-format-deactivated = "Idle Mode";
start-activated = false;
};
"clock#time" = {
format = "{:%H:%M}";
tooltip = true;
tooltip-format = "Standard Time: {:%I:%M %p}";
min-length = 6;
max-length = 6;
};
"clock#date" = {
format = "󰨳 {:%m-%d}";
tooltip-format = "<tt>{calendar}</tt>";
calendar = {
mode = "month";
mode-mon-col = 6;
on-clock-right = "mode";
format = {
months = "<span color='#b4befe'><b>{}</b></span>";
weekdays = "<span color='#a6adc8' font='7'>{}</span>";
today = "<span color='#f38ba8'><b>{}</b></span>";
};
};
actions = {
on-click = "mode";
on-click-right = "mode";
};
min-length = 8;
max-length = 8;
};
"custom/wifi" = {
exec = "~/.config/waybar/scripts/wifi-status.sh";
return-type = "json";
format = "{}";
tooltip = true;
on-click = "~/.config/waybar/scripts/wifi-menu.sh";
on-clock-right = "kitty --title '󰤨 Network Manager TUI' bash -c nmtui";
interval = 1;
min-length = 1;
max-length = 2;
};
bluetooth = {
format = "󰂰";
format-disabled = "󰂲";
format-connected = "󰂱";
format-connected-battery = "󰂱";
tooltip-format = "{num_connections} connected";
tooltip-format-disabled = "Bluetooth disabled";
tooltip-format-connected = "{num_connections} connected\n{device_enumerate}";
tooltip-format-enumerate-connected = "{device_alias}";
tooltip-format-enumerate-connected-battery = "{device_alias}: {device_battery_percentage}%";
on-click = "~/.config/waybar/scripts/bluetooth-menu.sh";
on-click-right = "kitty --title '󰂯 Bluetooth TUI' bash -c bluetui";
interval = 1;
min-length = 1;
max-length = 1;
};
"custom/update" = {
min-length = 1;
max-length = 1;
};
battery = {
states = {
warning = 20;
critical = 10;
};
format = "{icon} {capacity}%";
format-icons = ["󰂎" "󰁻" "󰁼" "󰁽" "󰁾" "󰁿" "󰂀" "󰂁" "󰂂" "󰁹"];
format-charging = "󱘖 {capacity}%";
tooltip-format = "Discharging: {time}";
tooltip-format-charging = "Charging: {time}";
interval = 1;
min-length = 6;
max-length = 6;
};
"custom/power" = {
format = " ";
tooltip = true;
tooltip-format = "Power Menu";
on-click = "~/.config/waybar/scripts/power-menu.sh";
};
# Padding
"custom/paddw" = {
format = " ";
tooltip = false;
};
"custom/paddc" = {
format = " ";
tooltip = false;
};
##### Arrows
# Left
"custom/left1" = {
format = "";
tooltip = false;
};
"custom/left2" = {
format = "";
tooltip = false;
};
"custom/left3" = {
format = "";
tooltip = false;
};
"custom/left4" = {
format = "";
tooltip = false;
};
"custom/left5" = {
format = "";
tooltip = false;
};
"custom/left6" = {
format = "";
tooltip = false;
};
"custom/left7" = {
format = "";
tooltip = false;
};
"custom/left8" = {
format = "";
tooltip = false;
};
# Right
"custom/right1" = {
format = "";
tooltip = false;
};
"custom/right2" = {
format = "";
tooltip = false;
};
"custom/right3" = {
format = "";
tooltip = false;
};
"custom/right4" = {
format = "";
tooltip = false;
};
"custom/right5" = {
format = "";
tooltip = false;
};
"custom/leftin1" = {
"format" = "";
"tooltip" = false;
};
"custom/leftin2" = {
"format" = "";
"tooltip" = false;
};
"custom/rightin1" = {
format = "";
tooltip = false;
};
};
};
};
}

View file

@ -0,0 +1,6 @@
{...} : {
home.file.".config/rofi" = {
recursive = true;
source = ./rofi;
};
}

View file

@ -0,0 +1,79 @@
/* Bluetooth menu */
configuration {
font: "JetBrainsMono Nerd Font 8";
}
@theme "~/.config/rofi/theme.rasi"
/* Window */
window {
location: north;
anchor: south;
y-offset: 3px;
width: 240px;
border: 2px;
border-radius: 10px;
border-color: @main-br;
background-color: @main-bg;
children: [ mainbox ];
}
mainbox {
spacing: 0;
background-color: inherit;
text-color: @main-fg;
children: [ inputbar, listview ];
}
/* Input */
inputbar {
margin: 6px;
border-radius: 6px;
spacing: inherit;
background-color: @input-bg;
text-color: inherit;
children: [ prompt, entry ];
}
prompt {
padding: 6px 6px 6px 12px;
background-color: inherit;
text-color: inherit;
}
entry {
placeholder: "Search";
padding: 6px 0;
cursor: text;
background-color: inherit;
text-color: inherit;
}
/* List */
listview {
lines: 6;
cycle: false;
padding: 0 6px 6px 6px;
background-color: inherit;
}
element {
padding: 6px;
cursor: pointer;
background-color: inherit;
text-color: @main-fg;
}
element selected active,
element selected normal {
border-radius: 6px;
background-color: @select-bg;
text-color: @select-fg;
}
element-text {
padding: 0 6px;
cursor: inherit;
background-color: inherit;
text-color: inherit;
}

View file

@ -0,0 +1,54 @@
/* Power menu */
configuration {
font: "JetBrainsMono Nerd Font 8";
}
@theme "~/.config/rofi/theme.rasi"
/* Window */
window {
location: northeast;
anchor: north;
x-offset: -3px;
y-offset: 3px;
width: 150px;
border: 2px;
border-radius: 10px;
border-color: @main-br;
background-color: @main-bg;
children: [ mainbox ];
}
mainbox {
background-color: inherit;
text-color: @main-fg;
children: [ listview ];
}
/* List */
listview {
lines: 6;
padding: 6px;
background-color: inherit;
}
element {
padding: 6px;
cursor: pointer;
background-color: inherit;
text-color: @main-fg;
}
element selected.normal {
border-radius: 6px;
background-color: @select-bg;
text-color: @select-fg;
}
element-text {
padding: 0 6px;
cursor: inherit;
background-color: inherit;
text-color: inherit;
}

View file

@ -0,0 +1,14 @@
/*
bg - background
fg - foreground
br - border
*/
* {
main-bg: #11111b;
main-fg: #cdd6f4;
main-br: #9399b2;
input-bg: #181825;
select-bg: #9399b2;
select-fg: #11111b;
}

View file

@ -0,0 +1,79 @@
/* WiFi menu */
configuration {
font: "JetBrainsMono Nerd Font 8";
}
@theme "~/.config/rofi/theme.rasi"
/* Window */
window {
location: north;
anchor: south;
y-offset: 3px;
width: 240px;
border: 2px;
border-radius: 10px;
border-color: @main-br;
background-color: @main-bg;
children: [ mainbox ];
}
mainbox {
spacing: 0;
background-color: inherit;
text-color: @main-fg;
children: [ inputbar, listview ];
}
/* Input */
inputbar {
margin: 6px;
border-radius: 6px;
spacing: inherit;
background-color: @input-bg;
text-color: inherit;
children: [ prompt, entry ];
}
prompt {
padding: 6px 6px 6px 12px;
background-color: inherit;
text-color: inherit;
}
entry {
placeholder: "Search";
padding: 6px 0;
cursor: text;
background-color: inherit;
text-color: inherit;
}
/* List */
listview {
lines: 6;
cycle: false;
padding: 0 6px 6px 6px;
background-color: inherit;
}
element {
padding: 6px;
cursor: pointer;
background-color: inherit;
text-color: @main-fg;
}
element selected active,
element selected normal {
border-radius: 6px;
background-color: @select-bg;
text-color: @select-fg;
}
element-text {
padding: 0 6px;
cursor: inherit;
background-color: inherit;
text-color: inherit;
}

View file

@ -0,0 +1,11 @@
{...}: {
home.file.".config/waybar/scripts" = {
source = ./scripts;
recursive = true;
};
# home.file.".config/waybar/scripts/cpu-temp.sh" = {
# source = ./scripts/cpu-temp.sh;
# executable = true;
# };
}

View file

@ -0,0 +1,80 @@
#!/usr/bin/env bash
# Original script by Eric Murphy
# https://github.com/ericmurphyxyz/dotfiles/blob/master/.local/bin/battery-alert
#
# Modified by Jesse Mirabel (@sejjy)
# https://github.com/sejjy/mechabar
# This script sends a notification when the battery is full, low, or critical.
# icon theme used: tela-circle-icon-theme-dracula
#
# (see the bottom of the script for more information)
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus"
# battery levels
WARNING_LEVEL=20
CRITICAL_LEVEL=10
# get the battery state and percentage using upower (waybar dependency)
BAT_PATH=$(upower -e | grep BAT | head -n 1)
BATTERY_STATE=$(upower -i "$BAT_PATH" | awk '/state:/ {print $2}')
BATTERY_LEVEL=$(upower -i "$BAT_PATH" | awk '/percentage:/ {print $2}' | tr -d '%')
# prevent multiple notifications
FILE_FULL=/tmp/battery-full
FILE_WARNING=/tmp/battery-warning
FILE_CRITICAL=/tmp/battery-critical
# remove the files if the battery is no longer in that state
if [ "$BATTERY_STATE" == "discharging" ]; then
rm -f $FILE_FULL
elif [ "$BATTERY_STATE" == "charging" ]; then
rm -f "$FILE_WARNING" "$FILE_CRITICAL"
fi
# if the battery is full and is plugged in
if [ "$BATTERY_LEVEL" -eq 100 ] && [ "$BATTERY_STATE" == "fully-charged" ] && [ ! -f $FILE_FULL ]; then
notify-send -a "state" "Battery Charged (${BATTERY_LEVEL}%)" "You might want to unplug your PC." -i "battery-full" -r 9991
touch $FILE_FULL
# if the battery is low and is discharging
elif [ "$BATTERY_LEVEL" -le $WARNING_LEVEL ] && [ "$BATTERY_STATE" == "discharging" ] && [ ! -f $FILE_WARNING ]; then
notify-send -a "state" "Battery Low (${BATTERY_LEVEL}%)" "You might want to plug in your PC." -u critical -i "battery-caution" -r 9991 -h string:fgcolor:\#fab387 -h string:frcolor:\#fab387
touch $FILE_WARNING
# if the battery is critical and is discharging
elif [ "$BATTERY_LEVEL" -le $CRITICAL_LEVEL ] && [ "$BATTERY_STATE" == "discharging" ] && [ ! -f $FILE_CRITICAL ]; then
notify-send -a "state" "Battery Critical (${BATTERY_LEVEL}%)" "Plug in your PC now." -u critical -i "battery-empty" -r 9991
touch $FILE_CRITICAL
fi
# systemd service
# Add the following to ~/.config/systemd/user/battery-level.service:
# [Unit]
# Description=Battery Level Checker
# After=graphical.target
#
# [Service]
# ExecStart=%h/.config/waybar/scripts/battery-level.sh
# Type=oneshot
# systemd timer
# Add the following to ~/.config/systemd/user/battery-level.timer:
# [Unit]
# Description=Run Battery Level Checker
#
# [Timer]
# OnBootSec=1min
# OnUnitActiveSec=1min
# Unit=battery-level.service
#
# [Install]
# WantedBy=timers.target
# enable the timer by running the following commands:
# systemctl --user daemon-reload
# systemctl --user enable --now battery-level.timer

View file

@ -0,0 +1,50 @@
#!/usr/bin/env bash
# Original script by Eric Murphy
# https://github.com/ericmurphyxyz/dotfiles/blob/master/.local/bin/battery-alert
#
# Modified by Jesse Mirabel (@sejjy)
# https://github.com/sejjy/mechabar
# This script sends a notification when the battery is charging or discharging.
# icon theme used: tela-circle-icon-theme-dracula
#
# (see the bottom of the script for more information)
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus"
# get the battery state from the udev rule
BATTERY_STATE=$1
# get the battery percentage using upower (waybar dependency)
BAT_PATH=$(upower -e | grep BAT | head -n 1)
BATTERY_LEVEL=$(upower -i "$BAT_PATH" | awk '/percentage:/ {print $2}' | tr -d '%')
# set the battery charging state and icon
case "$BATTERY_STATE" in
"charging")
BATTERY_CHARGING="Charging"
BATTERY_ICON="090-charging"
;;
"discharging")
BATTERY_CHARGING="Disharging"
BATTERY_ICON="090"
;;
esac
# send the notification
notify-send -a "state" "Battery ${BATTERY_CHARGING} (${BATTERY_LEVEL}%)" -u normal -i "battery-${BATTERY_ICON}" -r 9991
# udev rule
# Add the following to /etc/udev/rules.d/60-power.rules:
# ACTION=="change", SUBSYSTEM=="power_supply", ATTR{type}=="Mains", ATTR{online}=="0", ENV{DISPLAY}=":0", RUN+="/usr/bin/su <username> -c '$HOME/.config/waybar/scripts/battery-state.sh discharging'"
# ACTION=="change", SUBSYSTEM=="power_supply", ATTR{type}=="Mains", ATTR{online}=="1", ENV{DISPLAY}=":0", RUN+="/usr/bin/su <username> -c '$HOME/.config/waybar/scripts/battery-state.sh charging'"
# the number 60 in the udev rule can be changed to any number between 0 and 99.
# the lower the number, the higher the priority.
#
# $USER does not work, so you have to replace "<username>" with your username.
# reload udev rules by running the following command:
# sudo udevadm control --reload-rules

View file

@ -0,0 +1,105 @@
#!/usr/bin/env bash
# Author: Jesse Mirabel (@sejjy)
# GitHub: https://github.com/sejjy/mechabar
# Rofi config
config="$HOME/.config/rofi/bluetooth-menu.rasi"
# Rofi window override
override_disabled="mainbox { children: [ listview ]; } listview { lines: 1; padding: 6px; }"
get_device_icon() {
local device_mac=$1
device_info=$(bluetoothctl info "$device_mac")
device_icon=$(echo "$device_info" | grep "Icon:" | awk '{print $2}')
case "$device_icon" in
"audio-headphones" | "audio-headset") echo "󰋋 " ;; # Headphones
"video-display" | "computer") echo "󰍹 " ;; # Monitor
"audio-input-microphone") echo "󰍬 " ;; # Microphone
"input-keyboard") echo "󰌌 " ;; # Keyboard
"audio-speakers") echo "󰓃 " ;; # Speakers
"input-mouse") echo "󰍽 " ;; # Mouse
"phone") echo "󰏲 " ;; # Phone
*)
echo "󰂱 " # Default
;;
esac
}
while true; do
# Get list of paired devices
bluetooth_devices=$(bluetoothctl devices | while read -r line; do
device_mac=$(echo "$line" | awk '{print $2}')
device_name=$(echo "$line" | awk '{$1=$2=""; print substr($0, 3)}')
icon=$(get_device_icon "$device_mac")
echo "$icon $device_name"
done)
options=$(
echo "Scan for devices  "
echo "Disable Bluetooth"
echo "$bluetooth_devices"
)
option="Enable Bluetooth"
# Get Bluetooth status
bluetooth_status=$(bluetoothctl show | grep "Powered:" | awk '{print $2}')
if [[ "$bluetooth_status" == "yes" ]]; then
selected_option=$(echo -e "$options" | rofi -dmenu -i -selected-row 1 -config "${config}" -p " " || pkill -x rofi)
else
selected_option=$(echo -e "$option" | rofi -dmenu -i -selected-row 1 -config "${config}" -theme-str "${override_disabled}" -p " " || pkill -x rofi)
fi
# Exit if no option is selected
if [ -z "$selected_option" ]; then
exit
fi
# Actions based on selected option
case "$selected_option" in
"Enable Bluetooth")
notify-send "Bluetooth Enabled"
rfkill unblock bluetooth
bluetoothctl power on
sleep 1
;;
"Disable Bluetooth")
notify-send "Bluetooth Disabled"
rfkill block bluetooth
bluetoothctl power off
exit
;;
"Scan for devices"*)
notify-send "Press '?' to show help."
kitty --title '󰂱 Bluetooth TUI' bash -c "bluetui" # Launch bluetui
;;
*)
# Extract device name
device_name="${selected_option#* }"
device_name="${device_name## }"
if [[ -n "$device_name" ]]; then
# Get MAC address
device_mac=$(bluetoothctl devices | grep "$device_name" | awk '{print $2}')
# Trust and pair device
bluetoothctl trust "$device_mac" >/dev/null 2>&1
bluetoothctl pair "$device_mac" >/dev/null 2>&1
# Connect to device
bluetoothctl connect "$device_mac" &
sleep 3
connection_status=$(bluetoothctl info "$device_mac" | grep "Connected:" | awk '{print $2}')
if [[ "$connection_status" == "yes" ]]; then
notify-send "Connected to \"$device_name\"."
else
notify-send "Failed to connect to \"$device_name\"."
fi
fi
;;
esac
done

View file

@ -0,0 +1,92 @@
#!/usr/bin/env bash
# Print error message for invalid arguments
print_error() {
cat <<"EOF"
Usage: ./brightnesscontrol.sh <action>
Valid actions are:
i -- <i>ncrease brightness [+2%]
d -- <d>ecrease brightness [-2%]
EOF
}
# Send a notification with brightness info
send_notification() {
brightness=$(brightnessctl info | grep -oP "(?<=\()\d+(?=%)")
notify-send -a "state" -r 91190 -i "gpm-brightness-lcd" -h int:value:"$brightness" "Brightness: ${brightness}%" -u low
}
# Get the current brightness percentage and device name
get_brightness() {
brightness=$(brightnessctl -m | grep -o '[0-9]\+%' | head -c-2)
device=$(brightnessctl -m | head -n 1 | awk -F',' '{print $1}' | sed 's/_/ /g; s/\<./\U&/g') # Get device name
current_brightness=$(brightnessctl -m | head -n 1 | awk -F',' '{print $3}') # Get current brightness
max_brightness=$(brightnessctl -m | head -n 1 | awk -F',' '{print $5}') # Get max brightness
}
get_brightness
# Handle options
while getopts o: opt; do
case "${opt}" in
o)
case $OPTARG in
i) # Increase brightness
if [[ $brightness -lt 10 ]]; then
brightnessctl set +1%
else
brightnessctl set +2%
fi
send_notification
;;
d) # Decrease brightness
if [[ $brightness -le 1 ]]; then
brightnessctl set 1%
elif [[ $brightness -le 10 ]]; then
brightnessctl set 1%-
else
brightnessctl set 2%-
fi
send_notification
;;
*)
print_error
;;
esac
;;
*)
print_error
;;
esac
done
# Determine the icon based on brightness level
get_icon() {
if ((brightness <= 5)); then
icon=""
elif ((brightness <= 15)); then
icon=""
elif ((brightness <= 30)); then
icon=""
elif ((brightness <= 45)); then
icon=""
elif ((brightness <= 55)); then
icon=""
elif ((brightness <= 65)); then
icon=""
elif ((brightness <= 80)); then
icon=""
elif ((brightness <= 95)); then
icon=""
else
icon=""
fi
}
# Backlight module and tooltip
get_icon
module="${icon} ${brightness}%"
tooltip="Device Name: ${device}"
tooltip+="\nBrightness: ${current_brightness} / ${max_brightness}"
echo "{\"text\": \"${module}\", \"tooltip\": \"${tooltip}\"}"

View file

@ -0,0 +1,61 @@
#!/usr/bin/env bash
# Get CPU clock speeds
get_cpu_frequency() {
freqlist=$(awk '/cpu MHz/ {print $4}' /proc/cpuinfo)
maxfreq=$(sed 's/...$//' /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq)
average_freq=$(echo "$freqlist" | tr ' ' '\n' | awk "{sum+=\$1} END {printf \"%.0f/%s MHz\", sum/NR, $maxfreq}")
echo "$average_freq"
}
# Get CPU temperature
get_cpu_temperature() {
temp=$(sensors | awk '/Package id 0/ {print $4}' | awk -F '[+.]' '{print $2}')
if [[ -z "$temp" ]]; then
temp=$(sensors | awk '/Tctl/ {print $2}' | tr -d '+°C')
fi
if [[ -z "$temp" ]]; then
temp="N/A"
else
temp_f=$(awk "BEGIN {printf \"%.1f\", ($temp * 9 / 5) + 32}")
fi
echo "${temp:-N/A} ${temp_f:-N/A}"
}
# Get the corresponding icon based on temperature
get_temperature_icon() {
temp_value=$1
if [ "$temp_value" -ge 80 ]; then
icon="󰸁" # High temperature
elif [ "$temp_value" -ge 70 ]; then
icon="󱃂" # Medium temperature
elif [ "$temp_value" -ge 60 ]; then
icon="󰔏" # Normal temperature
else
icon="󱃃" # Low temperature
fi
echo "$icon"
}
# Main script execution
cpu_frequency=$(get_cpu_frequency)
read -r temp_info < <(get_cpu_temperature)
temp=$(echo "$temp_info" | awk '{print $1}') # Celsius
temp_f=$(echo "$temp_info" | awk '{print $2}') # Fahrenheit
# Determine the temperature icon
thermo_icon=$(get_temperature_icon "$temp")
# Set color based on temperature
if [ "$temp" -ge 80 ]; then
# If temperature is >= 80%, set color to #f38ba8
text_output="<span color='#f38ba8'>${thermo_icon} ${temp}°C</span>"
else
# Default color
text_output="${thermo_icon} ${temp}°C"
fi
tooltip="Temperature: ${temp_f}°F\nClock Speed: ${cpu_frequency}"
# Module and tooltip
echo "{\"text\": \"$text_output\", \"tooltip\": \"$tooltip\"}"

View file

@ -0,0 +1,33 @@
#!/usr/bin/env bash
# Get CPU model (removed "(R)", "(TM)", and clock speed)
model=$(awk -F ': ' '/model name/{print $2}' /proc/cpuinfo | head -n 1 | sed 's/@.*//; s/ *\((R)\|(TM)\)//g; s/^[ \t]*//; s/[ \t]*$//')
# Get CPU usage percentage
load=$(vmstat 1 2 | tail -1 | awk '{print 100 - $15}')
# Determine CPU state based on usage
if [ "$load" -ge 80 ]; then
state="Critical"
elif [ "$load" -ge 60 ]; then
state="High"
elif [ "$load" -ge 25 ]; then
state="Moderate"
else
state="Low"
fi
# Set color based on CPU load
if [ "$load" -ge 80 ]; then
# If CPU usage is >= 80%, set color to #f38ba8
text_output="<span color='#f38ba8'>󰀩 ${load}%</span>"
else
# Default color
text_output="󰻠 ${load}%"
fi
tooltip="${model}"
tooltip+="\nCPU Usage: ${state}"
# Module and tooltip
echo "{\"text\": \"$text_output\", \"tooltip\": \"$tooltip\"}"

View file

@ -0,0 +1,203 @@
#!/usr/bin/env python3
import gi
gi.require_version("Playerctl", "2.0")
from gi.repository import Playerctl, GLib
from gi.repository.Playerctl import Player # type: ignore
import argparse
import logging
import sys
import signal
import json
import os
from typing import List
logger = logging.getLogger(__name__)
def signal_handler(sig, frame):
# Handle termination signals gracefully.
logger.info("Received signal to stop, exiting")
sys.stdout.write("\n")
sys.stdout.flush()
sys.exit(0)
class PlayerManager:
def __init__(self, selected_player=None, excluded_players=[]):
self.manager = Playerctl.PlayerManager()
self.loop = GLib.MainLoop()
self.manager.connect("name-appeared", self.on_player_appeared)
self.manager.connect("player-vanished", self.on_player_vanished)
# Register signal handlers for termination
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
self.selected_player = selected_player
self.excluded_players = excluded_players.split(',') if excluded_players else []
self.init_players()
def init_players(self):
# Initialize players based on selection and exclusion criteria.
for player in self.manager.props.player_names:
if player.name not in self.excluded_players:
if self.selected_player is None or self.selected_player == player.name:
self.init_player(player)
def run(self):
# Start the GLib main loop.
logger.info("Starting main loop")
self.loop.run()
def init_player(self, player):
# Initialize a new media player.
logger.info(f"Initialize new player: {player.name}")
player_instance = Playerctl.Player.new_from_name(player)
player_instance.connect("playback-status", self.on_playback_status_changed)
player_instance.connect("metadata", self.on_metadata_changed)
self.manager.manage_player(player_instance)
self.on_metadata_changed(player_instance, player_instance.props.metadata)
def get_players(self) -> List[Player]:
# Retrieve the list of managed players.
return self.manager.props.players
def write_output(self, text, player):
# Format and send output for the player status.
logger.debug(f"Writing output: {text}")
# Determine the tooltip based on playback status
tooltip_status = f"<span color='#f38ba8'><b>Paused:</b> </span>" if player.props.status != "Playing" else ""
# Construct tooltip with track info
tooltip = f"{tooltip_status}{text}"
output = {
"text": text,
"class": "custom-" + player.props.player_name,
"alt": player.props.player_name,
"tooltip": tooltip
}
sys.stdout.write(json.dumps(output) + "\n")
sys.stdout.flush()
def clear_output(self):
# Clear the output.
sys.stdout.write("\n")
sys.stdout.flush()
def on_playback_status_changed(self, player, status, _=None):
# Handle changes in playback status.
logger.debug(f"Playback status changed for player {player.props.player_name}: {status}")
self.on_metadata_changed(player, player.props.metadata)
def get_first_playing_player(self):
# Return the first player that is currently playing.
players = self.get_players()
logger.debug(f"Getting first playing player from {len(players)} players")
for player in players[::-1]:
if player.props.status == "Playing":
return player
return players[0] if players else None
def show_most_important_player(self):
# Display the most relevant player information.
logger.debug("Showing most important player")
current_player = self.get_first_playing_player()
if current_player is not None:
self.on_metadata_changed(current_player, current_player.props.metadata)
else:
self.clear_output()
def on_metadata_changed(self, player, metadata, _=None):
logger.debug(f"Metadata changed for player {player.props.player_name}")
player_name = player.props.player_name
artist = player.get_artist()
title = player.get_title()
# Escape special characters in the title
title = title.replace("&", "&amp;") if title else "Unknown Title"
track_info = None
if metadata:
try:
# Access track ID safely
track_id_variant = metadata.lookup_value("mpris:trackid", GLib.VariantType("s"))
track_id = track_id_variant.unpack() if track_id_variant else ""
if player_name == "spotify" and ":ad:" in track_id:
track_info = "Advertisement"
except Exception as e:
logger.error(f"Error accessing metadata for player {player_name}: {e}")
# Fallback to artist and title
if not track_info and artist and title:
track_info = f"<b>{title}</b> - {artist}"
elif not track_info:
track_info = title
if track_info:
prefix = (
f"<span color='#a6e3a1'>󰓇 </span>" if player.props.status == "Playing" and player_name == "spotify" else
f"<span color='#f38ba8'>󰗃 </span>" if player.props.status == "Playing" and player_name == "firefox" else
f"<span color='#b4befe'>\u200A󰏤 \u2009\u2009\u200A</span>"
)
track_info = prefix + track_info
current_playing = self.get_first_playing_player()
if current_playing is None or current_playing.props.player_name == player.props.player_name:
self.write_output(track_info, player)
def on_player_appeared(self, _, player):
# Handle new player appearance.
logger.info(f"Player has appeared: {player.name}")
if player.name not in self.excluded_players:
if self.selected_player is None or player.name == self.selected_player:
self.init_player(player)
def on_player_vanished(self, _, player):
# Handle player disappearance.
logger.info(f"Player {player.props.player_name} has vanished")
self.show_most_important_player()
def parse_arguments():
# Parse command-line arguments.
parser = argparse.ArgumentParser()
parser.add_argument("-v", "--verbose", action="count", default=0)
parser.add_argument("-x", "--exclude", help="Comma-separated list of excluded players")
parser.add_argument("--player", help="Specify player to listen to")
parser.add_argument("--enable-logging", action="store_true", help="Enable logging to a file")
return parser.parse_args()
def main():
# Main function to initialize and run the player manager.
arguments = parse_arguments()
# Initialize logging if enabled
if arguments.enable_logging:
logfile = os.path.join(os.path.dirname(os.path.realpath(__file__)), "media-player.log")
logging.basicConfig(
filename=logfile,
level=logging.DEBUG,
format="%(asctime)s %(name)s %(levelname)s:%(lineno)d %(message)s"
)
# Set log level based on verbosity
logger.setLevel(max((3 - arguments.verbose) * 10, 0))
logger.info("Creating player manager")
if arguments.player:
logger.info(f"Filtering for player: {arguments.player}")
if arguments.exclude:
logger.info(f"Excluding players: {arguments.exclude}")
player_manager = PlayerManager(arguments.player, arguments.exclude)
player_manager.run()
if __name__ == "__main__":
main()

View file

@ -0,0 +1,30 @@
#!/usr/bin/env bash
config="$HOME/.config/rofi/power-menu.rasi"
actions=$(echo -e " Lock\n Shutdown\n Reboot\n Suspend\n Hibernate\n Logout")
# Display logout menu
selected_option=$(echo -e "$actions" | rofi -dmenu -i -config "${config}" || pkill -x rofi)
# Perform actions based on the selected option
case "$selected_option" in
*Lock)
loginctl lock-session
;;
*Shutdown)
systemctl poweroff
;;
*Reboot)
systemctl reboot
;;
*Suspend)
systemctl suspend
;;
*Hibernate)
systemctl hibernate
;;
*Logout)
loginctl kill-session "$XDG_SESSION_ID"
;;
esac

View file

@ -0,0 +1,86 @@
#!/usr/bin/env bash
# Check release
if [ ! -f /etc/arch-release ]; then
exit 0
fi
pkg_installed() {
local pkg=$1
if pacman -Qi "${pkg}" &>/dev/null; then
return 0
elif pacman -Qi "flatpak" &>/dev/null && flatpak info "${pkg}" &>/dev/null; then
return 0
elif command -v "${pkg}" &>/dev/null; then
return 0
else
return 1
fi
}
get_aur_helper() {
if pkg_installed yay; then
aur_helper="yay"
elif pkg_installed paru; then
aur_helper="paru"
fi
}
get_aur_helper
export -f pkg_installed
# Trigger upgrade
if [ "$1" == "up" ]; then
trap 'pkill -RTMIN+20 waybar' EXIT
command="
$0 upgrade
${aur_helper} -Syu
if pkg_installed flatpak; then flatpak update; fi
printf '\n'
read -n 1 -p 'Press any key to continue...'
"
kitty --title "󰞒 System Update" sh -c "${command}"
fi
# Check for AUR updates
if [ -n "$aur_helper" ]; then
aur_updates=$(${aur_helper} -Qua | grep -c '^')
else
aur_updates=0
fi
# Check for official repository updates
official_updates=$(
(while pgrep -x checkupdates >/dev/null; do sleep 1; done)
checkupdates | grep -c '^'
)
# Check for Flatpak updates
if pkg_installed flatpak; then
flatpak_updates=$(flatpak remote-ls --updates | grep -c '^')
else
flatpak_updates=0
fi
# Calculate total available updates
total_updates=$((official_updates + aur_updates + flatpak_updates))
# Handle formatting based on AUR helper
if [ "$aur_helper" == "yay" ]; then
[ "${1}" == upgrade ] && printf "Official: %-10s\nAUR ($aur_helper): %-10s\nFlatpak: %-10s\n\n" "$official_updates" "$aur_updates" "$flatpak_updates" && exit
tooltip="Official: $official_updates\nAUR ($aur_helper): $aur_updates\nFlatpak: $flatpak_updates"
elif [ "$aur_helper" == "paru" ]; then
[ "${1}" == upgrade ] && printf "Official: %-10s\nAUR ($aur_helper): %-10s\nFlatpak: %-10s\n\n" "$official_updates" "$aur_updates" "$flatpak_updates" && exit
tooltip="Official: $official_updates\nAUR ($aur_helper): $aur_updates\nFlatpak: $flatpak_updates"
fi
# Module and tooltip
if [ $total_updates -eq 0 ]; then
echo "{\"text\":\"󰸟\", \"tooltip\":\"Packages are up to date\"}"
else
echo "{\"text\":\"󰞒\", \"tooltip\":\"${tooltip//\"/\\\"}\"}"
fi

View file

@ -0,0 +1,123 @@
#!/usr/bin/env bash
# Define functions
print_error() {
cat <<"EOF"
Usage: ./volumecontrol.sh -[device] <actions>
...valid devices are...
i -- input device
o -- output device
p -- player application
...valid actions are...
i -- increase volume [+2]
d -- decrease volume [-2]
m -- mute [x]
EOF
exit 1
}
icon() {
vol=$(pactl get-sink-volume @DEFAULT_SINK@ | awk '{print $5}' | sed 's/%//')
mute=$(pactl get-sink-mute @DEFAULT_SINK@ | awk '{print $2}')
if [ "$mute" = "yes" ] || [ "$vol" -eq 0 ]; then
icon="volume-level-muted"
elif [ "$vol" -lt 33 ]; then
icon="volume-level-low"
elif [ "$vol" -lt 66 ]; then
icon="volume-level-medium"
else
icon="volume-level-high"
fi
}
send_notification() {
icon
notify-send -a "state" -r 91190 -i "$icon" -h int:value:"$vol" "Volume: ${vol}%" -u low
}
notify_mute() {
mute=$(pactl get-sink-mute @DEFAULT_SINK@ | awk '{print $2}')
if [ "$mute" = "yes" ]; then
notify-send -a "state" -r 91190 -i "volume-level-muted" "Volume: Muted" -u low
else
icon
notify-send -a "state" -r 91190 -i "$icon" "Volume: Unmuted" -u low
fi
}
action_volume() {
case "${1}" in
i)
# Increase volume if below 100
current_vol=$(pactl get-sink-volume @DEFAULT_SINK@ | awk '{print $5}' | sed 's/%//')
if [ "$current_vol" -lt 100 ]; then
new_vol=$((current_vol + 2))
[ "$new_vol" -gt 100 ] && new_vol=100
pactl set-sink-volume @DEFAULT_SINK@ "${new_vol}%"
fi
;;
d)
# Decrease volume if above 0
current_vol=$(pactl get-sink-volume @DEFAULT_SINK@ | awk '{print $5}' | sed 's/%//')
new_vol=$((current_vol - 2))
[ "$new_vol" -lt 0 ] && new_vol=0
pactl set-sink-volume @DEFAULT_SINK@ "${new_vol}%"
;;
esac
}
select_output() {
if [ "$@" ]; then
desc="$*"
device=$(pactl list sinks | grep -C2 -F "Description: $desc" | grep Name | cut -d: -f2 | xargs)
if pactl set-default-sink "$device"; then
notify-send -r 91190 "Activated: $desc"
else
notify-send -r 91190 "Error activating $desc"
fi
else
pactl list sinks | grep -ie "Description:" | awk -F ': ' '{print $2}' | sort
fi
}
# Evaluate device option
while getopts iops: DeviceOpt; do
case "${DeviceOpt}" in
i)
nsink=$(pactl list sources short | awk '{print $2}')
[ -z "${nsink}" ] && echo "ERROR: Input device not found..." && exit 0
srce="--default-source"
;;
o)
nsink=$(pactl list sinks short | awk '{print $2}')
[ -z "${nsink}" ] && echo "ERROR: Output device not found..." && exit 0
srce=""
;;
p)
nsink=$(playerctl --list-all | grep -w "${OPTARG}")
[ -z "${nsink}" ] && echo "ERROR: Player ${OPTARG} not active..." && exit 0
# shellcheck disable=SC2034
srce="${nsink}"
;;
s)
# Select an output device
select_output "$@"
exit
;;
*) print_error ;;
esac
done
# Set default variables
shift $((OPTIND - 1))
# Execute action
case "${1}" in
i) action_volume i ;;
d) action_volume d ;;
m) pactl set-sink-mute @DEFAULT_SINK@ toggle && notify_mute && exit 0 ;;
*) print_error ;;
esac
send_notification

View file

@ -0,0 +1,126 @@
#!/usr/bin/env bash
# Author: Jesse Mirabel (@sejjy)
# GitHub: https://github.com/sejjy/mechabar
# Rofi config
config="$HOME/.config/rofi/wifi-menu.rasi"
options=$(
echo "Manual Entry"
echo "Disable Wi-Fi"
)
option_disabled="Enable Wi-Fi"
# Rofi window override
override_ssid="entry { placeholder: \"Enter SSID\"; } listview { enabled: false; }"
override_password="entry { placeholder: \"Enter password\"; } listview { enabled: false; }"
override_disabled="mainbox { children: [ listview ]; } listview { lines: 1; padding: 6px; }"
# Prompt for password
get_password() {
rofi -dmenu -password -config "${config}" -theme-str "${override_password}" -p " " || pkill -x rofi
}
while true; do
wifi_list() {
nmcli --fields "SECURITY,SSID" device wifi list |
tail -n +2 | # Skip the header line from nmcli output
sed 's/ */ /g' | # Replace multiple spaces with a single space
sed -E "s/WPA*.?\S/󰤪 /g" | # Replace 'WPA*' with a Wi-Fi lock icon
sed "s/^--/󰤨 /g" | # Replace '--' (open networks) with an open Wi-Fi icon
sed "s/󰤪 󰤪/󰤪/g" | # Remove duplicate Wi-Fi lock icons
sed "/--/d" | # Remove lines containing '--' (empty SSIDs)
awk '!seen[$0]++' # Filter out duplicate SSIDs
}
# Get Wi-Fi status
wifi_status=$(nmcli -fields WIFI g)
case "$wifi_status" in
*"enabled"*)
selected_option=$(echo "$options"$'\n'"$(wifi_list)" |
rofi -dmenu -i -selected-row 1 -config "${config}" -p " " || pkill -x rofi)
;;
*"disabled"*)
selected_option=$(echo "$option_disabled" |
rofi -dmenu -i -config "${config}" -theme-str "${override_disabled}" || pkill -x rofi)
;;
esac
# Extract selected SSID
read -r selected_ssid <<<"${selected_option:3}"
# Actions based on selected option
case "$selected_option" in
"")
exit
;;
"Enable Wi-Fi")
notify-send "Scanning for networks..."
nmcli radio wifi on
nmcli device wifi rescan
sleep 3
;;
"Disable Wi-Fi")
notify-send "Wi-Fi Disabled"
nmcli radio wifi off
exit
;;
"Manual Entry")
# Prompt for SSID
manual_ssid=$(rofi -dmenu -config "${config}" -theme-str "${override_ssid}" -p " " || pkill -x rofi)
# Exit if no option is selected
if [ -z "$manual_ssid" ]; then
exit
fi
# Prompt for Wi-Fi password
wifi_password=$(get_password)
if [ -z "$wifi_password" ]; then
# Without password
if nmcli device wifi connect "$manual_ssid" | grep -q "successfully"; then
notify-send "Connected to \"$manual_ssid\"."
exit
else
notify-send "Failed to connect to \"$manual_ssid\"."
fi
else
# With password
if nmcli device wifi connect "$manual_ssid" password "$wifi_password" | grep -q "successfully"; then
notify-send "Connected to \"$manual_ssid\"."
exit
else
notify-send "Failed to connect to \"$manual_ssid\"."
fi
fi
;;
*)
# Get saved connections
saved_connections=$(nmcli -g NAME connection)
if echo "$saved_connections" | grep -qw "$selected_ssid"; then
if nmcli connection up id "$selected_ssid" | grep -q "successfully"; then
notify-send "Connected to \"$selected_ssid\"."
exit
else
notify-send "Failed to connect to \"$selected_ssid\"."
fi
else
# Handle secure network connection
if [[ "$selected_option" =~ ^"󰤪" ]]; then
wifi_password=$(get_password)
fi
if nmcli device wifi connect "$selected_ssid" password "$wifi_password" | grep -q "successfully"; then
notify-send "Connected to \"$selected_ssid\"."
exit
else
notify-send "Failed to connect to \"$selected_ssid\"."
fi
fi
;;
esac
done

View file

@ -0,0 +1,176 @@
#!/usr/bin/env bash
# This script gathers detailed Wi-Fi connection information.
# It collects the following fields:
#
# - SSID (Service Set Identifier): The name of the Wi-Fi network you
# are currently connected to. Example: "My_Network"
#
# - IP Address: The IP address assigned to the device by the router.
# This is typically a private IP within the local network. Example:
# "192.168.1.29/24" (with subnet mask)
#
# - Router (Gateway): The IP address of the router (default gateway)
# that your device uses to communicate outside the local network.
# Example: "192.168.1.1"
#
# - MAC Address: The unique Media Access Control address of the local
# device's Wi-Fi adapter. Example: "F8:34:41:07:1B:65"
#
# - Security: The encryption protocol being used to secure your Wi-Fi
# connection. Common security protocols include:
# - WPA2 (Wi-Fi Protected Access 2): The most commonly used security
# standard, offering strong encryption (AES).
# - WPA3: The latest version, providing even stronger security,
# especially in public or open networks.
# - WEP (Wired Equivalent Privacy): An outdated and insecure protocol
# that should not be used.
# Example: "WPA2" indicates that the connection is secured using WPA2
# with AES encryption.
#
# - BSSID (Basic Service Set Identifier): The MAC address of the Wi-Fi
# access point you are connected to. Example: "A4:22:49:DA:91:A0"
#
# - Channel: The wireless channel your Wi-Fi network is using. This is
# associated with the frequency band. Example: "100 (5500 MHz)"
# indicates the channel number (100) and the frequency (5500 MHz),
# which is within the 5 GHz band.
#
# - RSSI (Received Signal Strength Indicator): The strength of the
# Wi-Fi signal, typically in dBm (decibels relative to 1 milliwatt).
# Closer to 0 means stronger signal, with values like -40 dBm being
# very good. Example: "-40 dBm"
#
# - Signal: The signal quality, which is represented as a percentage,
# where higher numbers mean better signal. Example: "100"
# indicates perfect signal strength.
#
# - Rx Rate (Receive Rate): The maximum data rate (in Mbit/s) at which
# the device can receive data from the Wi-Fi access point. Example:
# "866.7 MBit/s" indicates a high-speed connection on a modern
# standard.
#
# - Tx Rate (Transmit Rate): The maximum data rate (in Mbit/s) at
# which the device can send data to the Wi-Fi access point. Example:
# "866.7 MBit/s"
#
# - PHY Mode (Physical Layer Mode): The Wi-Fi protocol or standard in
# use. Common modes include 802.11n, 802.11ac, and 802.11ax (Wi-Fi
# 6). Example: "802.11ac" indicates you're using the 5 GHz band with
# a modern high-speed standard.
if ! command -v nmcli &>/dev/null; then
echo "{\"text\": \"󰤫\", \"tooltip\": \"nmcli utility is missing\"}"
exit 1
fi
# Check if Wi-Fi is enabled
wifi_status=$(nmcli radio wifi)
if [ "$wifi_status" = "disabled" ]; then
echo "{\"text\": \"󰤮\", \"tooltip\": \"Wi-Fi Disabled\"}"
exit 0
fi
wifi_info=$(nmcli -t -f active,ssid,signal,security dev wifi | grep "^yes")
# If no ESSID is found, set a default value
if [ -z "$wifi_info" ]; then
essid="No Connection"
signal=0
tooltip="No Connection"
else
# Some defaults
ip_address="127.0.0.1"
# gateway="127.0.0.1"
# mac_address="N/A"
security=$(echo "$wifi_info" | awk -F: '{print $4}')
# bssid="N/A"
chan="N/A"
# rssi="N/A"
# rx_bitrate=""
# tx_bitrate=""
# phy_mode=""
signal=$(echo "$wifi_info" | awk -F: '{print $3}')
active_device=$(nmcli -t -f DEVICE,STATE device status |
grep -w "connected" |
grep -v -E "^(dummy|lo:)" |
awk -F: '{print $1}')
if [ -n "$active_device" ]; then
output=$(nmcli -e no -g ip4.address,ip4.gateway,general.hwaddr device show "$active_device")
ip_address=$(echo "$output" | sed -n '1p')
# gateway=$(echo "$output" | sed -n '2p')
# mac_address=$(echo "$output" | sed -n '3p')
line=$(nmcli -e no -t -f active,bssid,chan,freq device wifi | grep "^yes")
# bssid=$(echo "$line" | awk -F':' '{print $2":"$3":"$4":"$5":"$6":"$7}')
chan=$(echo "$line" | awk -F':' '{print $8}')
freq=$(echo "$line" | awk -F':' '{print $9}')
chan="$chan ($freq)"
# if command -v iw &>/dev/null; then
# iw_output=$(iw dev "$active_device" station dump)
# rssi=$(echo "$iw_output" | grep "signal:" | awk '{print $2 " dBm"}')
# Upload speed
# rx_bitrate=$(echo "$iw_output" | grep "rx bitrate:" | awk '{print $3 " " $4}')
# Download speed
# tx_bitrate=$(echo "$iw_output" | grep "tx bitrate:" | awk '{print $3 " " $4}')
# Physical Layer Mode
# if echo "$iw_output" | grep -E -q "rx bitrate:.* VHT"; then
# phy_mode="802.11ac" # Wi-Fi 5
# elif echo "$iw_output" | grep -E -q "rx bitrate:.* HT"; then
# phy_mode="802.11n" # Wi-Fi 4
# elif echo "$iw_output" | grep -E -q "rx bitrate:.* HE"; then
# phy_mode="802.11ax" # Wi-Fi 6
# fi
# fi
# Get the current Wi-Fi ESSID
essid=$(echo "$wifi_info" | awk -F: '{print $2}')
tooltip="${essid}\n"
tooltip+="\nIP Address: ${ip_address}"
# tooltip+="\nRouter: ${gateway}"
# tooltip+="\nMAC Address: ${mac_address}"
tooltip+="\nSecurity: ${security}"
# tooltip+="\nBSSID: ${bssid}"
tooltip+="\nChannel: ${chan}"
# tooltip+="\nRSSI: ${rssi}"
tooltip+="\nStrength: ${signal} / 100"
# if [ -n "$rx_bitrate" ]; then
# tooltip+="\nRx Rate: ${rx_bitrate}"
# fi
# if [ -n "$tx_bitrate" ]; then
# tooltip+="\nTx Rate: ${tx_bitrate}"
# fi
# if [ -n "$phy_mode" ]; then
# tooltip+="\nPHY Mode: ${phy_mode}"
# fi
fi
fi
# Determine Wi-Fi icon based on signal strength
if [ "$signal" -ge 80 ]; then
icon="󰤨" # Strong signal
elif [ "$signal" -ge 60 ]; then
icon="󰤥" # Good signal
elif [ "$signal" -ge 40 ]; then
icon="󰤢" # Weak signal
elif [ "$signal" -ge 20 ]; then
icon="󰤟" # Very weak signal
else
icon="󰤯" # No signal
fi
# Module and tooltip
echo "{\"text\": \"${icon}\", \"tooltip\": \"${tooltip}\"}"