summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules3
-rw-r--r--README.md30
-rw-r--r--desktop-common/.config/dunst/dunstrc315
-rw-r--r--desktop-common/.config/dunst/vaultboy-critical.pngbin0 -> 9267 bytes
-rw-r--r--desktop-common/.config/dunst/vaultboy-low.pngbin0 -> 9457 bytes
-rw-r--r--desktop-common/.config/dunst/vaultboy-normal.pngbin0 -> 9223 bytes
-rw-r--r--desktop-common/.config/rofi-pass/config99
-rw-r--r--desktop-common/.config/rofi/config.rasi28
-rw-r--r--desktop-common/.config/rofi/themes/dark-grid.rasi113
-rw-r--r--desktop-common/.config/rofi/themes/dark.rasi108
-rwxr-xr-xdesktop-common/.local/bin/rofi-power-menu289
-rw-r--r--desktop-common/.local/share/applications/auxilium.desktop9
-rw-r--r--desktop-common/.local/share/applications/fast.desktop9
-rw-r--r--desktop-common/.local/share/applications/kindle.desktop9
-rw-r--r--desktop-common/.local/share/icons/cross.pngbin0 -> 4535 bytes
-rw-r--r--desktop-common/.local/share/icons/kindle.pngbin0 -> 11315 bytes
-rw-r--r--desktop-common/.local/share/icons/st-benedict-cross.pngbin0 -> 25949 bytes
-rw-r--r--desktop-common/dot-Xresources3
-rw-r--r--desktop-wayland/.config/environment.d/path.conf1
-rwxr-xr-xdesktop-wayland/.config/river/init95
-rw-r--r--desktop-wayland/.config/waybar/config.jsonc152
-rw-r--r--desktop-wayland/.config/waybar/gruvbox.css23
-rw-r--r--desktop-wayland/.config/waybar/style.css132
-rwxr-xr-xdesktop-wayland/.local/bin/screenlock-wayland19
-rwxr-xr-xdesktop-x11/.config/bspwm/bspwmrc134
-rw-r--r--desktop-x11/.config/polybar/base.ini73
-rw-r--r--desktop-x11/.config/polybar/colors.ini35
-rw-r--r--desktop-x11/.config/polybar/config.ini49
-rwxr-xr-xdesktop-x11/.config/polybar/launch.sh45
-rw-r--r--desktop-x11/.config/polybar/modules.ini354
-rw-r--r--desktop-x11/.config/sxhkd/sxhkdrc353
-rwxr-xr-xdesktop-x11/.local/bin/rofi-pass868
-rw-r--r--global-common/usr/local/share/backgrounds/abandoned-hut-night.jpgbin0 -> 105644 bytes
-rw-r--r--global-common/usr/local/share/backgrounds/bag-end.jpgbin0 -> 383777 bytes
-rw-r--r--global-common/usr/local/share/backgrounds/book-of-kells.jpgbin0 -> 1795610 bytes
-rw-r--r--global-common/usr/local/share/backgrounds/dore-christ-leaving-the-praetorium.jpgbin0 -> 1409450 bytes
-rw-r--r--global-common/usr/local/share/backgrounds/gandalf-1.jpgbin0 -> 313967 bytes
-rw-r--r--global-common/usr/local/share/backgrounds/gandalf-2.jpgbin0 -> 361704 bytes
-rw-r--r--global-common/usr/local/share/backgrounds/in-hoc-signo-vinces-fire.pngbin0 -> 420242 bytes
-rw-r--r--global-common/usr/local/share/backgrounds/mass.jpgbin0 -> 379570 bytes
-rw-r--r--global-common/usr/local/share/backgrounds/mount-st-michel.jpgbin0 -> 475970 bytes
-rw-r--r--global-common/usr/local/share/backgrounds/odysseus-and-the-sirens-by-waterhouse.jpgbin0 -> 72133 bytes
-rw-r--r--global-common/usr/local/share/backgrounds/old-knight.jpgbin0 -> 286731 bytes
-rw-r--r--global-common/usr/local/share/backgrounds/saint-michael.pngbin0 -> 865127 bytes
-rw-r--r--global-common/usr/local/share/backgrounds/stained-glass-depicting-the-virgin-mary-holding-baby-jesus.jpgbin0 -> 239434 bytes
-rw-r--r--global-common/usr/local/share/backgrounds/the-lamb-of-god.jpgbin0 -> 550910 bytes
-rw-r--r--global-wayland/etc/greetd/config.toml12
-rw-r--r--global-wayland/etc/greetd/environments2
-rw-r--r--global-wayland/etc/greetd/gtkgreet.css56
m---------terminal/.config/tmux/plugins/tmux-current-pane-hostname0
-rw-r--r--terminal/.config/tmux/tmux.conf117
-rwxr-xr-xterminal/.local/bin/urlhandler25
-rw-r--r--terminal/dot-zimrc16
-rw-r--r--terminal/dot-zshrc142
54 files changed, 3718 insertions, 0 deletions
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..b7684b2
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "terminal/.config/tmux/plugins/tmux-current-pane-hostname"]
+ path = terminal/.config/tmux/plugins/tmux-current-pane-hostname
+ url = https://github.com/soyuka/tmux-current-pane-hostname
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e1fa727
--- /dev/null
+++ b/README.md
@@ -0,0 +1,30 @@
+# My Dot Files
+
+Get the submodules with
+
+```sh
+git submodule update --init --recursive
+```
+
+Make the symlinks for the dotfiles with
+
+```sh
+cd dotfiles
+stow -v2 --restow --dotfiles -t ~/ terminal
+stow -v2 --restow --dotfiles -t ~/ desktop-common
+stow -v2 --restow --dotfiles -t ~/ desktop-x11
+stow -v2 --restow --dotfiles -t ~/ desktop-wayland
+```
+
+Now, system wide configs with
+
+```sh
+sudo stow -v2 --restow -t / global-common
+sudo stow -v2 --restow -t / global-wayland
+```
+
+The links can be unstowed with
+```sh
+stow -v2 --dotfiles -t /tmp/foo --delete desktop-common
+sudo stow -v2 --dotfiles -t / --delete global-common
+```
diff --git a/desktop-common/.config/dunst/dunstrc b/desktop-common/.config/dunst/dunstrc
new file mode 100644
index 0000000..9afb74d
--- /dev/null
+++ b/desktop-common/.config/dunst/dunstrc
@@ -0,0 +1,315 @@
+[global]
+ monitor = 2
+ follow = none
+ geometry = "320x320-10+30"
+ indicate_hidden = yes
+ shrink = no
+ transparency = 15
+ notification_height = 0
+ separator_height = 2
+ padding = 8
+ horizontal_padding = 8
+ frame_width = 1
+ frame_color = "#D9D9D9"
+ separator_color = frame
+ sort = yes
+ idle_threshold = 120
+ vertical_alignment = top
+
+ ### Text ###
+
+ font = VictorMono Nerd Font Mono 12
+ # font = BlexMono Nerd Font 11
+ # font = Bitstream Vera Sans 12
+ # font = Source Code Pro Medium 9
+
+ line_height = 0
+ markup = full
+
+ # The format of the message. Possible variables are:
+ # %a appname
+ # %s summary
+ # %b body
+ # %i iconname (including its path)
+ # %I iconname (without its path)
+ # %p progress value if set ([ 0%] to [100%]) or nothing
+ # %n progress value if set without any extra characters
+ # %% Literal %
+ # Markup is allowed
+ # format = "<b>%s</b>\n%b\n%p\n%n"
+ format = "<b>%s</b>\n%b"
+
+ alignment = left
+
+ show_age_threshold = 60
+ word_wrap = yes
+ ellipsize = middle
+ ignore_newline = no
+ stack_duplicates = true
+ hide_duplicate_count = false
+ show_indicators = yes
+
+ ### Icons ###
+
+ # Align icons left/right/off
+ icon_position = left
+
+ # Scale larger icons down to this size, set to 0 to disable
+ min_icon_size = 32
+ max_icon_size = 96
+ icon_corner_radius = 5
+ icon_path = /usr/share/icons/gnome/32x32/status/:/usr/share/icons/gnome/32x32/devices/:/usr/share/icons/gnome/16x16/status/:/usr/share/icons/gnome/16x16/devices/
+
+ ### Progress Bar ###
+
+ progress_bar = true
+ progress_bar_height = 10
+ progress_bar_frame_width = 1
+ progress_bar_min_width = 160
+ progress_bar_max_width = 300
+ progress_bar_corner_radius = 4
+
+ ### History ###
+
+ # Should a notification popped up from history be sticky or timeout
+ # as if it would normally do.
+ sticky_history = yes
+
+ # Maximum amount of notifications kept in history
+ history_length = 20
+
+ ### Misc/Advanced ###
+
+ # dmenu path.
+ dmenu = /usr/bin/rofi -dmenu -p dunst:
+
+ # Browser for opening urls in context menu.
+ # browser = /usr/bin/surf
+ browser = /usr/bin/xdg-open
+
+ # Always run rule-defined scripts, even if the notification is suppressed
+ always_run_script = true
+
+ # Define the title of the windows spawned by dunst
+ title = Dunst
+
+ # Define the class of the windows spawned by dunst
+ class = Dunst
+
+ # Print a notification on startup.
+ # This is mainly for error detection, since dbus (re-)starts dunst
+ # automatically after a crash.
+ startup_notification = false
+
+ # Manage dunst's desire for talking
+ # Can be one of the following values:
+ # crit: Critical features. Dunst aborts
+ # warn: Only non-fatal warnings
+ # mesg: Important Messages
+ # info: all unimportant stuff
+ # debug: all less than unimportant stuff
+ verbosity = mesg
+
+ # Define the corner radius of the notification window
+ # in pixel size. If the radius is 0, you have no rounded
+ # corners.
+ # The radius will be automatically lowered if it exceeds half of the
+ # notification height to avoid clipping text and/or icons.
+ corner_radius = 6
+
+ ### Legacy
+
+ # Use the Xinerama extension instead of RandR for multi-monitor support.
+ # This setting is provided for compatibility with older nVidia drivers that
+ # do not support RandR and using it on systems that support RandR is highly
+ # discouraged.
+ #
+ # By enabling this setting dunst will not be able to detect when a monitor
+ # is connected or disconnected which might break follow mode if the screen
+ # layout changes.
+ force_xinerama = false
+
+ ### mouse
+
+ # Defines action of mouse event
+ # Possible values are:
+ # * none: Don't do anything.
+ # * do_action: If the notification has exactly one action, or one is marked as default,
+ # invoke it. If there are multiple and no default, open the context menu.
+ # * close_current: Close current notification.
+ # * close_all: Close all notifications.
+ mouse_left_click = close_current
+ mouse_middle_click = do_action
+ mouse_right_click = close_all
+
+# Experimental features that may or may not work correctly. Do not expect them
+# to have a consistent behaviour across releases.
+[experimental]
+ # Calculate the dpi to use on a per-monitor basis.
+ # If this setting is enabled the Xft.dpi value will be ignored and instead
+ # dunst will attempt to calculate an appropriate dpi value for each monitor
+ # using the resolution and physical size. This might be useful in setups
+ # where there are multiple screens with very different dpi values.
+ per_monitor_dpi = false
+
+[shortcuts]
+
+ # Shortcuts are specified as [modifier+][modifier+]...key
+ # Available modifiers are "ctrl", "mod1" (the alt-key), "mod2",
+ # "mod3" and "mod4" (windows-key).
+ # Xev might be helpful to find names for keys.
+
+ # Close notification.
+ close = ctrl+shift+grave
+
+ # Close all notifications.
+ close_all = ctrl+shift+alt+grave
+
+ # Redisplay last message(s).
+ # On the US keyboard layout "grave" is normally above TAB and left
+ # of "1". Make sure this key actually exists on your keyboard layout,
+ # e.g. check output of 'xmodmap -pke'
+ history = ctrl+grave
+
+ # Context menu.
+ context = ctrl+shift+period
+
+[urgency_low]
+ background = "#F9E8A3"
+ foreground = "#427EB4"
+ highlight = "#427EB4"
+ timeout = 10
+ icon = ~/.config/dunst/vaultboy-low.png
+
+[urgency_normal]
+ background = "#32598C"
+ foreground = "#E9C651"
+ highlight = "#E9C651"
+ timeout = 10
+ icon = ~/.config/dunst/vaultboy-normal.png
+ override_pause_level = 49
+
+[urgency_critical]
+ background = "#A63C45"
+ foreground = "#FBFBFB"
+ frame_color = "#F25252"
+ timeout = 0
+ icon = ~/.config/dunst/vaultboy-critical.png
+ override_pause_level = 89
+
+# Every section that isn't one of the above is interpreted as a rules to
+# override settings for certain messages.
+#
+# Messages can be matched by
+# appname (discouraged, see desktop_entry)
+# body
+# category
+# desktop_entry
+# icon
+# match_transient
+# msg_urgency
+# stack_tag
+# summary
+#
+# and you can override the
+# background
+# foreground
+# format
+# frame_color
+# fullscreen
+# new_icon
+# set_stack_tag
+# set_transient
+# timeout
+# urgency
+#
+# Shell-like globbing will get expanded.
+#
+# Instead of the appname filter, it's recommended to use the desktop_entry filter.
+# GLib based applications export their desktop-entry name. In comparison to the appname,
+# the desktop-entry won't get localized.
+#
+# SCRIPTING
+# You can specify a script that gets run when the rule matches by
+# setting the "script" option.
+# The script will be called as follows:
+# script appname summary body icon urgency
+# where urgency can be "LOW", "NORMAL" or "CRITICAL".
+#
+# NOTE: if you don't want a notification to be displayed, set the format
+# to "".
+# NOTE: It might be helpful to run dunst -print in a terminal in order
+# to find fitting options for rules.
+
+# Disable the transient hint so that idle_threshold cannot be bypassed from the
+# client
+#[transient_disable]
+# match_transient = yes
+# set_transient = no
+#
+# Make the handling of transient notifications more strict by making them not
+# be placed in history.
+#[transient_history_ignore]
+# match_transient = yes
+# history_ignore = yes
+
+# fullscreen values
+# show: show the notifications, regardless if there is a fullscreen window opened
+# delay: displays the new notification, if there is no fullscreen window active
+# If the notification is already drawn, it won't get undrawn.
+# pushback: same as delay, but when switching into fullscreen, the notification will get
+# withdrawn from screen again and will get delayed like a new notification
+#[fullscreen_delay_everything]
+# fullscreen = delay
+#[fullscreen_show_critical]
+# msg_urgency = critical
+# fullscreen = show
+
+#[espeak]
+# summary = "*"
+# script = dunst_espeak.sh
+
+#[script-test]
+# summary = "*script*"
+# script = dunst_test.sh
+
+#[ignore]
+# # This notification will not be displayed
+# summary = "foobar"
+# format = ""
+
+#[history-ignore]
+# # This notification will not be saved in history
+# summary = "foobar"
+# history_ignore = yes
+
+#[skip-display]
+# # This notification will not be displayed, but will be included in the history
+# summary = "foobar"
+# skip_display = yes
+
+#[signed_on]
+# appname = Pidgin
+# summary = "*signed on*"
+# urgency = low
+#
+#[signed_off]
+# appname = Pidgin
+# summary = *signed off*
+# urgency = low
+#
+#[says]
+# appname = Pidgin
+# summary = *says*
+# urgency = critical
+#
+#[twitter]
+# appname = Pidgin
+# summary = *twitter.com*
+# urgency = normal
+#
+#[stack-volumes]
+# appname = "some_volume_notifiers"
+# set_stack_tag = "volume"
+#
+# vim: ft=cfg
diff --git a/desktop-common/.config/dunst/vaultboy-critical.png b/desktop-common/.config/dunst/vaultboy-critical.png
new file mode 100644
index 0000000..f7862a6
--- /dev/null
+++ b/desktop-common/.config/dunst/vaultboy-critical.png
Binary files differ
diff --git a/desktop-common/.config/dunst/vaultboy-low.png b/desktop-common/.config/dunst/vaultboy-low.png
new file mode 100644
index 0000000..a97f5ff
--- /dev/null
+++ b/desktop-common/.config/dunst/vaultboy-low.png
Binary files differ
diff --git a/desktop-common/.config/dunst/vaultboy-normal.png b/desktop-common/.config/dunst/vaultboy-normal.png
new file mode 100644
index 0000000..a294c3c
--- /dev/null
+++ b/desktop-common/.config/dunst/vaultboy-normal.png
Binary files differ
diff --git a/desktop-common/.config/rofi-pass/config b/desktop-common/.config/rofi-pass/config
new file mode 100644
index 0000000..7bcea7a
--- /dev/null
+++ b/desktop-common/.config/rofi-pass/config
@@ -0,0 +1,99 @@
+# permanently set alternative root dir. Use ":" to separate multiple roots
+# which can be switched at runtime with shift+left/right
+# root=/path/to/root
+
+# rofi command. Make sure to have "$@" as last argument
+_rofi () {
+ rofi -i -no-auto-select "$@"
+}
+
+# default command to generate passwords
+_pwgen () {
+ pwgen -y "$@"
+}
+
+# image viewer to display qrcode of selected entry
+# qrencode is needed to generate the image and a viewer
+# that can read from pipes. Known viewers to work are feh and display
+_image_viewer () {
+ sxiv -
+# display
+}
+
+# xdotool needs the keyboard layout to be set using setxkbmap
+# You can do this in your autostart scripts (e.g. xinitrc)
+
+# If for some reason, you cannot do this, you can set the command here.
+# and set fix_layout to true
+fix_layout=false
+
+layout_cmd () {
+ setxkbmap us
+}
+
+# fields to be used
+URL_field='url'
+USERNAME_field='user'
+AUTOTYPE_field='autotype'
+
+# delay to be used for :delay keyword
+delay=2
+
+# rofi-pass needs to close itself before it can type passwords. Set delay here.
+wait=0.2
+
+# delay between keypresses when typing (in ms)
+xdotool_delay=12
+
+## Programs to be used
+# Editor
+EDITOR='nvim -f'
+
+# Browser
+BROWSER='xdg-open'
+
+## Misc settings
+
+default_do='menu' # menu, autotype, copyPass, typeUser, typePass, copyUser, copyUrl, viewEntry, typeMenu, actionMenu, copyMenu, openUrl
+auto_enter='false'
+notify='false'
+default_autotype='pass'
+
+# color of the help messages
+# leave empty for autodetection
+help_color="#4872FF"
+
+# Clipboard settings
+# Possible options: primary, clipboard, both
+clip=primary
+
+# Seconds before clearing pass from clipboard
+clip_clear=45
+
+## Options for generating new password entries
+
+# open new password entries in editor
+edit_new_pass="true"
+
+# default_user is also used for password files that have no user field.
+#default_user="${ROFI_PASS_DEFAULT_USER-$(whoami)}"
+#default_user2=mary_ann
+#password_length=12
+
+# Custom Keybindings
+autotype="Alt+1"
+type_user="Alt+2"
+type_pass="Alt+3"
+open_url="Alt+4"
+copy_name="Alt+u"
+copy_url="Alt+l"
+copy_pass="Alt+p"
+show="Alt+o"
+copy_entry="Alt+2"
+type_entry="Alt+1"
+copy_menu="Alt+c"
+action_menu="Alt+a"
+type_menu="Alt+t"
+help="Alt+h"
+switch="Alt+x"
+insert_pass="Alt+n"
diff --git a/desktop-common/.config/rofi/config.rasi b/desktop-common/.config/rofi/config.rasi
new file mode 100644
index 0000000..474a160
--- /dev/null
+++ b/desktop-common/.config/rofi/config.rasi
@@ -0,0 +1,28 @@
+configuration {
+ modi: "drun,window,run";
+
+ /*display-drun: "➤";*/
+ display-drun: "󰚌";
+ display-window: "";
+ display-run: "";
+ display-filebrowser: "";
+
+ show-icons: true;
+
+ window {
+ hide-active-window: true;
+ }
+
+ filebrowser {
+ directory: "/home/setanta/storage/Downloads/images/";
+ directories-first: false;
+ sorting-method: "atime";
+ command: "show_image_and_copy_to_clipboard";
+ }
+}
+
+@theme "/home/setanta/.config/rofi/themes/dark.rasi"
+
+/*
+* vim:ft=css
+**/
diff --git a/desktop-common/.config/rofi/themes/dark-grid.rasi b/desktop-common/.config/rofi/themes/dark-grid.rasi
new file mode 100644
index 0000000..35a4d49
--- /dev/null
+++ b/desktop-common/.config/rofi/themes/dark-grid.rasi
@@ -0,0 +1,113 @@
+* {
+ font: "VictorMono Nerd Font Mono Bold 14";
+
+ bg0: #1D1D1F;
+ bg1: #2D2D2D;
+ bg2: #333333;
+
+ fg0: #EEEEEE;
+ fg1: #CECECE;
+
+ /*prompt-color: #E9C651;*/
+ prompt-color: #FEFAD4;
+ active-color: #629c81;
+ urgent-color: #C43513;
+
+ background-color: transparent;
+ text-color: @fg1;
+
+ margin: 0;
+ padding: 0;
+ spacing: 0;
+}
+
+window {
+ location: center;
+ width: 1000;
+ background-color: @bg1;
+ padding: 8px;
+ border-radius: 10px;
+ border: 1px;
+ border-color: @prompt-color;
+}
+
+inputbar {
+ spacing: 10px;
+ padding: 10px;
+ background-color: @bg0;
+ border: 0 0 1px 0;
+ border-radius: 6px 6px 0 0;
+ border-color: @prompt-color;
+ margin: 0 0 8px 0;
+}
+
+prompt {
+ padding: 2px;
+}
+
+prompt, entry, element-icon, element-text {
+ vertical-align: 0.5;
+}
+
+prompt, entry {
+ text-color: @prompt-color;
+}
+
+textbox {
+ padding: 8px;
+ background-color: @bg2;
+}
+
+listview {
+ padding: 12px 0;
+ lines: 3;
+ columns: 4;
+ fixed-height: false;
+}
+
+element {
+ orientation: vertical;
+ border: 2px;
+ border-radius: 8px;
+ padding: 6px;
+ spacing: 6px;
+}
+
+element normal normal {
+ background-color: @bg2;
+ text-color: @fg1;
+}
+
+element normal urgent {
+ text-color: @urgent-color;
+}
+
+element normal active {
+ text-color: @active-color;
+}
+
+element selected {
+ text-color: @bg0;
+ border-radius: 4px;
+}
+
+element selected normal, element selected active {
+ background-color: @active-color;
+}
+
+element selected urgent {
+ background-color: @urgent-color;
+}
+
+element-icon {
+ size: 150px;
+ cursor: inherit;
+}
+
+element-icon, element-text {
+ horizontal-align: 0.5;
+}
+
+/*
+* vim:ft=css
+**/
diff --git a/desktop-common/.config/rofi/themes/dark.rasi b/desktop-common/.config/rofi/themes/dark.rasi
new file mode 100644
index 0000000..bd7f862
--- /dev/null
+++ b/desktop-common/.config/rofi/themes/dark.rasi
@@ -0,0 +1,108 @@
+* {
+ font: "VictorMono Nerd Font Mono Bold 14";
+
+ bg0: #1D1D1F;
+ bg1: #2D2D2D;
+ bg2: #333333;
+
+ fg0: #EEEEEE;
+ fg1: #CECECE;
+
+ /*prompt-color: #E9C651;*/
+ prompt-color: #FEFAD4;
+ active-color: #629c81;
+ urgent-color: #C43513;
+
+ background-color: transparent;
+ text-color: @fg1;
+
+ margin: 0;
+ padding: 0;
+ spacing: 0;
+}
+
+window {
+ location: center;
+ width: 700;
+ background-color: @bg1;
+ padding: 8px;
+ border-radius: 10px;
+ border: 1px;
+ border-color: @prompt-color;
+}
+
+inputbar {
+ spacing: 10px;
+ padding: 10px;
+ background-color: @bg0;
+ border: 0 0 1px 0;
+ border-radius: 6px 6px 0 0;
+ border-color: @prompt-color;
+ margin: 0 0 8px 0;
+}
+
+prompt {
+ padding: 2px;
+}
+
+prompt, entry, element-icon, element-text {
+ vertical-align: 0.5;
+}
+
+prompt, entry {
+ text-color: @prompt-color;
+}
+
+textbox {
+ padding: 8px;
+ background-color: @bg2;
+}
+
+listview {
+ padding: 2px 0;
+ lines: 5;
+ columns: 1;
+ fixed-height: false;
+}
+
+element {
+ padding: 6px;
+ spacing: 6px;
+}
+
+element normal normal {
+ background-color: @bg2;
+ text-color: @fg1;
+}
+
+element normal urgent {
+ text-color: @urgent-color;
+}
+
+element normal active {
+ text-color: @active-color;
+}
+
+element selected {
+ text-color: @bg0;
+ border-radius: 4px;
+}
+
+element selected normal, element selected active {
+ background-color: @active-color;
+}
+
+element selected urgent {
+ background-color: @urgent-color;
+}
+
+element-icon {
+ size: 1.6em;
+}
+element-text {
+ text-color: inherit;
+}
+
+/*
+* vim:ft=css
+**/
diff --git a/desktop-common/.local/bin/rofi-power-menu b/desktop-common/.local/bin/rofi-power-menu
new file mode 100755
index 0000000..5f11b2f
--- /dev/null
+++ b/desktop-common/.local/bin/rofi-power-menu
@@ -0,0 +1,289 @@
+#!/usr/bin/env bash
+
+# This script defines just a mode for rofi instead of being a self-contained
+# executable that launches rofi by itself. This makes it more flexible than
+# running rofi inside this script as now the user can call rofi as one pleases.
+# For instance:
+#
+# rofi -show powermenu -modi powermenu:./rofi-power-menu
+#
+# See README.md for more information.
+
+set -e
+set -u
+
+# All supported choices
+all=(shutdown reboot suspend hibernate logout lockscreen)
+
+# By default, show all (i.e., just copy the array)
+show=("${all[@]}")
+
+declare -A texts
+texts[lockscreen]="lock screen"
+texts[switchuser]="switch user"
+texts[logout]="log out"
+texts[suspend]="suspend"
+texts[hibernate]="hibernate"
+texts[reboot]="reboot"
+texts[shutdown]="shut down"
+
+declare -A icons
+# icons[lockscreen]="\Uf033e" # 󰌾
+# icons[switchuser]="\Uf0019" # 󰀙
+# icons[logout]="\Uf0343" # 󰍃
+# icons[suspend]="\Uf04b2" # 󰒲
+# icons[hibernate]="\Uf02ca" # 󰋊
+# icons[reboot]="\Uf0709" # 󰜉
+# icons[shutdown]="\Uf0425" # 󰐥
+# icons[cancel]="\Uf0156" # 󰅖
+icons[lockscreen]=""
+icons[switchuser]=""
+icons[logout]=""
+icons[suspend]="💤"
+icons[hibernate]=""
+icons[reboot]="↺"
+icons[shutdown]=""
+icons[cancel]="🗙"
+
+declare -A actions
+# actions[lockscreen]="loginctl lock-session ${XDG_SESSION_ID-}"
+actions[lockscreen]="i3lock -ti $HOME/Dropbox/Images/wallpapers/jeff-dragon.png"
+#actions[switchuser]="???"
+actions[logout]="loginctl terminate-session ${XDG_SESSION_ID-}"
+actions[suspend]="systemctl suspend"
+actions[hibernate]="systemctl hibernate"
+actions[reboot]="systemctl reboot"
+actions[shutdown]="systemctl poweroff"
+
+# By default, ask for confirmation for actions that are irreversible
+confirmations=(reboot shutdown logout)
+
+# By default, no dry run
+dryrun=false
+showsymbols=true
+showtext=true
+
+function check_valid {
+ option="$1"
+ shift 1
+ for entry in "${@}"
+ do
+ if [ -z "${actions[$entry]+x}" ]
+ then
+ echo "Invalid choice in $1: $entry" >&2
+ exit 1
+ fi
+ done
+}
+
+# Parse command-line options
+parsed=$(getopt --options=h --longoptions=help,dry-run,confirm:,choices:,choose:,symbols,no-symbols,text,no-text,symbols-font: --name "$0" -- "$@")
+if [ $? -ne 0 ]; then
+ echo 'Terminating...' >&2
+ exit 1
+fi
+eval set -- "$parsed"
+unset parsed
+while true; do
+ case "$1" in
+ "-h"|"--help")
+ echo "rofi-power-menu - a power menu mode for Rofi"
+ echo
+ echo "Usage: rofi-power-menu [--choices CHOICES] [--confirm CHOICES]"
+ echo " [--choose CHOICE] [--dry-run] [--symbols|--no-symbols]"
+ echo
+ echo "Use with Rofi in script mode. For instance, to ask for shutdown or reboot:"
+ echo
+ echo " rofi -show menu -modi \"menu:rofi-power-menu --choices=shutdown/reboot\""
+ echo
+ echo "Available options:"
+ echo " --dry-run Don't perform the selected action but print it to stderr."
+ echo " --choices CHOICES Show only the selected choices in the given order. Use /"
+ echo " as the separator. Available choices are lockscreen,"
+ echo " logout,suspend, hibernate, reboot and shutdown. By"
+ echo " default, all available choices are shown."
+ echo " --confirm CHOICES Require confirmation for the gives choices only. Use / as"
+ echo " the separator. Available choices are lockscreen, logout,"
+ echo " suspend, hibernate, reboot and shutdown. By default, only"
+ echo " irreversible actions logout, reboot and shutdown require"
+ echo " confirmation."
+ echo " --choose CHOICE Preselect the given choice and only ask for a"
+ echo " confirmation (if confirmation is set to be requested). It"
+ echo " is strongly recommended to combine this option with"
+ echo " --confirm=CHOICE if the choice wouldn't require"
+ echo " confirmation by default. Available choices are"
+ echo " lockscreen, logout, suspend, hibernate, reboot and"
+ echo " shutdown."
+ echo " --[no-]symbols Show Unicode symbols or not. Requires a font with support"
+ echo " for the symbols. Use, for instance, fonts from the"
+ echo " Nerdfonts collection. By default, they are shown"
+ echo " --[no-]text Show text description or not."
+ echo " --symbols-font FONT Use the given font for symbols. By default, the symbols"
+ echo " use the same font as the text. That font is configured"
+ echo " with rofi."
+ echo " -h,--help Show this help text."
+ exit 0
+ ;;
+ "--dry-run")
+ dryrun=true
+ shift 1
+ ;;
+ "--confirm")
+ IFS='/' read -ra confirmations <<< "$2"
+ check_valid "$1" "${confirmations[@]}"
+ shift 2
+ ;;
+ "--choices")
+ IFS='/' read -ra show <<< "$2"
+ check_valid "$1" "${show[@]}"
+ shift 2
+ ;;
+ "--choose")
+ # Check that the choice is valid
+ check_valid "$1" "$2"
+ selectionID="$2"
+ shift 2
+ ;;
+ "--symbols")
+ showsymbols=true
+ shift 1
+ ;;
+ "--no-symbols")
+ showsymbols=false
+ shift 1
+ ;;
+ "--text")
+ showtext=true
+ shift 1
+ ;;
+ "--no-text")
+ showtext=false
+ shift 1
+ ;;
+ "--symbols-font")
+ symbols_font="$2"
+ shift 2
+ ;;
+ "--")
+ shift
+ break
+ ;;
+ *)
+ echo "Internal error" >&2
+ exit 1
+ ;;
+ esac
+done
+
+if [ "$showsymbols" = "false" -a "$showtext" = "false" ]
+then
+ echo "Invalid options: cannot have --no-symbols and --no-text enabled at the same time." >&2
+ exit 1
+fi
+
+# Define the messages after parsing the CLI options so that it is possible to
+# configure them in the future.
+
+function write_message {
+ if [ -z ${symbols_font+x} ];
+ then
+ icon="<span font_size=\"medium\">$1</span>"
+ else
+ icon="<span font=\"${symbols_font}\" font_size=\"medium\">$1</span>"
+ fi
+ text="<span font_size=\"medium\">$2</span>"
+ if [ "$showsymbols" = "true" ]
+ then
+ if [ "$showtext" = "true" ]
+ then
+ echo -n "\u200e$icon \u2068$text\u2069"
+ else
+ echo -n "\u200e$icon"
+ fi
+ else
+ echo -n "$text"
+ fi
+}
+
+function print_selection {
+ echo -e "$1" | $(read -r -d '' entry; echo "echo $entry")
+}
+
+declare -A messages
+declare -A confirmationMessages
+for entry in "${all[@]}"
+do
+ messages[$entry]=$(write_message "${icons[$entry]}" "${texts[$entry]^}")
+done
+for entry in "${all[@]}"
+do
+ confirmationMessages[$entry]=$(write_message "${icons[$entry]}" "Yes, ${texts[$entry]}")
+done
+confirmationMessages[cancel]=$(write_message "${icons[cancel]}" "No, cancel")
+
+if [ $# -gt 0 ]
+then
+ # If arguments given, use those as the selection
+ selection="${@}"
+else
+ # Otherwise, use the CLI passed choice if given
+ if [ -n "${selectionID+x}" ]
+ then
+ selection="${messages[$selectionID]}"
+ fi
+fi
+
+# Don't allow custom entries
+echo -e "\0no-custom\x1ftrue"
+# Use markup
+echo -e "\0markup-rows\x1ftrue"
+
+if [ -z "${selection+x}" ]
+then
+ echo -e "\0prompt\x1fPower menu"
+ for entry in "${show[@]}"
+ do
+ echo -e "${messages[$entry]}\0icon\x1f${icons[$entry]}"
+ done
+else
+ for entry in "${show[@]}"
+ do
+ if [ "$selection" = "$(print_selection "${messages[$entry]}")" ]
+ then
+ # Check if the selected entry is listed in confirmation requirements
+ for confirmation in "${confirmations[@]}"
+ do
+ if [ "$entry" = "$confirmation" ]
+ then
+ # Ask for confirmation
+ echo -e "\0prompt\x1fAre you sure"
+ echo -e "${confirmationMessages[$entry]}\0icon\x1f${icons[$entry]}"
+ echo -e "${confirmationMessages[cancel]}\0icon\x1f${icons[cancel]}"
+ exit 0
+ fi
+ done
+ # If not, then no confirmation is required, so mark confirmed
+ selection=$(print_selection "${confirmationMessages[$entry]}")
+ fi
+ if [ "$selection" = "$(print_selection "${confirmationMessages[$entry]}")" ]
+ then
+ if [ $dryrun = true ]
+ then
+ # Tell what would have been done
+ echo "Selected: $entry" >&2
+ else
+ # Perform the action
+ ${actions[$entry]}
+ fi
+ exit 0
+ fi
+ if [ "$selection" = "$(print_selection "${confirmationMessages[cancel]}")" ]
+ then
+ # Do nothing
+ exit 0
+ fi
+ done
+ # The selection didn't match anything, so raise an error
+ echo "Invalid selection: $selection" >&2
+ exit 1
+fi
diff --git a/desktop-common/.local/share/applications/auxilium.desktop b/desktop-common/.local/share/applications/auxilium.desktop
new file mode 100644
index 0000000..ffe7553
--- /dev/null
+++ b/desktop-common/.local/share/applications/auxilium.desktop
@@ -0,0 +1,9 @@
+#!/usr/bin/env xdg-open
+[Desktop Entry]
+Type=Application
+Name=Auxilium Christianorum
+GenericName=Auxilium Christianorum
+Exec=surf http://www.hitektek.com/auxilium
+Icon=st-benedict-cross
+Terminal=false
+Categories=Network;WebBrowser;
diff --git a/desktop-common/.local/share/applications/fast.desktop b/desktop-common/.local/share/applications/fast.desktop
new file mode 100644
index 0000000..011b9a6
--- /dev/null
+++ b/desktop-common/.local/share/applications/fast.desktop
@@ -0,0 +1,9 @@
+#!/usr/bin/env xdg-open
+[Desktop Entry]
+Type=Application
+Name=FAST
+GenericName=Internet Speed Measurement
+Exec=surf https://fast.com/
+Icon=applications-internet
+Terminal=false
+Categories=Network;WebBrowser;
diff --git a/desktop-common/.local/share/applications/kindle.desktop b/desktop-common/.local/share/applications/kindle.desktop
new file mode 100644
index 0000000..2c72c09
--- /dev/null
+++ b/desktop-common/.local/share/applications/kindle.desktop
@@ -0,0 +1,9 @@
+#!/usr/bin/env xdg-open
+[Desktop Entry]
+Type=Application
+Name=Kindle Reader
+GenericName=Kindle Reader
+Exec=/usr/bin/surf https://ler.amazon.com.br/kindle-library
+Icon=kindle
+Terminal=false
+Categories=Books; Reading;
diff --git a/desktop-common/.local/share/icons/cross.png b/desktop-common/.local/share/icons/cross.png
new file mode 100644
index 0000000..7cea122
--- /dev/null
+++ b/desktop-common/.local/share/icons/cross.png
Binary files differ
diff --git a/desktop-common/.local/share/icons/kindle.png b/desktop-common/.local/share/icons/kindle.png
new file mode 100644
index 0000000..344f89a
--- /dev/null
+++ b/desktop-common/.local/share/icons/kindle.png
Binary files differ
diff --git a/desktop-common/.local/share/icons/st-benedict-cross.png b/desktop-common/.local/share/icons/st-benedict-cross.png
new file mode 100644
index 0000000..0fc01ba
--- /dev/null
+++ b/desktop-common/.local/share/icons/st-benedict-cross.png
Binary files differ
diff --git a/desktop-common/dot-Xresources b/desktop-common/dot-Xresources
new file mode 100644
index 0000000..d667ad7
--- /dev/null
+++ b/desktop-common/dot-Xresources
@@ -0,0 +1,3 @@
+Sxiv.background: #080F05
+Sxiv.foreground: #8AEABC
+*TkTheme: clam
diff --git a/desktop-wayland/.config/environment.d/path.conf b/desktop-wayland/.config/environment.d/path.conf
new file mode 100644
index 0000000..9cb7e8f
--- /dev/null
+++ b/desktop-wayland/.config/environment.d/path.conf
@@ -0,0 +1 @@
+PATH=$HOME/.local/bin:$PATH
diff --git a/desktop-wayland/.config/river/init b/desktop-wayland/.config/river/init
new file mode 100755
index 0000000..f0d9b9d
--- /dev/null
+++ b/desktop-wayland/.config/river/init
@@ -0,0 +1,95 @@
+# -------------------------------------------------------------------------------------------------
+# Key bindings
+
+# Workspaces
+for i in $(seq 1 10); do
+ tags=$((1 << ($i - 1)))
+ n=$(($i % 10))
+ riverctl map normal Super $n set-focused-tags $tags
+ riverctl map normal Super+Shift $n set-view-tags $tags
+ riverctl map normal Super+Control $n toggle-focused-tags $tags
+ riverctl map normal Super+Shift+Control $n toggle-view-tags $tags
+done
+
+# Terminal
+riverctl map normal Super Return spawn st
+riverctl map normal Super+Shift Return spawn "st -e tmux"
+riverctl map normal Super+Control Return spawn "st -z 24 -c Floating"
+riverctl map normal Super+Shift+Control Return spawn "st -z 30"
+
+# Notifications
+# Redisplay last message(s).
+riverctl map normal Control grave dunstctl history-pop
+# Close notification.
+riverctl map normal Control+Shift grave dunstctl close
+# Close all notifications.
+riverctl map normal Control+Shift+Alt grave dunstctl close-all
+# Context menu.
+riverctl map normal Control+Shift period dunstctl context
+
+# Launcher
+riverctl map normal Super Space spawn 'rofi -show drun -window-thumbnail -window-format "{w} {t}"'
+riverctl map normal Super P spawn "rofi-pass --last-used -lines 12"
+riverctl map normal Super Q spawn \
+ "rofi -show session-menu -modi 'session-menu:rofi-power-menu --choices=shutdown/reboot/logout/lockscreen'"
+
+# Views (windows)
+riverctl map normal Super F toggle-fullscreen
+riverctl map normal Super S toggle-float
+riverctl map normal Super T zoom
+
+# Move between views
+riverctl map normal Super H focus-view previous
+riverctl map normal Super J focus-view next
+riverctl map normal Super K focus-view previous
+riverctl map normal Super L focus-view next
+
+# Super+Alt+{H,J,K,L} to move views
+riverctl map normal Super+Alt H move left 100
+riverctl map normal Super+Alt J move down 100
+riverctl map normal Super+Alt K move up 100
+riverctl map normal Super+Alt L move right 100
+
+# Super+Alt+Shift+{H,J,K,L} to resize views
+riverctl map normal Super+Alt+Shift H resize horizontal -100
+riverctl map normal Super+Alt+Shift J resize vertical 100
+riverctl map normal Super+Alt+Shift K resize vertical -100
+riverctl map normal Super+Alt+Shift L resize horizontal 100
+
+# Screen
+riverctl map normal Super Escape spawn screenlock-wayland
+
+# Applications
+riverctl map normal Super N spawn nautilus
+riverctl map normal Super O spawn epiphany
+riverctl map normal Super+Control P spawn epiphany --incognito-mode
+
+
+# -------------------------------------------------------------------------------------------------
+# Settings
+
+riverctl keyboard-layout -rules evdev -model evdev -variant altgr-intl -options caps:escape us
+riverctl focus-follows-cursor normal
+riverctl output-layout rivertile
+riverctl border-color-focused 0xfdf070
+riverctl border-color-unfocused 0x345985
+
+# -------------------------------------------------------------------------------------------------
+# Rules
+
+riverctl rule-add -app-id "Floating" float
+
+# -------------------------------------------------------------------------------------------------
+# Processes
+
+riverctl spawn dunst
+riverctl spawn waybar
+riverctl spawn nm-applet
+riverctl spawn "rivertile -view-padding 2 -outer-padding 1 -main-ratio 0.5"
+riverctl spawn "swaybg -i /usr/local/share/backgrounds/dore-christ-leaving-the-praetorium.jpg"
+riverctl spawn "dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=river"
+riverctl spawn "systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=river"
+riverctl spawn "swayidle -w timeout 300 screenlock-wayland \
+ timeout 400 'wlr-randr --output eDP-1 --off' \
+ resume 'wlr-randr --output eDP-1 --on' \
+ before-sleep screenlock-wayland"
diff --git a/desktop-wayland/.config/waybar/config.jsonc b/desktop-wayland/.config/waybar/config.jsonc
new file mode 100644
index 0000000..d3005a9
--- /dev/null
+++ b/desktop-wayland/.config/waybar/config.jsonc
@@ -0,0 +1,152 @@
+{
+ "layer": "top",
+ "position": "top",
+ "height": 18,
+ "modules-left": [
+ "river/tags"
+ ],
+ "modules-center": ["river/window"],
+ "modules-right": [
+ "cpu",
+ "temperature",
+ "memory",
+ "disk",
+ "network#vpn",
+ "network",
+ "clock",
+ "battery",
+ "group/group-power",
+ "tray"
+ ],
+ "idle_inhibitor": {
+ "format": "{icon}",
+ "format-icons": {
+ "activated": "●",
+ "deactivated": "◌"
+ }
+ },
+
+ "river/tags": {
+ "num-tags": 10,
+ "tag-labels": ["I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X"]
+ },
+
+ "cpu": {
+ "interval": 1,
+ "format": " {icon0}{icon1}{icon2}{icon3}{icon4}{icon5}{icon6}{icon7}{icon8}{icon9}{icon10}{icon11}{icon12}{icon13} {usage:>2}%",
+ "format-icons": [
+ "<span color='#69ff94'>▁</span>", // green
+ "<span color='#2aa9ff'>▂</span>", // blue
+ "<span color='#f8f8f2'>▃</span>", // white
+ "<span color='#f8f8f2'>▄</span>", // white
+ "<span color='#ffffa5'>▅</span>", // yellow
+ "<span color='#ffffa5'>▆</span>", // yellow
+ "<span color='#ff9977'>▇</span>", // orange
+ "<span color='#dd532e'>█</span>" // red
+ ]
+ },
+
+ "temperature": {
+ "critical-threshold": 80,
+ "format-critical": " {temperatureC}°C",
+ "format": " {temperatureC}°C"
+ },
+
+ "memory": {
+ "interval": 30,
+ "format": " {}%",
+ "tooltip-format": "{used:0.1f}G / {total:0.1f}G"
+ },
+
+ "disk": {
+ "interval": 30,
+ "format": "󰋊 / {}%",
+ "path": "/"
+ },
+
+ "disk#external": {
+ "interval": 30,
+ "format": "󰋊 / {}%",
+ "path": "/"
+ },
+
+ "battery": {
+ "design-capacity": true,
+ "states": {
+ "good": 95,
+ "warning": 30,
+ "critical": 15
+ },
+ "format": "{capacity}% {icon}",
+ "format-icons": ["", "", "", "", ""]
+ },
+
+ "network": {
+ "format-wifi": " {signalStrength}%",
+ "tooltip-format-wifi": "{essid}",
+ "format-ethernet": "🖧 ↓{bandwidthDownBytes} ↑{bandwidthUpBytes}",
+ "tooltip-format-ethernet": "{ifname}",
+ "format-disconnected": "⚠ Disconnected"
+ },
+
+ "network#vpn": {
+ "interface": "tun0",
+ "format": "󰞇",
+ "format-disconnected": "",
+ "tooltip-format": "{ipaddr}",
+ "max-length": 50
+ },
+
+ "pulseaudio": {
+ "scroll-step": 1,
+ "format": "{volume}% {icon}",
+ "format-bluetooth": "{volume}% {icon}",
+ "format-muted": "",
+ "format-icons": {
+ "headphones": "",
+ "handsfree": "",
+ "headset": "",
+ "phone": "",
+ "portable": "",
+ "car": " ",
+ "default": ["", ""]
+ },
+ "on-click": "pavucontrol"
+ },
+
+ "clock": {
+ "interval": 60,
+ "format": "󰸘 {:%a %b %d, %H:%M (%Z)}",
+ "tooltip-format": "<tt><small>{calendar}</small></tt>",
+ "timezones": [
+ "America/Recife",
+ "America/Austin",
+ "America/Vancouver",
+ "Pacific/Auckland",
+ "Etc/UTC"
+ ],
+ "calendar": {
+ "mode" : "month",
+ "weeks-pos" : "right",
+ "on-scroll" : 1,
+ "on-click-right": "mode",
+ "format": {
+ "months": "<span color='#ffead3'><b>{}</b></span>",
+ "days": "<span color='#ecc6d9'><b>{}</b></span>",
+ "weeks": "<span color='#99ffdd'><b>W{}</b></span>",
+ "weekdays": "<span color='#ffcc66'><b>{}</b></span>",
+ "today": "<span color='#ff6699'><b><u>{}</u></b></span>"
+ }
+ },
+ "actions": {
+ "on-click": "tz_up",
+ "on-click-right": "tz_down",
+ "on-click-middle": "mode"
+ }
+ },
+
+ "tray": {
+ "icon-size": 21,
+ "spacing": 10
+ }
+}
diff --git a/desktop-wayland/.config/waybar/gruvbox.css b/desktop-wayland/.config/waybar/gruvbox.css
new file mode 100644
index 0000000..28a9d8a
--- /dev/null
+++ b/desktop-wayland/.config/waybar/gruvbox.css
@@ -0,0 +1,23 @@
+@define-color background #282828;
+@define-color foreground #ebdbb2;
+@define-color black #282828;
+@define-color red #cc241d;
+@define-color green #98971a;
+@define-color yellow #d79921;
+@define-color blue #458588;
+@define-color magenta #b16286;
+@define-color cyan #689d6a;
+@define-color white #a89984;
+@define-color aqua #689d6a;
+@define-color orange #d65d0e;
+
+@define-color magenta_b #d3869b;
+@define-color cyan_b #8ec07c;
+@define-color yellow_b #fabd2f;
+@define-color white_b #ebdbb2;
+@define-color black_b #928374;
+@define-color red_b #fb4934;
+@define-color green_b #b8bb26;
+@define-color blue_b #83a598;
+@define-color aqua_b #8ec07c;
+@define-color orange_b #fe8010;
diff --git a/desktop-wayland/.config/waybar/style.css b/desktop-wayland/.config/waybar/style.css
new file mode 100644
index 0000000..eb1ef62
--- /dev/null
+++ b/desktop-wayland/.config/waybar/style.css
@@ -0,0 +1,132 @@
+* {
+ border: none;
+ border-radius: 6px;
+ font-family: mononoki Nerd Font Mono;
+ font-size: 14px;
+ min-height: 0;
+}
+
+@import "gruvbox.css";
+
+window#waybar {
+ background: rgba(40, 40, 40, 1);
+ color: @white_b;
+}
+
+#tags button {
+ border-radius: 0;
+ padding: 2px 8px;
+ background: transparent;
+ border-bottom: 1px solid transparent;
+}
+
+#tags button.occupied {
+ background: rgba(255, 255, 255, 0.2);
+ border-bottom: 1px solid transparent;
+}
+
+#tags button.focused {
+ color: #f6af2b;
+ background: #625233;
+ border-bottom: 1px solid #f6af2b;
+}
+
+#tags button:hover {
+ background: rgba(0, 0, 0, 0.2);
+ box-shadow: inherit;
+ /*border-bottom: 1px solid @fg-color;*/
+ border-bottom: 1px solid #f6af2b;
+}
+
+#mode, #clock, #battery {
+ padding: 0 10px;
+ margin: 0 5px;
+}
+
+#mode {
+ background: @red;
+ /* border-bottom: 3px solid @white_b; */
+}
+
+#cpu {
+ background: @black;
+}
+
+#temperature {
+ background: @yellow;
+}
+
+#temperature .value {
+ color: @red;
+}
+
+#memory {
+ background: @orange;
+}
+
+#network {
+ background: @green_b;
+ color: @black;
+}
+
+#network.vpn {
+ background: @green;
+ margin: 0 0 0 3px;
+}
+
+#disk {
+ background: @blue;
+}
+
+#clock {
+ background-color: @aqua_b;
+ color: @black;
+}
+
+#battery {
+ background-color: @white_b;
+ color: @background;
+}
+
+#battery.discharging {
+ color: @white_b;
+ background-color: @red_b;
+}
+
+#battery.charging {
+ color: @black;
+ background-color: @yellow_b;
+}
+
+@keyframes blink {
+ to {
+ background-color: @white_b;
+ color: @background;
+ }
+}
+
+#idle_inhibitor,
+#pulseaudio,
+#custom-openvpn,
+#network,
+#cpu,
+#memory,
+#disk,
+#temperature,
+#backlight,
+#battery,
+#clock,
+#tray {
+ padding: 0 6px;
+ margin: 0 3px;
+}
+
+#battery.warning:not(.charging) {
+ background: @red;
+ color: @white_b;
+ animation-name: blink;
+ animation-duration: 0.5s;
+ animation-timing-function: linear;
+ animation-iteration-count: infinite;
+ animation-direction: alternate;
+}
diff --git a/desktop-wayland/.local/bin/screenlock-wayland b/desktop-wayland/.local/bin/screenlock-wayland
new file mode 100755
index 0000000..f722e0f
--- /dev/null
+++ b/desktop-wayland/.local/bin/screenlock-wayland
@@ -0,0 +1,19 @@
+#!/bin/env bash
+
+BACKGROUND_DIR=/usr/local/share/backgrounds
+IMAGES=(
+ bag-end.jpg
+ book-of-kells.jpg
+ gandalf-1.jpg
+ in-hoc-signo-vinces-fire.png
+ mount-st-michel.jpg
+ odysseus-and-the-sirens-by-waterhouse.jpg
+ saint-michael.png
+)
+IMAGE=$(printf "%s\n" "${IMAGES[@]}" | shuf -n 1)
+
+swaylock --indicator-radius 200 \
+ --indicator-thickness 30 \
+ --show-failed-attempts \
+ --daemonize \
+ --image $BACKGROUND_DIR/$IMAGE
diff --git a/desktop-x11/.config/bspwm/bspwmrc b/desktop-x11/.config/bspwm/bspwmrc
new file mode 100755
index 0000000..1c662f4
--- /dev/null
+++ b/desktop-x11/.config/bspwm/bspwmrc
@@ -0,0 +1,134 @@
+#! /bin/sh
+
+# set -xv
+# exec 2>>/tmp/bspwm.log
+
+pgrep -x sxhkd > /dev/null || sxhkd &
+
+# setxkbmap -rules evdev -model pc105 -layout ck61 -variant ck61 -option caps:escape
+# setxkbmap -option caps:escape
+# xmodmap $HOME/.Xmodmap
+
+# My monitors:
+# DP-2-2
+# HDMI-2
+# eDP-1
+CONNECTED_MONITORS=`xrandr -q | grep -w connected | cut -d ' ' -f1`
+MONITORS_COUNT=`echo "$CONNECTED_MONITORS" | wc -l`
+
+# Network Interfaces for Polybar modules
+NETWORK_INTERFACES=`nmcli -t device | grep -v bridge`
+ETHERNET_INTERFACES=`echo "$NETWORK_INTERFACES" | grep ":ethernet:"`
+ETHERNET_COUNT=`echo "$ETHERNET_INTERFACES" | wc -l`
+ETHER_IFACE=
+if [[ "$ETHERNET_COUNT" == "1" ]]; then
+ ETHER_IFACE=`echo "$ETHERNET_INTERFACES" | cut -d ':' -f1`
+else
+ ETHER_IFACE=`echo "$ETHERNET_INTERFACES" | grep ":connected" | cut -d ':' -f1`
+fi
+WIFI_INTERFACES=`echo "$NETWORK_INTERFACES" | grep ":wifi:"`
+WIFI_COUNT=`echo "$WIFI_INTERFACES" | wc -l`
+WIFI_IFACE=
+if [[ "$WIFI_COUNT" == "1" ]]; then
+ WIFI_IFACE=`echo "$WIFI_INTERFACES" | cut -d ':' -f1`
+else
+ WIFI_IFACE=`echo "$WIFI_INTERFACES" | grep ":connected" | cut -d ':' -f1`
+fi
+
+killall polybar
+xrandr --output eDP-1 --mode 1920x1080
+
+if [ "$MONITORS_COUNT" = "1" ]; then
+ bspc monitor eDP-1 -d I II III IV V VI VII VIII IX X
+ # PRIMARY_MONITOR="eDP-1" WIFI_IFACE="wlp4s0" polybar primary-monitor &
+ PRIMARY_MONITOR="eDP-1" ETHER_IFACE="$ETHER_IFACE" WIFI_IFACE="$WIFI_IFACE" polybar primary-monitor &
+else
+ EXTERNAL_MONITOR=`echo "$CONNECTED_MONITORS" | grep -v "eDP-1" | head -n1`
+ if [ "$EXTERNAL_MONITOR" = "DP-2-1" ] || [ "$EXTERNAL_MONITOR" = "DP-2-2" ]; then
+ EXTERNAL_MONITOR_RESOLUTION="2560x1080"
+ # xrandr --output $EXTERNAL_MONITOR --primary --mode 2560x1080 --left-of eDP-1
+ # bspc monitor eDP-1 -d IX X
+ # bspc monitor $EXTERNAL_MONITOR -d I II III IV V VI VII VIII
+ else
+ EXTERNAL_MONITOR_RESOLUTION="1920x1080"
+ # xrandr --output $EXTERNAL_MONITOR --primary --mode 1920x1080 --left-of eDP-1
+ # bspc monitor eDP-1 -d I II
+ # bspc monitor $EXTERNAL_MONITOR -d III IV V VI VII VIII IX X
+ fi
+ xrandr --output $EXTERNAL_MONITOR --primary --mode $EXTERNAL_MONITOR_RESOLUTION --left-of eDP-1
+ bspc monitor eDP-1 -d IX X
+ bspc monitor $EXTERNAL_MONITOR -d I II III IV V VI VII VIII
+ SECONDARY_MONITOR="eDP-1" polybar secondary-monitor &
+ PRIMARY_MONITOR="$EXTERNAL_MONITOR" ETHER_IFACE="$ETHER_IFACE" WIFI_IFACE="$WIFI_IFACE" polybar primary-monitor &
+fi
+
+bspc config border_width 1
+bspc config window_gap 3
+
+bspc config split_ratio 0.52 # 0.6
+bspc config borderless_monocle false # true
+bspc config gapless_monocle true
+
+bspc config focus_follows_pointer true
+bspc config pointer_follows_focus true
+bspc config pointer_follows_monitor true
+
+# Border colors
+# Original
+# bspc config normal_border_color "#484848"
+# bspc config focused_border_color "#21BA45"
+# bspc config active_border_color "#BA9521"
+# bspc config presel_feedback_color "#E2FF20"
+
+# Vault Tec
+bspc config normal_border_color "#345985"
+bspc config focused_border_color "#FDF070"
+bspc config active_border_color "#5C835E"
+bspc config presel_feedback_color "#A63C45"
+
+# xrdb ${XDG_CONFIG_HOME:-$HOME/.config}/Xresources
+pgrep -x picom > /dev/null || picom &
+pgrep -x unclutter > /dev/null || unclutter &
+pgrep -x dunst > /dev/null || dunst &
+pgrep -x nm-applet > /dev/null || nm-applet &
+# /usr/bin/gnome-keyring-daemon --start --components=ssh
+xset r rate 300 50
+
+feh --bg-fill $HOME/Dropbox/Images/wallpapers/dore-christ-leaving-the-praetorium.jpeg
+# wal -i $HOME/Dropbox/Images/wallpapers/dore-christ-leaving-the-praetorium.jpeg >/dev/null 2>&1
+
+# bspc rule -a Gimp desktop='^8' state=floating follow=on
+# bspc rule -a Chromium desktop='^2'
+# bspc rule -a mplayer2 state=floating
+# bspc rule -a Kupfer.py focus=on
+# bspc rule -a Screenkey manage=off
+
+bspc rule -a Floating state=floating center=true follow=on
+
+bspc rule -a Arandr state=floating
+bspc rule -a Blueman-manager state=floating
+bspc rule -a Cheese state=floating center=true follow=on
+bspc rule -a Clocks state=floating center=true follow=on
+bspc rule -a Eog state=floating center=true follow=on
+bspc rule -a Gitg state=floating center=true follow=on
+bspc rule -a Gitk state=floating center=true follow=on
+bspc rule -a Gnome-calculator state=floating center=true follow=on
+bspc rule -a Gnome-calendar state=floating center=true follow=on
+bspc rule -a Gnome-control-center state=floating center=true follow=on
+bspc rule -a Gnome-screenshot state=floating center=true follow=on
+bspc rule -a Gnome-todo state=floating center=true follow=on
+bspc rule -a Gnome-tweaks state=floating center=true follow=on
+bspc rule -a MuPDF state=floating center=true follow=on
+bspc rule -a Pavucontrol state=floating center=true follow=on
+bspc rule -a Qemu-system-i386 state=floating center=true follow=on
+bspc rule -a Qemu-system-x86_64 state=floating center=true follow=on
+bspc rule -a Signal state=floating
+bspc rule -a SimpleScreenRecorder state=floating center=true follow=on
+bspc rule -a Surf state=floating center=true follow=on
+bspc rule -a Sxiv state=floating center=true follow=on
+bspc rule -a mpv state=floating center=true follow=on
+bspc rule -a "Org.gnome.Characters:*:*" state=floating center=true follow=on
+bspc rule -a "Gpick:*:*" state=floating center=true follow=on
+bspc rule -a "*:*:Picture-in-Picture" state=floating follow=on
+bspc rule -a "*:*:Network Connections" state=floating follow=on
+bspc rule -a gnome-calculator state=floating center=true follow=on
diff --git a/desktop-x11/.config/polybar/base.ini b/desktop-x11/.config/polybar/base.ini
new file mode 100644
index 0000000..807104b
--- /dev/null
+++ b/desktop-x11/.config/polybar/base.ini
@@ -0,0 +1,73 @@
+;==========================================================
+;
+; ██████╗ ██████╗ ██╗ ██╗ ██╗██████╗ █████╗ ██████╗
+; ██╔══██╗██╔═══██╗██║ ╚██╗ ██╔╝██╔══██╗██╔══██╗██╔══██╗
+; ██████╔╝██║ ██║██║ ╚████╔╝ ██████╔╝███████║██████╔╝
+; ██╔═══╝ ██║ ██║██║ ╚██╔╝ ██╔══██╗██╔══██║██╔══██╗
+; ██║ ╚██████╔╝███████╗██║ ██████╔╝██║ ██║██║ ██║
+; ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝
+;
+;==========================================================
+
+[settings]
+; Reload upon receiving XCB_RANDR_SCREEN_CHANGE_NOTIFY events
+screenchange-reload = true
+pseudo-transparency = false
+
+; Compositing operators
+; @see: https://www.cairographics.org/manual/cairo-cairo-t.html#cairo-operator-t
+compositing-background = source
+compositing-foreground = over
+compositing-overline = over
+compositing-underline = over
+compositing-border = over
+
+; Define fallback values used by all module formats
+; format-foreground =
+; format-background =
+; format-underline =
+; format-overline =
+; format-spacing =
+; format-padding =
+; format-margin =
+; format-offset =
+
+[global/wm]
+margin-top = 0
+margin-bottom = 0
+
+[bar/base]
+enable-ipc = true
+
+background = ${colors.background}
+foreground = ${colors.foreground}
+
+font-0 = RobotoMono Nerd Font:style=Medium,Regular:size=8:antialias=true;2
+font-1 = FontAwesome:style=Regular:size=8:antialias=true;1
+font-2 = Symbola:style=Regular:size=8:antialias=true;1
+font-3 = fixed:pixelsize=0;0
+
+width = 100%
+height = 18
+fixed-center = false
+bottom = false
+
+line-size = 2
+line-color = #f00
+
+border-size = 0
+border-color = #00000000
+
+padding-left = 0
+padding-right = 0
+
+module-margin-left = 0
+module-margin-right = 1
+
+scroll-up = i3wm-wsprev
+scroll-down = i3wm-wsnext
+
+cursor-click = pointer
+cursor-scroll = ns-resize
+
+override-redirect = false
diff --git a/desktop-x11/.config/polybar/colors.ini b/desktop-x11/.config/polybar/colors.ini
new file mode 100644
index 0000000..d768194
--- /dev/null
+++ b/desktop-x11/.config/polybar/colors.ini
@@ -0,0 +1,35 @@
+;==========================================================
+;
+; ██████╗ ██████╗ ██╗ ██╗ ██╗██████╗ █████╗ ██████╗
+; ██╔══██╗██╔═══██╗██║ ╚██╗ ██╔╝██╔══██╗██╔══██╗██╔══██╗
+; ██████╔╝██║ ██║██║ ╚████╔╝ ██████╔╝███████║██████╔╝
+; ██╔═══╝ ██║ ██║██║ ╚██╔╝ ██╔══██╗██╔══██║██╔══██╗
+; ██║ ╚██████╔╝███████╗██║ ██████╔╝██║ ██║██║ ██║
+; ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝
+;
+;==========================================================
+
+[colors]
+background = ${xrdb:color0:#cc222222}
+background-alt = #444444
+foreground = ${xrdb:color7:#dfdfdf}
+foreground-alt = #555555
+
+primary = #ffb52a
+secondary = #e60053
+alert = #bd2c40
+
+module-label-foreground = #000000
+module-label-background = #0a6cf5
+module-value-foreground = #000000
+module-value-background = #d0d0d0d0
+
+module-value-intensity-1 = #55aa55
+module-value-intensity-2 = #557755
+module-value-intensity-3 = #f5a70a
+module-value-intensity-4 = #ff5555
+
+module-value-negative-foreground = #7C7772
+module-value-negative-background = #C1BAAD
+
+; vim:ft=dosini
diff --git a/desktop-x11/.config/polybar/config.ini b/desktop-x11/.config/polybar/config.ini
new file mode 100644
index 0000000..82a92fc
--- /dev/null
+++ b/desktop-x11/.config/polybar/config.ini
@@ -0,0 +1,49 @@
+;==========================================================
+;
+; ██████╗ ██████╗ ██╗ ██╗ ██╗██████╗ █████╗ ██████╗
+; ██╔══██╗██╔═══██╗██║ ╚██╗ ██╔╝██╔══██╗██╔══██╗██╔══██╗
+; ██████╔╝██║ ██║██║ ╚████╔╝ ██████╔╝███████║██████╔╝
+; ██╔═══╝ ██║ ██║██║ ╚██╔╝ ██╔══██╗██╔══██║██╔══██╗
+; ██║ ╚██████╔╝███████╗██║ ██████╔╝██║ ██║██║ ██║
+; ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝
+;
+;==========================================================
+
+include-file = ./colors.ini
+include-file = ./base.ini
+include-file = ./modules.ini
+
+[bar/primary-monitor]
+inherit = bar/base
+
+monitor = ${env:PRIMARY_MONITOR}
+
+modules-left = ewmh
+modules-center = xwindow
+modules-right = cpu temperature fs-root fs-storage network-iface-1 network-iface-2 vpn calendar
+
+tray-position = right
+tray-padding = 4
+tray-foreground = ${root.foreground}
+tray-background = ${root.background}
+
+[bar/secondary-monitor]
+inherit = bar/base
+
+monitor = ${env:SECONDARY_MONITOR}
+
+bottom = true
+
+modules-left = ewmh
+; modules-center = mpd
+modules-right = battery pulseaudio xkeyboard
+
+[module/network-iface-1]
+inherit = module/network-eth
+interface = ${env:ETHER_IFACE}
+
+[module/network-iface-2]
+inherit = module/network-wifi
+interface = ${env:WIFI_IFACE}
+
+; vim:ft=dosini
diff --git a/desktop-x11/.config/polybar/launch.sh b/desktop-x11/.config/polybar/launch.sh
new file mode 100755
index 0000000..0704e24
--- /dev/null
+++ b/desktop-x11/.config/polybar/launch.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+# Terminate already running bar instances
+killall -q polybar
+
+# Wait until the processes have been shut down
+while pgrep -x polybar >/dev/null; do sleep 1; done
+
+host=$(hostname)
+
+# My monitors:
+# DP-2-2
+# HDMI-2
+# eDP-1
+LAPTOP_BUILT_IN_MONITOR="eDP-1"
+
+NETWORK_INTERFACES=`nmcli -t device | grep -v bridge`
+
+ETHERNET_INTERFACES=`echo "$NETWORK_INTERFACES" | grep ":ethernet:"`
+ETHERNET_COUNT=`echo "$ETHERNET_INTERFACES" | wc -l`
+ETHER_IFACE=
+if [[ "$ETHERNET_COUNT" == "1" ]]; then
+ ETHER_IFACE=`echo "$ETHERNET_INTERFACES" | cut -d ':' -f1`
+else
+ ETHER_IFACE=`echo "$ETHERNET_INTERFACES" | grep ":connected" | cut -d ':' -f1`
+fi
+
+WIFI_INTERFACES=`echo "$NETWORK_INTERFACES" | grep ":wifi:"`
+WIFI_COUNT=`echo "$WIFI_INTERFACES" | wc -l`
+WIFI_IFACE=
+if [[ "$WIFI_COUNT" == "1" ]]; then
+ WIFI_IFACE=`echo "$WIFI_INTERFACES" | cut -d ':' -f1`
+else
+ WIFI_IFACE=`echo "$WIFI_INTERFACES" | grep ":connected" | cut -d ':' -f1`
+fi
+
+# Launch polybar
+CONNECTED_MONITORS=`xrandr -q | grep -w connected | cut -d ' ' -f1`
+MONITORS_COUNT=`echo "$CONNECTED_MONITORS" | wc -l`
+if [[ "$MONITORS_COUNT" == "1" ]]; then
+ PRIMARY_MONITOR="$CONNECTED_MONITORS" ETHER_IFACE="$ETHER_IFACE" WIFI_IFACE="$WIFI_IFACE" polybar primary-monitor &
+else
+ PRIMARY_MONITOR=`echo "$CONNECTED_MONITORS" | grep -v "$LAPTOP_BUILT_IN_MONITOR" | head -n1` ETHER_IFACE="$ETHER_IFACE" WIFI_IFACE="$WIFI_IFACE" polybar primary-monitor &
+ SECONDARY_MONITOR="$LAPTOP_BUILT_IN_MONITOR" polybar secondary-monitor &
+fi
diff --git a/desktop-x11/.config/polybar/modules.ini b/desktop-x11/.config/polybar/modules.ini
new file mode 100644
index 0000000..c3b2d0e
--- /dev/null
+++ b/desktop-x11/.config/polybar/modules.ini
@@ -0,0 +1,354 @@
+;==========================================================
+;
+; ██████╗ ██████╗ ██╗ ██╗ ██╗██████╗ █████╗ ██████╗
+; ██╔══██╗██╔═══██╗██║ ╚██╗ ██╔╝██╔══██╗██╔══██╗██╔══██╗
+; ██████╔╝██║ ██║██║ ╚████╔╝ ██████╔╝███████║██████╔╝
+; ██╔═══╝ ██║ ██║██║ ╚██╔╝ ██╔══██╗██╔══██║██╔══██╗
+; ██║ ╚██████╔╝███████╗██║ ██████╔╝██║ ██║██║ ██║
+; ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝
+;
+;==========================================================
+
+; Internal modules ------------------------------------------------------------
+
+[module/date]
+type = internal/date
+interval = 5
+time = %H:%M
+format-prefix-foreground = ${colors.foreground-alt}
+format-underline = #0a6cf5
+
+label = %time%
+
+[module/xwindow]
+type = internal/xwindow
+label = %title:0:30:...%
+
+[module/xkeyboard]
+type = internal/xkeyboard
+blacklist-0 = num lock
+
+format-prefix = " ⌨ "
+format-prefix-foreground = ${colors.module-label-foreground}
+format-prefix-background = #219ebc
+format-foreground = ${colors.module-value-foreground}
+format-background = ${colors.module-value-background}
+
+label-layout = " %layout% "
+
+label-indicator-padding = 2
+label-indicator-margin = 1
+label-indicator-background = ${colors.secondary}
+label-indicator-underline = ${colors.secondary}
+
+click-left = ~/.local/bin/fix-keyboard
+
+[fs-base]
+type = internal/fs
+interval = 25
+
+format-unmounted-prefix = ${self.format-mounted-prefix}
+format-unmounted-prefix-foreground = ${self.format-mounted-prefix-foreground}
+format-unmounted-prefix-background = ${self.format-mounted-prefix-background}
+
+label-mounted = " %percentage_free%% free · %free% "
+label-mounted-foreground = ${colors.module-value-foreground}
+label-mounted-background = ${colors.module-value-background}
+
+label-unmounted = " absent "
+label-unmounted-foreground = ${colors.module-value-negative-foreground}
+label-unmounted-background = ${colors.module-value-negative-background}
+
+[module/fs-root]
+inherit = fs-base
+mount-0 = /
+format-mounted-prefix = "  Root "
+format-mounted-prefix-foreground = #005500
+format-mounted-prefix-background = #b0e000
+
+[module/fs-storage]
+inherit = fs-base
+mount-0 = /home/setanta/storage
+format-mounted-prefix = "  External "
+format-mounted-prefix-foreground = #b7f6b9
+format-mounted-prefix-background = #347D39
+
+[module/ewmh]
+type = internal/xworkspaces
+
+pin-workspaces = true
+enable-click = true
+enable-scroll = true
+reverse-scroll = true
+
+format = <label-state>
+
+; Available tokens:
+; %name%
+; %icon%
+; %index%
+; Default: %icon% %name%
+label-active = %name%
+label-active-foreground = ${colors.primary}
+label-active-background = #625233
+
+label-occupied = %name%
+label-occupied-foreground = ${colors.foreground}
+label-occupied-background = ${colors.background-alt}
+
+label-urgent = %name%
+label-urgent-foreground = #ff3a03
+label-urgent-background = #743021
+
+label-font = 2.5
+
+label-active-padding = 1
+label-urgent-padding = 1
+label-occupied-padding = 1
+label-empty-padding = 1
+
+[module/cpu]
+type = internal/cpu
+interval = 5
+format = "<label> <ramp-coreload> "
+format-prefix = "  CPU "
+format-prefix-foreground = #7b0000
+format-prefix-background = #fe8700
+format-foreground = ${colors.module-value-foreground}
+format-background = ${colors.module-value-background}
+label = " %percentage:2%% "
+ramp-coreload-spacing = 2
+ramp-coreload-0 = "%{O-12}%{F#999}▁"
+ramp-coreload-1 = "%{O-12}%{F#977}▂"
+ramp-coreload-2 = "%{O-12}%{F#955}▃"
+ramp-coreload-3 = "%{O-12}%{F#931}▄"
+ramp-coreload-4 = "%{O-12}%{F#900}▅"
+ramp-coreload-5 = "%{O-12}%{F#B00}▆"
+ramp-coreload-6 = "%{O-12}%{F#D00}▇"
+ramp-coreload-7 = "%{O-12}%{F#F00}█"
+
+[module/memory]
+type = internal/memory
+interval = 5
+format = "<label> <bar-used> "
+format-prefix = " Mem "
+format-prefix-foreground = ${colors.module-label-foreground}
+format-prefix-background = #a1c181
+label = " %percentage_used%% "
+format-foreground = ${colors.module-value-foreground}
+format-background = ${colors.module-value-background}
+
+bar-used-indicator =
+bar-used-width = 8
+bar-used-foreground-0 = ${module-value-intensity-1}
+bar-used-foreground-1 = ${module-value-intensity-2}
+bar-used-foreground-2 = ${module-value-intensity-3}
+bar-used-foreground-3 = ${module-value-intensity-4}
+
+bar-used-fill = ▐
+bar-used-empty = ▐
+bar-used-empty-foreground = #444444
+
+ramp-used-0 = ▁
+ramp-used-1 = ▂
+ramp-used-2 = ▃
+ramp-used-3 = ▄
+ramp-used-4 = ▅
+ramp-used-5 = ▆
+ramp-used-6 = ▇
+ramp-used-7 = █
+
+ramp-free-0 = ▁
+ramp-free-1 = ▂
+ramp-free-2 = ▃
+ramp-free-3 = ▄
+ramp-free-4 = ▅
+ramp-free-5 = ▆
+ramp-free-6 = ▇
+ramp-free-7 = █
+
+[network-base]
+type = internal/network
+unknown-as-up = true
+label-connected = "%{B#E7FFE7}%{F#4E8049} ↓%downspeed:8% %{B#FFE6E8}%{F#80494C} ↑%upspeed:8% %{B- F-}"
+format-connected = <label-connected>
+format-connected-foreground = ${colors.module-value-foreground}
+format-connected-background = ${colors.module-value-background}
+label-disconnected = " offline "
+label-disconnected-foreground = ${colors.module-value-negative-foreground}
+label-disconnected-background = ${colors.module-value-negative-background}
+format-disconnected = <label-disconnected>
+format-disconnected-prefix = ${self.format-connected-prefix}
+format-disconnected-prefix-foreground = ${self.format-connected-prefix-foreground}
+format-disconnected-prefix-background = ${self.format-connected-prefix-background}
+
+[module/network-eth]
+inherit = network-base
+format-connected-prefix = " 🖧 Eth "
+format-connected-prefix-foreground = #71CDFF
+format-connected-prefix-background = #3F76BB
+
+; FIXME: I don't know why, but inheritance is not working for wifi
+[module/network-wifi]
+type = internal/network
+unknown-as-up = ${network-base.unknown-as-up}
+label-connected = ${network-base.label-connected}
+format-connected = ${network-base.format-connected}
+; inherit = network-base
+format-connected-prefix = " 📡 Wifi "
+format-connected-prefix-foreground = #DBA3FF
+format-connected-prefix-background = #8E69CA
+format-connected-foreground = ${network-base.format-connected-foreground}
+format-connected-background = ${network-base.format-connected-background}
+
+label-disconnected = " offline "
+label-disconnected-foreground = ${colors.module-value-negative-foreground}
+label-disconnected-background = ${colors.module-value-negative-background}
+format-disconnected = <label-disconnected>
+format-disconnected-prefix = ${self.format-connected-prefix}
+format-disconnected-prefix-foreground = ${self.format-connected-prefix-foreground}
+format-disconnected-prefix-background = ${self.format-connected-prefix-background}
+
+[module/pulseaudio]
+type = internal/pulseaudio
+
+format-volume = <label-volume> <bar-volume>
+label-volume = " ♫ VOL %percentage%% "
+label-volume-foreground = ${colors.module-label-foreground}
+label-volume-background = #d0a0d0
+label-muted = " ♫ muted "
+label-muted-foreground = #666
+bar-volume-width = 8
+bar-volume-foreground-0 = ${colors.module-value-intensity-1}
+bar-volume-foreground-1 = ${colors.module-value-intensity-1}
+bar-volume-foreground-2 = ${colors.module-value-intensity-2}
+bar-volume-foreground-3 = ${colors.module-value-intensity-2}
+bar-volume-foreground-4 = ${colors.module-value-intensity-3}
+bar-volume-foreground-5 = ${colors.module-value-intensity-3}
+bar-volume-foreground-6 = ${colors.module-value-intensity-4}
+
+bar-volume-gradient = false
+bar-volume-indicator = |
+bar-volume-indicator-font = 3
+bar-volume-fill = ─
+bar-volume-fill-font = 3
+bar-volume-empty = ─
+bar-volume-empty-font = 3
+
+[module/temperature]
+type = internal/temperature
+thermal-zone = 0
+warn-temperature = 60
+
+; format-prefix = " 🌡Temp "
+format-prefix = " Temp "
+format = <label><ramp>
+format-prefix-foreground = #3f4a47
+format-prefix-background = #88b1b1
+format-foreground = ${colors.module-value-foreground}
+format-background = ${colors.module-value-background}
+
+format-warn-prefix = " 🌡Temp "
+format-warn = <label-warn><ramp>
+format-warn-prefix-foreground = ${colors.module-value-foreground}
+format-warn-prefix-background = ${self.format-prefix-background}
+
+label = " %temperature-c% "
+; label-foreground = ${colors.module-label-foreground}
+; label-background = ${colors.module-label-background}
+label-foreground = ${colors.module-value-foreground}
+label-background = ${colors.module-value-background}
+
+label-warn = " %temperature-c% "
+label-warn-foreground = ${colors.module-value-foreground}
+label-warn-background = ${colors.module-value-background}
+
+ramp-0 = " ➊ "
+ramp-1 = " ➋ "
+ramp-2 = " ➌ "
+ramp-background = ${colors.module-value-background}
+ramp-0-foreground = ${colors.module-value-intensity-1}
+ramp-1-foreground = ${colors.module-value-intensity-3}
+ramp-2-foreground = ${colors.module-value-intensity-4}
+
+[module/battery]
+type = internal/battery
+full-at = 99
+low-at = 5
+battery = BAT0
+adapter = ADP1
+poll-interval = 5
+time-format = %H:%M
+format-charging = <animation-charging> <label-charging>
+format-discharging = <ramp-capacity> <label-discharging>
+label-charging = Charging %percentage%%
+label-discharging = Discharging %percentage%%
+label-full = " ⚡ Fully charged "
+label-full-foreground = #1a1a1a
+label-full-background = #ffff00
+label-low = BATTERY LOW
+ramp-capacity-0 = 
+ramp-capacity-1 = 
+ramp-capacity-2 = 
+ramp-capacity-3 = 
+ramp-capacity-4 = 
+bar-capacity-width = 10
+animation-charging-0 = 
+animation-charging-1 = 
+animation-charging-2 = 
+animation-charging-3 = 
+animation-charging-4 = 
+; Framerate in milliseconds
+animation-charging-framerate = 750
+animation-discharging-0 = 
+animation-discharging-1 = 
+animation-discharging-2 = 
+animation-discharging-3 = 
+animation-discharging-4 = 
+; Framerate in milliseconds
+animation-discharging-framerate = 500
+animation-low-0 = !
+animation-low-1 =
+animation-low-framerate = 200
+
+; [module/mpd]
+; type = internal/mpd
+;
+; host = 127.0.0.1
+; port = 6600
+; interval = 2
+; format-online = <label-time> <label-song>
+; label-song = %artist% - %title%
+; label-offline = 🎜 mpd is offline
+
+; Custom modules --------------------------------------------------------------
+
+[module/calendar]
+type = custom/script
+exec = ~/.local/bin/clock
+interval = 5
+tail = true
+format-prefix = " 📆 "
+format-prefix-foreground = #e3e7ce
+format-prefix-background = #076678
+format-foreground = ${colors.module-value-foreground}
+format-background = ${colors.module-value-background}
+click-left = BLOCK_BUTTON=1 ~/.local/bin/clock
+click-middle = BLOCK_BUTTON=2 ~/.local/bin/clock
+click-right = BLOCK_BUTTON=3 ~/.local/bin/clock
+
+[module/vpn]
+type = custom/script
+exec = ~/.local/bin/vpn
+interval = 25
+tail = true
+format-prefix = " ♜ VPN "
+format-prefix-foreground = #BE492A
+format-prefix-background = #f99256
+format-foreground = ${colors.module-value-foreground}
+format-background = ${colors.module-value-background}
+click-left = BLOCK_BUTTON=1 ~/.local/bin/vpn
+click-middle = BLOCK_BUTTON=2 ~/.local/bin/vpn
+click-right = BLOCK_BUTTON=3 ~/.local/bin/vpn
+
+; vim:ft=dosini
diff --git a/desktop-x11/.config/sxhkd/sxhkdrc b/desktop-x11/.config/sxhkd/sxhkdrc
new file mode 100644
index 0000000..f993ab5
--- /dev/null
+++ b/desktop-x11/.config/sxhkd/sxhkdrc
@@ -0,0 +1,353 @@
+# make sxhkd reload its configuration files:
+super + Escape
+ dunstctl set-paused true ; i3lock -tfi ~/Dropbox/Images/wallpapers/stmichael.png ; dunstctl set-paused false
+
+# make sxhkd reload its configuration files:
+super + ctrl + Escape
+ pkill -usr1 -x sxhkd; dunstify 'sxhkd' 'Reloaded config'
+
+#
+# Gaps
+#
+super + {_,shift + }equal
+ bspc config -d focused window_gap $(($(bspc config -d focused window_gap) + {2,10}))
+
+super + {_,shift + }minus
+ bspc config -d focused window_gap $(($(bspc config -d focused window_gap) - {2,10}))
+
+# Terminal
+super + Return
+ alacritty -e tmux
+
+super + shift + Return
+ alacritty
+
+super + ctrl + Return
+ alacritty --class Floating
+
+super + e
+ st -z 14
+ # alacritty --class Floating --option 'font.size=24.0' --option 'window.dimensions={columns=100,lines=20}' --command vim ~/scratchpad
+
+super + shift + e
+ st -z 14 -e tmux
+
+super + control + e
+ st -c Floating -z 16
+
+ # alacritty --class Floating --option 'font.size=24.0' --option 'window.dimensions={columns=100,lines=20}' --command vim --clean ~/scratchpad
+
+# Settings
+super + shift + s
+ pavucontrol
+
+# program launcher
+super + @space
+ rofi -show drun -window-thumbnail -window-format "\{w\} \{t\}"
+
+super + shift + @space
+ rofi -show run -window-thumbnail -window-format "\{w\} \{t\}"
+
+super + ctrl + @space
+ rofi -show window -window-thumbnail -window-format "\{w\} \{t\}" -window-command "bspc node \{window\} -d newest -f"
+
+super + i
+ rofi -show filebrowser -theme dark-grid
+
+super + ctrl + i
+ rofi -filebrowser-directory $HOME/Pictures/Screenshots -show filebrowser -show filebrowser -theme dark-grid
+
+super + p
+ rofi-pass --last-used -lines 12
+
+# Notifications
+
+# Redisplay last message(s).
+ctrl + grave
+ dunstctl history-pop
+
+# Close notification.
+ctrl + shift + grave
+ dunstctl close
+
+# Close all notifications.
+ctrl + shift + alt + grave
+ dunstctl close-all
+
+# Context menu.
+ctrl + shift + period
+ dunstctl context
+
+# start a web browser
+super + o
+ /usr/bin/librewolf -P personal
+
+super + ctrl + o
+ /usr/bin/librewolf -P work
+
+super + alt + o
+ bspc rule -a '*:*' -o state=floating ; /usr/bin/librewolf -P personal
+
+super + shift + p
+ bspc rule -a '*:*' -o state=floating ; /usr/bin/librewolf --private-window
+
+# super + alt + b
+# ~/.local/bin/rofi-buku2
+ # rofi-buku -show
+
+# start a file browser
+super + n
+ /usr/bin/nautilus
+
+super + shift + n
+ ~/.config/regolith/bin/open-dirs.sh
+
+super + shift + i
+ catfish ~/storage/Downloads/images --name Floating
+
+# Audio Controls
+{shift + XF86AudioLowerVolume, super + less}
+ ~/.local/bin/volume-control down
+
+{shift + XF86AudioRaiseVolume, super + greater}
+ ~/.local/bin/volume-control up
+
+XF86AudioLowerVolume
+ ~/.local/bin/volume-control down-a-bit
+
+XF86AudioRaiseVolume
+ ~/.local/bin/volume-control up-a-bit
+
+{XF86AudioMute, super + shift + m}
+ ~/.local/bin/volume-control mute
+ # ~/.local/bin/volume-control medium
+
+super + shift + less
+ ~/.local/bin/volume-control quiet
+
+super + shift + greater
+ ~/.local/bin/volume-control max
+
+# Music Player Daemon controls
+super + ctrl + p
+ song-control toggle
+ # dunstify --urgency normal --timeout 2000 --icon multimedia-player --hints=string:x-dunst-stack-tag:song "$(mpc toggle | head -n2)"
+
+super + ctrl + less
+ song-control prev
+ # dunstify --urgency normal --timeout 2000 --icon multimedia-player --hints=string:x-dunst-stack-tag:song "$(mpc prev | head -n1)"
+
+super + ctrl + greater
+ song-control next
+ # dunstify --urgency normal --timeout 2000 --icon multimedia-player --hints=string:x-dunst-stack-tag:song "$(mpc next | head -n1)"
+
+# bspwm hotkeys
+#
+
+# quit/restart bspwm
+super + shift + r
+ [ $(printf "Yes\nNo" | rofi -dmenu -i -p "Restart BSPWM") = "Yes" ] && bspc wm -r
+
+super + q
+ rofi -show session-menu -modi "session-menu:/home/setanta/.local/bin/rofi-power-menu"
+ # [ $(printf "Yes\nNo" | rofi -dmenu -i -p "Logout") = "Yes" ] && bspc quit
+
+# close and kill
+super + {_,shift + }w
+ bspc node -{c,k}
+
+# alternate between the tiled and monocle layout
+super + m
+ bspc desktop -l next
+
+super + alt + n
+ bsp-layout next | head -n1 | xargs dunstify
+
+super + alt + p
+ bsp-layout previous | head -n1 | xargs dunstify
+
+super + alt + t
+ bsp-layout set tall | head -n1 | xargs dunstify
+
+super + alt + shift + t
+ bsp-layout set tiled | head -n1 | xargs dunstify
+
+# send the newest marked node to the newest preselected node
+super + y
+ bspc node newest.marked.local -n newest.!automatic.local
+
+# swap the current node and the biggest window
+super + g
+ bspc node -s biggest.window
+
+#
+# state/flags
+#
+
+# set the window state
+super + {t,shift + t,s,f}
+ bspc node -t {tiled,pseudo_tiled,floating,fullscreen}
+
+# set the node flags
+super + ctrl + {m,x,y,z}
+ bspc node -g {marked,locked,sticky,private}
+
+#
+# focus/swap
+#
+
+# focus the node in the given direction
+super + {_,shift + }{h,j,k,l}
+ bspc node -{f,s} {west,south,north,east}
+super + {_,shift + }{Left,Down,Up,Right}
+ bspc node -{f,s} {west,south,north,east}
+
+# focus the node for the given path jump
+# super + {p,b,comma,period}
+# bspc node -f @{parent,brother,first,second}
+
+# focus the next/previous window in the current desktop
+# super + {_,shift + }c
+# bspc node -f {next,prev}.local.!hidden.window
+super + comma
+ bspc node -f prev.local.!hidden.window
+super + period
+ bspc node -f next.local.!hidden.window
+
+# focus the next/previous desktop in the current monitor
+super + {Prior,Next}
+ bspc desktop -f {prev,next}.local.occupied
+
+super + ctrl + {Prior,Next}
+ bspc desktop -f {prev,next}.local
+
+super + bracket{left,right}
+ bspc desktop -f {prev,next}.local.occupied
+
+super + ctrl + bracket{left,right}
+ bspc desktop -f {prev,next}.local
+
+# focus the last node/desktop
+super + {Tab,grave}
+ bspc {node,desktop} -f last
+
+# focus the older or newer node in the focus history
+super + {o,i}
+ bspc wm -h off; \
+ bspc node {older,newer} -f; \
+ bspc wm -h on
+
+# focus or send to the given desktop
+super + {_,shift + }{1-9,0}
+ bspc {desktop -f,node -d} '^{1-9,10}'
+
+super + alt + {1-9,0}
+ bspc node -d '^{1-9,10}' --follow
+
+#
+# preselect
+#
+
+# preselect the direction
+super + ctrl + shift + {h,j,k,l}
+ bspc node -p {west,south,north,east}
+
+# preselect the ratio
+super + ctrl + {1-9}
+ bspc node -o 0.{1-9}
+
+# cancel the preselection for the focused node
+# super + ctrl + space
+# bspc node -p cancel
+
+# cancel the preselection for the focused desktop
+# super + ctrl + shift + space
+super + alt + space
+ bspc query -N -d | xargs -I id -n 1 bspc node id -p cancel
+
+#
+# move/resize
+#
+
+# move a floating window
+super + ctrl + {Left,Down,Up,Right}
+ bspc node -v {-20 0,0 20,0 -20,20 0}
+
+super + ctrl + {h,j,k,l}
+ bspc node -v {-20 0,0 20,0 -20,20 0}
+
+# expand/contract a window
+# super + control + shift + {h,j,k,l}
+# bspc node -z {left -20 0 || bspc node -z right -20 0, \
+# bottom 0 20 || bspc node -z top 0 20,\
+# top 0 -20 || bspc node -z bottom 0 -20,\
+# right 20 0 || bspc node -z left 20 0}
+
+super + control + shift + {Left,Down,Up,Right}
+ bspc node -z {left -20 0 || bspc node -z right -20 0, \
+ bottom 0 20 || bspc node -z top 0 20,\
+ top 0 -20 || bspc node -z bottom 0 -20,\
+ right 20 0 || bspc node -z left 20 0}
+
+# expand a window by moving one of its side outward
+super + alt + {h,j,k,l}
+ bspc node -z {left -20 0,bottom 0 20,top 0 -20,right 20 0}
+
+super + alt + {Left,Down,Up,Right}
+ bspc node -z {left -20 0,bottom 0 20,top 0 -20,right 20 0}
+
+# contract a window by moving one of its side inward
+super + alt + shift + {h,j,k,l}
+ bspc node -z {right -20 0,top 0 20,bottom 0 -20,left 20 0}
+
+super + alt + shift + {Left,Down,Up,Right}
+ bspc node -z {right -20 0,top 0 20,bottom 0 -20,left 20 0}
+
+#
+# Prayers
+#
+super + shift + o
+ sxiv -bsf ~/Dropbox/Images/prayers/ -g 1700x1010
+
+super + shift + z
+ sxiv -bsf ~/Nextcloud/Images/imgs-ca-from-gdrive/Rosary-2/ -g 1430x1044
+
+#
+# Calendar & Clock
+#
+
+super + c
+ ~/.local/bin/mycal
+
+super + shift + c
+ ~/.local/bin/mytime
+
+#
+# Screenshots
+#
+
+# Select area to capture
+Print
+ SCREENSHOT_FILE=$HOME/Pictures/Screenshots/Screenshot_$(date +%Y%b%d-%H%M%S).png ; \
+ maim -s $SCREENSHOT_FILE && \
+ xclip -selection clipboard -t image/png -i ~/Pictures/Screenshots/`ls -1 -t ~/Pictures/Screenshots | head -1` && \
+ add_recent_file $SCREENSHOT_FILE && \
+ if [ "$(dunstify 'Screenshot taken.' --action='show,Show Image' --action='dismiss,Dismiss' -I $SCREENSHOT_FILE)" = "show" ]; then sxiv $SCREENSHOT_FILE; fi;
+
+# Capture the whole screen
+shift + Print
+ SCREENSHOT_FILE=$HOME/Pictures/Screenshots/Screenshot_$(date +%Y%b%d-%H%M%S).png ; \
+ maim $SCREENSHOT_FILE && \
+ xclip -selection clipboard -t image/png -i ~/Pictures/Screenshots/`ls -1 -t ~/Pictures/Screenshots | head -1` && \
+ add_recent_file $SCREENSHOT_FILE && \
+ if [ "$(dunstify 'Screenshot taken.' --action='show,Show Image' --action='dismiss,Dismiss' -I $SCREENSHOT_FILE)" = "show" ]; then sxiv $SCREENSHOT_FILE; fi;
+
+# Capture focused window
+alt + Print
+ SCREENSHOT_FILE=$HOME/Pictures/Screenshots/Screenshot_$(date +%Y%b%d-%H%M%S).png ; \
+ maim -i $(xdotool getactivewindow) $SCREENSHOT_FILE && \
+ xclip -selection clipboard -t image/png -i ~/Pictures/Screenshots/`ls -1 -t ~/Pictures/Screenshots | head -1` && \
+ add_recent_file $SCREENSHOT_FILE && \
+ if [ "$(dunstify 'Screenshot taken.' --action='show,Show Image' --action='dismiss,Dismiss' -I $SCREENSHOT_FILE)" = "show" ]; then sxiv $SCREENSHOT_FILE; fi;
+
+# vim:ft=bash
diff --git a/desktop-x11/.local/bin/rofi-pass b/desktop-x11/.local/bin/rofi-pass
new file mode 100755
index 0000000..8d38cfc
--- /dev/null
+++ b/desktop-x11/.local/bin/rofi-pass
@@ -0,0 +1,868 @@
+#!/usr/bin/env bash
+
+# rofi-pass
+# (c) 2015 Rasmus Steinke <rasi@xssn.at>
+basecommand="$0"
+
+# set default settings
+_rofi () {
+ rofi -no-auto-select -i "$@"
+}
+
+_pwgen () {
+ pwgen -y "$@"
+}
+
+_image_viewer () {
+ feh -
+}
+
+# We expect to find these fields in pass(1)'s output
+URL_field='url'
+USERNAME_field='user'
+AUTOTYPE_field='autotype'
+OTPmethod_field='otp_method'
+
+default_autotype="user :tab pass"
+delay=2
+wait=0.2
+xdotool_delay=12
+default_do='menu' # menu, copyPass, typeUser, typePass, copyUser, copyUrl, viewEntry, typeMenu, actionMenu, copyMenu, openUrl
+auto_enter='false'
+notify='false'
+help_color=""
+clip=primary
+clip_clear=45
+default_user="${ROFI_PASS_DEFAULT_USER-$(whoami)}"
+default_user2=john_doe
+password_length=12
+fix_layout=false
+
+# default shortcuts
+autotype="Alt+1"
+type_user="Alt+2"
+type_pass="Alt+3"
+open_url="Alt+4"
+copy_name="Alt+u"
+copy_url="Alt+l"
+copy_pass="Alt+p"
+show="Alt+o"
+copy_menu="Alt+c"
+action_menu="Alt+a"
+type_menu="Alt+t"
+help="Alt+h"
+switch="Alt+x"
+insert_pass="Alt+n"
+qrcode="Alt+q"
+previous_root="Shift+Left"
+next_root="Shift+Right"
+
+# Safe permissions
+umask 077
+
+has_qrencode() {
+ command -v qrencode >/dev/null 2>&1
+}
+
+# get all password files and create an array
+list_passwords() {
+ cd "${root}" || exit
+ pw_list=(**/*.gpg)
+ printf '%s\n' "${pw_list[@]%.gpg}" | sort -n
+
+}
+
+doClip () {
+ case "$clip" in
+ "primary") xclip ;;
+ "clipboard") xclip -selection clipboard;;
+ "both") xclip; xclip -o | xclip -selection clipboard;;
+ esac
+}
+
+checkIfPass () {
+ printf '%s\n' "${root}: $selected_password" >| "$HOME/.cache/rofi-pass/last_used"
+}
+
+
+autopass () {
+ x_repeat_enabled=$(xset q | awk '/auto repeat:/ {print $3}')
+ xset r off
+
+ rm -f "$HOME/.cache/rofi-pass/last_used"
+ printf '%s\n' "${root}: $selected_password" > "$HOME/.cache/rofi-pass/last_used"
+ for word in ${stuff["$AUTOTYPE_field"]}; do
+ case "$word" in
+ ":tab") xdotool key Tab;;
+ ":space") xdotool key space;;
+ ":delay") sleep "${delay}";;
+ ":enter") xdotool key Return;;
+ ":otp") printf '%s' "$(generateOTP)" | xdotool type --delay ${xdotool_delay} --clearmodifiers --file -;;
+ "pass") printf '%s' "${password}" | xdotool type --delay ${xdotool_delay} --clearmodifiers --file -;;
+ "path") printf '%s' "${selected_password}" | rev | cut -d'/' -f1 | rev | xdotool type --clearmodifiers --file -;;
+ *) printf '%s' "${stuff[${word}]}" | xdotool type --delay ${xdotool_delay} --clearmodifiers --file -;;
+ esac
+ done
+
+ if [[ ${auto_enter} == "true" ]]; then
+ xdotool key Return
+ fi
+
+ xset r "$x_repeat_enabled"
+ unset x_repeat_enabled
+ clearUp
+}
+
+generateQrCode() {
+ has_qrencode
+
+ if [[ $? -eq "1" ]]; then
+ printf '%s\n' "qrencode not found" | _rofi -dmenu
+ exit_code=$?
+ if [[ $exit_code -eq "1" ]]; then
+ exit
+ else
+ "${basecommand}"
+ fi
+ fi
+
+ checkIfPass
+ pass "$selected_password" | head -n 1 | qrencode -d 300 -v 8 -l H -o - | _image_viewer
+ if [[ $? -eq "1" ]]; then
+ printf '%s\n' "" | _rofi -dmenu -mesg "Image viewer not defined or cannot read from pipe"
+ exit_value=$?
+ if [[ $exit_value -eq "1" ]]; then
+ exit
+ else
+ "${basecommand}"
+ fi
+ fi
+ clearUp
+}
+
+openURL () {
+ checkIfPass
+ $BROWSER "$(PASSWORD_STORE_DIR="${root}" pass "$selected_password" | grep "${URL_field}: " | gawk '{sub(/:/,"")}{print $2}1' | head -1)"; exit;
+ clearUp
+}
+
+typeUser () {
+ checkIfPass
+
+ x_repeat_enabled=$(xset q | awk '/auto repeat:/ {print $3}')
+ xset r off
+
+ printf '%s' "${stuff[${USERNAME_field}]}" | xdotool type --delay ${xdotool_delay} --clearmodifiers --file -
+
+ xset r "$x_repeat_enabled"
+ unset x_repeat_enabled
+
+ clearUp
+}
+
+typePass () {
+ checkIfPass
+
+ x_repeat_enabled=$(xset q | awk '/auto repeat:/ {print $3}')
+ xset r off
+
+ printf '%s' "${password}" | xdotool type --delay ${xdotool_delay} --clearmodifiers --file -
+
+ if [[ $notify == "true" ]]; then
+ if [[ "${stuff[notify]}" == "false" ]]; then
+ :
+ else
+ notify-send "rofi-pass" "finished typing password";
+ fi
+ elif [[ $notify == "false" ]]; then
+ if [[ "${stuff[notify]}" == "true" ]]; then
+ notify-send "rofi-pass" "finished typing password";
+ else
+ :
+ fi
+ fi
+
+ xset r "$x_repeat_enabled"
+ unset x_repeat_enabled
+ clearUp
+}
+
+typeField () {
+ checkIfPass
+ local to_type
+
+ x_repeat_enabled=$(xset q | awk '/auto repeat:/ {print $3}')
+ xset r off
+
+ case $typefield in
+ "OTP") to_type="$(generateOTP)" ;;
+ *) to_type="${stuff[${typefield}]}" ;;
+ esac
+
+ printf '%s' "$to_type" | xdotool type --delay ${xdotool_delay} --clearmodifiers --file -
+
+ xset r "$x_repeat_enabled"
+ unset x_repeat_enabled
+ unset to_type
+
+ clearUp
+}
+
+generateOTP () {
+ checkIfPass
+
+ # First, we check if there is a non-conventional OTP command in the pass file
+ if PASSWORD_STORE_DIR="${root}" pass "$selected_password" | grep -q "${OTPmethod_field}: "; then
+ # We execute the commands after otp_method: AS-IS
+ bash -c "$(PASSWORD_STORE_DIR="${root}" pass "$selected_password" | grep "${OTPmethod_field}: " | cut -d' ' -f2-)"
+ else
+ # If there is no method defined, fallback to pass-otp
+ PASSWORD_STORE_DIR="${root}" pass otp "$selected_password"
+ fi
+
+ clearUp
+}
+
+copyUser () {
+ checkIfPass
+ printf '%s' "${stuff[${USERNAME_field}]}" | doClip
+ clearUp
+}
+
+copyField () {
+ checkIfPass
+ printf '%s' "${stuff[${copyfield}]}" | doClip
+ clearUp
+}
+
+copyURL () {
+ checkIfPass
+ printf '%s' "${stuff[${URL_field}]}" | doClip
+ clearUp
+}
+
+copyPass () {
+ checkIfPass
+ printf '%s' "$password" | doClip
+ if [[ $notify == "true" ]]; then
+ notify-send "rofi-pass" "Copied Password\\nClearing in $clip_clear seconds"
+ fi
+
+ if [[ $notify == "true" ]]; then
+ (sleep $clip_clear; printf '%s' "" | xclip; printf '%s' "" | xclip -selection clipboard | notify-send "rofi-pass" "Clipboard cleared") &
+ elif [[ $notify == "false" ]]; then
+ (sleep $clip_clear; printf '%s' "" | xclip; printf '%s' "" | xclip -selection clipboard) &
+ fi
+}
+
+viewEntry () {
+ checkIfPass
+ showEntry "${selected_password}"
+}
+
+generatePass () {
+ askmenu_content=(
+ "Yes"
+ "No")
+
+ askGenMenu=$(printf '%s\n' "${askmenu_content[@]}" | _rofi -dmenu -p "Generate new Password for ${selected_password}? > ")
+ askgen_exit=$?
+
+ if [[ $askgen_exit -eq 1 ]]; then
+ exit
+ fi
+ if [[ $askGenMenu == "Yes" ]]; then
+ true
+ elif [[ $askGenMenu == "No" ]]; then
+ actionMenu
+ fi
+
+ checkIfPass
+
+ symbols_content=(
+ "0 Cancel"
+ "1 Yes"
+ "2 No")
+
+ symbols=$(printf '%s\n' "${symbols_content[@]}" | _rofi -dmenu -p "Use Symbols? > ")
+ symbols_val=$?
+
+ if [[ $symbols_val -eq 1 ]]; then
+ exit
+ fi
+ if [[ $symbols == "0 Cancel" ]]; then
+ mainMenu;
+ elif [[ $symbols == "1 Yes" ]]; then
+ symbols="";
+ elif [[ $symbols == "2 No" ]]; then
+ symbols="-n";
+ fi
+
+ HELP="<span color='$help_color'>Enter Number or hit Enter to use default length</span>"
+ length=$(printf '%s' "" | _rofi -dmenu -mesg "${HELP}" -p "Password length? (Default: ${password_length}) > ")
+ length_exit=$?
+
+ if [[ $length_exit -eq 1 ]]; then
+ exit
+ fi
+ if [[ $length == "" ]]; then
+ PASSWORD_STORE_DIR="${root}" pass generate ${symbols} -i "$selected_password" "${password_length}" > /dev/null;
+ else
+ PASSWORD_STORE_DIR="${root}" pass generate ${symbols} -i "$selected_password" "${length}" > /dev/null;
+ fi
+}
+
+# main Menu
+mainMenu () {
+ if [[ $1 == "--bmarks" ]]; then
+ selected_password="$(list_passwords 2>/dev/null \
+ | _rofi -mesg "Bookmarks Mode. ${switch} to switch" \
+ -dmenu \
+ -kb-custom-10 "${switch}" \
+ -select "$entry" \
+ -p "rofi-pass > ")"
+
+ rofi_exit=$?
+
+ if [[ $rofi_exit -eq 1 ]]; then
+ exit
+ elif [[ $rofi_exit -eq 19 ]]; then
+ ${basecommand}
+ elif [[ $rofi_exit -eq 0 ]]; then
+ openURL
+ fi
+ else
+ unset selected_password
+
+ args=( -dmenu
+ -kb-custom-1 "${autotype}"
+ -kb-custom-2 "${type_user}"
+ -kb-custom-3 "${type_pass}"
+ -kb-custom-4 "${open_url}"
+ -kb-custom-5 "${copy_name}"
+ -kb-custom-6 "${copy_pass}"
+ -kb-custom-7 "${show}"
+ -kb-custom-8 "${copy_url}"
+ -kb-custom-9 "${type_menu}"
+ -kb-custom-10 "${previous_root}"
+ -kb-custom-11 "${next_root}"
+ -kb-custom-14 "${action_menu}"
+ -kb-custom-15 "${copy_menu}"
+ -kb-custom-16 "${help}"
+ -kb-custom-17 "${switch}"
+ -kb-custom-18 "${insert_pass}"
+ -kb-custom-19 "${qrcode}")
+ args+=(-kb-mode-previous "" # These keyboard shortcut options are needed, because
+ -kb-mode-next "" # Shift+<Left|Right> are otherwise taken by rofi.
+ -select "$entry"
+ -p "󱕵")
+
+ if [[ ${#roots[@]} -gt "1" || $custom_root == "true" ]]; then
+ args+=(-mesg "PW Store: ${root}")
+ fi
+
+ selected_password="$(list_passwords 2>/dev/null | _rofi "${args[@]}")"
+
+ rofi_exit=$?
+ if [[ $rofi_exit -eq 1 ]]; then
+ exit
+ fi
+
+ # Actions based on exit code, which do not need the entry.
+ # The exit code for -kb-custom-X is X+9.
+ case "${rofi_exit}" in
+ 19) roots_index=$(( (roots_index-1+roots_length) % roots_length)); root=${roots[$roots_index]}; mainMenu; return;;
+ 20) roots_index=$(( (roots_index+1) % roots_length)); root=${roots[$roots_index]}; mainMenu; return;;
+ 25) helpMenu; return;;
+ 26) ${basecommand} --bmarks; return;;
+ esac
+
+ mapfile -t password_temp < <(PASSWORD_STORE_DIR="${root}" pass show "$selected_password")
+ password=${password_temp[0]}
+
+ if [[ ${password} == "#FILE="* ]]; then
+ pass_file="${password#*=}"
+ mapfile -t password_temp2 < <(PASSWORD_STORE_DIR="${root}" pass show "${pass_file}")
+ password=${password_temp2[0]}
+ fi
+
+ fields=$(printf '%s\n' "${password_temp[@]:1}" | awk '$1 ~ /:$/ || /otpauth:\/\// {$1=$1;print}')
+ declare -A stuff
+ stuff["pass"]=${password}
+
+ if [[ -n $fields ]]; then
+ while read -r LINE; do
+ unset _id _val
+ case "$LINE" in
+ "otpauth://"*|"${OTPmethod_field}"*)
+ _id="OTP"
+ _val=""
+ ;;
+ *)
+ _id="${LINE%%: *}"
+ _val="${LINE#* }"
+ ;;
+ esac
+
+ if [[ -n "$_id" ]]; then
+ stuff["${_id}"]=${_val}
+ fi
+ done < <(printf '%s\n' "${fields}")
+
+ if test "${stuff['autotype']+autotype}"; then
+ :
+ else
+ stuff["autotype"]="${USERNAME_field} :tab pass"
+ fi
+ fi
+ fi
+
+ if [[ -z "${stuff["${AUTOTYPE_field}"]}" ]]; then
+ if [[ -n $default_autotype ]]; then
+ stuff["${AUTOTYPE_field}"]="${default_autotype}"
+ fi
+ fi
+ if [[ -z "${stuff["${USERNAME_field}"]}" ]]; then
+ if [[ -n $default_user ]]; then
+ if [[ "$default_user" == ":filename" ]]; then
+ stuff["${USERNAME_field}"]="$(basename $selected_password)"
+ else
+ stuff["${USERNAME_field}"]="${default_user}"
+ fi
+ fi
+ fi
+ pass_content="$(for key in "${!stuff[@]}"; do printf '%s\n' "${key}: ${stuff[$key]}"; done)"
+
+ # actions based on keypresses
+ # The exit code for -kb-custom-X is X+9.
+ case "${rofi_exit}" in
+ 0) typeMenu;;
+ 10) sleep $wait; autopass;;
+ 11) sleep $wait; typeUser;;
+ 12) sleep $wait; typePass;;
+ 13) openURL;;
+ 14) copyUser;;
+ 15) copyPass;;
+ 16) viewEntry;;
+ 17) copyURL;;
+ 18) default_do="menu" typeMenu;;
+ 23) actionMenu;;
+ 24) copyMenu;;
+ 27) insertPass;;
+ 28) generateQrCode;;
+ esac
+ clearUp
+}
+
+
+clearUp () {
+ password=''
+ selected_password=''
+ unset stuff
+ unset password
+ unset selected_password
+ unset password_temp
+ unset stuff
+}
+
+helpMenu () {
+ printf '%s' "${autotype}: Autotype
+${type_user}: Type Username
+${type_pass}: Type Password
+${qrcode}: Generate and display qrcode
+---
+${copy_name}: Copy Username
+${copy_pass}: Copy Password
+${copy_url}: Copy URL
+${open_url}: Open URL
+${copy_menu}: Copy Custom Field
+---
+${action_menu}: Edit, Move, Delete, Re-generate Submenu
+${show}: Show Password File
+${insert_pass}: Insert new Pass Entry
+${switch}: Switch Pass/Bookmark Mode
+---
+${previous_root}: Switch to previous password store (--root)
+${next_root}: Switch to next password store (--root)
+ " | _rofi -dmenu -mesg "Hint: All hotkeys are configurable in config file" -p "Help > "
+ help_val=$?
+
+ if [[ $help_val -eq 1 ]]; then
+ exit;
+ else
+ unset helptext; mainMenu;
+ fi
+}
+
+
+typeMenu () {
+ if [[ -n $default_do ]]; then
+ if [[ $default_do == "menu" ]]; then
+ checkIfPass
+ local -a keys=("${!stuff[@]}")
+ keys=("${keys[@]/$AUTOTYPE_field}")
+ typefield=$({ printf '%s' "${AUTOTYPE_field}" ; printf '%s\n' "${keys[@]}" | sort; } | _rofi -dmenu -p "Choose Field to type > ")
+ typefield_exit=$?
+ if [[ $typefield_exit -eq 1 ]]; then
+ exit
+ fi
+ case "$typefield" in
+ '') exit;;
+ 'pass') sleep $wait; typePass;;
+ "${AUTOTYPE_field}") sleep $wait; autopass;;
+ *) sleep $wait; typeField
+ esac
+ clearUp
+ elif [[ $default_do == "${AUTOTYPE_field}" ]]; then
+ sleep $wait; autopass
+ else
+ ${default_do}
+ fi
+ fi
+}
+
+copyMenu () {
+ checkIfPass
+ copyfield=$(printf '%s\n' "${!stuff[@]}" | sort | _rofi -dmenu -p "Choose Field to copy > ")
+ val=$?
+ if [[ $val -eq 1 ]]; then
+ exit;
+ fi
+ if [[ $copyfield == "pass" ]]; then
+ copyPass;
+ else
+ copyField
+ fi
+ clearUp
+}
+
+actionMenu () {
+ checkIfPass
+ action_content=("< Return"
+ "---"
+ "1 Move Password File"
+ "2 Copy Password File"
+ "3 Delete Password File"
+ "4 Edit Password File"
+ "5 Generate New Password")
+
+ action=$(printf '%s\n' "${action_content[@]}" | _rofi -dmenu -p "Choose Action > ")
+ if [[ ${action} == "1 Move Password File" ]]; then
+ manageEntry move;
+ elif [[ ${action} == "3 Delete Password File" ]]; then
+ manageEntry delete;
+ elif [[ ${action} == "2 Copy Password File" ]]; then
+ manageEntry copy;
+ elif [[ ${action} == "4 Edit Password File" ]]; then
+ manageEntry edit;
+ elif [[ ${action} == "5 Generate New Password" ]]; then
+ generatePass;
+ elif [[ ${action} == "< Return" ]]; then
+ mainMenu;
+ elif [[ ${action} == "" ]]; then
+ exit
+ fi
+}
+
+showEntry () {
+ if [[ -z $pass_content ]]; then
+ pass_temp=$(PASSWORD_STORE_DIR="${root}" pass show "$selected_password")
+ password="${pass_temp%%$'\n'*}"
+ pass_key_value=$(printf '%s\n' "${pass_temp}" | tail -n+2 | grep ': ')
+ declare -A stuff
+
+ while read -r LINE; do
+ _id="${LINE%%: *}"
+ _val="${LINE#* }"
+ stuff["${_id}"]=${_val}
+ done < <(printf '%s\n' "${pass_key_value}")
+
+ stuff["pass"]=${password}
+
+ if test "${stuff['autotype']+autotype}"; then
+ :
+ else
+ stuff["autotype"]="${USERNAME_field} :tab pass"
+ fi
+
+ pass_content="$(for key in "${!stuff[@]}"; do printf '%s\n' "${key}: ${stuff[$key]}"; done)"
+ fi
+
+ bla_content=("< Return"
+ "${pass_content}")
+
+ bla=$(printf '%s\n' "${bla_content[@]}" | _rofi -dmenu -mesg "Enter: Copy entry to clipboard" -p "> ")
+ rofi_exit=$?
+
+ word=$(printf '%s' "$bla" | gawk -F': ' '{print $1}')
+
+ if [[ ${rofi_exit} -eq 1 ]]; then
+ exit
+ elif [[ ${rofi_exit} -eq 0 ]]; then
+ if [[ ${bla} == "< Return" ]]; then
+ mainMenu
+ else
+ if [[ -z $(printf '%s' "${stuff[${word}]}") ]]; then
+ printf '%s' "$word" | doClip
+ else
+ printf '%s' "${stuff[${word}]}" | doClip
+ fi
+ if [[ $notify == "true" ]]; then
+ notify-send "rofi-pass" "Copied Password\\nClearing in $clip_clear seconds"
+ fi
+ if [[ $notify == "true" ]]; then
+ (sleep $clip_clear; printf '%s' "" | xclip; printf '%s' "" | xclip -selection clipboard | notify-send "rofi-pass" "Clipboard cleared") &
+ elif [[ $notify == "false" ]]; then
+ (sleep $clip_clear; printf '%s' "" | xclip; printf '%s' "" | xclip -selection clipboard) &
+ fi
+ exit
+ fi
+ fi
+ exit
+ unset stuff
+ unset password
+ unset selected_password
+ unset password_temp
+ unset stuff
+ exit
+}
+
+manageEntry () {
+ if [[ "$1" == "edit" ]]; then
+ EDITOR=$EDITOR PASSWORD_STORE_DIR="${root}" pass edit "${selected_password}"
+ mainMenu
+ elif [[ $1 == "move" ]]; then
+ cd "${root}" || exit
+ group_array=(*/)
+ group=$(printf '%s\n' "${group_array[@]%/}" | _rofi -dmenu -p "Choose Group > ")
+ if [[ $group == "" ]]; then
+ exit
+ fi
+ PASSWORD_STORE_DIR="${root}" pass mv "$selected_password" "${group}"
+ mainMenu
+ elif [[ $1 == "copy" ]]; then
+ cd "${root}" || exit
+ group_array=(*/)
+ group=$(printf '%s\n' "${group_array[@]%/}" | _rofi -dmenu -p "Choose Group > ")
+ if [[ $group == "" ]]; then
+ exit
+ else
+ new_name="$(listgpg | _rofi -dmenu -format 'f' -mesg "Copying to same Group. Please enter a name for the new entry" -p "> ")"
+ fi
+ PASSWORD_STORE_DIR="${root}" pass cp "$selected_password" "${group}/${new_name}"
+ mainMenu
+ elif [[ "$1" == "delete" ]]; then
+ HELP="<span color='$help_color'>Selected entry: ${selected_password}</span>"
+ ask_content=("Yes"
+ "No")
+ ask=$(printf '%s\n' "${ask_content[@]}" | _rofi -mesg "${HELP}" -dmenu -p "Are You Sure? > ")
+ if [[ "$ask" == "Yes" ]]; then
+ PASSWORD_STORE_DIR="${root}" pass rm --force "${selected_password}"
+ elif [[ "$ask" == "No" ]]; then
+ mainMenu
+ elif [[ -z "$ask" ]]; then
+ exit
+ fi
+ else
+ mainMenu
+ fi
+}
+
+listgpg () {
+ pw_list=(**/*.gpg)
+ printf '%s\n' "${pw_list[@]}" | sort -n
+}
+
+insertPass () {
+ url=$(xclip --selection clipboard -o)
+
+ if [[ "${url:0:4}" == "http" ]]; then
+ domain_name="$(printf '%s\n' "${url}" | awk -F / '{l=split($3,a,"."); print (a[l-1]=="com"?a[l-2] OFS:X) a[l-1] OFS a[l]}' OFS=".")"
+ help_content="Domain: ${domain_name}
+ Type name, make sure it is unique"
+ else
+ help_content="Hint: Copy URL to clipboard before calling this menu.
+ Type name, make sure it is unique"
+ fi
+
+ cd "${root}" || exit
+ group_array=(*/)
+ grouplist=$(printf '%s\n' "${group_array[@]%/}")
+ name="$(listgpg | _rofi -dmenu -format 'f' -filter "${domain_name}" -mesg "${help_content}" -p "> ")"
+ val=$?
+
+ if [[ $val -eq 1 ]]; then
+ exit
+ fi
+
+ user_content=("${default_user2}"
+ "${USER}"
+ "${default_user}")
+
+ user=$(printf '%s\n' "${user_content[@]}" | _rofi -dmenu -mesg "Chose Username or type" -p "> ")
+ val=$?
+
+ if [[ $val -eq 1 ]]; then
+ exit
+ fi
+
+ group_content=("No Group"
+ "---"
+ "${grouplist}")
+
+ group=$(printf '%s\n' "${group_content[@]}" | _rofi -dmenu -p "Choose Group > ")
+ val=$?
+
+ if [[ $val -eq 1 ]]; then
+ exit
+ fi
+
+ pw=$(printf '%s' "Generate" | _rofi -dmenu -password -p "Password > " -mesg "Type Password or hit Enter to generate one")
+
+ if [[ $pw == "Generate" ]]; then
+ pw=$(_pwgen "${password_length}")
+ fi
+
+ clear
+
+ if [[ "$group" == "No Group" ]]; then
+ if [[ $url == http* ]]; then
+ pass_content=("${pw}"
+ "---"
+ "${USERNAME_field}: ${user}"
+ "${URL_field}: ${url}")
+ printf '%s\n' "${pass_content[@]}" | PASSWORD_STORE_DIR="${root}" pass insert -m "${name}" > /dev/null && PASSWORD_STORE_DIR="${root}" pass edit "${name}"
+ else
+ pass_content=("${pw}"
+ "---"
+ "${USERNAME_field}: ${user}")
+ printf '%s\n' "${pass_content[@]}" | PASSWORD_STORE_DIR="${root}" pass insert -m "${name}" > /dev/null && PASSWORD_STORE_DIR="${root}" pass edit "${name}"
+ fi
+ else
+ if [[ $url == http* ]]; then
+ pass_content=("${pw}"
+ "---"
+ "${USERNAME_field}: ${user}"
+ "${URL_field}: ${url}")
+ printf '%s\n' "${pass_content[@]}" | PASSWORD_STORE_DIR="${root}" pass insert -m "${group}/${name}" > /dev/null && PASSWORD_STORE_DIR="${root}" pass edit "${group}/${name}"
+ else
+ pass_content=("${pw}"
+ "---"
+ "${USERNAME_field}: ${user}")
+ printf '%s\n' "${pass_content[@]}" | PASSWORD_STORE_DIR="${root}" pass insert -m "${group}/${name}" > /dev/null
+ if [[ $edit_new_pass == "true" ]]; then
+ PASSWORD_STORE_DIR="${root}" pass edit "${group}/${name}"
+ fi
+ fi
+ fi
+}
+
+help_msg () {
+ cat <<'EOF'
+ Usage:
+ rofi-pass [command]
+
+ Commands:
+ --insert insert new entry to password store
+ --root set custom root directories (colon separated)
+ --last-used highlight last used item
+ --show-last show details of last used Entry
+ --bmarks start in bookmarks mode
+
+ rofi-pass version 1.5.3
+EOF
+}
+
+get_config_file () {
+ configs=("$ROFI_PASS_CONFIG"
+ "$HOME/.config/rofi-pass/config"
+ "/etc/rofi-pass.conf")
+
+ # return the first config file with a valid path
+ for config in "${configs[@]}"; do
+ # '! -z' is needed in case ROFI_PASS_CONFIG is not set
+ if [[ ! -z "${config}" && -f "${config}" ]]; then
+ printf "%s" "$config"
+ return
+ fi
+ done
+}
+
+main () {
+ # enable extended globbing
+ shopt -s nullglob globstar
+
+ # load config file
+ config_file="$(get_config_file)"
+ [[ ! -z "$config_file" ]] && source "$config_file"
+
+ # create tmp dir
+ if [[ ! -d "$HOME/.cache/rofi-pass" ]]; then
+ mkdir "$HOME/.cache/rofi-pass"
+ fi
+
+ # fix keyboard layout if enabled in config
+ if [[ $fix_layout == "true" ]]; then
+ layout_cmd
+ fi
+
+ # set help color
+ if [[ $help_color == "" ]]; then
+ help_color=$(rofi -dump-xresources | grep 'rofi.color.normal' | gawk -F ',' '/,/{gsub(/ /, "", $2); print $2}')
+ fi
+
+ # check for BROWSER variable, use xdg-open as fallback
+ if [[ -z $BROWSER ]]; then
+ export BROWSER=xdg-open
+ fi
+
+ # check if alternative root directory was given on commandline
+ if [[ -r "$HOME/.cache/rofi-pass/last_used" ]] && [[ $1 == "--last-used" || $1 == "--show-last" ]]; then
+ roots=("$(awk -F ': ' '{ print $1 }' "$HOME/.cache/rofi-pass/last_used")")
+ elif [[ -n "$2" && "$1" == "--root" ]]; then
+ custom_root=true; IFS=: read -r -a roots <<< "$2"
+ elif [[ -n $root ]]; then
+ custom_root=true; IFS=: read -r -a roots <<< "${root}"
+ elif [[ -n ${PASSWORD_STORE_DIR} ]]; then
+ roots=("${PASSWORD_STORE_DIR}")
+ else
+ roots=("$HOME/.password-store")
+ fi
+ roots_index=0
+ roots_length=${#roots[@]}
+ export root=${roots[$roots_index]}
+ export PASSWORD_STORE_DIR="${root}"
+ case $1 in
+ --insert)
+ insertPass
+ ;;
+ --root)
+ mainMenu
+ ;;
+ --help)
+ help_msg
+ ;;
+ --last-used)
+ if [[ -r "$HOME/.cache/rofi-pass/last_used" ]]; then
+ entry="$(awk -F ': ' '{ print $2 }' "$HOME/.cache/rofi-pass/last_used")"
+ fi
+ mainMenu
+ ;;
+ --show-last)
+ if [[ -r "$HOME/.cache/rofi-pass/last_used" ]]; then
+ selected_password="$(awk -F ': ' '{ print $2 }' "$HOME/.cache/rofi-pass/last_used")" viewEntry
+ else
+ mainMenu
+ fi
+ ;;
+ --bmarks)
+ mainMenu --bmarks;
+ ;;
+ *)
+ mainMenu
+ ;;
+ esac
+}
+
+main "$@"
+
diff --git a/global-common/usr/local/share/backgrounds/abandoned-hut-night.jpg b/global-common/usr/local/share/backgrounds/abandoned-hut-night.jpg
new file mode 100644
index 0000000..abda2ce
--- /dev/null
+++ b/global-common/usr/local/share/backgrounds/abandoned-hut-night.jpg
Binary files differ
diff --git a/global-common/usr/local/share/backgrounds/bag-end.jpg b/global-common/usr/local/share/backgrounds/bag-end.jpg
new file mode 100644
index 0000000..5bbf078
--- /dev/null
+++ b/global-common/usr/local/share/backgrounds/bag-end.jpg
Binary files differ
diff --git a/global-common/usr/local/share/backgrounds/book-of-kells.jpg b/global-common/usr/local/share/backgrounds/book-of-kells.jpg
new file mode 100644
index 0000000..1704633
--- /dev/null
+++ b/global-common/usr/local/share/backgrounds/book-of-kells.jpg
Binary files differ
diff --git a/global-common/usr/local/share/backgrounds/dore-christ-leaving-the-praetorium.jpg b/global-common/usr/local/share/backgrounds/dore-christ-leaving-the-praetorium.jpg
new file mode 100644
index 0000000..e201dda
--- /dev/null
+++ b/global-common/usr/local/share/backgrounds/dore-christ-leaving-the-praetorium.jpg
Binary files differ
diff --git a/global-common/usr/local/share/backgrounds/gandalf-1.jpg b/global-common/usr/local/share/backgrounds/gandalf-1.jpg
new file mode 100644
index 0000000..060325d
--- /dev/null
+++ b/global-common/usr/local/share/backgrounds/gandalf-1.jpg
Binary files differ
diff --git a/global-common/usr/local/share/backgrounds/gandalf-2.jpg b/global-common/usr/local/share/backgrounds/gandalf-2.jpg
new file mode 100644
index 0000000..c4167c3
--- /dev/null
+++ b/global-common/usr/local/share/backgrounds/gandalf-2.jpg
Binary files differ
diff --git a/global-common/usr/local/share/backgrounds/in-hoc-signo-vinces-fire.png b/global-common/usr/local/share/backgrounds/in-hoc-signo-vinces-fire.png
new file mode 100644
index 0000000..d1fefde
--- /dev/null
+++ b/global-common/usr/local/share/backgrounds/in-hoc-signo-vinces-fire.png
Binary files differ
diff --git a/global-common/usr/local/share/backgrounds/mass.jpg b/global-common/usr/local/share/backgrounds/mass.jpg
new file mode 100644
index 0000000..042dba6
--- /dev/null
+++ b/global-common/usr/local/share/backgrounds/mass.jpg
Binary files differ
diff --git a/global-common/usr/local/share/backgrounds/mount-st-michel.jpg b/global-common/usr/local/share/backgrounds/mount-st-michel.jpg
new file mode 100644
index 0000000..4031b89
--- /dev/null
+++ b/global-common/usr/local/share/backgrounds/mount-st-michel.jpg
Binary files differ
diff --git a/global-common/usr/local/share/backgrounds/odysseus-and-the-sirens-by-waterhouse.jpg b/global-common/usr/local/share/backgrounds/odysseus-and-the-sirens-by-waterhouse.jpg
new file mode 100644
index 0000000..d693e13
--- /dev/null
+++ b/global-common/usr/local/share/backgrounds/odysseus-and-the-sirens-by-waterhouse.jpg
Binary files differ
diff --git a/global-common/usr/local/share/backgrounds/old-knight.jpg b/global-common/usr/local/share/backgrounds/old-knight.jpg
new file mode 100644
index 0000000..3f4e6c0
--- /dev/null
+++ b/global-common/usr/local/share/backgrounds/old-knight.jpg
Binary files differ
diff --git a/global-common/usr/local/share/backgrounds/saint-michael.png b/global-common/usr/local/share/backgrounds/saint-michael.png
new file mode 100644
index 0000000..35d228f
--- /dev/null
+++ b/global-common/usr/local/share/backgrounds/saint-michael.png
Binary files differ
diff --git a/global-common/usr/local/share/backgrounds/stained-glass-depicting-the-virgin-mary-holding-baby-jesus.jpg b/global-common/usr/local/share/backgrounds/stained-glass-depicting-the-virgin-mary-holding-baby-jesus.jpg
new file mode 100644
index 0000000..7797604
--- /dev/null
+++ b/global-common/usr/local/share/backgrounds/stained-glass-depicting-the-virgin-mary-holding-baby-jesus.jpg
Binary files differ
diff --git a/global-common/usr/local/share/backgrounds/the-lamb-of-god.jpg b/global-common/usr/local/share/backgrounds/the-lamb-of-god.jpg
new file mode 100644
index 0000000..056935a
--- /dev/null
+++ b/global-common/usr/local/share/backgrounds/the-lamb-of-god.jpg
Binary files differ
diff --git a/global-wayland/etc/greetd/config.toml b/global-wayland/etc/greetd/config.toml
new file mode 100644
index 0000000..8e35d8d
--- /dev/null
+++ b/global-wayland/etc/greetd/config.toml
@@ -0,0 +1,12 @@
+[terminal]
+# The VT to run the greeter on. Can be "next", "current" or a number
+# designating the VT.
+vt = 1
+
+[default_session]
+command = "cage -s -- gtkgreet -l --style=/etc/greetd/gtkgreet.css"
+
+# The user to run the command as. The privileges this user must have depends
+# on the greeter. A graphical greeter may for example require the user to be
+# in the `video` group.
+user = "greeter"
diff --git a/global-wayland/etc/greetd/environments b/global-wayland/etc/greetd/environments
new file mode 100644
index 0000000..9783e95
--- /dev/null
+++ b/global-wayland/etc/greetd/environments
@@ -0,0 +1,2 @@
+river
+zsh
diff --git a/global-wayland/etc/greetd/gtkgreet.css b/global-wayland/etc/greetd/gtkgreet.css
new file mode 100644
index 0000000..36aab94
--- /dev/null
+++ b/global-wayland/etc/greetd/gtkgreet.css
@@ -0,0 +1,56 @@
+window {
+ background-image: url("file:///usr/local/share/backgrounds/mass.jpg");
+ background-size: cover;
+ background-position: center;
+ background-color: rgb(146, 149, 145);
+}
+
+#clock {
+ font-weight: bold;
+ padding: 20px;
+ color: rgb(245, 245, 245);
+ text-shadow: 4px 0 #000, -4px 0 #000, 0 4px #000, 0 -4px #000,
+ 2px 2px #000, -2px -2px #000, 2px -2px #000, -2px 2px #000;
+}
+
+box#body {
+ background-color: rgba(245, 245, 245, 0.4);
+ border: 3px solid rgb(49, 54, 56);
+ border-radius: 10px;
+ padding: 20px;
+}
+
+#body > box {
+ background-color: rgba(49, 54, 56, 0.8);
+ padding: 20px;
+}
+
+#body > box > box {
+ padding: 20px 0 20px 0;
+}
+
+box#body > box > box > label {
+ margin-right: 20px;
+}
+
+label,
+entry {
+ font-size: 1.7em;
+ min-height: 50px;
+ border-radius: 0;
+}
+
+button,
+entry,
+combobox * {
+ color: rgb(245, 245, 245);
+ background: rgb(24, 26, 27);
+ border: none;
+}
+
+box#body > box > box > button,
+box#body > box > box > entry,
+box#body > box > combobox {
+ border: 1px solid rgb(245, 245, 245);
+ border-radius: 0;
+}
diff --git a/terminal/.config/tmux/plugins/tmux-current-pane-hostname b/terminal/.config/tmux/plugins/tmux-current-pane-hostname
new file mode 160000
+Subproject 6bb3c95250f8120d8b072f46a807d2678ecbc97
diff --git a/terminal/.config/tmux/tmux.conf b/terminal/.config/tmux/tmux.conf
new file mode 100644
index 0000000..1070843
--- /dev/null
+++ b/terminal/.config/tmux/tmux.conf
@@ -0,0 +1,117 @@
+unbind C-b
+unbind C-Space
+set-option -g prefix C-Space
+bind C-Space send-prefix
+
+# Source: https://michenriksen.com/notes/alacritty-tmux-neovim-colors-and-undercurl/#codeblock-01
+set -g default-terminal "tmux-256color"
+# Enable undercurl and color.
+set -ga terminal-features ",*:usstyle"
+# Support RGB color with SGR escape sequences.
+set -gs terminal-overrides ",*:RGB"
+
+set -g mouse on
+set -g base-index 1
+setw -g xterm-keys on
+set -s escape-time 10
+set -sg repeat-time 600
+set -s focus-events on
+
+set -g status-position bottom
+set -g status-justify centre
+set-option -g status-style bg=#181A1B
+
+set-option -ag message-style fg=yellow,blink
+set-option -ag message-style bg=default
+
+set -g status-left '#[fg=blue,bg=white,bold] 󰏉 #S #[bg=default] '
+set -g status-left-length 20
+
+set -g @tpm_plugins "tmux-plugins/tpm soyuka/tmux-current-pane-hostname"
+
+set -g status-right "#[fg=none,bg=none]#{?client_prefix,⌨ , }#[fg=orange,bg=black] #H #[fg=black,bg=orange] %a "
+set -g status-right-length 50
+
+set-window-option -g window-status-separator ' '
+set-window-option -g window-status-current-style 'bold'
+set-window-option -g window-status-last-style 'bold'
+set-window-option -g window-status-style 'none'
+
+set-window-option -g window-status-current-format '#[fg=white,bg=blue] #I| #W '
+set-window-option -g window-status-format '#[fg=lightblue] #I| #W '
+
+set-window-option -g pane-active-border-style "bg=default fg=#fdf070"
+
+# Rather than constraining window size to the maximum size of any client
+# connected to the *session*, constrain window size to the maximum size of any
+# client connected to *that window*. Much more reasonable.
+setw -g aggressive-resize on
+
+# Bindings
+
+bind \; command-prompt
+bind r command-prompt -I "rename-window #{window_name}"
+bind e command-prompt -I "rename-session #{session_name}"
+
+# Source: https://hamvocke.com/blog/a-guide-to-customizing-your-tmux-conf/
+# split panes using | and -
+bind | split-window -h -c '#{pane_current_path}'
+bind \\ split-window -h -c '#{pane_current_path}'
+bind - split-window -v -c '#{pane_current_path}'
+bind _ split-window -v -c '#{pane_current_path}'
+unbind '"'
+unbind %
+
+# Split right, left, down, up
+# bind -r C-l split-pane -h -c '#{pane_current_path}'
+# bind -r C-h split-pane -hb -c '#{pane_current_path}'
+# bind -r C-j split-pane -v -c '#{pane_current_path}'
+# bind -r C-k split-pane -vb -c '#{pane_current_path}'
+
+bind Enter new-window -c '#{pane_current_path}'
+
+# Source: https://hamvocke.com/blog/a-guide-to-customizing-your-tmux-conf/
+# switch panes using Alt-arrow without prefix
+bind -n M-Left select-pane -L
+bind -n M-Right select-pane -R
+bind -n M-Up select-pane -U
+bind -n M-Down select-pane -D
+
+bind -n M-h select-pane -L
+bind -n M-l select-pane -R
+bind -n M-k select-pane -U
+bind -n M-j select-pane -D
+
+bind -r h select-pane -L
+bind -r l select-pane -R
+bind -r k select-pane -U
+bind -r j select-pane -D
+
+bind -r [ select-pane -t :.-
+bind -r ] select-pane -t :.+
+
+bind -r p previous-window
+bind -r n next-window
+
+bind -r Space next-layout
+
+# Resize right, left, down, up
+bind -r -T prefix M-k resize-pane -U 5
+bind -r -T prefix M-j resize-pane -D 5
+bind -r -T prefix M-h resize-pane -L 5
+bind -r -T prefix M-l resize-pane -R 5
+bind -r -T prefix C-k resize-pane -U
+bind -r -T prefix C-j resize-pane -D
+bind -r -T prefix C-h resize-pane -L
+bind -r -T prefix C-l resize-pane -R
+
+# Easier vertical scroll
+bind -n M-U copy-mode -e \; send-keys -X -N 5 scroll-up
+bind -T copy-mode M-D copy-mode -e \; send-keys -X -N 5 scroll-down
+
+set -gq allow-passthrough on
+set -g visual-activity off
+set-option -ga terminal-features ",alacritty:usstyle"
+
+# Source: https://github.com/soyuka/tmux-current-pane-hostname
+run-shell ~/.config/tmux/plugins/tmux-current-pane-hostname/current_pane_hostname.tmux
diff --git a/terminal/.local/bin/urlhandler b/terminal/.local/bin/urlhandler
new file mode 100755
index 0000000..021c487
--- /dev/null
+++ b/terminal/.local/bin/urlhandler
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+urlregex="(((http|https|gopher|gemini|ftp|ftps|git)://|www\\.)[a-zA-Z0-9.]*[:;a-zA-Z0-9./+@$&%?$\#=_~-]*)|((magnet:\\?xt=urn:btih:)[a-zA-Z0-9]*)"
+
+urls="$(sed 's/.*│//g' | tr -d '\n' | # First remove linebreaks and mutt sidebars:
+ grep -aEo "$urlregex" | # grep only urls as defined above.
+ uniq | # Ignore neighboring duplicates.
+ sed "s/\(\.\|,\|;\|\!\\|\?\)$//;
+ s/^www./http:\/\/www\./")" # xdg-open will not detect url without http
+
+[ -z "$urls" ] && exit 1
+
+if [ $(echo "$urls" | wc -l) = "1" ]; then
+ chosen_url="$urls"
+else
+ chosen_url="$(echo "$urls" | rofi -dmenu -i -p "󰌹" -l 10)"
+fi
+
+case "$chosen_url" in
+ http://*suckless.org*|https://*suckless.org*) command="surf" ;;
+ https://*.reliant.io*|https://acumera.*) command="/usr/bin/librewolf -P work" ;;
+ *) command="xdg-open" ;;
+esac
+
+setsid $command "$chosen_url" >/dev/null 2>&1
diff --git a/terminal/dot-zimrc b/terminal/dot-zimrc
new file mode 100644
index 0000000..341b0f3
--- /dev/null
+++ b/terminal/dot-zimrc
@@ -0,0 +1,16 @@
+zmodule input
+zmodule termtitle
+
+zmodule prompt-pwd
+zmodule duration-info
+zmodule git-info
+
+zmodule zsh-users/zsh-completions --fpath src
+zmodule completion
+
+# Modules that must be initialized last
+
+zmodule zsh-users/zsh-syntax-highlighting
+zmodule zsh-users/zsh-history-substring-search
+zmodule zsh-users/zsh-autosuggestions
+zmodule fzf
diff --git a/terminal/dot-zshrc b/terminal/dot-zshrc
new file mode 100644
index 0000000..3258454
--- /dev/null
+++ b/terminal/dot-zshrc
@@ -0,0 +1,142 @@
+export LANG=en_US.UTF-8
+export EDITOR=nvim
+
+# Set editor default keymap to emacs (`-e`) or vi (`-v`)
+bindkey -e
+
+export HISTFILE=~/.zsh_history
+export HISTSIZE=268435456
+export SAVEHIST="$HISTSIZE"
+
+setopt APPEND_HISTORY
+setopt SHARE_HISTORY
+setopt HIST_EXPIRE_DUPS_FIRST
+setopt HIST_IGNORE_DUPS
+setopt HIST_IGNORE_ALL_DUPS
+setopt HIST_FIND_NO_DUPS
+setopt HIST_SAVE_NO_DUPS
+setopt HIST_VERIFY
+setopt HIST_IGNORE_SPACE
+setopt HIST_REDUCE_BLANKS
+setopt NO_NOMATCH
+
+# Remove path separator from WORDCHARS.
+WORDCHARS=${WORDCHARS//[\/]}
+
+# -----------------
+# Zim configuration
+# -----------------
+
+setopt nopromptbang prompt{cr,percent,sp,subst}
+
+zstyle ':zim:git-info' verbose yes
+zstyle ':zim:git-info:branch' format '%b'
+zstyle ':zim:git-info:commit' format '%c'
+zstyle ':zim:git-info:stashed' format '%F{#40995A}%S%f'
+zstyle ':zim:git-info:dirty' format '%F{red}⚡%f'
+zstyle ':zim:git-info:clean' format '%F{green}✓%f'
+zstyle ':zim:git-info:indexed' format '%F{#F88C15}✚%f'
+zstyle ':zim:git-info:untracked' format '%F{red}✹%f'
+zstyle ':zim:git-info:keys' format 'prompt' '  %b%c %D%S%C%i%u '
+
+zstyle ':zim:prompt-pwd' git-root no
+zstyle ':zim:prompt-pwd:tail' length 2
+
+autoload -Uz add-zsh-hook && add-zsh-hook precmd git-info
+
+# PS1='%K{#5F87AF}%F{yellow}  $(prompt-pwd) %f%k%F{blue}%K{yellow}${(e)git_info[prompt]}%k%f %B%(?:%F{green}:%F{red})%{%G➤%}%b '
+PS1='%F{#F88C15}@${(%):-%m} %F{yellow} $(prompt-pwd) %f%F{#AACCFF}${(e)git_info[prompt]}%f %B%(?:%F{green}:%F{red})%{%G➤%}%b '
+
+# termtitle
+
+# Set a custom terminal title format using prompt expansion escape sequences.
+# See http://zsh.sourceforge.net/Doc/Release/Prompt-Expansion.html#Simple-Prompt-Escapes
+# If none is provided, the default '%n@%m: %~' is used.
+# zstyle ':zim:termtitle' format '%1~'
+
+# zsh-autosuggestions
+
+# Disable automatic widget re-binding on each precmd. This can be set when
+# zsh-users/zsh-autosuggestions is the last module in your ~/.zimrc.
+ZSH_AUTOSUGGEST_MANUAL_REBIND=1
+
+# Customize the style that the suggestions are shown with.
+# See https://github.com/zsh-users/zsh-autosuggestions/blob/master/README.md#suggestion-highlight-style
+# ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE='fg=242'
+
+# zsh-syntax-highlighting
+
+# Set what highlighters will be used.
+# See https://github.com/zsh-users/zsh-syntax-highlighting/blob/master/docs/highlighters.md
+ZSH_HIGHLIGHT_HIGHLIGHTERS=(main brackets)
+
+# Customize the main highlighter styles.
+# See https://github.com/zsh-users/zsh-syntax-highlighting/blob/master/docs/highlighters/main.md#how-to-tweak-it
+# typeset -A ZSH_HIGHLIGHT_STYLES
+# ZSH_HIGHLIGHT_STYLES[comment]='fg=242'
+
+# ------------------
+# Initialize modules
+# ------------------
+
+ZIM_HOME=${ZDOTDIR:-${HOME}}/.zim
+# Download zimfw plugin manager if missing.
+if [[ ! -e ${ZIM_HOME}/zimfw.zsh ]]; then
+ if (( ${+commands[curl]} )); then
+ curl -fsSL --create-dirs -o ${ZIM_HOME}/zimfw.zsh \
+ https://github.com/zimfw/zimfw/releases/latest/download/zimfw.zsh
+ else
+ mkdir -p ${ZIM_HOME} && wget -nv -O ${ZIM_HOME}/zimfw.zsh \
+ https://github.com/zimfw/zimfw/releases/latest/download/zimfw.zsh
+ fi
+fi
+# Install missing modules, and update ${ZIM_HOME}/init.zsh if missing or outdated.
+if [[ ! ${ZIM_HOME}/init.zsh -nt ${ZDOTDIR:-${HOME}}/.zimrc ]]; then
+ source ${ZIM_HOME}/zimfw.zsh init -q
+fi
+# Initialize modules.
+source ${ZIM_HOME}/init.zsh
+
+# ------------------------------
+# Post-init module configuration
+# ------------------------------
+
+# zsh-history-substring-search
+
+zmodload -F zsh/terminfo +p:terminfo
+# Bind ^[[A/^[[B manually so up/down works both before and after zle-line-init
+for key ('^[[A' '^P' ${terminfo[kcuu1]}) bindkey ${key} history-substring-search-up
+for key ('^[[B' '^N' ${terminfo[kcud1]}) bindkey ${key} history-substring-search-down
+for key ('k') bindkey -M vicmd ${key} history-substring-search-up
+for key ('j') bindkey -M vicmd ${key} history-substring-search-down
+unset key
+
+# ------------------------------
+# My Stuff
+alias grep='grep --color=auto'
+alias ip='ip -color=auto'
+alias xproxy='ssh -N -D 9090 illyria'
+alias gk='gitk --all &'
+alias ls='exa --icons'
+alias tree='exa --icons --tree'
+alias undercurl='echo -e "\e[4:3mUNDERCURL!"'
+
+alias mpd-start='systemctl start --user mpd'
+
+alias nocontrol="rm ~/.ssh/control:*"
+alias mute_notifications="dunstify 'Muting notifications' && sleep 2 && dunstctl set-paused true"
+alias unmute_notifications="dunstctl close-all && dunstctl set-paused false && dunstify 'Notifications unmutted'"
+
+eval "$(zoxide init zsh --cmd cd)"
+
+# Add RVM to PATH for scripting. Make sure this is the last PATH variable change.
+# Source: https://github.com/rvm/rvm/issues/3212#issuecomment-274912875
+# Squelch the warning by appending ' > /dev/null 2>&1' here
+[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" > /dev/null 2>&1
+
+# RVM fixes whatever it considers the problem to be, on its own, in `rvm use`.
+# It also prints some junk we don't care about, so we squelch its output in the same way.
+rvm use default > /dev/null 2>&1
+
+export ZK_NOTEBOOK_DIR="$HOME/Documents/zk"
+fpath+=${ZDOTDIR:-~}/.zsh_functions