Switch to wayland
Added a simple wayland configuration. Currently set up simple wayland configuration based on river window manager and waybar. Rivercarro is the layout manager, being the same in principle as rivertile, the default layout manager for river, only it comes with smart gaps (gaps turn off if there is only one window open) and monocle mode (give one window all space). Runs `keyd` in the background to replace the old `xcape` capslock switching (capslock is escape and if held control). Uses `swaybg` to set a wallpaper. Added powermenu and lockscreen scripts. Improved lockscreen script to detect and work for wayland. Moved old rofi mode 'powermenu' to more general powermenu script, which works with any rofi-like selector (dmenu, bemenu, wofi, etc.) Loses some of its design quality but since it was wonky anyway, and I rarely see the menu, we could repurpose its functionality for a more general powermenu concept. Currently hardcoded for `bemenu` but can be easily swapped and possibly even extended back to rofi. Fixed file upload link sharing to clipboard. Updated rofi-pass to pass-pick. Made rofi-pass universal and less integrated to rofi - that's also the reason for the name change. `pass-pick` works with rofi (default), bemenu or dmenu. In theory it should also work with any other picker that contains a stdin listing function similar to dmenu. It has been definitely tested both on rofi and bemenu. The best user experience still reigns on rofi, where available keys are displayed on the picker and the keys themselves make the most sense. But all functions can be reached from bemenu as well, though the key mappings are more arbitrary and can not be changed as in rofi. The autofilling tool works with both xdotool and ydotool, so should work both on X11 and on Wayland. Ydotool ideally requires its daemon to be running, otherwise some of the typing may get gut off. Otherwise no change should be necessary. Updated qutebrowser open_download for bemenu. Updated download opening script to work with both rofi and bemenu. Prefers original rofi implementation but works with both, and can be set to use a custom dmenu-like file picker as well. Add brightnessctl and removed custom audio / brightness scripts since they became unnecessary. Updated bootstrap script to include system files: With `keyd` taking its configuration from the `/etc` directory and not home, a second stow stage was necessary. These stow files are in a module called `system-packages` inside the top-level `bootstrap` stow package. They will not be installed by the default dotfile stow invocation but have been integrated as an extra step into the install script. Installing this module requires sudo privileges! Switched vifm überzug to sixel graphics rendering. überzug relies on X11 functionality to work, while sixel does not. Unfortunately, alacritty does not work with sixel graphics yet, only foot does (somewhat). Waybar currently runs the gruvbox dark soft color scheme. Added the old polybar archupdates script to waybar and extended it to output json format with additional metadata that waybar can read. Can still output the old plaintext format that polybar expects. Added a wireguard connection to waybar,shows if currently connected to either a wireguard or tun VPN service. If so, shows an icon in the waybar - that can be hovered over to show the full assigned IP address. Added an upcoming event display to waybar, a simple event indicator to show upcoming events on the calendar, on hovering over it the tooltip lists all upcoming events. Added `screenshot` script to take simple screenshots and rectangle region shots of the current output. Can be invoked through the river shortcut PrintScr: `PrintScr` - Fullscreen screenshot `Mod+PrintScr` - Region screenshot `Shift+PrintScr` - Fullscreen screenshot and file upload `Mod+Shift+PrintScr` - Region screenshot and file upload Extended `sharefile` to take paths through stdin and make use of `fd` if it is found on the system.
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 3.7 KiB |
BIN
.assets/waybar/simple.png
Normal file
After Width: | Height: | Size: 6.2 KiB |
|
@ -1,61 +0,0 @@
|
|||
<?xml version='1.0'?>
|
||||
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
|
||||
<fontconfig>
|
||||
<!-- Replacements from http://bohoomil.com/doc/05-fonts/ (until ibfonts-meta-extended) -->
|
||||
<alias>
|
||||
<family>serif</family>
|
||||
<prefer><family>Heuristica</family></prefer>
|
||||
</alias>
|
||||
<alias>
|
||||
<family>sans-serif</family>
|
||||
<prefer><family>Noto Sans</family></prefer>
|
||||
</alias>
|
||||
<alias>
|
||||
<family>monospace</family>
|
||||
<prefer><family>Iosevka</family></prefer>
|
||||
</alias>
|
||||
<alias>
|
||||
<family>fantasy</family>
|
||||
<prefer><family>Signika</family></prefer>
|
||||
</alias>
|
||||
<alias>
|
||||
<family>cursive</family>
|
||||
<prefer><family>Comic Neue</family></prefer>
|
||||
</alias>
|
||||
<!-- more advanced replacements (replacing many fonts with open alternatives) see spark/fonts/local.conf -->
|
||||
<match target="font">
|
||||
<edit name="antialias" mode="assign">
|
||||
<bool>true</bool>
|
||||
</edit>
|
||||
</match>
|
||||
<match target="font">
|
||||
<edit name="rgba" mode="assign">
|
||||
<const>rgb</const>
|
||||
</edit>
|
||||
</match>
|
||||
<match target="font">
|
||||
<edit name="lcdfilter" mode="assign">
|
||||
<const>lcddefault</const>
|
||||
</edit>
|
||||
</match>
|
||||
<match target="font">
|
||||
<edit name="hinting" mode="assign">
|
||||
<bool>true</bool>
|
||||
</edit>
|
||||
</match>
|
||||
<match target="font">
|
||||
<edit name="hintstyle" mode="assign">
|
||||
<const>hintfull</const>
|
||||
</edit>
|
||||
</match>
|
||||
<match target="font">
|
||||
<edit name="autohint" mode="assign">
|
||||
<bool>false</bool>
|
||||
</edit>
|
||||
</match>
|
||||
<match target="pattern">
|
||||
<edit name="dpi" mode="assign">
|
||||
<double>92</double>
|
||||
</edit>
|
||||
</match>
|
||||
</fontconfig>
|
|
@ -1,12 +0,0 @@
|
|||
! ~/.Xresources
|
||||
|
||||
! Setting up commonly changed vars
|
||||
#define myfontsize 11
|
||||
#define myfont Iosevka Mono
|
||||
#define myOpacity 90
|
||||
|
||||
! Font settings
|
||||
#include "Xresources.d/fonts"
|
||||
|
||||
! Colorscheme
|
||||
#include "Xresources.d/colorscheme"
|
|
@ -1,7 +0,0 @@
|
|||
Xft.antialias: 1
|
||||
Xft.autohint: 0
|
||||
Xft.dpi: 92
|
||||
Xft.hinting: true
|
||||
Xft.hintstyle: hintslight
|
||||
Xft.lcdfilter: lcddefault
|
||||
Xft.rgba: rgb
|
|
@ -1,77 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
userresources=$XDG_CONFIG_HOME/xresources/Xresources
|
||||
usermodmap=$XDG_CONFIG_HOME/xresources/Xmodmap
|
||||
sysresources=/etc/X11/xinit/.Xresources
|
||||
sysmodmap=/etc/X11/xinit/.Xmodmap
|
||||
|
||||
# merge in defaults and keymaps
|
||||
|
||||
if [ -f $sysresources ]; then
|
||||
xrdb -merge $sysresources
|
||||
fi
|
||||
|
||||
if [ -f $sysmodmap ]; then
|
||||
xmodmap $sysmodmap
|
||||
fi
|
||||
|
||||
if [ -f "$userresources" ]; then
|
||||
xrdb -merge "$userresources"
|
||||
fi
|
||||
|
||||
if [ -f "$usermodmap" ]; then
|
||||
xmodmap "$usermodmap"
|
||||
fi
|
||||
|
||||
if [ -d /etc/X11/xinit/xinitrc.d ]; then
|
||||
for f in /etc/X11/xinit/xinitrc.d/?*.sh; do
|
||||
# shellcheck disable=1090
|
||||
[ -x "$f" ] && . "$f"
|
||||
done
|
||||
unset f
|
||||
fi
|
||||
|
||||
# unclutter is a program to hide your mouse cursor when it is not moved
|
||||
type unclutter >/dev/null 2>&1 && unclutter &
|
||||
# picom is the maintained version of desktop compositor compton
|
||||
type picom >/dev/null 2>&1 && picom &
|
||||
|
||||
# if sxhkd - the key-binding daemon is installed, start it up
|
||||
# set it to start up a custom fifo-creating version
|
||||
# and set the chain-mode exiting key to a non existing one (default would be escape)
|
||||
type sxhkd >/dev/null 2>&1 && sxhkd-piped -a "copyright" &
|
||||
|
||||
# if nextcloud-client exists, start it up
|
||||
type nextcloud >/dev/null 2>&1 && nextcloud --background &
|
||||
|
||||
# load nm-applet, to allow easy vpn setting/switching from x interface
|
||||
# TODO this should over time be replaced with a custom polybar interface
|
||||
type nm-applet >/dev/null 2>&1 && nm-applet &
|
||||
|
||||
# additional config options for Touchpad devices ONLY
|
||||
if [ "$(journalctl --dmesg -o short-monotonic --no-hostname --no-pager | grep -c "Touchpad")" -gt 0 ]; then
|
||||
# enable touch tapping for XPS13 touchpad - for different devices get the touchpad name with xinput list-prop <TAB>
|
||||
xinput set-prop "DLL075B:01 06CB:76AF Touchpad" "libinput Tapping Enabled" 1
|
||||
|
||||
# sets default to EURkey layout, with possibility to switch to german
|
||||
# sets german layout to be default for the only pc I have with a german keyboard
|
||||
# allows switching layouts with alt+space
|
||||
setxkbmap -layout eu,de
|
||||
else
|
||||
setxkbmap -layout de,eu
|
||||
fi
|
||||
# Remaps Capslock key to control.
|
||||
# (only works for x environment - I haven't needed it for non-x yet)
|
||||
setxkbmap -option ctrl:nocaps
|
||||
setxkbmap -option grp:alt_shift_toggle
|
||||
|
||||
# Makes Capslock behave as escape - when ONLY capslock is pressed and released
|
||||
# this only works when we already substitute a ctrl for caps with the lines above,
|
||||
# otherwise control itself will act as escape.
|
||||
# Needs xcape package installed. https://github.com/alols/xcape
|
||||
# set a timeout of 500ms, if pressed longer it will ignore esc
|
||||
type xcape >/dev/null 2>&1 && xcape -e 'Control_L=Escape' -t 500
|
||||
|
||||
type feh >/dev/null 2>&1 && exec feh --bg-scale ~/pictures/wall.jpg &
|
||||
type xss-lock >/dev/null 2>&1 && exec xss-lock &
|
||||
type i3 >/dev/null 2>&1 && exec i3
|
|
@ -1,36 +0,0 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# clip -- easy copying to x clipboard manager with xclip
|
||||
#
|
||||
# clips the first argument to the clipboard
|
||||
# or stdin if stdin is passed
|
||||
# will copy png/jpg as image files
|
||||
#
|
||||
# idea ~~stolen~~ creatively borrowed from
|
||||
# https://github.com/kyazdani42/dotfiles/blob/master/bin/copy
|
||||
|
||||
if ! exist xclip normal; then exit 1; fi
|
||||
|
||||
# if we are in a pipe, read from stdin
|
||||
if [ ! -t 0 ]; then
|
||||
xclip -i -selection clipboard /dev/stdin
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ $# != 1 ] || [ ! -f "$1" ]; then
|
||||
printf "No file argument passed to xclip to clip: %s" "$1"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
options=""
|
||||
if grep -qE '.png$' "$1"; then
|
||||
options="-target image/png"
|
||||
elif grep -qE '.jpe\?g$' "$1"; then
|
||||
options="-target image/jpeg"
|
||||
fi
|
||||
|
||||
if [ -n "$options" ]; then
|
||||
xclip -selection clipboard "$options" "$1"
|
||||
else
|
||||
xclip -selection clipboard "$1"
|
||||
fi
|
|
@ -8,10 +8,11 @@ scrolling:
|
|||
multiplier: 3
|
||||
|
||||
font:
|
||||
size: 12.5
|
||||
size: 12
|
||||
|
||||
# Allow terminal applications to change Alacritty's window title.
|
||||
window.dynamic_title: true
|
||||
background_opacity: 1.0
|
||||
|
||||
import:
|
||||
- .config/alacritty/colorscheme.yml
|
||||
|
|
|
@ -3,3 +3,4 @@
|
|||
^/install_packages.sh
|
||||
^/packages.*.txt
|
||||
^/README.md
|
||||
^/system-packages
|
||||
|
|
|
@ -160,9 +160,6 @@ reflector
|
|||
restic
|
||||
ripgrep-all
|
||||
rng-tools
|
||||
rofi-calc
|
||||
rofi-dmenu
|
||||
rofi-greenclip
|
||||
rofimoji
|
||||
rtv
|
||||
sc-im
|
||||
|
@ -210,13 +207,6 @@ vifm
|
|||
vim-language-server
|
||||
vimiv
|
||||
visidata
|
||||
xcape
|
||||
xclip
|
||||
xsel
|
||||
xorg-xev
|
||||
xorg-xinit
|
||||
xorg-xinput
|
||||
xss-lock
|
||||
youtube-dl
|
||||
zathura-pdf-mupdf
|
||||
zsh-autosuggestions
|
||||
|
@ -257,3 +247,16 @@ zathura-djvu
|
|||
yt-dlp-git
|
||||
yaml-language-server-bin
|
||||
|
||||
river
|
||||
rivercarro
|
||||
keyd
|
||||
waybar-git
|
||||
swaybg
|
||||
waylock
|
||||
wl-clipboard
|
||||
clipman
|
||||
libqalculate
|
||||
ydotool
|
||||
brightnessctl
|
||||
grim
|
||||
slurp
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
# Makes capslock to control/escape
|
||||
# insert to paste
|
||||
# right alt to enable German Umlaute (äÄöÖüÜ),
|
||||
# sharp s (ß), and the Euro sign (€).
|
||||
# Needs compose key to be set in xkb to work correctly:
|
||||
# $ setxkbmap -option "compose:menu"
|
||||
|
||||
capslock = overload(C, esc)
|
||||
insert = S-insert
|
||||
rightalt = layer(dia)
|
||||
shift = layer(shift)
|
||||
rightshift = layer(shift)
|
||||
|
||||
[shift:S]
|
||||
|
||||
rightalt = layer(shiftedDia)
|
||||
|
||||
[dia]
|
||||
|
||||
shift = layer(shiftedDia)
|
||||
rightshift = layer(shiftedDia)
|
||||
|
||||
a = macro(compose a ")
|
||||
o = macro(compose o ")
|
||||
u = macro(compose u ")
|
||||
s = macro(compose s s)
|
||||
e = macro(compose = e)
|
||||
|
||||
[shiftedDia]
|
||||
|
||||
a = macro(compose A ")
|
||||
o = macro(compose O ")
|
||||
u = macro(compose U ")
|
9
bootstrap/system-packages/etc/keyd/default.cfg
Normal file
|
@ -0,0 +1,9 @@
|
|||
# leftshift = oneshot(S)
|
||||
# leftalt = oneshot(A)
|
||||
# rightalt = oneshot(G)
|
||||
# rightshift = oneshot(A)
|
||||
# leftmeta = oneshot(M)
|
||||
# rightmeta = oneshot(M)
|
||||
|
||||
capslock = overload(C, esc)
|
||||
insert = S-insert
|
|
@ -1,205 +0,0 @@
|
|||
# This file has been auto-generated by i3-config-wizard(1).
|
||||
# It will not be overwritten, so edit it as you like.
|
||||
#
|
||||
# Should you change your keyboard layout some time, delete
|
||||
# this file and re-run i3-config-wizard(1).
|
||||
#
|
||||
|
||||
# i3 config file (v4)
|
||||
#
|
||||
# Please see https://i3wm.org/docs/userguide.html for a complete reference!
|
||||
|
||||
set $mod Mod4
|
||||
set $modemod Mod1
|
||||
set $font "pango:Iosevka 8"
|
||||
|
||||
# Font for window titles. Will also be used by the bar unless a different font
|
||||
# is used in the bar {} block below.
|
||||
#font pango:monospace 8
|
||||
font $font
|
||||
|
||||
workspace_auto_back_and_forth yes
|
||||
|
||||
# This font is widely installed, provides lots of unicode glyphs, right-to-left
|
||||
# text rendering and scalability on retina/hidpi displays (thanks to pango).
|
||||
#font pango:DejaVu Sans Mono 8
|
||||
|
||||
# Before i3 v4.8, we used to recommend this one as the default:
|
||||
# font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
|
||||
# The font above is very space-efficient, that is, it looks good, sharp and
|
||||
# clear in small sizes. However, its unicode glyph coverage is limited, the old
|
||||
# X core fonts rendering does not support right-to-left and this being a bitmap
|
||||
# font, it doesn’t scale on retina/hidpi displays.
|
||||
|
||||
# Use Mouse+$mod to drag floating windows to their wanted position
|
||||
floating_modifier $mod
|
||||
|
||||
# kill focused window
|
||||
bindsym $mod+Shift+c kill
|
||||
|
||||
# change focus
|
||||
bindsym $mod+h focus left
|
||||
bindsym $mod+j focus down
|
||||
bindsym $mod+k focus up
|
||||
bindsym $mod+l focus right
|
||||
|
||||
# alternatively, you can use the cursor keys:
|
||||
bindsym $mod+Left focus left
|
||||
bindsym $mod+Down focus down
|
||||
bindsym $mod+Up focus up
|
||||
bindsym $mod+Right focus right
|
||||
|
||||
# move focused window
|
||||
bindsym $mod+Shift+h move left
|
||||
bindsym $mod+Shift+j move down
|
||||
bindsym $mod+Shift+k move up
|
||||
bindsym $mod+Shift+l move right
|
||||
|
||||
# alternatively, you can use the cursor 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
|
||||
|
||||
# split in horizontal orientation
|
||||
bindsym $mod+Shift+s split v
|
||||
|
||||
# split in vertical orientation
|
||||
bindsym $mod+s split h
|
||||
|
||||
# enter fullscreen mode for the focused container
|
||||
bindsym $mod+f fullscreen toggle
|
||||
|
||||
# change container layout (stacked, tabbed, toggle split)
|
||||
bindsym $mod+Shift+w layout stacking
|
||||
bindsym $mod+w layout tabbed
|
||||
bindsym $mod+e layout toggle split
|
||||
|
||||
# toggle tiling / floating
|
||||
bindsym $mod+Shift+v floating toggle
|
||||
|
||||
# change focus between tiling / floating windows
|
||||
bindsym $mod+v focus mode_toggle
|
||||
|
||||
# focus the parent/child container
|
||||
bindsym $mod+Shift+a focus parent
|
||||
bindsym $mod+a focus child
|
||||
|
||||
# make a (floating) window stick to all workspaces
|
||||
bindsym $mod+ctrl+v sticky toggle
|
||||
|
||||
# set up scratch pad for todo and 'drop-down' terminal
|
||||
# call scratchpads to current workspace -- scratchpads started on i3 starting (see end of file)
|
||||
bindsym $mod+t [class="scratchpad" title="dropdown-todo"] scratchpad show
|
||||
bindsym $mod+Shift+Return [class="scratchpad" title="dropdown-terminal"] scratchpad show
|
||||
|
||||
# GAP MANAGEMENT
|
||||
# disable titles and borders, necessary for i3gaps to work apparently
|
||||
for_window [class="^.*"] border pixel 0
|
||||
# by default set no gaps when multiple windows are on the workspace
|
||||
gaps inner 0
|
||||
gaps outer 0
|
||||
# increase/decrease inner gapping
|
||||
bindsym $mod+shift+g gaps inner current plus 10
|
||||
bindsym $mod+g gaps inner current minus 10
|
||||
# increase/decrease border sizes
|
||||
bindsym $mod+b border toggle 2
|
||||
|
||||
# Define names for default workspaces for which we configure key bindings later on.
|
||||
# We use variables to avoid repeating the names in multiple places.
|
||||
set $ws1 "1"
|
||||
set $ws2 "2"
|
||||
set $ws3 "3"
|
||||
set $ws4 "4"
|
||||
set $ws5 "5"
|
||||
set $ws6 "6"
|
||||
set $ws7 "7"
|
||||
set $ws8 "8"
|
||||
set $ws9 "9"
|
||||
set $ws10 "10"
|
||||
|
||||
# switch to workspace
|
||||
bindsym $mod+1 workspace $ws1
|
||||
bindsym $mod+2 workspace $ws2
|
||||
bindsym $mod+3 workspace $ws3
|
||||
bindsym $mod+4 workspace $ws4
|
||||
bindsym $mod+5 workspace $ws5
|
||||
bindsym $mod+6 workspace $ws6
|
||||
bindsym $mod+7 workspace $ws7
|
||||
bindsym $mod+8 workspace $ws8
|
||||
bindsym $mod+9 workspace $ws9
|
||||
bindsym $mod+0 workspace $ws10
|
||||
|
||||
# move focused container to workspace
|
||||
bindsym $mod+Shift+1 move container to workspace $ws1
|
||||
bindsym $mod+Shift+2 move container to workspace $ws2
|
||||
bindsym $mod+Shift+3 move container to workspace $ws3
|
||||
bindsym $mod+Shift+4 move container to workspace $ws4
|
||||
bindsym $mod+Shift+5 move container to workspace $ws5
|
||||
bindsym $mod+Shift+6 move container to workspace $ws6
|
||||
bindsym $mod+Shift+7 move container to workspace $ws7
|
||||
bindsym $mod+Shift+8 move container to workspace $ws8
|
||||
bindsym $mod+Shift+9 move container to workspace $ws9
|
||||
bindsym $mod+Shift+0 move container to workspace $ws10
|
||||
|
||||
|
||||
# resize window (you can also use the mouse for that)
|
||||
mode "resize" {
|
||||
# These bindings trigger as soon as you enter the resize mode
|
||||
|
||||
# Pressing left will shrink the window’s width.
|
||||
# Pressing right will grow the window’s width.
|
||||
# Pressing up will shrink the window’s height.
|
||||
# Pressing down will grow the window’s height.
|
||||
bindsym h resize shrink width 10 px or 10 ppt
|
||||
bindsym Shift+h resize shrink width 30 px or 30 ppt
|
||||
bindsym j resize grow height 10 px or 10 ppt
|
||||
bindsym Shift+j resize grow height 30 px or 30 ppt
|
||||
bindsym k resize shrink height 10 px or 10 ppt
|
||||
bindsym Shift+k resize shrink height 30 px or 30 ppt
|
||||
bindsym l resize grow width 10 px or 10 ppt
|
||||
bindsym Shift+l resize grow width 30 px or 30 ppt
|
||||
|
||||
# same bindings, but for the arrow keys
|
||||
bindsym Left resize shrink width 10 px or 10 ppt
|
||||
bindsym Down resize grow height 10 px or 10 ppt
|
||||
bindsym Up resize shrink height 10 px or 10 ppt
|
||||
bindsym Right resize grow width 10 px or 10 ppt
|
||||
|
||||
# back to normal: Enter or Escape or $mod+r
|
||||
bindsym Return mode "default"
|
||||
bindsym Escape mode "default"
|
||||
bindsym $modemod+r mode "default"
|
||||
|
||||
}
|
||||
|
||||
bindsym $modemod+r mode "resize"
|
||||
|
||||
# reload the configuration file
|
||||
bindsym $mod+F12 reload
|
||||
# restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
|
||||
bindsym $mod+Shift+F12 restart
|
||||
|
||||
# default workspaces for most used apps
|
||||
# assign [class="^qutebrowser$"] → number 1
|
||||
# spotify needs for_window, see https://i3wm.org/docs/userguide.html#assign_workspace
|
||||
assign [class="^spotify$"] → 10
|
||||
assign [class="^Spotify$"] → 10
|
||||
#fix for spotify not moving to workspace 10
|
||||
for_window [class="^spotify$"] move to workspace 10
|
||||
|
||||
# windows with class floating will automatically float
|
||||
# windows with class scratchpad will automatically float and be sent to the scratchpad
|
||||
for_window [class="floating"] floating enable
|
||||
for_window [class="scratchpad"] floating enable
|
||||
for_window [class="scratchpad"] move scratchpad
|
||||
|
||||
# Vim-like mark system - set with mod+m, go there with mod+'
|
||||
# read 1 character and mark the current window with this character
|
||||
bindsym $mod+m exec i3-input -F 'mark %s' -l 1 -P 'Mark: '
|
||||
# read 1 character and go to the window with the character
|
||||
bindsym $mod+apostrophe exec i3-input -F '[con_mark="%s"] focus' -l 1 -P 'Goto: '
|
||||
|
||||
# launch polybar (script ensures only 1 instance existing at a time)
|
||||
exec_always --no-startup-id polybar-launch top
|
||||
|
92
install.sh
|
@ -17,7 +17,7 @@ main() {
|
|||
|
||||
case "$1" in
|
||||
-v | --version)
|
||||
printf "Personal system bootstrap script.\n\n©Marty Oehme\n\nVersion: 0.1.1\n"
|
||||
printf "Personal system bootstrap script.\n\nby Marty Oehme\n\nv0.2\n"
|
||||
;;
|
||||
-h | --help)
|
||||
printf "Usage: install [-f|--force][-v|--version][-h|--help]\n\n-f Do not ask for any confirmations but force update and installation.\n"
|
||||
|
@ -36,44 +36,41 @@ main() {
|
|||
exit $ret
|
||||
}
|
||||
|
||||
# takes default value (y/n), question, abort message as arguments
|
||||
# automatically answers yes if unattended install
|
||||
check_consent() {
|
||||
echo "This will take a while, install many packages and link dotfiles all over the place. Proceed [y/N]?"
|
||||
read -r yes
|
||||
if [[ "$yes" != y* ]]; then
|
||||
echo "Exiting."
|
||||
exit
|
||||
if [ "$UNATTENDED" == "true" ]; then
|
||||
true
|
||||
else
|
||||
[[ "$1" == "y" ]] && default_consent="[Y/n]" || default_consent="[y/N]"
|
||||
printf "%s %s " "$2" "$default_consent"
|
||||
read -r answer
|
||||
if [[ "$1" == "n" ]] && [[ "$answer" != y* ]]; then
|
||||
echo first
|
||||
printf "%s\n" "$3"
|
||||
false
|
||||
elif [[ "$1" == "y" ]] && [[ "$answer" == n* ]]; then
|
||||
echo second
|
||||
printf "%s\n" "$3"
|
||||
false
|
||||
else
|
||||
true
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
entry_question() {
|
||||
check_consent n "This will take a while, install many packages and link dotfiles all over the place. Proceed?" "Aborting." || exit
|
||||
}
|
||||
|
||||
enable_git_hooks() {
|
||||
if [ "$1" == "false" ]; then
|
||||
echo "Should we enable git hooks for this repository, so that installed packages are automatically compared when committing? [Y/n]"
|
||||
read -r no
|
||||
if [[ "$no" == n* ]]; then
|
||||
echo "Not changing repository settings."
|
||||
return
|
||||
fi
|
||||
fi
|
||||
check_consent y "Should we enable git hooks for this repository, so that installed packages are automatically compared when committing?" "Not changing repository settings." || return
|
||||
git config --local core.hooksPath .githooks/
|
||||
echo "Changed repository settings."
|
||||
}
|
||||
|
||||
install() {
|
||||
unattended=$1
|
||||
if ! "$unattended"; then
|
||||
check_consent
|
||||
fi
|
||||
echo "====================== BEGINNING INSTALLATION ============================="
|
||||
if ! "$unattended"; then
|
||||
export BOOTSTRAP_PACKAGES="bootstrap/packages.txt"
|
||||
"$bootstrap_dir"/install_packages.sh
|
||||
else
|
||||
export BOOTSTRAP_PACKAGES="bootstrap/packages.txt"
|
||||
"$bootstrap_dir"/install_packages.sh -f
|
||||
fi
|
||||
unset BOOTSTRAP_PACKAGES
|
||||
|
||||
echo "=================== BEGINNING DOTFILE MANAGEMENT =========================="
|
||||
stow_dotfiles() {
|
||||
check_consent y "Link home directory dot files?" "Not linking dotfiles." || return
|
||||
# get all top level directories, remove their slashes and dots
|
||||
# finally get rid of .dot-directories, since they are for the repo not for my homedir
|
||||
targets="$(find . -maxdepth 1 -type d | sed -e 's/^\.\/\(.*\)$/\1/' | sed -e '/^\./d')"
|
||||
|
@ -81,9 +78,42 @@ install() {
|
|||
# shellcheck disable=2086
|
||||
# -- for some reason stow only works with unqoted var expansion
|
||||
stow -R ${targets} 2> >(grep -v 'Absolute/relative mismatch between Stow dir' 1>&2)
|
||||
echo "Linked dotfiles."
|
||||
}
|
||||
|
||||
stow_system_packages() {
|
||||
check_consent n "Link system settings as well? This will require sudo access." "Not touching system files." || return
|
||||
sudo stow --dir="$bootstrap_dir" --target="/" -R system-packages/
|
||||
echo "Linked system files."
|
||||
}
|
||||
|
||||
install_packages() {
|
||||
check_consent n "Install pre-designated packages? This will take a while." "Not installing packages." || return
|
||||
export BOOTSTRAP_PACKAGES="bootstrap/packages.txt"
|
||||
if ! "$UNATTENDED"; then
|
||||
"$bootstrap_dir"/install_packages.sh
|
||||
else
|
||||
"$bootstrap_dir"/install_packages.sh -f
|
||||
fi
|
||||
unset BOOTSTRAP_PACKAGES
|
||||
echo "Installed packages."
|
||||
}
|
||||
|
||||
install() {
|
||||
UNATTENDED=$1
|
||||
if ! "$UNATTENDED"; then
|
||||
entry_question
|
||||
fi
|
||||
|
||||
echo "====================== BEGINNING INSTALLATION ============================="
|
||||
install_packages
|
||||
|
||||
echo "=================== BEGINNING DOTFILE MANAGEMENT =========================="
|
||||
stow_dotfiles
|
||||
stow_system_packages
|
||||
|
||||
echo "================== ENABLING GIT REPOSITORY HOOKS =========================="
|
||||
enable_git_hooks "$unattended"
|
||||
enable_git_hooks
|
||||
|
||||
echo "====================== INSTALLATION FINISHED =============================="
|
||||
exit 0
|
||||
|
|
|
@ -31,8 +31,6 @@ import os
|
|||
import socket
|
||||
import errno
|
||||
import subprocess
|
||||
import fcntl
|
||||
import stat
|
||||
import string
|
||||
|
||||
files = sys.argv[1:]
|
||||
|
@ -43,18 +41,21 @@ def is_url(filename):
|
|||
if len(parts) < 2:
|
||||
return False
|
||||
# protocol prefix has no special characters => it's an URL
|
||||
allowed_symbols = string.ascii_letters + string.digits + '_'
|
||||
allowed_symbols = string.ascii_letters + string.digits + "_"
|
||||
prefix = parts[0]
|
||||
return all(map(lambda c: c in allowed_symbols, prefix))
|
||||
|
||||
|
||||
# make them absolute; also makes them safe against interpretation as options
|
||||
def make_abs(filename):
|
||||
if not is_url(filename):
|
||||
return os.path.abspath(filename)
|
||||
return filename
|
||||
|
||||
|
||||
files = [make_abs(f) for f in files]
|
||||
|
||||
SOCK = os.path.join(os.getenv("HOME"), ".umpv_socket")
|
||||
SOCK = os.path.join(str(os.getenv("HOME")), ".umpv_socket")
|
||||
|
||||
sock = None
|
||||
try:
|
||||
|
@ -74,14 +75,16 @@ if sock:
|
|||
# Unhandled race condition: what if mpv is terminating right now?
|
||||
for f in files:
|
||||
# escape: \ \n "
|
||||
f = f.replace("\\", "\\\\").replace("\"", "\\\"").replace("\n", "\\n")
|
||||
f = "\"" + f + "\""
|
||||
f = f.replace("\\", "\\\\").replace('"', '\\"').replace("\n", "\\n")
|
||||
f = '"' + f + '"'
|
||||
sock.send(("raw loadfile " + f + " append\n").encode("utf-8"))
|
||||
else:
|
||||
# Let mpv recreate socket if it doesn't already exist.
|
||||
|
||||
opts = (os.getenv("MPV") or "mpv").split()
|
||||
opts.extend(["--no-terminal",
|
||||
opts.extend(
|
||||
[
|
||||
"--no-terminal",
|
||||
"--force-window",
|
||||
"--input-ipc-server=" + SOCK,
|
||||
# position on lower left screen corner
|
||||
|
@ -90,7 +93,11 @@ else:
|
|||
"--geometry=15%+-10-+5",
|
||||
"--on-all-workspaces",
|
||||
"--force-window=immediate",
|
||||
"--"])
|
||||
"--x11-name=float",
|
||||
"--wayland-app-id=float",
|
||||
"--",
|
||||
]
|
||||
)
|
||||
opts.extend(files)
|
||||
|
||||
subprocess.check_call(opts)
|
||||
|
|
361
pass/.local/bin/pass-pick
Executable file
|
@ -0,0 +1,361 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Pass picker
|
||||
#
|
||||
# Use a dmenu-like list selector to display and autofill your pass passwords.
|
||||
# Can work with rofi, bemenu and dmenu, or a custom picker given as an option.
|
||||
# Invoke it with `pass-pick`. You can set options through environment variables
|
||||
# or through a configuration file.
|
||||
#
|
||||
# Keys:
|
||||
# By default shows the available keys on rofi, but not on bemenu/dmenu.
|
||||
# ROFI mapped keys (main password list):
|
||||
# return autofill username/password combination
|
||||
# alt+return enter entry submenu
|
||||
# alt+u autofill username
|
||||
# alt+p autofill password
|
||||
# alt+ctrl+u send username to clipboard
|
||||
# alt+ctrl+p send password to clipboard
|
||||
# ROFI mapped keys (individual entry):
|
||||
# return autofill selected field
|
||||
# alt+return send selected field to clipboard
|
||||
# alt+s reveal hidden password field
|
||||
# alt+backspace back to main password menu
|
||||
# Those options also work on bemenu, but have different (and fixed) mappings.
|
||||
# BEMENU mapped keys (main password list):
|
||||
# return autofill username/password combination
|
||||
# alt+2 send username to clipboard
|
||||
# alt+3 send password to clipboard
|
||||
# alt+4 autofill username
|
||||
# alt+5 autofill password
|
||||
# alt+6 enter entry submenu
|
||||
# BEMENU mapped keys (individual entry):
|
||||
# return autofill selected field
|
||||
# alt+2 send selected field to clipboard
|
||||
# alt+3 back to main password menu
|
||||
# alt+4 reveal hidden password field
|
||||
|
||||
# Selector wrapper
|
||||
# Prefers rofi if found, otherwise bemenu or dmenu if found, complains if no selector available.
|
||||
# Passes along any options given to main script.
|
||||
rofi_opts=("$@")
|
||||
_picker() {
|
||||
if [ -n "$PICKER" ]; then
|
||||
"${PICKER[@]}"
|
||||
elif command -v rofi 1>/dev/null 2>/dev/null; then
|
||||
rofi -dmenu -no-auto-select -i "${rofi_opts[@]}" "$@" -p "entry"
|
||||
elif command -v bemenu 1>/dev/null 2>/dev/null; then
|
||||
bemenu -l 20 -i -p "entry >"
|
||||
elif command -v dmenu 1>/dev/null 2>/dev/null; then
|
||||
dmenu -i -p "entry >"
|
||||
else
|
||||
printf "%s: 📦 %s must be installed for %s function.\n" "critical" "rofi/dmenu" "this" >&2
|
||||
notify-send "📦 rofi/dmenu" --urgency="critical" "must be installed for this function."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# parse, see https://unix.stackexchange.com/a/331965/8541
|
||||
_parse_config() {
|
||||
(grep -e "^$2=" -m 1 "$1" 2>/dev/null || printf "var=__UNDEFINED__\n") | head -n1 | cut -d '=' -f 2-
|
||||
}
|
||||
|
||||
# read config file
|
||||
get_config() {
|
||||
local locations=(
|
||||
"$PP_CONFIGURATION_FILE"
|
||||
"${xdg_config_home:-$HOME/.config}/pass-picker/pass-picker.conf"
|
||||
"$HOME/.pass-picker.conf"
|
||||
"/etc/pass-picker.conf"
|
||||
)
|
||||
|
||||
# return the first config file with a valid path
|
||||
for config in "${locations[@]}"; do
|
||||
if [[ -n "$config" && -f "$config" ]]; then
|
||||
# see if the config has been given a value
|
||||
local val
|
||||
val="$(_parse_config "$config" "$1")"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# if there was a config file but no value
|
||||
# or there was no config file at all
|
||||
if [ "$val" = "__UNDEFINED__" ] || [ -z "$val" ]; then
|
||||
val="$2"
|
||||
fi
|
||||
printf -- "%s" "$val"
|
||||
}
|
||||
|
||||
set_defaults() {
|
||||
# The location of the pass-picker config file
|
||||
# PP_CONFIGURATION_FILE="~/.config/pass-picker/pass-picker.conf"
|
||||
# set options, leaving already set environment variables intact
|
||||
# try to read any settings from config files
|
||||
PICKER="${PP_PICKER:-$(get_config PICKER)}"
|
||||
|
||||
KEY_AUTOFILL="${PP_KEY_AUTOFILL:-$(get_config KEY_AUTOFILL Return)}"
|
||||
KEY_ENTRY_OPEN="${PP_KEY_ENTRY_OPEN:-$(get_config KEY_ENTRY_OPEN Alt+Return)}"
|
||||
KEY_FILL_USER="${PP_KEY_FILL_USER:-$(get_config KEY_FILL_USER Alt+u)}"
|
||||
KEY_CLIP_USER="${PP_KEY_CLIP_USER:-$(get_config KEY_CLIP_USER Ctrl+Alt+u)}"
|
||||
KEY_FILL_PASS="${PP_KEY_FILL_PASS:-$(get_config KEY_FILL_PASS Alt+p)}"
|
||||
KEY_CLIP_PASS="${PP_KEY_CLIP_PASS:-$(get_config KEY_CLIP_PASS Ctrl+Alt+p)}"
|
||||
KEY_ENTRYMENU_FILL="${PP_KEY_ENTRYMENU_FILL:-$(get_config KEY_ENTRYMENU_FILL Return)}"
|
||||
KEY_ENTRYMENU_CLIP="${PP_KEY_ENTRYMENU_CLIP:-$(get_config KEY_ENTRYMENU_CLIP Alt+Return)}"
|
||||
KEY_ENTRYMENU_SHOWFIELD="${KEY_ENTRYMENU_SHOWFIELD:-$(get_config KEY_ENTRYMENU_SHOWFIELD Alt+s)}"
|
||||
KEY_ENTRYMENU_QUIT="${PP_KEY_ENTRYMENU_QUIT:-$(get_config KEY_ENTRYMENU_QUIT Alt+BackSpace)}"
|
||||
|
||||
AUTOFILL_BACKEND="${PP_AUTOFILL_BACKEND:-$(get_config AUTOFILL_BACKEND ydotool)}"
|
||||
AUTOFILL_CHAIN="${PP_AUTOENTRY_CHAIN:-$(get_config AUTOFILL_CHAIN 'username :tab password')}"
|
||||
AUTOFILL_DELAY="${PP_AUTOENTRY_DELAY:-$(get_config AUTOFILL_DELAY 30)}"
|
||||
PASS_USERNAME_FIELD="${PP_PASS_USERNAME_FIELD:-$(get_config PASS_USERNAME_FIELD 'username user login')}"
|
||||
}
|
||||
|
||||
# exit on escape pressed
|
||||
exit_check() {
|
||||
[ "$1" -eq 1 ] && exit
|
||||
}
|
||||
|
||||
# simply return a list of all passwords in pass store
|
||||
# TODO only show website names (+ folder names), and account names for multiple accounts on one site
|
||||
list_passwords() {
|
||||
shopt -s nullglob globstar
|
||||
prefix=${PASSWORD_STORE_DIR:-~/.password-store}
|
||||
password_files=("$prefix"/**/*.gpg)
|
||||
password_files=("${password_files[@]#"$prefix"/}")
|
||||
password_files=("${password_files[@]%.gpg}")
|
||||
|
||||
printf '%s\n' "${password_files[@]}"
|
||||
}
|
||||
|
||||
# return password for argument passed
|
||||
show_password() {
|
||||
pass show "$1" | head -n1
|
||||
}
|
||||
|
||||
# send password to clipboard
|
||||
clip_password() {
|
||||
pass show -c "$1"
|
||||
}
|
||||
|
||||
# attempt to return the field specified
|
||||
# attempts all (space separated) fields until the
|
||||
# first one successfully returned
|
||||
_p_get_field() {
|
||||
local gp_entry="$1"
|
||||
local gp_field="$2"
|
||||
local clip="$3"
|
||||
|
||||
# return on first successfully returned key
|
||||
for key in $gp_field; do
|
||||
local value
|
||||
value=$(_p_get_key_value "$gp_entry" "$key")
|
||||
|
||||
# found entry
|
||||
if [ -n "$value" ]; then
|
||||
|
||||
if [ -n "$clip" ]; then
|
||||
# copies to clipboard, removes any trailing newlines,
|
||||
# and only keeps it in for 1 paste (1 loop to read in script, 1 to output)
|
||||
if command -v wl-copy; then
|
||||
echo "$value" | wl-copy -o && break
|
||||
elif command -v xclip; then
|
||||
echo "$value" | xclip -i -selection 'clipboard' -loops 2 -rmlastnl && break
|
||||
elif command -v xsel; then
|
||||
echo "$value" | xsel -b && break
|
||||
else
|
||||
notify-send "No clipboard utility" "Install wl-copy, xclip or xsel."
|
||||
fi
|
||||
else
|
||||
echo "$value" && break
|
||||
fi
|
||||
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# returns the corresponding value for the key passed in
|
||||
# arguments:
|
||||
# $1: pass (file) entry to search through
|
||||
# $2: string name of the containting key
|
||||
_p_get_key_value() {
|
||||
local value
|
||||
value=$(list_fields "$1" | grep "$2")
|
||||
|
||||
# get everything after first colon, remove whitespace
|
||||
echo "$value" | cut -d':' -f2- | tr -d '[:blank:]'
|
||||
}
|
||||
|
||||
# return username for argument passed
|
||||
show_username() {
|
||||
_p_get_field "$1" "${PASS_USERNAME_FIELD}"
|
||||
}
|
||||
|
||||
clip_username() {
|
||||
_p_get_field "$1" "${PASS_USERNAME_FIELD}" "-c"
|
||||
}
|
||||
|
||||
show_field() {
|
||||
_p_get_field "$1" "$2"
|
||||
}
|
||||
|
||||
clip_field() {
|
||||
_p_get_field "$1" "$2" "-c"
|
||||
}
|
||||
|
||||
list_fields() {
|
||||
pass show "$1" | tail -n+2
|
||||
}
|
||||
|
||||
# invoke the dotool to type inputs
|
||||
_type() {
|
||||
local tool="${AUTOFILL_BACKEND}"
|
||||
local toolmode="$1"
|
||||
local key="$2"
|
||||
|
||||
if [ "$tool" = "xdotool" ]; then
|
||||
"$tool" "$toolmode" --delay "${AUTOFILL_DELAY}" "$key"
|
||||
elif [ "$tool" = "ydotool" ]; then
|
||||
"$tool" "$toolmode" --key-delay "${AUTOFILL_DELAY}" "$key"
|
||||
else
|
||||
"$tool" "$toolmode" "$key"
|
||||
fi
|
||||
}
|
||||
|
||||
# automatically fill out fields
|
||||
# transform special chain entries into valid dotool commands
|
||||
autofill() {
|
||||
local selected="${1}"
|
||||
local autoentry_chain="${2}"
|
||||
|
||||
for part in $autoentry_chain; do
|
||||
case "$part" in
|
||||
":tab") _type key Tab ;;
|
||||
":return") _type key Return ;;
|
||||
":space") _type key space ;;
|
||||
"username") _type type "$(show_username "$selected")" ;;
|
||||
"password") _type type "$(show_password "$selected")" ;;
|
||||
":direct") _type type "$selected" ;;
|
||||
*) printf '%s' "$selected" ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# opens a menu for the specified pass entry, containing its individual fields
|
||||
entrymenu() {
|
||||
local entry="$1"
|
||||
local deobfuscate="$2"
|
||||
local k_entrymenu_fill="${KEY_ENTRYMENU_FILL}"
|
||||
local k_entrymenu_clip="${KEY_ENTRYMENU_CLIP}"
|
||||
local k_entrymenu_showfield="${KEY_ENTRYMENU_SHOWFIELD}"
|
||||
local k_entrymenu_quit="${KEY_ENTRYMENU_QUIT}"
|
||||
|
||||
local pass
|
||||
if [ "$deobfuscate" = "true" ]; then
|
||||
pass="$(show_password "$entry")"
|
||||
else
|
||||
pass="(hidden)"
|
||||
fi
|
||||
|
||||
local field
|
||||
field=$(
|
||||
printf "password: %s\n%s" "$pass" "$(list_fields "$entry")" |
|
||||
_picker \
|
||||
-kb-accept-entry "" \
|
||||
-kb-custom-1 "$k_entrymenu_fill" \
|
||||
-kb-custom-2 "$k_entrymenu_clip" \
|
||||
-kb-custom-3 "$k_entrymenu_quit" \
|
||||
-kb-custom-4 "$k_entrymenu_showfield" \
|
||||
-mesg " ᐊ $k_entrymenu_quit ᐊ | $k_entrymenu_fill: fill selection | $k_entrymenu_clip: clip selection | $k_entrymenu_showfield: reveal password"
|
||||
)
|
||||
exit_value=$?
|
||||
exit_check "$exit_value"
|
||||
|
||||
# get field name
|
||||
field=${field%%:*}
|
||||
case "$exit_value" in
|
||||
"0" | "10")
|
||||
if [ "$field" = "password" ]; then
|
||||
autofill "$entry" "password"
|
||||
else
|
||||
autofill "$(show_field "$entry" "$field")" ":direct"
|
||||
fi
|
||||
exit 0
|
||||
;;
|
||||
"11")
|
||||
if [ "$field" = "password" ]; then
|
||||
clip_password "$entry"
|
||||
else
|
||||
clip_field "$entry" "$field"
|
||||
fi
|
||||
exit 0
|
||||
;;
|
||||
"12")
|
||||
main
|
||||
;;
|
||||
"13")
|
||||
local toggle
|
||||
if [ "$deobfuscate" = "true" ]; then
|
||||
toggle=false
|
||||
else
|
||||
toggle=true
|
||||
fi
|
||||
entrymenu "$entry" "$toggle"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main() {
|
||||
local autoentry_chain="${AUTOFILL_CHAIN}"
|
||||
local k_autofill="${KEY_AUTOFILL}"
|
||||
local k_fill_user="${KEY_FILL_USER}"
|
||||
local k_clip_user="${KEY_CLIP_USER}"
|
||||
local k_fill_pass="${KEY_FILL_PASS}"
|
||||
local k_clip_pass="${KEY_CLIP_PASS}"
|
||||
local k_submenu="${KEY_ENTRY_OPEN}"
|
||||
|
||||
entry="$(
|
||||
list_passwords |
|
||||
_picker -kb-accept-entry "" \
|
||||
-kb-custom-1 "$k_autofill" \
|
||||
-kb-custom-2 "$k_clip_user" \
|
||||
-kb-custom-3 "$k_clip_pass" \
|
||||
-kb-custom-4 "$k_fill_user" \
|
||||
-kb-custom-5 "$k_fill_pass" \
|
||||
-kb-custom-6 "$k_submenu" \
|
||||
-mesg "| $k_autofill: fill credentials | $k_submenu: open entry | $k_fill_user: fill username | $k_fill_pass: fill password | $k_clip_user: clip username | $k_clip_pass: clip password |"
|
||||
)"
|
||||
exit_value=$?
|
||||
|
||||
echo "$entry"
|
||||
exit_check "$exit_value"
|
||||
case "$exit_value" in
|
||||
"0" | "10")
|
||||
autofill "$entry" "$autoentry_chain"
|
||||
exit 0
|
||||
;;
|
||||
"11")
|
||||
clip_username "$entry"
|
||||
exit 0
|
||||
;;
|
||||
"12")
|
||||
clip_password "$entry"
|
||||
exit
|
||||
;;
|
||||
"13")
|
||||
autofill "$entry" "username"
|
||||
exit
|
||||
;;
|
||||
"14")
|
||||
autofill "$entry" "password"
|
||||
exit
|
||||
;;
|
||||
"15")
|
||||
entrymenu "$entry"
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
set_defaults
|
||||
main
|
|
@ -1,307 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
|
||||
# selector wrapper
|
||||
# uses rofi if found, or dmenu if found, complains if no selector available
|
||||
# passes along any options given to main script
|
||||
rofi_opts=("$@")
|
||||
_rofi() {
|
||||
if type rofi 1>/dev/null 2>/dev/null; then
|
||||
rofi -dmenu -no-auto-select -i "${rofi_opts[@]}" "$@" -p "Entry"
|
||||
elif type dmenu 1>/dev/null 2>/dev/null; then
|
||||
dmenu -i "${rofi_opts[@]}" "$@" -p "Entry"
|
||||
else
|
||||
printf "%s: 📦 %s must be installed for %s function.\n" "critical" "rofi/dmenu" "this" >&2
|
||||
notify-send "📦 rofi/dmenu" --urgency="critical" "must be installed for this function."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# parse, see https://unix.stackexchange.com/a/331965/8541
|
||||
_parse_config() {
|
||||
(grep -E "^$2=" -m 1 "$1" 2>/dev/null || printf "VAR=__UNDEFINED__\n") | head -n1 | cut -d '=' -f 2-
|
||||
}
|
||||
|
||||
# read config file
|
||||
get_config() {
|
||||
local locations=(
|
||||
"$RP_CONFIGURATION_FILE"
|
||||
"${XDG_CONFIG_HOME:-$HOME/.config}/rofi-pass/rofi-pass.conf"
|
||||
"$HOME/.rofi-pass.conf"
|
||||
"/etc/rofi-pass.conf"
|
||||
)
|
||||
|
||||
# return the first config file with a valid path
|
||||
for config in "${locations[@]}"; do
|
||||
if [[ -n "$config" && -f "$config" ]]; then
|
||||
# see if the config has been given a value
|
||||
local val
|
||||
val="$(_parse_config "$config" "$1")"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# if there was a config file but no value
|
||||
# or there was no config file at all
|
||||
if [ "$val" = "__UNDEFINED__" ] || [ -z "$val" ]; then
|
||||
val="$2"
|
||||
fi
|
||||
printf -- "%s" "$val"
|
||||
}
|
||||
|
||||
set_defaults() {
|
||||
# The location of the rofi-pass config file
|
||||
# RP_CONFIGURATION_FILE="~/.config/rofi-pass/rofi-pass.conf"
|
||||
# set options, leaving already set environment variables intact
|
||||
# try to read any settings from config files
|
||||
KEY_AUTOFILL="${RP_KEY_AUTOFILL:-$(get_config KEY_AUTOFILL Return)}"
|
||||
KEY_ENTRY_OPEN="${RP_KEY_ENTRY_OPEN:-$(get_config KEY_ENTRY_OPEN Alt+Return)}"
|
||||
KEY_FILL_USER="${RP_KEY_FILL_USER:-$(get_config KEY_FILL_USER Alt+u)}"
|
||||
KEY_CLIP_USER="${RP_KEY_CLIP_USER:-$(get_config KEY_CLIP_USER Ctrl+Alt+u)}"
|
||||
KEY_FILL_PASS="${RP_KEY_FILL_PASS:-$(get_config KEY_FILL_PASS Alt+p)}"
|
||||
KEY_CLIP_PASS="${RP_KEY_CLIP_PASS:-$(get_config KEY_CLIP_PASS Ctrl+Alt+p)}"
|
||||
KEY_ENTRYMENU_FILL="${RP_KEY_ENTRYMENU_FILL:-$(get_config KEY_ENTRYMENU_FILL Return)}"
|
||||
KEY_ENTRYMENU_CLIP="${RP_KEY_ENTRYMENU_CLIP:-$(get_config KEY_ENTRYMENU_CLIP Alt+Return)}"
|
||||
KEY_ENTRYMENU_SHOWFIELD="${KEY_ENTRYMENU_SHOWFIELD:-$(get_config KEY_ENTRYMENU_SHOWFIELD Alt+s)}"
|
||||
KEY_ENTRYMENU_QUIT="${RP_KEY_ENTRYMENU_QUIT:-$(get_config KEY_ENTRYMENU_QUIT Alt+BackSpace)}"
|
||||
|
||||
AUTOFILL_BACKEND="${RP_AUTOFILL_BACKEND:-$(get_config AUTOFILL_BACKEND xdotool)}"
|
||||
AUTOFILL_CHAIN="${RP_AUTOENTRY_CHAIN:-$(get_config AUTOFILL_CHAIN 'username :tab password')}"
|
||||
AUTOFILL_DELAY="${RP_AUTOENTRY_DELAY:-$(get_config AUTOFILL_DELAY 30)}"
|
||||
PASS_USERNAME_FIELD="${RP_PASS_USERNAME_FIELD:-$(get_config PASS_USERNAME_FIELD 'username user login')}"
|
||||
}
|
||||
|
||||
# exit on escape pressed
|
||||
# rofi returns exit code 1 on esc
|
||||
exit_check() {
|
||||
[ "$1" -eq 1 ] && exit
|
||||
}
|
||||
|
||||
# simply return a list of all passwords in pass store
|
||||
# TODO only show website names (+ folder names), and account names for multiple accounts on one site
|
||||
list_passwords() {
|
||||
shopt -s nullglob globstar
|
||||
prefix=${PASSWORD_STORE_DIR:-~/.password-store}
|
||||
password_files=("$prefix"/**/*.gpg)
|
||||
password_files=("${password_files[@]#"$prefix"/}")
|
||||
password_files=("${password_files[@]%.gpg}")
|
||||
|
||||
printf '%s\n' "${password_files[@]}"
|
||||
}
|
||||
|
||||
# return password for argument passed
|
||||
show_password() {
|
||||
pass show "$1" | head -n1
|
||||
}
|
||||
|
||||
# send password to clipboard
|
||||
clip_password() {
|
||||
pass show -c "$1"
|
||||
}
|
||||
|
||||
# attempt to return the field specified
|
||||
# attempts all (space separated) fields until the
|
||||
# first one successfully returned
|
||||
_p_get_field() {
|
||||
local gp_entry="$1"
|
||||
local gp_field="$2"
|
||||
local clip="$3"
|
||||
|
||||
# return on first successfully returned key
|
||||
for key in $gp_field; do
|
||||
local value
|
||||
value=$(_p_get_key_value "$gp_entry" "$key")
|
||||
|
||||
# found entry
|
||||
if [ -n "$value" ]; then
|
||||
|
||||
if [ -n "$clip" ]; then
|
||||
# copies to clipboard, removes any trailing newlines,
|
||||
# and only keeps it in for 1 paste (1 loop to read in script, 1 to output)
|
||||
echo "$value" | xclip -i -selection 'clipboard' -loops 2 -rmlastnl && break
|
||||
else
|
||||
echo "$value" && break
|
||||
fi
|
||||
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# returns the corresponding value for the key passed in
|
||||
# arguments:
|
||||
# $1: pass (file) entry to search through
|
||||
# $2: string name of the containting key
|
||||
_p_get_key_value() {
|
||||
local value
|
||||
value=$(list_fields "$1" | grep "$2")
|
||||
|
||||
# get everything after first colon, remove whitespace
|
||||
echo "$value" | cut -d':' -f2- | tr -d '[:blank:]'
|
||||
}
|
||||
|
||||
# return username for argument passed
|
||||
show_username() {
|
||||
_p_get_field "$1" "${PASS_USERNAME_FIELD}"
|
||||
}
|
||||
|
||||
clip_username() {
|
||||
_p_get_field "$1" "${PASS_USERNAME_FIELD}" "-c"
|
||||
}
|
||||
|
||||
show_field() {
|
||||
_p_get_field "$1" "$2"
|
||||
}
|
||||
|
||||
clip_field() {
|
||||
_p_get_field "$1" "$2" "-c"
|
||||
}
|
||||
|
||||
list_fields() {
|
||||
pass show "$1" | tail -n+2
|
||||
}
|
||||
|
||||
# invoke the dotool to type inputs
|
||||
_type() {
|
||||
local tool="${AUTOFILL_BACKEND}"
|
||||
local toolmode="$1"
|
||||
local key="$2"
|
||||
|
||||
"$tool" "$toolmode" --delay "${AUTOFILL_DELAY}" "$key"
|
||||
}
|
||||
|
||||
# automatically fill out fields
|
||||
# transform special chain entries into valid dotool commands
|
||||
autofill() {
|
||||
local selected="${1}"
|
||||
local autoentry_chain="${2}"
|
||||
|
||||
for part in $autoentry_chain; do
|
||||
case "$part" in
|
||||
":tab") _type key Tab ;;
|
||||
":return") _type key Return ;;
|
||||
":space") _type key space ;;
|
||||
"username") _type type "$(show_username "$selected")" ;;
|
||||
"password") _type type "$(show_password "$selected")" ;;
|
||||
":direct") _type type "$selected" ;;
|
||||
*) printf '%s' "$selected" ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# opens a menu for the specified pass entry, containing its individual fields
|
||||
entrymenu() {
|
||||
local entry="$1"
|
||||
local deobfuscate="$2"
|
||||
local k_entrymenu_fill="${KEY_ENTRYMENU_FILL}"
|
||||
local k_entrymenu_clip="${KEY_ENTRYMENU_CLIP}"
|
||||
local k_entrymenu_showfield="${KEY_ENTRYMENU_SHOWFIELD}"
|
||||
local k_entrymenu_quit="${KEY_ENTRYMENU_QUIT}"
|
||||
|
||||
local pass
|
||||
if [ "$deobfuscate" = "true" ]; then
|
||||
pass="$(show_password "$entry")"
|
||||
else
|
||||
pass="(hidden)"
|
||||
fi
|
||||
|
||||
local field
|
||||
field=$(
|
||||
printf "password: %s\n%s" "$pass" "$(list_fields "$entry")" |
|
||||
_rofi \
|
||||
-kb-accept-entry "" \
|
||||
-kb-custom-1 "$k_entrymenu_fill" \
|
||||
-kb-custom-2 "$k_entrymenu_clip" \
|
||||
-kb-custom-3 "$k_entrymenu_quit" \
|
||||
-kb-custom-4 "$k_entrymenu_showfield" \
|
||||
-mesg " ᐊ $k_entrymenu_quit ᐊ | $k_entrymenu_fill: fill selection | $k_entrymenu_clip: clip selection | $k_entrymenu_showfield: reveal password"
|
||||
)
|
||||
exit_value=$?
|
||||
exit_check "$exit_value"
|
||||
|
||||
# get field name
|
||||
field=${field%%:*}
|
||||
case "$exit_value" in
|
||||
"10")
|
||||
if [ "$field" = "password" ]; then
|
||||
autofill "$entry" "password"
|
||||
else
|
||||
autofill "$(show_field "$entry" "$field")" ":direct"
|
||||
fi
|
||||
exit 0
|
||||
;;
|
||||
"11")
|
||||
if [ "$field" = "password" ]; then
|
||||
clip_password "$entry"
|
||||
else
|
||||
clip_field "$entry" "$field"
|
||||
fi
|
||||
exit 0
|
||||
;;
|
||||
"12")
|
||||
main
|
||||
;;
|
||||
"13")
|
||||
local toggle
|
||||
if [ "$deobfuscate" = "true" ]; then
|
||||
toggle=false
|
||||
else
|
||||
toggle=true
|
||||
fi
|
||||
entrymenu "$entry" "$toggle"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main() {
|
||||
local autoentry_chain="${AUTOFILL_CHAIN}"
|
||||
local k_autofill="${KEY_AUTOFILL}"
|
||||
local k_fill_user="${KEY_FILL_USER}"
|
||||
local k_clip_user="${KEY_CLIP_USER}"
|
||||
local k_fill_pass="${KEY_FILL_PASS}"
|
||||
local k_clip_pass="${KEY_CLIP_PASS}"
|
||||
local k_submenu="${KEY_ENTRY_OPEN}"
|
||||
|
||||
entry="$(
|
||||
list_passwords |
|
||||
_rofi -kb-accept-entry "" \
|
||||
-kb-custom-1 "$k_autofill" \
|
||||
-kb-custom-2 "$k_clip_user" \
|
||||
-kb-custom-3 "$k_clip_pass" \
|
||||
-kb-custom-4 "$k_fill_user" \
|
||||
-kb-custom-5 "$k_fill_pass" \
|
||||
-kb-custom-6 "$k_submenu" \
|
||||
-mesg "| $k_autofill: fill credentials | $k_submenu: open entry | $k_fill_user: fill username | $k_fill_pass: fill password | $k_clip_user: clip username | $k_clip_pass: clip password |"
|
||||
)"
|
||||
exit_value=$?
|
||||
|
||||
exit_check "$exit_value"
|
||||
case "$exit_value" in
|
||||
"10")
|
||||
autofill "$entry" "$autoentry_chain"
|
||||
exit 0
|
||||
;;
|
||||
"11")
|
||||
clip_username "$entry"
|
||||
exit 0
|
||||
;;
|
||||
"12")
|
||||
clip_password "$entry"
|
||||
exit
|
||||
;;
|
||||
"13")
|
||||
autofill "$entry" "username"
|
||||
exit
|
||||
;;
|
||||
"14")
|
||||
autofill "$entry" "password"
|
||||
exit
|
||||
;;
|
||||
"15")
|
||||
entrymenu "$entry"
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
set_defaults
|
||||
main
|
|
@ -1,364 +0,0 @@
|
|||
;==========================================================
|
||||
;
|
||||
;
|
||||
; ██████╗ ██████╗ ██╗ ██╗ ██╗██████╗ █████╗ ██████╗
|
||||
; ██╔══██╗██╔═══██╗██║ ╚██╗ ██╔╝██╔══██╗██╔══██╗██╔══██╗
|
||||
; ██████╔╝██║ ██║██║ ╚████╔╝ ██████╔╝███████║██████╔╝
|
||||
; ██╔═══╝ ██║ ██║██║ ╚██╔╝ ██╔══██╗██╔══██║██╔══██╗
|
||||
; ██║ ╚██████╔╝███████╗██║ ██████╔╝██║ ██║██║ ██║
|
||||
; ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝
|
||||
;
|
||||
;
|
||||
; To learn more about how to configure Polybar
|
||||
; go to https://github.com/polybar/polybar
|
||||
;
|
||||
; The README contains a lot of information
|
||||
;
|
||||
;==========================================================
|
||||
|
||||
[colors]
|
||||
background = ${xrdb:background}
|
||||
background-alt = ${xrdb:color8}
|
||||
foreground = ${xrdb:foreground}
|
||||
foreground-alt = ${xrdb:color3}
|
||||
primary = ${xrdb:color1}
|
||||
secondary = ${xrdb:color4}
|
||||
alert = ${xrdb:color2}
|
||||
|
||||
[settings]
|
||||
; The throttle settings lets the eventloop swallow up til X events
|
||||
; if they happen within Y millisecond after first event was received.
|
||||
; This is done to prevent flood of update event.
|
||||
;
|
||||
; For example if 5 modules emit an update event at the same time, we really
|
||||
; just care about the last one. But if we wait too long for events to swallow
|
||||
; the bar would appear sluggish so we continue if timeout
|
||||
; expires or limit is reached.
|
||||
throttle-output = 5
|
||||
throttle-output-for = 10
|
||||
; Time in milliseconds that the input handler will wait between processing events
|
||||
throttle-input-for = 30
|
||||
|
||||
[global/wm]
|
||||
margin-top = 0
|
||||
margin-bottom = 0
|
||||
|
||||
[bar/top]
|
||||
; enable inter process communication, so that we can send messages
|
||||
; to polybar via polybar-msg command
|
||||
enable-ipc = true
|
||||
|
||||
; Put the bar at the bottom of the screen
|
||||
bottom=false
|
||||
|
||||
width = 100%
|
||||
height = 20
|
||||
padding-left = 0
|
||||
padding-right = 0
|
||||
module-margin-left = 2
|
||||
module-margin-right = 2
|
||||
|
||||
modules-left = sxhkdmode workspaces pomo papersdue
|
||||
modules-center = music datecal
|
||||
modules-right = dunstpaused networkspeed mail weather archupdates cpu temp volume battery
|
||||
; do not use offsets for the bar, would only work with override-redirect
|
||||
; and will mess up tray https://github.com/polybar/polybar/issues/1355
|
||||
tray-position = right
|
||||
|
||||
; Basic Colors, defined further up
|
||||
background = ${colors.background}
|
||||
foreground = ${colors.foreground}
|
||||
line-size = 1
|
||||
line-color = ${colors.primary}
|
||||
|
||||
; Prefer fixed center position for the `modules-center` block.
|
||||
; The center block will stay in the middle of the bar whenever
|
||||
; possible. It can still be pushed around if other blocks need
|
||||
; more space.
|
||||
; When false, the center block is centered in the space between
|
||||
; the left and right block.
|
||||
fixed-center = true
|
||||
|
||||
; Fonts are defined using <font-name>;<vertical-offset>
|
||||
; Font names are specified using a fontconfig pattern.
|
||||
; font-0 = NotoSans-Regular:size=8;2
|
||||
; font-1 = MaterialIcons:size=10
|
||||
; font-2 = Termsynu:size=8;-1
|
||||
; font-3 = FontAwesome:size=10
|
||||
; See the Fonts wiki page for more details
|
||||
font-0 = Comic Neue:size=10
|
||||
font-1 = NotoSans:size=23
|
||||
font-2 = Iosevka:size=14;1
|
||||
|
||||
cursor-click = pointer
|
||||
|
||||
[module/sxhkdmode]
|
||||
type = custom/script
|
||||
exec = sxhkd-chain-labels
|
||||
exec-if = type sxhkd-chain-labels
|
||||
tail = true
|
||||
format = <label>
|
||||
format-padding = 5
|
||||
format-prefix = "狀 "
|
||||
format-background = ${colors.primary}
|
||||
format-foreground = ${colors.background}
|
||||
|
||||
[module/workspaces]
|
||||
; module type
|
||||
type = internal/i3
|
||||
; default formatting
|
||||
format = <label-mode><label-state>
|
||||
; removes numbers for workspaces which have distinct names / icons
|
||||
strip-wsnumbers = true
|
||||
|
||||
ws-icon-0 = 1;
|
||||
ws-icon-1 = 2;
|
||||
ws-icon-2 = 3;
|
||||
ws-icon-3 = 4;4
|
||||
ws-icon-4 = 5;5
|
||||
ws-icon-5 = 6;6
|
||||
ws-icon-6 = 7;7
|
||||
ws-icon-7 = 8;8
|
||||
ws-icon-8 = 9;
|
||||
ws-icon-9 = 10;
|
||||
ws-icon-default = ♟
|
||||
|
||||
; Available tokens:
|
||||
; %name%
|
||||
; %icon%
|
||||
; %index%
|
||||
; %output%
|
||||
; Default: %icon% %name%
|
||||
; unfocused = Inactive workspace on any monitor
|
||||
label-unfocused = %icon%
|
||||
label-unfocused-padding = 2
|
||||
label-unfocused-underline = ${colors.background-alt}
|
||||
; focused = Active workspace on focused monitor
|
||||
label-focused = %icon%
|
||||
label-focused-foreground = ${colors.foreground}
|
||||
label-focused-background = ${colors.background-alt}
|
||||
label-focused-underline = ${colors.primary}
|
||||
label-focused-padding = ${self.label-unfocused-padding}
|
||||
; visible = Active workspace on unfocused monitor
|
||||
label-visible = %icon%
|
||||
label-visible-background = ${self.label-focused-background}
|
||||
label-visible-underline = ${self.label-focused-underline}
|
||||
label-visible-padding = ${self.label-unfocused-padding}
|
||||
; urgent = Workspace with urgency hint set
|
||||
label-urgent = %icon%
|
||||
label-urgent-background = ${colors.alert}
|
||||
label-urgent-padding = ${self.label-unfocused-padding}
|
||||
; formatting of the mode display
|
||||
label-mode = %mode%
|
||||
label-mode-padding = ${self.label-unfocused-padding}
|
||||
label-mode-foreground = ${colors.background}
|
||||
label-mode-background = ${colors.primary}
|
||||
|
||||
[module/cpu]
|
||||
; module type
|
||||
type = internal/cpu
|
||||
; Seconds to sleep between updates
|
||||
interval = 1.0
|
||||
; Available tags:
|
||||
; <label> (default)
|
||||
; <bar-load>
|
||||
; <ramp-load>
|
||||
; <ramp-coreload>
|
||||
format = <ramp-load>
|
||||
; Available tokens:
|
||||
; %percentage% (default) - total cpu load averaged over all cores
|
||||
; %percentage-sum% - Cumulative load on all cores
|
||||
; %percentage-cores% - load percentage for each core
|
||||
; %percentage-core[1-9]% - load percentage for specific core
|
||||
label =
|
||||
; enable large icon font
|
||||
label-font = 2
|
||||
; Spacing between individual per-core ramps
|
||||
ramp-load-0 = ▁
|
||||
ramp-load-1 = %{F#ffe5e5}▂%{F-}
|
||||
ramp-load-2 = %{F#ffcccc}▃%{F-}
|
||||
ramp-load-3 = %{F#ffb2b2}▄%{F-}
|
||||
ramp-load-4 = %{F#ff9999}▅%{F-}
|
||||
ramp-load-5 = %{F#ff6666}▆%{F-}
|
||||
ramp-load-6 = %{F#ff3232}▇%{F-}
|
||||
ramp-load-7 = %{F#ff0000}█%{F-}
|
||||
format-underline = ${colors.primary}
|
||||
|
||||
[module/temp]
|
||||
type = internal/temperature
|
||||
; Seconds to sleep between updates
|
||||
interval = 1.0
|
||||
; Thermal zone to use
|
||||
; To list all the zone types, run
|
||||
; $ for i in /sys/class/thermal/thermal_zone*; do echo "$i: $(<$i/type)"; done
|
||||
; Default: 0
|
||||
thermal-zone = 2
|
||||
; Use `sensors` to find preferred temperature source, then run
|
||||
; $ for i in /sys/class/hwmon/hwmon*/temp*_input; do echo "$(<$(dirname $i)/name): $(cat ${i%_*}_label 2>/dev/null || echo $(basename ${i%_*})) $(readlink -f $i)"; done
|
||||
; hwmon-path = /sys/devices/platform/coretemp.0/hwmon/hwmon0/temp1_input
|
||||
; Base temperature for where to start the ramp (in degrees celsius)
|
||||
base-temperature = 50
|
||||
; Threshold temperature to display warning label (in degrees celsius)
|
||||
warn-temperature = 70
|
||||
units = true
|
||||
format = <ramp>
|
||||
format-warn = <ramp> <label-warn>
|
||||
label-warn = %temperature-c%
|
||||
label-warn-foreground = ${colors.alert}
|
||||
ramp-0 =
|
||||
ramp-1 = %{F#ff9999}ﲲﲲ%{F-}
|
||||
ramp-2 = %{F#ff0000}ﲲﲲﲲ%{F-}
|
||||
format-underline = ${colors.primary}
|
||||
|
||||
[module/date]
|
||||
type = internal/date
|
||||
; Seconds to sleep between updates
|
||||
interval = 5.0
|
||||
; See "http://en.cppreference.com/w/cpp/io/manip/put_time" for details on how to format the date string
|
||||
; NOTE: if you want to use syntax tags here you need to use %%{...}
|
||||
date = %d/%m
|
||||
; Optional time format
|
||||
time = %H:%M
|
||||
; if `date-alt` or `time-alt` is defined, clicking
|
||||
; the module will toggle between formats
|
||||
date-alt = %A, %d %B %Y (W %V)
|
||||
time-alt = %H:%M:%S
|
||||
label = %date%%{T2} %{T-}%time%
|
||||
format-underline = ${colors.primary}
|
||||
|
||||
[module/datecal]
|
||||
type = custom/script
|
||||
exec = $XDG_CONFIG_HOME/polybar/scripts/poly-date
|
||||
tail = true
|
||||
click-left = gsimplecal
|
||||
click-right = kill -USR1 %pid%
|
||||
format-underline = ${colors.primary}
|
||||
|
||||
; display information on currently playing track, allows simple track manipulation
|
||||
; TODO: add album art display (on click?) - retrieved by playerctl metadata mpris:artUrl
|
||||
[module/music]
|
||||
type = custom/script
|
||||
exec = $XDG_CONFIG_HOME/polybar/scripts/poly-mprisdisplay
|
||||
exec-if = type $XDG_CONFIG_HOME/polybar/scripts/poly-mprisdisplay
|
||||
tail = true
|
||||
click-left = kill -USR1 %pid%
|
||||
click-right = kill -USR2 %pid%
|
||||
format-underline = ${colors.primary}
|
||||
|
||||
; display information on remaining papers to read for the upcoming week
|
||||
[module/papersdue]
|
||||
type = custom/script
|
||||
exec = $XDG_CONFIG_HOME/polybar/scripts/poly-papersdue
|
||||
exec-if = type bib-due
|
||||
tail = true
|
||||
; show list with high prio
|
||||
click-left = exist rofi-bib-due normal "opening due papers" && rofi-bib-due -p1 -u $(date --date='fri this week' +%Y-%m-%d)
|
||||
; show list with all
|
||||
click-right = exist rofi-bib-due normal "opening due papers" && rofi-bib-due -p3 -u $(date --date='fri this week' +%Y-%m-%d)
|
||||
format-prefix = " "
|
||||
interval = 120
|
||||
format-underline = ${colors.primary}
|
||||
|
||||
[module/dunstpaused]
|
||||
type = custom/script
|
||||
exec = sed -e 's/true/⏾/' -e 's/false//' /tmp/dunstpaused
|
||||
exec-if = [ -f /tmp/dunstpaused ]
|
||||
tail = true
|
||||
format-underline = ${colors.primary}
|
||||
|
||||
[module/mail]
|
||||
type = custom/script
|
||||
exec = echo "$( [ $(systemctl --user --property=ActiveState show mbsync.timer) = 'ActiveState=active' ] && echo "" || echo "" ) $(notmuch count tag:inbox and tag:unread)"
|
||||
exec-if = check-internet && [ "$(notmuch count tag:inbox and tag:unread)" -gt 0 ]
|
||||
click-right = systemctl --user start mbsync.timer
|
||||
click-left = systemctl --user stop mbsync.timer
|
||||
interval = 300.0
|
||||
format-underline = ${colors.primary}
|
||||
|
||||
[module/weather]
|
||||
type = custom/script
|
||||
exec = $XDG_CONFIG_HOME/polybar/scripts/poly-weather 'Copenhagen?m&format=%t+%C+(%p)'
|
||||
exec-if = type $XDG_CONFIG_HOME/polybar/scripts/poly-weather && check-internet
|
||||
interval = 60.0
|
||||
; format-background = ${colors.primary}
|
||||
; format-foreground = ${colors.background}
|
||||
format-underline = ${colors.primary}
|
||||
|
||||
; displays a small pomodoro timer
|
||||
[module/pomo]
|
||||
type = custom/script
|
||||
exec = $XDG_CONFIG_HOME/polybar/scripts/poly-pomo
|
||||
exec-if = exist pomo normal "pomodoro timer"
|
||||
format-underline = ${colors.primary}
|
||||
; pause timer
|
||||
click-left = $XDG_CONFIG_HOME/polybar/scripts/poly-pomo toggle
|
||||
; restart timer
|
||||
click-right = $XDG_CONFIG_HOME/polybar/scripts/poly-pomo restart
|
||||
tail = true
|
||||
|
||||
; display unified available packages for update on arch from repos/aur
|
||||
; uses pacman-contrib/checkupdates if available to avoid partial arch upgrades
|
||||
[module/archupdates]
|
||||
type = custom/script
|
||||
exec = $XDG_CONFIG_HOME/polybar/scripts/poly-archupdates
|
||||
exec-if = type $XDG_CONFIG_HOME/polybar/scripts/poly-archupdates && check-internet
|
||||
interval = 600
|
||||
format = <label>
|
||||
format-prefix = " "
|
||||
; format-foreground = ${colors.primary}
|
||||
format-underline = ${colors.primary}
|
||||
|
||||
[module/networkspeed]
|
||||
type = custom/script
|
||||
exec = $XDG_CONFIG_HOME/polybar/scripts/poly-networkspeed
|
||||
exec-if = type $XDG_CONFIG_HOME/polybar/scripts/poly-networkspeed && check-internet
|
||||
tail = true
|
||||
format-underline = ${colors.primary}
|
||||
|
||||
[module/volume]
|
||||
type = internal/pulseaudio
|
||||
; Available tags:
|
||||
; <label-volume> (default)
|
||||
; <ramp-volume>
|
||||
; <bar-volume>
|
||||
format-volume = <ramp-volume>
|
||||
format-underline = ${colors.primary}
|
||||
|
||||
; Use PA_VOLUME_UI_MAX (~153%) if true, or PA_VOLUME_NORM (100%) if false
|
||||
use-ui-max = false
|
||||
|
||||
label-muted = ﱝ
|
||||
label-muted-foreground = ${colors.foreground-alt}
|
||||
|
||||
; Only applies if <ramp-volume> is used
|
||||
ramp-volume-0 =
|
||||
ramp-volume-1 =
|
||||
ramp-volume-2 =
|
||||
ramp-volume-3 = 墳
|
||||
|
||||
[module/backlight]
|
||||
type = internal/xbacklight
|
||||
format = <ramp><label>
|
||||
ramp-0 =
|
||||
ramp-1 =
|
||||
ramp-2 =
|
||||
ramp-3 =
|
||||
ramp-4 =
|
||||
format-underline = ${colors.primary}
|
||||
enable-scroll = true
|
||||
|
||||
[module/battery]
|
||||
type = internal/battery
|
||||
battery = BAT0
|
||||
adapter = AC
|
||||
label-charging = %percentage%%
|
||||
label-discharging = %percentage%%
|
||||
format-discharging = <ramp-capacity> <label-discharging>
|
||||
format-charging = <label-charging>
|
||||
ramp-capacity-0 =
|
||||
ramp-capacity-1 =
|
||||
ramp-capacity-2 =
|
||||
ramp-capacity-3 =
|
||||
ramp-capacity-4 =
|
||||
format-underline = ${colors.primary}
|
||||
; vim:ft=dosini
|
|
@ -1,31 +0,0 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
update_time=5
|
||||
mode=${1:-0}
|
||||
separator=' '
|
||||
short_date_string='%d/%m'"${separator}"'%H:%M'
|
||||
long_date_string='%A, %d %B %Y (CW %V)'"${separator}"'%H:%M:%S'
|
||||
|
||||
modetoggle() {
|
||||
mode=$(((mode + 1) % 2))
|
||||
}
|
||||
trap "modetoggle" USR1
|
||||
|
||||
display_date() {
|
||||
if [ "$1" = "long" ]; then
|
||||
date +"${long_date_string}"
|
||||
else
|
||||
date +"${short_date_string}"
|
||||
fi
|
||||
}
|
||||
|
||||
while true; do
|
||||
if [ $mode -eq 0 ]; then
|
||||
display_date short
|
||||
elif [ $mode -eq 1 ]; then
|
||||
display_date long
|
||||
fi
|
||||
|
||||
sleep $update_time &
|
||||
wait
|
||||
done
|
|
@ -1,47 +0,0 @@
|
|||
#!/bin/sh
|
||||
# script to echo the current playback situation
|
||||
#
|
||||
# call without args to return playing symbol or empty, depending on current playback status
|
||||
# call with 1 to return 'artist - title' metadata (verbose mode)
|
||||
# send SIGUSR2 signal to toggle pause/playing state of song (e.g. kill -USR2 %PID)
|
||||
#
|
||||
# depends on playerctl being installed
|
||||
|
||||
exist playerctl low "polybar music" || exit 1
|
||||
|
||||
mode=${1:-0}
|
||||
update_time=1
|
||||
symbol_playing=""
|
||||
symbol_paused=""
|
||||
|
||||
modetoggle() {
|
||||
mode=$(((mode + 1) % 2))
|
||||
}
|
||||
trap "modetoggle" USR1
|
||||
|
||||
playpause() {
|
||||
playerctl play-pause
|
||||
}
|
||||
trap "playpause" USR2
|
||||
|
||||
decorate() {
|
||||
if [ "$player_status" = "Playing" ]; then
|
||||
echo "${symbol_playing}$1"
|
||||
elif [ "$player_status" = "Paused" ]; then
|
||||
echo "${symbol_paused}$1"
|
||||
else
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
while true; do
|
||||
player_status=$(playerctl status 2>/dev/null)
|
||||
|
||||
if [ $mode -eq 0 ]; then
|
||||
decorate ""
|
||||
elif [ $mode -eq 1 ]; then
|
||||
decorate " $(playerctl metadata artist) - $(playerctl metadata title)"
|
||||
fi
|
||||
sleep $update_time &
|
||||
wait
|
||||
done
|
|
@ -1,83 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
INTERVAL=3
|
||||
# interfaces for desktop and laptop
|
||||
INTERFACES="enp6s0 wlp0s29u1u1 wlp56s0"
|
||||
|
||||
print_bytes() {
|
||||
if [ "$1" -eq 0 ] || [ "$1" -lt 1000 ]; then
|
||||
bytes="0"
|
||||
elif [ "$1" -lt 1000000 ]; then
|
||||
bytes="$(echo "scale=0;$1/1000" | bc -l)k"
|
||||
else
|
||||
bytes="$(echo "scale=1;$1/1000000" | bc -l)M"
|
||||
fi
|
||||
|
||||
echo "$bytes"
|
||||
}
|
||||
|
||||
print_bit() {
|
||||
if [ "$1" -eq 0 ] || [ "$1" -lt 10 ]; then
|
||||
bit="0 B"
|
||||
elif [ "$1" -lt 100 ]; then
|
||||
bit="$(echo "scale=0;$1*8" | bc -l) B"
|
||||
elif [ "$1" -lt 100000 ]; then
|
||||
bit="$(echo "scale=0;$1*8/1000" | bc -l) K"
|
||||
else
|
||||
bit="$(echo "scale=1;$1*8/1000000" | bc -l) M"
|
||||
fi
|
||||
|
||||
echo "$bit"
|
||||
}
|
||||
|
||||
declare -A bytes
|
||||
|
||||
get_initial_throughput() {
|
||||
for interface in $INTERFACES; do
|
||||
|
||||
local dir="/sys/class/net/$interface"
|
||||
if [ -d "$dir" ]; then
|
||||
bytes[past_rx_$interface]="$(cat "$dir"/statistics/rx_bytes)"
|
||||
bytes[past_tx_$interface]="$(cat "$dir"/statistics/tx_bytes)"
|
||||
fi
|
||||
|
||||
done
|
||||
}
|
||||
|
||||
get_throughput() {
|
||||
while true; do
|
||||
down=0
|
||||
up=0
|
||||
|
||||
for interface in $INTERFACES; do
|
||||
local dir="/sys/class/net/$interface"
|
||||
if [ -d "$dir" ]; then
|
||||
bytes[now_rx_$interface]="$(cat "$dir"/statistics/rx_bytes)"
|
||||
bytes[now_tx_$interface]="$(cat "$dir"/statistics/tx_bytes)"
|
||||
|
||||
bytes_down=$((((${bytes[now_rx_$interface]} - ${bytes[past_rx_$interface]})) / INTERVAL))
|
||||
bytes_up=$((((${bytes[now_tx_$interface]} - ${bytes[past_tx_$interface]})) / INTERVAL))
|
||||
|
||||
down=$(((("$down" + "$bytes_down"))))
|
||||
up=$(((("$up" + "$bytes_up"))))
|
||||
|
||||
bytes[past_rx_$interface]=${bytes[now_rx_$interface]}
|
||||
bytes[past_tx_$interface]=${bytes[now_tx_$interface]}
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$down" -gt 1000 ] || [ "$up" -gt 1000 ]; then
|
||||
echo " $(print_bytes $down) 祝$(print_bytes $up)"
|
||||
else
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# echo "Download: $(print_bytes $down) / Upload: $(print_bytes $up)"
|
||||
# echo "Download: $(print_bit $down) / Upload: $(print_bit $up)"
|
||||
|
||||
sleep $INTERVAL
|
||||
done
|
||||
}
|
||||
|
||||
get_initial_throughput
|
||||
get_throughput
|
|
@ -1,15 +0,0 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
while true; do
|
||||
all="$(bib-due -u 'fri this week' -p3 | wc -l)"
|
||||
required="$(bib-due -u 'fri this week' -p1 | wc -l)"
|
||||
|
||||
# add polybar formatting to color required readings red
|
||||
# https://github.com/polybar/polybar/wiki/Formatting#format-tags
|
||||
# TODO use xresources
|
||||
colorreq=$(xrdb -query | grep -e '\*color1:' | cut -f2)
|
||||
colorall=$(xrdb -query | grep -e '\*foreground:' | cut -f2)
|
||||
printf "%s%s%s(%s)\n" "%{F${colorall:-#000}}" "$all" "%{F${colorreq:-#d00}}" "$required"
|
||||
|
||||
sleep 120
|
||||
done
|
|
@ -1,41 +0,0 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
run_notify() {
|
||||
pomo notify &
|
||||
PID_NOTIFY="$!"
|
||||
echo "$PID_NOTIFY" >"${XDG_RUNTIME_DIR:-$HOME}"/.running-pomo.lock
|
||||
}
|
||||
|
||||
# create background notify process; close it when this process is killed
|
||||
close_notify() {
|
||||
lockfile="${XDG_RUNTIME_DIR:-$HOME}"/.running-pomo.lock
|
||||
[ -f "$lockfile" ] && kill "$(cat "$lockfile")"
|
||||
kill "$PID_NOTIFY"
|
||||
rm "${XDG_RUNTIME_DIR:-$HOME}"/.running-pomo.lock
|
||||
}
|
||||
trap close_notify EXIT
|
||||
|
||||
restart_notify() {
|
||||
close_notify
|
||||
run_notify
|
||||
}
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
run_notify
|
||||
while true; do
|
||||
display=$(pomo clock)
|
||||
# replace W (work)
|
||||
# B (break)
|
||||
# P (paused) with pomodoro symbols
|
||||
# remove seconds *except for* when 00 minutes reached
|
||||
display=$(echo "$display" | sed -e 's/--:--/ /;s/P.*$/ /;s/W/ /;s/B/ /;/00:/! { s/:[[:digit:]]\+$// }')
|
||||
echo "$display"
|
||||
sleep 1
|
||||
done
|
||||
elif [ "$1" = "toggle" ]; then
|
||||
pomo pause
|
||||
restart_notify
|
||||
elif [ "$1" = "restart" ]; then
|
||||
pomo stop
|
||||
restart_notify
|
||||
fi
|
|
@ -1,23 +0,0 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
wttr() {
|
||||
# change Paris to your default location
|
||||
request="wttr.in/${1-~Leipzig}"
|
||||
curl -s -H "Accept-Language: ${LANG%_*}" --compressed "${request}"
|
||||
}
|
||||
|
||||
wttr "$@"
|
||||
|
||||
# while true; do
|
||||
# all="$(bib-due -u 'fri this week' -p3 | wc -l)"
|
||||
# required="$(bib-due -u 'fri this week' -p1 | wc -l)"
|
||||
|
||||
# # add polybar formatting to color required readings red
|
||||
# # https://github.com/polybar/polybar/wiki/Formatting#format-tags
|
||||
# # TODO use xresources
|
||||
# colorreq=$(xrdb -query | grep -e '\*color1:' | cut -f2)
|
||||
# colorall=$(xrdb -query | grep -e '\*foreground:' | cut -f2)
|
||||
# printf "%s%s%s(%s)\n" "%{F${colorall:-#000}}" "$all" "%{F${colorreq:-#d00}}" "$required"
|
||||
|
||||
# sleep 120
|
||||
# done
|
|
@ -1,20 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# force start or restart (all) polybar instances
|
||||
# if ipc is enabled, can be replaced with `polybar-msg cmd restart`, provided polybar is not stuck
|
||||
|
||||
# Terminate already running bar instances
|
||||
killall -q polybar
|
||||
|
||||
# Wait until the processes have been shut down
|
||||
while pgrep -u $UID -x polybar >/dev/null; do sleep 1; done
|
||||
|
||||
startbars() {
|
||||
for bar in "$@"; do
|
||||
local logfile="/tmp/polybar-$bar.log"
|
||||
printf -- "---\npolybar: %s starting...\n---\n" "$bar" | tee -a "$logfile"
|
||||
polybar "$bar" >>"$logfile" 2>&1 &
|
||||
done
|
||||
}
|
||||
|
||||
startbars "$@"
|
||||
echo "Polybars launched..."
|
|
@ -1 +0,0 @@
|
|||
../share/pomo-app/pomo.sh
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 68a8e26a46f8516ee73b429c153a1fc7a4a2c300
|
|
@ -1,92 +0,0 @@
|
|||
# Polybar module
|
||||
|
||||
[polybar](https://polybar.github.io/) - a fast and easy-to-use statusbar
|
||||
|
||||
[[_TOC_]]
|
||||
|
||||
## Polybar look
|
||||
|
||||
minimal look:
|
||||
|
||||
![minimal](.assets/polybar/minimal.png)
|
||||
|
||||
Active i3 workspaces are displayed left with current workspace highlighted, and any active i3 modes. The center contains information on the currently playing song, displaying notes if something is playing, date and time, and upcoming bib readings from the library. The right contains system information and the task tray.
|
||||
|
||||
with network activity:
|
||||
|
||||
![network](.assets/polybar/network.png)
|
||||
|
||||
full-load and temperature warning:
|
||||
|
||||
![full](.assets/polybar/full.png)
|
||||
|
||||
In general, the bar's colors are derived from the colors defined in xresources. It follows the base16 color template, as does every module in these dotfiles. That means the bar can be quickly re-themed using base16 color themes and the process can be automated (e.g. with styler).
|
||||
|
||||
## i3 workspaces
|
||||
|
||||
![normal](.assets/polybar/i3-normal.png) -- focus on workspace 4
|
||||
|
||||
The i3 workspaces module is pretty simple and self-explanatory. It shows all existing workspaces, and highlights the one that is currently active. It also highlights any workspaces on which an event took place.
|
||||
|
||||
![highlight](.assets/polybar/i3-highlight.png) -- focus on workspace 2, workspace 1 highlighted
|
||||
|
||||
Additionally, if an i3 mode is active, it will be displayed next to the workspaces in a stark color to notice the mode being active. This is slowly being deprecated in favor of sxhkd modes -- e.g. media mode is now displayed by the sxhkd module instead. The only remaining mode is resize for the moment.
|
||||
|
||||
![mode](.assets/polybar/i3-mode.png) -- focus on workspace 3, 'Media' mode active
|
||||
|
||||
Workspaces can be cycled with the mouse-wheel when hovering over the module, or can be invoked by clicking on the icons.
|
||||
|
||||
## sxhkd modes
|
||||
|
||||
The current mode of the desktop is being passed from sxhkd to polybar for display.
|
||||
Its look is based on the i3 workspace mode display, though by default they appear to the right of the workspaces.
|
||||
|
||||
![sxhkd mode](.assets/polybar/sxhkd_mode.png) -- academia sxhkd mode activated
|
||||
|
||||
## Current track information
|
||||
|
||||
By default, the track information panel is very minimal. It simply displays a note when something is currently playing, a pause symbol when the current track is pause, and nothing at all when no track is currently available. (no media player open, all tracks stopped, etc.)
|
||||
|
||||
When clicked, the track metadata is revealed, displaying track artist and title. Another click toggles it off again.
|
||||
|
||||
![mpris](.assets/polybar/mpris.png)
|
||||
|
||||
When right-clicked, the current track can be toggled between playing and paused.
|
||||
|
||||
The `poly-mprisdisplay` script implementation requires `playerctl` available on the system to be run. It will return with an error message if the binary is not found. Symbols used can be easily customized in the script.
|
||||
|
||||
## Date
|
||||
|
||||
The standard polybar date display. Displays current date (DD/MM) and current time (24-hours) by default. On click, toggles to an expanded date display with current weekday and current week of the year.
|
||||
|
||||
![clock](.assets/polybar/clock.png)
|
||||
|
||||
![extended clock](.assets/polybar/clock_alt.png)
|
||||
|
||||
## Upcoming Bibtex readings
|
||||
|
||||
Depends on the [`bibtex`](bibtex/) module being installed, more specifically:
|
||||
|
||||
* the `bib-due` script accessible as a program
|
||||
* a `$BIBFILE` environment variable pointing to the bibtex library (or at least, the relevant library of the system)
|
||||
* optionally: `rofi` (or `dmenu`) to enable listing of readings on click
|
||||
|
||||
Displays the library readings remaining for the week in simple numerical fashion. On click invokes the full `bib_due` script to show further information on the upcoming readings, requiring either `dmenu` or `rofi` to display them.
|
||||
|
||||
## System information
|
||||
|
||||
Contains various system-relevant details.
|
||||
|
||||
![system info](.assets/polybar/system.png)
|
||||
|
||||
If the network has activity, it shows upload and download speeds (dynamically switching between displaying Kb/s, Mb/s). The script `poly-networkspeed` as of now uses hard-coded network interface names. If network interfaces have a different name, this will need to be adjusted.
|
||||
|
||||
If updates for arch packages are available (from repositories or aur) it displays the number of available updates. The script `poly-archupdates` requires `yay` to be available. If checkupdates is available it will use this to check for repo packages, which can avoid partial arch updates in rare circumstances. (contained in `pacman-contrib` package)
|
||||
|
||||
The volume module simply displays the current pulseaudio volume as a ramped version of the volume symbol. On click it toggles mute and un-mute.
|
||||
|
||||
If xbacklight is available, the current display brightness is displayed as a symbol between a moon (dark) and a sun (bright).
|
||||
|
||||
If a battery is available, it will display its current status, percentage, and whether it is charging.
|
||||
|
||||
The cpu load is displayed as a simple vertical bar, changing color at specific intervals to be more noticeable. When the cpu gets warm, a temperature warning will be displayed, along with current numeric temperature value (in °C). The correct sensor may have to be changed in the polybar config file; as well as useful limits for the display of temperature information.
|
112
qutebrowser/.local/share/qutebrowser/userscripts/open_download
Executable file
|
@ -0,0 +1,112 @@
|
|||
#!/usr/bin/env bash
|
||||
# Both standalone script and qutebrowser userscript that opens a rofi menu with
|
||||
# all files from the download directory and opens the selected file. It works
|
||||
# both as a userscript and a standalone script that is called from outside of
|
||||
# qutebrowser.
|
||||
#
|
||||
# Suggested keybinding (for "show downloads"):
|
||||
# spawn --userscript ~/.config/qutebrowser/open_download
|
||||
# sd
|
||||
#
|
||||
# Requirements:
|
||||
# - rofi (in a recent version), or bemenu
|
||||
# - xdg-open and xdg-mime
|
||||
# - You should configure qutebrowser to download files to a single directory
|
||||
# - It comes in handy if you enable downloads.remove_finished. If you want to
|
||||
# see the recent downloads, just press "sd".
|
||||
#
|
||||
# Thorsten Wißmann, 2015 (thorsten` on Libera Chat)
|
||||
# Refactored to work with bemenu by Marty Oehme, 2021 (@martyo@matrix.org on Matrix)
|
||||
# Any feedback is welcome!
|
||||
|
||||
set -e
|
||||
|
||||
# open a file from the download directory using rofi
|
||||
DOWNLOAD_DIR=${DOWNLOAD_DIR:-${QUTE_DOWNLOAD_DIR:-$HOME/downloads}}
|
||||
# the name of the rofi-like command
|
||||
if [ -n "$ROFI_CMD" ]; then
|
||||
:
|
||||
elif command -v rofi >/dev/null 2>&1; then
|
||||
ROFI_CMD="rofi"
|
||||
ROFI_ARGS=${ROFI_ARGS:-(
|
||||
-monitor -2 # place above window
|
||||
-location 6 # aligned at the bottom
|
||||
-width 100 # use full window width
|
||||
-i
|
||||
-no-custom
|
||||
-format i # make rofi return the index
|
||||
-l 10
|
||||
-p 'Open download:' -dmenu
|
||||
)}
|
||||
elif command -v bemenu >/dev/null 2>&1; then
|
||||
ROFI_CMD="bemenu"
|
||||
ROFI_ARGS="${ROFI_ARGS:--il 10}"
|
||||
fi
|
||||
|
||||
msg() {
|
||||
local cmd="$1"
|
||||
shift
|
||||
local msg="$*"
|
||||
if [ -z "$QUTE_FIFO" ]; then
|
||||
echo "$cmd: $msg" >&2
|
||||
else
|
||||
echo "message-$cmd '${msg//\'/\\\'}'" >>"$QUTE_FIFO"
|
||||
fi
|
||||
}
|
||||
die() {
|
||||
msg error "$*"
|
||||
if [ -n "$QUTE_FIFO" ]; then
|
||||
# when run as a userscript, the above error message already informs the
|
||||
# user about the failure, and no additional "userscript exited with status
|
||||
# 1" is needed.
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
if ! [ -d "$DOWNLOAD_DIR" ]; then
|
||||
die "Download directory »$DOWNLOAD_DIR« not found!"
|
||||
fi
|
||||
if ! command -v "${ROFI_CMD}" >/dev/null; then
|
||||
die "Rofi command »${ROFI_CMD}« not found in PATH!"
|
||||
fi
|
||||
|
||||
crop-first-column() {
|
||||
cut -d' ' -f2
|
||||
}
|
||||
|
||||
ls-files() {
|
||||
# add the slash at the end of the download dir enforces to follow the
|
||||
# symlink, if the DOWNLOAD_DIR itself is a symlink
|
||||
# sort by newest
|
||||
find "${DOWNLOAD_DIR}/" -maxdepth 1 -type f -printf "%T+ %f\n" | sort -r
|
||||
}
|
||||
|
||||
mapfile -t entries < <(ls-files)
|
||||
|
||||
# we need to manually check that there are items, because rofi doesn't show up
|
||||
# if there are no items and -no-custom is passed to rofi.
|
||||
if [ "${#entries[@]}" -eq 0 ]; then
|
||||
die "Download directory »${DOWNLOAD_DIR}« empty"
|
||||
fi
|
||||
|
||||
line=$(printf '%s\n' "${entries[@]}" |
|
||||
crop-first-column |
|
||||
$ROFI_CMD "${ROFI_ARGS[@]}") || true
|
||||
if [ -z "$line" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
msg info "file is $line"
|
||||
path="$DOWNLOAD_DIR/$line"
|
||||
filetype=$(xdg-mime query filetype "$path")
|
||||
application=$(xdg-mime query default "$filetype")
|
||||
|
||||
if [ -z "$application" ]; then
|
||||
die "Do not know how to open »$line« of type $filetype"
|
||||
fi
|
||||
|
||||
msg info "Opening »$line« (of type $filetype) with ${application%.desktop}"
|
||||
|
||||
xdg-open "$path" &
|
|
@ -1,73 +0,0 @@
|
|||
#!/usr/bin/env sh
|
||||
# Custom key bindings do not work in script-mode, use a wrapper instead
|
||||
# Script at .local/bin/rofi-gopass
|
||||
OLD_GOPASS_GPG_OPTS="$GOPASS_GPG_OPTS"
|
||||
|
||||
break_out() {
|
||||
if [ "$1" -eq 1 ]; then
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
has_xclip() {
|
||||
if (type xclip >/dev/null 2>&1); then
|
||||
printf "Your system does not appear to support pasting to clipboard via xclip."
|
||||
exit 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
to_clipboard() {
|
||||
has_xclip
|
||||
value="$(gopass show "$1" "$2")"
|
||||
printf "%s" "$value" | xclip -selection clipboard
|
||||
notify-send "Password" "Copied pass for $2 to clipboard.\n"
|
||||
exit
|
||||
}
|
||||
|
||||
show_secrets() {
|
||||
printf "%s" "$(gopass ls -fo)"
|
||||
}
|
||||
|
||||
# get_key() {
|
||||
# return echo "$*" | gpg --passphrase-fd 0 --pinentry-mode loopback --batch --export-secret-keys 2>&1
|
||||
# }
|
||||
|
||||
# check_gpg_key() {
|
||||
# check_keyphrase=$(echo "$*" | gpg --passphrase-fd 0 --pinentry-mode loopback --batch --export-secret-keys 2>&1)
|
||||
# if echo "$check_keyphrase" | grep -q -e '.*<.*@.*>'; then
|
||||
# printf "\x00prompt\x1fLogin> \n"
|
||||
# show_secrets
|
||||
# elif echo "$check_keyphrase" | grep -q -e "can't get input" - || echo "$check_keyphrase" | grep -q -e "error receiving key" -; then
|
||||
# printf "\x00prompt\x1fMaster Passphrase> \n"
|
||||
# printf "%s" "$check_keyphrase"
|
||||
# else
|
||||
# echo "passphrase successfully input, $check_keyphrase"
|
||||
# fi
|
||||
# }
|
||||
|
||||
# has_selected_login() {
|
||||
# echo "this is passed to ls: $*"
|
||||
# echo "grep reveals: $(gopass ls -f | grep -e "$*" -)"
|
||||
# if grep "$(gopass ls -f | grep -q -e "$*" -)"; then
|
||||
# echo "ls found something"
|
||||
# true
|
||||
# else
|
||||
# false
|
||||
# fi
|
||||
# }
|
||||
|
||||
# if [ -z "$*" ]; then
|
||||
# check_gpg_key "$*"
|
||||
# elif has_selected_login "$*"; then
|
||||
# echo "has selected login $*"
|
||||
# else
|
||||
# check_gpg_key "$*"
|
||||
# fi
|
||||
|
||||
main() {
|
||||
show_secrets
|
||||
}
|
||||
|
||||
main
|
|
@ -1,92 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
#### Environment Variable Options ###
|
||||
# Interface options
|
||||
# ROFI_POWERMENU_SHOW_ICONS=1
|
||||
# ROFI_POWERMENU_SHOW_TEXT=0
|
||||
# ROFI_POWERMENU_SHOW_UPTIME=1
|
||||
# ROFI_POWERMENU_SEARCHABLE=0
|
||||
# Command options
|
||||
# ROFI_POWERMENU_SHUTDOWN_CMD=""
|
||||
# ROFI_POWERMENU_REBOOT_CMD=""
|
||||
# ROFI_POWERMENU_LOCKSCREEN_CMD=""
|
||||
# ROFI_POWERMENU_LOGOUT_CMD=""
|
||||
# ROFI_POWERMENU_SUSPEND_CMD=""
|
||||
|
||||
#### Menu Options ###
|
||||
if [ "${ROFI_POWERMENU_SHOW_TEXT:-0}" -eq 0 ] && [ "${ROFI_POWERMENU_SHOW_ICONS:-1}" -eq 0 ]; then
|
||||
echo "You disabled both text and icons for rofi-powermenu, nothing can be shown."
|
||||
exit 1
|
||||
elif [ "${ROFI_POWERMENU_SHOW_ICONS:-1}" -eq 1 ]; then
|
||||
power_off_btn=""
|
||||
reboot_btn=""
|
||||
lock_btn=""
|
||||
suspend_btn="鈴"
|
||||
logout_btn=""
|
||||
fi
|
||||
if [ "${ROFI_POWERMENU_SHOW_TEXT:-0}" -eq 1 ]; then
|
||||
power_off_btn="${power_off_btn} Shut Down"
|
||||
reboot_btn="${reboot_btn} Restart"
|
||||
lock_btn="${lock_btn} Lock Screen"
|
||||
suspend_btn="${suspend_btn} Suspend"
|
||||
logout_btn="${logout_btn} Log Out"
|
||||
fi
|
||||
# FIXME does not hide pango comments anymore for some reason
|
||||
if [ "${ROFI_POWERMENU_SEARCHABLE:-1}" -eq 1 ]; then
|
||||
power_off_btn="${power_off_btn} <!-- Shutdown Poweroff -->"
|
||||
reboot_btn="${reboot_btn} <!-- Reboot Restart -->"
|
||||
lock_btn="${lock_btn} <!-- Lockscreen -->"
|
||||
suspend_btn="${suspend_btn} <!-- Suspend Sleep -->"
|
||||
logout_btn="${logout_btn} <!-- Exit X Logout -->"
|
||||
fi
|
||||
|
||||
# grep -a since it assumes with our nullcodes etc that this is a binary file
|
||||
# grep -o to only leave the things we grep for
|
||||
case "$*" in
|
||||
"Shutdown" | "$power_off_btn")
|
||||
if [ -n "$ROFI_POWERMENU_SHUTDOWN_CMD" ]; then eval "$ROFI_POWERMENU_SHUTDOWN_CMD"; else
|
||||
systemctl poweroff
|
||||
fi
|
||||
;;
|
||||
"Reboot" | "$reboot_btn")
|
||||
if [ -n "$ROFI_POWERMENU_REBOOT_CMD" ]; then eval "$ROFI_POWERMENU_REBOOT_CMD"; else
|
||||
systemctl reboot
|
||||
fi
|
||||
;;
|
||||
"Lockscreen" | "$lock_btn")
|
||||
# Completely detach from the parent script
|
||||
# If in/outputs are not redirected, rofi will wait for the forked process as well.
|
||||
if [ -n "$ROFI_POWERMENU_LOCKSCREEN_CMD" ]; then eval "$ROFI_POWERMENU_LOCKSCREEN_CMD"; else
|
||||
lockscreen rofi </dev/null >/dev/null 2>/dev/null &
|
||||
fi
|
||||
;;
|
||||
"Logout" | "$logout_btn")
|
||||
if [ -n "$ROFI_POWERMENU_LOGOUT_CMD" ]; then eval "$ROFI_POWERMENU_LOGOUT_CMD"; else
|
||||
i3-msg exit
|
||||
fi
|
||||
;;
|
||||
"Suspend" | "$suspend_btn")
|
||||
if [ -n "$ROFI_POWERMENU_SUSPEND_CMD" ]; then eval "$ROFI_POWERMENU_SUSPEND_CMD"; else
|
||||
lockscreen rofi </dev/null >/dev/null 2>/dev/null &
|
||||
systemctl hibernate
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ "${ROFI_POWERMENU_SHOW_UPTIME:-1}" -eq 1 ]; then
|
||||
prompt="Uptime: $(uptime -p | sed -e 's/up //g')"
|
||||
else
|
||||
prompt="Power"
|
||||
fi
|
||||
|
||||
if [ -z "$*" ]; then
|
||||
printf "\0prompt\x1f%s\n" "$prompt"
|
||||
printf "\0markup\x1ftrue\n"
|
||||
|
||||
printf "%s\n" "$power_off_btn"
|
||||
printf "%s\n" "$reboot_btn"
|
||||
printf "%s\n" "$lock_btn"
|
||||
printf "%s\n" "$suspend_btn"
|
||||
printf "%s\n" "$logout_btn"
|
||||
printf "\0markup-rows\x1ftrue\n"
|
||||
fi
|
|
@ -1,53 +0,0 @@
|
|||
#!/usr/bin/env sh
|
||||
# Brightness control script using xbacklight
|
||||
# Will use notify-send to create brightness notifications, if dunst is used
|
||||
# or the notification daemon supports tag stacks, will automatically update
|
||||
# the same notifications and not create new ones.
|
||||
#
|
||||
# inspired from https://gist.github.com/Blaradox/030f06d165a82583ae817ee954438f2e
|
||||
|
||||
usage() {
|
||||
echo "usage: control-brightness up|down [step], where step can be any int value
|
||||
or: control-brightness set target, where target can be an int value 0-100"
|
||||
}
|
||||
|
||||
direction=$1
|
||||
step=${2:-10}
|
||||
|
||||
get_brightness() {
|
||||
xbacklight -get | cut -d. -f1
|
||||
}
|
||||
|
||||
send_notification() {
|
||||
icon="preferences-system-brightness-lock"
|
||||
brightness=$(get_brightness)
|
||||
if type dunstify 1>/dev/null 2>/dev/null; then
|
||||
notcmd="dunstify -h string:x-dunst-stack-tag:brightness"
|
||||
else
|
||||
notcmd="notify-send -h string:x-dunst-stack-tag:brightness"
|
||||
fi
|
||||
$notcmd -a "changeVolume" -u low -i "$icon" \
|
||||
-h int:value:"$brightness" "Brightness: $brightness%"
|
||||
}
|
||||
|
||||
case $direction in
|
||||
up)
|
||||
xbacklight -inc "$step"
|
||||
send_notification
|
||||
;;
|
||||
down)
|
||||
xbacklight -dec "$step"
|
||||
send_notification
|
||||
;;
|
||||
set)
|
||||
if [ -z "$step" ]; then
|
||||
echo "set option requires target brightness to be specified."
|
||||
return 1
|
||||
fi
|
||||
xbacklight -set "$step"
|
||||
send_notification
|
||||
;;
|
||||
*)
|
||||
echo "usage: control-brightness up|down [step], where step can be any int value"
|
||||
;;
|
||||
esac
|
|
@ -1,97 +0,0 @@
|
|||
#!/usr/bin/env sh
|
||||
# change Volume in an easy and unified way
|
||||
|
||||
direction=$1
|
||||
step=${2:-5dB}
|
||||
|
||||
# amixer channel to target
|
||||
amixer_quiet() {
|
||||
amixer -c 0 "$@" >/dev/null
|
||||
}
|
||||
amixer_noisy="amixer -c 0 "
|
||||
|
||||
# Query amixer for the current volume
|
||||
get_volume() {
|
||||
$amixer_noisy get Master | tail -1 | awk '{print $4}' | sed 's/[^0-9]*//g'
|
||||
}
|
||||
|
||||
# query amixer for mute state (off=muted)
|
||||
get_mute() {
|
||||
$amixer_noisy get Master | tail -1 | awk '{print $6}' | sed 's/[^a-z]*//g'
|
||||
}
|
||||
|
||||
set_volume() {
|
||||
# Change the volume using alsa(might differ if you use pulseaudio)
|
||||
amixer_quiet set Master "$@" >/dev/null
|
||||
|
||||
# Play the volume changed sound
|
||||
# -- this is *extremely* laggy (>8s) on my system, no idea why and no time to find out
|
||||
# canberra-gtk-play -i audio-volume-change -d "changeVolume"
|
||||
}
|
||||
|
||||
# set mute state (off=mute)
|
||||
set_mute() {
|
||||
[ "$(get_mute)" = "on" ] && toggleto=off || toggleto=on
|
||||
if [ "$1" = 'off' ]; then
|
||||
amixer_quiet set Master mute
|
||||
elif [ "$1" = 'on' ]; then
|
||||
amixer_quiet set Master unmute
|
||||
# the following is needed, see https://superuser.com/questions/805525/why-is-unmute-not-working-with-amixer-command
|
||||
amixer_quiet set Speaker unmute
|
||||
amixer_quiet set Headphone unmute
|
||||
else
|
||||
amixer_quiet set Master "$toggleto"
|
||||
amixer_quiet set Speaker "$toggleto"
|
||||
amixer_quiet set Headphone "$toggleto"
|
||||
fi
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "control-volume up|down [step], with step any int value
|
||||
or: control-brightness set [target], with target any int value 0-100"
|
||||
}
|
||||
|
||||
send_notification() {
|
||||
if type dunstify 1>/dev/null 2>/dev/null; then
|
||||
notcmd="dunstify -h string:x-dunst-stack-tag:brightness"
|
||||
else
|
||||
notcmd="notify-send -h string:x-dunst-stack-tag:brightness"
|
||||
fi
|
||||
|
||||
vol="$(get_volume)"
|
||||
|
||||
if [ "$vol" -eq 0 ] || [ "$(get_mute)" = "off" ]; then
|
||||
# Show the sound muted notification
|
||||
$notcmd -a "changeVolume" -u low -i audio-volume-muted "Volume muted"
|
||||
else
|
||||
# Show the volume notification
|
||||
$notcmd -a "changeVolume" -u low -i audio-volume-high \
|
||||
-h int:value:"$vol" "Volume: $vol%"
|
||||
fi
|
||||
}
|
||||
|
||||
case $direction in
|
||||
up)
|
||||
set_volume "${step}+"
|
||||
;;
|
||||
down)
|
||||
set_volume "${step}-"
|
||||
;;
|
||||
mute)
|
||||
set_mute "$step"
|
||||
;;
|
||||
mutetoggle)
|
||||
set_mute
|
||||
;;
|
||||
set)
|
||||
if [ -z "$step" ]; then
|
||||
echo "set option requires target brightness to be specified."
|
||||
return 1
|
||||
fi
|
||||
set_volume "$step"
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
send_notification
|
|
@ -1,12 +1,23 @@
|
|||
#!/usr/bin/env sh
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Example locker script -- demonstrates how to use the --transfer-sleep-lock
|
||||
# option with i3lock's forking mode to delay sleep until the screen is locked.
|
||||
# locker script -- makes sure that x does not give up the lock easily (using i3lock)
|
||||
# simply locks the screen on wayland (using waylock)
|
||||
|
||||
## CONFIGURATION ##############################################################
|
||||
|
||||
is_wayland() {
|
||||
# alternative $(</proc/self/sessionid), see
|
||||
# https://stackoverflow.com/questions/3214935/can-a-bash-script-tell-if-its-being-run-via-cron
|
||||
if loginctl show-session "$(loginctl show-user "$(whoami)" -p Display --value)" -p Type --value | grep -q wayland; then
|
||||
true
|
||||
else
|
||||
false
|
||||
fi
|
||||
}
|
||||
|
||||
# Options to pass to i3lock
|
||||
i3lock_options="-e -f -c 1d2021"
|
||||
waylock_options="--init-color #223344 --input-color #224444 --fail-color #554444"
|
||||
|
||||
# Run before starting the locker
|
||||
pre_lock() {
|
||||
|
@ -26,18 +37,21 @@ post_lock() {
|
|||
|
||||
pre_lock
|
||||
|
||||
# We set a trap to kill the locker if we get killed, then start the locker and
|
||||
if is_wayland; then
|
||||
# shellcheck disable=SC2086
|
||||
waylock $waylock_options
|
||||
elif [ -e "/dev/fd/${XSS_SLEEP_LOCK_FD:--1}" ]; then
|
||||
# On X, we set a trap to kill the locker if we get killed, then start the locker and
|
||||
# wait for it to exit. The waiting is not that straightforward when the locker
|
||||
# forks, so we use this polling only if we have a sleep lock to deal with.
|
||||
if [ -e /dev/fd/${XSS_SLEEP_LOCK_FD:--1} ]; then
|
||||
kill_i3lock() {
|
||||
pkill -xu $EUID "$@" i3lock
|
||||
pkill -xu "$EUID" "$@" i3lock
|
||||
}
|
||||
|
||||
trap kill_i3lock TERM INT
|
||||
|
||||
# we have to make sure the locker does not inherit a copy of the lock fd
|
||||
i3lock $i3lock_options {XSS_SLEEP_LOCK_FD}<&-
|
||||
i3lock "$i3lock_options" {XSS_SLEEP_LOCK_FD}<&-
|
||||
|
||||
# now close our fd (only remaining copy) to indicate we're ready to sleep
|
||||
exec {XSS_SLEEP_LOCK_FD}<&-
|
||||
|
@ -47,7 +61,7 @@ if [ -e /dev/fd/${XSS_SLEEP_LOCK_FD:--1} ]; then
|
|||
done
|
||||
else
|
||||
trap 'kill %%' TERM INT
|
||||
i3lock -n $i3lock_options &
|
||||
i3lock -n "$i3lock_options" &
|
||||
wait
|
||||
fi
|
||||
|
||||
|
|
84
scripts/.local/bin/powermenu
Executable file
|
@ -0,0 +1,84 @@
|
|||
#!/usr/bin/env bash
|
||||
# A simple powermenu listing.
|
||||
# Uses bemenu to display the powermenu on X11, Wayland and terminal.
|
||||
|
||||
#### Environment Variable Options ###
|
||||
# Interface options
|
||||
# POWERMENU_SHOW_ICONS=1
|
||||
# POWERMENU_SHOW_TEXT=1
|
||||
# POWERMENU_SHOW_UPTIME=1
|
||||
# Command options
|
||||
# POWERMENU_SHUTDOWN_CMD=""
|
||||
# POWERMENU_REBOOT_CMD=""
|
||||
# POWERMENU_LOCKSCREEN_CMD=""
|
||||
# POWERMENU_LOGOUT_CMD=""
|
||||
# POWERMENU_SUSPEND_CMD=""
|
||||
# Command chooser options
|
||||
# POWERMENU_PICKER_CMD=""
|
||||
# POWERMENU_PICKER_OPTS=""
|
||||
|
||||
#### Menu Options ###
|
||||
if [ "${POWERMENU_SHOW_TEXT:-0}" -eq 0 ] && [ "${POWERMENU_SHOW_ICONS:-1}" -eq 0 ]; then
|
||||
echo "You disabled both text and icons for rofi-powermenu, nothing can be shown."
|
||||
exit 1
|
||||
elif [ "${POWERMENU_SHOW_ICONS:-1}" -eq 1 ]; then
|
||||
power_off_btn=""
|
||||
reboot_btn=""
|
||||
lock_btn=""
|
||||
suspend_btn="鈴"
|
||||
logout_btn=""
|
||||
fi
|
||||
if [ "${POWERMENU_SHOW_TEXT:-1}" -eq 1 ]; then
|
||||
power_off_btn="${power_off_btn} Shut Down"
|
||||
reboot_btn="${reboot_btn} Restart"
|
||||
lock_btn="${lock_btn} Lock Screen"
|
||||
suspend_btn="${suspend_btn} Suspend"
|
||||
logout_btn="${logout_btn} Log Out"
|
||||
fi
|
||||
|
||||
## SET PROMPT
|
||||
if [ "${POWERMENU_SHOW_UPTIME:-1}" -eq 1 ]; then
|
||||
prompt="Uptime $(uptime -p | sed -e 's/up //g') >"
|
||||
else
|
||||
prompt="Power >"
|
||||
fi
|
||||
|
||||
selector_program="${POWERMENU_PICKER_CMD:-bemenu}"
|
||||
selector_opts="${POWERMENU_PICKER_OPTS:--i}"
|
||||
|
||||
menu=$(printf "%s\n" "$lock_btn" "$suspend_btn" "$power_off_btn" "$reboot_btn" "$logout_btn")
|
||||
# shellcheck disable=SC2086
|
||||
result=$(printf "%s" "$menu" | $selector_program $selector_opts --prompt "$prompt")
|
||||
|
||||
# grep -a since it assumes with our nullcodes etc that this is a binary file
|
||||
# grep -o to only leave the things we grep for
|
||||
case "$result" in
|
||||
"Shutdown" | "$power_off_btn")
|
||||
if [ -n "$POWERMENU_SHUTDOWN_CMD" ]; then eval "$POWERMENU_SHUTDOWN_CMD"; else
|
||||
systemctl poweroff
|
||||
fi
|
||||
;;
|
||||
"Reboot" | "$reboot_btn")
|
||||
if [ -n "$POWERMENU_REBOOT_CMD" ]; then eval "$POWERMENU_REBOOT_CMD"; else
|
||||
systemctl reboot
|
||||
fi
|
||||
;;
|
||||
"Lockscreen" | "$lock_btn")
|
||||
# Completely detach from the parent script
|
||||
# If in/outputs are not redirected, rofi will wait for the forked process as well.
|
||||
if [ -n "$POWERMENU_LOCKSCREEN_CMD" ]; then eval "$POWERMENU_LOCKSCREEN_CMD"; else
|
||||
lockscreen
|
||||
fi
|
||||
;;
|
||||
"Logout" | "$logout_btn")
|
||||
if [ -n "$POWERMENU_LOGOUT_CMD" ]; then eval "$POWERMENU_LOGOUT_CMD"; else
|
||||
command -v i3 >/dev/null 2>&1 && i3-msg exit
|
||||
command -v riverctl >/dev/null 2>&1 && riverctl exit
|
||||
fi
|
||||
;;
|
||||
"Suspend" | "$suspend_btn")
|
||||
if [ -n "$POWERMENU_SUSPEND_CMD" ]; then eval "$POWERMENU_SUSPEND_CMD"; else
|
||||
systemctl hibernate
|
||||
fi
|
||||
;;
|
||||
esac
|
|
@ -4,28 +4,75 @@
|
|||
#
|
||||
# Examples:
|
||||
# `sharefile`
|
||||
# calling without arguments allows you to first select a folder and then
|
||||
# Calling without arguments allows you to first select a folder and then
|
||||
# a file from the folder to share.
|
||||
# `sharefile ~/my-folder/`
|
||||
# Calling with a folder as argument restricts the file selection to files within.
|
||||
# `sharefile ~/my-file.zip`
|
||||
# calling with a file as argument automatically uploads the file and copies
|
||||
# Calling with a file as argument automatically uploads the file and copies
|
||||
# share link to clipboard.
|
||||
# When called with a folder as argument allows you to select file within, uploads it and copies share link.
|
||||
# `screenshot | sharefile -`
|
||||
# Calling with a dash as argument gets the file from stdin instead.
|
||||
# Be aware that this currently only works for files not folders.
|
||||
|
||||
OXO_URL="https://0x0.st"
|
||||
|
||||
folderpicker() {
|
||||
selected=$(find "${1:-$HOME}" -type d | fzf)
|
||||
# use fd if available
|
||||
if command -v fd >/dev/null 2>&1; then
|
||||
sharefile_fd_cmd="fd"
|
||||
else
|
||||
sharefile_fd_cmd="find"
|
||||
fi
|
||||
|
||||
main() {
|
||||
if [ $# -eq 0 ]; then
|
||||
foldpick=$(picker d "")
|
||||
exit_check $?
|
||||
picked=$(picker f "$foldpick")
|
||||
elif [ "$1" = "-" ]; then
|
||||
while read -r file; do
|
||||
picked="$file"
|
||||
done <"/dev/stdin"
|
||||
elif [ -f "$1" ]; then
|
||||
picked="$1"
|
||||
elif [ -d "$1" ]; then
|
||||
picked=$(picker f "$1")
|
||||
else
|
||||
printf "Please only provide a folder or file as the optional argument to sharefile." >&2
|
||||
exit 1
|
||||
fi
|
||||
exit_check $?
|
||||
|
||||
url=$(file_to_oxo "$picked")
|
||||
echo "$url"
|
||||
url_to_clipboard "$url"
|
||||
if command -v notify-send >/dev/null 2>&1; then
|
||||
notify-send "Upload finished" "URL: $url"
|
||||
fi
|
||||
exit
|
||||
}
|
||||
|
||||
picker() {
|
||||
if [ "$sharefile_fd_cmd" = "fd" ]; then
|
||||
selected=$(fd "$SHAREFILE_FD_OPTS" --type "${1:-f}" . "${2:-$HOME}" | fzf)
|
||||
elif [ "$sharefile_fd_cmd" = "find" ]; then
|
||||
selected=$(find "$SHAREFILE_FD_OPTS" "${2:-$HOME}" -type "$1" | fzf)
|
||||
fi
|
||||
[ "$?" -eq 130 ] && exit 130
|
||||
echo "$selected"
|
||||
}
|
||||
|
||||
filepicker() {
|
||||
selected=$(find "${1:-$HOME}" -type f | fzf)
|
||||
[ "$?" -eq 130 ] && exit 130
|
||||
echo "$selected"
|
||||
url_to_clipboard() {
|
||||
if command -v wl-copy >/dev/null 2>&1; then
|
||||
printf "%s" "$@" | wl-copy
|
||||
elif command -v xsel >/dev/null 2>&1; then
|
||||
printf "%s" "$@" | xsel --clipboard
|
||||
elif command -v xclip >/dev/null 2>&1; then
|
||||
printf "%s" "$@" | xclip -selection clipboard >/dev/null 2>&1
|
||||
fi
|
||||
}
|
||||
|
||||
filetooxo() {
|
||||
file_to_oxo() {
|
||||
curl -F"file=@$1" "$OXO_URL"
|
||||
}
|
||||
|
||||
|
@ -34,29 +81,4 @@ exit_check() {
|
|||
[ "$1" -eq 130 ] && exit 130
|
||||
}
|
||||
|
||||
main() {
|
||||
if [ $# -eq 0 ]; then
|
||||
foldpick=$(folderpicker "")
|
||||
exit_check $?
|
||||
picked=$(filepicker "$foldpick")
|
||||
elif [ -f "$1" ]; then
|
||||
picked="$1"
|
||||
elif [ -d "$1" ]; then
|
||||
picked=$(filepicker "$1")
|
||||
else
|
||||
printf "Please only provide a folder or file as the optional argument to sharefile." >&2
|
||||
exit 1
|
||||
fi
|
||||
exit_check $?
|
||||
|
||||
url=$(filetooxo "$picked")
|
||||
echo "$url"
|
||||
if command -v notify-send >/dev/null; then
|
||||
notify-send "Upload finished" "URL: $url"
|
||||
fi
|
||||
# printf "%s" "$url" | nohup xclip -i -selection clipboard -r -verbose -loops 2 >/dev/null 2>&1
|
||||
printf "%s" "$url" | xsel --clipboard
|
||||
exit
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
if [ ! "$DISPLAY" ] && [ -n "$XDG_VTNR" ] && [ "$XDG_VTNR" -eq 1 ]; then
|
||||
exec startx "$XDG_CONFIG_HOME"/xresources/xinitrc
|
||||
if [ -n "$DISPLAY" ] || [ -z "$XDG_VTNR" ] || [ "$XDG_VTNR" -ne 1 ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
if command -v river >/dev/null 2>&1; then
|
||||
river
|
||||
fi
|
||||
|
|
62
vifm/.config/vifm/scripts/vifm-sixel
Executable file
|
@ -0,0 +1,62 @@
|
|||
#!/bin/sh
|
||||
|
||||
[ -d "$HOME/.cache/vifm" ] || mkdir -p "$HOME/.cache/vifm"
|
||||
|
||||
# $1 action
|
||||
action="$1"
|
||||
# $2 panel width
|
||||
panel_width=$(($2 * 6))
|
||||
# $3 panel height
|
||||
panel_height=$(($3 * 14))
|
||||
# $4 image path
|
||||
image_file="$4"
|
||||
|
||||
PCACHE="$HOME/.cache/vifm/thumbnail.$(stat --printf '%n\0%i\0%F\0%s\0%W\0%Y' -- "$(readlink -f "$PWD/$image_file")" | sha256sum | awk '{print $1}')"
|
||||
|
||||
cleanup() {
|
||||
printf '\33[s\33[5A\33[2K\33[u'
|
||||
clear
|
||||
exit 0
|
||||
}
|
||||
|
||||
# recieves image with height
|
||||
image() {
|
||||
montage "$1" -geometry "${2}x${3}" sixel:-
|
||||
}
|
||||
|
||||
case "$action" in
|
||||
"clear")
|
||||
cleanup
|
||||
;;
|
||||
"draw")
|
||||
[ ! -f "${PCACHE}.jpg" ] && convert "$image_file"'[0]' "${PCACHE}.jpg"
|
||||
# FILE="$PWD/$image_file"
|
||||
image "${PCACHE}.jpg" "$panel_width" "$panel_height"
|
||||
;;
|
||||
"video")
|
||||
[ ! -f "${PCACHE}.jpg" ] &&
|
||||
ffmpegthumbnailer -i "$4" -o "${PCACHE}.jpg" -s 0 -q 5
|
||||
image "${PCACHE}.jpg" "$panel_width" "$panel_height"
|
||||
;;
|
||||
"epub")
|
||||
[ ! -f "${PCACHE}.jpg" ] &&
|
||||
epub-thumbnailer "$image_file" "$PCACHE" 1024
|
||||
image "${PCACHE}.jpg" "$panel_width" "$panel_height"
|
||||
;;
|
||||
"pdf")
|
||||
[ ! -f "${PCACHE}.jpg" ] &&
|
||||
pdftoppm -jpeg -f 1 -singlefile "$image_file" "$PCACHE"
|
||||
image "${PCACHE}.jpg" "$panel_width" "$panel_height"
|
||||
;;
|
||||
"audio")
|
||||
[ ! -f "${PCACHE}.jpg" ] &&
|
||||
ffmpeg -i "$image_file" "${PCACHE}.jpg" -y >/dev/null
|
||||
image "${PCACHE}.jpg" "$panel_width" "$panel_height"
|
||||
;;
|
||||
"font")
|
||||
[ ! -f "${PCACHE}.jpg" ] &&
|
||||
fontpreview -i "$image_file" -o "${PCACHE}.jpg"
|
||||
image "${PCACHE}.jpg" "$panel_width" "$panel_height"
|
||||
;;
|
||||
*) ;;
|
||||
esac
|
|
@ -348,6 +348,37 @@ set classify+=' ::*.doc,,*.docx::, ::*.xls,,*.xls[mx]::, ::*.pptx,,*.pp
|
|||
" You can also add %CLEAR if you want to clear screen before running FUSE
|
||||
" program.
|
||||
|
||||
|
||||
fileviewer *.pdf
|
||||
\ vifm-sixel pdf %pw %ph %c %pd
|
||||
\ %pc
|
||||
\ vifm-sixel clear
|
||||
|
||||
fileviewer *.epub
|
||||
\ vifm-sixel epub %pw %ph %c %pd
|
||||
\ %pc
|
||||
\ vifm-sixel clear
|
||||
|
||||
fileviewer <video/*>
|
||||
\ vifm-sixel video %pw %ph %c %pd
|
||||
\ %pc
|
||||
\ vifm-sixel clear
|
||||
|
||||
fileviewer <image/*>
|
||||
\ vifm-sixel draw %pw %ph %c %pd
|
||||
\ %pc
|
||||
\ vifm-sixel clear
|
||||
|
||||
fileviewer <audio/*>
|
||||
\ vifm-sixel audio %pw %ph %c %pd
|
||||
\ %pc
|
||||
\ vifm-sixel clear
|
||||
|
||||
fileviewer <font/*>
|
||||
\ vifm-sixel font %pw %ph %c %pd
|
||||
\ %pc
|
||||
\ vifm-sixel clear
|
||||
|
||||
" Pdf
|
||||
filextype *.pdf
|
||||
\ { view as rich file }
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# EASY-INSTALL-ENTRY-SCRIPT: 'ueberzug==18.1.5','console_scripts','ueberzug'
|
||||
__requires__ = 'ueberzug==18.1.5'
|
||||
import re
|
||||
import sys
|
||||
from pkg_resources import load_entry_point
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(
|
||||
load_entry_point('ueberzug==18.1.5', 'console_scripts', 'ueberzug')()
|
||||
)
|
|
@ -1,154 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
readonly ID_PREVIEW="preview"
|
||||
|
||||
#PLAY_GIF="yes"
|
||||
# By enabling this option the GIF will be animated, by leaving it commented like it
|
||||
# is now will make the gif previews behave the same way as video previews.
|
||||
|
||||
#AUTO_REMOVE="yes"
|
||||
# By enabling this option the script will remove the preview file after it is drawn
|
||||
# and by doing so the preview will always be up-to-date with the file.
|
||||
# This however, requires more CPU and therefore affects the overall performance.
|
||||
|
||||
# The messy code below is for moving pages in pdf files in the vifm file preview by
|
||||
# utilizing the < and > keys which will be bound to `vifmimg inc` or `vifmimg dec`.
|
||||
PDF_PAGE_CONFIG="$HOME/.config/vifm/vifmimgpdfpage"
|
||||
PDF_FILE_CONFIG="$HOME/.config/vifm/vifmimgpdffile"
|
||||
PDF_PAGE=1
|
||||
PDF_FILE=""
|
||||
# Initialize the variables and required files
|
||||
[[ -f "$PDF_PAGE_CONFIG" ]] && PDF_PAGE=$(cat $PDF_PAGE_CONFIG) || touch $PDF_PAGE_CONFIG
|
||||
[[ -f "$PDF_FILE_CONFIG" ]] && PDF_FILE=$(cat $PDF_FILE_CONFIG) || touch $PDF_FILE_CONFIG
|
||||
|
||||
|
||||
# Create temporary working directory if the directory structure doesn't exist
|
||||
if [[ ! -d "/tmp$PWD/" ]]; then
|
||||
mkdir -p "/tmp$PWD/"
|
||||
fi
|
||||
|
||||
function inc() {
|
||||
VAL="$(cat $PDF_PAGE_CONFIG)"
|
||||
echo "$(expr $VAL + 1)" > $PDF_PAGE_CONFIG
|
||||
}
|
||||
|
||||
function dec() {
|
||||
VAL="$(cat $PDF_PAGE_CONFIG)"
|
||||
echo "$(expr $VAL - 1)" > $PDF_PAGE_CONFIG
|
||||
if [[ $VAL -le 0 ]]; then
|
||||
echo 0 > $PDF_PAGE_CONFIG
|
||||
fi
|
||||
}
|
||||
|
||||
function previewclear() {
|
||||
declare -p -A cmd=([action]=remove [identifier]="$ID_PREVIEW") \
|
||||
> "$FIFO_UEBERZUG"
|
||||
}
|
||||
|
||||
function fileclean() {
|
||||
if [[ -f "/tmp$PWD/$6.png" ]]; then
|
||||
rm -f "/tmp$PWD/$6.png"
|
||||
elif [[ -d "/tmp$PWD/$6/" ]]; then
|
||||
rm -rf "/tmp$PWD/$6/"
|
||||
fi
|
||||
}
|
||||
|
||||
function preview() {
|
||||
declare -p -A cmd=([action]=add [identifier]="$ID_PREVIEW"
|
||||
[x]="$2" [y]="$3" [width]="$4" [height]="$5" \
|
||||
[path]="$PWD/$6") \
|
||||
> "$FIFO_UEBERZUG"
|
||||
}
|
||||
|
||||
function previewvideo() {
|
||||
if [[ ! -f "/tmp$PWD/$6.png" ]]; then
|
||||
ffmpegthumbnailer -i "$PWD/$6" -o "/tmp$PWD/$6.png" -s 0 -q 10
|
||||
fi
|
||||
declare -p -A cmd=([action]=add [identifier]="$ID_PREVIEW"
|
||||
[x]="$2" [y]="$3" [width]="$4" [height]="$5" \
|
||||
[path]="/tmp$PWD/$6.png") \
|
||||
> "$FIFO_UEBERZUG"
|
||||
}
|
||||
|
||||
function previewepub() {
|
||||
if [[ ! -f "/tmp$PWD/$6.png" ]]; then
|
||||
epub-thumbnailer "$6" "/tmp$PWD/$6.png" 1024
|
||||
fi
|
||||
declare -p -A cmd=([action]=add [identifier]="$ID_PREVIEW"
|
||||
[x]="$2" [y]="$3" [width]="$4" [height]="$5" \
|
||||
[path]="/tmp$PWD/$6.png") \
|
||||
> "$FIFO_UEBERZUG"
|
||||
}
|
||||
|
||||
function previewgif() {
|
||||
if [[ ! -d "/tmp$PWD/$6/" ]]; then
|
||||
mkdir -p "/tmp$PWD/$6/"
|
||||
convert -coalesce "$PWD/$6" "/tmp$PWD/$6/$6.png"
|
||||
fi
|
||||
if [[ ! -z "$PLAY_GIF" ]]; then
|
||||
for frame in $(ls -1 /tmp$PWD/$6/$6*.png | sort -V); do
|
||||
declare -p -A cmd=([action]=add [identifier]="$ID_PREVIEW"
|
||||
[x]="$2" [y]="$3" [width]="$4" [height]="$5" \
|
||||
[path]="$frame") \
|
||||
> "$FIFO_UEBERZUG"
|
||||
# Sleep between frames to make the animation smooth.
|
||||
sleep .07
|
||||
done
|
||||
else
|
||||
declare -p -A cmd=([action]=add [identifier]="$ID_PREVIEW"
|
||||
[x]="$2" [y]="$3" [width]="$4" [height]="$5" \
|
||||
[path]="/tmp$PWD/$6/$6-0.png") \
|
||||
> "$FIFO_UEBERZUG"
|
||||
fi
|
||||
}
|
||||
|
||||
function previewpdf() {
|
||||
if [[ ! "$6" == "$PDF_FILE" ]]; then
|
||||
PDF_PAGE=1
|
||||
echo 1 > $PDF_PAGE_CONFIG
|
||||
rm -f "/tmp$PWD/$6.png"
|
||||
fi
|
||||
|
||||
if [[ ! "$PDF_PAGE" == "1" ]] && [[ -f "/tmp$PWD/$6.png" ]]; then
|
||||
rm -f "/tmp$PWD/$6.png"
|
||||
fi
|
||||
|
||||
if [[ ! -f "/tmp$PWD/$6.png" ]]; then
|
||||
pdftoppm -png -f $PDF_PAGE -singlefile "$6" "/tmp$PWD/$6"
|
||||
fi
|
||||
echo "$6" > $PDF_FILE_CONFIG
|
||||
|
||||
declare -p -A cmd=([action]=add [identifier]="$ID_PREVIEW"
|
||||
[x]="$2" [y]="$3" [width]="$4" [height]="$5" \
|
||||
[path]="/tmp$PWD/$6.png") \
|
||||
> "$FIFO_UEBERZUG"
|
||||
}
|
||||
|
||||
|
||||
function previewmagick() {
|
||||
if [[ ! -f "/tmp$PWD/$6.png" ]]; then
|
||||
convert -thumbnail $(identify -format "%wx%h" "$6") "$PWD/$6" "/tmp$PWD/$6.png"
|
||||
fi
|
||||
declare -p -A cmd=([action]=add [identifier]="$ID_PREVIEW"
|
||||
[x]="$2" [y]="$3" [width]="$4" [height]="$5" \
|
||||
[path]="/tmp$PWD/$6.png") \
|
||||
> "$FIFO_UEBERZUG"
|
||||
}
|
||||
|
||||
|
||||
|
||||
function main() {
|
||||
case "$1" in
|
||||
"inc") inc "$@" ;;
|
||||
"dec") dec "$@" ;;
|
||||
"clear") previewclear "$@" ;;
|
||||
"clean") fileclean "$@" ;;
|
||||
"draw") preview "$@" ;;
|
||||
"videopreview") previewvideo "$@" ;;
|
||||
"epubpreview") previewepub "$@" ;;
|
||||
"gifpreview") previewgif "$@" ;;
|
||||
"pdfpreview") previewpdf "$@" ;;
|
||||
"magickpreview") previewmagick "$@" ;;
|
||||
"*") echo "Unknown command: '$@'" ;;
|
||||
esac
|
||||
}
|
||||
main "$@"
|
|
@ -1,15 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
export FIFO_UEBERZUG="/tmp/vifm-ueberzug-${PPID}"
|
||||
|
||||
function cleanup {
|
||||
rm "$FIFO_UEBERZUG" 2>/dev/null
|
||||
pkill -P $$ 2>/dev/null
|
||||
}
|
||||
pkill -P $$ 2>/dev/null
|
||||
rm "$FIFO_UEBERZUG" 2>/dev/null
|
||||
mkfifo "$FIFO_UEBERZUG" >/dev/null
|
||||
trap cleanup EXIT 2>/dev/null
|
||||
tail --follow "$FIFO_UEBERZUG" | ueberzug layer --silent --parser bash >/dev/null 2>&1 &
|
||||
|
||||
vifm "$@"
|
||||
cleanup
|
242
wayland/.config/river/init
Executable file
|
@ -0,0 +1,242 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
mod="Mod4"
|
||||
modemod="Mod1"
|
||||
term=${TERMINAL:-foot}
|
||||
|
||||
## OPTIONS
|
||||
riverctl spawn "dbus-update-activation-environment SEATD_SOCK DISPLAY WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=river"
|
||||
riverctl focus-follows-cursor normal
|
||||
riverctl attach-mode bottom
|
||||
|
||||
# Set background and border color
|
||||
riverctl background-color 0x000000
|
||||
riverctl border-width 1
|
||||
riverctl border-color-focused 0xffffff
|
||||
riverctl border-color-unfocused 0x586e75
|
||||
# Set repeat rate
|
||||
riverctl set-repeat 75 300
|
||||
# Make certain views start floating
|
||||
riverctl float-filter-add app-id float
|
||||
# riverctl float-filter-add title "popup title with spaces"
|
||||
# # Set app-ids and titles of views which should use client side decorations
|
||||
# riverctl csd-filter-add app-id "gedit"
|
||||
riverctl csd-filter-add app-id "zathura"
|
||||
|
||||
## DEBUG
|
||||
# Reload river configuration
|
||||
riverctl map normal $mod+Shift F12 spawn "$HOME/.config/river/init"
|
||||
|
||||
## HOTKEYS
|
||||
# close focused view
|
||||
riverctl map normal $mod+Shift C close
|
||||
|
||||
# Open terminal
|
||||
riverctl map normal $mod Return spawn "$term"
|
||||
|
||||
# Open run menu
|
||||
riverctl map normal $mod Space spawn "bemenu-run"
|
||||
|
||||
# Toggle status bar
|
||||
riverctl map normal $mod F7 spawn "killall -SIGUSR1 waybar"
|
||||
|
||||
# Switch to lockscreen
|
||||
riverctl map normal $mod X spawn "lockscreen"
|
||||
|
||||
# Open logout script
|
||||
riverctl map normal $mod backspace spawn "powermenu"
|
||||
|
||||
# Open Bookmark search
|
||||
riverctl map normal None XF86Search spawn "qutedmenu"
|
||||
|
||||
# Open clipboard history
|
||||
riverctl map normal $mod+Shift Space spawn "clipman pick --tool=bemenu"
|
||||
|
||||
# Open floting calculator
|
||||
riverctl map normal $mod+Shift R spawn "$term --class float -e qalc"
|
||||
|
||||
# Desktop theming
|
||||
# shellcheck disable=SC2016
|
||||
riverctl map normal $mod F8 spawn 'styler set $(styler list themes | bemenu)'
|
||||
|
||||
# Password dropdown frontend
|
||||
riverctl map normal $mod+Shift P spawn "pass-pick"
|
||||
|
||||
# File upload
|
||||
riverctl map normal $mod+Shift U spawn "$term --class float -e sharefile | xargs notify-send"
|
||||
|
||||
# # Screenshot
|
||||
riverctl map normal None Print spawn "screenshot"
|
||||
riverctl map normal Shift Print spawn "screenshot | sharefile -"
|
||||
riverctl map normal $mod Print spawn "screenshot region"
|
||||
riverctl map normal $mod+Shift Print spawn "screenshot region | sharefile -"
|
||||
|
||||
# # Clear clipboard
|
||||
# riverctl map normal $mod BackSpace spawn 'wl-copy -c && printf ''|xclip -selection c'
|
||||
|
||||
# # PixelColor script
|
||||
# riverctl map normal "Mod1" C spawn 'bash ~/.config/bin/pixelcolor'
|
||||
|
||||
# MOVEMENT
|
||||
# focus the next/previous view in the layout stack
|
||||
riverctl map normal $mod J focus-view next
|
||||
riverctl map normal $mod K focus-view previous
|
||||
|
||||
# swap the focused view with the next/previous view in the layout stack
|
||||
riverctl map normal $mod+Shift J swap next
|
||||
riverctl map normal $mod+Shift K swap previous
|
||||
|
||||
# bump the focused view to the top of the layout stack
|
||||
riverctl map normal $mod+Shift Return zoom
|
||||
|
||||
# decrease/increase the main ratio of layout
|
||||
riverctl map normal $mod+Shift H send-layout-cmd rivercarro "main-ratio -0.05"
|
||||
riverctl map normal $mod+Shift L send-layout-cmd rivercarro "main-ratio +0.05"
|
||||
|
||||
# increment/decrement the main count of layout
|
||||
riverctl map normal $mod+Control H send-layout-cmd rivercarro "main-count +1"
|
||||
riverctl map normal $mod+Control L send-layout-cmd rivercarro "main-count -1"
|
||||
|
||||
# change layout orientation
|
||||
riverctl map normal $mod Up send-layout-cmd rivercarro "main-location top"
|
||||
riverctl map normal $mod Right send-layout-cmd rivercarro "main-location right"
|
||||
riverctl map normal $mod Down send-layout-cmd rivercarro "main-location bottom"
|
||||
riverctl map normal $mod Left send-layout-cmd rivercarro "main-location left"
|
||||
|
||||
# Mod+F to toggle fullscreen
|
||||
riverctl map normal $mod F toggle-fullscreen
|
||||
|
||||
# toggle float
|
||||
riverctl map normal $mod+Shift v toggle-float
|
||||
# Mod + Left Mouse Button to move views
|
||||
riverctl map-pointer normal $mod BTN_LEFT move-view
|
||||
# Mod + Right Mouse Button to resize views
|
||||
riverctl map-pointer normal $mod BTN_RIGHT resize-view
|
||||
|
||||
### Begin resize and moving mode, for floating windows
|
||||
riverctl declare-mode interact_float
|
||||
riverctl map normal $modemod R enter-mode interact_float
|
||||
riverctl map interact_float $modemod R enter-mode normal
|
||||
|
||||
# resize views on screen
|
||||
riverctl map interact_float $mod H resize horizontal -100
|
||||
riverctl map interact_float $mod J resize vertical 100
|
||||
riverctl map interact_float $mod K resize vertical -100
|
||||
riverctl map interact_float $mod L resize horizontal 100
|
||||
|
||||
# move views around screen
|
||||
riverctl map interact_float None H move left 100
|
||||
riverctl map interact_float None J move down 100
|
||||
riverctl map interact_float None K move up 100
|
||||
riverctl map interact_float None L move right 100
|
||||
|
||||
# snap views to screen edges
|
||||
riverctl map interact_float $mod+Shift H snap left
|
||||
riverctl map interact_float $mod+Shift J snap down
|
||||
riverctl map interact_float $mod+Shift K snap up
|
||||
riverctl map interact_float $mod+Shift L snap right
|
||||
### End resize and moving mode
|
||||
|
||||
# focus the next/previous output
|
||||
riverctl map normal $mod Period focus-output next
|
||||
riverctl map normal $mod Comma focus-output previous
|
||||
|
||||
# send the focused view to the next/previous output
|
||||
riverctl map normal $mod+Shift Period send-to-output next
|
||||
riverctl map normal $mod+Shift Comma send-to-output previous
|
||||
|
||||
# set up 10 tags (with '0' opening the 10th one)
|
||||
for i in $(seq 0 9); do
|
||||
tags=$((1 << (i - 1)))
|
||||
if [ "$i" -eq 0 ]; then tags=$((1 << 9)); fi
|
||||
|
||||
# Mod+[1-9] to focus tag [0-8]
|
||||
riverctl map normal $mod "$i" set-focused-tags $tags
|
||||
|
||||
# Mod+Shift+[1-9] to tag focused view with tag [0-8]
|
||||
riverctl map normal $mod+Shift "$i" set-view-tags $tags
|
||||
|
||||
# Mod+Ctrl+[1-9] to toggle focus of tag [0-8]
|
||||
riverctl map normal $mod+Control "$i" toggle-focused-tags $tags
|
||||
|
||||
# Mod+Shift+Ctrl+[1-9] to toggle tag [0-8] of focused view
|
||||
riverctl map normal $mod+Shift+Control "$i" toggle-view-tags $tags
|
||||
done
|
||||
|
||||
# focus all tags
|
||||
all_tags=$(((1 << 32) - 1))
|
||||
riverctl map normal $mod equal set-focused-tags $all_tags
|
||||
# tag focused view with all tags
|
||||
riverctl map normal $mod+Shift equal set-view-tags $all_tags
|
||||
|
||||
# Various media key mapping examples for both normal and locked mode which do
|
||||
# not have a modifier
|
||||
for mode in normal locked; do
|
||||
# Eject the optical drive
|
||||
riverctl map $mode None XF86Eject spawn 'eject -T'
|
||||
|
||||
riverctl map $mode None XF86AudioRaiseVolume spawn 'pactl set-sink-volume @DEFAULT_SINK@ +5%'
|
||||
riverctl map $mode None XF86AudioLowerVolume spawn 'pactl set-sink-volume @DEFAULT_SINK@ -5%'
|
||||
riverctl map $mode None XF86AudioMute spawn 'pactl set-sink-mute @DEFAULT_SINK@ toggle'
|
||||
|
||||
# Control MPRIS aware media players with playerctl (https://github.com/altdesktop/playerctl)
|
||||
riverctl map $mode None XF86AudioMedia spawn 'playerctl play-pause'
|
||||
riverctl map $mode None XF86AudioPlay spawn 'playerctl play-pause'
|
||||
riverctl map $mode None XF86AudioPrev spawn 'playerctl previous'
|
||||
riverctl map $mode None XF86AudioNext spawn 'playerctl next'
|
||||
|
||||
# You can control screen backlight brighness with light (https://github.com/haikarainen/light); but we prefer brightnessctl
|
||||
riverctl map $mode None XF86MonBrightnessUp spawn 'brightnessctl set 10%+'
|
||||
riverctl map $mode None XF86MonBrightnessDown spawn 'brightnessctl set 10%-'
|
||||
done
|
||||
|
||||
# The scratchpad will live on an unused tag. Which tags are used depends on your
|
||||
# config, but rivers default uses the first 9 tags.
|
||||
scratch_tag=$((1 << 20))
|
||||
# Toggle the scratchpad with Super+P
|
||||
riverctl map normal $mod grave toggle-focused-tags ${scratch_tag}
|
||||
# Send windows to the scratchpad with Super+Shift+P
|
||||
riverctl map normal $mod+Shift grave set-view-tags ${scratch_tag}
|
||||
# Set spawn tagmask to ensure new windows don't have the scratchpad tag unless
|
||||
# explicitly set.
|
||||
all_but_scratch_tag=$((((1 << 32) - 1) ^ scratch_tag))
|
||||
riverctl spawn-tagmask ${all_but_scratch_tag}
|
||||
|
||||
# set up scratch pad for todo and 'drop-down' terminal
|
||||
# call scratchpads to current workspace -- scratchpads started on i3 starting (see end of file)
|
||||
# bindsym $mod+t [class="scratchpad" title="dropdown-todo"] scratchpad show
|
||||
# bindsym $mod+Shift+Return [class="scratchpad" title="dropdown-terminal"] scratchpad show
|
||||
|
||||
## INPUT
|
||||
# device (touchscreen)
|
||||
# enable touch clicking for touchpads
|
||||
for pad in $(riverctl list-inputs | grep -i touchpad); do
|
||||
riverctl input "$pad" events enabled
|
||||
riverctl input "$pad" tap enabled
|
||||
done
|
||||
for pad in $(riverctl list-inputs | grep -i touchscreen); do
|
||||
riverctl input "$pad" events enabled
|
||||
riverctl input "$pad" tap enabled
|
||||
riverctl input "$pad" drag enabled
|
||||
riverctl input "$pad" pointer-accel 0.5
|
||||
done
|
||||
|
||||
setxkbmap -option "compose:menu"
|
||||
exec swaybg -i ~/pictures/wall.jpg -o '*' -m fill &
|
||||
# killall mako
|
||||
# mako &
|
||||
killall waybar
|
||||
exec waybar &
|
||||
|
||||
killall clipman
|
||||
exec wl-paste -t text --watch clipman store &
|
||||
# bash ~/.config/bin/gtktheme # setting our gtk variables
|
||||
# killall polkit-gnome-authentication-agent-1
|
||||
# /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 &
|
||||
# Set and exec into the default layout generator, rivercarro.
|
||||
# River will send the process group of the init executable SIGTERM on exit.
|
||||
riverctl default-layout rivercarro &
|
||||
# start layouting engine
|
||||
killall rivercarro
|
||||
exec rivercarro -main-ratio 0.65 -view-padding 6 -outer-padding 6 &
|
||||
# brightnessctl set 100%
|
3
wayland/.config/sh/env.d/compose-key.sh
Normal file
|
@ -0,0 +1,3 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
export XKB_DEFAULT_OPTIONS='compose:menu'
|
170
wayland/.config/waybar/config
Normal file
|
@ -0,0 +1,170 @@
|
|||
{
|
||||
"layer": "top",
|
||||
"modules-left": ["river/tags"],
|
||||
"modules-center": ["clock", ],
|
||||
"modules-right": ["custom/events", "custom/media", "custom/wireguard", "custom/archupdates", "pulseaudio", "backlight", "network", "cpu", "memory", "temperature", "battery", "tray"],
|
||||
"custom/archupdates": {
|
||||
"format": "{} {icon}",
|
||||
"format-alt-click": "right",
|
||||
"format-icons": {
|
||||
"default": ""
|
||||
},
|
||||
"return-type": "json",
|
||||
"exec": "~/.config/waybar/modules/archupdates 5 json",
|
||||
"interval": 3600,
|
||||
"on-click": "alacritty --class float -e topgrade"
|
||||
},
|
||||
"backlight": {
|
||||
"device": "intel_backlight",
|
||||
"format": "{percent}% {icon}",
|
||||
"format-icons": ["滋", "", "", ""],
|
||||
"on-scroll-up": "brightnessctl set 1%+",
|
||||
"on-scroll-down": "brightnessctl set 1%-"
|
||||
},
|
||||
"battery": {
|
||||
"format": "{capacity}% {icon}",
|
||||
"format-alt":"{capacity}% ({time}) {icon}",
|
||||
"format-alt-click": "click-right",
|
||||
"format-icons": ["", "", "", "", ""],
|
||||
"interval": 60,
|
||||
"states": {
|
||||
"warning": 30,
|
||||
"critical": 15
|
||||
},
|
||||
},
|
||||
"clock": {
|
||||
"format-alt": "{:%a, %d. %b %H:%M}",
|
||||
"format-alt-click": "click-right",
|
||||
"on-click": "gsimplecal"
|
||||
},
|
||||
"cpu": {
|
||||
"interval": 10,
|
||||
"format": "{usage}% ",
|
||||
"max-length": 10,
|
||||
"states": {
|
||||
"warning": 50,
|
||||
"critical": 80
|
||||
},
|
||||
"on-click": "alacritty --class float -e top",
|
||||
"on-click-right": "alacritty --class float -e glances"
|
||||
},
|
||||
"custom/events": {
|
||||
"format": "{}",
|
||||
"interval": 300,
|
||||
"format-icons": {
|
||||
"default": ""
|
||||
},
|
||||
"exec": "~/.config/waybar/modules/khal.py 2>/dev/null",
|
||||
"exec-if": "command -v khal >/dev/null 2>&1",
|
||||
"return-type": "json"
|
||||
},
|
||||
"memory": {
|
||||
"interval": 30,
|
||||
"format": "{avail:0.1f}G ",
|
||||
"format-alt": "{used:0.1f}G/{total:0.1f}G ",
|
||||
"format-alt-click": "click-right",
|
||||
"max-length": 10
|
||||
},
|
||||
"mpd": {
|
||||
"format": "{stateIcon} {consumeIcon}{randomIcon}{repeatIcon}{singleIcon}",
|
||||
"format-disconnected": "ﱙ",
|
||||
"format-stopped": "",
|
||||
"interval": 10,
|
||||
"consume-icons": {
|
||||
"on": " " // Icon shows only when "consume" is on
|
||||
},
|
||||
"random-icons": {
|
||||
"on": " "
|
||||
},
|
||||
"repeat-icons": {
|
||||
"on": " "
|
||||
},
|
||||
"single-icons": {
|
||||
"on": "1 "
|
||||
},
|
||||
"state-icons": {
|
||||
"paused": "",
|
||||
"playing": "",
|
||||
},
|
||||
"tooltip-format": "{artist} - {album} - {title} ({elapsedTime:%M:%S}/{totalTime:%M:%S}) ",
|
||||
"tooltip-format-disconnected": "MPD (disconnected)"
|
||||
},
|
||||
"custom/media": {
|
||||
"format": "{icon}{}",
|
||||
"format-alt-click": "right",
|
||||
"return-type": "json",
|
||||
"format-icons": {
|
||||
"Playing": " ",
|
||||
"Paused": " ",
|
||||
},
|
||||
"escape": true,
|
||||
"max-length":70,
|
||||
"exec": "playerctl -a metadata --format '{\"text\": \"\", \"tooltip\": \"{{playerName}} : {{markup_escape(title)}}\", \"alt\": \"{{status}}\", \"class\": \"{{status}}\"}' -F",
|
||||
"exec-if": "command -v playerctl >/dev/null 2>&1",
|
||||
"on-click": "playerctl play-pause",
|
||||
"on-click-right": "playerctl stop",
|
||||
},
|
||||
"network": {
|
||||
"interface": "wlp58s0",
|
||||
"format": "{ifname}",
|
||||
"format-wifi": "{signalStrength}% ",
|
||||
"format-ethernet": "{ipaddr}/{cidr} ",
|
||||
"format-disconnected": "睊",
|
||||
"tooltip-format": "{ifname} via {gwaddr} ",
|
||||
"tooltip-format-wifi": "{essid}: {bandwidthDownBits}-{bandwidthUpBits} ({signalStrength}%) {ifname}",
|
||||
"tooltip-format-ethernet": "{ifname} ",
|
||||
"tooltip-format-disconnected": "Disconnected",
|
||||
"max-length": 50,
|
||||
"on-click": "alacritty --class float -e nmtui",
|
||||
// "on-click-right": "sudo rfkill toggle wlan"
|
||||
},
|
||||
"pulseaudio": {
|
||||
"format": "{volume}% {icon}",
|
||||
"format-bluetooth": "{volume}% {icon}",
|
||||
"format-muted": "",
|
||||
"format-icons": {
|
||||
"headphone": "",
|
||||
"hands-free": "",
|
||||
"headset": "",
|
||||
"phone": "",
|
||||
"portable": "",
|
||||
"car": "",
|
||||
"default": ["", ""]
|
||||
},
|
||||
"scroll-step": 1,
|
||||
"on-click": "alacritty --class float -e pulsemixer",
|
||||
"on-scroll-up": "pactl set-sink-volume @DEFAULT_SINK@ +1%",
|
||||
"on-scroll-down": "pactl set-sink-volume @DEFAULT_SINK@ -1%"
|
||||
},
|
||||
"river/tags": {
|
||||
"num-tags": 10,
|
||||
"tag-labels": [ "", "", "", "", "", "", "", "", "", "" ]
|
||||
},
|
||||
"temperature": {
|
||||
// "thermal-zone": 2,
|
||||
"hwmon-path": "/sys/class/hwmon/hwmon5/temp1_input",
|
||||
"critical-threshold": 80,
|
||||
// "format-critical": "{temperatureC}° ",
|
||||
"format": "{temperatureC}° ",
|
||||
"on-click": "alacritty --class float -e watch sensors"
|
||||
},
|
||||
"tray": {
|
||||
"icon-size": 21,
|
||||
"spacing": 10
|
||||
},
|
||||
"custom/weather": {
|
||||
"exec": "curl 'https://wttr.in/?format=%t'",
|
||||
"exec-if": "command -v curl >/dev/null 2>&1",
|
||||
"interval": 3600
|
||||
},
|
||||
"custom/wireguard": {
|
||||
"format-icons": {
|
||||
"default": "嬨"
|
||||
},
|
||||
"exec": "~/.config/waybar/modules/wireguard json",
|
||||
"exec-if": "command -v nmcli >/dev/null 2>&1",
|
||||
"return-type": "json",
|
||||
"signal": 6,
|
||||
"interval": 60,
|
||||
}
|
||||
}
|
|
@ -1,15 +1,22 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# check for available archupdates and return their number
|
||||
# checks both repositories and aur
|
||||
# Check for available archupdates and return their number.
|
||||
# Checks both repositories and aur,
|
||||
# returns empty string when 0 packages are available, so
|
||||
# that polybar simply displays nothing.
|
||||
# Can be used to generate json-like output for waybar.
|
||||
#
|
||||
# dependendies: yay, (pacman-contrib optional)
|
||||
# dependencies: yay, (pacman-contrib optional)
|
||||
# optional: jq
|
||||
#
|
||||
# Takes 2 arguments:
|
||||
# Takes an optional integer argument, which is the minimum
|
||||
# numer of package updates for an answer to be returned.
|
||||
min_upd=${1:-0}
|
||||
# Takes as second optional argument the output format
|
||||
# Valid value is "json", everything else returns plain-text.
|
||||
# json output requires jq.
|
||||
format=${2:-plain}
|
||||
|
||||
# prefer checkupdates since it allows checking w/o partial upgrade
|
||||
if command -v "checkupdates" >/dev/null; then
|
||||
|
@ -30,6 +37,20 @@ updates_aur="$(yay -Qum 2>/dev/null | wc -l)"
|
|||
# updates_aur=$(rua upgrade --printonly 2> /dev/null | wc -l)
|
||||
|
||||
updates=$((updates_repo + updates_aur))
|
||||
|
||||
text="${updates}"
|
||||
alt="${updates_repo}|${updates_aur}"
|
||||
tooltip="Repositories: ${updates_repo} | AUR: ${updates_aur}"
|
||||
[ "$updates" -gt "$min_upd" ] && class="available" || class="empty"
|
||||
if [ "$format" = "json" ]; then
|
||||
printf "{\"text\": \"%s\", \"alt\": \"%s\", \"tooltip\": \"%s\", \"class\": \"%s\"}" \
|
||||
"$text" \
|
||||
"$alt" \
|
||||
"$tooltip" \
|
||||
"$class"
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ "$updates" -gt "$min_upd" ]; then
|
||||
echo "$updates"
|
||||
else
|
35
wayland/.config/waybar/modules/khal.py
Executable file
|
@ -0,0 +1,35 @@
|
|||
#!/usr/bin/env python
|
||||
# from https://gist.github.com/bjesus/178a9bd3453470d74803945dbbf9ed40
|
||||
# List upcoming khal events in simple json container fit for waybar
|
||||
|
||||
import subprocess
|
||||
import datetime
|
||||
import json
|
||||
from html import escape
|
||||
|
||||
data = {}
|
||||
|
||||
today = datetime.date.today().strftime("%Y-%m-%d")
|
||||
|
||||
next_week = (datetime.date.today() + datetime.timedelta(days=10)).strftime("%Y-%m-%d")
|
||||
|
||||
output = subprocess.check_output("khal list now " + next_week, shell=True)
|
||||
output = output.decode("utf-8")
|
||||
|
||||
lines = output.split("\n")
|
||||
new_lines = []
|
||||
for line in lines:
|
||||
clean_line = escape(line).split(" ::")[0]
|
||||
if len(clean_line) and not clean_line[0] in ["0", "1", "2"]:
|
||||
clean_line = "\n<b>" + clean_line + "</b>"
|
||||
new_lines.append(clean_line)
|
||||
output = "\n".join(new_lines).strip()
|
||||
|
||||
if today in output:
|
||||
data["text"] = " " + output.split("\n")[1]
|
||||
else:
|
||||
data["text"] = ""
|
||||
|
||||
data["tooltip"] = output
|
||||
|
||||
print(json.dumps(data))
|
143
wayland/.config/waybar/modules/wireguard
Executable file
|
@ -0,0 +1,143 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# nmcli WireGuard abstraction layer for use with my waybar module and rofi custom menu script
|
||||
#
|
||||
# requires nmcli on your path
|
||||
# install to the same directory as wireguard-rofi.sh
|
||||
#
|
||||
# usage: ./wireguard.sh [menu|toggle NAME]
|
||||
# no argument: print current connections
|
||||
# json: print waybar-ready json output
|
||||
# menu: print all connections
|
||||
# toggle NAME: toggle connection NAME
|
||||
|
||||
if ! command -v nmcli >/dev/null 2>&1; then
|
||||
echo "err: nmcli not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
nargs=$#
|
||||
showmenu="no"
|
||||
dotoggle="no"
|
||||
printjson="no"
|
||||
if [[ $nargs == 1 ]]; then
|
||||
if [[ $1 == "menu" ]]; then
|
||||
showmenu="yes"
|
||||
elif [[ $1 == "json" ]]; then
|
||||
printjson="yes"
|
||||
fi
|
||||
elif [[ $nargs == 2 ]]; then
|
||||
if [[ $1 == "toggle" ]]; then
|
||||
dotoggle="yes"
|
||||
conn="$2"
|
||||
fi
|
||||
fi
|
||||
|
||||
nmclicmd="nmcli connection"
|
||||
wgconns="$nmclicmd show"
|
||||
wgactive="$wgconns --active"
|
||||
|
||||
connected=()
|
||||
available=()
|
||||
|
||||
function print_as_json() {
|
||||
text="嬨" # only prints a single icon when connected
|
||||
# text="${1}" # use this line to show all output in text
|
||||
alt="${1}"
|
||||
tooltip="${1}"
|
||||
[ -n "$1" ] && class="connected" || class="disconnected"
|
||||
printf "{\"text\": \"%s\", \"alt\": \"%s\", \"tooltip\": \"%s\", \"class\": \"%s\"}" \
|
||||
"$text" \
|
||||
"$alt" \
|
||||
"$tooltip" \
|
||||
"$class"
|
||||
}
|
||||
|
||||
function get_conns {
|
||||
while read -r name _ type device; do
|
||||
if [[ $type != "wireguard" && ($type != "tun" || $device != "proton0") ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ $device != "--" ]]; then
|
||||
while read -r key value; do
|
||||
if [[ $key != "ipv4.addresses:" ]]; then
|
||||
continue
|
||||
fi
|
||||
connected+=("$name: $value")
|
||||
done < <($wgconns "$name")
|
||||
else
|
||||
available+=("$name")
|
||||
fi
|
||||
done < <($1)
|
||||
}
|
||||
|
||||
function print_conns {
|
||||
local first="yes"
|
||||
local array_print="$1[@]"
|
||||
local array_print=("${!array_print}")
|
||||
if [[ $2 == "list" ]]; then
|
||||
for c in "${array_print[@]}"; do
|
||||
output="$1: $c"
|
||||
done
|
||||
else
|
||||
output=""
|
||||
for c in "${array_print[@]}"; do
|
||||
if [[ "$first" != "yes" ]]; then
|
||||
output+=" | "
|
||||
fi
|
||||
output+="$c"
|
||||
first="no"
|
||||
done
|
||||
fi
|
||||
if [[ "$printjson" == "yes" ]]; then
|
||||
print_as_json "$output"
|
||||
else
|
||||
echo "$output"
|
||||
fi
|
||||
}
|
||||
|
||||
function array_contains {
|
||||
local array_has="$1[@]"
|
||||
local array_has=("${!array_has}")
|
||||
local element="$2"
|
||||
for e in "${array_has[@]}"; do
|
||||
if [[ "$e" == *"$element"* ]]; then
|
||||
echo "yes"
|
||||
return
|
||||
fi
|
||||
done
|
||||
echo "no"
|
||||
}
|
||||
|
||||
if [[ $nargs == 0 ]]; then
|
||||
get_conns "$wgactive"
|
||||
print_conns connected
|
||||
|
||||
elif [[ $showmenu == "yes" ]]; then
|
||||
get_conns "$wgconns"
|
||||
print_conns connected "list"
|
||||
print_conns available "list"
|
||||
|
||||
elif [[ $printjson == "yes" ]]; then
|
||||
get_conns "$wgactive"
|
||||
print_conns connected
|
||||
|
||||
elif
|
||||
[[ $dotoggle == "yes" ]]
|
||||
then
|
||||
get_conns "$wgconns"
|
||||
|
||||
if [[ "$(array_contains connected "$conn")" == "yes" ]]; then
|
||||
$nmclicmd down "$conn"
|
||||
elif [[ "$(array_contains available "$conn")" == "yes" ]]; then
|
||||
$nmclicmd up "$conn"
|
||||
else
|
||||
echo "err: connection not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
else
|
||||
echo "err: wrong args"
|
||||
exit 1
|
||||
fi
|
152
wayland/.config/waybar/style.css
Normal file
|
@ -0,0 +1,152 @@
|
|||
/* @import "colorscheme.css"; */
|
||||
|
||||
* {
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
window#waybar {
|
||||
font-size: 15px;
|
||||
color: #d5c4a1;
|
||||
background-color: #32302f;
|
||||
border-bottom: 1px solid #3c3836;
|
||||
transition-property: background-color;
|
||||
transition-duration: .5s;
|
||||
}
|
||||
|
||||
window#waybar.hidden {
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
#tags button {
|
||||
font-size:17px;
|
||||
font-weight:900;
|
||||
background-color: transparent;
|
||||
color: #665c54;
|
||||
margin: 0px;
|
||||
padding: 0px 5px;
|
||||
/* Use box-shadow instead of border so the text isn't offset */
|
||||
}
|
||||
/* /1* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect *1/ */
|
||||
#tags button:hover {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
/* box-shadow: inset 0 -1px #d5c4a1; */
|
||||
box-shadow: inset 0 0;
|
||||
}
|
||||
#tags button.occupied {
|
||||
font-weight: 400;
|
||||
color: #d5c4a1;
|
||||
}
|
||||
#tags button.focused {
|
||||
font-weight: 400;
|
||||
color: #83a598;
|
||||
}
|
||||
#tags button.urgent {
|
||||
color: #8ec07c;
|
||||
}
|
||||
|
||||
#clock,
|
||||
#battery,
|
||||
#cpu,
|
||||
#memory,
|
||||
#disk,
|
||||
#temperature,
|
||||
#backlight,
|
||||
#network,
|
||||
#pulseaudio,
|
||||
#tray,
|
||||
#mode,
|
||||
#idle_inhibitor,
|
||||
#mpd,
|
||||
#custom-archupdates,
|
||||
#custom-wireguard,
|
||||
#custom-events,
|
||||
#custom-media {
|
||||
padding: 0 10px;
|
||||
margin: 0 5px;
|
||||
color: #d5c4a1;
|
||||
background-color: #3c3836;
|
||||
}
|
||||
|
||||
/* If workspaces is the leftmost module, omit left margin */
|
||||
.modules-left > widget:first-child > #tags {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
/* If workspaces is the rightmost module, omit right margin */
|
||||
.modules-right > widget:last-child > #tags {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
#battery.charging, #battery.plugged {
|
||||
background-color: #504945;
|
||||
}
|
||||
|
||||
#battery.warning {
|
||||
background-color: #fe8019;
|
||||
color: #32302f;
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
to {
|
||||
background-color: #fb4934;
|
||||
color: #32302f;
|
||||
}
|
||||
}
|
||||
|
||||
#battery.critical:not(.charging) {
|
||||
color: #d5c4a1;
|
||||
background-color: #32302f;
|
||||
animation-name: blink;
|
||||
animation-duration: 0.5s;
|
||||
animation-timing-function: linear;
|
||||
animation-iteration-count: infinite;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
|
||||
#cpu.warning {
|
||||
color: #32302f;
|
||||
background-color: #fabd2f;
|
||||
}
|
||||
#cpu.critical {
|
||||
color: #d5c4a1;
|
||||
background-color: #fb4934;
|
||||
}
|
||||
|
||||
#custom-archupdates.empty {
|
||||
background-color: transparent;
|
||||
color: transparent;
|
||||
font-size: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#custom-wireguard.disconnected {
|
||||
background-color: transparent;
|
||||
color: transparent;
|
||||
font-size: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#temperature.critical {
|
||||
background-color: #fb4934;
|
||||
}
|
||||
|
||||
#tray > .passive {
|
||||
-gtk-icon-effect: dim;
|
||||
}
|
||||
|
||||
|
||||
#tray > .needs-attention {
|
||||
-gtk-icon-effect: highlight;
|
||||
}
|
||||
|
||||
#mpd.disconnected {
|
||||
background-color: transparent;
|
||||
color: transparent;
|
||||
font-size: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
48
wayland/.local/bin/screenshot
Executable file
|
@ -0,0 +1,48 @@
|
|||
#!/usr/bin/env sh
|
||||
# Take a screenshot on wayland
|
||||
# By default takes a screenshot of the whole desktop
|
||||
# If 'region' or 'area' command is passed in will allow selecting a region to screenshot.
|
||||
# Example: `screenshot region`
|
||||
|
||||
TIME="$(date +%Y-%m-%d-%H-%M-%S)"
|
||||
readonly TIME
|
||||
readonly TMPSCREENSHOTDIR="$HOME/.cache/screenshot"
|
||||
readonly TMPIMGPATH="$TMPSCREENSHOTDIR/img-$TIME.png"
|
||||
|
||||
FULLSCREEN=true
|
||||
|
||||
if [ "$1" = "area" ] || [ "$1" = "region" ]; then
|
||||
FULLSCREEN=false
|
||||
fi
|
||||
|
||||
main() {
|
||||
prepare_cache
|
||||
take_screenshot "$FULLSCREEN"
|
||||
if [ -n "$SCREENSHOT_POSTPROCESS" ]; then
|
||||
eval "$SCREENSHOT_POSTPROCESS"
|
||||
else
|
||||
postprocess
|
||||
fi
|
||||
}
|
||||
|
||||
prepare_cache() {
|
||||
if [ ! -d "$TMPSCREENSHOTDIR" ]; then
|
||||
mkdir -p "$TMPSCREENSHOTDIR"
|
||||
fi
|
||||
}
|
||||
|
||||
take_screenshot() {
|
||||
if $1; then
|
||||
grim "$TMPIMGPATH"
|
||||
else
|
||||
grim -g "$(slurp)" "$TMPIMGPATH"
|
||||
fi
|
||||
}
|
||||
|
||||
postprocess() {
|
||||
notify-send -i "$TMPIMGPATH" "Screenshot taken" "$TMPIMGPATH"
|
||||
echo "$TMPIMGPATH" | wl-copy
|
||||
echo "$TMPIMGPATH"
|
||||
}
|
||||
|
||||
main "$@"
|
110
wayland/README.md
Normal file
|
@ -0,0 +1,110 @@
|
|||
# wayland
|
||||
|
||||
Contains:
|
||||
[riverwm](https://github.com/riverwm/river)
|
||||
[waybar](https://github.com/Alexays/Waybar)
|
||||
|
||||
My first foray into wayland is based on river,
|
||||
a tiling window manager somewhat based on bspwm.
|
||||
|
||||
This is only a very work-in-progress README file.
|
||||
|
||||
Since wayland handles key presses and so on completely differently
|
||||
from X,
|
||||
I can't for example use sxhkd which is a shame.
|
||||
|
||||
## Missing
|
||||
|
||||
not set up:
|
||||
|
||||
* [x] lockscreen
|
||||
* [x] power menu -- rofi on X
|
||||
* [x] extensive run menu (clipboard, open windows) -- rofi on X
|
||||
* [x] clipboard manager
|
||||
* [x] pass frontend dropdown -- clipboard and xdotool
|
||||
* [ ] investigate [wtype](https://github.com/atx/wtype) over ydotool
|
||||
* [x] file uploading (works but without url clipboard)
|
||||
* [x] open_download (qutebrowser script)
|
||||
* [x] gap regulation
|
||||
* [x] brightnessctl
|
||||
* [x] waybar and various status modules
|
||||
* [ ] include waybar in styler settings
|
||||
* [x] pacman new packages in status
|
||||
* [x] personal keyboard layout (ae, oe, ue, ..)
|
||||
* [x] styler
|
||||
* still works as before, only less programs respect xresources settings
|
||||
* works even for foot, if I want to switch to it
|
||||
* [ ] need to set it up for waybar
|
||||
* [ ] dropdown terminal and dropdown todo
|
||||
* [ ] rofimoji emoji dropdown -- clipboard
|
||||
* [ ] show current mode
|
||||
* [-] hide cursor
|
||||
* [-] dropdown calculator -- rofi on X -- could use `qalc` directly
|
||||
* [-] modes: media, academia (worth?)
|
||||
* [-] picture in terminal, a-la ueberzug
|
||||
* ueberzug is X only
|
||||
* there is sixel rendering for foot, st, xterm, urxvt
|
||||
* alacritty does *not* support sixel rendering [yet](https://github.com/alacritty/alacritty/issues/910), see also [existing sixel implementation](https://github.com/betaboon/alacritty/tree/graphics).
|
||||
* We have sixel support enabled in vifm and foot. It is very wonky, however.
|
||||
|
||||
|
||||
### undecided
|
||||
|
||||
* [ ] polybar -> waybar / yambar
|
||||
* [ ] foot / alacritty
|
||||
|
||||
## River
|
||||
|
||||
River is set up to come close to my old i3 setup.
|
||||
Of course, some mappings are different
|
||||
(especially those for movement between windows),
|
||||
but overall the keys map to the old ones.
|
||||
|
||||
Since the window manager now also takes over the task of compositor
|
||||
and does not pass through all keys to all programs,
|
||||
it takes over the role of `sxhkd` as well and summons other programs.
|
||||
|
||||
I am not entirely sure how I feel about this bundling of tasks into one application,
|
||||
but so far it works.
|
||||
Since river is also, mimicking bspwm, using an executable file
|
||||
(any executable file)
|
||||
as its configuration file it is also reasonable that the setup can be tamed and refactored better than a single i3 configuration file.
|
||||
|
||||
## Waybar
|
||||
|
||||
Waybar replaces the old [polybar](https://gitlab.com/marty-oehme/dotfiles/-/tree/89d1402b3e711c4aa473386e47e84f3593e5ae56/polybar) setup.
|
||||
|
||||
It displays the first 10 tags on its left,
|
||||
with tags highlighted that are either occupied by windows or currently in focus.
|
||||
In the center it displays a clock which can be clicked to open a simple calendar.
|
||||
|
||||
![Simple waybar configuration](.assets/waybar/simple.png)
|
||||
|
||||
To the right is where most of the info modules are:
|
||||
If there are upcoming events listed for the khal application, it will display a calendar module here.
|
||||
If music is playing through an mpris-compatible player, its status is shown here.
|
||||
If a connection through wireguard or over a vpn tunnel is established, it is shown here.
|
||||
Then, from left to right, audio, brightness, wifi, cpu, ram, temperature, and battery information are displayed.
|
||||
|
||||
Some displays have alternative display states, with for example the battery showing remaining time and ram information showing used and total available.
|
||||
|
||||
Clicking on:
|
||||
|
||||
* audio opens pulsemixer
|
||||
* network opens nmtui
|
||||
* cpu opens top (or glances on right-click)
|
||||
* temperature shows sensors
|
||||
|
||||
## keyd
|
||||
|
||||
keyd is set up within `/etc/` and not in the dotfiles themselves.
|
||||
If using the included `./install.sh` file, there is an option to also set up files outside the home directory, including keyd options.
|
||||
It is configured through `/etc/keyd/default.cfg`.
|
||||
Currently, it takes care of mapping `capslock` to both control and escape (depending on if its used alone or with other keys),
|
||||
as well as adding some German characters that I am otherwise missing on my en_US keyboard.
|
||||
Lastly, it allows easy clipboard pasting with the `insert` key.
|
||||
|
||||
## Swaybg
|
||||
|
||||
`swaybg` is used to set the wallpaper from the river configuration file.
|
||||
|