This commit is contained in:
2025-09-27 01:01:01 +04:00
parent 959300bc41
commit 4dc5660e60
51 changed files with 2502 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
#!/bin/sh
current_abs=$(brightnessctl get)
current_rel() {
echo "$(brightnessctl get) * 100 / $(brightnessctl max)" | bc
}
max=$(brightnessctl max)
factor=3
brightness_step=$((max * factor / 100 < 1 ? 1 : max * factor / 100))
case $1'' in
'') ;;
'down')
# if current value <= 3% and absolute value != 1, set brightness to absolute 1
if [ "$(current_rel)" -le "$factor" ] && [ "$current_abs" -ge 0 ]; then
brightnessctl --quiet set 1
else
brightnessctl --quiet set "${brightness_step}-"
fi
;;
'up')
brightnessctl --quiet set "${brightness_step}+"
;;
esac
current_rel

View File

@@ -0,0 +1,22 @@
#!/bin/sh
case $1'' in
'status')
printf '{\"text\":\"%s\",\"tooltip\":\"%s\"}' "$(pamac checkupdates -q | wc -l)" "$(pamac checkupdates -q | awk 1 ORS='\\n' | sed 's/\\n$//')"
;;
'check')
[ $(pamac checkupdates -q | wc -l) -gt 0 ]
exit $?
;;
'upgrade')
if [ -x "$(command -v pacseek)" ]; then
xdg-terminal-exec pacseek -u
elif [ -x "$(command -v topgrade)" ]; then
xdg-terminal-exec topgrade
elif [ -x "$(command -v pamac-manager)" ]; then
pamac-manager --updates
else
xdg-terminal-exec pacman -Syu
fi
;;
esac

13
local/share/sway/scripts/dnd.sh Executable file
View File

@@ -0,0 +1,13 @@
#!/bin/sh
case $1'' in
'status')
printf '{\"alt\":\"%s\",\"tooltip\":\"mode: %s\"}' $(makoctl mode | grep -q 'do-not-disturb' && echo dnd || echo default) $(makoctl mode | tail -1)
;;
'restore')
makoctl restore
;;
'toggle')
makoctl mode | grep 'do-not-disturb' && makoctl mode -r do-not-disturb || makoctl mode -a do-not-disturb
;;
esac

View File

@@ -0,0 +1,18 @@
#!/bin/bash
set -xu
THEME=$1
gsettings set org.gnome.desktop.interface gtk-theme $THEME
mkdir -p "$HOME"/.config/gtk-4.0
THEME_DIR="/usr/share/themes/${THEME}/gtk-4.0"
[ -d "$THEME_DIR/assets" ] && /usr/bin/cp -rf --backup "/usr/share/themes/${THEME}/gtk-4.0/assets" "$HOME"/.config/gtk-4.0/
[ -f "$THEME_DIR/gtk.css" ] && /usr/bin/cp -rf --backup "/usr/share/themes/${THEME}/gtk-4.0/gtk.css" "$HOME"/.config/gtk-4.0/
[ -f "$THEME_DIR/gtk-dark.css" ] && /usr/bin/cp -rf --backup "/usr/share/themes/${THEME}/gtk-4.0/gtk-dark.css" "$HOME"/.config/gtk-4.0/
[ ! -f "$THEME_DIR/gtk-dark.css" ] && rm -rf "$HOME"/.config/gtk-4.0/gtk-dark.css
[ -d "$THEME_DIR/icons" ] && /usr/bin/cp -rf --backup "/usr/share/themes/${THEME}/gtk-4.0/icons" "$HOME"/.config/gtk-4.0/

View File

@@ -0,0 +1,51 @@
#!/usr/bin/python3
import i3ipc
from argparse import ArgumentParser
from time import sleep
# Assumption: it exists 10 workspaces (otherwise, change this value)
NUM_WORKSPACES = 10
if __name__ == "__main__":
arguments_parser = ArgumentParser()
arguments_parser.add_argument('-s',
'--switch',
action='store_true',
help='switch to the first empty workspace'
)
arguments_parser.add_argument('-m',
'--move',
action='store_true',
help='move the currently focused container to the first empty workspace'
)
arguments = arguments_parser.parse_args()
assert(arguments.switch or arguments.move) # at least one of the flags must be specificated
ipc = i3ipc.Connection()
tree = ipc.get_tree()
current_workspace = tree.find_focused().workspace()
workspaces = tree.workspaces() # includes current_workspace
workspace_numbers = [workspace.num for workspace in workspaces]
empty_workspace_numbers = set([number for number in range(1,NUM_WORKSPACES+1)]) - set(workspace_numbers)
# Take into consideration that the current workspace exists but might be empty
if len(current_workspace.nodes) == 0: empty_workspace_numbers.add(current_workspace.num)
# Get the minor empty workspace's number (or set it as the current workspace's number if all are busy)
first_empty_workspace_number = current_workspace.num
if empty_workspace_numbers:
first_empty_workspace_number = min(empty_workspace_numbers)
# Use the value of first_empty_workspace_number to make the requested actions
if arguments.move and arguments.switch:
# Avoid wallpaper flickering when moving and switching by specifying both actions in the same Sway's command
reply = ipc.command("move container to workspace number {}, workspace number {}".format(first_empty_workspace_number, first_empty_workspace_number))
assert(reply[0].success) # exit with non-zero status if the assertion fails
elif arguments.switch:
reply = ipc.command("workspace number {}".format(first_empty_workspace_number))
assert(reply[0].success) # exit with non-zero status if the assertion fails
elif arguments.move:
reply = ipc.command("move container to workspace number {}".format(first_empty_workspace_number))
assert(reply[0].success) # exit with non-zero status if the assertion fails

View File

@@ -0,0 +1,11 @@
#!/usr/bin/env sh
set -xu
export CATEGORY=${1:-"monospace"}
export FONT=${2:-"JetBrainsMono NF"}
FONTCONFIG_DIR=$HOME/.config/fontconfig/conf.d
mkdir -p $FONTCONFIG_DIR
cat /usr/share/sway/templates/fontconfig.conf | envsubst > $FONTCONFIG_DIR/51-${CATEGORY}.conf

View File

@@ -0,0 +1,15 @@
#!/usr/bin/env sh
# wrapper script for foot
USER_CONFIG_PATH="${HOME}/.config/foot/foot.ini"
USER_THEME_CONFIG_PATH="${HOME}/.config/foot/foot-theme.ini"
if [ -f "$USER_THEME_CONFIG_PATH" ]; then
USER_CONFIG=$USER_THEME_CONFIG_PATH
fi
if [ -f "$USER_CONFIG_PATH" ]; then
USER_CONFIG=$USER_CONFIG_PATH
fi
foot -c "${USER_CONFIG:-"/usr/share/sway/templates/foot.ini"}" $@

View File

@@ -0,0 +1,9 @@
#!/usr/bin/env sh
set -xu
export CROWN=$1
export ROOT=$2
export BACKGROUND=$3
# shellcheck disable=SC2002
cat /usr/share/sway/templates/manjarosway-scalable.svg | envsubst > "$HOME/.config/sway/generated_background.svg"

View File

@@ -0,0 +1,11 @@
#!/bin/sh
set -u
cache_file="$HOME/.cache/geoip"
cache_time=$(date -r "$cache_file" +%s)
yesterday_time=$(date -d 'now - 6 hour' +%s)
start_of_day=$(date -d '00:00' +%s)
if [ ! -f "$cache_file" ] || [ $cache_time -lt $yesterday_time ] || [ $cache_time -lt $start_of_day ]; then
curl -sL https://manjaro-sway.download/geoip >"$cache_file"
fi
cat "$cache_file"

View File

@@ -0,0 +1,31 @@
#!/usr/bin/env sh
set -x
# toggles the help wrapper state
VISIBILITY_SIGNAL=30
QUIT_SIGNAL=31
LOCKFILE="$HOME/.local/help_disabled"
if [ "$1" = "--toggle" ]; then
if [ -f "$LOCKFILE" ]; then
rm "$LOCKFILE"
else
touch "$LOCKFILE"
fi
# toggles the visibility
pkill -U $USER -f -${VISIBILITY_SIGNAL} 'nwg-wrapper.*-s help.sh'
else
# makes sure no "old" wrappers are mounted (on start and reload)
pkill -U $USER -f -${QUIT_SIGNAL} 'nwg-wrapper.*-s help.sh'
# mounts the wrapper to all outputs
for output in $(swaymsg -t get_outputs --raw | jq -r '.[].name'); do
# sets the initial visibility
if [ -f "$LOCKFILE" ]; then
VISIBILITY="--invisible"
else
VISIBILITY="--no-invisible"
fi
nwg-wrapper ${VISIBILITY} -o "$output" -sv ${VISIBILITY_SIGNAL} -sq ${QUIT_SIGNAL} -s help.sh -p left -a end &
done
fi

View File

@@ -0,0 +1,15 @@
#!/usr/bin/env sh
set -x
case $1'' in
'on')
for device in $DEVICES; do
brightnessctl -r -d "*kbd_backlight"
done
;;
'off')
for device in $DEVICES; do
brightnessctl -s -d "*kbd_backlight" && brightnessctl -d "*kbd_backlight" set 0
done
;;
esac

View File

@@ -0,0 +1,7 @@
#!/usr/bin/env sh
# script that sets the locale from current locale settings
swaymsg input type:keyboard xkb_layout "$(localectl status | grep "X11 Layout" | sed -e "s/^.*X11 Layout://")"
if localectl status | grep "X11 Variant" ; then
swaymsg input type:keyboard xkb_variant "$(localectl status | grep "X11 Variant" | sed -e "s/^.*X11 Variant://")"
fi

View File

@@ -0,0 +1,5 @@
#!/bin/sh
swaylock --daemonize --show-failed-attempts -K \
--color 282828 \
--inside-color 282828

View File

@@ -0,0 +1,10 @@
#!/usr/bin/env sh
# wrapper script for mako
USER_CONFIG_PATH="${HOME}/.config/mako/config"
if [ -f "$USER_CONFIG_PATH" ]; then
USER_CONFIG=$USER_CONFIG_PATH
fi
# mako -c "${USER_CONFIG}" "$@"
mako "$@"

View File

@@ -0,0 +1,9 @@
#!/usr/bin/env sh
mkdir -p "$HOME/.local/state"
LOCKFILE="$HOME/.local/state/once.lock"
# Kills the process if it's already running
lsof -Fp "$LOCKFILE" | sed 's/^p//' | xargs -r kill
flock --verbose -n "$LOCKFILE" "$@"

View File

@@ -0,0 +1,44 @@
#!/usr/bin/env sh
set -x
pgrep wf-recorder
status=$?
countdown() {
notify "Recording in 3 seconds" -t 1000
sleep 1
notify "Recording in 2 seconds" -t 1000
sleep 1
notify "Recording in 1 seconds" -t 1000
sleep 1
}
notify() {
line=$1
shift
notify-send "Recording" "${line}" -i /usr/share/icons/Papirus-Dark/32x32/devices/camera-video.svg $*
}
if [ $status != 0 ]; then
target_path=$(xdg-user-dir VIDEOS)
timestamp=$(date +'recording_%Y%m%d-%H%M%S')
notify "Select a region to record" -t 1000
area=$(swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | .rect | "\(.x),\(.y) \(.width)x\(.height)"' | slurp)
countdown
(sleep 0.5 && waybar-signal recorder) &
if [ "$1" = "-a" ]; then
file="$target_path/$timestamp.mp4"
wf-recorder --audio -g "$area" --file="$file"
else
file="$target_path/$timestamp.webm"
wf-recorder -g "$area" -c libvpx --codec-param="qmin=0" --codec-param="qmax=25" --codec-param="crf=4" --codec-param="b:v=1M" --file="$file"
fi
waybar-signal recorder && notify "Finished recording ${file}"
else
pkill -U $USER -x --signal SIGINT wf-recorder
waybar-signal recorder
fi

138
local/share/sway/scripts/sbdp.py Executable file
View File

@@ -0,0 +1,138 @@
#!/usr/bin/python
import sys
import glob
import re
import os
from typing import Text
import json
if len(sys.argv) >= 2:
rootPath = sys.argv[1]
else:
rootPath = '/etc/sway/config'
def readFile(filePath):
try:
paths = glob.glob(filePath)
except:
print("couldn't resolve glob:", filePath)
paths = []
allLines: list[str] = []
for path in paths:
allLines = allLines + open(path, "r").readlines()
finalLines: list[str] = []
for line in allLines:
if re.search(r'^include\s+(.+?)$', line):
nextPath = re.findall(r'^include\s+(.+?)$', line)[0]
nextPath = os.path.expandvars(nextPath)
finalLines = finalLines + readFile(nextPath)
else:
finalLines = finalLines + [line]
return finalLines
lines = readFile(rootPath)
def findKeybindingForLine(lineNumber: int, lines: list[str]):
return lines[lineNumber+1].split(' ')[1]
class DocsConfig:
category: Text
action: Text
keybinding: Text
def getDocsConfig(lines: list[str]):
docsLineRegex = r"^## (?P<category>.+?) // (?P<action>.+?)\s+(// (?P<keybinding>.+?))*##"
docsConfig: list[DocsConfig] = []
for index, line in enumerate(lines):
match = re.match(docsLineRegex, line)
if (match):
config = DocsConfig()
config.category = match.group('category')
config.action = match.group('action')
config.keybinding = match.group('keybinding')
if (config.keybinding == None):
config.keybinding = findKeybindingForLine(index, lines)
docsConfig = docsConfig + [config]
return docsConfig
def getSymbolDict(lines: list[str]):
setRegex = r"^set\s+(?P<variable>\$.+?)\s(?P<value>.+)?"
dictionary = {}
for line in lines:
match = re.match(setRegex, line)
if (match):
if (match.group('variable')):
dictionary[match.group('variable')] = match.group('value')
return dict(dictionary)
translations = {
'Mod1': "Alt",
'Mod2': "",
'Mod3': "󰘲",
'Mod4': "",
'Mod5': "Scroll",
'question': "?",
'space': "",
'minus': "-",
'plus': '+',
'Return': "󰌑",
'XF86AudioRaiseVolume': "󰝝",
'XF86AudioLowerVolume': "󰝞",
'XF86AudioMute': "󰝟",
'XF86AudioMicMute': '󰍭',
'XF86MonBrightnessUp': "󰃠",
'XF86MonBrightnessDown': "󰃞",
'XF86PowerOff': "󰐥",
'XF86TouchpadToggle': "Toggle Touchpad"
}
def translate(word: Text, dictionary: dict):
try:
return dictionary[word.strip()]
except:
return word.strip()
def replaceBindingFromMap(binding: Text, dictionary: dict):
elements = binding.split('+')
resultElements = []
for el in elements:
translation = translate(translate(el, dictionary), translations)
resultElements = resultElements + [translation]
return " + ".join(resultElements)
def sanitize(configs: list[DocsConfig], symbolDict: dict):
for index, config in enumerate(configs):
config.keybinding = replaceBindingFromMap(
config.keybinding, symbolDict)
configs[index] = config
return configs
def getDocsList(lines: list[str]):
docsConfig = getDocsConfig(lines)
symbolDict = getSymbolDict(lines)
sanitizedConfig = sanitize(docsConfig, symbolDict)
return sanitizedConfig
docsList = getDocsList(lines)
result = []
for config in docsList:
result = result + [{'category': config.category,
'action': config.action, 'keybinding': config.keybinding}]
print(json.dumps(result))

View File

@@ -0,0 +1,36 @@
#!/bin/sh
make=$(swaymsg -t get_outputs | jq -r '.[] | select(.focused==true) | .make')
model=$(swaymsg -t get_outputs | jq -r '.[] | select(.focused==true) | .model')
name=$(swaymsg -t get_outputs | jq -r '.[] | select(.focused==true) | .name')
current_screen="$make $model ($name"
increment=0.25
current_scale() {
swaymsg -t get_outputs | jq -r '.[] | select(.focused==true) | .scale'
}
next_scale=$(current_scale)
scale() {
[ -x "$(command -v way-displays)" ] && way-displays -s SCALE "$current_screen" $next_scale && way-displays -w || swaymsg output "\"$name\"" scale "$next_scale"
}
case $1'' in
'')
current_scale
;;
'up')
next_scale=$(echo "$(current_scale) + $increment" | bc)
scale
;;
'down')
next_scale=$(echo "$(current_scale) - $increment" | bc)
scale
;;
'default')
next_scale=1
scale
;;
esac

View File

@@ -0,0 +1,15 @@
#!/usr/bin/env sh
tooltip=$(swaymsg -r -t get_tree | jq -r 'recurse(.nodes[]) | first(select(.name=="__i3_scratch")) | .floating_nodes | .[] | "\(.app_id) | \(.name)"')
count=$(printf "%s" "$tooltip" | grep -c '^')
if [ "$count" -eq 0 ]; then
exit 1
elif [ "$count" -eq 1 ]; then
class="one"
elif [ "$count" -gt 1 ]; then
class="many"
else
class="unknown"
fi
printf '{"text":"%s", "class":"%s", "alt":"%s", "tooltip":"%s"}\n' "$count" "$class" "$class" "$(echo "${tooltip}" | sed -z 's/\n/\\n/g')"

View File

@@ -0,0 +1,8 @@
#!/usr/bin/env sh
set -e
DIR=${XDG_SCREENSHOTS_DIR:-$HOME/Screenshots}
while true; do
mkdir -p "$DIR" && inotifywait -q -e create "$DIR" --format '%w%f' | xargs notify-send "Screenshot saved"
done

View File

@@ -0,0 +1,67 @@
#!/usr/bin/env sh
config="$HOME/.config/wlsunset/config"
#Startup function
start() {
[ -f "$config" ] && . "$config"
temp_low=${temp_low:-"4000"}
temp_high=${temp_high:-"6500"}
duration=${duration:-"900"}
sunrise=${sunrise:-"07:00"}
sunset=${sunset:-"19:00"}
location=${location:-"on"}
fallback_longitude=${fallback_longitude:-"8.7"}
fallback_latitude=${fallback_latitude:-"50.1"}
if [ "${location}" = "on" ]; then
if [ -z ${longitude+x} ] || [ -z ${latitude+x} ]; then
GEO_CONTENT=$(sh /usr/share/sway/scripts/geoip.sh)
fi
longitude=${longitude:-$(echo "$GEO_CONTENT" | jq -r '.longitude // empty')}
longitude=${longitude:-$fallback_longitude}
latitude=${latitude:-$(echo "$GEO_CONTENT" | jq -r '.latitude // empty')}
latitude=${latitude:-$fallback_latitude}
echo longitude: "$longitude" latitude: "$latitude"
wlsunset -l "$latitude" -L "$longitude" -t "$temp_low" -T "$temp_high" -d "$duration" &
else
wlsunset -t "$temp_low" -T "$temp_high" -d "$duration" -S "$sunrise" -s "$sunset" &
fi
}
#Accepts managing parameter
case $1'' in
'off')
pkill -U $USER -x wlsunset
waybar-signal sunset
;;
'on')
start
waybar-signal sunset
;;
'toggle')
if pkill -U $USER -x -0 wlsunset; then
pkill -U $USER -x wlsunset
else
start
fi
waybar-signal sunset
;;
'check')
command -v wlsunset
exit $?
;;
esac
#Returns a string for Waybar
if pkill -U $USER -x -0 wlsunset; then
class="on"
text="location-based gamma correction"
else
class="off"
text="no gamma correction"
fi
printf '{"alt":"%s","tooltip":"%s"}\n' "$class" "$text"

View File

@@ -0,0 +1,122 @@
#!/usr/bin/env bash
set -u
LOCKFILE="$HOME/.local/auto-theme-toggle"
DARK_SWAY_THEME="$HOME/.config/sway/definitions.d/theme.dark.conf_"
LIGHT_SWAY_THEME="$HOME/.config/sway/definitions.d/theme.light.conf_"
CURRENT_PRIMARY_THEME="dark"
CURRENT_SECONDARY_THEME="light"
NEXT_PRIMARY_THEME="dark"
NEXT_SECONDARY_THEME="light"
if [ -f "$DARK_SWAY_THEME" ]; then
CURRENT_PRIMARY_THEME="light"
CURRENT_SECONDARY_THEME="dark"
NEXT_PRIMARY_THEME="light"
NEXT_SECONDARY_THEME="dark"
fi
current_unix=$(date +%s)
__geo_content=$(sh /usr/share/sway/scripts/geoip.sh)
sunrise_unix() {
sunrise_string=$(echo "$__geo_content" | jq -r '.sunrise // empty')
sunrise_unix=$(date -d "$sunrise_string" +%s)
echo "$sunrise_unix"
}
sunset_unix() {
sunset_string=$(echo "$__geo_content" | jq -r '.sunset // empty')
sunset_unix=$(date -d "$sunset_string" +%s)
echo "$sunset_unix"
}
tomorrow_sunrise_unix() {
sunrise_string=$(echo "$__geo_content" | jq -r '.sunrise_tomorrow // empty')
sunrise_unix=$(date -d "$sunrise_string" +%s)
echo "$sunrise_unix"
}
tomorrow_sunset_unix() {
sunset_string=$(echo "$__geo_content" | jq -r '.sunset_tomorrow // empty')
sunset_unix=$(date -d "$sunset_string" +%s)
echo "$sunset_unix"
}
if [ -f "$LOCKFILE" ]; then
if [ $current_unix -ge $(sunrise_unix) ] && [ $current_unix -lt $(sunset_unix) ]; then
NEXT_PRIMARY_THEME="light"
NEXT_SECONDARY_THEME="dark"
else
NEXT_PRIMARY_THEME="dark"
NEXT_SECONDARY_THEME="light"
fi
fi
ensure_theme() {
if [ "$CURRENT_PRIMARY_THEME" != "$1" ]; then
PRIMARY_SWAY_THEME="$HOME/.config/sway/definitions.d/theme.conf"
PRIMARY_FOOT_THEME="$HOME/.config/foot/foot-theme.ini"
/usr/bin/mv --backup -v $PRIMARY_SWAY_THEME "$HOME/.config/sway/definitions.d/theme.$2.conf_"
/usr/bin/mv --backup -v $PRIMARY_FOOT_THEME "$HOME/.config/foot/foot-theme.$2.ini_"
/usr/bin/mv --backup -v "$HOME/.config/sway/definitions.d/theme.$1.conf_" $PRIMARY_SWAY_THEME
/usr/bin/mv --backup -v "$HOME/.config/foot/foot-theme.$1.ini_" $PRIMARY_FOOT_THEME
swaymsg reload
fi
}
#Accepts managing parameter
case $1'' in
'toggle')
if [ -f "$LOCKFILE" ]; then
NEXT_PRIMARY_THEME="$CURRENT_PRIMARY_THEME"
NEXT_SECONDARY_THEME="$CURRENT_SECONDARY_THEME"
else
NEXT_PRIMARY_THEME="$CURRENT_SECONDARY_THEME"
NEXT_SECONDARY_THEME="$CURRENT_PRIMARY_THEME"
fi
ensure_theme $NEXT_PRIMARY_THEME $NEXT_SECONDARY_THEME
exit 0
;;
'auto-toggle')
if [ -f "$LOCKFILE" ]; then
rm "$LOCKFILE"
else
touch "$LOCKFILE"
fi
waybar-signal theme
exit 0
;;
'check')
[ -f "$DARK_SWAY_THEME" ] || [ -f "$LIGHT_SWAY_THEME" ]
exit $?
;;
'status')
#Returns a string for Waybar
text="switch to ${CURRENT_SECONDARY_THEME} theme\r(Right click to switch automatically)"
alt=$CURRENT_PRIMARY_THEME
if [ -f "$LOCKFILE" ]; then
next_switch_unix=$(sunrise_unix)
if [ $current_unix -ge $next_switch_unix ]; then
next_switch_unix=$(sunset_unix)
fi
if [ $current_unix -ge $next_switch_unix ]; then
next_switch_unix=$(tomorrow_sunrise_unix)
fi
hours=$((($next_switch_unix - $current_unix) / (60 * 60)))
minutes=$((($next_switch_unix - $current_unix) / 60 % 60))
text="switching to ${CURRENT_SECONDARY_THEME} theme in ${hours}h ${minutes}m\r(Right click to disable)"
alt="auto_${CURRENT_PRIMARY_THEME}"
ensure_theme $NEXT_PRIMARY_THEME $NEXT_SECONDARY_THEME
fi
printf '{"alt":"%s","tooltip":"%s"}\n' "$alt" "$text"
exit 0
;;
esac

View File

@@ -0,0 +1,15 @@
#!/bin/sh
set -x
PID=$(swaymsg -t get_tree | jq '.. | select(.type?) | select(.focused==true) | .pid')
matcher=$1
shift
type=$@
swaymsg [$matcher] focus
if [ "$?" = "0" ]
then
wtype $type
swaymsg "[pid=$PID] focus"
fi

View File

@@ -0,0 +1,97 @@
#!/usr/bin/env python3
import dbus
import json
import logging, sys
import os
import math
level = logging.DEBUG if os.environ.get("DEBUG") == "true" else logging.INFO
logging.basicConfig(stream=sys.stderr, level=level)
CONNECTIVITY_STRENGTH_SYMBOL = ["󰞃", "󰢼", "󰢽", "󰢾", "󰢾"]
BATTERY_PERCENTAGE_SYMBOL = ["󱃍", "󰁺", "󰁼", "󰁽", "󰁾", "󰁿", "󰂀", "󰂁", "󰂂", "󰁹"]
bus = dbus.SessionBus()
valent_object = bus.get_object("ca.andyholmes.Valent", "/ca/andyholmes/Valent")
valent_interface = dbus.Interface(valent_object, "org.freedesktop.DBus.ObjectManager")
managed_objects = valent_interface.GetManagedObjects()
dangerously_empty = False
connected = False
no_connectivity = False
devices = []
for path in managed_objects:
device = {}
device["state"] = (
"connected"
if managed_objects[path].get("ca.andyholmes.Valent.Device", {}).get("State", 0)
== 3
else "disconnected"
)
device["id"] = (
managed_objects[path].get("ca.andyholmes.Valent.Device", {}).get("Id", 0)
)
device["name"] = (
managed_objects[path].get("ca.andyholmes.Valent.Device", {}).get("Name", 0)
)
device_obj = bus.get_object("ca.andyholmes.Valent", path)
device_action_interface = dbus.Interface(device_obj, "org.gtk.Actions")
battery_state = device_action_interface.Describe("battery.state")[2][0]
device["battery_percentage"] = battery_state["percentage"]
device["battery_status"] = (
"discharging" if battery_state["charging"] == 0 else "charging"
)
connectivity_state = device_action_interface.Describe("connectivity_report.state")[
2
][0]["signal-strengths"]["1"]
device["connectivity_strength"] = connectivity_state["signal-strength"]
if device["state"] == "connected":
connected = True
if device["connectivity_strength"] <= 1:
no_connectivity = True
if device["battery_percentage"] <= 15 and device["battery_status"] == "discharging":
dangerously_empty = True
devices.append(device)
data = {}
data["alt"] = (
"no-devices"
if len(devices) == 0
else "dangerously-empty"
if dangerously_empty
else "no-signal"
if no_connectivity
else "connected"
if connected
else "disconnected"
)
data["class"] = data["alt"]
data["tooltip"] = ""
logging.debug(devices)
tooltip = []
for device in devices:
battery_symbol = math.ceil(round(device["battery_percentage"] / 10, 0))
details = (
f"\t{CONNECTIVITY_STRENGTH_SYMBOL[device['connectivity_strength']]} {BATTERY_PERCENTAGE_SYMBOL[battery_symbol]} {device['battery_percentage']}% ({device['battery_status']})"
if device["state"] == "connected"
else ""
)
tooltip.append(f"{device['name']} ({device['state']}){details}")
data["tooltip"] = "\n".join(tooltip)
print(json.dumps(data))

View File

@@ -0,0 +1,17 @@
#!/usr/bin/env bash
# wrapper script for waybar with args, see https://github.com/swaywm/sway/issues/5724
USER_CONFIG_PATH=$HOME/.config/waybar/config.jsonc
USER_STYLE_PATH=$HOME/.config/waybar/style.css
pkill -U $USER -x waybar
if [ -f "$USER_CONFIG_PATH" ]; then
USER_CONFIG=$USER_CONFIG_PATH
fi
if [ -f "$USER_STYLE_PATH" ]; then
USER_STYLE=$USER_STYLE_PATH
fi
waybar -c "${USER_CONFIG}" -s "${USER_STYLE}" > $(mktemp -t XXXX.waybar.log)

View File

@@ -0,0 +1,89 @@
#!/usr/bin/env python
"""Script for the Waybar weather module."""
import getopt
import json
import locale
import sys
import urllib.parse
from datetime import datetime
import requests
import configparser
from os import path, environ
config_path = path.join(
environ.get('APPDATA') or
environ.get('XDG_CONFIG_HOME') or
path.join(environ['HOME'], '.config'),
"weather.cfg"
)
config = configparser.ConfigParser()
config.read(config_path)
# see https://docs.python.org/3/library/locale.html#background-details-hints-tips-and-caveats
locale.setlocale(locale.LC_ALL, "")
current_locale, _ = locale.getlocale(locale.LC_NUMERIC)
city = config.get('DEFAULT', 'city', fallback='auto')
temperature = config.get('DEFAULT', 'temperature', fallback='C')
distance = config.get('DEFAULT', 'distance', fallback='km')
lng = config.get('DEFAULT', 'locale', fallback=locale.getlocale()[0] or current_locale)
if current_locale == "en_US":
temperature = temperature or "F"
distance = distance or "miles"
argument_list = sys.argv[1:]
options = "t:c:d:"
long_options = ["temperature=", "city=", "distance="]
try:
args, values = getopt.getopt(argument_list, options, long_options)
for current_argument, current_value in args:
if current_argument in ("-t", "--temperature"):
temperature = current_value[0].upper()
if temperature not in ("C", "F"):
msg = "temperature unit is neither (C)elsius, nor (F)ahrenheit"
raise RuntimeError(
msg,
temperature,
)
elif current_argument in ("-d", "--distance"):
distance = current_value.lower()
if distance not in ("km", "miles"):
msg = "distance unit is neither km, nor miles", distance
raise RuntimeError(msg)
else:
city = urllib.parse.quote(current_value)
except getopt.error as err:
print(str(err))
sys.exit(1)
if temperature == "F":
temperature_unit = "fahrenheit"
if temperature == "C":
temperature_unit = "celsius"
if distance == "miles":
wind_speed_unit = "mph"
if distance == "km":
wind_speed_unit = "kmh"
try:
headers = {"Accept-Language": f"{lng.replace("_", "-")},{lng.split("_")[0]};q=0.5"}
weather = requests.get(f"https://manjaro-sway.download/weather/{city}?temperature_unit={temperature_unit}&wind_speed_unit={wind_speed_unit}", timeout=10, headers=headers).json()
except (
requests.exceptions.HTTPError,
requests.exceptions.ConnectionError,
requests.exceptions.Timeout,
) as err:
print(str(err))
sys.exit(1)
print(json.dumps(weather))

View File

@@ -0,0 +1,28 @@
#!/usr/bin/env sh
status() {
systemctl --user is-active wluma >/dev/null 2>&1
}
#Accepts managing parameter
case $1'' in
'toggle')
status && systemctl --user stop wluma || systemctl --user --now enable wluma
waybar-signal adaptive_brightness
;;
'check')
[ -x "$(command -v wluma)" ] && [ $(ls -A /sys/class/backlight/ | wc -l) -gt 0 ]
exit $?
;;
esac
#Returns data for Waybar
if status; then
class="on"
text="adaptive brightness"
else
class="off"
text="static brightness"
fi
printf '{"alt":"%s","tooltip":"%s"}\n' "$class" "$text"

49
local/share/sway/scripts/wob.sh Executable file
View File

@@ -0,0 +1,49 @@
#!/usr/bin/env sh
# https://github.com/francma/wob/wiki/wob-wrapper-script
#$1 - accent color. $2 - background color. $3 - new value
# returns 0 (success) if $1 is running and is attached to this sway session; else 1
is_running_on_this_screen() {
pkill -U $USER -x -0 "wob" || return 1
for pid in $(pgrep "wob"); do
WOB_SWAYSOCK="$(tr '\0' '\n' </proc/"$pid"/environ | awk -F'=' '/^SWAYSOCK/ {print $2}')"
if [ "$WOB_SWAYSOCK" = "$SWAYSOCK" ]; then
return 0
fi
done
return 1
}
wob_pipe=~/.cache/$(basename "$SWAYSOCK").wob
[ -p "$wob_pipe" ] || mkfifo "$wob_pipe"
ini=~/.config/wob.ini
refresh() {
pkill -U $USER -x wob
rm $ini
{
echo "anchor = top center"
echo "margin = 20"
echo "border_color = $(echo "$1" | sed 's/#//')"
echo "bar_color = $(echo "$1" | sed 's/#//')"
echo "background_color = $(echo "$2" | sed 's/#//')"
} >>$ini
}
if [ ! -f "$ini" ] || [ "$3" = "--refresh" ]; then
refresh "$1" "$2"
fi
# wob does not appear in $(swaymsg -t get_msg), so:
is_running_on_this_screen || {
tail -f "$wob_pipe" | wob -c $ini &
}
if [ "$3" = "--refresh" ]; then
exit 0;
elif [ -n "$3" ]; then
echo "$3" >"$wob_pipe"
else
cat >"$wob_pipe"
fi