Wire up more scripts

This commit is contained in:
Aleksey Samoilov 2023-05-05 17:13:31 +04:00
parent f121c42e2c
commit b5cd4f058c
11 changed files with 443 additions and 0 deletions

View file

@ -3,10 +3,14 @@
exec {
$polkit_agent
$swappy_notify
$dex_autostart
$wlsunset
$autotiling
$term_server
$cliphist_store
$cliphist_watch
$autoname_workspaces
$pcmanfm_daemon
}
exec_always {
@ -16,4 +20,5 @@ exec_always {
$poweralertd
$watch_playerctl
$calendar_daemon
$import_gsettings
}

View file

@ -21,6 +21,26 @@ set $menu fuzzel
# Add --to-code to bindsym, support for non-latin layouts
set $bindsym bindsym --to-code
# Volume notification
set $volume_bar /usr/share/sway/scripts/volume-notify.sh
# Brightness notification
set $brightness_bar /usr/share/sway/scripts/brightness-notify.sh
# brightness control
set $brightness_step bash -c 'echo $(( $(light -Mr) / 100 * 5 < 1 ? 1 : $(( $(light -Mr) / 100 * 5 )) ))'
set $brightness_up light -r -A $($brightness_step) && $brightness_bar
set $brightness_down light -r -U $($brightness_step) && $brightness_bar
# Volume control
set $volume_down pulsemixer --change-volume -5 && $volume_bar
set $volume_up pulsemixer --change-volume +5 && $volume_bar
set $volume_mute pulsemixer --toggle-mute && $volume_bar
# clipboard history
set $clipboard cliphist list | fuzzel -dmenu -p "Select item to copy" --lines 10 --width 35 | cliphist decode | wl-copy
set $clipboard-del cliphist list | fuzzel -dmenu -p "Select item to delete" --lines 10 --width 35 | cliphist delete
# Pulseaudo command
set $pulseaudio $term_float pulsemixer
@ -54,12 +74,21 @@ set $screenshot_active $pipe_active | $swappy && $notify_paste
# PolicyKit agent
set $polkit_agent /usr/bin/mate-polkit &
# Night Light
set $wlsunset '[ -x "$(command -v wlsunset)" ] && /usr/share/sway/scripts/sunset.sh "on"'
# Autotiling script
set $autotiling '[ -x "$(command -v autotiling)" ] && autotiling -w 1 3 5 7 9'
# Automatic workspace names
set $autoname_workspaces '[ -f /usr/share/sway/scripts/autoname-workspaces.py ] && /usr/share/sway/scripts/autoname-workspaces.py'
# restart kanshi https://github.com/emersion/kanshi/issues/43#issuecomment-531679213
set $kanshi '[ -x "$(command -v kanshi)" ] && pkill kanshi; exec kanshi'
# Workaround for applying GTK theme
set $import_gsettings '[ -f /usr/share/sway/scripts/import-gsettings.sh ] && /usr/share/sway/scripts/import-gsettings.sh'
# Dex autostart daemon
set $dex_autostart '[ -x "$(command -v dex)" ] && gdbus wait --session org.kde.StatusNotifierWatcher && dex --autostart'

View file

@ -0,0 +1,165 @@
#!/usr/bin/python
# This script requires i3ipc-python package (install it from a system package manager
# or pip).
# It adds icons to the workspace name for each open window.
# Set your keybindings like this: set $workspace1 workspace number 1
# Add your icons to WINDOW_ICONS.
# Based on https://github.com/maximbaz/dotfiles/blob/master/bin/i3-autoname-workspaces
import argparse
import i3ipc
import logging
import re
import signal
import sys
WINDOW_ICONS = {
"audacious": "",
"azote": "",
"balena-etcher": "",
"Chromium": "",
"chromium": "",
"code": "",
"discord": "",
"engrampa": "",
"firefox": "",
"foot": "",
"gimp-2.10": "",
"gimp-2.99": "",
"Google-chrome": "",
"google-chrome": "",
"gpk-application": "",
"libreoffice-startcenter": "",
"libreoffice-writer": "",
"libreoffice-calc": "",
"libreoffice-impress": "",
"libreoffice-draw": "",
"lximage-qt": "",
"mate-calc": "",
"mpv": "",
"nheko": "",
"nwg-look": "",
"nwg-displays": "",
"org.telegram.desktop": "",
"org.qbittorrent.qBittorrent": "",
"org.pwmt.zathura": "",
"org.inkscape.inkscape": "",
"pavucontrol": "",
"pluma": "",
"pcmanfm": "",
"simple-scan": "",
"software-properties-gtk": "",
"steam": "",
"sway-input-config": "",
"telegram": "",
"Thunderbird": "",
"thunderbird": "",
"transmission-gtk": "",
"vlc": ""
}
DEFAULT_ICON = ""
def icon_for_window(window):
name = None
if window.app_id is not None and len(window.app_id) > 0:
name = window.app_id.lower()
elif window.window_class is not None and len(window.window_class) > 0:
name = window.window_class.lower()
if name in WINDOW_ICONS:
return WINDOW_ICONS[name]
logging.info("No icon available for window with name: %s" % str(name))
return DEFAULT_ICON
def rename_workspaces(ipc):
for workspace in ipc.get_tree().workspaces():
name_parts = parse_workspace_name(workspace.name)
icon_tuple = ()
for w in workspace:
if w.app_id is not None or w.window_class is not None:
icon = icon_for_window(w)
if not ARGUMENTS.duplicates and icon in icon_tuple:
continue
icon_tuple += (icon,)
name_parts["icons"] = " ".join(icon_tuple) + " "
new_name = construct_workspace_name(name_parts)
ipc.command('rename workspace "%s" to "%s"' % (workspace.name, new_name))
def undo_window_renaming(ipc):
for workspace in ipc.get_tree().workspaces():
name_parts = parse_workspace_name(workspace.name)
name_parts["icons"] = None
new_name = construct_workspace_name(name_parts)
ipc.command('rename workspace "%s" to "%s"' % (workspace.name, new_name))
ipc.main_quit()
sys.exit(0)
def parse_workspace_name(name):
return re.match(
"(?P<num>[0-9]+):?(?P<shortname>\w+)? ?(?P<icons>.+)?", name
).groupdict()
def construct_workspace_name(parts):
new_name = str(parts["num"])
if parts["shortname"] or parts["icons"]:
new_name += ":"
if parts["shortname"]:
new_name += parts["shortname"]
if parts["icons"]:
new_name += " " + parts["icons"]
return new_name
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="This script automatically changes the workspace name in sway depending on your open applications."
)
parser.add_argument(
"--duplicates",
"-d",
action="store_true",
help="Set it when you want an icon for each instance of the same application per workspace.",
)
parser.add_argument(
"--logfile",
"-l",
type=str,
default="/tmp/sway-autoname-workspaces.log",
help="Path for the logfile.",
)
args = parser.parse_args()
global ARGUMENTS
ARGUMENTS = args
logging.basicConfig(
level=logging.INFO,
filename=ARGUMENTS.logfile,
filemode="w",
format="%(message)s",
)
ipc = i3ipc.Connection()
for sig in [signal.SIGINT, signal.SIGTERM]:
signal.signal(sig, lambda signal, frame: undo_window_renaming(ipc))
def window_event_handler(ipc, e):
if e.change in ["new", "close", "move"]:
rename_workspaces(ipc)
ipc.on("window", window_event_handler)
rename_workspaces(ipc)
ipc.main()

View file

@ -0,0 +1,11 @@
#!/bin/sh
VALUE=$(light -G | cut -d'.' -f1)
TEXT="Brightness: ${VALUE}%"
notify-send \
--expire-time 800 \
--hint string:x-canonical-private-synchronous:brightness \
--hint "int:value:$VALUE" \
--hint "int:transient:1" \
"${TEXT}"

View file

@ -0,0 +1,54 @@
#!/usr/bin/python3
from argparse import ArgumentParser
import i3ipc
# 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 specification
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 workspaces number (or set it as the current workspaces 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,26 @@
#!/bin/sh
# usage: import-gsettings
config="${XDG_CONFIG_HOME:-$HOME/.config}/gtk-3.0/settings.ini"
if [ ! -f "$config" ]; then exit 1; fi
# Color scheme for GTK apps can be 0 (light, default) and 1 (dark)
color_scheme="$(grep 'gtk-application-prefer-dark-theme' "$config" | sed 's/.*\s*=\s*//')"
cursor_theme="$(grep 'gtk-cursor-theme-name' "$config" | sed 's/.*\s*=\s*//')"
font_name="$(grep 'gtk-font-name' "$config" | sed 's/.*\s*=\s*//')"
gnome_schema="org.gnome.desktop.interface"
gnome_wm_schema="org.gnome.desktop.wm.preferences"
gtk_theme="$(grep 'gtk-theme-name' "$config" | sed 's/.*\s*=\s*//')"
icon_theme="$(grep 'gtk-icon-theme-name' "$config" | sed 's/.*\s*=\s*//')"
gsettings set "$gnome_schema" gtk-theme "$gtk_theme"
gsettings set "$gnome_schema" icon-theme "$icon_theme"
gsettings set "$gnome_schema" cursor-theme "$cursor_theme"
gsettings set "$gnome_schema" font-name "$font_name"
gsettings set "$gnome_wm_schema" button-layout ""
if [ "$color_scheme" -eq 1 ]; then
gsettings set "$gnome_schema" color-scheme "prefer-dark"
else
gsettings set "$gnome_schema" color-scheme "prefer-light"
fi

View file

@ -0,0 +1,44 @@
#!/bin/bash
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/Yaru/scalable/devices/camera-video-symbolic.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 && pkill -RTMIN+8 waybar) &
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
pkill -RTMIN+8 waybar && notify "Finished recording ${file}"
else
pkill --signal SIGINT wf-recorder
pkill -RTMIN+8 waybar
fi

View file

@ -0,0 +1,15 @@
#!/bin/bash
tooltip=$(swaymsg -r -t get_tree | jq -r 'recurse(.nodes[]) | first(select(.name=="__i3_scratch")) | .floating_nodes | .[] | "\(.app_id) | \(.name)"')
count=$(echo -n "$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" "${tooltip//$'\n'/'\n'}"

View file

@ -0,0 +1,8 @@
#!/bin/sh
set -e
DIR=${XDG_PICTURES_DIR:-$HOME/Pictures}
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,64 @@
#!/bin/bash
#Startup function
function start() {
[[ -f "$HOME/.config/wlsunset/config" ]] && source "$HOME/.config/wlsunset/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=$(curl -sL https://freegeoip.live/json/)
fi
longitude=${longitude:-$(echo "$GEO_CONTENT" | jq '.longitude // empty')}
longitude=${longitude:-$fallback_longitude}
latitude=${latitude:-$(echo "$GEO_CONTENT" | jq '.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 wlsunset
;;
'on')
start
;;
'toggle')
if pkill -0 wlsunset; then
pkill wlsunset
else
start
fi
;;
'check')
command -v wlsunset
exit $?
;;
esac
#Returns a string for Waybar
if pkill -0 wlsunset; then
class="on"
tooltip="Night Color mode: enabled"
else
class="off"
tooltip="Night Color mode: disabled"
fi
printf '{"alt":"%s", "tooltip":"%s"}\n' "$class" "$tooltip"

View file

@ -0,0 +1,22 @@
#!/bin/sh
VOLUME=$(pulsemixer --get-volume)
# get first percent value
VOLUME=${VOLUME%%%*}
VOLUME=${VOLUME##* }
TEXT="Volume: ${VOLUME}%"
case $(pulsemixer --get-mute) in
*1)
TEXT="Volume: muted"
VOLUME=0
;;
esac
notify-send \
--app-name sway \
--expire-time 800 \
--hint string:x-canonical-private-synchronous:volume \
--hint "int:value:$VOLUME" \
--hint "int:transient:1" \
"${TEXT}"