File permissions for Arch Linux
This commit is contained in:
parent
f1076fa383
commit
777a0c3d29
|
@ -21,6 +21,9 @@ switch (uname)
|
|||
# Android
|
||||
fish_add_path -a /usr/share/android-tools
|
||||
|
||||
# rocm
|
||||
fish_add_path -a /opt/rocm/bin
|
||||
|
||||
# Java
|
||||
#fish_add_path -a /usr/local/jdk-21/bin
|
||||
|
||||
|
@ -28,10 +31,14 @@ switch (uname)
|
|||
#fish_add_path -a /usr/local/share/ltex-ls-16.0.0/bin
|
||||
|
||||
# pyenv
|
||||
fish_add_path -a /usr/share/pyenv/bin
|
||||
pyenv init - | source
|
||||
set -x PYENV_ROOT /usr/share/pyenv
|
||||
fish_add_path -a $PYENV_ROOT/bin
|
||||
pyenv init - fish | source
|
||||
status --is-interactive; and pyenv virtualenv-init - | source
|
||||
|
||||
# Zig
|
||||
fish_add_path -a /usr/share/zig
|
||||
|
||||
|
||||
|
||||
# VARIABLES
|
||||
|
|
|
@ -87,6 +87,19 @@ macos-icon = official
|
|||
macos-icon-frame = aluminum
|
||||
macos-icon-ghost-color =
|
||||
macos-icon-screen-color =
|
||||
linux-cgroup = single-instance
|
||||
linux-cgroup-memory-limit =
|
||||
linux-cgroup-processes-limit =
|
||||
linux-cgroup-hard-fail = false
|
||||
gtk-single-instance = desktop
|
||||
#gtk-titlebar = true
|
||||
gtk-titlebar = false
|
||||
gtk-tabs-location = top
|
||||
adw-toolbar-style = raised
|
||||
#adw-toast = clipboard-copy
|
||||
gtk-wide-tabs = true
|
||||
gtk-adwaita = true
|
||||
#gtk-custom-css =
|
||||
desktop-notifications = true
|
||||
bold-is-bright = false
|
||||
term = xterm-ghostty
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
return {
|
||||
"lukas-reineke/indent-blankline.nvim",
|
||||
event = { "BufReadPre", "BufNewFile" },
|
||||
main = "ibl",
|
||||
opts = {
|
||||
indent = { char = "┊" },
|
||||
},
|
||||
"lukas-reineke/indent-blankline.nvim",
|
||||
event = { "BufReadPre", "BufNewFile" },
|
||||
main = "ibl",
|
||||
opts = {
|
||||
indent = { char = "┊" },
|
||||
},
|
||||
}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
# Default config for sway
|
||||
#
|
||||
# Copy this to ~/.config/sway/config and edit it to your liking.
|
||||
#
|
||||
# Read `man 5 sway` for a complete reference.
|
||||
|
||||
# openSUSE theme
|
||||
default_border pixel 2
|
||||
gaps inner 10
|
||||
client.focused #6da741 #173f4f #73ba25
|
||||
client.unfocused #00a489 #173f4f #35b9ab
|
||||
client.focused_inactive #6da741 #00a489 #173f4f
|
||||
|
||||
#don't show gaps if there's only one window on the desktop
|
||||
smart_gaps on
|
||||
|
||||
### Variables
|
||||
#
|
||||
# Logo key. Use Mod1 for Alt.
|
||||
set $mod Mod4
|
||||
|
||||
# Home row direction keys, like vim
|
||||
set $left h
|
||||
set $down j
|
||||
set $up k
|
||||
set $right l
|
||||
|
||||
# Waybar position
|
||||
set $waybar_position top
|
||||
|
||||
# Your preferred terminal emulator
|
||||
#set $term alacritty #--config-file ~/.config/alacritty/alacritty.yml
|
||||
set $term ghostty
|
||||
|
||||
# Your preferred application launcher
|
||||
# Note: pass the final command to swaymsg so that the resulting window can be opened
|
||||
# on the original workspace that the command was run on.
|
||||
#set $menu dmenu_path | dmenu | xargs swaymsg exec --
|
||||
# it is set in config.d/50-openSUSE.conf
|
||||
|
||||
# wofi as application launcher
|
||||
set $menu wofi -I -S drun --conf=/etc/wofi/config --style=/etc/wofi/style.css
|
||||
#set $menu rofi -no-lazy-grab -disable-history -modi "drun" -show drun -theme ~/.config/rofi/config.rasi
|
||||
|
||||
# Sway Notification Centre
|
||||
set $toggle_notification "swaync-client -t -sw"
|
||||
|
||||
# Wob
|
||||
set $wob wob --config ~/.config/sway/wob/wob.ini
|
||||
|
||||
# background
|
||||
set $background ~/.config/backgrounds/tokyonight.jpg
|
||||
|
||||
# monitors
|
||||
set $ext_monitor HDMI-A-1
|
||||
set $int_monitor eDP-1
|
||||
|
||||
# screen capture
|
||||
set $screen grimshot copy
|
||||
# screen capture
|
||||
set $screen_area grimshot copy area
|
||||
|
||||
|
||||
include ~/.config/sway/config.d/*.conf
|
||||
include ~/.config/sway/inputs/*.conf
|
||||
include ~/.config/sway/outputs/*.conf
|
||||
include ~/.config/sway/modes/*.conf
|
||||
include ~/.config/sway/config.d/*
|
|
@ -0,0 +1,143 @@
|
|||
### Key bindings
|
||||
#
|
||||
# Basics:
|
||||
#
|
||||
# Start a terminal
|
||||
bindsym $mod+Shift+Return exec $term
|
||||
|
||||
# Kill focused window
|
||||
bindsym $mod+Shift+c kill
|
||||
|
||||
# Start your launcher
|
||||
bindsym $mod+p exec $menu
|
||||
|
||||
# Screen capture
|
||||
bindsym $mod+Print exec $screen
|
||||
|
||||
# Screen capture area
|
||||
bindsym $mod+Shift+Print exec $screen_area
|
||||
|
||||
# Drag floating windows by holding down $mod and left mouse button.
|
||||
# Resize them with right mouse button + $mod.
|
||||
# Despite the name, also works for non-floating windows.
|
||||
# Change normal to inverse to use left mouse button for resizing and right
|
||||
# mouse button for dragging.
|
||||
floating_modifier $mod normal
|
||||
|
||||
# Reload the configuration file
|
||||
bindsym $mod+q reload
|
||||
|
||||
# Exit sway (logs you out of your Wayland session)
|
||||
bindsym $mod+Shift+q exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit'
|
||||
|
||||
#
|
||||
# Moving around:
|
||||
#
|
||||
# Move your focus around
|
||||
bindsym $mod+$left focus left
|
||||
bindsym $mod+$down focus down
|
||||
bindsym $mod+$up focus up
|
||||
bindsym $mod+$right focus right
|
||||
# Or use $mod+[up|down|left|right]
|
||||
bindsym $mod+Left focus left
|
||||
bindsym $mod+Down focus down
|
||||
bindsym $mod+Up focus up
|
||||
bindsym $mod+Right focus right
|
||||
|
||||
# Move the focused window with the same, but add Shift
|
||||
bindsym $mod+Shift+$left move left
|
||||
bindsym $mod+Shift+$down move down
|
||||
bindsym $mod+Shift+$up move up
|
||||
bindsym $mod+Shift+$right move right
|
||||
# Ditto, with arrow keys
|
||||
bindsym $mod+Shift+Left move left
|
||||
bindsym $mod+Shift+Down move down
|
||||
bindsym $mod+Shift+Up move up
|
||||
bindsym $mod+Shift+Right move right
|
||||
#
|
||||
# Workspaces:
|
||||
#
|
||||
# Switch to workspace
|
||||
bindsym $mod+1 workspace number 1
|
||||
bindsym $mod+2 workspace number 2
|
||||
bindsym $mod+3 workspace number 3
|
||||
bindsym $mod+4 workspace number 4
|
||||
bindsym $mod+5 workspace number 5
|
||||
bindsym $mod+6 workspace number 6
|
||||
bindsym $mod+7 workspace number 7
|
||||
bindsym $mod+8 workspace number 8
|
||||
bindsym $mod+9 workspace number 9
|
||||
bindsym $mod+0 workspace number 10
|
||||
# Move focused container to workspace
|
||||
bindsym $mod+Shift+1 move container to workspace number 1
|
||||
bindsym $mod+Shift+2 move container to workspace number 2
|
||||
bindsym $mod+Shift+3 move container to workspace number 3
|
||||
bindsym $mod+Shift+4 move container to workspace number 4
|
||||
bindsym $mod+Shift+5 move container to workspace number 5
|
||||
bindsym $mod+Shift+6 move container to workspace number 6
|
||||
bindsym $mod+Shift+7 move container to workspace number 7
|
||||
bindsym $mod+Shift+8 move container to workspace number 8
|
||||
bindsym $mod+Shift+9 move container to workspace number 9
|
||||
bindsym $mod+Shift+0 move container to workspace number 10
|
||||
# Note: workspaces can have any name you want, not just numbers.
|
||||
# We just use 1-10 as the default.
|
||||
|
||||
#
|
||||
# Layout stuff:
|
||||
#
|
||||
# You can "split" the current object of your focus with
|
||||
# $mod+b or $mod+v, for horizontal and vertical splits
|
||||
# respectively.
|
||||
bindsym $mod+b splith
|
||||
bindsym $mod+v splitv
|
||||
|
||||
# Switch the current container between different layout styles
|
||||
bindsym $mod+s layout stacking
|
||||
bindsym $mod+w layout tabbed
|
||||
bindsym $mod+e layout toggle split
|
||||
|
||||
# Make the current focus fullscreen
|
||||
bindsym $mod+f fullscreen
|
||||
|
||||
# Toggle the current focus between tiling and floating mode
|
||||
bindsym $mod+Shift+space floating toggle
|
||||
|
||||
# Swap focus between the tiling area and the floating area
|
||||
bindsym $mod+space focus mode_toggle
|
||||
|
||||
# Move focus to the parent container
|
||||
bindsym $mod+a focus parent
|
||||
|
||||
bindsym $mod+r mode "resize"
|
||||
|
||||
# Cycle through workspaces
|
||||
bindsym $mod+tab workspace next_on_output
|
||||
bindsym $mod+Shift+tab workspace prev_on_output
|
||||
|
||||
bindsym --to-code {
|
||||
$mod+b splith
|
||||
$mod+v splitv
|
||||
}
|
||||
|
||||
# Media keys
|
||||
bindsym XF86AudioMicMute exec pactl set-source-mute @DEFAULT_SOURCE@ toggle
|
||||
|
||||
bindsym XF86MonBrightnessDown exec brightnessctl -q set 5%- && ( echo $((`brightnessctl get` * 100 / `brightnessctl m`)) > $SWAYSOCK.wob )
|
||||
bindsym XF86MonBrightnessUp exec brightnessctl -q set +5% && ( echo $((`brightnessctl get` * 100 / `brightnessctl m`)) > $SWAYSOCK.wob )
|
||||
|
||||
bindsym XF86AudioRaiseVolume exec pamixer --allow-boost -ui 2 && dc -e "[`pamixer --get-volume`]sM 100d `pamixer --get-volume`<Mp" > $SWAYSOCK.wob
|
||||
bindsym XF86AudioLowerVolume exec pamixer --allow-boost -ud 2 && dc -e "[`pamixer --get-volume`]sM 100d `pamixer --get-volume`<Mp" > $SWAYSOCK.wob
|
||||
bindsym XF86AudioMute exec pamixer --toggle-mute && ( pamixer --get-mute && echo 0 > $SWAYSOCK.wob )
|
||||
|
||||
# Media player controls
|
||||
bindsym --no-warn XF86AudioPlay exec playerctl play-pause
|
||||
bindsym --no-warn XF86AudioNext exec playerctl next
|
||||
bindsym --no-warn XF86AudioPrev exec playerctl previous
|
||||
|
||||
# Shutdown
|
||||
# unbindsym $mod+Shift+q
|
||||
# bindsym $mod+Shift+q mode $mode_system
|
||||
|
||||
# Toggle notification bar
|
||||
bindsym $mod+Shift+n exec $toggle_notification
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# sway does not set DISPLAY/WAYLAND_DISPLAY in the systemd user environment
|
||||
# See FS#63021
|
||||
# Adapted from xorg's 50-systemd-user.sh, which achieves a similar goal.
|
||||
|
||||
# Upstream refuses to set XDG_CURRENT_DESKTOP so we have to.
|
||||
exec systemctl --user set-environment XDG_CURRENT_DESKTOP=sway
|
||||
exec systemctl --user import-environment DISPLAY \
|
||||
SWAYSOCK \
|
||||
WAYLAND_DISPLAY \
|
||||
XDG_CURRENT_DESKTOP
|
||||
|
||||
exec hash dbus-update-activation-environment 2>/dev/null && \
|
||||
dbus-update-activation-environment --systemd DISPLAY \
|
||||
SWAYSOCK \
|
||||
XDG_CURRENT_DESKTOP=sway \
|
||||
WAYLAND_DISPLAY
|
|
@ -0,0 +1,8 @@
|
|||
#
|
||||
# Status Bar:
|
||||
#
|
||||
bar {
|
||||
id default
|
||||
swaybar_command waybar
|
||||
position $waybar_position
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
# enable numlock
|
||||
input * xkb_numlock enable
|
||||
|
||||
exec {
|
||||
'[ -x "$(command -v blueman-applet)" ] && blueman-applet'
|
||||
#'[ -x "$(command -v ~/.config/waybar/scripts/battery-notification.sh)" ] && ~/.config/waybar/scripts/battery-notification.sh'
|
||||
# Default wallpaper
|
||||
swaybg -o $int_monitor -i $background
|
||||
swaybg -o $ext_monitor -i $background
|
||||
}
|
||||
|
||||
exec_always {
|
||||
#emacs --daemon
|
||||
gsettings set org.gnome.desktop.interface gtk-theme 'Adwaita-dark'
|
||||
gsettings set org.gnome.desktop.interface icon-theme 'Adwaita'
|
||||
gsettings set org.gnome.desktop.interface cursor-theme 'Adwaita'
|
||||
systemctl --user import-environment
|
||||
test -e $SWAYSOCK.wob || mkfifo $SWAYSOCK.wob
|
||||
tail -f $SWAYSOCK.wob | $wob
|
||||
swaync --style ~/.config/sway/swaync/style.css --config ~/.config/sway/swaync/config.json
|
||||
}
|
||||
|
||||
exec /usr/libexec/polkit-gnome-authentication-agent-1
|
|
@ -0,0 +1,17 @@
|
|||
# recomended enviroment variables for sway based desktop
|
||||
# openSUSEway installs/imports this to/from:
|
||||
# /usr/lib/environment.d/50-openSUSE.conf
|
||||
# /etc/profile.d/openSUSEway.sh
|
||||
MOZ_ENABLE_WAYLAND=1
|
||||
QT_QPA_PLATFORM=wayland-egl
|
||||
CLUTTER_BACKEND=wayland
|
||||
ECORE_EVAS_ENGINE=wayland-egl
|
||||
ELM_ENGINE=wayland_egl
|
||||
SDL_VIDEODRIVER=wayland
|
||||
_JAVA_AWT_WM_NONREPARENTING=1
|
||||
NO_AT_BRIDGE=1
|
||||
|
||||
# QT theme for openSUSEway
|
||||
# needs qt5ct and adwaita-qt5 packages
|
||||
# default config is /etc/xdg/qt5ct/qt5ct.conf
|
||||
QT_QPA_PLATFORMTHEME=qt5ct
|
|
@ -0,0 +1,14 @@
|
|||
### Input configuration
|
||||
#
|
||||
# You can get the names of your inputs by running: swaymsg -t get_inputs
|
||||
# Read `man 5 sway-input` for more information about this section.
|
||||
|
||||
#input type:keyboard {
|
||||
# xkb_layout "us"
|
||||
#}
|
||||
|
||||
input type:keyboard {
|
||||
xkb_layout "us"
|
||||
xkb_variant "altgr-intl"
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
### Input configuration
|
||||
#
|
||||
# You can get the names of your inputs by running: swaymsg -t get_inputs
|
||||
# Read `man 5 sway-input` for more information about this section.
|
||||
input type:touchpad {
|
||||
dwt enabled
|
||||
tap enabled
|
||||
natural_scroll enabled
|
||||
}
|
||||
|
||||
#input type:mouse {
|
||||
# map_to_output eDP-1
|
||||
#}
|
||||
#
|
||||
#input type:touchpad {
|
||||
# map_to_output eDP-1
|
||||
#}
|
||||
#
|
||||
#input type:tablet_tool {
|
||||
# map_to_output eDP-1
|
||||
#}
|
||||
#
|
||||
#input type:touch {
|
||||
# map_to_output eDP-1
|
||||
#}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
#
|
||||
# You can get the names of your outputs by running: swaymsg -t get_outputs
|
||||
|
||||
### Idle configuration
|
||||
#
|
||||
# Example configuration:
|
||||
#
|
||||
# exec swayidle -w \
|
||||
# timeout 300 'swaylock -f -c 000000' \
|
||||
# timeout 600 'swaymsg "output * dpms off"' resume 'swaymsg "output * dpms on"' \
|
||||
# before-sleep 'swaylock -f -c 000000'
|
||||
#
|
||||
# This will lock your screen after 300 seconds of inactivity, then turn off
|
||||
# your displays after another 300 seconds, and turn your screens back on when
|
||||
# resumed. It will also lock your screen before your computer goes to sleep.
|
||||
|
||||
# Lockscreen configuration
|
||||
set $screenlock 'swaylock -f -c 000000'
|
||||
# Idle configuration
|
||||
exec swayidle -w \
|
||||
timeout 7200 $screenlock \
|
||||
timeout 3600 'swaymsg "output * dpms off"' \
|
||||
resume 'swaymsg "output * dpms on"' \
|
||||
before-sleep $screenlock
|
|
@ -0,0 +1,23 @@
|
|||
#
|
||||
# Resizing containers:
|
||||
#
|
||||
mode "resize" {
|
||||
# left will shrink the containers width
|
||||
# right will grow the containers width
|
||||
# up will shrink the containers height
|
||||
# down will grow the containers height
|
||||
bindsym $left resize shrink width 10px
|
||||
bindsym $down resize grow height 10px
|
||||
bindsym $up resize shrink height 10px
|
||||
bindsym $right resize grow width 10px
|
||||
|
||||
# Ditto, with arrow keys
|
||||
bindsym Left resize shrink width 10px
|
||||
bindsym Down resize grow height 10px
|
||||
bindsym Up resize shrink height 10px
|
||||
bindsym Right resize grow width 10px
|
||||
|
||||
# Return to default mode
|
||||
bindsym Return mode "default"
|
||||
bindsym Escape mode "default"
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
#
|
||||
# Scratchpad:
|
||||
#
|
||||
# Sway has a "scratchpad", which is a bag of holding for windows.
|
||||
# You can send windows there and get them back later.
|
||||
|
||||
# Move the currently focused window to the scratchpad
|
||||
bindsym $mod+Shift+minus move scratchpad
|
||||
|
||||
# Show the next scratchpad window or hide the focused scratchpad window.
|
||||
# If there are multiple scratchpad windows, this command cycles through them.
|
||||
bindsym $mod+minus scratchpad show
|
|
@ -0,0 +1,15 @@
|
|||
# System mode menu
|
||||
set $mode_system "What to do? (l) lock, (e) logout, (r) reboot, (s) suspend, (Shift+s) shutdown"
|
||||
|
||||
mode $mode_system {
|
||||
bindsym l exec $screenlock; mode "default"
|
||||
bindsym e exec swaymsg exit; mode "default"
|
||||
bindsym r exec systemctl reboot; mode "default"
|
||||
bindsym s exec systemctl suspend; mode "default"
|
||||
bindsym Shift+s exec systemctl poweroff; mode "default"
|
||||
|
||||
# back to normal: Enter or Escape
|
||||
bindsym Return mode "default"
|
||||
bindsym Escape mode "default"
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
set $mode_recording "<span foreground='$color10'></span> \
|
||||
<span foreground='$color5'><b>Record</b></span> <span foreground='$color10'>(<b>r</b>)</span> \
|
||||
<span foreground='$color5'>+ [<span foreground='$color10'><b>Shift</b></span> for ]</span>"
|
||||
|
||||
set $recorder /usr/share/sway/scripts/recorder.sh
|
||||
|
||||
mode --pango_markup $mode_recording {
|
||||
$bindsym r exec $recorder, mode "default"
|
||||
$bindsym Shift+r exec $recorder -a, mode "default"
|
||||
|
||||
# Return to default mode.
|
||||
$bindsym Escape mode "default"
|
||||
}
|
||||
|
||||
## Launch // Recording Mode ##
|
||||
$bindsym $mod+Shift+r mode $mode_recording
|
||||
|
||||
## Launch // Stop Recording Mode ##
|
||||
$bindsym $mod+Escape exec killall -s SIGINT wf-recorder
|
|
@ -0,0 +1,23 @@
|
|||
set $mode_screenshot "<span foreground='$color10'></span> \
|
||||
<span foreground='$color5'><b>Pick</b></span> <span foreground='$color10'>(<b>p</b>)</span> \
|
||||
<span foreground='$color5'><b>Output</b></span> <span foreground='$color10'>(<b>o</b>)</span> \
|
||||
<span foreground='$color7'>+ <span foreground='$color10'><b>Shift</b></span> for </span> \
|
||||
<span foreground='$color7'>+ <span foreground='$color10'><b>Ctrl</b></span> for </span>"
|
||||
|
||||
mode --pango_markup $mode_screenshot {
|
||||
# output = currently active output
|
||||
$bindsym o mode "default", exec $screenshot_screen_clipboard
|
||||
$bindsym Shift+o mode "default", exec $screenshot_screen_file
|
||||
$bindsym Shift+Ctrl+o mode "default", exec $screenshot_screen_upload
|
||||
|
||||
# pick the region to screenshot
|
||||
$bindsym p mode "default", exec $screenshot_selection_clipboard
|
||||
$bindsym Shift+p mode "default", exec $screenshot_selection_file
|
||||
$bindsym Shift+Ctrl+p mode "default", exec $screenshot_selection_upload
|
||||
|
||||
# Return to default mode.
|
||||
$bindsym Escape mode "default"
|
||||
}
|
||||
|
||||
## Launch // Screenshot Mode ##
|
||||
$bindsym Print mode $mode_screenshot
|
|
@ -0,0 +1,35 @@
|
|||
### Output configuration
|
||||
#
|
||||
# Example configuration:
|
||||
#
|
||||
# output HDMI-A-1 resolution 1920x1080 position 1920,0
|
||||
#
|
||||
# You can get the names of your outputs by running: swaymsg -t get_outputs
|
||||
# Default wallpaper output * bg $background fill
|
||||
#
|
||||
# output $ext_monitor pos 0 0 res 1920x1080 output $int_monitor pos 1920 0 res 1920x1080
|
||||
#
|
||||
# Default wallpaper (more resolutions are available in /usr/share/backgrounds/sway/)
|
||||
|
||||
|
||||
|
||||
output $ext_monitor pos 0 0 res 1920x1080
|
||||
output $int_monitor pos 1920 0 res 1920x1080
|
||||
|
||||
# focus output $ext_monitor
|
||||
# focus output $int_monitor
|
||||
|
||||
bindswitch --reload --locked lid:on output $int_monitor disable
|
||||
bindswitch --reload --locked lid:off output $int_monitor enable
|
||||
|
||||
workspace 1 output $ext_monitor
|
||||
workspace 2 output $ext_monitor
|
||||
workspace 3 output $ext_monitor
|
||||
workspace 4 output $ext_monitor
|
||||
workspace 5 output $ext_monitor
|
||||
workspace 6 output $int_monitor
|
||||
workspace 7 output $int_monitor
|
||||
workspace 8 output $int_monitor
|
||||
workspace 9 output $int_monitor
|
||||
workspace 0 output $int_monitor
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"$schema": "/etc/xdg/swaync/configSchema.json",
|
||||
"positionX": "right",
|
||||
"positionY": "top",
|
||||
"control-center-margin-top": 0,
|
||||
"control-center-margin-bottom": 0,
|
||||
"control-center-margin-right": 0,
|
||||
"control-center-margin-left": 0,
|
||||
"notification-icon-size": 64,
|
||||
"notification-body-image-height": 100,
|
||||
"notification-body-image-width": 200,
|
||||
"timeout": 10,
|
||||
"timeout-low": 5,
|
||||
"timeout-critical": 0,
|
||||
"fit-to-screen": true,
|
||||
"control-center-width": 500,
|
||||
"control-center-height": 600,
|
||||
"notification-window-width": 500,
|
||||
"keyboard-shortcuts": true,
|
||||
"image-visibility": "when-available",
|
||||
"transition-time": 200,
|
||||
"hide-on-clear": false,
|
||||
"hide-on-action": true,
|
||||
"script-fail-notify": true,
|
||||
"scripts": {
|
||||
"example-script": {
|
||||
"exec": "echo 'Do something...'",
|
||||
"urgency": "Normal"
|
||||
}
|
||||
},
|
||||
"notification-visibility": {
|
||||
"example-name": {
|
||||
"state": "muted",
|
||||
"urgency": "Low",
|
||||
"app-name": "Spotify"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,217 @@
|
|||
@define-color cc-bg rgba(190, 29, 122, 0.4);
|
||||
|
||||
@define-color noti-text-color rgba(122, 162, 247, 1);
|
||||
@define-color noti-border-color rgba(149.2, 21, 95.1, 0.4);
|
||||
@define-color noti-bg rgba(239, 78, 145, 0.4);
|
||||
@define-color noti-bg-hover rgba(243.7, 60.5, 136.7, 1);
|
||||
@define-color noti-bg-focus rgba(243.7, 60.5, 136.7, 0.6);
|
||||
@define-color noti-close-bg rgba(115.0, 218.0, 202.0, 0.1);
|
||||
@define-color noti-close-bg-hover rgba(115.0, 218.0, 202.0, 0.15);
|
||||
|
||||
@define-color bg-selected rgba(231, 129, 179, 1);
|
||||
|
||||
* {
|
||||
font-family: "Comic Code";
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.notification-row {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.notification-row:focus,
|
||||
.notification-row:hover {
|
||||
background: @noti-bg-focus;
|
||||
}
|
||||
|
||||
.notification {
|
||||
border-radius: 12px;
|
||||
margin: 6px 12px;
|
||||
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3), 0 1px 3px 1px rgba(0, 0, 0, 0.7),
|
||||
0 2px 6px 2px rgba(0, 0, 0, 0.3);
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.critical {
|
||||
background: @bg-selected;
|
||||
padding: 6px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
/* Uncomment to enable specific urgency colors
|
||||
.low {
|
||||
background: yellow;
|
||||
padding: 6px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.normal {
|
||||
background: green;
|
||||
padding: 6px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.critical {
|
||||
background: red;
|
||||
padding: 6px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
*/
|
||||
|
||||
.notification-content {
|
||||
background: transparent;
|
||||
padding: 6px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.close-button {
|
||||
background: @noti-close-bg;
|
||||
color: @noti-text-color;
|
||||
text-shadow: none;
|
||||
padding: 0;
|
||||
border-radius: 100%;
|
||||
margin-top: 10px;
|
||||
margin-right: 16px;
|
||||
box-shadow: none;
|
||||
border: none;
|
||||
min-width: 24px;
|
||||
min-height: 24px;
|
||||
}
|
||||
|
||||
.close-button:hover {
|
||||
box-shadow: none;
|
||||
background: @noti-close-bg-hover;
|
||||
transition: all 0.15s ease-in-out;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.notification-default-action,
|
||||
.notification-action {
|
||||
padding: 4px;
|
||||
margin: 0;
|
||||
box-shadow: none;
|
||||
background: @noti-bg;
|
||||
border: 1px solid @noti-border-color;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.notification-default-action:hover,
|
||||
.notification-action:hover {
|
||||
-gtk-icon-effect: none;
|
||||
background: @noti-bg-hover;
|
||||
}
|
||||
|
||||
.notification-default-action {
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
/* When alternative actions are visible */
|
||||
.notification-default-action:not(:only-child) {
|
||||
border-bottom-left-radius: 0px;
|
||||
border-bottom-right-radius: 0px;
|
||||
}
|
||||
|
||||
.notification-action {
|
||||
border-radius: 0px;
|
||||
border-top: none;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
/* add bottom border radius to eliminate clipping */
|
||||
.notification-action:first-child {
|
||||
border-bottom-left-radius: 10px;
|
||||
}
|
||||
|
||||
.notification-action:last-child {
|
||||
border-bottom-right-radius: 10px;
|
||||
border-right: 1px solid @noti-border-color;
|
||||
}
|
||||
|
||||
.image {
|
||||
}
|
||||
|
||||
.body-image {
|
||||
margin-top: 6px;
|
||||
background-color: white;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.summary {
|
||||
color: @noti-text-color;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.time {
|
||||
color: @noti-text-color;
|
||||
text-shadow: none;
|
||||
margin-right: 18px;
|
||||
}
|
||||
|
||||
.body {
|
||||
background: transparent;
|
||||
color: @noti-text-color;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
/* The "Notifications" and "Do Not Disturb" text widget */
|
||||
.top-action-title {
|
||||
color: @noti-text-color;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.control-center-clear-all {
|
||||
color: @noti-text-color;
|
||||
text-shadow: none;
|
||||
background: @cc-bg;
|
||||
border: 1px solid @noti-border-color;
|
||||
box-shadow: none;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.control-center-clear-all:hover {
|
||||
background: @noti-bg-hover;
|
||||
}
|
||||
|
||||
.control-center-dnd {
|
||||
border-radius: 12px;
|
||||
background: @noti-bg;
|
||||
border: 1px solid @noti-border-color;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.control-center-dnd:checked {
|
||||
background: @bg-selected;
|
||||
}
|
||||
|
||||
.control-center-dnd slider:hover {
|
||||
background: @noti-close-bg-hover;
|
||||
}
|
||||
|
||||
.control-center-dnd slider {
|
||||
background: @noti-bg-hover;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
/* The .control-center Window.
|
||||
* Can't apply padding and margin so may be easier to use "> box" instead
|
||||
*/
|
||||
.control-center {
|
||||
background: @cc-bg;
|
||||
}
|
||||
|
||||
/* The first control-center child. May be easier to style this than .control-center */
|
||||
.control-center > box {
|
||||
}
|
||||
|
||||
.control-center-list {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.floating-notifications {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* Window behind control center and on all other monitors */
|
||||
.blank-window {
|
||||
background: alpha(black, 0.25);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
timeout = 1000
|
||||
height = 32
|
||||
border_offset = 0
|
||||
border_size = 2
|
||||
bar_padding = 2
|
||||
border_color = 35B9AB66
|
||||
background_color = 173F4F66
|
||||
bar_color = 35B9ABFF
|
||||
overflow_border_color = EE2E2466
|
||||
overflow_background_color = 173F4F66
|
||||
overflow_bar_color = EE2E24FF
|
|
@ -0,0 +1,314 @@
|
|||
// =============================================================================
|
||||
//
|
||||
// Waybar configuration
|
||||
//
|
||||
// Configuration reference: https://github.com/Alexays/Waybar/wiki/Configuration
|
||||
//
|
||||
// =============================================================================
|
||||
|
||||
{
|
||||
// -------------------------------------------------------------------------
|
||||
// Global configuration
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
"layer": "top",
|
||||
|
||||
// If height property would be not present, it'd be calculated dynamically
|
||||
"height": 30,
|
||||
"position": "top",
|
||||
|
||||
"modules-left": ["custom/menu", "sway/workspaces", "custom/scratchpad"],
|
||||
"modules-center": ["custom/wf-recorder", "sway/mode", "custom/weather"],
|
||||
"modules-right": [
|
||||
|
||||
// informational
|
||||
"sway/language",
|
||||
//"custom/github",
|
||||
//"custom/clipboard",
|
||||
"cpu",
|
||||
"memory",
|
||||
"disk",
|
||||
"battery",
|
||||
"temperature",
|
||||
|
||||
// connecting
|
||||
"network",
|
||||
//"bluetooth",
|
||||
|
||||
// media
|
||||
//"custom/playerctl",
|
||||
"idle_inhibitor",
|
||||
"pulseaudio",
|
||||
"backlight",
|
||||
|
||||
// system
|
||||
//"custom/sunset",
|
||||
//"custom/pacman",
|
||||
|
||||
//"clock",
|
||||
"custom/clock",
|
||||
"tray"
|
||||
],
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Modules
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
"battery": {
|
||||
"interval": 30,
|
||||
"states": {
|
||||
"warning": 30,
|
||||
"critical": 15
|
||||
},
|
||||
"format-charging": " {capacity}%",
|
||||
"format": "{icon} {capacity}%",
|
||||
"format-icons": ["", "", "", "", "", ""],
|
||||
"tooltip": true
|
||||
//"bat": "BAT0"
|
||||
},
|
||||
|
||||
"custom/clock": {
|
||||
"exec": "echo ' '$(date +'%e %b %Y %H:%M')' '",
|
||||
"interval": 60,
|
||||
"tooltip": true,
|
||||
"tooltip-format": "<big>{:%B %Y}</big>\n<tt>{calendar}</tt>",
|
||||
"on-click": "swaymsg exec \\$calendar"
|
||||
},
|
||||
|
||||
"clock": {
|
||||
"interval": 60,
|
||||
"format": "{:%e %b %Y %H:%M}",
|
||||
"tooltip": true,
|
||||
"tooltip-format": "<big>{:%B %Y}</big>\n<tt>{calendar}</tt>",
|
||||
"on-click": "swaymsg exec \\$calendar"
|
||||
},
|
||||
|
||||
"cpu": {
|
||||
"interval": 5,
|
||||
"format": " {usage}%",
|
||||
"states": {
|
||||
"warning": 70,
|
||||
"critical": 90
|
||||
},
|
||||
"on-click": "swaymsg exec \\$term_float htop"
|
||||
},
|
||||
|
||||
"memory": {
|
||||
"interval": 5,
|
||||
"format": " {}%",
|
||||
"states": {
|
||||
"warning": 70,
|
||||
"critical": 90
|
||||
},
|
||||
"on-click": "swaymsg exec \\$term_float htop"
|
||||
},
|
||||
|
||||
"network": {
|
||||
"interval": 5,
|
||||
"format-wifi": " ",
|
||||
"format-ethernet": "",
|
||||
"format-disconnected": "睊",
|
||||
"tooltip-format": "{ifname} ({essid}): {ipaddr}",
|
||||
"on-click": "swaymsg exec \\$term_float nmtui"
|
||||
},
|
||||
|
||||
"sway/mode": {
|
||||
"format": "<span style=\"italic\">{}</span>",
|
||||
"tooltip": false
|
||||
},
|
||||
|
||||
"idle_inhibitor": {
|
||||
"format": "{icon}",
|
||||
"format-icons": {
|
||||
"activated": "",
|
||||
"deactivated": ""
|
||||
}
|
||||
},
|
||||
|
||||
"backlight": {
|
||||
"format": "{icon} {percent}%",
|
||||
"format-icons": ["", "", ""],
|
||||
"on-scroll-up": "light -A 1",
|
||||
"on-scroll-down": "light -U 1"
|
||||
},
|
||||
|
||||
"pulseaudio": {
|
||||
"scroll-step": 5,
|
||||
"format": "{icon} {volume}%{format_source}",
|
||||
"format-muted": "婢 {format_source}",
|
||||
"format-source": "",
|
||||
"format-source-muted": " ",
|
||||
"format-icons": {
|
||||
"headphone": "",
|
||||
"headset": "",
|
||||
"default": ["奄", "奔", "墳"]
|
||||
},
|
||||
"tooltip-format": "{icon} {volume}% {format_source}",
|
||||
"on-click": "swaymsg exec \\$pulseaudio"
|
||||
},
|
||||
|
||||
"temperature": {
|
||||
"critical-threshold": 90,
|
||||
"interval": 5,
|
||||
"format": "{icon} {temperatureC}°C",
|
||||
"format-icons": ["", "", ""],
|
||||
"tooltip": false,
|
||||
"on-click": "swaymsg exec \"\\$term_float watch sensors\""
|
||||
},
|
||||
|
||||
"tray": {
|
||||
"icon-size": 21,
|
||||
"spacing": 5
|
||||
},
|
||||
|
||||
//"custom/pacman": {
|
||||
// "format": " {}",
|
||||
// "interval": 3600,
|
||||
// "exec-if": "[ $(pamac checkupdates -q | wc -l) -gt 0 ]",
|
||||
// "exec": "pamac checkupdates -q | wc -l",
|
||||
// "on-click": "pamac-manager --updates; pkill -RTMIN+4 waybar",
|
||||
// "signal": 4
|
||||
//},
|
||||
|
||||
"custom/menu": {
|
||||
"format": "",
|
||||
"on-click": "swaymsg exec \\$menu",
|
||||
"tooltip": false
|
||||
},
|
||||
|
||||
"bluetooth": {
|
||||
"format": " {status}",
|
||||
"format-connected": " {status}",
|
||||
"format-connected-battery": " {status} {device_battery_percentage}%",
|
||||
//"format-connected": " {device_alias}",
|
||||
//"format-connected-battery": " {device_alias} {device_battery_percentage}%",
|
||||
//"format-device-preference": [ "device1", "device2" ], // preference list deciding the displayed device
|
||||
"tooltip-format": "{controller_alias}\t{controller_address}\n\n{num_connections} connected",
|
||||
"tooltip-format-connected": "{controller_alias}\t{controller_address}\n\n{num_connections} connected\n\n{device_enumerate}",
|
||||
"tooltip-format-enumerate-connected": "{device_alias}\t{device_address}",
|
||||
"tooltip-format-enumerate-connected-battery": "{device_alias}\t{device_address}\t{device_battery_percentage}%"
|
||||
},
|
||||
|
||||
"sway/language": {
|
||||
"format": " {}",
|
||||
"min-length": 5,
|
||||
"tooltip": false,
|
||||
"on-click": "swaymsg input $(swaymsg -t get_inputs --raw | jq '[.[] | select(.type == \"keyboard\")][0] | .identifier') xkb_switch_layout next"
|
||||
},
|
||||
|
||||
"custom/scratchpad": {
|
||||
"interval": "once",
|
||||
"return-type": "json",
|
||||
"format": "{icon}",
|
||||
"format-icons": {
|
||||
"one": "类",
|
||||
"many": "缾"
|
||||
},
|
||||
"exec": "/bin/sh ~/.config/waybar/scripts/scratchpad.sh",
|
||||
"on-click": "swaymsg 'scratchpad show'",
|
||||
"signal": 7
|
||||
},
|
||||
|
||||
"custom/sunset": {
|
||||
"interval": "once",
|
||||
"tooltip": false,
|
||||
"return-type": "json",
|
||||
"format": "{icon}",
|
||||
"format-icons": {
|
||||
"on": "",
|
||||
"off": ""
|
||||
},
|
||||
"exec": "~/.config/waybar/scripts/sunset.sh",
|
||||
"on-click": "~/.config/waybar/scripts/sunset.sh toggle; pkill -RTMIN+6 waybar",
|
||||
"exec-if": "~/.config/waybar/scripts/sunset.sh check",
|
||||
"signal": 6
|
||||
},
|
||||
|
||||
"custom/wf-recorder": {
|
||||
"interval": "once",
|
||||
"return-type": "json",
|
||||
"format": "{}",
|
||||
"tooltip-format": "{tooltip}",
|
||||
"exec": "echo '{\"class\": \"recording\",\"text\":\"雷\",\"tooltip\":\"press $mod+Esc to stop recording\"}'",
|
||||
"exec-if": "pgrep wf-recorder",
|
||||
"on-click": "killall -s SIGINT wf-recorder",
|
||||
"signal": 8
|
||||
},
|
||||
|
||||
"custom/github": {
|
||||
"interval": 300,
|
||||
"tooltip": false,
|
||||
"return-type": "json",
|
||||
"format": " {}",
|
||||
"exec": "gh api '/notifications' -q '{ text: length }' | cat -",
|
||||
"exec-if": "[ -x \"$(command -v gh)\" ] && gh auth status 2>&1 | grep -q -m 1 'Logged in' && gh api '/notifications' -q 'length' | grep -q -m 1 '0' ; test $? -eq 1",
|
||||
"on-click": "xdg-open https://github.com/notifications && sleep 30 && pkill -RTMIN+4 waybar",
|
||||
"signal": 4
|
||||
},
|
||||
|
||||
"disk": {
|
||||
"interval": 30,
|
||||
"format": " {free}",
|
||||
"path": "/"
|
||||
},
|
||||
|
||||
"custom/playerctl": {
|
||||
"interval": "once",
|
||||
"tooltip": true,
|
||||
"return-type": "json",
|
||||
"format": "{icon}",
|
||||
"format-icons": {
|
||||
"Playing": "奈",
|
||||
"Paused": ""
|
||||
},
|
||||
"exec": "playerctl metadata --format '{\"alt\": \"{{status}}\", \"tooltip\": \"{{playerName}}: {{markup_escape(title)}} - {{markup_escape(artist)}}\" }'",
|
||||
"on-click": "playerctl play-pause; pkill -RTMIN+5 waybar",
|
||||
"on-click-right": "playerctl next; pkill -RTMIN+5 waybar",
|
||||
"on-scroll-up": "playerctl position 10+; pkill -RTMIN+5 waybar",
|
||||
"on-scroll-down": "playerctl position 10-; pkill -RTMIN+5 waybar",
|
||||
"signal": 5
|
||||
},
|
||||
|
||||
"custom/clipboard": {
|
||||
"format": "",
|
||||
"interval": "once",
|
||||
"return-type": "json",
|
||||
"on-click": "swaymsg -q exec '$clipboard'; pkill -RTMIN+9 waybar",
|
||||
"on-click-right": "swaymsg -q exec '$clipboard-del'; pkill -RTMIN+9 waybar",
|
||||
"on-click-middle": "rm -f ~/.cache/cliphist/db; pkill -RTMIN+9 waybar",
|
||||
"exec": "printf '{\"tooltip\":\"%s\"}' $(cliphist list | wc -l)",
|
||||
"exec-if": "[ -x \"$(command -v cliphist)\" ] && [ $(cliphist list | wc -l) -gt 0 ]",
|
||||
"signal": 9
|
||||
},
|
||||
|
||||
"custom/weather": {
|
||||
"icon-size": 42,
|
||||
"format": "{icon} {}",
|
||||
"tooltip": true,
|
||||
"interval": 3600,
|
||||
// accepts a location as an argument (in quotes)
|
||||
"exec": "~/.config/sway/waybar/scripts/weather.py",
|
||||
"return-type": "json",
|
||||
"format-icons": {
|
||||
"Unknown": "",
|
||||
"Cloudy": "摒",
|
||||
"Fog": "",
|
||||
"HeavyRain": "",
|
||||
"HeavyShowers": "",
|
||||
"HeavySnow": "",
|
||||
"HeavySnowShowers": "ﰕ",
|
||||
"LightRain": "",
|
||||
"LightShowers": "",
|
||||
"LightSleet": "",
|
||||
"LightSleetShowers": "",
|
||||
"LightSnow": "",
|
||||
"LightSnowShowers": "ﭽ",
|
||||
"PartlyCloudy": "",
|
||||
"Sunny": "",
|
||||
"ThunderyHeavyRain": "ﭼ",
|
||||
"ThunderyShowers": "",
|
||||
"ThunderySnowShowers": "",
|
||||
"VeryCloudy": ""
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
#!/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 = {
|
||||
"firefox": "",
|
||||
}
|
||||
|
||||
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()
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
# This script requires i3ipc-python package (install it from a system package manager
|
||||
# or pip).
|
||||
# It makes inactive windows transparent. Use `transparency_val` variable to control
|
||||
# transparency strength in range of 0…1 or use the command line argument -o.
|
||||
|
||||
import argparse
|
||||
import i3ipc
|
||||
import signal
|
||||
import sys
|
||||
from functools import partial
|
||||
|
||||
def on_window_focus(inactive_opacity, ipc, event):
|
||||
global prev_focused
|
||||
global prev_workspace
|
||||
|
||||
focused_workspace = ipc.get_tree().find_focused()
|
||||
|
||||
if focused_workspace == None:
|
||||
return
|
||||
|
||||
focused = event.container
|
||||
workspace = focused_workspace.workspace().num
|
||||
|
||||
if focused.id != prev_focused.id: # https://github.com/swaywm/sway/issues/2859
|
||||
focused.command("opacity 1")
|
||||
if workspace == prev_workspace:
|
||||
prev_focused.command("opacity " + inactive_opacity)
|
||||
prev_focused = focused
|
||||
prev_workspace = workspace
|
||||
|
||||
|
||||
def remove_opacity(ipc):
|
||||
for workspace in ipc.get_tree().workspaces():
|
||||
for w in workspace:
|
||||
w.command("opacity 1")
|
||||
ipc.main_quit()
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
transparency_val = "0.80"
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="This script allows you to set the transparency of unfocused windows in sway."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--opacity",
|
||||
"-o",
|
||||
type=str,
|
||||
default=transparency_val,
|
||||
help="set opacity value in range 0...1",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
ipc = i3ipc.Connection()
|
||||
prev_focused = None
|
||||
prev_workspace = ipc.get_tree().find_focused().workspace().num
|
||||
|
||||
for window in ipc.get_tree():
|
||||
if window.focused:
|
||||
prev_focused = window
|
||||
else:
|
||||
window.command("opacity " + args.opacity)
|
||||
for sig in [signal.SIGINT, signal.SIGTERM]:
|
||||
signal.signal(sig, lambda signal, frame: remove_opacity(ipc))
|
||||
ipc.on("window::focus", partial(on_window_focus, args.opacity))
|
||||
ipc.main()
|
|
@ -0,0 +1,124 @@
|
|||
#!/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 = {
|
||||
"firefox": "",
|
||||
}
|
||||
|
||||
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()
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
#!/bin/bash
|
||||
# This program uses upower to check the battery percentage every 5 seconds
|
||||
# Dependencies: upower, libnotify, alsa-utils * mako?? *
|
||||
# Havent tested without mako, but it should work without it...
|
||||
|
||||
# Defaults
|
||||
THRESHOLD=20 # threshold percentage to send a notification
|
||||
NOTIFICATION_SENT=0
|
||||
|
||||
while true; do
|
||||
# Calculate the current percentage and round to whole number
|
||||
CURRENT_PERCENTAGE=$(upower -i $(upower -e | grep 'BAT') | awk '/percentage/ {print $2}' | tr -d '%')
|
||||
STATUS=$(upower -i $(upower -e | grep 'BAT') | grep -oP 'state:\s+\K\w+')
|
||||
# Convert the status to an integer for easier comparison later
|
||||
case "$STATUS" in
|
||||
"charging") STATUS=1 ;;
|
||||
"discharging") STATUS=0 ;;
|
||||
*) STATUS=-1 ;;
|
||||
esac
|
||||
|
||||
# Send a notification if
|
||||
# 1. The battery is discharging
|
||||
# 2. The current percentage is less than the threshold
|
||||
# 3. A notification hasn't been sent yet
|
||||
if [ "$CURRENT_PERCENTAGE" -lt "$THRESHOLD" ] && [ "$STATUS" -eq 0 ] && [ "$NOTIFICATION_SENT" -eq 0 ]; then
|
||||
# Send the notification and play a sound
|
||||
notify-send -u low -a "BatteryNotification" -t 5000 "Low battery. Please plug in."
|
||||
#This is for playing a sound, you can comment it out if you don't want it or change it to something else
|
||||
ffplay -v 0 -nodisp -autoexit notification.mp3 > /dev/null 2>&1
|
||||
# IMPORTANT: Set the notification sent flag to 1 so we don't send another notification until the battery is charged
|
||||
NOTIFICATION_SENT=1
|
||||
fi
|
||||
|
||||
# Reset the notification sent flag if the battery is charging
|
||||
if [ $STATUS -eq 1 ]; then
|
||||
NOTIFICATION_SENT=0
|
||||
fi
|
||||
|
||||
sleep 5
|
||||
done
|
|
@ -0,0 +1,154 @@
|
|||
#!/bin/sh
|
||||
|
||||
## Grimshot: a helper for screenshots within sway
|
||||
## Requirements:
|
||||
## - `grim`: screenshot utility for wayland
|
||||
## - `slurp`: to select an area
|
||||
## - `swaymsg`: to read properties of current window
|
||||
## - `wl-copy`: clipboard utility
|
||||
## - `jq`: json utility to parse swaymsg output
|
||||
## - `notify-send`: to show notifications
|
||||
## Those are needed to be installed, if unsure, run `grimshot check`
|
||||
##
|
||||
## See `man 1 grimshot` or `grimshot usage` for further details.
|
||||
|
||||
getTargetDirectory() {
|
||||
test -f ${XDG_CONFIG_HOME:-~/.config}/user-dirs.dirs && \
|
||||
. ${XDG_CONFIG_HOME:-~/.config}/user-dirs.dirs
|
||||
|
||||
echo ${XDG_SCREENSHOTS_DIR:-${XDG_PICTURES_DIR:-$HOME}}
|
||||
}
|
||||
|
||||
if [ "$1" = "--notify" ]; then
|
||||
NOTIFY=yes
|
||||
shift 1
|
||||
else
|
||||
NOTIFY=no
|
||||
fi
|
||||
|
||||
ACTION=${1:-usage}
|
||||
SUBJECT=${2:-screen}
|
||||
FILE=${3:-$(getTargetDirectory)/$(date -Ins).png}
|
||||
|
||||
if [ "$ACTION" != "save" ] && [ "$ACTION" != "copy" ] && [ "$ACTION" != "check" ]; then
|
||||
echo "Usage:"
|
||||
echo " grimshot [--notify] (copy|save) [active|screen|output|area|window] [FILE|-]"
|
||||
echo " grimshot check"
|
||||
echo " grimshot usage"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " copy: Copy the screenshot data into the clipboard."
|
||||
echo " save: Save the screenshot to a regular file or '-' to pipe to STDOUT."
|
||||
echo " check: Verify if required tools are installed and exit."
|
||||
echo " usage: Show this message and exit."
|
||||
echo ""
|
||||
echo "Targets:"
|
||||
echo " active: Currently active window."
|
||||
echo " screen: All visible outputs."
|
||||
echo " output: Currently active output."
|
||||
echo " area: Manually select a region."
|
||||
echo " window: Manually select a window."
|
||||
exit
|
||||
fi
|
||||
|
||||
notify() {
|
||||
notify-send -t 3000 -a grimshot "$@"
|
||||
}
|
||||
notifyOk() {
|
||||
[ "$NOTIFY" = "no" ] && return
|
||||
|
||||
TITLE=${2:-"Screenshot"}
|
||||
MESSAGE=${1:-"OK"}
|
||||
notify "$TITLE" "$MESSAGE"
|
||||
}
|
||||
notifyError() {
|
||||
if [ $NOTIFY = "yes" ]; then
|
||||
TITLE=${2:-"Screenshot"}
|
||||
MESSAGE=${1:-"Error taking screenshot with grim"}
|
||||
notify -u critical "$TITLE" "$MESSAGE"
|
||||
else
|
||||
echo $1
|
||||
fi
|
||||
}
|
||||
|
||||
die() {
|
||||
MSG=${1:-Bye}
|
||||
notifyError "Error: $MSG"
|
||||
exit 2
|
||||
}
|
||||
|
||||
check() {
|
||||
COMMAND=$1
|
||||
if command -v "$COMMAND" > /dev/null 2>&1; then
|
||||
RESULT="OK"
|
||||
else
|
||||
RESULT="NOT FOUND"
|
||||
fi
|
||||
echo " $COMMAND: $RESULT"
|
||||
}
|
||||
|
||||
takeScreenshot() {
|
||||
FILE=$1
|
||||
GEOM=$2
|
||||
OUTPUT=$3
|
||||
if [ ! -z "$OUTPUT" ]; then
|
||||
grim -o "$OUTPUT" "$FILE" || die "Unable to invoke grim"
|
||||
elif [ -z "$GEOM" ]; then
|
||||
grim "$FILE" || die "Unable to invoke grim"
|
||||
else
|
||||
grim -g "$GEOM" "$FILE" || die "Unable to invoke grim"
|
||||
fi
|
||||
}
|
||||
|
||||
if [ "$ACTION" = "check" ] ; then
|
||||
echo "Checking if required tools are installed. If something is missing, install it to your system and make it available in PATH..."
|
||||
check grim
|
||||
check slurp
|
||||
check swaymsg
|
||||
check wl-copy
|
||||
check jq
|
||||
check notify-send
|
||||
exit
|
||||
elif [ "$SUBJECT" = "area" ] ; then
|
||||
GEOM=$(slurp -d)
|
||||
# Check if user exited slurp without selecting the area
|
||||
if [ -z "$GEOM" ]; then
|
||||
exit 1
|
||||
fi
|
||||
WHAT="Area"
|
||||
elif [ "$SUBJECT" = "active" ] ; then
|
||||
FOCUSED=$(swaymsg -t get_tree | jq -r 'recurse(.nodes[]?, .floating_nodes[]?) | select(.focused)')
|
||||
GEOM=$(echo "$FOCUSED" | jq -r '.rect | "\(.x),\(.y) \(.width)x\(.height)"')
|
||||
APP_ID=$(echo "$FOCUSED" | jq -r '.app_id')
|
||||
WHAT="$APP_ID window"
|
||||
elif [ "$SUBJECT" = "screen" ] ; then
|
||||
GEOM=""
|
||||
WHAT="Screen"
|
||||
elif [ "$SUBJECT" = "output" ] ; then
|
||||
GEOM=""
|
||||
OUTPUT=$(swaymsg -t get_outputs | jq -r '.[] | select(.focused)' | jq -r '.name')
|
||||
WHAT="$OUTPUT"
|
||||
elif [ "$SUBJECT" = "window" ] ; then
|
||||
GEOM=$(swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | .rect | "\(.x),\(.y) \(.width)x\(.height)"' | slurp)
|
||||
# Check if user exited slurp without selecting the area
|
||||
if [ -z "$GEOM" ]; then
|
||||
exit 1
|
||||
fi
|
||||
WHAT="Window"
|
||||
else
|
||||
die "Unknown subject to take a screen shot from" "$SUBJECT"
|
||||
fi
|
||||
|
||||
if [ "$ACTION" = "copy" ] ; then
|
||||
takeScreenshot - "$GEOM" "$OUTPUT" | wl-copy --type image/png || die "Clipboard error"
|
||||
notifyOk "$WHAT copied to buffer"
|
||||
else
|
||||
if takeScreenshot "$FILE" "$GEOM" "$OUTPUT"; then
|
||||
TITLE="Screenshot of $SUBJECT"
|
||||
MESSAGE=$(basename "$FILE")
|
||||
notifyOk "$MESSAGE" "$TITLE"
|
||||
echo $FILE
|
||||
else
|
||||
notifyError "Error taking screenshot with grim"
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/sh
|
||||
set -x
|
||||
# toggles the help wrapper state
|
||||
|
||||
STATE_FILE=$HOME/.config/nwg-wrapper/help.state
|
||||
PID_FILE=$HOME/.config/nwg-wrapper/help.pid
|
||||
|
||||
PID=$(cat $PID_FILE 2>/dev/null)
|
||||
STATE=$(cat $STATE_FILE 2>/dev/null)
|
||||
|
||||
if [[ $STATE == 'true' && "$1" != "--restore" ]] || [[ "$1" == "--restore" && $STATE == 'false' ]]
|
||||
then
|
||||
if kill -0 $PID; then
|
||||
kill -9 $PID
|
||||
rm -rf $PID_FILE
|
||||
fi
|
||||
echo "false" > $STATE_FILE
|
||||
else
|
||||
if ! kill -0 $PID; then
|
||||
nwg-wrapper -s help.sh -p left -a end &
|
||||
echo $! > $PID_FILE
|
||||
fi
|
||||
echo "true" > $STATE_FILE
|
||||
fi
|
|
@ -0,0 +1,69 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
# This script requires i3ipc-python package (install it from a system package manager
|
||||
# or pip).
|
||||
# It makes inactive windows transparent. Use `transparency_val` variable to control
|
||||
# transparency strength in range of 0…1 or use the command line argument -o.
|
||||
|
||||
import argparse
|
||||
import i3ipc
|
||||
import signal
|
||||
import sys
|
||||
from functools import partial
|
||||
|
||||
def on_window_focus(inactive_opacity, ipc, event):
|
||||
global prev_focused
|
||||
global prev_workspace
|
||||
|
||||
focused_workspace = ipc.get_tree().find_focused()
|
||||
|
||||
if focused_workspace == None:
|
||||
return
|
||||
|
||||
focused = event.container
|
||||
workspace = focused_workspace.workspace().num
|
||||
|
||||
if focused.id != prev_focused.id: # https://github.com/swaywm/sway/issues/2859
|
||||
focused.command("opacity 1")
|
||||
if workspace == prev_workspace:
|
||||
prev_focused.command("opacity " + inactive_opacity)
|
||||
prev_focused = focused
|
||||
prev_workspace = workspace
|
||||
|
||||
|
||||
def remove_opacity(ipc):
|
||||
for workspace in ipc.get_tree().workspaces():
|
||||
for w in workspace:
|
||||
w.command("opacity 1")
|
||||
ipc.main_quit()
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
transparency_val = "0.80"
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="This script allows you to set the transparency of unfocused windows in sway."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--opacity",
|
||||
"-o",
|
||||
type=str,
|
||||
default=transparency_val,
|
||||
help="set opacity value in range 0...1",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
ipc = i3ipc.Connection()
|
||||
prev_focused = None
|
||||
prev_workspace = ipc.get_tree().find_focused().workspace().num
|
||||
|
||||
for window in ipc.get_tree():
|
||||
if window.focused:
|
||||
prev_focused = window
|
||||
else:
|
||||
window.command("opacity " + args.opacity)
|
||||
for sig in [signal.SIGINT, signal.SIGTERM]:
|
||||
signal.signal(sig, lambda signal, frame: remove_opacity(ipc))
|
||||
ipc.on("window::focus", partial(on_window_focus, args.opacity))
|
||||
ipc.main()
|
Binary file not shown.
|
@ -0,0 +1,47 @@
|
|||
#!/bin/bash
|
||||
set -x
|
||||
|
||||
pid=`pgrep wf-recorder`
|
||||
status=$?
|
||||
|
||||
gif=false
|
||||
|
||||
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 && 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
|
|
@ -0,0 +1,142 @@
|
|||
#!/usr/bin/python
|
||||
import glob
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from typing import Text
|
||||
|
||||
if len(sys.argv) >= 2:
|
||||
rootPath = sys.argv[1]
|
||||
else:
|
||||
rootPath = "~/.config/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]
|
||||
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))
|
|
@ -0,0 +1,15 @@
|
|||
#!/bin/sh
|
||||
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'}"
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh
|
||||
## updates the sway keyboard setting to the currently active X11 layout
|
||||
|
||||
swaymsg input type:keyboard xkb_layout "$(localectl status | grep "X11 Layout" | sed -e "s/^.*X11 Layout://")"
|
||||
swaymsg input type:keyboard xkb_variant "$(localectl status | grep "X11 Variant" | sed -e "s/^.*X11 Variant://")"
|
|
@ -0,0 +1,60 @@
|
|||
#!/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"}
|
||||
longitude=${longitude:-65}
|
||||
latitude=${latitude:-65}
|
||||
location=${location:-"off"}
|
||||
|
||||
if [ "${location}" = "on" ];
|
||||
then
|
||||
CONTENT=$(curl -s https://freegeoip.app/json/)
|
||||
content_longitude=$(echo $CONTENT | jq '.longitude // empty')
|
||||
longitude=${content_longitude:-"${longitude}"}
|
||||
content_latitude=$(echo $CONTENT | jq '.latitude // empty')
|
||||
latitude=${content_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"
|
||||
else
|
||||
class="off"
|
||||
fi
|
||||
|
||||
printf '{"alt":"%s"}\n' "$class"
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/bash
|
||||
|
||||
URL=$(curl -s -F "file=@\"$1\";filename=.png" 'https://x0.at')
|
||||
echo $URL | wl-copy
|
||||
notify-send " $URL"
|
|
@ -0,0 +1,145 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# credits: @bjesus https://gist.github.com/bjesus/f8db49e1434433f78e5200dc403d58a3
|
||||
|
||||
import json
|
||||
import requests
|
||||
import sys
|
||||
import urllib.parse
|
||||
from datetime import datetime
|
||||
|
||||
WEATHER_SYMBOL = {
|
||||
"Unknown": "✨",
|
||||
"Cloudy": "☁️",
|
||||
"Fog": "🌫",
|
||||
"HeavyRain": "🌧",
|
||||
"HeavyShowers": "🌧",
|
||||
"HeavySnow": "❄️",
|
||||
"HeavySnowShowers": "❄️",
|
||||
"LightRain": "🌦",
|
||||
"LightShowers": "🌦",
|
||||
"LightSleet": "🌧",
|
||||
"LightSleetShowers": "🌧",
|
||||
"LightSnow": "🌨",
|
||||
"LightSnowShowers": "🌨",
|
||||
"PartlyCloudy": "⛅️",
|
||||
"Sunny": "☀️",
|
||||
"ThunderyHeavyRain": "🌩",
|
||||
"ThunderyShowers": "⛈",
|
||||
"ThunderySnowShowers": "⛈",
|
||||
"VeryCloudy": "☁️",
|
||||
}
|
||||
|
||||
WWO_CODE = {
|
||||
"113": "Sunny",
|
||||
"116": "PartlyCloudy",
|
||||
"119": "Cloudy",
|
||||
"122": "VeryCloudy",
|
||||
"143": "Fog",
|
||||
"176": "LightShowers",
|
||||
"179": "LightSleetShowers",
|
||||
"182": "LightSleet",
|
||||
"185": "LightSleet",
|
||||
"200": "ThunderyShowers",
|
||||
"227": "LightSnow",
|
||||
"230": "HeavySnow",
|
||||
"248": "Fog",
|
||||
"260": "Fog",
|
||||
"263": "LightShowers",
|
||||
"266": "LightRain",
|
||||
"281": "LightSleet",
|
||||
"284": "LightSleet",
|
||||
"293": "LightRain",
|
||||
"296": "LightRain",
|
||||
"299": "HeavyShowers",
|
||||
"302": "HeavyRain",
|
||||
"305": "HeavyShowers",
|
||||
"308": "HeavyRain",
|
||||
"311": "LightSleet",
|
||||
"314": "LightSleet",
|
||||
"317": "LightSleet",
|
||||
"320": "LightSnow",
|
||||
"323": "LightSnowShowers",
|
||||
"326": "LightSnowShowers",
|
||||
"329": "HeavySnow",
|
||||
"332": "HeavySnow",
|
||||
"335": "HeavySnowShowers",
|
||||
"338": "HeavySnow",
|
||||
"350": "LightSleet",
|
||||
"353": "LightShowers",
|
||||
"356": "HeavyShowers",
|
||||
"359": "HeavyRain",
|
||||
"362": "LightSleetShowers",
|
||||
"365": "LightSleetShowers",
|
||||
"368": "LightSnowShowers",
|
||||
"371": "HeavySnowShowers",
|
||||
"374": "LightSleetShowers",
|
||||
"377": "LightSleet",
|
||||
"386": "ThunderyShowers",
|
||||
"389": "ThunderyHeavyRain",
|
||||
"392": "ThunderySnowShowers",
|
||||
"395": "HeavySnowShowers",
|
||||
}
|
||||
|
||||
data = {}
|
||||
|
||||
try:
|
||||
city = urllib.parse.quote(sys.argv[1].strip())
|
||||
except:
|
||||
#city = "ireland_dublin"
|
||||
city = "ciudad_juarez"
|
||||
|
||||
weather = requests.get("https://wttr.in/" + city + "?format=j1").json()
|
||||
|
||||
|
||||
def format_time(time):
|
||||
return time.replace("00", "").zfill(2)
|
||||
|
||||
|
||||
def format_temp(temp):
|
||||
return (hour['FeelsLikeC']+"°").ljust(3)
|
||||
|
||||
|
||||
def format_chances(hour):
|
||||
chances = {
|
||||
"chanceoffog": "Fog",
|
||||
"chanceoffrost": "Frost",
|
||||
"chanceofovercast": "Overcast",
|
||||
"chanceofrain": "Rain",
|
||||
"chanceofsnow": "Snow",
|
||||
"chanceofsunshine": "Sunshine",
|
||||
"chanceofthunder": "Thunder",
|
||||
"chanceofwindy": "Wind"
|
||||
}
|
||||
|
||||
conditions = []
|
||||
for event in chances.keys():
|
||||
if int(hour[event]) > 0:
|
||||
conditions.append(chances[event]+" "+hour[event]+"%")
|
||||
return ", ".join(conditions)
|
||||
|
||||
|
||||
data['text'] = weather['current_condition'][0]['FeelsLikeC']+"°"
|
||||
data['alt'] = WWO_CODE[weather['current_condition'][0]['weatherCode']]
|
||||
|
||||
data['tooltip'] = f"<b>{weather['current_condition'][0]['weatherDesc'][0]['value']} {weather['current_condition'][0]['temp_C']}°</b>\n"
|
||||
data['tooltip'] += f"Feels like: {weather['current_condition'][0]['FeelsLikeC']}°\n"
|
||||
data['tooltip'] += f"Wind: {weather['current_condition'][0]['windspeedKmph']}Km/h\n"
|
||||
data['tooltip'] += f"Humidity: {weather['current_condition'][0]['humidity']}%\n"
|
||||
for i, day in enumerate(weather['weather']):
|
||||
data['tooltip'] += f"\n<b>"
|
||||
if i == 0:
|
||||
data['tooltip'] += "Today, "
|
||||
if i == 1:
|
||||
data['tooltip'] += "Tomorrow, "
|
||||
data['tooltip'] += f"{day['date']}</b>\n"
|
||||
data['tooltip'] += f"⬆️ {day['maxtempC']}° ⬇️ {day['mintempC']}° "
|
||||
data['tooltip'] += f"🌅 {day['astronomy'][0]['sunrise']} 🌇 {day['astronomy'][0]['sunset']}\n"
|
||||
for hour in day['hourly']:
|
||||
if i == 0:
|
||||
if int(format_time(hour['time'])) < datetime.now().hour-2:
|
||||
continue
|
||||
data['tooltip'] += f"{format_time(hour['time'])} {WEATHER_SYMBOL[WWO_CODE[hour['weatherCode']]]} {format_temp(hour['FeelsLikeC'])} {hour['weatherDesc'][0]['value']}, {format_chances(hour)}\n"
|
||||
|
||||
|
||||
print(json.dumps(data))
|
|
@ -0,0 +1,27 @@
|
|||
#!/usr/bin/env bash
|
||||
# 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 -0 $1 || return 1
|
||||
for pid in $( pgrep $1 ); 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
|
||||
}
|
||||
|
||||
new_value=$3 # null or a percent; no checking!!
|
||||
|
||||
wob_pipe=~/.cache/$( basename $SWAYSOCK ).wob
|
||||
|
||||
[[ -p $wob_pipe ]] || mkfifo $wob_pipe
|
||||
|
||||
# wob does not appear in $(swaymsg -t get_msg), so:
|
||||
is_running_on_this_screen wob || {
|
||||
tail -f $wob_pipe | wob --border-color $1 --bar-color $1 --background-color $2 --anchor top --anchor center --margin 20 &
|
||||
}
|
||||
|
||||
[[ "$new_value" ]] && echo $new_value > $wob_pipe
|
|
@ -0,0 +1,214 @@
|
|||
/* =============================================================================
|
||||
*
|
||||
* Waybar configuration
|
||||
*
|
||||
* Configuration reference: https://github.com/Alexays/Waybar/wiki/Configuration
|
||||
*
|
||||
* =========================================================================== */
|
||||
|
||||
/* import css definitions for current theme */
|
||||
@import "theme.css";
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Keyframes
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
@keyframes blink-warning {
|
||||
70% {
|
||||
color: @wm_icon_bg;
|
||||
}
|
||||
|
||||
to {
|
||||
color: @wm_icon_bg;
|
||||
background-color: @warning_color;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes blink-critical {
|
||||
70% {
|
||||
color: @wm_icon_bg;
|
||||
}
|
||||
|
||||
to {
|
||||
color: @wm_icon_bg;
|
||||
background-color: @error_color;
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Base styles
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
/* Reset all styles */
|
||||
* {
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
min-height: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: "Terminess Nerd Font Mono", "Terminess Nerd Font", sans-serif;
|
||||
/*font-family: "Comic Code", "Comic Code", sans-serif;*/
|
||||
}
|
||||
|
||||
/* The whole bar */
|
||||
#waybar {
|
||||
background: @background_color;
|
||||
color: @text_color;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* Each module */
|
||||
#custom-pacman,
|
||||
#custom-menu,
|
||||
#custom-help,
|
||||
#custom-scratchpad,
|
||||
#custom-github,
|
||||
#custom-clipboard,
|
||||
#bluetooth,
|
||||
#battery,
|
||||
#clock,
|
||||
#cpu,
|
||||
#memory,
|
||||
#mode,
|
||||
#network,
|
||||
#pulseaudio,
|
||||
#temperature,
|
||||
#idle_inhibitor,
|
||||
#backlight,
|
||||
#language,
|
||||
#custom-sunset,
|
||||
#custom-playerctl,
|
||||
#tray {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Module styles
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
#custom-scratchpad {
|
||||
background-color: @background_color;
|
||||
}
|
||||
|
||||
#battery {
|
||||
animation-timing-function: linear;
|
||||
animation-iteration-count: infinite;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
|
||||
#battery.warning {
|
||||
color: @warning_color;
|
||||
}
|
||||
|
||||
#battery.critical {
|
||||
color: @error_color;
|
||||
}
|
||||
|
||||
#battery.warning.discharging {
|
||||
animation-name: blink-warning;
|
||||
animation-duration: 3s;
|
||||
}
|
||||
|
||||
#battery.critical.discharging {
|
||||
animation-name: blink-critical;
|
||||
animation-duration: 2s;
|
||||
}
|
||||
|
||||
#clock {
|
||||
font-weight: bold;
|
||||
background-color: @accent_color;
|
||||
}
|
||||
|
||||
#custom-clock {
|
||||
/*color: @bright_text_color;*/
|
||||
color: @black_color;
|
||||
font-weight: bold;
|
||||
background-color: @accent_color;
|
||||
}
|
||||
|
||||
#cpu.warning {
|
||||
color: @warning_color;
|
||||
}
|
||||
|
||||
#cpu.critical {
|
||||
color: @error_color;
|
||||
}
|
||||
|
||||
#custom-menu {
|
||||
color: @bright_text_color;
|
||||
background-color: @accent_color;
|
||||
padding-left: 10px;
|
||||
padding-right: 14px;
|
||||
}
|
||||
|
||||
#memory {
|
||||
animation-timing-function: linear;
|
||||
animation-iteration-count: infinite;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
|
||||
#memory.warning {
|
||||
color: @warning_color;
|
||||
}
|
||||
|
||||
#memory.critical {
|
||||
color: @error_color;
|
||||
animation-name: blink-critical;
|
||||
animation-duration: 2s;
|
||||
}
|
||||
|
||||
#mode {
|
||||
background: @background_color;
|
||||
}
|
||||
|
||||
#network.disconnected {
|
||||
color: @warning_color;
|
||||
}
|
||||
|
||||
#pulseaudio.muted {
|
||||
color: @warning_color;
|
||||
}
|
||||
|
||||
#temperature.critical {
|
||||
color: @error_color;
|
||||
}
|
||||
|
||||
#window {
|
||||
font-weight: bold;
|
||||
margin-right: 25px;
|
||||
color: @theme_selected_bg_color;
|
||||
}
|
||||
|
||||
#workspaces button {
|
||||
border-top: 2px solid transparent;
|
||||
/* To compensate for the top border and still have vertical centering */
|
||||
padding-bottom: 2px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
color: @text_color;
|
||||
}
|
||||
|
||||
#workspaces button.focused {
|
||||
border-color: @bright_text_color;
|
||||
color: @bright_text_color;
|
||||
background-color: @accent_color;
|
||||
}
|
||||
|
||||
#workspaces button.urgent {
|
||||
border-color: @error_color;
|
||||
color: @error_color;
|
||||
}
|
||||
|
||||
#custom-pacman {
|
||||
color: @warning_color;
|
||||
}
|
||||
|
||||
#bluetooth.disabled {
|
||||
color: @warning_color;
|
||||
}
|
||||
|
||||
#custom-wf-recorder {
|
||||
color: @error_color;
|
||||
padding-right: 10px;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/* theme specific color values */
|
||||
/* file will be overwritten on each logon with values from configured theme in /usr/share/sway/themes */
|
||||
@define-color transparent_background_color rgba(20, 22, 27, 0.9);
|
||||
@define-color background_color #111111;
|
||||
@define-color bright_text_color #ffffff;
|
||||
/*@define-color dim_text_color #cab9d0; */
|
||||
@define-color dim_text_color #ffffff;
|
||||
@define-color text_color #e5097f;
|
||||
/*@define-color accent_color #d960a8; */
|
||||
@define-color accent_color #e5097f;
|
||||
@define-color alternative_color #b7026d;
|
||||
@define-color warning_color #524778;
|
||||
@define-color error_color #dc3545;
|
|
@ -0,0 +1,13 @@
|
|||
/* theme specific color values */
|
||||
/* file will be overwritten on each logon with values from configured theme in /usr/share/sway/themes */
|
||||
@define-color transparent_background_color rgba(20, 22, 27, 0.9);
|
||||
@define-color background_color #b7026d;
|
||||
@define-color bright_text_color #e88fda;
|
||||
@define-color dim_text_color #cab9d0;
|
||||
/*@define-color text_color #e88fda;*/
|
||||
@define-color text_color #f8b8d0;
|
||||
@define-color accent_color #d960a8;
|
||||
@define-color alternative_color #b7026d;
|
||||
@define-color warning_color #524778;
|
||||
@define-color error_color #dc3545;
|
||||
@define-color black_color #000000;
|
|
@ -4,3 +4,7 @@
|
|||
name = Eduardo Cueto-Mendoza
|
||||
[commit]
|
||||
gpgsign = true
|
||||
[safe]
|
||||
directory = /usr/share/pyenv
|
||||
[init]
|
||||
defaultBranch = main
|
||||
|
|
|
@ -6,10 +6,8 @@
|
|||
#pinentry-program /usr/local/bin/pinentry-curses
|
||||
#pinentry-program /usr/local/bin/pinentry-mac
|
||||
#pinentry-program /opt/homebrew/bin/pinentry-mac
|
||||
pinentry-program /opt/homebrew/bin/pinentry
|
||||
#pinentry-program /usr/bin/pinentry-curses
|
||||
pinentry-program /usr/bin/pinentry-curses
|
||||
enable-ssh-support
|
||||
ttyname $GPG_TTY
|
||||
default-cache-ttl 60
|
||||
max-cache-ttl 120
|
||||
allow-loopback-pinentry
|
||||
|
|
Loading…
Reference in New Issue