diff --git a/alacritty b/alacritty new file mode 100755 index 0000000..41593c7 --- /dev/null +++ b/alacritty @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +## Copyright (C) 2020-2024 Aditya Shakya +## +## launch alacritty with alt config + +CONFIG="$HOME/.config/hypr/alacritty/alacritty.toml" + +if [ "$1" == "-f" ]; then + alacritty --class 'alacritty-float,alacritty-float' --config-file "$CONFIG" +elif [ "$1" == "-F" ]; then + alacritty --class 'alacritty-fullscreen,alacritty-fullscreen' --config-file "$CONFIG" \ + -o window.startup_mode="'Fullscreen'" \ + window.padding.x=30 window.padding.y=30 \ + window.opacity=0.95 font.size=14 +else + alacritty --config-file "$CONFIG" ${@} +fi diff --git a/asroot b/asroot new file mode 100755 index 0000000..e686006 --- /dev/null +++ b/asroot @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +# Directory containing the script +DIR="$HOME/.config/hypr" + +# Rofi sudo askpass helper +export SUDO_ASKPASS="$DIR/scripts/rofi_askpass" + +# Check if a command is provided +if [ -z "$1" ]; then + echo "Usage: $0 " + exit 1 +fi + +# Execute the application with sudo +if ! sudo -E -A "$@"; then + echo "Failed to execute command with sudo." + exit 1 +fi + diff --git a/brightness b/brightness new file mode 100755 index 0000000..e3fdae5 --- /dev/null +++ b/brightness @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +## Copyright (C) 2020-2024 Aditya Shakya +## +## Script To Manage Brightness For Archcraft (in Wayland). + +iDIR="$HOME/.config/hypr/mako/icons" + +# Get brightness +get_backlight() { + LIGHT=$(printf "%.0f\n" `light -G`) + echo "${LIGHT}%" +} + +# Get icons +get_icon() { + backlight="$(get_backlight)" + current="${backlight%%%}" + if [[ ("$current" -ge "0") && ("$current" -le "20") ]]; then + icon="$iDIR"/brightness-20.png + elif [[ ("$current" -ge "20") && ("$current" -le "40") ]]; then + icon="$iDIR"/brightness-40.png + elif [[ ("$current" -ge "40") && ("$current" -le "60") ]]; then + icon="$iDIR"/brightness-60.png + elif [[ ("$current" -ge "60") && ("$current" -le "80") ]]; then + icon="$iDIR"/brightness-80.png + elif [[ ("$current" -ge "80") && ("$current" -le "100") ]]; then + icon="$iDIR"/brightness-100.png + fi +} + +# Notify +notify_user() { + notify-send -h string:x-canonical-private-synchronous:sys-notify-backlight -u low -i "$icon" "Brightness : $(get_backlight)" +} + +# Increase brightness +inc_backlight() { + light -A 5 && get_icon && notify_user +} + +# Decrease brightness +dec_backlight() { + light -U 5 && get_icon && notify_user +} + +# Execute accordingly +if [[ "$1" == "--get" ]]; then + get_backlight +elif [[ "$1" == "--inc" ]]; then + inc_backlight +elif [[ "$1" == "--dec" ]]; then + dec_backlight +else + get_backlight +fi diff --git a/colorpicker b/colorpicker new file mode 100755 index 0000000..484df65 --- /dev/null +++ b/colorpicker @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +## Copyright (C) 2020-2024 Aditya Shakya +## +## Simple Script To Pick Color Quickly. + +#color=$(grim -g "`slurp -b 00000000 -p`" -t ppm - | convert - -format '%[pixel:p{0,0}]' txt:- | tail -n1 | cut -d' ' -f4) +color=`$(which hyprpicker)` +image=/tmp/${color}.png + +main() { + if [[ "$color" ]]; then + # copy color code to clipboard + echo $color | tr -d "\n" | wl-copy + # generate preview + convert -size 48x48 xc:"$color" ${image} + # notify about it + notify-send -h string:x-canonical-private-synchronous:sys-notify-picker -u low -i ${image} "$color, copied to clipboard." + fi +} + +# Run the script +main diff --git a/config-backup.sh b/config-backup.sh index 0b0c470..23ff0f7 100755 --- a/config-backup.sh +++ b/config-backup.sh @@ -5,7 +5,9 @@ SRC="/home/belar/.config" DST_DIR=/mnt/nas_belar/rsync/config-backup/ # Sync the source directory to the destination directory -/usr/bin/rsync -CERrltm --delete "${SRC}" "${DST_DIR}" +#/usr/bin/rsync -CERrltm --delete "${SRC}" "${DST_DIR}" +/usr/bin/rsync -CERrltm --delete "${SRC}" truenas-belar:/mnt/DATA/USER_DATA/belar/rsync + # Change to the Git repository directory cd $DST_DIR diff --git a/foot b/foot new file mode 100755 index 0000000..7028a9c --- /dev/null +++ b/foot @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +## Copyright (C) 2020-2024 Aditya Shakya +## +## launch terminal with alt config + +# Get Colors +DIR="$HOME/.config/hypr" +background="`cat $DIR/rofi/shared/colors.rasi | grep 'background:' | cut -d':' -f2 | tr -d ' '\;`" +accent="`cat $DIR/rofi/shared/colors.rasi | grep 'selected:' | cut -d':' -f2 | tr -d ' '\;`" + +CONFIG="$HOME/.config/hypr/foot/foot.ini" + +if [ "$1" == "-f" ]; then + foot --app-id='foot-float' --config="$CONFIG" +elif [ "$1" == "-F" ]; then + foot --fullscreen --app-id='foot-full' --font="Iosevka Nerd Font:size=14" --override=pad=35x35 --config="$CONFIG" +elif [ "$1" == "-s" ]; then + foot --app-id='foot-float' --config="$CONFIG" \ + --window-size-pixels=$(slurp -b ${background:1}CC -c ${accent:1}ff -s ${accent:1}0D -w 2 -f "%wx%h") +else + foot --config="$CONFIG" ${@} +fi diff --git a/gtkthemes b/gtkthemes new file mode 100755 index 0000000..b1bf5db --- /dev/null +++ b/gtkthemes @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +## Copyright (C) 2020-2024 Aditya Shakya +## +## Set GTK Themes, Icons, Cursor and Fonts + +THEME='Manhattan' +ICONS='Luv-Folders-Dark' +FONT='Noto Sans 9' +CURSOR='Qogirr-Dark' + +SCHEMA='gsettings set org.gnome.desktop.interface' + +apply_themes () { + ${SCHEMA} gtk-theme "$THEME" + ${SCHEMA} icon-theme "$ICONS" + ${SCHEMA} cursor-theme "$CURSOR" + ${SCHEMA} font-name "$FONT" +} + +apply_themes diff --git a/kitty b/kitty new file mode 100755 index 0000000..1efbd6f --- /dev/null +++ b/kitty @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +## Copyright (C) 2020-2024 Aditya Shakya +## +## launch kitty with hypr config + +# hypr directory +DIR="$HOME/.config/hypr" +CONFIG="$DIR/kitty/kitty.conf" + +if [ "$1" == "-f" ]; then + kitty --class 'kitty-float' --config "$CONFIG" +elif [ "$1" == "-F" ]; then + kitty --class 'kitty-fullscreen' --config "$CONFIG" \ + --start-as fullscreen \ + --override 'window_padding_width=30' \ + --override 'font_size=14' \ + --override 'background_opacity=0.95' +else + kitty --config "$CONFIG" ${@} +fi diff --git a/lockscreen b/lockscreen new file mode 100755 index 0000000..9b4a7c4 --- /dev/null +++ b/lockscreen @@ -0,0 +1,72 @@ +#!/usr/bin/env bash + +## Copyright (C) 2020-2024 Aditya Shakya + +# Source Theme file +DIR="$HOME/.config/hypr" +source "$DIR"/theme/current.bash + +# Colors +bg=${background:1} fg=${foreground:1} +red=${color1:1} green=${color2:1} yellow=${color3:1} +blue=${color4:1} magenta=${color5:1} cyan=${color6:1} +alpha='00000000' + +# CMD +swaylock -f \ + \ + `# General` \ + --ignore-empty-password \ + --show-failed-attempts \ + --hide-keyboard-layout \ + --indicator-caps-lock \ + \ + `# Appearance` \ + --color ${bg}E6 \ + --font 'JetBrainsMono Nerd Font' --font-size 18 \ + \ + `# Backspace Key` \ + --key-hl-color ${green} \ + --caps-lock-key-hl-color ${blue} \ + --bs-hl-color ${red} \ + --caps-lock-bs-hl-color ${red} \ + \ + `# Indicator` \ + --indicator-radius 120 \ + --indicator-thickness 10 \ + \ + `# Inside Circle Colors` \ + --inside-color ${alpha} \ + --inside-clear-color ${alpha} \ + --inside-caps-lock-color ${alpha} \ + --inside-ver-color ${blue} \ + --inside-wrong-color ${red} \ + \ + `# Layout Colors` \ + --layout-bg-color ${cyan} \ + --layout-border-color ${cyan} \ + --layout-text-color ${bg} \ + \ + `# Line Colors` \ + --line-color ${bg} \ + --line-clear-color ${red} \ + --line-caps-lock-color ${bg} \ + --line-ver-color ${bg} \ + --line-wrong-color ${bg} \ + \ + `# Ring Colors` \ + --ring-color ${cyan} \ + --ring-clear-color ${bg} \ + --ring-caps-lock-color ${magenta} \ + --ring-ver-color ${blue} \ + --ring-wrong-color ${red} \ + \ + `# Separator Color` \ + --separator-color ${bg} \ + \ + `# Text Colors` \ + --text-color ${fg} \ + --text-clear-color ${fg} \ + --text-caps-lock-color ${fg} \ + --text-ver-color ${bg} \ + --text-wrong-color ${bg} diff --git a/mako/config b/mako/config new file mode 100644 index 0000000..537ae40 --- /dev/null +++ b/mako/config @@ -0,0 +1,54 @@ +## Copyright (C) 2020-2024 Aditya Shakya +## +## Mako configuration file + +# GLOBAL CONFIGURATION OPTIONS +max-history=100 +sort=-time + +# BINDING OPTIONS +on-button-left=dismiss +on-button-middle=none +on-button-right=dismiss-all +on-touch=dismiss +on-notify=exec mpv /usr/share/sounds/freedesktop/stereo/message.oga + +# STYLE OPTIONS +font=JetBrains Mono 10 +width=300 +height=100 +margin=10 +padding=15 +border-size=2 +border-radius=0 +icons=1 +max-icon-size=48 +icon-location=left +markup=1 +actions=1 +history=1 +text-alignment=left +default-timeout=5000 +ignore-timeout=0 +max-visible=5 +layer=overlay +anchor=top-right + +# Mako_Colors +background-color=#3d3942 +text-color=#e0dde2 +border-color=#49454f +progress-color=over #C3B2CD + +[urgency=low] +border-color=#49454f +default-timeout=2000 + +[urgency=normal] +border-color=#49454f +default-timeout=5000 + +[urgency=high] +border-color=#9A9EAA +text-color=#9A9EAA +default-timeout=0 diff --git a/mako/icons/brightness-100.png b/mako/icons/brightness-100.png new file mode 100644 index 0000000..6656c80 Binary files /dev/null and b/mako/icons/brightness-100.png differ diff --git a/mako/icons/brightness-20.png b/mako/icons/brightness-20.png new file mode 100644 index 0000000..4907992 Binary files /dev/null and b/mako/icons/brightness-20.png differ diff --git a/mako/icons/brightness-40.png b/mako/icons/brightness-40.png new file mode 100644 index 0000000..41b0584 Binary files /dev/null and b/mako/icons/brightness-40.png differ diff --git a/mako/icons/brightness-60.png b/mako/icons/brightness-60.png new file mode 100644 index 0000000..66596fa Binary files /dev/null and b/mako/icons/brightness-60.png differ diff --git a/mako/icons/brightness-80.png b/mako/icons/brightness-80.png new file mode 100644 index 0000000..4952211 Binary files /dev/null and b/mako/icons/brightness-80.png differ diff --git a/mako/icons/dropper.png b/mako/icons/dropper.png new file mode 100644 index 0000000..a2c0288 Binary files /dev/null and b/mako/icons/dropper.png differ diff --git a/mako/icons/microphone-mute.png b/mako/icons/microphone-mute.png new file mode 100644 index 0000000..1780e33 Binary files /dev/null and b/mako/icons/microphone-mute.png differ diff --git a/mako/icons/microphone.png b/mako/icons/microphone.png new file mode 100644 index 0000000..d1b6d76 Binary files /dev/null and b/mako/icons/microphone.png differ diff --git a/mako/icons/music.png b/mako/icons/music.png new file mode 100644 index 0000000..648bcdc Binary files /dev/null and b/mako/icons/music.png differ diff --git a/mako/icons/palette.png b/mako/icons/palette.png new file mode 100644 index 0000000..0e65534 Binary files /dev/null and b/mako/icons/palette.png differ diff --git a/mako/icons/picture.png b/mako/icons/picture.png new file mode 100644 index 0000000..233d9db Binary files /dev/null and b/mako/icons/picture.png differ diff --git a/mako/icons/timer.png b/mako/icons/timer.png new file mode 100644 index 0000000..f37ae53 Binary files /dev/null and b/mako/icons/timer.png differ diff --git a/mako/icons/volume-high.png b/mako/icons/volume-high.png new file mode 100644 index 0000000..26f83cb Binary files /dev/null and b/mako/icons/volume-high.png differ diff --git a/mako/icons/volume-low.png b/mako/icons/volume-low.png new file mode 100644 index 0000000..2a81d5e Binary files /dev/null and b/mako/icons/volume-low.png differ diff --git a/mako/icons/volume-mid.png b/mako/icons/volume-mid.png new file mode 100644 index 0000000..01790b8 Binary files /dev/null and b/mako/icons/volume-mid.png differ diff --git a/mako/icons/volume-mute.png b/mako/icons/volume-mute.png new file mode 100644 index 0000000..a5d32e0 Binary files /dev/null and b/mako/icons/volume-mute.png differ diff --git a/minecraft/server.jar b/minecraft/server.jar deleted file mode 100644 index 9da97d3..0000000 Binary files a/minecraft/server.jar and /dev/null differ diff --git a/notifications b/notifications new file mode 100755 index 0000000..2daa47b --- /dev/null +++ b/notifications @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +## Copyright (C) 2020-2024 Aditya Shakya +## +## launch mako with alt config + +CONFIG="$HOME/.config/hypr/mako/config" + +if [[ ! `pidof mako` ]]; then + mako --config ${CONFIG} +fi diff --git a/rofi/askpass.rasi b/rofi/askpass.rasi new file mode 100644 index 0000000..9ab321f --- /dev/null +++ b/rofi/askpass.rasi @@ -0,0 +1,76 @@ +/** + * Copyright (C) 2020-2024 Aditya Shakya + **/ + +/*****----- Global Properties -----*****/ +@import "shared/colors.rasi" +@import "shared/fonts.rasi" + +/*****----- Main Window -----*****/ +window { + location: center; + anchor: center; + fullscreen: false; + width: 350px; + x-offset: 0px; + y-offset: 0px; + margin: 0px; + padding: 30px; + border: 2px solid; + border-radius: 0px; + border-color: @background-alt; + background-color: @background; + cursor: "default"; + children: [ "inputbar", "listview" ]; +} + +/*****----- Inputbar -----*****/ +inputbar { + enabled: true; + spacing: 10px; + margin: 0px; + padding: 0px; + border: 0px; + border-radius: 0px; + border-color: @selected; + background-color: transparent; + text-color: @foreground; + children: [ "textbox-prompt-colon", "prompt", "entry" ]; +} + +textbox-prompt-colon { + enabled: true; + expand: false; + str: ""; + padding: 10px 12px; + border-radius: 0px; +/* background-image: linear-gradient(to right, #E06B74, #C778DD); */ + background-color: var(urgent); + text-color: @background; +} +prompt { + enabled: true; + padding: 10px 12px; + border-radius: 0px; +/* background-image: linear-gradient(to right, #E06B74, #C778DD); */ + background-color: var(active); + text-color: @background; +} +entry { + enabled: true; + padding: 10px 12px; + border: 0px 0px 0px 0px; + border-radius: 0px; + border-color: @selected; + background-color: @background-alt; + text-color: inherit; + cursor: text; + placeholder: "Password"; + placeholder-color: inherit; +} + +/*****----- Listview -----*****/ +listview { + enabled: false; +} + diff --git a/rofi/asroot.rasi b/rofi/asroot.rasi new file mode 100644 index 0000000..259b980 --- /dev/null +++ b/rofi/asroot.rasi @@ -0,0 +1,148 @@ +/** + * Copyright (C) 2020-2024 Aditya Shakya + **/ + +/*****----- Configuration -----*****/ +configuration { + show-icons: false; +} + +/*****----- Global Properties -----*****/ +@import "shared/colors.rasi" +@import "shared/fonts.rasi" + +/* +USE_ICON=YES +*/ + +/*****----- Main Window -----*****/ +window { + transparency: "real"; + location: center; + anchor: center; + fullscreen: false; + width: 440px; + x-offset: 0px; + y-offset: 0px; + margin: 0px; + padding: 0px; + border: 2px solid; + border-radius: 0px; + border-color: @background-alt; + cursor: "default"; + background-color: @background; +} + +/*****----- Main Box -----*****/ +mainbox { + enabled: true; + spacing: 10px; + margin: 0px; + padding: 30px; + background-color: transparent; + children: [ "inputbar", "message", "listview" ]; +} + +/*****----- Inputbar -----*****/ +inputbar { + enabled: true; + spacing: 10px; + padding: 0px; + border: 0px; + border-radius: 0px; + border-color: @selected; + background-color: transparent; + text-color: @foreground; + children: [ "textbox-prompt-colon", "prompt"]; +} + +textbox-prompt-colon { + enabled: true; + expand: false; + str: ""; + padding: 10px 12px; + border-radius: 0px; + background-color: var(urgent); + text-color: @background; +} +prompt { + enabled: true; + padding: 10px; + border-radius: 0px; + background-color: var(active); + text-color: @background; +} + +/*****----- Message -----*****/ +message { + enabled: true; + margin: 0px; + padding: 10px; + border: 0px solid; + border-radius: 0px; + border-color: @selected; + background-color: @background-alt; + text-color: @foreground; +} +textbox { + background-color: inherit; + text-color: inherit; + vertical-align: 0.5; + horizontal-align: 0.0; +} + +/*****----- Listview -----*****/ +listview { + enabled: true; + columns: 6; + lines: 1; + cycle: true; + scrollbar: false; + layout: vertical; + + spacing: 10px; + background-color: transparent; + cursor: "default"; +} + +/*****----- Elements -----*****/ +element { + enabled: true; + padding: 15px; + border: 0px solid; + border-radius: 0px; + border-color: @selected; + background-color: transparent; + text-color: @foreground; + cursor: pointer; +} +element-text { + font: "feather 20"; + background-color: transparent; + text-color: inherit; + cursor: inherit; + vertical-align: 0.5; + horizontal-align: 0.5; +} + +element normal.normal, +element alternate.normal { + background-color: var(background-alt); + text-color: var(foreground); +} +element normal.urgent, +element alternate.urgent, +element selected.active { + background-color: var(urgent); + text-color: var(background); +} +element normal.active, +element alternate.active, +element selected.urgent { + background-color: var(active); + text-color: var(background); +} +element selected.normal { + background-color: var(selected); + text-color: var(background); +} diff --git a/rofi/bluetooth.rasi b/rofi/bluetooth.rasi new file mode 100644 index 0000000..5ede7a3 --- /dev/null +++ b/rofi/bluetooth.rasi @@ -0,0 +1,202 @@ +/** + * Copyright (C) 2020-2024 Aditya Shakya + **/ + +/*****----- Configuration -----*****/ +configuration { + modi: "drun,run,filebrowser"; + show-icons: false; + drun-display-format: "{name}"; +} + +/*****----- Global Properties -----*****/ +@import "shared/colors.rasi" +@import "shared/fonts.rasi" + +/*****----- Main Window -----*****/ +window { + /* properties for window widget */ + transparency: "real"; + location: center; + anchor: center; + fullscreen: false; + width: 500px; + x-offset: 0px; + y-offset: 0px; + + /* properties for all widgets */ + enabled: true; + margin: 0px; + padding: 0px; + border: 2px solid; + border-radius: 0px; + border-color: @background-alt; + cursor: "default"; + background-color: @background; +} + +/*****----- Main Box -----*****/ +mainbox { + enabled: true; + spacing: 10px; + margin: 0px; + padding: 30px; + background-color: transparent; + children: [ "inputbar", "listview" ]; +} + +/*****----- Inputbar -----*****/ +inputbar { + enabled: true; + spacing: 10px; + margin: 0px; + padding: 0px; + border-radius: 0px; + background-color: transparent; + text-color: @foreground; + children: [ "textbox-prompt-colon", "prompt" ]; +} + +prompt { + enabled: true; + padding: 8px; + border-radius: 0px; + background-color: var(active); + text-color: @background; +} +textbox-prompt-colon { + enabled: true; + expand: false; + str: ""; + padding: 8px 10px; + border-radius: 0px; + background-color: var(urgent); + text-color: @background; +} +entry { + enabled: true; + padding: 8px 0px; + background-color: inherit; + text-color: inherit; + cursor: text; + placeholder: ""; + placeholder-color: inherit; +} + +/*****----- Listview -----*****/ +listview { + enabled: true; + columns: 1; + lines: 7; + cycle: true; + dynamic: true; + scrollbar: false; + layout: vertical; + reverse: false; + fixed-height: true; + fixed-columns: true; + + spacing: 5px; + background-color: transparent; + text-color: @foreground; + cursor: "default"; +} +scrollbar { + handle-width: 5px ; + handle-color: @selected; + border-radius: 10px; + background-color: @background-alt; +} + +/*****----- Elements -----*****/ +element { + enabled: true; + spacing: 10px; + margin: 0px; + padding: 8px; + border-radius: 0px; + background-color: transparent; + text-color: @foreground; + cursor: pointer; +} +element normal.normal, +element alternate.normal { + background-color: var(background); + text-color: var(foreground); +} +element normal.urgent, +element alternate.urgent, +element selected.active { + background-color: var(urgent); + text-color: var(background); +} +element normal.active, +element alternate.active, +element selected.urgent { + background-color: var(active); + text-color: var(background); +} +element selected.normal { + background-color: var(selected); + text-color: var(background); +} +element-icon { + background-color: transparent; + text-color: inherit; + size: 24px; + cursor: inherit; +} +element-text { + background-color: transparent; + text-color: inherit; + highlight: inherit; + cursor: inherit; + vertical-align: 0.5; + horizontal-align: 0.0; +} + +/*****----- Mode Switcher -----*****/ +mode-switcher{ + enabled: true; + spacing: 10px; + margin: 0px; + padding: 0px; + background-color: transparent; + text-color: @foreground; +} +button { + padding: 8px 12px; + border-radius: 12px; + background-color: @background-alt; + text-color: inherit; + cursor: pointer; +} +button selected { + background-image: linear-gradient(to right, #E06B74, #C778DD); + text-color: var(background); +} + +/*****----- Message -----*****/ +message { + enabled: true; + margin: 0px; + padding: 8px 12px; + border-radius: 12px; + background-color: @background-alt; + text-color: @foreground; +} +textbox { + background-color: transparent; + text-color: @foreground; + vertical-align: 0.5; + horizontal-align: 0.0; + highlight: none; + placeholder-color: @foreground; + blink: true; + markup: true; +} +error-message { + padding: 30px; + background-color: @background; + text-color: @foreground; +} diff --git a/rofi/confirm.rasi b/rofi/confirm.rasi new file mode 100644 index 0000000..80e31a3 --- /dev/null +++ b/rofi/confirm.rasi @@ -0,0 +1,148 @@ +/** + * Copyright (C) 2020-2024 Aditya Shakya + **/ + +/*****----- Configuration -----*****/ +configuration { + show-icons: false; +} + +/*****----- Global Properties -----*****/ +@import "shared/colors.rasi" +@import "shared/fonts.rasi" + +/* +USE_ICON=YES +*/ + +/*****----- Main Window -----*****/ +window { + transparency: "real"; + location: center; + anchor: center; + fullscreen: false; + width: 300px; + x-offset: 0px; + y-offset: 0px; + margin: 0px; + padding: 0px; + border: 2px solid; + border-radius: 0px; + border-color: @background-alt; + cursor: "default"; + background-color: @background; +} + +/*****----- Main Box -----*****/ +mainbox { + enabled: true; + spacing: 10px; + margin: 0px; + padding: 30px; + background-color: transparent; + children: [ "inputbar", "message", "listview" ]; +} + +/*****----- Inputbar -----*****/ +inputbar { + enabled: true; + spacing: 10px; + padding: 0px; + border: 0px; + border-radius: 0px; + border-color: @selected; + background-color: transparent; + text-color: @foreground; + children: [ "textbox-prompt-colon", "prompt"]; +} + +textbox-prompt-colon { + enabled: true; + expand: false; + str: ""; + padding: 10px 12px; + border-radius: 0px; + background-color: var(urgent); + text-color: @background; +} +prompt { + enabled: true; + padding: 10px; + border-radius: 0px; + background-color: var(active); + text-color: @background; +} + +/*****----- Message -----*****/ +message { + enabled: true; + margin: 0px; + padding: 10px; + border: 0px solid; + border-radius: 0px; + border-color: @selected; + background-color: @background-alt; + text-color: @foreground; +} +textbox { + background-color: inherit; + text-color: inherit; + vertical-align: 0.5; + horizontal-align: 0.0; +} + +/*****----- Listview -----*****/ +listview { + enabled: true; + columns: 6; + lines: 1; + cycle: true; + scrollbar: false; + layout: vertical; + + spacing: 10px; + background-color: transparent; + cursor: "default"; +} + +/*****----- Elements -----*****/ +element { + enabled: true; + padding: 2px; + border: 0px solid; + border-radius: 0px; + border-color: @selected; + background-color: transparent; + text-color: @foreground; + cursor: pointer; +} +element-text { + font: "feather 20"; + background-color: transparent; + text-color: inherit; + cursor: inherit; + vertical-align: 0.5; + horizontal-align: 0.5; +} + +element normal.normal, +element alternate.normal { + background-color: var(background-alt); + text-color: var(foreground); +} +element normal.urgent, +element alternate.urgent, +element selected.active { + background-color: var(urgent); + text-color: var(background); +} +element normal.active, +element alternate.active, +element selected.urgent { + background-color: var(active); + text-color: var(background); +} +element selected.normal { + background-color: var(selected); + text-color: var(background); +} diff --git a/rofi/launcher.rasi b/rofi/launcher.rasi new file mode 100644 index 0000000..0f7d840 --- /dev/null +++ b/rofi/launcher.rasi @@ -0,0 +1,202 @@ +/** + * Copyright (C) 2020-2024 Aditya Shakya + **/ + +/*****----- Configuration -----*****/ +configuration { + modi: "drun,run,filebrowser"; + show-icons: true; + display-drun: ""; + display-run: ""; + display-filebrowser: ""; + drun-display-format: "{name}"; +} + +/*****----- Global Properties -----*****/ +@import "shared/colors.rasi" +@import "shared/fonts.rasi" + +/*****----- Main Window -----*****/ +window { + /* properties for window widget */ + transparency: "real"; + location: center; + anchor: center; + fullscreen: false; + width: 800px; + x-offset: 0px; + y-offset: 0px; + + /* properties for all widgets */ + enabled: true; + margin: 0px; + padding: 0px; + border: 2px solid; + border-radius: 0px; + border-color: @background-alt; + cursor: "default"; + background-color: @background; +} + +/*****----- Main Box -----*****/ +mainbox { + enabled: true; + spacing: 10px; + margin: 0px; + padding: 30px; + background-color: transparent; + children: [ "inputbar", "message", "listview", "mode-switcher" ]; +} + +/*****----- Inputbar -----*****/ +inputbar { + enabled: true; + spacing: 10px; + margin: 0px; + padding: 10px; + border-radius: 0px; + background-color: @background-alt; + text-color: @foreground; + children: [ "textbox-prompt-colon", "entry" ]; +} + +prompt { + enabled: true; + background-color: inherit; + text-color: inherit; +} +textbox-prompt-colon { + enabled: true; + padding: 0px; + expand: false; + str: ""; + background-color: inherit; + text-color: inherit; +} +entry { + enabled: true; + padding: 0px; + background-color: inherit; + text-color: inherit; + cursor: text; + placeholder: "Search..."; + placeholder-color: inherit; +} + +/*****----- Listview -----*****/ +listview { + enabled: true; + columns: 2; + lines: 7; + cycle: true; + dynamic: true; + scrollbar: false; + layout: vertical; + reverse: false; + fixed-height: true; + fixed-columns: true; + + spacing: 5px; + background-color: transparent; + text-color: @foreground; + cursor: "default"; +} +scrollbar { + handle-width: 5px ; + handle-color: @selected; + border-radius: 10px; + background-color: @background-alt; +} + +/*****----- Elements -----*****/ +element { + enabled: true; + spacing: 10px; + margin: 0px; + padding: 6px; + border-radius: 0px; + background-color: transparent; + text-color: @foreground; + cursor: pointer; +} +element normal.normal, +element alternate.normal { + background-color: var(background); + text-color: var(foreground); +} +element normal.urgent, +element alternate.urgent, +element selected.active { + background-color: var(urgent); + text-color: var(background); +} +element normal.active, +element alternate.active, +element selected.urgent { + background-color: var(active); + text-color: var(background); +} +element selected.normal { + background-color: var(selected); + text-color: var(background); +} +element-icon { + background-color: transparent; + text-color: inherit; + size: 24px; + cursor: inherit; +} +element-text { + background-color: transparent; + text-color: inherit; + highlight: inherit; + cursor: inherit; + vertical-align: 0.5; + horizontal-align: 0.0; +} + +/*****----- Mode Switcher -----*****/ +mode-switcher{ + enabled: true; + spacing: 10px; + margin: 0px; + padding: 0px 250px; + background-color: transparent; + text-color: @foreground; +} +button { + padding: 10px; + border-radius: 0px; + background-color: @background-alt; + text-color: inherit; + cursor: pointer; +} +button selected { + background-color: var(urgent); + text-color: var(background); +} + +/*****----- Message -----*****/ +message { + enabled: true; + margin: 0px; + padding: 10px; + border-radius: 0px; + background-color: @background-alt; + text-color: @foreground; +} +textbox { + background-color: transparent; + text-color: @foreground; + vertical-align: 0.5; + horizontal-align: 0.0; + highlight: none; + placeholder-color: @foreground; + blink: true; + markup: true; +} +error-message { + padding: 30px; + background-color: @background; + text-color: @foreground; +} diff --git a/rofi/music.rasi b/rofi/music.rasi new file mode 100644 index 0000000..3eb97bd --- /dev/null +++ b/rofi/music.rasi @@ -0,0 +1,148 @@ +/** + * Copyright (C) 2020-2024 Aditya Shakya + **/ + +/*****----- Configuration -----*****/ +configuration { + show-icons: false; +} + +/*****----- Global Properties -----*****/ +@import "shared/colors.rasi" +@import "shared/fonts.rasi" + +/* +USE_ICON=YES +*/ + +/*****----- Main Window -----*****/ +window { + transparency: "real"; + location: center; + anchor: center; + fullscreen: false; + width: 510px; + x-offset: 0px; + y-offset: 0px; + margin: 0px; + padding: 0px; + border: 2px solid; + border-radius: 0px; + border-color: @background-alt; + cursor: "default"; + background-color: @background; +} + +/*****----- Main Box -----*****/ +mainbox { + enabled: true; + spacing: 10px; + margin: 0px; + padding: 30px; + background-color: transparent; + children: [ "inputbar", "message", "listview" ]; +} + +/*****----- Inputbar -----*****/ +inputbar { + enabled: true; + spacing: 10px; + padding: 0px; + border: 0px; + border-radius: 0px; + border-color: @selected; + background-color: transparent; + text-color: @foreground; + children: [ "textbox-prompt-colon", "prompt"]; +} + +textbox-prompt-colon { + enabled: true; + expand: false; + str: ""; + padding: 10px 12px; + border-radius: 0px; + background-color: var(urgent); + text-color: @background; +} +prompt { + enabled: true; + padding: 10px; + border-radius: 0px; + background-color: var(active); + text-color: @background; +} + +/*****----- Message -----*****/ +message { + enabled: true; + margin: 0px; + padding: 10px; + border: 0px solid; + border-radius: 0px; + border-color: @selected; + background-color: @background-alt; + text-color: @foreground; +} +textbox { + background-color: inherit; + text-color: inherit; + vertical-align: 0.5; + horizontal-align: 0.0; +} + +/*****----- Listview -----*****/ +listview { + enabled: true; + columns: 6; + lines: 1; + cycle: true; + scrollbar: false; + layout: vertical; + + spacing: 10px; + background-color: transparent; + cursor: "default"; +} + +/*****----- Elements -----*****/ +element { + enabled: true; + padding: 15px; + border: 0px solid; + border-radius: 0px; + border-color: @selected; + background-color: transparent; + text-color: @foreground; + cursor: pointer; +} +element-text { + font: "feather 20"; + background-color: transparent; + text-color: inherit; + cursor: inherit; + vertical-align: 0.5; + horizontal-align: 0.5; +} + +element normal.normal, +element alternate.normal { + background-color: var(background-alt); + text-color: var(foreground); +} +element normal.urgent, +element alternate.urgent, +element selected.active { + background-color: var(urgent); + text-color: var(background); +} +element normal.active, +element alternate.active, +element selected.urgent { + background-color: var(active); + text-color: var(background); +} +element selected.normal { + background-color: var(selected); + text-color: var(background); +} diff --git a/rofi/networkmenu.rasi b/rofi/networkmenu.rasi new file mode 100644 index 0000000..1643487 --- /dev/null +++ b/rofi/networkmenu.rasi @@ -0,0 +1,206 @@ +/** + * Copyright (C) 2020-2024 Aditya Shakya + **/ + +/*****----- Configuration -----*****/ +configuration { + modi: "drun,run,filebrowser"; + show-icons: false; + display-drun: ""; + display-run: ""; + display-filebrowser: ""; + drun-display-format: "{name}"; +} + +/*****----- Global Properties -----*****/ +@import "shared/colors.rasi" +@import "shared/fonts.rasi" + +/*****----- Main Window -----*****/ +window { + /* properties for window widget */ + transparency: "real"; + location: center; + anchor: center; + fullscreen: false; + width: 500px; + height: 495px; + x-offset: 0px; + y-offset: 0px; + + /* properties for all widgets */ + enabled: true; + margin: 0px; + padding: 0px; + border: 2px solid; + border-radius: 0px; + border-color: @background-alt; + cursor: "default"; + background-color: @background; +} + +/*****----- Main Box -----*****/ +mainbox { + enabled: true; + spacing: 10px; + margin: 0px; + padding: 30px; + background-color: transparent; + children: [ "inputbar", "listview" ]; +} + +/*****----- Inputbar -----*****/ +inputbar { + enabled: true; + spacing: 10px; + margin: 0px; + padding: 0px; + border-radius: 0px; + background-color: transparent; + text-color: @foreground; + children: [ "textbox-prompt-colon", "prompt", "entry" ]; +} + +prompt { + enabled: true; + padding: 8px; + border-radius: 0px; + background-color: var(active); + text-color: @background; +} +textbox-prompt-colon { + enabled: true; + expand: false; + str: ""; + padding: 8px 10px; + border-radius: 0px; + background-color: var(urgent); + text-color: @background; +} +entry { + enabled: true; + padding: 8px 0px; + background-color: inherit; + text-color: inherit; + cursor: text; + placeholder: ""; + placeholder-color: inherit; +} + +/*****----- Listview -----*****/ +listview { + enabled: true; + columns: 1; + lines: 8; + cycle: true; + dynamic: true; + scrollbar: false; + layout: vertical; + reverse: false; + fixed-height: true; + fixed-columns: true; + + spacing: 5px; + background-color: transparent; + text-color: @foreground; + cursor: "default"; +} +scrollbar { + handle-width: 5px ; + handle-color: @selected; + border-radius: 10px; + background-color: @background-alt; +} + +/*****----- Elements -----*****/ +element { + enabled: true; + spacing: 10px; + margin: 0px; + padding: 8px; + border-radius: 0px; + background-color: transparent; + text-color: @foreground; + cursor: pointer; +} +element normal.normal, +element alternate.normal { + background-color: var(background); + text-color: var(foreground); +} +element normal.urgent, +element alternate.urgent, +element selected.active { + background-color: var(urgent); + text-color: var(background); +} +element normal.active, +element alternate.active, +element selected.urgent { + background-color: var(active); + text-color: var(background); +} +element selected.normal { + background-color: var(selected); + text-color: var(background); +} +element-icon { + background-color: transparent; + text-color: inherit; + size: 24px; + cursor: inherit; +} +element-text { + background-color: transparent; + text-color: inherit; + highlight: inherit; + cursor: inherit; + vertical-align: 0.5; + horizontal-align: 0.0; +} + +/*****----- Mode Switcher -----*****/ +mode-switcher{ + enabled: true; + spacing: 10px; + margin: 0px; + padding: 0px; + background-color: transparent; + text-color: @foreground; +} +button { + padding: 8px 12px; + border-radius: 12px; + background-color: @background-alt; + text-color: inherit; + cursor: pointer; +} +button selected { + background-image: linear-gradient(to right, #E06B74, #C778DD); + text-color: var(background); +} + +/*****----- Message -----*****/ +message { + enabled: true; + margin: 0px; + padding: 8px 12px; + border-radius: 12px; + background-color: @background-alt; + text-color: @foreground; +} +textbox { + background-color: transparent; + text-color: @foreground; + vertical-align: 0.5; + horizontal-align: 0.0; + highlight: none; + placeholder-color: @foreground; + blink: true; + markup: true; +} +error-message { + padding: 30px; + background-color: @background; + text-color: @foreground; +} diff --git a/rofi/networkmenu_config.ini b/rofi/networkmenu_config.ini new file mode 100644 index 0000000..f28c112 --- /dev/null +++ b/rofi/networkmenu_config.ini @@ -0,0 +1,30 @@ +## Copyright (C) 2020-2024 Aditya Shakya + +[dmenu] +dmenu_command = rofi -dmenu -theme ~/.config/hypr/rofi/networkmenu.rasi +# # Note that dmenu_command can contain arguments as well like `rofi -width 30` +# # Rofi and dmenu are set to case insensitive by default `-i` +# l = number of lines to display, defaults to number of total network options +# fn = font string +# nb = normal background (name, #RGB, or #RRGGBB) +# nf = normal foreground +# sb = selected background +# sf = selected foreground +# b = (just set to empty value and menu will appear at the bottom +# m = number of monitor to display on +# p = Custom Prompt for the networks menu +# pinentry = Pinentry command +# rofi_highlight = # (Default: False) use rofi highlighting instead of '**' + +# # override normal foreground and background colors (dmenu) or use the +# # -password option (rofi) to obscure passphrase entry +# [dmenu_passphrase] +# nf = #222222 +# nb = #222222 +# rofi_obscure = True + +[editor] +terminal = alacritty +gui_if_available = True +# terminal = +# gui_if_available = diff --git a/rofi/powermenu.rasi b/rofi/powermenu.rasi new file mode 100644 index 0000000..067f325 --- /dev/null +++ b/rofi/powermenu.rasi @@ -0,0 +1,148 @@ +/** + * Copyright (C) 2020-2024 Aditya Shakya + **/ + +/*****----- Configuration -----*****/ +configuration { + show-icons: false; +} + +/*****----- Global Properties -----*****/ +@import "shared/colors.rasi" +@import "shared/fonts.rasi" + +/* +USE_ICON=YES +*/ + +/*****----- Main Window -----*****/ +window { + transparency: "real"; + location: center; + anchor: center; + fullscreen: false; + width: 510px; + x-offset: 0px; + y-offset: 0px; + margin: 0px; + padding: 0px; + border: 2px solid; + border-radius: 0px; + border-color: @background-alt; + cursor: "default"; + background-color: @background; +} + +/*****----- Main Box -----*****/ +mainbox { + enabled: true; + spacing: 10px; + margin: 0px; + padding: 30px; + background-color: transparent; + children: [ "inputbar", "message", "listview" ]; +} + +/*****----- Inputbar -----*****/ +inputbar { + enabled: true; + spacing: 10px; + padding: 0px; + border: 0px; + border-radius: 0px; + border-color: @selected; + background-color: transparent; + text-color: @foreground; + children: [ "textbox-prompt-colon", "prompt"]; +} + +textbox-prompt-colon { + enabled: true; + expand: false; + str: ""; + padding: 10px 12px; + border-radius: 0px; + background-color: var(urgent); + text-color: @background; +} +prompt { + enabled: true; + padding: 10px; + border-radius: 0px; + background-color: var(active); + text-color: @background; +} + +/*****----- Message -----*****/ +message { + enabled: true; + margin: 0px; + padding: 10px; + border: 0px solid; + border-radius: 0px; + border-color: @selected; + background-color: @background-alt; + text-color: @foreground; +} +textbox { + background-color: inherit; + text-color: inherit; + vertical-align: 0.5; + horizontal-align: 0.0; +} + +/*****----- Listview -----*****/ +listview { + enabled: true; + columns: 6; + lines: 1; + cycle: true; + scrollbar: false; + layout: vertical; + + spacing: 10px; + background-color: transparent; + cursor: "default"; +} + +/*****----- Elements -----*****/ +element { + enabled: true; + padding: 15px; + border: 0px solid; + border-radius: 0px; + border-color: @selected; + background-color: transparent; + text-color: @foreground; + cursor: pointer; +} +element-text { + font: "feather 20"; + background-color: transparent; + text-color: inherit; + cursor: inherit; + vertical-align: 0.5; + horizontal-align: 0.5; +} + +element normal.normal, +element alternate.normal { + background-color: var(background-alt); + text-color: var(foreground); +} +element normal.urgent, +element alternate.urgent, +element selected.active { + background-color: var(urgent); + text-color: var(background); +} +element normal.active, +element alternate.active, +element selected.urgent { + background-color: var(active); + text-color: var(background); +} +element selected.normal { + background-color: var(selected); + text-color: var(background); +} diff --git a/rofi/runner.rasi b/rofi/runner.rasi new file mode 100644 index 0000000..858edd0 --- /dev/null +++ b/rofi/runner.rasi @@ -0,0 +1,202 @@ +/** + * Copyright (C) 2020-2024 Aditya Shakya + **/ + +/*****----- Configuration -----*****/ +configuration { + modi: "run"; + show-icons: true; + display-drun: ""; + display-run: ""; + display-filebrowser: ""; + drun-display-format: "{name}"; +} + +/*****----- Global Properties -----*****/ +@import "shared/colors.rasi" +@import "shared/fonts.rasi" + +/*****----- Main Window -----*****/ +window { + /* properties for window widget */ + transparency: "real"; + location: center; + anchor: center; + fullscreen: false; + width: 600px; + x-offset: 0px; + y-offset: 0px; + + /* properties for all widgets */ + enabled: true; + margin: 0px; + padding: 0px; + border: 2px solid; + border-radius: 0px; + border-color: @background-alt; + cursor: "default"; + background-color: @background; +} + +/*****----- Main Box -----*****/ +mainbox { + enabled: true; + spacing: 10px; + margin: 0px; + padding: 30px; + background-color: transparent; + children: [ "inputbar", "listview" ]; +} + +/*****----- Inputbar -----*****/ +inputbar { + enabled: true; + spacing: 10px; + margin: 0px; + padding: 10px; + border-radius: 0px; + background-color: @background-alt; + text-color: @foreground; + children: [ "textbox-prompt-colon", "entry" ]; +} + +prompt { + enabled: true; + background-color: inherit; + text-color: inherit; +} +textbox-prompt-colon { + enabled: true; + padding: 0px; + expand: false; + str: ""; + background-color: inherit; + text-color: inherit; +} +entry { + enabled: true; + padding: 0px; + background-color: inherit; + text-color: inherit; + cursor: text; + placeholder: "Run..."; + placeholder-color: inherit; +} + +/*****----- Listview -----*****/ +listview { + enabled: true; + columns: 2; + lines: 6; + cycle: true; + dynamic: true; + scrollbar: false; + layout: vertical; + reverse: false; + fixed-height: true; + fixed-columns: true; + + spacing: 5px; + background-color: transparent; + text-color: @foreground; + cursor: "default"; +} +scrollbar { + handle-width: 5px ; + handle-color: @selected; + border-radius: 10px; + background-color: @background-alt; +} + +/*****----- Elements -----*****/ +element { + enabled: true; + spacing: 10px; + margin: 0px; + padding: 6px; + border-radius: 0px; + background-color: transparent; + text-color: @foreground; + cursor: pointer; +} +element normal.normal, +element alternate.normal { + background-color: var(background); + text-color: var(foreground); +} +element normal.urgent, +element alternate.urgent, +element selected.active { + background-color: var(urgent); + text-color: var(background); +} +element normal.active, +element alternate.active, +element selected.urgent { + background-color: var(active); + text-color: var(background); +} +element selected.normal { + background-color: var(selected); + text-color: var(background); +} +element-icon { + background-color: transparent; + text-color: inherit; + size: 24px; + cursor: inherit; +} +element-text { + background-color: transparent; + text-color: inherit; + highlight: inherit; + cursor: inherit; + vertical-align: 0.5; + horizontal-align: 0.0; +} + +/*****----- Mode Switcher -----*****/ +mode-switcher{ + enabled: true; + spacing: 10px; + margin: 0px; + padding: 0px 250px; + background-color: transparent; + text-color: @foreground; +} +button { + padding: 10px; + border-radius: 0px; + background-color: @background-alt; + text-color: inherit; + cursor: pointer; +} +button selected { + background-color: var(urgent); + text-color: var(background); +} + +/*****----- Message -----*****/ +message { + enabled: true; + margin: 0px; + padding: 10px; + border-radius: 0px; + background-color: @background-alt; + text-color: @foreground; +} +textbox { + background-color: transparent; + text-color: @foreground; + vertical-align: 0.5; + horizontal-align: 0.0; + highlight: none; + placeholder-color: @foreground; + blink: true; + markup: true; +} +error-message { + padding: 30px; + background-color: @background; + text-color: @foreground; +} diff --git a/rofi/screenshot.rasi b/rofi/screenshot.rasi new file mode 100644 index 0000000..f9918e7 --- /dev/null +++ b/rofi/screenshot.rasi @@ -0,0 +1,148 @@ +/** + * Copyright (C) 2020-2024 Aditya Shakya + **/ + +/*****----- Configuration -----*****/ +configuration { + show-icons: false; +} + +/*****----- Global Properties -----*****/ +@import "shared/colors.rasi" +@import "shared/fonts.rasi" + +/* +USE_ICON=YES +*/ + +/*****----- Main Window -----*****/ +window { + transparency: "real"; + location: center; + anchor: center; + fullscreen: false; + width: 440px; + x-offset: 0px; + y-offset: 0px; + margin: 0px; + padding: 0px; + border: 2px solid; + border-radius: 0px; + border-color: @background-alt; + cursor: "default"; + background-color: @background; +} + +/*****----- Main Box -----*****/ +mainbox { + enabled: true; + spacing: 10px; + margin: 0px; + padding: 30px; + background-color: transparent; + children: [ "inputbar", "message", "listview" ]; +} + +/*****----- Inputbar -----*****/ +inputbar { + enabled: true; + spacing: 10px; + padding: 0px; + border: 0px; + border-radius: 0px; + border-color: @selected; + background-color: transparent; + text-color: @foreground; + children: [ "textbox-prompt-colon", "prompt"]; +} + +textbox-prompt-colon { + enabled: true; + expand: false; + str: ""; + padding: 10px 12px; + border-radius: 0px; + background-color: var(urgent); + text-color: @background; +} +prompt { + enabled: true; + padding: 10px; + border-radius: 0px; + background-color: var(active); + text-color: @background; +} + +/*****----- Message -----*****/ +message { + enabled: true; + margin: 0px; + padding: 10px; + border: 0px solid; + border-radius: 0px; + border-color: @selected; + background-color: @background-alt; + text-color: @foreground; +} +textbox { + background-color: inherit; + text-color: inherit; + vertical-align: 0.5; + horizontal-align: 0.0; +} + +/*****----- Listview -----*****/ +listview { + enabled: true; + columns: 6; + lines: 1; + cycle: true; + scrollbar: false; + layout: vertical; + + spacing: 10px; + background-color: transparent; + cursor: "default"; +} + +/*****----- Elements -----*****/ +element { + enabled: true; + padding: 15px; + border: 0px solid; + border-radius: 0px; + border-color: @selected; + background-color: transparent; + text-color: @foreground; + cursor: pointer; +} +element-text { + font: "feather 20"; + background-color: transparent; + text-color: inherit; + cursor: inherit; + vertical-align: 0.5; + horizontal-align: 0.5; +} + +element normal.normal, +element alternate.normal { + background-color: var(background-alt); + text-color: var(foreground); +} +element normal.urgent, +element alternate.urgent, +element selected.active { + background-color: var(urgent); + text-color: var(background); +} +element normal.active, +element alternate.active, +element selected.urgent { + background-color: var(active); + text-color: var(background); +} +element selected.normal { + background-color: var(selected); + text-color: var(background); +} diff --git a/rofi/shared/colors.rasi b/rofi/shared/colors.rasi new file mode 100644 index 0000000..3183750 --- /dev/null +++ b/rofi/shared/colors.rasi @@ -0,0 +1,8 @@ +* { + background: #3d3942; + background-alt: #49454f; + foreground: #e0dde2; + selected: #C3B2CD; + active: #A896B3; + urgent: #9A9EAA; +} diff --git a/rofi/shared/fonts.rasi b/rofi/shared/fonts.rasi new file mode 100644 index 0000000..b15f0fa --- /dev/null +++ b/rofi/shared/fonts.rasi @@ -0,0 +1,7 @@ +/* Copyright (C) 2020-2024 Aditya Shakya */ + +/* Text Font */ + +* { + font: "Iosevka 10"; +} diff --git a/rofi/windows.rasi b/rofi/windows.rasi new file mode 100644 index 0000000..99026dd --- /dev/null +++ b/rofi/windows.rasi @@ -0,0 +1,302 @@ +/** + * Copyright (C) 2020-2022 Aditya Shakya + **/ + +/*****----- Configuration -----*****/ +configuration { + modi: "window"; + show-icons: true; + display-drun: " Apps"; + display-run: " Run"; + display-filebrowser: " Files"; + display-window: " Windows"; + drun-display-format: "{name}"; + window-format: "{c} · {t}"; +} + +/*****----- Global Properties -----*****/ +@import "shared/colors.rasi" +@import "shared/fonts.rasi" + +* { + border-colour: var(selected); + handle-colour: var(selected); + background-colour: var(background); + foreground-colour: var(foreground); + alternate-background: var(background-alt); + normal-background: var(background); + normal-foreground: var(foreground); + urgent-background: var(urgent); + urgent-foreground: var(background); + active-background: var(active); + active-foreground: var(background); + selected-normal-background: var(selected); + selected-normal-foreground: var(background); + selected-urgent-background: var(active); + selected-urgent-foreground: var(background); + selected-active-background: var(urgent); + selected-active-foreground: var(background); + alternate-normal-background: var(background); + alternate-normal-foreground: var(foreground); + alternate-urgent-background: var(urgent); + alternate-urgent-foreground: var(background); + alternate-active-background: var(active); + alternate-active-foreground: var(background); +} + +/*****----- Main Window -----*****/ +window { + /* properties for window widget */ + transparency: "real"; + location: center; + anchor: center; + fullscreen: false; + width: 600px; + x-offset: 0px; + y-offset: 0px; + + /* properties for all widgets */ + enabled: true; + margin: 0px; + padding: 0px; + border: 1px solid; + border-radius: 0px; + border-color: @border-colour; + cursor: "default"; + /* Backgroud Colors */ + background-color: @background-colour; + /* Backgroud Image */ + //background-image: url("/path/to/image.png", none); + /* Simple Linear Gradient */ + //background-image: linear-gradient(red, orange, pink, purple); + /* Directional Linear Gradient */ + //background-image: linear-gradient(to bottom, pink, yellow, magenta); + /* Angle Linear Gradient */ + //background-image: linear-gradient(45, cyan, purple, indigo); +} + +/*****----- Main Box -----*****/ +mainbox { + enabled: true; + spacing: 10px; + margin: 0px; + padding: 20px; + border: 0px solid; + border-radius: 0px 0px 0px 0px; + border-color: @border-colour; + background-color: transparent; + children: [ "inputbar", "message", "listview" ]; +} + +/*****----- Inputbar -----*****/ +inputbar { + enabled: true; + spacing: 10px; + margin: 0px; + padding: 0px 0px 8px 0px; + border: 0px 0px 1px 0px; + border-radius: 0px; + border-color: @border-colour; + background-color: transparent; + text-color: @foreground-colour; + children: [ "textbox-prompt-colon", "entry" ]; +} + +prompt { + enabled: true; + background-color: inherit; + text-color: inherit; +} +textbox-prompt-colon { + enabled: true; + padding: 0px; + expand: false; + str: ""; + background-color: inherit; + text-color: inherit; +} +entry { + enabled: true; + padding: 0px; + background-color: inherit; + text-color: inherit; + cursor: text; + placeholder: "Filter..."; + placeholder-color: inherit; +} +num-filtered-rows { + enabled: true; + expand: false; + background-color: inherit; + text-color: inherit; +} +textbox-num-sep { + enabled: true; + expand: false; + str: "/"; + background-color: inherit; + text-color: inherit; +} +num-rows { + enabled: true; + expand: false; + background-color: inherit; + text-color: inherit; +} +case-indicator { + enabled: true; + background-color: inherit; + text-color: inherit; +} + +/*****----- Listview -----*****/ +listview { + enabled: true; + columns: 1; + lines: 8; + cycle: true; + dynamic: true; + scrollbar: false; + layout: vertical; + reverse: false; + fixed-height: true; + fixed-columns: true; + + spacing: 5px; + margin: 0px; + padding: 0px; + border: 0px solid; + border-radius: 0px; + border-color: @border-colour; + background-color: transparent; + text-color: @foreground-colour; + cursor: "default"; +} +scrollbar { + handle-width: 5px ; + handle-color: @handle-colour; + border-radius: 0px; + background-color: @alternate-background; +} + +/*****----- Elements -----*****/ +element { + enabled: true; + spacing: 10px; + margin: 0px; + padding: 6px; + border: 0px solid; + border-radius: 0px; + border-color: @border-colour; + background-color: transparent; + text-color: @foreground-colour; + cursor: pointer; +} +element normal.normal { + background-color: var(normal-background); + text-color: var(normal-foreground); +} +element normal.urgent { + background-color: var(urgent-background); + text-color: var(urgent-foreground); +} +element normal.active { + background-color: var(active-background); + text-color: var(active-foreground); +} +element selected.normal { + background-color: var(selected-normal-background); + text-color: var(selected-normal-foreground); +} +element selected.urgent { + background-color: var(selected-urgent-background); + text-color: var(selected-urgent-foreground); +} +element selected.active { + background-color: var(selected-active-background); + text-color: var(selected-active-foreground); +} +element alternate.normal { + background-color: var(alternate-normal-background); + text-color: var(alternate-normal-foreground); +} +element alternate.urgent { + background-color: var(alternate-urgent-background); + text-color: var(alternate-urgent-foreground); +} +element alternate.active { + background-color: var(alternate-active-background); + text-color: var(alternate-active-foreground); +} +element-icon { + background-color: transparent; + text-color: inherit; + size: 24px; + cursor: inherit; +} +element-text { + background-color: transparent; + text-color: inherit; + highlight: inherit; + cursor: inherit; + vertical-align: 0.5; + horizontal-align: 0.0; +} + +/*****----- Mode Switcher -----*****/ +mode-switcher{ + enabled: true; + spacing: 10px; + margin: 0px; + padding: 0px; + border: 0px solid; + border-radius: 0px; + border-color: @border-colour; + background-color: transparent; + text-color: @foreground-colour; +} +button { + padding: 8px 12px; + border: 0px solid; + border-radius: 0px; + border-color: @border-colour; + background-color: @alternate-background; + text-color: inherit; + cursor: pointer; +} +button selected { + background-color: var(selected-normal-background); + text-color: var(selected-normal-foreground); +} + +/*****----- Message -----*****/ +message { + enabled: true; + margin: 0px; + padding: 8px 12px; + border: 0px solid; + border-radius: 0px; + border-color: @border-colour; + background-color: @alternate-background; + text-color: @foreground-colour; +} +textbox { + border: 0px solid; + border-color: @border-colour; + background-color: transparent; + text-color: @foreground-colour; + vertical-align: 0.5; + horizontal-align: 0.0; + highlight: none; + placeholder-color: @foreground-colour; + blink: true; + markup: true; +} +error-message { + padding: 20px; + border: 0px solid; + border-radius: 0px; + border-color: @border-colour; + background-color: @background-colour; + text-color: @foreground-colour; +} diff --git a/rofi_askpass b/rofi_askpass new file mode 100755 index 0000000..ac4beff --- /dev/null +++ b/rofi_askpass @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +# Import Current Theme +DIR="$HOME/.scripts" +RASI="$DIR/rofi/askpass.rasi" + +# Rofi text dialog to get password +rofi -dmenu \ + -password \ + -i \ + -p "Root" \ + -theme ${RASI} diff --git a/rofi_asroot b/rofi_asroot new file mode 100755 index 0000000..8630d00 --- /dev/null +++ b/rofi_asroot @@ -0,0 +1,77 @@ +#!/usr/bin/env bash + +# Import Current Theme +DIR="$HOME/.scripts" +RASI="$DIR/rofi/asroot.rasi" +ASROOT="$DIR/scripts/asroot" +USER=`whoami` + +# Theme Elements +prompt='Root' +mesg="Run Applications As Root" +term="alacritty --class alacritty-float,alacritty-float --config-file /home/$USER/.config/hypr/alacritty/alacritty.toml" + +# Options +layout=`cat ${RASI} | grep 'USE_ICON' | cut -d'=' -f2` +if [[ "$layout" == 'NO' ]]; then + option_1=" Alacritty" + option_2=" Thunar" + option_3=" Geany" + option_4=" Ranger" + option_5=" Vim" +else + option_1="" + option_2="" + option_3="" + option_4="" + option_5="" +fi + +# Rofi CMD +rofi_cmd() { + rofi -dmenu \ + -p "$prompt" \ + -mesg "$mesg" \ + -markup-rows \ + -theme ${RASI} +} + +# Pass variables to rofi dmenu +run_rofi() { + echo -e "$option_1\n$option_2\n$option_3\n$option_4\n$option_5" | rofi_cmd +} + +# Execute Command +run_cmd() { + if [[ "$1" == '--opt1' ]]; then + ${ASROOT} "$term" + elif [[ "$1" == '--opt2' ]]; then + ${ASROOT} 'dbus-run-session thunar' + elif [[ "$1" == '--opt3' ]]; then + ${ASROOT} geany + elif [[ "$1" == '--opt4' ]]; then + ${ASROOT} "$term -e ranger" + elif [[ "$1" == '--opt5' ]]; then + ${ASROOT} "$term -e vim" + fi +} + +# Actions +chosen="$(run_rofi)" +case ${chosen} in + $option_1) + run_cmd --opt1 + ;; + $option_2) + run_cmd --opt2 + ;; + $option_3) + run_cmd --opt3 + ;; + $option_4) + run_cmd --opt4 + ;; + $option_5) + run_cmd --opt5 + ;; +esac diff --git a/rofi_bluetooth b/rofi_bluetooth new file mode 100755 index 0000000..4ebb49e --- /dev/null +++ b/rofi_bluetooth @@ -0,0 +1,321 @@ +#!/usr/bin/env bash +# __ _ _ _ _ _ _ +# _ __ ___ / _(_) | |__ | |_ _ ___| |_ ___ ___ | |_| |__ +# | '__/ _ \| |_| |_____| '_ \| | | | |/ _ \ __/ _ \ / _ \| __| '_ \ +# | | | (_) | _| |_____| |_) | | |_| | __/ || (_) | (_) | |_| | | | +# |_| \___/|_| |_| |_.__/|_|\__,_|\___|\__\___/ \___/ \__|_| |_| +# +# Author: Nick Clyde (clydedroid) +# +# A script that generates a rofi menu that uses bluetoothctl to +# connect to bluetooth devices and display status info. +# +# Inspired by networkmanager-dmenu (https://github.com/firecat53/networkmanager-dmenu) +# Thanks to x70b1 (https://github.com/polybar/polybar-scripts/tree/master/polybar-scripts/system-bluetooth-bluetoothctl) +# +# Depends on: +# Arch repositories: rofi, bluez-utils (contains bluetoothctl) + +# Import Current Theme +DIR="$HOME/.scripts" +RASI="$DIR/rofi/bluetooth.rasi" + +# Constants +divider="---------" +goback="Back" + +# Checks if bluetooth controller is powered on +power_on() { + if bluetoothctl show | grep -q "Powered: yes"; then + return 0 + else + return 1 + fi +} + +# Toggles power state +toggle_power() { + if power_on; then + bluetoothctl power off + show_menu + else + if rfkill list bluetooth | grep -q 'blocked: yes'; then + rfkill unblock bluetooth && sleep 3 + fi + bluetoothctl power on + show_menu + fi +} + +# Checks if controller is scanning for new devices +scan_on() { + if bluetoothctl show | grep -q "Discovering: yes"; then + echo "Scan: on" + return 0 + else + echo "Scan: off" + return 1 + fi +} + +# Toggles scanning state +toggle_scan() { + if scan_on; then + kill $(pgrep -f "bluetoothctl scan on") + bluetoothctl scan off + show_menu + else + bluetoothctl scan on & + echo "Scanning..." + sleep 5 + show_menu + fi +} + +# Checks if controller is able to pair to devices +pairable_on() { + if bluetoothctl show | grep -q "Pairable: yes"; then + echo "Pairable: on" + return 0 + else + echo "Pairable: off" + return 1 + fi +} + +# Toggles pairable state +toggle_pairable() { + if pairable_on; then + bluetoothctl pairable off + show_menu + else + bluetoothctl pairable on + show_menu + fi +} + +# Checks if controller is discoverable by other devices +discoverable_on() { + if bluetoothctl show | grep -q "Discoverable: yes"; then + echo "Discoverable: on" + return 0 + else + echo "Discoverable: off" + return 1 + fi +} + +# Toggles discoverable state +toggle_discoverable() { + if discoverable_on; then + bluetoothctl discoverable off + show_menu + else + bluetoothctl discoverable on + show_menu + fi +} + +# Checks if a device is connected +device_connected() { + device_info=$(bluetoothctl info "$1") + if echo "$device_info" | grep -q "Connected: yes"; then + return 0 + else + return 1 + fi +} + +# Toggles device connection +toggle_connection() { + if device_connected "$1"; then + bluetoothctl disconnect "$1" + device_menu "$device" + else + bluetoothctl connect "$1" + device_menu "$device" + fi +} + +# Checks if a device is paired +device_paired() { + device_info=$(bluetoothctl info "$1") + if echo "$device_info" | grep -q "Paired: yes"; then + echo "Paired: yes" + return 0 + else + echo "Paired: no" + return 1 + fi +} + +# Toggles device paired state +toggle_paired() { + if device_paired "$1"; then + bluetoothctl remove "$1" + device_menu "$device" + else + bluetoothctl pair "$1" + device_menu "$device" + fi +} + +# Checks if a device is trusted +device_trusted() { + device_info=$(bluetoothctl info "$1") + if echo "$device_info" | grep -q "Trusted: yes"; then + echo "Trusted: yes" + return 0 + else + echo "Trusted: no" + return 1 + fi +} + +# Toggles device connection +toggle_trust() { + if device_trusted "$1"; then + bluetoothctl untrust "$1" + device_menu "$device" + else + bluetoothctl trust "$1" + device_menu "$device" + fi +} + +# Prints a short string with the current bluetooth status +# Useful for status bars like polybar, etc. +print_status() { + if power_on; then + printf '󰂯' + + paired_devices_cmd="devices Paired" + # Check if an outdated version of bluetoothctl is used to preserve backwards compatibility + if (( $(echo "$(bluetoothctl version | cut -d ' ' -f 2) < 5.65" | bc -l) )); then + paired_devices_cmd="paired-devices" + fi + + mapfile -t paired_devices < <(bluetoothctl $paired_devices_cmd | grep Device | cut -d ' ' -f 2) + counter=0 + + for device in "${paired_devices[@]}"; do + if device_connected "$device"; then + device_alias=$(bluetoothctl info "$device" | grep "Alias" | cut -d ' ' -f 2-) + + if [ $counter -gt 0 ]; then + printf ", %s" "$device_alias" + else + printf " %s" "$device_alias" + fi + + ((counter++)) + fi + done + printf "\n" + else + echo "󰂲" + fi +} + +# A submenu for a specific device that allows connecting, pairing, and trusting +device_menu() { + device=$1 + + # Get device name and mac address + device_name=$(echo "$device" | cut -d ' ' -f 3-) + mac=$(echo "$device" | cut -d ' ' -f 2) + + # Build options + if device_connected "$mac"; then + connected="Connected: yes" + else + connected="Connected: no" + fi + paired=$(device_paired "$mac") + trusted=$(device_trusted "$mac") + options="$connected\n$paired\n$trusted\n$divider\n$goback\nExit" + + # Open rofi menu, read chosen option + chosen="$(echo -e "$options" | $rofi_command "$device_name")" + + # Match chosen option to command + case "$chosen" in + "" | "$divider") + echo "No option chosen." + ;; + "$connected") + toggle_connection "$mac" + ;; + "$paired") + toggle_paired "$mac" + ;; + "$trusted") + toggle_trust "$mac" + ;; + "$goback") + show_menu + ;; + esac +} + +# Opens a rofi menu with current bluetooth status and options to connect +show_menu() { + # Get menu options + if power_on; then + power="Power: on" + + # Human-readable names of devices, one per line + # If scan is off, will only list paired devices + devices=$(bluetoothctl devices | grep Device | cut -d ' ' -f 3-) + + # Get controller flags + scan=$(scan_on) + pairable=$(pairable_on) + discoverable=$(discoverable_on) + + # Options passed to rofi + options="$devices\n$divider\n$power\n$scan\n$pairable\n$discoverable\nExit" + else + power="Power: off" + options="$power\nExit" + fi + + # Open rofi menu, read chosen option + chosen="$(echo -e "$options" | $rofi_command "Bluetooth")" + + # Match chosen option to command + case "$chosen" in + "" | "$divider") + echo "No option chosen." + ;; + "$power") + toggle_power + ;; + "$scan") + toggle_scan + ;; + "$discoverable") + toggle_discoverable + ;; + "$pairable") + toggle_pairable + ;; + *) + device=$(bluetoothctl devices | grep "$chosen") + # Open a submenu if a device is selected + if [[ $device ]]; then device_menu "$device"; fi + ;; + esac +} + +# Rofi command to pipe into, can add any options here +rofi_command="rofi -theme ${RASI} -dmenu $* -p" + +case "$1" in + --status) + print_status + ;; + *) + show_menu + ;; +esac diff --git a/rofi_launcher b/rofi_launcher new file mode 100755 index 0000000..ae2af0b --- /dev/null +++ b/rofi_launcher @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +## Copyright (C) 2020-2024 Aditya Shakya + +# Import Current Theme +DIR="$HOME/.scripts" +RASI="$DIR/rofi/launcher.rasi" + +# Run +rofi \ + -show drun \ + -theme ${RASI} diff --git a/rofi_music b/rofi_music new file mode 100755 index 0000000..238e006 --- /dev/null +++ b/rofi_music @@ -0,0 +1,120 @@ +#!/usr/bin/env bash + +## Copyright (C) 2020-2024 Aditya Shakya + +# Import Current Theme +DIR="$HOME/.scripts" +RASI="$DIR/rofi/music.rasi" + +# Theme Elements +status="`mpc status`" +if [[ -z "$status" ]]; then + prompt='Offline' + mesg="MPD is Offline" +else + prompt="`mpc -f "%artist%" current`" + mesg="`mpc -f "%title%" current` 𝅘𝅥𝅮 `mpc status | grep "#" | awk '{print $3}'`" +fi + +# Options +layout=`cat ${RASI} | grep 'USE_ICON' | cut -d'=' -f2` +if [[ "$layout" == 'NO' ]]; then + if [[ ${status} == *"[playing]"* ]]; then + option_1=" Pause" + else + option_1=" Play" + fi + option_2=" Stop" + option_3=" Previous" + option_4=" Next" + option_5=" Repeat" + option_6=" Random" +else + if [[ ${status} == *"[playing]"* ]]; then + option_1="" + else + option_1="" + fi + option_2="" + option_3="" + option_4="" + option_5="" + option_6="" +fi + +# Toggle Actions +active='' +urgent='' +# Repeat +if [[ ${status} == *"repeat: on"* ]]; then + active="-a 4" +elif [[ ${status} == *"repeat: off"* ]]; then + urgent="-u 4" +else + option_5=" Parsing Error" +fi +# Random +if [[ ${status} == *"random: on"* ]]; then + [ -n "$active" ] && active+=",5" || active="-a 5" +elif [[ ${status} == *"random: off"* ]]; then + [ -n "$urgent" ] && urgent+=",5" || urgent="-u 5" +else + option_6=" Parsing Error" +fi + +# Rofi CMD +rofi_cmd() { + rofi -dmenu \ + -p "$prompt" \ + -mesg "$mesg" \ + ${active} ${urgent} \ + -markup-rows \ + -theme ${RASI} +} + +# Pass variables to rofi dmenu +run_rofi() { + echo -e "$option_1\n$option_2\n$option_3\n$option_4\n$option_5\n$option_6" | rofi_cmd +} + +# Execute Command +iDIR="$HOME/.config/hypr/mako/icons" +notify_song="notify-send -h string:x-canonical-private-synchronous:sys-notify-song -u low -i ${iDIR}/music.png" +run_cmd() { + if [[ "$1" == '--opt1' ]]; then + mpc -q toggle && ${notify_song} "`mpc -f "%artist%" current`" + elif [[ "$1" == '--opt2' ]]; then + mpc -q stop + elif [[ "$1" == '--opt3' ]]; then + mpc -q prev && ${notify_song} "`mpc -f "%artist%" current`" + elif [[ "$1" == '--opt4' ]]; then + mpc -q next && ${notify_song} "`mpc -f "%artist%" current`" + elif [[ "$1" == '--opt5' ]]; then + mpc -q repeat + elif [[ "$1" == '--opt6' ]]; then + mpc -q random + fi +} + +# Actions +chosen="$(run_rofi)" +case ${chosen} in + $option_1) + run_cmd --opt1 + ;; + $option_2) + run_cmd --opt2 + ;; + $option_3) + run_cmd --opt3 + ;; + $option_4) + run_cmd --opt4 + ;; + $option_5) + run_cmd --opt5 + ;; + $option_6) + run_cmd --opt6 + ;; +esac diff --git a/rofi_network b/rofi_network new file mode 100755 index 0000000..6230b95 --- /dev/null +++ b/rofi_network @@ -0,0 +1,1038 @@ +#!/usr/bin/env python3 +# encoding:utf8 +"""NetworkManager command line dmenu script. + +To add new connections or enable/disable networking requires policykit +permissions setup per: +https://wiki.archlinux.org/index.php/NetworkManager#Set_up_PolicyKit_permissions + +OR running the script as root + +Add dmenu options and default terminal if desired to +~/.config/hypr/rofi/networkmenu_config.ini + +""" +import pathlib +import struct +import configparser +import locale +import os +from os.path import basename, expanduser +import shlex +from shutil import which +import sys +from time import sleep +import uuid +import subprocess + +# pylint: disable=import-error +import gi +gi.require_version('NM', '1.0') +from gi.repository import GLib, NM # noqa pylint: disable=wrong-import-position +# pylint: enable=import-error + +ENV = os.environ.copy() +ENC = locale.getpreferredencoding() + +CONF = configparser.ConfigParser() +CONF.read(expanduser("~/.config/hypr/rofi/networkmenu_config.ini")) + + +def cli_args(): + """ Don't override dmenu_cmd function arguments with CLI args. Removes -l + and -p if those are passed on the command line. + + Exception: if -l is passed and dmenu_command is not defined, assume that the + user wants to switch dmenu to the vertical layout and include -l. + + Returns: List of additional CLI arguments + + """ + args = sys.argv[1:] + cmd = CONF.get('dmenu', 'dmenu_command', fallback=False) + if "-l" in args or "-p" in args: + for nope in ['-l', '-p'] if cmd is not False else ['-p']: + try: + nope_idx = args.index(nope) + del args[nope_idx] + del args[nope_idx] + except ValueError: + pass + return args + + +def dmenu_pass(command, color): + """Check if dmenu passphrase patch is applied and return the correct command + line arg list + + Args: command - string + color - obscure color string + Returns: list or None + + """ + if command != 'dmenu': + return None + try: + # Check for dmenu password patch + dm_patch = b'P' in subprocess.run(["dmenu", "-h"], + capture_output=True, + check=False).stderr + except FileNotFoundError: + dm_patch = False + return ["-P"] if dm_patch else ["-nb", color, "-nf", color] + + +def dmenu_cmd(num_lines, prompt="Networks", active_lines=None): + """Parse config.ini for menu options + + Args: args - num_lines: number of lines to display + prompt: prompt to show + active_lines: list of line numbers to tag as active + Returns: command invocation (as a list of strings) for example + ["dmenu", "-l", "", "-p", "", "-i"] + + """ + # Create command string + commands = {"dmenu": ["-p", str(prompt)], + "rofi": ["-dmenu", "-p", str(prompt)], + "bemenu": ["-p", str(prompt)], + "wofi": ["-p", str(prompt)], + "fuzzel": ["-p", str(prompt), "--log-level", "none"]} + command = shlex.split(CONF.get('dmenu', 'dmenu_command', fallback="dmenu")) + cmd_base = basename(command[0]) + command.extend(cli_args()) + command.extend(commands.get(cmd_base, [])) + # Highlighting + highlight = CONF.getboolean('dmenu', 'highlight', fallback=False) + if highlight is True: + # Rofi + if cmd_base == "rofi" and active_lines: + command.extend(["-a", ",".join([str(num) for num in active_lines])]) + # Wofi + if cmd_base == "wofi" and active_lines: + # add '-q' to prevent tag name and properties of pango markup from searchable + command.extend(["-m", "-q"]) + # Passphrase prompts + obscure = CONF.getboolean('dmenu_passphrase', 'obscure', fallback=False) + if prompt == "Passphrase" and obscure is True: + obscure_color = CONF.get('dmenu_passphrase', 'obscure_color', fallback='#222222') + pass_prompts = {"dmenu": dmenu_pass(cmd_base, obscure_color), + "rofi": ['-password'], + "bemenu": ['-x'], + "wofi": ['-P'], + "fuzzel": ['--password']} + command.extend(pass_prompts.get(cmd_base, [])) + return command + + +def choose_adapter(client): + """If there is more than one wifi adapter installed, ask which one to use + + """ + devices = client.get_devices() + devices = [i for i in devices if i.get_device_type() == NM.DeviceType.WIFI] + if not devices: + return None + if len(devices) == 1: + return devices[0] + device_names = "\n".join([d.get_iface() for d in devices]) + sel = subprocess.run(dmenu_cmd(len(devices), "CHOOSE ADAPTER:"), + capture_output=True, + check=False, + env=ENV, + input=device_names, + encoding=ENC).stdout + if not sel.strip(): + sys.exit() + devices = [i for i in devices if i.get_iface() == sel.strip()] + if len(devices) != 1: + raise ValueError(f"Selection was ambiguous: '{str(sel.strip())}'") + return devices[0] + + +def is_installed(cmd): + """Check if a utility is installed""" + return which(cmd) is not None + + +def is_running(cmd): + try: + subprocess.check_output(["pidof", cmd]) + except subprocess.CalledProcessError: + return False + else: + return True + + +def bluetooth_get_enabled(): + """Check if bluetooth is enabled. Try bluetoothctl first, then rfkill. + + Returns None if no bluetooth device was found. + """ + if is_installed('bluetoothctl') and is_running('bluetoothd'): + # Times out in 2 seconds, otherwise bluetoothctl will hang if bluetooth + # service isn't running. + try: + res = subprocess.run(['bluetoothctl', 'show'], + timeout=2, + capture_output=True, + text=True) + return "Powered: yes" in res.stdout + except subprocess.TimeoutExpired: + pass + # See https://www.kernel.org/doc/Documentation/ABI/stable/sysfs-class-rfkill + for path in pathlib.Path('/sys/class/rfkill/').glob('rfkill*'): + if (path / 'type').read_text().strip() == 'bluetooth': + return (path / 'soft').read_text().strip() == '0' + return None + + +def create_other_actions(client): + """Return list of other actions that can be taken + + """ + networking_enabled = client.networking_get_enabled() + networking_action = "Disable" if networking_enabled else "Enable" + + wifi_enabled = client.wireless_get_enabled() + wifi_action = "Disable" if wifi_enabled else "Enable" + + bluetooth_enabled = bluetooth_get_enabled() + bluetooth_action = "Disable" if bluetooth_enabled else "Enable" + + actions = [Action(f"{wifi_action} Wifi", toggle_wifi, + not wifi_enabled), + Action(f"{networking_action} Networking", + toggle_networking, not networking_enabled)] + if bluetooth_enabled is not None: + actions.append(Action(f"{bluetooth_action} Bluetooth", + toggle_bluetooth, not bluetooth_enabled)) + actions += [Action("Launch Connection Manager", launch_connection_editor), + Action("Delete a Connection", delete_connection)] + if wifi_enabled: + actions.append(Action("Rescan Wifi Networks", rescan_wifi)) + return actions + + +def rescan_wifi(): + """ + Rescan Wifi Access Points + """ + delay = CONF.getint('nmdm', 'rescan_delay', fallback=5) + for dev in CLIENT.get_devices(): + if gi.repository.NM.DeviceWifi == type(dev): + try: + dev.request_scan_async(None, rescan_cb, None) + LOOP.run() + sleep(delay) + notify("Wifi scan complete") + main() + except gi.repository.GLib.Error as err: + # Too frequent rescan error + notify("Wifi rescan failed", urgency="critical") + if not err.code == 6: # pylint: disable=no-member + raise err + + +def rescan_cb(dev, res, data): + """Callback for rescan_wifi. Just for notifications + + """ + if dev.request_scan_finish(res) is True: + notify("Wifi scan running...") + else: + notify("Wifi scan failed", urgency="critical") + LOOP.quit() + + +def ssid_to_utf8(nm_ap): + """ Convert binary ssid to utf-8 """ + ssid = nm_ap.get_ssid() + if not ssid: + return "" + ret = NM.utils_ssid_to_utf8(ssid.get_data()) + return ret + + +def prompt_saved(saved_cons): + """Prompt for a saved connection.""" + actions = create_saved_actions(saved_cons) + sel = get_selection(actions) + sel() + + +def ap_security(nm_ap): + """Parse the security flags to return a string with 'WPA2', etc. """ + flags = nm_ap.get_flags() + wpa_flags = nm_ap.get_wpa_flags() + rsn_flags = nm_ap.get_rsn_flags() + sec_str = "" + if ((flags & getattr(NM, '80211ApFlags').PRIVACY) and + (wpa_flags == 0) and (rsn_flags == 0)): + sec_str = " WEP" + if wpa_flags: + sec_str = " WPA1" + if rsn_flags & getattr(NM, '80211ApSecurityFlags').KEY_MGMT_PSK: + sec_str += " WPA2" + if rsn_flags & getattr(NM, '80211ApSecurityFlags').KEY_MGMT_SAE: + sec_str += " WPA3" + if ((wpa_flags & getattr(NM, '80211ApSecurityFlags').KEY_MGMT_802_1X) or + (rsn_flags & getattr(NM, '80211ApSecurityFlags').KEY_MGMT_802_1X)): + sec_str += " 802.1X" + if ((wpa_flags & getattr(NM, '80211ApSecurityFlags').KEY_MGMT_OWE) or + (rsn_flags & getattr(NM, '80211ApSecurityFlags').KEY_MGMT_OWE)): + sec_str += " OWE" + + # If there is no security use "--" + if sec_str == "": + sec_str = "--" + return sec_str.lstrip() + + +class Action(): # pylint: disable=too-few-public-methods + """Helper class to execute functions from a string variable""" + def __init__(self, + name, + func, + args=None, + active=False): + self.name = name + self.func = func + self.is_active = active + if args is None: + self.args = None + elif isinstance(args, list): + self.args = args + else: + self.args = [args] + + def __str__(self): + return self.name + + def __call__(self): + if self.args is None: + self.func() + else: + self.func(*self.args) + + +def conn_matches_adapter(conn, adapter): + """Return True if the connection is applicable for the given adapter. + + There seem to be two ways for a connection specify what interface it belongs + to: + + - By setting 'mac-address' in [wifi] to the adapter's MAC + - By setting 'interface-name` in [connection] to the adapter's name. + + Depending on how the connection was added, it seems like either + 'mac-address', 'interface-name' or neither of both is set. + """ + # [wifi] mac-address + setting_wireless = conn.get_setting_wireless() + mac = setting_wireless.get_mac_address() + if mac is not None: + return mac == adapter.get_permanent_hw_address() + + # [connection] interface-name + setting_connection = conn.get_setting_connection() + interface = setting_connection.get_interface_name() + if interface is not None: + return interface == adapter.get_iface() + + # Neither is set, let's assume this connection is for multiple/all adapters. + return True + + +def process_ap(nm_ap, is_active, adapter): + """Activate/Deactivate a connection and get password if required""" + if is_active: + CLIENT.deactivate_connection_async(nm_ap, None, deactivate_cb, nm_ap) + LOOP.run() + else: + conns_cur = [i for i in CONNS if + i.get_setting_wireless() is not None and + conn_matches_adapter(i, adapter)] + con = nm_ap.filter_connections(conns_cur) + if len(con) > 1: + raise ValueError("There are multiple connections possible") + + if len(con) == 1: + CLIENT.activate_connection_async(con[0], adapter, nm_ap.get_path(), + None, activate_cb, nm_ap) + LOOP.run() + else: + if ap_security(nm_ap) != "--": + password = get_passphrase() + else: + password = "" + set_new_connection(nm_ap, password, adapter) + + +def activate_cb(dev, res, data): + """Notification if activate connection completed successfully + + """ + try: + conn = dev.activate_connection_finish(res) + except GLib.Error: + conn = None + if conn is not None: + notify(f"Activated {conn.get_id()}") + else: + notify(f"Problem activating {data.get_id()}", urgency="critical") + LOOP.quit() + + +def deactivate_cb(dev, res, data): + """Notification if deactivate connection completed successfully + + """ + if dev.deactivate_connection_finish(res) is True: + notify(f"Deactivated {data.get_id()}") + else: + notify(f"Problem deactivating {data.get_id()}", urgency="critical") + LOOP.quit() + + +def process_vpngsm(con, activate): + """Activate/deactive VPN or GSM connections""" + if activate: + CLIENT.activate_connection_async(con, None, None, + None, activate_cb, con) + else: + CLIENT.deactivate_connection_async(con, None, deactivate_cb, con) + LOOP.run() + +def strength_bars(signal_strength): + bars = NM.utils_wifi_strength_bars(signal_strength) + wifi_chars = CONF.get("dmenu", "wifi_chars", fallback=False) + if wifi_chars: + bars = "".join([wifi_chars[i] for i, j in enumerate(bars) if j == '*']) + return bars + + +def strength_icon(signal_strength): + wifi_icons = CONF.get("dmenu", "wifi_icons", fallback=False) + if wifi_icons: + return wifi_icons[round(signal_strength / 100 * (len(wifi_icons) - 1))] + return "" + + +def create_ap_actions(aps, active_ap, active_connection, adapter): # noqa pylint: disable=too-many-locals,line-too-long + """For each AP in a list, create the string and its attached function + (activate/deactivate) + + """ + active_ap_bssid = active_ap.get_bssid() if active_ap is not None else "" + + names = [ssid_to_utf8(ap) for ap in aps] + max_len_name = max([len(name) for name in names]) if names else 0 + secs = [ap_security(ap) for ap in aps] + max_len_sec = max([len(sec) for sec in secs]) if secs else 0 + + ap_actions = [] + + if CONF.getboolean("dmenu", "compact", fallback=False): + format = CONF.get("dmenu", "format", fallback="{name} {sec} {bars}") + else: + format = CONF.get("dmenu", "format", fallback="{name:<{max_len_name}s} {sec:<{max_len_sec}s} {bars:>4}") + + for nm_ap, name, sec in zip(aps, names, secs): + is_active = nm_ap.get_bssid() == active_ap_bssid + signal_strength = nm_ap.get_strength() + bars = strength_bars(signal_strength) + icon = strength_icon(signal_strength) + action_name = format.format(name=name, sec=sec, signal=signal_strength, bars=bars, icon=icon, + max_len_name=max_len_name, max_len_sec=max_len_sec) + if is_active: + ap_actions.append(Action(action_name, process_ap, + [active_connection, True, adapter], + active=True)) + else: + ap_actions.append(Action(action_name, process_ap, + [nm_ap, False, adapter])) + return ap_actions + + +def create_vpn_actions(vpns, active): + """Create the list of strings to display with associated function + (activate/deactivate) for VPN connections. + + """ + active_vpns = [i for i in active if i.get_vpn()] + return _create_vpngsm_actions(vpns, active_vpns, "VPN") + + +def create_vlan_actions(vlans, active): + """Create the list of strings to display with associated function + (activate/deactivate) for VLAN connections. + + """ + active_vlans = [i for i in active if "vlan" == i.get_connection_type()] + return _create_vpngsm_actions(vlans, active_vlans, "VLAN") + + +def create_wireguard_actions(wgs, active): + """Create the list of strings to display with associated function + (activate/deactivate) for Wireguard connections. + + """ + active_wgs = [i for i in active if i.get_connection_type() == "wireguard"] + return _create_vpngsm_actions(wgs, active_wgs, "Wireguard") + + +def create_eth_actions(eths, active): + """Create the list of strings to display with associated function + (activate/deactivate) for Ethernet connections. + + """ + active_eths = [i for i in active if 'ethernet' in i.get_connection_type()] + return _create_vpngsm_actions(eths, active_eths, "Eth") + + +def create_gsm_actions(gsms, active): + """Create the list of strings to display with associated function + (activate/deactivate) GSM connections.""" + active_gsms = [i for i in active if + i.get_connection() is not None and + i.get_connection().is_type(NM.SETTING_GSM_SETTING_NAME)] + return _create_vpngsm_actions(gsms, active_gsms, "GSM") + + +def create_blue_actions(blues, active): + """Create the list of strings to display with associated function + (activate/deactivate) Bluetooth connections.""" + active_blues = [i for i in active if + i.get_connection() is not None and + i.get_connection().is_type(NM.SETTING_BLUETOOTH_SETTING_NAME)] + return _create_vpngsm_actions(blues, active_blues, "Bluetooth") + + +def create_saved_actions(saved): + """Create the list of strings to display with associated function + (activate/deactivate) for VPN connections. + + """ + return _create_vpngsm_actions(saved, [], "SAVED") + + +def _create_vpngsm_actions(cons, active_cons, label): + active_con_ids = [a.get_id() for a in active_cons] + actions = [] + for con in cons: + is_active = con.get_id() in active_con_ids + action_name = f"{con.get_id()}:{label}" + if is_active: + active_connection = [a for a in active_cons + if a.get_id() == con.get_id()] + if len(active_connection) != 1: + raise ValueError(f"Multiple active connections match {con.get_id()}") + active_connection = active_connection[0] + + actions.append(Action(action_name, process_vpngsm, + [active_connection, False], active=True)) + else: + actions.append(Action(action_name, process_vpngsm, + [con, True])) + return actions + + +def create_wwan_actions(client): + """Create WWWAN actions + + """ + wwan_enabled = client.wwan_get_enabled() + wwan_action = "Disable" if wwan_enabled else "Enable" + return [Action(f"{wwan_action} WWAN", toggle_wwan, not wwan_enabled)] + + +def combine_actions(eths, aps, vlans, vpns, wgs, gsms, blues, wwan, others, saved): + # pylint: disable=too-many-arguments + """Combine all given actions into a list of actions. + + Args: args - eths: list of Actions + aps: list of Actions + vpns: list of Actions + gsms: list of Actions + blues: list of Actions + wwan: list of Actions + others: list of Actions + """ + compact = CONF.getboolean("dmenu", "compact", fallback=False) + empty_action = [Action('', None)] if not compact else [] + all_actions = [] + all_actions += eths + empty_action if eths else [] + all_actions += aps + empty_action if aps else [] + all_actions += vlans + empty_action if vlans else [] + all_actions += vpns + empty_action if vpns else [] + all_actions += wgs + empty_action if wgs else [] + all_actions += gsms + empty_action if (gsms and wwan) else [] + all_actions += blues + empty_action if blues else [] + all_actions += wwan + empty_action if wwan else [] + all_actions += others + empty_action if others else [] + all_actions += saved + empty_action if saved else [] + return all_actions + + +def get_wofi_highlight_markup(action): + highlight_fg = CONF.get('dmenu', 'highlight_fg', fallback=None) + highlight_bg = CONF.get('dmenu', 'highlight_bg', fallback=None) + highlight_bold = CONF.getboolean('dmenu', 'highlight_bold', fallback=True) + + style = "" + if highlight_fg: + style += f'foreground="{highlight_fg}" ' + if highlight_bg: + style += f'background="{highlight_bg}" ' + if highlight_bold: + style += 'weight="bold" ' + + return f"" + str(action) + "" + + +def get_selection(all_actions): + """Spawn dmenu for selection and execute the associated action.""" + command = shlex.split(CONF.get("dmenu", "dmenu_command", fallback="dmenu")) + cmd_base = basename(command[0]) + active_chars = CONF.get("dmenu", "active_chars", fallback="==") + highlight = CONF.getboolean("dmenu", "highlight", fallback=False) + inp = [] + + if highlight is True and cmd_base == "rofi": + inp = [str(action) for action in all_actions] + elif highlight is True and cmd_base == "wofi": + inp = [get_wofi_highlight_markup(action) if action.is_active else str(action) + for action in all_actions] + else: + inp = [(active_chars if action.is_active else " " * len(active_chars)) + " " + str(action) + for action in all_actions] + active_lines = [index for index, action in enumerate(all_actions) + if action.is_active] + + command = dmenu_cmd(len(inp), active_lines=active_lines) + sel = subprocess.run(command, + capture_output=True, + check=False, + input="\n".join(inp), + encoding=ENC, + env=ENV).stdout + + if not sel.rstrip(): + sys.exit() + + if highlight is True and cmd_base == "rofi": + action = [i for i in all_actions if str(i).strip() == sel.strip()] + elif highlight is True and cmd_base == "wofi": + action = [i for i in all_actions + if str(i).strip() == sel.strip() or + get_wofi_highlight_markup(i) == sel.strip()] + else: + action = [i for i in all_actions + if ((str(i).strip() == str(sel.strip()) + and not i.is_active) or + (active_chars + " " + str(i) == str(sel.rstrip('\n')) + and i.is_active))] + if len(action) != 1: + raise ValueError(f"Selection was ambiguous: '{str(sel.strip())}'") + return action[0] + + +def toggle_networking(enable): + """Enable/disable networking + + Args: enable - boolean + + """ + toggle = GLib.Variant.new_tuple(GLib.Variant.new_boolean(enable)) + try: + CLIENT.dbus_call(NM.DBUS_PATH, NM.DBUS_INTERFACE, "Enable", toggle, + None, -1, None, None, None) + except AttributeError: + # Workaround for older versions of python-gobject + CLIENT.networking_set_enabled(enable) + notify(f"Networking {'enabled' if enable is True else 'disabled'}") + + +def toggle_wifi(enable): + """Enable/disable Wifi + + Args: enable - boolean + + """ + toggle = GLib.Variant.new_boolean(enable) + try: + CLIENT.dbus_set_property(NM.DBUS_PATH, NM.DBUS_INTERFACE, "WirelessEnabled", toggle, + -1, None, None, None) + except AttributeError: + # Workaround for older versions of python-gobject + CLIENT.wireless_set_enabled(enable) + notify(f"Wifi {'enabled' if enable is True else 'disabled'}") + + +def toggle_wwan(enable): + """Enable/disable WWAN + + Args: enable - boolean + + """ + toggle = GLib.Variant.new_boolean(enable) + try: + CLIENT.dbus_set_property(NM.DBUS_PATH, NM.DBUS_INTERFACE, "WwanEnabled", toggle, + -1, None, None, None) + except AttributeError: + # Workaround for older versions of python-gobject + CLIENT.wwan_set_enabled(enable) + notify(f"Wwan {'enabled' if enable is True else 'disabled'}") + + +def toggle_bluetooth(enable): + """Enable/disable Bluetooth + + Try bluetoothctl first, then drop to rfkill if it's not installed or + bluetooth service isn't running. + + Args: enable - boolean + + References: + https://github.com/blueman-project/blueman/blob/master/blueman/plugins/mechanism/RfKill.py + https://www.kernel.org/doc/html/latest/driver-api/rfkill.html + https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/include/uapi/linux/rfkill.h?h=v5.8.9 + + """ + if is_installed('bluetoothctl') and is_running('bluetoothd'): + # Times out in 2 seconds, otherwise bluetoothctl will hang if bluetooth + # service isn't running. + try: + res = subprocess.run(['bluetoothctl', 'power', 'on' if enable is True else 'off'], + timeout=2, + capture_output=True) + except subprocess.TimeoutExpired: + pass + try: + res = subprocess.run(['bluetoothctl', 'show'], + timeout=2, + capture_output=True, + text=True) + if "Powered: yes" in res.stdout: + notify("Bluetooth enabled") + return + except subprocess.TimeoutExpired: + pass + # Now try using rfkill + type_bluetooth = 2 + op_change_all = 3 + idx = 0 + soft_state = 0 if enable else 1 + hard_state = 0 + + data = struct.pack("IBBBB", idx, type_bluetooth, op_change_all, + soft_state, hard_state) + + try: + with open('/dev/rfkill', 'r+b', buffering=0) as rff: + rff.write(data) + except PermissionError: + notify("Lacking permission to write to /dev/rfkill.", + "Check README for configuration options.", + urgency="critical") + else: + notify(f"Bluetooth {'enabled' if enable else 'disabled'}") + + +def launch_connection_editor(): + """Launch nmtui or the gui nm-connection-editor + + """ + terminal = shlex.split(CONF.get("editor", "terminal", fallback="xterm")) + gui_if_available = CONF.getboolean("editor", "gui_if_available", fallback=True) + gui = CONF.get("editor", "gui", fallback="nm-connection-editor") + if gui_if_available is True: + if is_installed(gui): + subprocess.run(gui, check=False) + return + if is_installed("nmtui"): + subprocess.run(terminal + ["-e", "nmtui"], check=False) + return + notify("No network connection editor installed", urgency="critical") + + +def get_passphrase(): + """Get a password + + Returns: string + + """ + pinentry = CONF.get("dmenu", "pinentry", fallback=None) + if pinentry: + description = CONF.get("pinentry", "description", fallback="Get network password") + prompt = CONF.get("pinentry", "prompt", fallback="Password: ") + pin = "" + out = subprocess.run(pinentry, + capture_output=True, + check=False, + encoding=ENC, + input=f"setdesc {description}\nsetprompt {prompt}\ngetpin\n").stdout + if out: + res = [i for i in out.split("\n") if i.startswith("D ")] + if res and res[0].startswith("D "): + pin = res[0].split("D ")[1] + return pin + return subprocess.run(dmenu_cmd(0, "Passphrase"), + stdin=subprocess.DEVNULL, + capture_output=True, + check=False, + encoding=ENC).stdout + + +def delete_connection(): + """Display list of NM connections and delete the selected one + + """ + conn_acts = [Action(i.get_id(), i.delete_async, args=[None, delete_cb, None]) for i in CONNS] + conn_names = "\n".join([str(i) for i in conn_acts]) + sel = subprocess.run(dmenu_cmd(len(conn_acts), "CHOOSE CONNECTION TO DELETE:"), + capture_output=True, + check=False, + input=conn_names, + encoding=ENC, + env=ENV).stdout + if not sel.strip(): + sys.exit() + action = [i for i in conn_acts if str(i) == sel.rstrip("\n")] + if len(action) != 1: + raise ValueError(f"Selection was ambiguous: {str(sel)}") + action[0]() + LOOP.run() + + +def delete_cb(dev, res, data): + """Notification if delete completed successfully + + """ + if dev.delete_finish(res) is True: + notify(f"Deleted {dev.get_id()}") + else: + notify(f"Problem deleting {dev.get_id()}", urgency="critical") + LOOP.quit() + + +def set_new_connection(nm_ap, nm_pw, adapter): + """Setup a new NetworkManager connection + + Args: ap - NM.AccessPoint + pw - string + + """ + nm_pw = str(nm_pw).strip() + profile = create_wifi_profile(nm_ap, nm_pw, adapter) + CLIENT.add_and_activate_connection_async(profile, adapter, nm_ap.get_path(), + None, verify_conn, profile) + LOOP.run() + + +def create_wifi_profile(nm_ap, password, adapter): + # pylint: disable=line-too-long + # noqa From https://cgit.freedesktop.org/NetworkManager/NetworkManager/tree/examples/python/gi/add_connection.py + # noqa and https://cgit.freedesktop.org/NetworkManager/NetworkManager/tree/examples/python/dbus/add-wifi-psk-connection.py + # pylint: enable=line-too-long + """Create the NM profile given the AP and passphrase""" + ap_sec = ap_security(nm_ap) + profile = NM.SimpleConnection.new() + + s_con = NM.SettingConnection.new() + s_con.set_property(NM.SETTING_CONNECTION_ID, ssid_to_utf8(nm_ap)) + s_con.set_property(NM.SETTING_CONNECTION_UUID, str(uuid.uuid4())) + s_con.set_property(NM.SETTING_CONNECTION_TYPE, "802-11-wireless") + profile.add_setting(s_con) + + s_wifi = NM.SettingWireless.new() + s_wifi.set_property(NM.SETTING_WIRELESS_SSID, nm_ap.get_ssid()) + s_wifi.set_property(NM.SETTING_WIRELESS_MODE, 'infrastructure') + s_wifi.set_property(NM.SETTING_WIRELESS_MAC_ADDRESS, adapter.get_permanent_hw_address()) + profile.add_setting(s_wifi) + + s_ip4 = NM.SettingIP4Config.new() + s_ip4.set_property(NM.SETTING_IP_CONFIG_METHOD, "auto") + profile.add_setting(s_ip4) + + s_ip6 = NM.SettingIP6Config.new() + s_ip6.set_property(NM.SETTING_IP_CONFIG_METHOD, "auto") + profile.add_setting(s_ip6) + + if ap_sec != "--": + s_wifi_sec = NM.SettingWirelessSecurity.new() + if "WPA" in ap_sec: + if "WPA3" in ap_sec: + s_wifi_sec.set_property(NM.SETTING_WIRELESS_SECURITY_KEY_MGMT, + "sae") + else: + s_wifi_sec.set_property(NM.SETTING_WIRELESS_SECURITY_KEY_MGMT, + "wpa-psk") + s_wifi_sec.set_property(NM.SETTING_WIRELESS_SECURITY_AUTH_ALG, + "open") + s_wifi_sec.set_property(NM.SETTING_WIRELESS_SECURITY_PSK, password) + elif "WEP" in ap_sec: + s_wifi_sec.set_property(NM.SETTING_WIRELESS_SECURITY_KEY_MGMT, + "None") + s_wifi_sec.set_property(NM.SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, + NM.WepKeyType.PASSPHRASE) + s_wifi_sec.set_wep_key(0, password) + profile.add_setting(s_wifi_sec) + + return profile + + +def verify_conn(client, result, data): + """Callback function for add_and_activate_connection_async + + Check if connection completes successfully. Delete the connection if there + is an error. + + """ + try: + act_conn = client.add_and_activate_connection_finish(result) + conn = act_conn.get_connection() + if not all([conn.verify(), + conn.verify_secrets(), + data.verify(), + data.verify_secrets()]): + raise GLib.Error + notify(f"Added {conn.get_id()}") + except GLib.Error: + try: + notify(f"Connection to {conn.get_id()} failed", + urgency="critical") + conn.delete_async(None, None, None) + except UnboundLocalError: + pass + finally: + LOOP.quit() + + +def create_ap_list(adapter, active_connections): + """Generate list of access points. Remove duplicate APs , keeping strongest + ones and the active AP + + Args: adapter + active_connections - list of all active connections + Returns: aps - list of access points + active_ap - active AP + active_ap_con - active Connection + adapter + + """ + aps = [] + ap_names = [] + active_ap = adapter.get_active_access_point() + aps_all = sorted(adapter.get_access_points(), + key=lambda a: a.get_strength(), reverse=True) + conns_cur = [i for i in CONNS if + i.get_setting_wireless() is not None and + conn_matches_adapter(i, adapter)] + try: + ap_conns = active_ap.filter_connections(conns_cur) + active_ap_name = ssid_to_utf8(active_ap) + active_ap_con = [active_conn for active_conn in active_connections + if active_conn.get_connection() in ap_conns] + except AttributeError: + active_ap_name = None + active_ap_con = [] + if len(active_ap_con) > 1: + raise ValueError("Multiple connection profiles match" + " the wireless AP") + active_ap_con = active_ap_con[0] if active_ap_con else None + for nm_ap in aps_all: + ap_name = ssid_to_utf8(nm_ap) + if nm_ap != active_ap and ap_name == active_ap_name: + # Skip adding AP if it's not active but same name as active AP + continue + if ap_name not in ap_names: + ap_names.append(ap_name) + aps.append(nm_ap) + return aps, active_ap, active_ap_con, adapter + + +def notify(message, details=None, urgency="low"): + """Use notify-send if available for notifications + + """ + delay = CONF.getint('nmdm', 'rescan_delay', fallback=5) + args = ["-u", urgency, "-a", "networkmanager-dmenu", + "-t", str(delay * 1000), message] + if details is not None: + args.append(details) + if is_installed("notify-send"): + subprocess.run(["notify-send"] + args, check=False) + + +def run(): # pylint: disable=too-many-locals + """Main script entrypoint""" + try: + subprocess.check_output(["pidof", "NetworkManager"]) + except subprocess.CalledProcessError: + notify("WARNING: NetworkManager don't seems to be running") + print("WARNING: NetworkManager don't seems to be running") + active = CLIENT.get_active_connections() + adapter = choose_adapter(CLIENT) + if adapter: + ap_actions = create_ap_actions(*create_ap_list(adapter, active)) + else: + ap_actions = [] + + vpns = [i for i in CONNS if i.is_type(NM.SETTING_VPN_SETTING_NAME)] + try: + wgs = [i for i in CONNS if i.is_type(NM.SETTING_WIREGUARD_SETTING_NAME)] + except AttributeError: + # Workaround for older versions of python-gobject with no wireguard support + wgs = [] + eths = [i for i in CONNS if i.is_type(NM.SETTING_WIRED_SETTING_NAME)] + vlans = [i for i in CONNS if i.is_type(NM.SETTING_VLAN_SETTING_NAME)] + blues = [i for i in CONNS if i.is_type(NM.SETTING_BLUETOOTH_SETTING_NAME)] + + vpn_actions = create_vpn_actions(vpns, active) + wg_actions = create_wireguard_actions(wgs, active) + eth_actions = create_eth_actions(eths, active) + vlan_actions = create_vlan_actions(vlans, active) + blue_actions = create_blue_actions(blues, active) + other_actions = create_other_actions(CLIENT) + wwan_installed = is_installed("ModemManager") + if wwan_installed: + gsms = [i for i in CONNS if i.is_type(NM.SETTING_GSM_SETTING_NAME)] + gsm_actions = create_gsm_actions(gsms, active) + wwan_actions = create_wwan_actions(CLIENT) + else: + gsm_actions = [] + wwan_actions = [] + + list_saved = CONF.getboolean('dmenu', 'list_saved', fallback=False) + saved_cons = [i for i in CONNS if i not in vpns + wgs + eths + blues] + if list_saved: + saved_actions = create_saved_actions(saved_cons) + else: + saved_actions = [Action("Saved connections", prompt_saved, [saved_cons])] + + + actions = combine_actions(eth_actions, ap_actions, vlan_actions, vpn_actions, + wg_actions, gsm_actions, blue_actions, wwan_actions, + other_actions, saved_actions) + sel = get_selection(actions) + sel() + + +def main(): + """Main. Enables script to be re-run after a wifi rescan + + """ + global CLIENT, CONNS, LOOP # noqa pylint: disable=global-variable-undefined + CLIENT = NM.Client.new(None) + LOOP = GLib.MainLoop() + CONNS = CLIENT.get_connections() + + run() + + +if __name__ == '__main__': + main() + +# vim: set et ts=4 sw=4 : diff --git a/rofi_powermenu b/rofi_powermenu new file mode 100755 index 0000000..f23e303 --- /dev/null +++ b/rofi_powermenu @@ -0,0 +1,117 @@ +#!/usr/bin/env bash + +## Copyright (C) 2020-2024 Aditya Shakya + +# Import Current Theme +DIR="$HOME/.scripts" +RASI="$DIR/rofi/powermenu.rasi" +CNFR="$DIR/rofi/confirm.rasi" + +# Theme Elements +prompt="`hostname` (`echo $DESKTOP_SESSION`)" +mesg="Uptime : `uptime -p | sed -e 's/up //g'`" + +# Options +layout=`cat ${RASI} | grep 'USE_ICON' | cut -d'=' -f2` +if [[ "$layout" == 'NO' ]]; then + option_1=" Lock" + option_2=" Logout" + option_3=" Suspend" + option_4=" Hibernate" + option_5=" Reboot" + option_6=" Shutdown" +else + option_1="" + option_2="" + option_3="" + option_4="" + option_5="" + option_6="" +fi +cnflayout=`cat ${CNFR} | grep 'USE_ICON' | cut -d'=' -f2` +if [[ "$cnflayout" == 'NO' ]]; then + yes=' Yes' + no=' No' +else + yes='' + no='' +fi + +# Rofi CMD +rofi_cmd() { + rofi -dmenu \ + -p "$prompt" \ + -mesg "$mesg" \ + -markup-rows \ + -theme ${RASI} +} + +# Pass variables to rofi dmenu +run_rofi() { + echo -e "$option_1\n$option_2\n$option_3\n$option_4\n$option_5\n$option_6" | rofi_cmd +} + +# Confirmation CMD +confirm_cmd() { + rofi -dmenu \ + -p 'Confirmation' \ + -mesg 'Are you Sure?' \ + -selected-row 1 \ + -no-click-to-exit \ + -theme ${CNFR} +} + +# Ask for confirmation +confirm_exit() { + echo -e "$yes\n$no" | confirm_cmd +} + +# Confirm and execute +confirm_run () { + selected="$(confirm_exit)" + if [[ "$selected" == "$yes" ]]; then + ${1} && ${2} && ${3} && ${4} + else + exit + fi +} + +# Execute Command +run_cmd() { + if [[ "$1" == '--opt1' ]]; then + hyprlock + elif [[ "$1" == '--opt2' ]]; then + confirm_run 'hyprctl dispatch exit 0' + elif [[ "$1" == '--opt3' ]]; then + confirm_run 'mpc -q pause' 'pulsemixer --mute' 'systemctl suspend' + elif [[ "$1" == '--opt4' ]]; then + confirm_run 'systemctl hibernate' + elif [[ "$1" == '--opt5' ]]; then + confirm_run 'systemctl reboot' + elif [[ "$1" == '--opt6' ]]; then + confirm_run 'systemctl poweroff' + fi +} + +# Actions +chosen="$(run_rofi)" +case ${chosen} in + $option_1) + run_cmd --opt1 + ;; + $option_2) + run_cmd --opt2 + ;; + $option_3) + run_cmd --opt3 + ;; + $option_4) + run_cmd --opt4 + ;; + $option_5) + run_cmd --opt5 + ;; + $option_6) + run_cmd --opt6 + ;; +esac diff --git a/rofi_runner b/rofi_runner new file mode 100755 index 0000000..172abb9 --- /dev/null +++ b/rofi_runner @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +## Copyright (C) 2020-2024 Aditya Shakya + +# Import Current Theme +DIR="$HOME/.scripts" +RASI="$DIR/rofi/runner.rasi" + +# Run +rofi \ + -show run \ + -theme ${RASI} diff --git a/rofi_screenshot b/rofi_screenshot new file mode 100755 index 0000000..a8d2443 --- /dev/null +++ b/rofi_screenshot @@ -0,0 +1,143 @@ +#!/usr/bin/env bash + +## Copyright (C) 2020-2024 Aditya Shakya + +# Get Colors +DIR="$HOME/.scripts" +background="`cat $DIR/rofi/shared/colors.rasi | grep 'background:' | cut -d':' -f2 | tr -d ' '\;`" +accent="`cat $DIR/rofi/shared/colors.rasi | grep 'selected:' | cut -d':' -f2 | tr -d ' '\;`" + +# Import Current Theme +DIR="$HOME/.scripts" +RASI="$DIR/rofi/screenshot.rasi" + +# Theme Elements +prompt='Screenshot' +mesg="Directory :: `xdg-user-dir PICTURES`/Screenshots" + +# Options +layout=`cat ${RASI} | grep 'USE_ICON' | cut -d'=' -f2` +if [[ "$layout" == 'NO' ]]; then + option_1=" Capture Desktop" + option_2=" Capture Area" + option_3=" Capture Window" + option_4=" Capture in 5s" + option_5=" Capture in 10s" +else + option_1="" + option_2="" + option_3="" + option_4="" + option_5="" +fi + +# Rofi CMD +rofi_cmd() { + rofi -dmenu \ + -p "$prompt" \ + -mesg "$mesg" \ + -markup-rows \ + -theme ${RASI} +} + +# Pass variables to rofi dmenu +run_rofi() { + echo -e "$option_1\n$option_2\n$option_3\n$option_4\n$option_5" | rofi_cmd +} + +# Screenshot +time=`date +%Y-%m-%d-%H-%M-%S` +dir="`xdg-user-dir PICTURES`/Screenshots" +file="Screenshot_${time}_${geometry}.png" + +# Directory +if [[ ! -d "$dir" ]]; then + mkdir -p "$dir" +fi + +# notify and view screenshot +iDIR="$HOME/.config/hypr/mako/icons" +notify_view() { + notify_cmd_shot="notify-send -h string:x-canonical-private-synchronous:sys-notify-shot -u low -i ${iDIR}/picture.png" + ${notify_cmd_shot} "Copied to clipboard." + paplay /usr/share/sounds/freedesktop/stereo/screen-capture.oga &>/dev/null & + viewnior ${dir}/"$file" + if [[ -e "$dir/$file" ]]; then + ${notify_cmd_shot} "Screenshot Saved." + else + ${notify_cmd_shot} "Screenshot Deleted." + fi +} + +# countdown +countdown () { + for sec in `seq $1 -1 1`; do + notify-send -h string:x-canonical-private-synchronous:sys-notify-count -t 1000 -i "$iDIR"/timer.png "Taking shot in : $sec" + sleep 1 + done +} + +# take shots +shotnow () { + cd ${dir} && sleep 0.5 && grim - | tee "$file" | wl-copy + notify_view +} + +shot5 () { + countdown '5' + sleep 1 && cd ${dir} && grim - | tee "$file" | wl-copy + notify_view +} + +shot10 () { + countdown '10' + sleep 1 && cd ${dir} && grim - | tee "$file" | wl-copy + notify_view +} + +shotwin () { + w_pos=`hyprctl activewindow | grep 'at:' | cut -d':' -f2 | tr -d ' ' | tail -n1` + w_size=`hyprctl activewindow | grep 'size:' | cut -d':' -f2 | tr -d ' ' | tail -n1 | sed s/,/x/g` + cd ${dir} && sleep 0.3 && grim -g "$w_pos $w_size" - | tee "$file" | wl-copy + notify_view +} + +shotarea () { + cd ${dir} && grim -g "$(slurp -b ${background:1}CC -c ${accent:1}ff -s ${accent:1}0D -w 2 && sleep 0.3)" - | tee "$file" | wl-copy + notify_view +} + +# Execute Command +run_cmd() { + if [[ "$1" == '--opt1' ]]; then + shotnow + elif [[ "$1" == '--opt2' ]]; then + shotarea + elif [[ "$1" == '--opt3' ]]; then + shotwin + elif [[ "$1" == '--opt4' ]]; then + shot5 + elif [[ "$1" == '--opt5' ]]; then + shot10 + fi +} + +# Actions +chosen="$(run_rofi)" +case ${chosen} in + $option_1) + run_cmd --opt1 + ;; + $option_2) + run_cmd --opt2 + ;; + $option_3) + run_cmd --opt3 + ;; + $option_4) + run_cmd --opt4 + ;; + $option_5) + run_cmd --opt5 + ;; +esac diff --git a/rofi_windows b/rofi_windows new file mode 100755 index 0000000..62693e5 --- /dev/null +++ b/rofi_windows @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +## Copyright (C) 2020-2022 Aditya Shakya + +# Import Current Theme +DIR="$HOME/.scripts" +STYLE="onedark" +RASI="$DIR/rofi/windows.rasi" + +# Run +rofi \ + -show window \ + -theme ${RASI} diff --git a/scan_hosts.sh b/scan_hosts.sh new file mode 100755 index 0000000..20cba69 --- /dev/null +++ b/scan_hosts.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +# Check if the subnet argument is provided +if [ "$#" -ne 1 ]; then + echo "Usage: $0 " + exit 1 +fi + +# Extract the base IP and CIDR from the argument +subnet="$1" +IFS='.' read -r -a octets <<< "$(echo "$subnet" | cut -d'/' -f1)" +cidr=$(echo "$subnet" | cut -d'/' -f2) + +# Function to ping a single IP +ping_host() { + ip="$1" + if ping -c 1 -W 1 "$ip" &> /dev/null; then + echo "$ip is up" + fi +} + +# Export the function so it can be used by GNU Parallel +export -f ping_host + +# Generate IPs based on CIDR +if [ "$cidr" -eq 24 ]; then + # For /24, only the last octet changes + for i in {1..254}; do + ip="${octets[0]}.${octets[1]}.${octets[2]}.$i" + echo "$ip" + done +elif [ "$cidr" -eq 16 ]; then + # For /16, the last two octets change + for i in {0..255}; do + for j in {0..255}; do + if [ "$i" -eq 0 ] && [ "$j" -eq 0 ]; then + continue # Skip network address + fi + if [ "$i" -eq 255 ] && [ "$j" -eq 255 ]; then + continue # Skip broadcast address + fi + ip="${octets[0]}.${octets[1]}.$i.$j" + echo "$ip" + done + done +else + echo "Unsupported CIDR notation. Only /24 and /16 are supported in this script." + exit 1 +fi | parallel -j 512 --progress ping_host + +echo "Scan completed." + diff --git a/screenshot b/screenshot new file mode 100755 index 0000000..3c5eca2 --- /dev/null +++ b/screenshot @@ -0,0 +1,87 @@ +#!/usr/bin/env bash + +## Copyright (C) 2020-2024 Aditya Shakya +## +## Script to take screenshots with grim, slurp (in Wayland) + +# Get Colors +DIR="$HOME/.config/hypr" +background="`cat $DIR/rofi/shared/colors.rasi | grep 'background:' | cut -d':' -f2 | tr -d ' '\;`" +accent="`cat $DIR/rofi/shared/colors.rasi | grep 'selected:' | cut -d':' -f2 | tr -d ' '\;`" + +iDIR="$HOME/.config/hypr/mako/icons" + +time=`date +%Y-%m-%d-%H-%M-%S` +dir="`xdg-user-dir PICTURES`/Screenshots" +file="Screenshot_${time}_${RANDOM}.png" + +# notify and view screenshot +notify_cmd_shot="notify-send -h string:x-canonical-private-synchronous:sys-notify-shot -u low -i ${iDIR}/picture.png" +notify_view () { + ${notify_cmd_shot} "Copied to clipboard." + paplay /usr/share/sounds/freedesktop/stereo/screen-capture.oga &>/dev/null & + viewnior ${dir}/"$file" + if [[ -e "$dir/$file" ]]; then + ${notify_cmd_shot} "Screenshot Saved." + else + ${notify_cmd_shot} "Screenshot Deleted." + fi +} + +# countdown +countdown () { + for sec in `seq $1 -1 1`; do + notify-send -h string:x-canonical-private-synchronous:sys-notify-count -t 1000 -i "$iDIR"/timer.png "Taking shot in : $sec" + sleep 1 + done +} + +# take shots +shotnow () { + cd ${dir} && sleep 0.5 && grim - | tee "$file" | wl-copy + notify_view +} + +shot5 () { + countdown '5' + sleep 1 && cd ${dir} && grim - | tee "$file" | wl-copy + notify_view +} + +shot10 () { + countdown '10' + sleep 1 && cd ${dir} && grim - | tee "$file" | wl-copy + notify_view +} + +shotwin () { + w_pos=`hyprctl activewindow | grep 'at:' | cut -d':' -f2 | tr -d ' ' | tail -n1` + w_size=`hyprctl activewindow | grep 'size:' | cut -d':' -f2 | tr -d ' ' | tail -n1 | sed s/,/x/g` + cd ${dir} && grim -g "$w_pos $w_size" - | tee "$file" | wl-copy + notify_view +} + +shotarea () { + cd ${dir} && grim -g "$(slurp -b ${background:1}CC -c ${accent:1}ff -s ${accent:1}0D -w 2 && sleep 0.3)" - | tee "$file" | wl-copy + notify_view +} + +if [[ ! -d "$dir" ]]; then + mkdir -p "$dir" +fi + +if [[ "$1" == "--now" ]]; then + shotnow +elif [[ "$1" == "--in5" ]]; then + shot5 +elif [[ "$1" == "--in10" ]]; then + shot10 +elif [[ "$1" == "--win" ]]; then + shotwin +elif [[ "$1" == "--area" ]]; then + shotarea +else + echo -e "Available Options : --now --in5 --in10 --win --area" +fi + +exit 0 diff --git a/statusbar b/statusbar new file mode 100755 index 0000000..747d7db --- /dev/null +++ b/statusbar @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +## Copyright (C) 2020-2024 Aditya Shakya +## +## launch waybar with alt config + +CONFIG="$HOME/.config/hypr/waybar/config" +STYLE="$HOME/.config/hypr/waybar/style.css" + +if [[ ! `pidof waybar` ]]; then + waybar --bar main-bar --log-level error --config ${CONFIG} --style ${STYLE} +fi diff --git a/toggle_bar.sh b/toggle_bar.sh new file mode 100755 index 0000000..1d885f9 --- /dev/null +++ b/toggle_bar.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +## Copyright (C) 2024 +## +## Script to toggle waybar visibility in Hyprland + +# Check if waybar is running +if pgrep -x "waybar" > /dev/null; then + # If waybar is running, kill it + killall -q waybar + notify-send -h string:x-canonical-private-synchronous:sys-notify -u low "Waybar Disabled" +else + # If waybar is not running, start it with the config files + CONFIG="$HOME/.config/hypr/waybar/config" + STYLE="$HOME/.config/hypr/waybar/style.css" + waybar --bar main-bar --log-level error --config ${CONFIG} --style ${STYLE} & + notify-send -h string:x-canonical-private-synchronous:sys-notify -u low "Waybar Enabled" +fi \ No newline at end of file diff --git a/toggle_gaps.sh b/toggle_gaps.sh new file mode 100755 index 0000000..cd00fdc --- /dev/null +++ b/toggle_gaps.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +## Copyright (C) 2024 +## +## Script to toggle gaps in Hyprland + +# Path to store the gap state +STATE_FILE="$HOME/.cache/hypr_gaps_state" + +# Default gaps values (matching your hyprtheme.conf) +DEFAULT_GAPS_IN=5 +DEFAULT_GAPS_OUT=10 +DEFAULT_GAPS_WS=-10 + +# Check if state file exists, create if not +if [ ! -f "$STATE_FILE" ]; then + echo "enabled" > "$STATE_FILE" +fi + +# Read current state +CURRENT_STATE=$(cat "$STATE_FILE") + +if [ "$CURRENT_STATE" = "enabled" ]; then + # Disable gaps + hyprctl --batch "keyword general:gaps_in 0; keyword general:gaps_out 0; keyword general:gaps_workspaces 0" + echo "disabled" > "$STATE_FILE" + notify-send -h string:x-canonical-private-synchronous:sys-notify -u low "Gaps Disabled" +else + # Enable gaps + hyprctl --batch "keyword general:gaps_in $DEFAULT_GAPS_IN; keyword general:gaps_out $DEFAULT_GAPS_OUT; keyword general:gaps_workspaces $DEFAULT_GAPS_WS" + echo "enabled" > "$STATE_FILE" + notify-send -h string:x-canonical-private-synchronous:sys-notify -u low "Gaps Enabled" +fi \ No newline at end of file diff --git a/toggle_wg.sh b/toggle_wg.sh new file mode 100644 index 0000000..c8fc328 --- /dev/null +++ b/toggle_wg.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +## Script to toggle WireGuard tunnel using wg command for state determination + +# Define the WireGuard interface name +WG_INTERFACE="wg0" + +# Function to check if WireGuard interface is active +is_wg_active() { + sudo /usr/bin/wg show | grep -q "interface" +} + +if is_wg_active; then + # If the interface is active, disable it + sudo /usr/bin/wg-quick down "$WG_INTERFACE" + if ! is_wg_active; then + notify-send -h string:x-canonical-private-synchronous:sys-notify -u low -i network-vpn "WireGuard Tunnel" "Tunnel Deactivated" + else + notify-send --urgency=critical -i network-vpn "WireGuard Tunnel" "Error: Failed to deactivate tunnel" + fi +else + # If the interface is not active, enable it + sudo /usr/bin/wg-quick up "$WG_INTERFACE" + if is_wg_active; then + notify-send -h string:x-canonical-private-synchronous:sys-notify -u low -i network-vpn "WireGuard Tunnel" "Tunnel Activated" + else + notify-send --urgency=critical -i network-vpn "WireGuard Tunnel" "Error: Failed to activate tunnel" + fi +fi + diff --git a/volume b/volume new file mode 100755 index 0000000..4f26a43 --- /dev/null +++ b/volume @@ -0,0 +1,82 @@ +#!/usr/bin/env bash + +## Copyright (C) 2020-2024 Aditya Shakya +## +## Script To Manage Speaker Volume For Archcraft (in Wayland). + +iDIR="$HOME/.config/hypr/mako/icons" +notify_cmd='notify-send -h string:x-canonical-private-synchronous:sys-notify-volume -u low' + +# Get Volume +get_volume() { + echo "`pulsemixer --get-volume | cut -d' ' -f1`" +} + +# Get icons +get_icon() { + current="$(get_volume)" + if [[ "$current" -eq "0" ]]; then + icon="$iDIR/volume-mute.png" + elif [[ ("$current" -ge "0") && ("$current" -le "30") ]]; then + icon="$iDIR/volume-low.png" + elif [[ ("$current" -ge "30") && ("$current" -le "60") ]]; then + icon="$iDIR/volume-mid.png" + elif [[ ("$current" -ge "60") && ("$current" -le "100") ]]; then + icon="$iDIR/volume-high.png" + fi +} + +# Notify +notify_user() { + ${notify_cmd} -i "$icon" "Volume : $(get_volume)%" +} + +# Increase Volume +inc_volume() { + [[ `pulsemixer --get-mute` == 1 ]] && pulsemixer --unmute + pulsemixer --max-volume 100 --change-volume +5 && get_icon && notify_user +} + +# Decrease Volume +dec_volume() { + [[ `pulsemixer --get-mute` == 1 ]] && pulsemixer --unmute + pulsemixer --max-volume 100 --change-volume -5 && get_icon && notify_user +} + +# Toggle Mute +toggle_mute() { + if [[ `pulsemixer --get-mute` == 0 ]]; then + pulsemixer --toggle-mute && ${notify_cmd} -i "$iDIR/volume-mute.png" "Mute" + else + pulsemixer --toggle-mute && get_icon && ${notify_cmd} -i "$icon" "Unmute" + fi +} + +# Toggle Mic +toggle_mic() { + ID="`pulsemixer --list-sources | grep 'Default' | cut -d',' -f1 | cut -d' ' -f3`" + if [[ `pulsemixer --id $ID --get-mute` == 0 ]]; then + pulsemixer --id ${ID} --toggle-mute && ${notify_cmd} -i "$iDIR/microphone-mute.png" "Microphone Switched OFF" + else + pulsemixer --id ${ID} --toggle-mute && ${notify_cmd} -i "$iDIR/microphone.png" "Microphone Switched ON" + fi +} + +# Execute accordingly +if [[ -x `which pulsemixer` ]]; then + if [[ "$1" == "--get" ]]; then + get_volume + elif [[ "$1" == "--inc" ]]; then + inc_volume + elif [[ "$1" == "--dec" ]]; then + dec_volume + elif [[ "$1" == "--toggle" ]]; then + toggle_mute + elif [[ "$1" == "--toggle-mic" ]]; then + toggle_mic + else + echo $(get_volume)% + fi +else + ${notify_cmd} "'pulsemixer' is not installed." +fi diff --git a/wallpaper b/wallpaper new file mode 100755 index 0000000..b806dcf --- /dev/null +++ b/wallpaper @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +## Copyright (C) 2020-2024 Aditya Shakya +## +## Set Wallpaper in Hyprland + +#WALLPAPER='/home/belar/Pictures/wallpapers/677966.png' + +#swaybg --output '*' --mode fill --image "$WALLPAPER" + +# live wallpaper +#/usr/bin/mpvpaper -s -o "no-audio loop" ALL /home/belar/.background/live/live/Parking-Scene-Unreal.mp4 & +#/usr/bin/mpvpaper -s -o "no-audio loop" ALL /home/belar/.background/live/proxima_centauri2.mp4 +#/usr/bin/mpvpaper -s -o "no-audio loop" DP-3 /home/belar/.background/live/live/Computer.mp4 & +/usr/bin/mpvpaper -s -o "no-audio loop --hwdec=vaapi" DP-3 /home/belar/.background/live/live/Evening-Falling-Star.mp4 & +#/usr/bin/mpvpaper -s -o "no-audio loop --hwdec=vaapi" HDMI-A-4 /home/belar/.background/live/frieren_up.mp4 & diff --git a/waybar/colors.css b/waybar/colors.css new file mode 100644 index 0000000..786431e --- /dev/null +++ b/waybar/colors.css @@ -0,0 +1,14 @@ +/** ********** Colors ********** **/ +@define-color background #3d3942; +@define-color background-alt1 #49454f; +@define-color background-alt2 #56515d; +@define-color foreground #e0dde2; +@define-color selected #C3B2CD; +@define-color black #3d3942; +@define-color red #9A9EAA; +@define-color green #A896B3; +@define-color yellow #CAAEB0; +@define-color blue #C3B2CD; +@define-color magenta #94CCC5; +@define-color cyan #A7D5CF; +@define-color white #e0dde2; diff --git a/waybar/config b/waybar/config new file mode 100644 index 0000000..aeba5fc --- /dev/null +++ b/waybar/config @@ -0,0 +1,28 @@ +// Copyright (C) 2020-2024 Aditya Shakya +// +// Waybar config file +{ + "include": "~/.config/hypr/waybar/modules", + "name": "main-bar", // Waybar name + "id": "main-bar", // Waybar id + "layer": "top", // Waybar at top layer + //"mode": "dock", // Display mode (dock|hide|invisible|overlay) + "exclusive": true, // Request an exclusive zone from the compositor + "passthrough": false, // Pass any pointer events to the window under the bar + "position": "top", // Waybar position (top|bottom|left|right) + "height": 34, // Waybar height (to be removed for auto height) + "width": "", // Waybar width (empty for auto width) + "spacing": 0, // Gaps between modules + "margin": 0, // Space around the bar + "margin-top": 0, // Space above the bar + "margin-bottom": 0, // Space below the bar + "margin-left": 0, // Space to the left of the bar + "margin-right": 0, // Space to the right of the bar + "fixed-center": true, // Center modules position + "ipc": true, // Control waybar with `swaymsg bar` commands + // Choose the order of the modules + "modules-left": ["custom/menu", "hyprland/workspaces", "mpd#2", "mpd#3", "mpd#4", "mpd" ], + //"modules-left": ["custom/menu", "hyprland/workspaces", "idle_inhibitor", "tray", "custom/spotify" ], + "modules-center": [ "cpu", "cpu#2", "memory", "memory#2", "disk", "disk#2" ], + "modules-right": ["custom/themes", "pulseaudio", "pulseaudio#2", "backlight", "backlight#2", "battery", "battery#2", "bluetooth", "bluetooth#2", "network", "network#2", "clock", "clock#2", "idle_inhibitor", "tray", "custom/power"], +} diff --git a/waybar/modules b/waybar/modules new file mode 100644 index 0000000..51a4230 --- /dev/null +++ b/waybar/modules @@ -0,0 +1,326 @@ +// Copyright (C) 2020-2024 Aditya Shakya +// +// Waybar modules configuration +{ + // waybar-backlight + "backlight": { + "interval": 2, + //"device": "amdgpu_bl0", + "format": "{icon}", + "format-icons": ["", "", "", "", "", "", ""], + // Commands to execute on events + "on-scroll-up": "light -A 5%", + "on-scroll-down": "light -U 5%", + "smooth-scrolling-threshold": 1, + }, + "backlight#2": { + "interval": 2, + //"device": "amdgpu_bl0", + "format": "{percent}%", + // Commands to execute on events + "on-scroll-up": "light -A 5%", + "on-scroll-down": "light -U 5%", + "smooth-scrolling-threshold": 1, + }, + + // waybar-battery + "battery": { + "interval": 60, + //"bat": "BAT1", + //"adapter": "ACAD", + "full-at": 100, + "design-capacity": false, + "states": { + "good": 95, + "warning": 30, + "critical": 15 + }, + "format": "{icon}", + "format-charging": "", + "format-plugged": "ﮣ", + "format-full": "", + "format-icons": ["", "", "", "", "", "", "", "", ""], + "format-time": "{H}h {M}min", + "tooltip": true, + }, + "battery#2": { + "interval": 60, + //"bat": "BAT1", + //"adapter": "ACAD", + "full-at": 100, + "design-capacity": false, + "states": { + "good": 95, + "warning": 30, + "critical": 15 + }, + "format": "{capacity}%", + "format-charging": "{capacity}%", + "format-plugged": "{capacity}%", + "format-full": "Full", + "format-alt": "{time}", + "format-time": "{H}h {M}min", + "tooltip": true, + }, + + // waybar-bluetooth + "bluetooth": { + //"controller": "controller1", + //"format-device-preference": "", + "format": "", + "format-on": "", + "format-off": "", + "format-disabled": "", + "format-connected": "", + "format-connected-battery": "", + "tooltip": true, + "tooltip-format": "{controller_alias}\t{controller_address}", + "tooltip-format-connected": "{controller_alias}\t{controller_address}\n\n{device_enumerate}", + "tooltip-format-enumerate-connected": "{device_alias}\t{device_address}", + "on-click": "~/.config/hypr/scripts/rofi_bluetooth", + "on-click-right": "blueman-manager", + }, + "bluetooth#2": { + //"controller": "controller1", + //"format-device-preference": "", + "format": "{status}", + "format-on": "{status}", + "format-off": "{status}", + "format-disabled": "{status}", + "format-connected": "{device_alias}", + "format-connected-battery": "{device_alias}, {device_battery_percentage}%", + "tooltip": true, + "tooltip-format": "{controller_alias}\t{controller_address}", + "tooltip-format-connected": "{controller_alias}\t{controller_address}\n\n{device_enumerate}", + "tooltip-format-enumerate-connected": "{device_alias}\t{device_address}", + "on-click": "~/.config/hypr/scripts/rofi_bluetooth", + "on-click-right": "blueman-manager", + }, + + // waybar-clock + "clock": { + "tooltip-format": "{:%B %Y}\n{calendar}", + "format": "", + }, + "clock#2": { + "interval": 60, + "tooltip-format": "{:%B %Y}\n{calendar}", + "format": "{:%I:%M %p}", + "format-alt": "{:%a %b %d, %G}" + }, + + // waybar-cpu + "cpu": { + "interval": 5, + "format": "", + }, + "cpu#2": { + "interval": 5, + "format": "{usage}%", + }, + + // waybar-custom + "custom/themes": { + "format": "", + "tooltip": false, + "on-click": "$HOME/.config/hypr/theme/theme.sh --pywal", + "on-click-right": "$HOME/.config/hypr/theme/theme.sh --default", + }, + + "custom/menu": { + "format": "", + "tooltip": false, + //"on-click": "$HOME/.config/hypr/scripts/wofi_menu", + "on-click": "$HOME/.config/hypr/scripts/rofi_launcher", + "on-click-right": "$HOME/.config/hypr/scripts/rofi_runner", + }, + + "custom/power": { + "format": "襤", + "tooltip": false, + //"on-click": "$HOME/.config/hypr/scripts/wlogout", + "on-click": "$HOME/.config/hypr/scripts/rofi_powermenu", + }, + + // waybar-disk + "disk": { + "interval": 30, + "format": "", + }, + "disk#2": { + "interval": 30, + "format": "{free}", + }, + + // waybar-memory + "memory": { + "interval": 10, + "format": "", + }, + "memory#2": { + "interval": 10, + "format": "{used:0.1f}G", + }, + + // waybar-spotify + "custom/spotify": { + "exec": "$HOME/.config/hypr/waybar/spotify", + "interval": 1, + "format": "{}", + "tooltip": true, + "max-length": 40, + "on-click": "playerctl play-pause", + "on-click-middle": "playerctl previous", + "on-click-right": "playerctl next", + "on-scroll-up": "playerctl position 05+", + "on-scroll-down": "playerctl position 05-", + "smooth-scrolling-threshold": 1, + }, + + // waybar-mpd + "mpd": { + "interval": 2, + "unknown-tag": "N/A", + "format": "{artist} - {title} | 祥 {elapsedTime:%M:%S}", + "format-disconnected": "Disconnected", + "format-paused": "{artist} - {title}", + "format-stopped": "Stopped", + "tooltip-format": "MPD (connected)", + "tooltip-format-disconnected": "MPD (disconnected)", + // Commands to execute on events + "on-click": "mpc toggle", + "on-scroll-up": "mpc seek +00:00:01", + "on-scroll-down": "mpc seek -00:00:01", + "smooth-scrolling-threshold": 1, + }, + "mpd#2": { + "format": "玲", + "format-disconnected": "玲", + "format-paused": "玲", + "format-stopped": "玲", + // Commands to execute on events + "on-click": "mpc prev", + }, + "mpd#3": { + "interval": 1, + "format": "{stateIcon}", + "format-disconnected": "", + "format-paused": "{stateIcon}", + "format-stopped": "", + "state-icons": { + "paused": "", + "playing": "" + }, + // Commands to execute on events + "on-click": "mpc toggle", + }, + "mpd#4": { + "format": "怜", + "format-disconnected": "怜", + "format-paused": "怜", + "format-stopped": "怜", + // Commands to execute on events + "on-click": "mpc next", + }, + + // waybar-network + "network": { + "interval": 5, + //"interface": "wlan*", // (Optional) To force the use of this interface, set it for netspeed to work + "format-wifi": "直", + "format-ethernet": "", + "format-linked": "", + "format-disconnected": "睊", + "format-disabled": "睊", + "tooltip-format": " {ifname} via {gwaddr}", + //"on-click": "[[ ! `pidof nm-connection-editor` ]] && nm-connection-editor || pkill nm-connection-e", + "on-click": "~/.config/hypr/scripts/rofi_network", + }, + "network#2": { + "interval": 5, + //"interface": "wlan*", // (Optional) To force the use of this interface, set it for netspeed to work + "format-wifi": "{essid}", + "format-ethernet": "{ipaddr}/{cidr}", + "format-linked": "{ifname} (No IP)", + "format-disconnected": "Disconnected", + "format-disabled": "Disabled", + "format-alt": " {bandwidthUpBits} |  {bandwidthDownBits}", + "tooltip-format": " {ifname} via {gwaddr}", + }, + + // waybar-pulseaudio + "pulseaudio": { + //"format": "{volume}% {icon} {format_source}", + "format": "{icon}", + "format-muted": "", + "format-bluetooth": "", + "format-bluetooth-muted": "", + "format-source": "", + "format-source-muted": "", + "format-icons": { + "headphone": "", + "hands-free": "ﳌ", + "headset": "", + "phone": "", + "portable": "", + "car": "", + "default": ["", "", ""] + }, + "scroll-step": 5.0, + // Commands to execute on events + "on-click": "pulsemixer --toggle-mute", + "on-click-right": "pulsemixer --toggle-mute", + "smooth-scrolling-threshold": 1, + }, + "pulseaudio#2": { + //"format": "{volume}% {icon} {format_source}", + "format": "{volume}%", + "format-muted": "Mute", + "format-bluetooth": "{volume}%", + "format-bluetooth-muted": "Mute", + "format-source": "{volume}%", + "scroll-step": 5.0, + // Commands to execute on events + "on-click": "pulsemixer --toggle-mute", + "on-click-right": "pulsemixer --toggle-mute", + "smooth-scrolling-threshold": 1, + }, + + // waybar-idle-inhibitor + "idle_inhibitor": { + "format": "{icon}", + "format-icons": { + "activated": "💻", + "deactivated": "☕" + }, + }, + + // waybar-wlr-workspaces + "hyprland/workspaces": { + "format": "{icon}", + "sort-by-number": true, + "active-only": false, + "format-icons": { + "1": "I", + "2": "II", + "3": "III", + "4": "IV", + "5": "V", + "6": "VI", + "7": "VII", + "8": "VIII", + "9": "IX", + "10": "X", + "urgent": "", + "focused": "", + "default": "" + }, + "on-click": "activate", + }, + + // waybar-tray + "tray": { + "icon-size": 16, + "spacing": 10 + } +} diff --git a/waybar/spotify b/waybar/spotify new file mode 100755 index 0000000..089cc90 --- /dev/null +++ b/waybar/spotify @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +## Copyright (C) 2020-2024 Aditya Shakya +## +## Script for spotify for waybar + +player_status=$(playerctl status 2> /dev/null) + +if [ "$player_status" = "Playing" ]; then + echo -e " $(playerctl metadata artist) - $(playerctl metadata title)\nPlaying: $(playerctl metadata artist) - $(playerctl metadata title)\nplaying" +elif [ "$player_status" = "Paused" ]; then + echo -e " $(playerctl metadata artist) - $(playerctl metadata title)\nPaused: $(playerctl metadata artist) - $(playerctl metadata title)\npaused" +else + echo -e " Spotify Offline!\nSpotify Offline.\noffline" +fi diff --git a/waybar/style.css b/waybar/style.css new file mode 100644 index 0000000..0e34d10 --- /dev/null +++ b/waybar/style.css @@ -0,0 +1,314 @@ +/* + * Copyright (C) 2020-2024 Aditya Shakya +*/ + +/** ********** Import Colors ********** **/ +@import "./colors.css"; + +/** ********** Fonts ********** **/ +* { + font-family: "JetBrains Mono", "Symbols Nerd Font", Iosevka, archcraft, sans-serif; + font-size: 14px; +} + +/** ********** Waybar Window ********** **/ +window#waybar { + background-color: @background; + color: @foreground; + border-bottom: 2px solid @background-alt1; + transition-property: background-color; + transition-duration: .5s; +} + +window#waybar.hidden { + opacity: 0.5; +} + +/** ********** Custom ********** **/ + +#custom-menu { + background-color: @background-alt1; + color: @magenta; + font-size: 18px; + border-radius: 0px 14px 0px 0px; + margin: 0px 0px 0px 0px; + padding: 2px 8px 2px 8px; +} + +#custom-themes { + background-color: @selected; +} + +#custom-power { + background-color: @red; + font-size: 16px; +} + +#custom-power, #custom-themes { + color: @background; + border-radius: 10px; + margin: 6px 6px 6px 0px; + padding: 2px 8px 2px 8px; +} + +/** ********** Idle Inhibitor ********** **/ +#idle_inhibitor { + background-color: @green; + color: @background; + border-radius: 10px; + margin: 6px 0px 6px 6px ; + padding: 4px 6px; +} +#idle_inhibitor.deactivated { + background-color: @red; +} + +/** ********** Tray ********** **/ +#tray { + background-color: @background-alt1; + border-radius: 10px; + margin: 6px 0px 6px 6px ; + padding: 4px 6px; +} +#tray > .passive { + -gtk-icon-effect: dim; +} +#tray > .needs-attention { + -gtk-icon-effect: highlight; +} +#tray > .active { +} + +/** ********** MPD ********** **/ +@keyframes gradient { + 0% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } + 100% { + background-position: 0% 50%; + } +} + +#mpd { + color: @foreground; + font-size: 12px; + font-weight: bold; +} +#mpd.disconnected { + color: @red; +} +#mpd.stopped { + color: @red; +} +#mpd.playing { + color: @cyan; +} +#mpd.paused { +} + +#mpd.2 { + border-radius: 10px 0px 0px 10px; + margin: 6px 0px 6px 6px ; + padding: 4px 6px 4px 10px; +} +#mpd.3 { + margin: 6px 0px 6px 0px ; + padding: 4px; +} +#mpd.4 { + border-radius: 0px 10px 10px 0px; + margin: 6px 6px 6px 0px ; + padding: 4px 10px 4px 6px; +} +#mpd.2,#mpd.3,#mpd.4 { + background-color: @background-alt1; + font-size: 14px; +} + +/** ********** Spotify ********** **/ +#custom-spotify { + background-color: @background-alt1; + color: @foreground; + border-radius: 10px; + margin: 6px 0px 6px 6px ; + padding: 4px 8px; + font-size: 12px; + font-weight: bold; +} + +#custom-spotify.paused { + color: @foreground; +} + +#custom-spotify.playing { + background: linear-gradient(90deg, @magenta 25%, @red 50%, @yellow 75%, @cyan 100%); + background-size: 300% 300%; + animation: gradient 10s ease infinite; + color: @background; +} + +#custom-spotify.offline { + color: @red; +} + +/** ********** CPU ********** **/ +#cpu { + color: @red; +} + +/** ********** Memory ********** **/ +#memory { + color: @green; +} + +/** ********** Disk ********** **/ +#disk { + color: @yellow; +} + +/** ********** Pulseaudio ********** **/ +#pulseaudio { + color: @blue; +} +#pulseaudio.bluetooth { + color: @cyan; +} +#pulseaudio.muted { + color: @red; +} + +#pulseaudio.2 { +} +#pulseaudio.2.bluetooth { +} +#pulseaudio.2.muted { +} + +/** ********** Backlight ********** **/ +#backlight { + color: @magenta; +} + +/** ********** Battery ********** **/ +#battery { + color: @cyan; +} +#battery.charging { +} +#battery.plugged { +} +@keyframes blink { + to { + color: @foreground; + } +} +#battery.critical:not(.charging) { + background-color: @background-alt2; +} +#battery.2.critical:not(.charging) { + background-color: @background-alt1; + color: @red; + animation-name: blink; + animation-duration: 0.5s; + animation-timing-function: linear; + animation-iteration-count: infinite; + animation-direction: alternate; +} + +/** ********** Network ********** **/ +#network { + color: @yellow; +} +#network.disconnected,#network.disabled { + color: @red; +} +#network.linked { +} +#network.ethernet { +} +#network.wifi { +} + +/** ********** Bluetooth ********** **/ +#bluetooth { + color: @green; +} +#bluetooth.disabled{ + color: @red; +} +#bluetooth.off{ + color: @red; +} +#bluetooth.on{ +} +#bluetooth.connected{ +} +#bluetooth.discoverable{ +} +#bluetooth.discovering{ +} +#bluetooth.pairable{ +} + +/** ********** Clock ********** **/ +#clock { + color: @blue; +} + +/** ********** WLR Desktop ********** **/ +#workspaces { + background-color: @background; + border-radius: 10px; + margin-left: 6px ; + margin-bottom: 2px ; + padding: 0px; +} +#workspaces button{ + color: @foreground; +} +#workspaces button.active{ + color: @red; +} +#workspaces button.urgent{ + color: @green; +} +#workspaces button.hidden{ + color: @yellow; +} + +/** ********** Common style ********** **/ +#backlight, +#battery, +#clock, +#cpu, +#disk, +#memory, +#pulseaudio, +#network, +#bluetooth { + background-color: @background-alt2; + border-radius: 10px 0px 0px 10px; + margin: 6px 0px 6px 0px ; + padding: 4px 6px; +} + +#backlight.2, +#battery.2, +#clock.2, +#cpu.2, +#disk.2, +#memory.2, +#pulseaudio.2, +#network.2, +#bluetooth.2 { + background-color: @background-alt1; + color: @foreground; + font-size: 12px; + font-weight: bold; + border-radius: 0px 10px 10px 0px; + margin: 6px 6px 6px 0px ; + padding: 5px 6px 4px 6px; +} diff --git a/wlogout b/wlogout new file mode 100755 index 0000000..3c67580 --- /dev/null +++ b/wlogout @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +## Copyright (C) 2020-2024 Aditya Shakya +## +## wlogout with alt layout and style file + +LAYOUT="$HOME/.config/hypr/wlogout/layout" +STYLE="$HOME/.config/hypr/wlogout/style.css" + +if [[ ! `pidof wlogout` ]]; then + wlogout --layout ${LAYOUT} --css ${STYLE} \ + --buttons-per-row 5 \ + --column-spacing 50 \ + --row-spacing 50 \ + --margin-top 390 \ + --margin-bottom 390 \ + --margin-left 150 \ + --margin-right 150 +else + pkill wlogout +fi diff --git a/wofi/config b/wofi/config new file mode 100644 index 0000000..c8c4e24 --- /dev/null +++ b/wofi/config @@ -0,0 +1,41 @@ +## Copyright (C) 2020-2024 Aditya Shakya +## +## Wofi Config + +## General +show=drun +prompt=Apps +normal_window=true +layer=top +term=foot + +## Geometry +width=400px +height=320px +location=0 +orientation=vertical +halign=fill +line_wrap=off +dynamic_lines=false + +## Images +allow_markup=true +allow_images=true +image_size=24 + +## Search +exec_search=false +hide_search=false +parse_search=false +insensitive=true + +## Other +hide_scroll=true +no_actions=true +sort_order=default +gtk_dark=true +filter_rate=100 + +## Keys +key_expand=Tab +key_exit=Escape diff --git a/wofi/style.css b/wofi/style.css new file mode 100644 index 0000000..ba7a20e --- /dev/null +++ b/wofi/style.css @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2020-2024 Aditya Shakya +*/ + +/** ********** Colors ********** **/ +@define-color background #3d3942; +@define-color background-alt1 #49454f; +@define-color background-alt2 #56515d; +@define-color foreground #e0dde2; +@define-color selected #C3B2CD; +@define-color black #3d3942; +@define-color red #9A9EAA; +@define-color green #A896B3; +@define-color yellow #CAAEB0; +@define-color blue #C3B2CD; +@define-color magenta #94CCC5; +@define-color cyan #A7D5CF; +@define-color white #e0dde2; + +/** ********** Fonts ********** **/ +* { + font-family: "JetBrains Mono", "Iosevka Nerd Font", archcraft, sans-serif; + font-size: 12px; +} + +#window { + background-color: @background; + color: @foreground; + border: 0px solid @background-alt1; + border-radius: 0px; +} + +#outer-box { + padding: 10px; +} + +#input { + background-color: @background-alt1; + border: 0px solid @background-alt2; + padding: 4px 12px; +} + +#scroll { + margin-top: 10px; +} + +#inner-box { +} + +#img { + padding-right: 8px; +} + +#text { + color: @foreground; +} + +#text:selected { + color: @background; +} + +#entry { + padding: 6px; +} + +#entry:selected { + background-color: @selected; + color: @background; +} + +#unselected { +} + +#selected { +} + +#input, #entry:selected { + border-radius: 0px; +} diff --git a/wofi_menu b/wofi_menu new file mode 100755 index 0000000..b632081 --- /dev/null +++ b/wofi_menu @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +## Copyright (C) 2020-2024 Aditya Shakya +## +## launch wofi with alt config + +CONFIG="$HOME/.config/hypr/wofi/config" +STYLE="$HOME/.config/hypr/wofi/style.css" + +if [[ ! `pidof wofi` ]]; then + wofi --show drun --prompt 'Search...' --conf ${CONFIG} --style ${STYLE} +else + pkill wofi +fi diff --git a/wofi_powermenu b/wofi_powermenu new file mode 100755 index 0000000..5ed837e --- /dev/null +++ b/wofi_powermenu @@ -0,0 +1,84 @@ +#!/usr/bin/env bash + +## Copyright (C) 2020-2024 Aditya Shakya +## +## Wofi Powermenu + +## Files +CONFIG="$HOME/.config/hypr/wofi/config" +STYLE="$HOME/.config/hypr/wofi/style.css" + +## Wofi Command +wofi_command="wofi --show dmenu \ + --conf ${CONFIG} --style ${STYLE} \ + --width=300 --height=215 \ + --cache-file=/dev/null \ + --hide-scroll --no-actions \ + --define=matching=fuzzy" + +uptime=$(uptime -p | sed -e 's/up //g') + +## Entries +shutdown=" Shutdown" +reboot=" Restart" +lock=" Lock" +suspend=" Sleep" +logout=" Logout" + +# Ask for confirmation +cdialog () { + yad --title='Confirm?' --borders=15 --center --fixed --undecorated --button=Yes:0 --button=No:1 --text="Are you sure?" --text-align=center +} + +# Variable passed to rofi +open_menu () { + options="$lock\n$suspend\n$logout\n$reboot\n$shutdown" + + chosen="$(echo -e "$options" | $wofi_command --prompt "UP - $uptime")" + case $chosen in + $shutdown) + cdialog + if [[ "$?" == 0 ]]; then + systemctl poweroff + else + exit + fi + ;; + $reboot) + cdialog + if [[ "$?" == 0 ]]; then + systemctl reboot + else + exit + fi + ;; + $lock) + hyprlock + ;; + $suspend) + cdialog + if [[ "$?" == 0 ]]; then + mpc -q pause + pulsemixer --mute + systemctl suspend + else + exit + fi + ;; + $logout) + cdialog + if [[ "$?" == 0 ]]; then + hyprctl dispatch exit 0 + else + exit + fi + ;; + esac +} + +if [[ ! `pidof wofi` ]]; then + open_menu +else + pkill wofi +fi +