commit fffd5c7f5109234c4d0bf0c58dc648fc068dcd87
parent 6231aedafd862b047ac670eca32d91ff0b00f83b
Author: Mahdi Mirzade <[email protected]>
Date: Sat, 8 Oct 2022 22:07:50 +0330
Remove builds
Diffstat:
236 files changed, 794 insertions(+), 69997 deletions(-)
diff --git a/.config/mbsync/mbsyncrc b/.config/mbsync/mbsyncrc
@@ -1,9 +1,18 @@
+# Automatically create missing mailboxes, both locally and on the server.
+Create Both
+
+# Sync the movement of messages between folders and deletions,
+# add after making sure the sync works.
+Expunge Both
+
+# Save the synchronization state files in the relevant directory.
+SyncState *
+
IMAPAccount acct0
Host mail.mahdi.pw
User me
-# Pass "This is my secure password"
-PassCmd "pass email"
-# Use SSL
+#Pass "This is my secure password"
+PassCmd "pash s email"
SSLType IMAPS
SSLVersions TLSv1.2
AuthMechs LOGIN
@@ -14,18 +23,9 @@ Account acct0
MaildirStore acct0-local
Subfolders Verbatim
-# The trailing "/" is important
-Path ~/.local/share/mail/acct0/
+Path ~/.local/share/mail/acct0/ # The trailing "/" is important
Inbox ~/.local/share/mail/acct0/Inbox
Channel acct0
Far :acct0-remote:
Near :acct0-local:
-# Include everything
-Patterns *
-# Automatically create missing mailboxes, both locally and on the server
-Create Both
-# Sync the movement of messages between folders and deletions, add after making sure the sync works
-Expunge Both
-# Save the synchronization state files in the relevant directory
-SyncState *
diff --git a/.config/mpv/input.conf b/.config/mpv/input.conf
@@ -53,6 +53,12 @@ Ctrl+d run "/bin/sh" "-c" "(choice=`printf 'Yes\nNo' | dmenu -p \"Delete \\\"${p
# - Copy the name of the file to clipboard
Ctrl+y run "/bin/sh" "-c" "printf '%s' \"${path}\" | xclip -selection c"; show-text "Copied ${path} to Clipboard"
+# - Copy subtitle-text to clipboard
+ctrl+s run "/bin/sh" "-c" "echo \"${sub-text}\" | tr '\n' ' ' | xclip -selection c" ; show-text "Copied subtitle to clipboard."
+
+# - Copy a word from subtitle-text to clipboard (dmenu)
+ctrl+shift+s run "/bin/sh" "-c" "echo \"${sub-text}\" | tr ' ' '\n' | dmenu -i -l 20 | xclip -selection c" ; show-text "Copied word to clipboard."
+
# TODO: Figure this out
# - Paste from clipboard to playlist
Ctrl+p run "/bin/sh" "-c" "xclip -selection c -o"
diff --git a/.config/mutt/mailcap b/.config/mutt/mailcap
@@ -1,6 +1,6 @@
text/plain; $EDITOR %s ;
text/html; openfile %s ; nametemplate=%s.html
-text/html; lynx -assume_charset=%{charset} -display_charset=utf-8 -dump -width=1024 %s; nametemplate=%s.html; copiousoutput;
+text/html; lynx -dump %s; nametemplate=%s.html; copiousoutput;
image/*; openfile %s ;
video/*; mpv --quiet %s &; copiousoutput
audio/*; mpv %s ;
diff --git a/.config/mutt/muttrc b/.config/mutt/muttrc
@@ -6,6 +6,7 @@ macro index,pager <f3> '<sync-mailbox><enter-command>source ~/.config/mutt/work<
# Personal Details
set realname="Mahdi Mirzade"
set from="[email protected]"
+set signature="~/.config/mutt/signature"
set use_from=yes
set use_envelope_from=yes
set reverse_name=yes
@@ -16,12 +17,12 @@ set ssl_force_tls = yes
# Syntax: imaps://user@domain@imap_domain:port
#set folder="imaps://[email protected]@mail.mahdi.pw:993"
-#set imap_pass = `pass email`
+#set imap_pass = `pash s email`
set folder="~/.local/share/mail/acct0"
# Syntax: smtps://user@domain@smtp_domain:port
set smtp_url = "smtps://[email protected]@mail.mahdi.pw:465"
-set smtp_pass = `pass email`
+set smtp_pass = `pash s email`
# Mailboxes
set spoolfile="+Inbox"
@@ -34,6 +35,7 @@ mailboxes =Inbox =Drafts =Sent =Junk =Trash
# Settings
set mailcap_path="~/.config/mutt/mailcap"
macro attach s <save-entry><bol>~/Downloads/<eol>
+macro index V "!email -sn^M" "Update through mbsync"
set date_format="%y/%m/%d %I:%M%p"
set index_format="%2C %Z %?X?A& ? %D %-15.15F %s (%-4.4c)"
set sort = 'reverse-date'
diff --git a/.config/shell/aliasrc b/.config/shell/aliasrc
@@ -1,36 +0,0 @@
-#!/bin/sh
-
-# Run some programs in sudo.
-for command in mount umount sv pacman pkg updatedb su; do
- alias $command="doas $command"
-done; unset command
-
-alias startx="startx \"$XINITRC\""
-alias vim="vim -i ${XDG_DATA_HOME:-$HOME/.local/share}/viminfo"
-
-alias \
- ..='cd ..' \
- ...='cd ../..' \
- ....='cd ../../..'
-
-# Fix colorizing commands.
-alias \
- ls="ls -h --color=always" \
- ip="ip --color=auto" \
- grep="grep --color=auto"
-
-# Lazy Aliases.
-alias \
- c="clear -x" \
- e="$EDITOR" \
- g="git" \
- h="htop" \
- l="ls" \
- p="pacman" \
- v="$EDITOR" \
- x="exit"
-
-# Suckless now with tabbed.
-#alias \
-# surf="surf-open" \
-# st="tabbed -c -r 2 st -w ''"
diff --git a/.config/shell/inputrc b/.config/shell/inputrc
@@ -1,15 +0,0 @@
-set editing-mode vi
-
-set show-mode-in-prompt on
-set vi-ins-mode-string \1\e[6 q\2
-set vi-cmd-mode-string \1\e[2 q\2
-
-set keymap vi-command
-# these are for vi-command mode
-Control-l: clear-screen
-Control-a: beginning-of-line
-
-set keymap vi-insert
-# these are for vi-insert mode
-Control-l: clear-screen
-Control-a: beginning-of-line
diff --git a/.config/shell/profile b/.config/shell/profile
@@ -1,57 +0,0 @@
-#!/bin/sh
-# Environmental variables are set here. (Runs on login)
-
-# Adds `~/.local/bin/*` to $PATH
-#export PATH="$PATH:${$(find ~/.local/bin -type d -printf %p:)%%:}"
-# Adds `~/.local/bin` to $PATH
-export PATH="$PATH:$HOME/.local/bin"
-
-# Default Programs
-export BROWSER="surf-open"
-export EDITOR="vi"
-export TERMINAL="st"
-
-# XDG_CONFIG
-export XDG_CACHE_HOME="$HOME/.cache"
-export XDG_CONFIG_HOME="$HOME/.config"
-export XDG_DATA_HOME="$HOME/.local/share"
-export XDG_STATE_HOME="$HOME/.local/state"
-export XDG_RUNTIME_DIR="$HOME/.local/run"
-
-[ -d "$XDG_CACHE_HOME" ] || mkdir -p "$XDG_CACHE_HOME"
-[ -d "$XDG_CONFIG_HOME" ] || mkdir -p "$XDG_CONFIG_HOME"
-[ -d "$XDG_DATA_HOME" ] || mkdir -p "$XDG_DATA_HOME"
-[ -d "$XDG_STATE_HOME" ] || mkdir -p "$XDG_STATE_HOME"
-[ -d "$XDG_RUNTIME_DIR" ] || mkdir -p "$XDG_RUNTIME_DIR"
-
-# Use $XDG_CONFIG_HOME for disrespectful programs
-export GNUPGHOME="${XDG_DATA_HOME:-$HOME/.local/share}/gnupg"
-export GTK2_RC_FILES="${XDG_CONFIG_HOME:-$HOME/.config}/gtk-2.0/gtkrc-2.0"
-export HISTFILE="${XDG_DATA_HOME:-$HOME/.local/share}/history.$(basename "$(echo "${0:-$SHELL}" | sed 's|-||')")"
-export INPUTRC="${XDG_CONFIG_HOME:-$HOME/.config}/shell/inputrc"
-export MBSYNCRC="${XDG_CONFIG_HOME:-$HOME/.config}/mbsync/mbsyncrc"
-export PASSWORD_STORE_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/password-store"
-export WGETRC="${XDG_CONFIG_HOME:-$HOME/.config}/wget/wgetrc"
-export LESSHISTFILE="${XDG_DATA_HOME:-$HOME/.local/share}/lesshst"
-export XAUTHORITY="${XDG_RUNTIME_DIR}/Xauthority"
-export XINITRC="${XDG_CONFIG_HOME:-$HOME/.config}/x11/xinitrc"
-
-export DOAS_ASKPASS="dmenu -P -p Password:"
-export QT_STYLE_OVERRIDE="kvantum"
-
-if [ "$(tty)" = "/dev/tty1" ] || [ "$(tty)" = "/dev/ttyv0" ]; then
- pidof -s Xorg >/dev/null 2>&1 || exec startx "$XINITRC"
-fi
-
-## Start graphics if 'libxft-bgra' was installed and already not running.
-#if pacman -Q libxft-bgra >/dev/null 2>&1; then
-# [ "$(tty)" = "/dev/tty1" ] && ! pidof -s Xorg >/dev/null 2>&1 && exec startx "$XINITRC"
-#else
-# printf "\033[31mIMPORTANT\033[0m: Note that \033[32m\`libxft-bgra\`\033[0m must be installed for my build of dwm, st, ...\n"
-# printf "Please run:\n"
-# printf "\033[32m\tgit clone https://mahdi.pw/git/libxft.git\n\033[0m"
-# printf "\033[32m\tcd libxft\n\033[0m"
-# printf "\033[32m\tmakepkg -si\n\033[0m"
-# printf "and replace 'libxft' (if not replaced by pacman).\n"
-# printf "Afterwards enter the graphical server using: \033[34mstartx \"$XINITRC\"\033[0m\n"
-#fi
diff --git a/.config/surf/styles/default.css b/.config/surf/styles/default.css
@@ -1,25 +1,29 @@
/*html, img { -webkit-filter: invert(1) hue-rotate(180deg); }*/
*, *::before, *::after { background-image: none !important; }
-/*a,button,col,div,textarea,body,input,form,td,tr,th,p,span,article,svg,header,footer,details,summary { */
-html,head,body,header,footer,a,p,h1,h2,h3,h4,h5,h6,h7,div,ul,li,dl,dt,q,pre,code,blockquote,i,u,input,button,tag,table,thead,tbody,tfoot,td,tr,th,span,article,details,summary,textarea,div,a,svg,label,aside,main {
-/*,*, *::before, *::after { */
- background-color: #1E2127 !important;
- border-color: #5C6370 !important;
- color: #ABB2BF !important;
+/*a,button,col,div,textarea,body,input,form,td,tr,th,p,span,
+article,svg,header,footer,details,summary { */
+/*html,head,body,header,footer,a,p,h1,h2,h3,h4,h5,h6,h7,div,
+ul,li,dl,dt,q,pre,code,blockquote,i,u,input,button,tag,table,
+thead,tbody,tfoot,td,tr,th,span,article,details,summary,textarea,
+div,a,svg,label,aside,main {*/
+*, *::before, *::after {
+ background-color: #282a36 !important;
+ border-color: #4D4D4D !important;
+ color: #BFBFBF !important;
}
blockquote, pre, code, code>* {
- background-color: #1E2127 !important;
- border-color: #5C6370 !important;
- color: #ABB2BF !important;
+ background-color: #282a36 !important;
+ border-color: #4D4D4D !important;
+ color: #BFBFBF !important;
padding: 5px;
font-family: monospace;
}
-a:link { color: #56B6C2 !important; }
-a:hover { color: #C678DD !important; }
-a:visited { color: #C678DD !important; }
-input:hover { color: #56B6C2 !important; }
-button:hover { color: #56B6C2 !important; }
+a:link { color: #8BE9FD !important; }
+a:hover { color: #FF79C6 !important; }
+a:visited { color: #FF92D0 !important; }
+input:hover { color: #9AEDFE !important; }
+button:hover { color: #9AEDFE !important; }
img { opacity: .75; }
img:hover { opacity: 1; }
diff --git a/.config/surf/styles/default.css.in b/.config/surf/styles/default.css.in
@@ -1,8 +1,12 @@
/*html, img { -webkit-filter: invert(1) hue-rotate(180deg); }*/
*, *::before, *::after { background-image: none !important; }
-/*a,button,col,div,textarea,body,input,form,td,tr,th,p,span,article,svg,header,footer,details,summary { */
-html,head,body,header,footer,a,p,h1,h2,h3,h4,h5,h6,h7,div,ul,li,dl,dt,q,pre,code,blockquote,i,u,input,button,tag,table,thead,tbody,tfoot,td,tr,th,span,article,details,summary,textarea,div,a,svg,label,aside,main {
-/*,*, *::before, *::after { */
+/*a,button,col,div,textarea,body,input,form,td,tr,th,p,span,
+article,svg,header,footer,details,summary { */
+/*html,head,body,header,footer,a,p,h1,h2,h3,h4,h5,h6,h7,div,
+ul,li,dl,dt,q,pre,code,blockquote,i,u,input,button,tag,table,
+thead,tbody,tfoot,td,tr,th,span,article,details,summary,textarea,
+div,a,svg,label,aside,main {*/
+*, *::before, *::after {
background-color: %cl0% !important;
border-color: %cl8% !important;
color: %cl7% !important;
diff --git a/.config/vis/visrc.lua b/.config/vis/visrc.lua
@@ -1,50 +1,53 @@
require('vis')
vis.events.subscribe(vis.events.INIT, function()
- -- Your global configuration options
+ -- Your global configuration options
end)
vis.events.subscribe(vis.events.WIN_OPEN, function(win)
- -- Your per window configuration options e.g.
- vis:command('set number')
- --vis:command('set relativenumbers')
+ -- Your per window configuration options e.g.
+ vis:command('set number')
+ vis:command('set colorcolumn 80')
+ --vis:command('set relativenumbers')
--vis:command('set expandtab')
vis:command('set tabwidth 4')
vis:command('set escdelay 0')
vis:command('set show-eof off')
- vis:command('set theme dark-16')
- vis:command('set autoindent on')
+ vis:command('set theme my-theme')
+ vis:command('set autoindent on')
end)
-- Backspace removes 4 spaces if need be
vis:map(vis.modes.INSERT, '<Backspace>', function()
- local tabwidth = 4
- local single_selection = false
- for selection in vis.win:selections_iterator() do
- if single_selection then
- single_selection = false
- break
- end
- single_selection = true
- end
-
- local to_stop = (vis.win.selection.col - 1) % tabwidth
- if to_stop == 0 then
- to_stop = tabwidth
- end
-
- if single_selection and to_stop > 1 and vis.win.file:content(vis.win.selection.pos - to_stop, to_stop) == string.rep(' ', to_stop) then
- vis:feedkeys(string.rep('<vis-delete-char-prev>', to_stop))
- else
- vis:feedkeys('<vis-delete-char-prev>')
- end
-end)
+ local tabwidth = 4
+ local single_selection = false
+ for selection in vis.win:selections_iterator() do
+ if single_selection then
+ single_selection = false
+ break
+ end
+ single_selection = true
+ end
+
+ local to_stop = (vis.win.selection.col - 1) % tabwidth
+ if to_stop == 0 then
+ to_stop = tabwidth
+ end
+
+ if single_selection and to_stop > 1 and
+ vis.win.file:content(vis.win.selection.pos - to_stop, to_stop) ==
+ string.rep(' ', to_stop) then
+ vis:feedkeys(string.rep('<vis-delete-char-prev>', to_stop))
+ else
+ vis:feedkeys('<vis-delete-char-prev>')
+ end
+end, "Backspace removes 4 spaces if need be")
-- Strip trailing spaces
vis:command_register("sts", function(argv, force, win, selection, range)
- local lines = win.file.lines
- for index=1, #lines do
- lines[index] = lines[index]:gsub("%s+$", "")
- end
- return true
+ local lines = win.file.lines
+ for index=1, #lines do
+ lines[index] = lines[index]:gsub("%s+$", "")
+ end
+ return true
end, "Strip line trailing spaces")
diff --git a/.config/x11/colors b/.config/x11/colors
@@ -1,31 +1,20 @@
-! Custom
-! Original theme https://github.com/nathanbuchar/atom-one-dark-terminal
-*.foreground: #ABB2BF
-*.background: #1E2127
-*.cursorColor: #5C6370
-*.highlightColor:#3A3F4B
-
-! Negro y gris
-*.color0: #1E2127
-*.color8: #5C6370
-! Rojos
-*.color1: #E06C75
-*.color9: #E06C75
-! Verde
-*.color2: #98C379
-*.color10: #98C379
-! Amarillo
-*.color3: #D19A66
-*.color11: #D19A66
-! Azul
-*.color4: #61AFEF
-*.color12: #61AFEF
-! Magenta
-*.color5: #C678DD
-*.color13: #C678DD
-! Cyan
-*.color6: #56B6C2
-*.color14: #56B6C2
-! Blanco
-*.color7: #ABB2BF
-*.color15: #FFFFFF
+! Dracula Xresources palette
+*.foreground: #f8f8f2
+*.background: #282a36
+*.cursorColor: #6272a4
+*.color0: #282a36
+*.color8: #4D4D4D
+*.color1: #FF5555
+*.color9: #FF6E67
+*.color2: #50FA7B
+*.color10: #5AF78E
+*.color3: #F1FA8C
+*.color11: #F4F99D
+*.color4: #BD93F9
+*.color12: #CAA9FA
+*.color5: #FF79C6
+*.color13: #FF92D0
+*.color6: #8BE9FD
+*.color14: #9AEDFE
+*.color7: #BFBFBF
+*.color15: #E6E6E6
diff --git a/.config/x11/themes/solarized-dark b/.config/x11/themes/solarized-dark
@@ -1,36 +1,53 @@
-*.foreground: #708284
-*.background: #001e27
-*.cursorColor: #708284
-!
-! Black
-*.color0: #002831
-*.color8: #001e27
-!
-! Red
-*.color1: #d11c24
-*.color9: #bd3613
-!
-! Green
-*.color2: #738a05
-*.color10: #475b62
-!
-! Yellow
-*.color3: #a57706
-*.color11: #536870
-!
-! Blue
-*.color4: #2176c7
-*.color12: #708284
-!
-! Magenta
-*.color5: #c61c6f
-*.color13: #5956ba
-!
-! Cyan
-*.color6: #259286
-*.color14: #819090
-!
-! White
-*.color7: #eae3cb
-*.color15: #fcf4dc
+#define S_base03 #002b36
+#define S_base02 #073642
+#define S_base01 #586e75
+#define S_base00 #657b83
+#define S_base0 #839496
+#define S_base1 #93a1a1
+#define S_base2 #eee8d5
+#define S_base3 #fdf6e3
+*.background: S_base03
+*.foreground: S_base0
+*.cursorColor: S_base1
+
+#define S_yellow #b58900
+#define S_orange #cb4b16
+#define S_red #dc322f
+#define S_magenta #d33682
+#define S_violet #6c71c4
+#define S_blue #268bd2
+#define S_cyan #2aa198
+#define S_green #859900
+
+! black dark/light
+*.color0: S_base03
+*.color8: S_base02
+
+! red dark/light
+*.color1: S_red
+*.color9: S_orange
+
+! green dark/light
+*.color2: S_green
+*.color10: S_base01
+
+! yellow dark/light
+*.color3: S_yellow
+*.color11: S_base00
+
+! blue dark/light
+*.color4: S_blue
+*.color12: S_base0
+
+! magenta dark/light
+*.color5: S_magenta
+*.color13: S_violet
+
+! cyan dark/light
+*.color6: S_cyan
+*.color14: S_base1
+
+! white dark/light
+*.color7: S_base2
+*.color15: S_base3
diff --git a/.config/x11/xinitrc b/.config/x11/xinitrc
@@ -6,17 +6,12 @@ UMM="${XDG_CONFIG_HOME:-$HOME/.config}"/x11/xmodmap
[ -f "$UMM" ] && xmodmap "$UMM"
# Autostart:
-#setsid xsetroot -cursor_name left_ptr
-#setsid xautolock -time 10 -locker slock
-[ -f "$HOME/.cache/theme" ] || theme-sel
-#pidof "dunst" || setsid "dunst"
-pidof "bg-gen" || setsid "bg-gen"
-pidof "dwm-bar" || setsid "dwm-bar"
-pidof "pipewire" || setsid "pipewire"
-pidof "pipewire-alsa" || setsid "pipewire-alsa"
-pidof "pipewire-jack" || setsid "pipewire-jack"
-pidof "pipewire-pulse" || setsid "pipewire-pulse"
-pidof "pipewire-media-session" || setsid "pipewire-media-session"
+pidof "theme-sel" || theme-sel -x
+pidof "bg-gen" || bg-gen &
+pidof "dwm-bar" || dwm-bar &
+pidof "pipewire" || pipewire &
+xset -dpms # Disables Energy Star features
+xset s off # Disables screen saver
# Monitors:
i=0
@@ -36,11 +31,10 @@ done
setxkbmap -layout us,ir
setxkbmap -option 'grp:caps_toggle'
-# Keyboard - Fix for my laptop's broken keyboard:
+# Keyboard - Bind `Alt_L` to `p` for my laptop's broken keyboard:
xmodmap -e "clear mod1"
xmodmap -e "keycode 108 = p P Arabic_hah bracketleft"
xmodmap -e "add mod1 = Alt_L Meta_L"
# Add -f after startx to experience dwm in floating mode.
ssh-agent dwm "$@"
-#exec dwm "$@"
diff --git a/.config/yt-dlp/config b/.config/yt-dlp/config
@@ -14,4 +14,4 @@
--embed-subs
# Cookies are good
---cookies ~/.local/share/yt-cookies.txt
+#--cookies ~/.local/share/yt-cookies.txt
diff --git a/.config/zathura/zathurarc b/.config/zathura/zathurarc
@@ -11,31 +11,31 @@ set adjust-open width # Adjust to when opening file
map b toggle_statusbar
# Theme
-set default-bg "#1E2127"
-set default-fg "#ABB2BF"
-set statusbar-bg "#1E2127"
-set statusbar-fg "#ABB2BF"
-set inputbar-bg "#1E2127"
-set inputbar-fg "#56B6C2"
-set completion-bg "#1E2127"
-set completion-fg "#ABB2BF"
-set completion-group-bg "#1E2127"
-set completion-group-fg "#ABB2BF"
-set completion-highlight-bg "#5C6370"
-set completion-highlight-fg "#ABB2BF"
-set notification-bg "#5C6370"
-set notification-fg "#FFFFFF"
-set notification-error-bg "#E06C75"
-set notification-error-fg "#FFFFFF"
-set notification-warning-bg "#D19A66"
-set notification-warning-fg "#1E2127"
-set highlight-color "#56B6C2"
-set highlight-active-color "#56B6C2"
-set index-bg "#1E2127"
-set index-fg "#ABB2BF"
-set index-active-bg "#5C6370"
-set index-active-fg "#ABB2BF"
-set recolor-darkcolor "#ABB2BF"
-set recolor-lightcolor "#1E2127"
-set render-loading-bg "#1E2127"
-set render-loading-fg "#ABB2BF"
+set default-bg "#282a36"
+set default-fg "#f8f8f2"
+set statusbar-bg "#282a36"
+set statusbar-fg "#f8f8f2"
+set inputbar-bg "#282a36"
+set inputbar-fg "#8BE9FD"
+set completion-bg "#282a36"
+set completion-fg "#f8f8f2"
+set completion-group-bg "#282a36"
+set completion-group-fg "#f8f8f2"
+set completion-highlight-bg "#4D4D4D"
+set completion-highlight-fg "#f8f8f2"
+set notification-bg "#4D4D4D"
+set notification-fg "#E6E6E6"
+set notification-error-bg "#FF6E67"
+set notification-error-fg "#E6E6E6"
+set notification-warning-bg "#F4F99D"
+set notification-warning-fg "#282a36"
+set highlight-color "#9AEDFE"
+set highlight-active-color "#8BE9FD"
+set index-bg "#282a36"
+set index-fg "#f8f8f2"
+set index-active-bg "#4D4D4D"
+set index-active-fg "#f8f8f2"
+set recolor-darkcolor "#f8f8f2"
+set recolor-lightcolor "#282a36"
+set render-loading-bg "#282a36"
+set render-loading-fg "#f8f8f2"
diff --git a/.local/bin/bg-gen b/.local/bin/bg-gen
@@ -11,7 +11,6 @@ if [ ! -f "$IMG" ]; then
RES="683x384"
#RES="1366x768"
#TAGS="xc: -attenuate 0.3 +noise Random"
- #TAGS="xc: -attenuate 0.3 +noise Random"
#TAGS="xc: -attenuate 0.3 +noise Random -paint 10"
TAGS="plasma:"
magick -size "$RES" $TAGS \
diff --git a/.local/bin/bg-set b/.local/bin/bg-set
@@ -41,13 +41,15 @@ image_preview() {
}
if [ "$SET_BG_SELECT" ]; then
- cd "$WLPS"
+ cd "$WLPS" || exit
if [ "$#" = 0 ]; then
trap stop_ueberzug EXIT QUIT INT TERM
start_ueberzug
- OUTPUT="$(find -type f -printf '%P\n' | sort | fzf -i -e \
- --layout=reverse --border=sharp --info=inline --preview "sh $0 {}" \
- --preview-window "right:50%:noborder:wrap" --bind "µ:toggle-preview+toggle-preview")"
+ OUTPUT=$(find . -type f -printf '%P\n' | sort \
+ | fzf -i -e --layout=reverse --border=sharp \
+ --info=inline --preview "sh $0 {}" \
+ --preview-window "right:50%:noborder:wrap" \
+ --bind "µ:toggle-preview+toggle-preview")
if [ "$OUTPUT" ]; then
stop_ueberzug
bg_set "$WLPS/$OUTPUT"
diff --git a/.local/bin/bright b/.local/bin/bright
@@ -1,36 +1,19 @@
#!/bin/sh
# Notes for linux users:
-# Add backlight rules to change your card's file permissions to the group `video`
+# Add backlight rule to change your card's file permissions
+# to your user, replace [USER] with your user & [CARD] with
+# your brightness card.
# /etc/udev/rules.d/backlight.rules:
# ----------------------------------
-# RUN+="/bin/chgrp video /sys/class/backlight/amdgpu_bl0/brightness"
+# RUN+="/bin/chown [USER] /sys/class/backlight/[CARD]/brightness"
BRIGHTNESS_ACT="get"
-BRIGHTNESS_STEPS="10"
+BRIGHTNESS_STEPS="5"
+BRIGHTNESS_NOTIF=0
-KERNEL=$(uname)
-
-case "$KERNEL" in
- Linux*)
- BRIGHTNESS_CARD=$(ls /sys/class/backlight | head -n 1)
- BRIGHTNESS_CARD=/sys/class/backlight/$BRIGHTNESS_CARD
- BRIGHTNESS_MAX=$(cat "${BRIGHTNESS_CARD}/max_brightness")
- BRIGHTNESS=$(cat "${BRIGHTNESS_CARD}/brightness")
- BRIGHTNESS=$((BRIGHTNESS*100/BRIGHTNESS_MAX))
- BRIGHTNESS=${BRIGHTNESS%.*}
- ;;
- FreeBSD*)
- BRIGHTNESS_MAX=100
- BRIGHTNESS=$(backlight | cut -d ' ' -f 2)
- ;;
- OpenBSD*)
- BRIGHTNESS_MAX=100
- BRIGHTNESS=$(apm -l)
- ;;
-esac
-
-while getopts ':gidos:c:' flag; do
+while getopts ':ngidos:c:' flag; do
case "${flag}" in
+ n) BRIGHTNESS_NOTIF=1 ;;
g) BRIGHTNESS_ACT="get" ;;
i) BRIGHTNESS_ACT="inc" ;;
d) BRIGHTNESS_ACT="dec" ;;
@@ -48,50 +31,78 @@ while getopts ':gidos:c:' flag; do
esac
done
-case "$BRIGHTNESS_ACT" in
- get)
- pkill -SIGUSR1 merbe
- merbe "$BRIGHTNESS_ICON $BRIGHTNESS" &
- exit
- ;;
- inc)
- BRIGHTNESS_NEW="$((BRIGHTNESS+BRIGHTNESS_STEPS))"
- ;;
- dec)
- BRIGHTNESS_NEW="$((BRIGHTNESS-BRIGHTNESS_STEPS))"
- ;;
- opt)
- TMPFILE=$(mktemp /tmp/backlight-optimal-XXXXXXX.jpg)
- ffmpeg -y -loglevel quiet -f v4l2 -i /dev/video0 -frames:v 1 -f image2 "$TMPFILE"
- AVG=$(convert "$TMPFILE" -format "%[mean]" info:)
- rm "$TMPFILE"
- BRIGHTNESS_NEW=$(printf '%s' "$AVG" | awk '{print int($1/65535*100+30)}')
- ;;
-esac
-
-BRIGHTNESS_NEW=$((BRIGHTNESS_NEW * BRIGHTNESS_MAX / 100))
-[ "$BRIGHTNESS_NEW" -gt "$BRIGHTNESS_MAX" ] && BRIGHTNESS_NEW=$BRIGHTNESS_MAX
-[ "$BRIGHTNESS_NEW" -lt "1" ] && BRIGHTNESS_NEW=1
+KERNEL=$(uname)
case "$KERNEL" in
Linux*)
- echo "$BRIGHTNESS_NEW" > "${BRIGHTNESS_CARD}/brightness"
+ BRIGHTNESS_CARD=$(find /sys/class/backlight -depth | head -n 1)
+ BRIGHTNESS_MAX=$(cat "${BRIGHTNESS_CARD}/max_brightness")
+ BRIGHTNESS=$(cat "${BRIGHTNESS_CARD}/brightness")
+ BRIGHTNESS=$((BRIGHTNESS*100/BRIGHTNESS_MAX))
+ BRIGHTNESS=${BRIGHTNESS%.*}
;;
FreeBSD*)
- backlight "$BRIGHTNESS_NEW"
+ BRIGHTNESS_MAX=100
+ BRIGHTNESS=$(backlight | cut -d ' ' -f 2)
;;
OpenBSD*)
- apm -s "$BRIGHTNESS_NEW"
+ BRIGHTNESS_MAX=100
+ BRIGHTNESS=$(apm -l)
;;
esac
-BRIGHTNESS="$((BRIGHTNESS_NEW*100/BRIGHTNESS_MAX))"
-if [ "$BRIGHTNESS" -le 25 ]; then
- BRIGHTNESS_ICON=""
-elif [ "$BRIGHTNESS" -le 60 ]; then
- BRIGHTNESS_ICON=""
-else
- BRIGHTNESS_ICON=""
-fi
-pkill -SIGUSR1 merbe
-merbe "$BRIGHTNESS_ICON $BRIGHTNESS" &
+change_bright() {
+ BRIGHTNESS_NEW=$1
+ BRIGHTNESS_NEW=$((BRIGHTNESS_NEW * BRIGHTNESS_MAX / 100))
+ [ "$BRIGHTNESS_NEW" -gt "$BRIGHTNESS_MAX" ] && BRIGHTNESS_NEW=$BRIGHTNESS_MAX
+ [ "$BRIGHTNESS_NEW" -lt "1" ] && BRIGHTNESS_NEW=1
+
+ case "$KERNEL" in
+ Linux*)
+ echo "$BRIGHTNESS_NEW" > "${BRIGHTNESS_CARD}/brightness"
+ ;;
+ FreeBSD*)
+ backlight "$BRIGHTNESS_NEW"
+ ;;
+ OpenBSD*)
+ apm -s "$BRIGHTNESS_NEW"
+ ;;
+ esac
+}
+
+main() {
+ case "$BRIGHTNESS_ACT" in
+ get)
+ echo "$BRIGHTNESS"
+ ;;
+ inc)
+ BRIGHTNESS_NEW=$((BRIGHTNESS+BRIGHTNESS_STEPS))
+ ;;
+ dec)
+ BRIGHTNESS_NEW=$((BRIGHTNESS-BRIGHTNESS_STEPS))
+ ;;
+ opt)
+ TMPFILE=$(mktemp /tmp/backlight-optimal-XXXXXXX.jpg)
+ ffmpeg -y -loglevel quiet -f v4l2 -i /dev/video0 -frames:v 1 -f image2 "$TMPFILE"
+ AVG=$(convert "$TMPFILE" -format "%[mean]" info:)
+ rm "$TMPFILE"
+ BRIGHTNESS_NEW=$(printf '%s' "$AVG" | awk '{print int($1/65535*100+30)}')
+ ;;
+ esac
+
+ [ "$BRIGHTNESS_ACT" = "get" ] || change_bright "$BRIGHTNESS_NEW"
+
+ if [ "$BRIGHTNESS_NOTIF" -eq 1 ]; then
+ BRIGHTNESS=$((BRIGHTNESS_NEW*100/BRIGHTNESS_MAX))
+ if [ "$BRIGHTNESS" -le 25 ]; then
+ BRIGHTNESS_ICON=""
+ elif [ "$BRIGHTNESS" -le 60 ]; then
+ BRIGHTNESS_ICON=""
+ else
+ BRIGHTNESS_ICON=""
+ fi
+ notify "$BRIGHTNESS_ICON $BRIGHTNESS"
+ fi
+}
+
+main
diff --git a/.local/bin/dmenu-archwiki b/.local/bin/dmenu-archwiki
@@ -2,9 +2,9 @@
# Install: arch-wiki-doc
wikipath="/usr/share/doc/arch-wiki/html/en"
wikimenu () {
- for file in $wikipath/*; do
- [ -f $file ] && printf '%s\n' "${file##*/}"
- done
+ for file in "$wikipath"/*; do
+ [ -f "$file" ] && printf '%s\n' "${file##*/}"
+ done
}
wikipage="$(wikimenu | dmenu -i -l 20 -p "Choose Wiki:")"
[ -z "$wikipage" ] || "${BROWSER:-xdg-open}" "$wikipath/$wikipage"
diff --git a/.local/bin/dmenu-emoji b/.local/bin/dmenu-emoji
@@ -1,17 +1,17 @@
#!/bin/sh
active_window="$(xdotool getactivewindow)"
-emoji=$(sed '0,/^__DATA__$/d' "$(which "$0")" | sed -e 's/\ufe0f//g' | dmenu -i -l 20 | sed 's/ .*//')
-xdotool windowactivate "$active_window"
+emoji=$(sed '/^__DATA__$/,$!d;/^__DATA__$/d;s/\ufe0f//g' "$(which "$0")" | dmenu -i -l 20 | sed 's/ .*//')
[ "$emoji" ] || exit
+xdotool windowactivate "$active_window"
case "$1" in
- [Cc]|[Cc][Ll][Ii][Pp][Bb][Oo][Aa][Rr][Dd])
- echo "$emoji" | xclip -selection clipboard
- merbe "Emoji" "Copied $emoji to clipboard!"
- ;;
- *)
- xdotool type -delay 100 "$emoji"
- ;;
+ [Cc]|[Cc][Ll][Ii][Pp][Bb][Oo][Aa][Rr][Dd])
+ echo "$emoji" | xclip -selection clipboard
+ notify "Emoji" "Copied $emoji to clipboard!"
+ ;;
+ *)
+ xdotool type -delay 100 "$emoji"
+ ;;
esac
exit $?
diff --git a/.local/bin/dmenu-fix-sheet b/.local/bin/dmenu-fix-sheet
@@ -1,21 +1,21 @@
#!/bin/sh
-# Some cheatsheet for some fast fixes wouldn't be bad.
-CHOICE="$(printf '%s\n' "background noise in pulse" \
- | dmenu -p "Get Help For Some Quick Fix:" -l 20)"
+# Some cheatsheet for some fast fixes wouldn't be bad.
+CHOICE="$(printf '%s\n' "background noise in pulse" \
+ | dmenu -p "Get Help For Some Quick Fix:" -l 20)"
case "$CHOICE" in
- "background noise in pulse")
- printf '# My fix for background noise in pulse.\n'
- printf '#\n'
- printf '# 1. Run privilaged:\n'
- printf '# doas ./fix.mic.sh\n'
- printf '# 2. Restart Audio Server:\n'
- printf '# pulseaudio -k\n'
- printf '#\n'
- printf 'doas cp /etc/pulse/default.pa /etc/pulse/default.pa.bak\n'
- printf 'doas cat << EOT >> /etc/pulse/default.pa\n'
- printf 'load-module module-echo-cancel source_name=noechosource sink_name=noechosink\n'
- printf 'set-default-source noechosource\n'
- printf 'set-default-sink noechosink\n'
- printf 'EOT\n'
- ;;
+ "background noise in pulse")
+ printf '# My fix for background noise in pulse.\n'
+ printf '#\n'
+ printf '# 1. Run privilaged:\n'
+ printf '# doas ./fix.mic.sh\n'
+ printf '# 2. Restart Audio Server:\n'
+ printf '# pulseaudio -k\n'
+ printf '#\n'
+ printf 'doas cp /etc/pulse/default.pa /etc/pulse/default.pa.bak\n'
+ printf 'doas cat << EOT >> /etc/pulse/default.pa\n'
+ printf 'load-module module-echo-cancel source_name=noechosource sink_name=noechosink\n'
+ printf 'set-default-source noechosource\n'
+ printf 'set-default-sink noechosink\n'
+ printf 'EOT\n'
+ ;;
esac
diff --git a/.local/bin/dmenu-man b/.local/bin/dmenu-man
@@ -1,3 +1,3 @@
#!/bin/sh
-CHOICE="$(man -k . | dmenu -p 'Choose Manual:' -l 20 | awk '{print $1"."$2}' | sed 's/(//;s/)//')"
-[ "$CHOICE" ] && man -Tpdf "$CHOICE" | zathura -
+CHOICE=${1:-$(man -k . | dmenu -p 'Choose Manual:' -l 20 | awk '{print $1"."$2}' | sed 's/(//;s/)//')}
+[ "$CHOICE" ] && "$TERMINAL" -e man "$CHOICE"
diff --git a/.local/bin/dmenu-power b/.local/bin/dmenu-power
@@ -1,8 +1,9 @@
#!/bin/sh
ask() {
- prompt="Do you really want to $1?"
- answer="$(printf 'Yes\nNo' | dmenu -i -p "$prompt")"
- [ "$answer" = "Yes" ] && doas-askpass "$2"
+ doas-askpass "$2"
+ #prompt="Do you really want to $1?"
+ #answer="$(printf 'Yes\nNo' | dmenu -i -p "$prompt")"
+ #[ "$answer" = "Yes" ] && doas-askpass "$2"
}
btn_power="📴 Poweroff"
@@ -16,5 +17,5 @@ case "$CHOICE" in
#"$btn_logout") ask "logout from \"$(logname)\"" "pkill -KILL -u \"$(logname)\"" ;;
"$btn_logout") ask "logout from \"$(logname)\"" "kill -9 -1" ;;
"$btn_reboot") ask "reboot this machine" "reboot" ;;
- "$btn_power") ask "this computer to shutdown" "shutdown now";;
+ "$btn_power") ask "this computer to shutdown" "poweroff";;
esac
diff --git a/.local/bin/doas-askpass b/.local/bin/doas-askpass
@@ -1,4 +1,4 @@
-#!/usr/local/bin/expect --
+#!/usr/bin/expect --
# askpass implementation for doas
# /home/mahdi/.local/bin/doas-askpass
diff --git a/.local/bin/dwm-bar b/.local/bin/dwm-bar
@@ -4,48 +4,129 @@
# ------------------ #
# ----- Config ----- #
# ------------------ #
-
-# Colorful status: change to 1 if you want your modules colored. (Xresources)
-COLORFUL=0
-
-# Colorful background: Change to 1 if you want your modules'
-# backgrounds to be set to your Xresources background colors,
-# But darkened for each module to a certain number from left to right.
-# Note: *REQUIRES COLORFUL=1*
-COLORFUL_BACKGROUND=0
+# Cache directory
+CACHE_DIR=${XDG_CACHE_HOME:-$HOME/.cache}/dwm-bar
+[ -d "$CACHE_DIR" ] || mkdir -p "$CACHE_DIR"
# The location for weather module, the necessary information is parsed from:
# v2d.wttr.in/${WEATHER_LOC}
WEATHER_LOC="Babol"
-# The keyboard layouts you want to use in "Keyboard" module.
-# You can modify your own layouts,
-# *:%;
-# Where:
-# * -> The order of the layout you've set from setxkbmap (starting from 0)
-# % -> The name you want the module to return for the layout.
-KBD_LAYOUTS="0:English;1:Persian;"
+# List of modules
+full_mods="Weather PublicIP PrivateIP Keyboard Battery Brightness Volume CPUtemp Memory Uptime DTime"
+opts_mods="
+Volume Memory DTime
+Volume CPUtemp Uptime DTime
+Keyboard Battery Brightness DTime
+Weather Battery Brightness DTime
+Weather Keyboard Battery Brightness DTime
+Weather PublicIP PrivateIP Uptime DTime
+"
+
+# Store Kernel's Name (Linux/FreeBSD/OpenBSD)
+KERNEL=$(uname -s)
+
+case "$KERNEL" in
+ Linux*)
+ TEMPERATURE_FILES="
+ /sys/class/thermal/thermal_zone0/temp
+ /sys/class/thermal/thermal_zone1/temp
+ /sys/class/thermal/thermal_zone2/temp
+ /sys/class/hwmon/hwmon0/temp1_input
+ /sys/class/hwmon/hwmon1/temp1_input
+ /sys/class/hwmon/hwmon2/temp1_input
+ /sys/class/hwmon/hwmon0/device/temp1_input
+ /sys/class/hwmon/hwmon1/device/temp1_input
+ /sys/class/hwmon/hwmon2/device/temp1_input
+ null
+ "
+
+ for file in $TEMPERATURE_FILES; do
+ TEMP_FILE=$file
+ [ -f "$TEMP_FILE" ] && break
+ done
+
+ [ "$TEMP_FILE" = "null" ] && unset TEMP_FILE
+ ;;
+esac
-KERNEL=$(uname)
# ------------------ #
# ---- Modules ----- #
# ------------------ #
Weather(){
- find "$HOME/.cache/weather" -mmin +59 -delete
- if [ ! -f "$HOME/.cache/weather" ] || [ -z "$(cat "$HOME/.cache/weather" >/dev/null 2>&1)" ] ; then
- weather=$(curl -s "v2d.wttr.in/${WEATHER_LOC}" \
- | sed "/Weather:/!d;s/Weather://;s/,//g;s/+//g;s/°C.*//;s/.*m//;s/ //;s/ //;s/ //")
- [ "$weather" ] && echo "${weather}°C" > "$HOME/.cache/weather"
+ weather_file="$CACHE_DIR/.weather"
+ weather_file_last=$(stat -c%Y "$weather_file")
+ if [ "$(date +%s)" -ge $((weather_file_last+3600)) ]; then
+ for interface in $(find /sys/class/net -depth | \
+ sed '/\/lo$/d;/\/net$/d'); do
+ if [ "$(cat "$interface" 2>/dev/null)" -eq 1 ]; then
+ rm "$weather_file"
+ break
+ fi
+ done
fi
- weather=$(cat "$HOME/.cache/weather")
- printf "%s" "$weather"
+ weather=$(cat "$weather_file" 2>/dev/null)
+
+ if [ ! "$weather" ]; then
+ weather=$(curl -s "v2d.wttr.in/${WEATHER_LOC}" | \
+ sed "/Weather:/!d;s/Weather://;s/,//g;
+ s/+//g;s/°C.*//;s/.*m//;s/ //;s/ //;s/ //")
+ weather="${weather}°C"
+ echo "$weather" > "$weather_file"
+ fi
+
+ [ "$weather" ] && printf "%s" "${weather}"
+}
+
+PublicIP(){
+ publicip_file="$CACHE_DIR/.publicip"
+ publicip_last=$(stat -c%Y "$publicip_file")
+ if [ "$(date +%s)" -ge $((publicip_last+300)) ]; then
+ for interface in $(find /sys/class/net -depth | \
+ sed '/\/lo$/d;/\/net$/d'); do
+ if [ "$(cat "$interface" 2>/dev/null)" -eq 1 ]; then
+ rm "$publicip_file"
+ break
+ fi
+ done
+ fi
+ PUBLIC_IP=$(cat "$publicip_file" 2>/dev/null)
+
+ if [ ! "$PUBLIC_IP" ]; then
+ RESOLVERS='resolver1.opendns.com resolver2.opendns.com resolver3.opendns.com resolver4.opendns.com'
+ for resolver in $RESOLVERS ; do
+ PUBLIC_IP=$(host myip.opendns.com "$resolver" | \
+ grep "myip.opendns.com has" | awk '{print $4}')
+ [ -n "$PUBLIC_IP" ] && break
+ done
+ echo "$PUBLIC_IP" > "$publicip_file"
+ fi
+
+ [ "$PUBLIC_IP" ] && printf " %s" "$PUBLIC_IP"
+}
+
+PrivateIP(){
+ case "$KERNEL" in
+ Darwin*|FreeBSD*|OpenBSD*)
+ PRIVATE_IP=$(ifconfig | grep "inet " | \
+ grep -Fv 127.0.0.1 | awk '{print $2}')
+ ;;
+ Linux*)
+ PRIVATE_IP=$(ip a | sed '/inet.*scope global/!d' | \
+ grep -o '[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*' | sed -n '1p')
+ ;;
+ esac
+
+ [ "$PRIVATE_IP" ] && printf " %s" "$PRIVATE_IP"
}
Keyboard(){
+ KBD_LAYOUTS=$(setxkbmap -query | awk '/layout/{print $2}' | \
+ tr ',' '\n' | awk '{print NR-1":"$1}')
KBD=$(xset -q | grep LED | awk '{ print substr($10,5,1) }')
- KBD=$(echo "$KBD_LAYOUTS" | sed "s/;/\n/g" | sed "/$KBD:/!d;s/.*://")
- printf " %s" "${KBD}"
+ KBD=$(echo "$KBD_LAYOUTS" | sed "/^$KBD:/!d;s/.*://")
+ [ "$KBD" ] && printf " %s" "$KBD"
}
Battery() {
@@ -57,6 +138,7 @@ Battery() {
BATTERY_4_ICON=''
FULL_AT=98
+ WARNING_AT=15
BAT_ICON=""
ICON=""
@@ -68,16 +150,16 @@ Battery() {
CAPACITY=$(cat "${BAT}/capacity")
CHARGING=$(cat "${BAT}/status")
fi
- [ "$CHARGING" = "Charging" ] && ICON=$CHARGING_ICON
+ [ "$CHARGING" = "Charging" ] && ICON=$CHARGING_ICON
;;
FreeBSD*)
CAPACITY=$(sysctl -n hw.acpi.battery.life)
CHARGING=$(sysctl -n hw.acpi.battery.state)
- [ $CHARGING -eq 2 ] && ICON=$CHARGING_ICON
+ [ "$CHARGING" -eq 2 ] && ICON=$CHARGING_ICON
;;
esac
- [ -z "$ICON" ] && [ $CAPACITY -le 25 ] && ICON=$WARNING_ICON
+ [ -z "$ICON" ] && [ "$CAPACITY" -le "$WARNING_AT" ] && ICON=$WARNING_ICON
if [ "$CAPACITY" -ge "$FULL_AT" ]; then
BAT_ICON=$BATTERY_FULL_ICON
@@ -93,13 +175,32 @@ Battery() {
[ "$ICON" ] && printf "%s " "$ICON"
[ "$BAT_ICON" ] && printf "%s " "$BAT_ICON"
[ "$CAPACITY" ] && printf "%s%%" "$CAPACITY"
+
+ CHARG_BAT="$CACHE_DIR/.battery-charge"
+ if [ "$CHARGING" = "Charging" ] || [ "$CHARGING" -eq 2 ]; then
+ [ -e "$CHARG_BAT" ] && return;
+ touch "$CHARG_BAT"
+ notify "Charging - ${ICON} ${BAT_ICON} ${CAPACITY}%"
+ rm "$LOW_BAT"
+ else
+ [ -e "$CHARG_BAT" ] || return;
+ notify "Discharging - ${BAT_ICON} ${CAPACITY}%"
+ rm "$CHARG_BAT"
+ fi
+
+ LOW_BAT="$CACHE_DIR/.battery-low"
+ if [ "$CAPACITY" -le "$WARNING_AT" ] && \
+ [ ! -e "$LOW_BAT" ] && [ ! -e "$CHARG_BAT" ]; then
+ touch "$LOW_BAT"
+ notify "${WARNING_ICON} Low Battery
+${BAT_ICON} ${CAPACITY}% Remains"
+ fi
}
Brightness() {
case "$KERNEL" in
- Linux*)
- BRIGHTNESS_CARD=$(ls /sys/class/backlight | head -n 1)
- BRIGHTNESS_CARD=/sys/class/backlight/$BRIGHTNESS_CARD
+ *Linux*)
+ BRIGHTNESS_CARD=$(find /sys/class/backlight -depth | head -n 1)
BRIGHTNESS_MAX=$(cat "${BRIGHTNESS_CARD}/max_brightness")
BRIGHTNESS=$(cat "${BRIGHTNESS_CARD}/brightness")
BRIGHTNESS=$((BRIGHTNESS*100/BRIGHTNESS_MAX))
@@ -112,21 +213,20 @@ Brightness() {
BRIGHTNESS=$(apm -l)
;;
esac
- if [ "$BRIGHTNESS" -le 25 ]; then
- ICON=""
- elif [ "$BRIGHTNESS" -le 60 ]; then
- ICON=""
- else
- ICON=""
- fi
- [ "$BRIGHTNESS" ] && printf "%s %s%%" "$ICON" "$BRIGHTNESS"
+ if [ "$BRIGHTNESS" -le 25 ]; then
+ ICON=""
+ elif [ "$BRIGHTNESS" -le 60 ]; then
+ ICON=""
+ else
+ ICON=""
+ fi
+ [ "$BRIGHTNESS" ] && printf "%s %s%%" "$ICON" "$BRIGHTNESS"
}
Volume() {
- VOLUME=$(mixer vol | cut -d':' -f2)
case "$KERNEL" in
Linux*)
- if pactl stat >/dev/null 2>&1; then
+ if pactl stat 2>/dev/null; then
VOLUME=$(pactl get-sink-volume @DEFAULT_SOURCE@ | \
awk '/%/{sub(/%/, "", $5);print $5}')
else
@@ -138,30 +238,21 @@ Volume() {
VOLUME=$(mixer -s vol | cut -d ':' -f 2)
;;
esac
- if [ "$VOLUME" -le 25 ]; then
- ICON=""
- elif [ "$VOLUME" -le 60 ]; then
- ICON=""
- else
- ICON=""
+ if [ "$VOLUME" -le 25 ]; then
+ ICON=""
+ elif [ "$VOLUME" -le 60 ]; then
+ ICON=""
+ else
+ ICON=""
fi
- [ "$VOLUME" ] && printf "%s %s%%" "$ICON" "$VOLUME"
-}
-
-CPU() {
- USAGE=$(ps aux | awk 'BEGIN {sum=0} {sum+=$3}; END {print sum}' | sed 's/\..*//')
- case "$KERNEL" in
- Linux)
- USAGE=$((USAGE/$(grep -c "^processor" /proc/cpuinfo)))
- ;;
- esac
- printf " %s%%" "$USAGE"
+ [ "$VOLUME" ] && printf "%s %s%%" "$ICON" "$VOLUME"
}
CPUtemp() {
case "$KERNEL" in
Linux*)
- TEMP=$(sensors | awk '/temp1/ {sub(/^\+/, "", $2);print $2}' | sed 's/\..*//')
+ [ -z "$TEMP_FILE" ] || \
+ TEMP=$(sed 's/...$//' "$TEMP_FILE" 2>/dev/null)
;;
FreeBSD*)
TEMP=$(sysctl -n dev.cpu.0.temperature | sed 's/\..*//')
@@ -172,38 +263,12 @@ CPUtemp() {
sed 's/00/0/')
;;
esac
- printf " %s°C" "$TEMP"
-}
-
-Uptime() {
- case "$KERNEL" in
- Linux)
- SECS=$(cat /proc/uptime | sed 's/\..*//g')
- ;;
- *BSD*)
- SECS=$(($(date +%s)-$(sysctl -n kern.boottime | \
- cut -d ',' -f 1 | cut -d '=' -f 2)))
- ;;
- esac
- D=$((SECS / 60 / 60 / 24))
- H=$((SECS / 60/ 60 % 24))
- M=$((SECS / 60 % 60))
- S=$((SECS % 60))
- if [ "$D" != 0 ]; then
- UPTIME="${D}d ${H:-0}h ${M:-0}m"
- elif [ "$H" != 0 ]; then
- UPTIME="${H}h ${M:-0}m"
- elif [ "$M" != 0 ]; then
- UPTIME="${M}m"
- else
- UPTIME="${S}s"
- fi
- printf " %s" "$UPTIME"
+ [ "$TEMP" ] && printf " %s°C" "$TEMP"
}
Memory() {
case "$KERNEL" in
- Linux)
+ Linux*)
free=$(awk '/^MemFree/{free=$2}
/^Buffers/{buff=$2}
/^Cached/{cached=$2}
@@ -226,7 +291,35 @@ Memory() {
;;
esac
USAGE=$(((total-free)*100/total))
- printf " %s%%" "${USAGE%.*}"
+ [ "$USAGE" ] && printf " %s%%" "${USAGE%.*}"
+}
+
+Uptime() {
+ case "$KERNEL" in
+ Linux*)
+ SECS=$(sed 's/\..*//g' /proc/uptime)
+ ;;
+ *BSD*)
+ SECS=$(($(date +%s)-$(sysctl -n kern.boottime | \
+ cut -d ',' -f 1 | cut -d '=' -f 2)))
+ ;;
+ esac
+ if [ "$SECS" -ge 86400 ]; then
+ D=$((SECS / 60 / 60 / 24))
+ H=$((SECS / 60/ 60 % 24))
+ M=$((SECS / 60 % 60))
+ UPTIME="${D}d ${H:-0}h ${M:-0}m"
+ elif [ "$SECS" -ge 3600 ]; then
+ H=$((SECS / 60/ 60 % 24))
+ M=$((SECS / 60 % 60))
+ UPTIME="${H}h ${M:-0}m"
+ elif [ "$SECS" -ge 60 ]; then
+ M=$((SECS / 60 % 60))
+ UPTIME="${M}m"
+ else
+ UPTIME="${SECS}s"
+ fi
+ [ "$UPTIME" ] && printf " %s" "$UPTIME"
}
DTime() {
@@ -239,95 +332,42 @@ DTime() {
*) echo "th";;
esac
}
- printf " %s" "$(date "+$DAY$(day_suffix) %b %I:%M %p")"
+ DATE=$(date "+$DAY$(day_suffix) %b %I:%M %p")
+ [ "$DATE" ] && printf " %s" "$DATE"
}
# ------------------ #
# --- Functions ---- #
# ------------------ #
-darken_hex(){
- C=${1:-FFFFFF}
- V=${2:-10}
- if [ "$(printf '%s' "$C" | cut -c1-1)" = "#" ]; then
- C=$(printf '%s' "$C" | cut -c2-8)
- else
- C=$1
- fi
- R=$(printf '%s' "$C" | awk '{print substr($0, 0, 2)}')
- G=$(printf '%s' "$C" | awk '{print substr($0, 3, 2)}')
- B=$(printf '%s' "$C" | awk '{print substr($0, 5, 2)}')
- R=$(printf '%d' 0x"$R")
- G=$(printf '%d' 0x"$G")
- B=$(printf '%d' 0x"$B")
- R=$((R+V))
- G=$((G+V))
- B=$((B+V))
- if [ "$R" -lt 0 ]; then
- R=0
- elif [ "$R" -gt 255 ]; then
- R=255
- fi
- if [ "$G" -lt 0 ]; then
- G=0
- elif [ "$G" -gt 255 ]; then
- G=255
- fi
- if [ "$B" -lt 0 ]; then
- B=0
- elif [ "$B" -gt 255 ]; then
- B=255
- fi
- printf "#%02X%02X%02X\n" "$R" "$G" "$B"
-}
usage() {
- printf "$0 [-m modules] [-M] [-h]\n"
+ printf "%s [-m modules] [-M] [-h]\n" "$0"
exit 2
}
stopbar() {
for pid in $(ps ax | grep "/bin/sh.*dwm-bar" | awk '{print $1}'); do
[ "$pid" = "$$" ] && continue
- kill -9 "$pid" > /dev/null 2>&1
+ kill -9 "$pid" 2>/dev/null
wait
done
}
startbar() {
c=1
- while ! pgrep -x dwm >/dev/null; do
+ while ! pgrep -x dwm 2>/dev/null; do
sleep 1;
c=$((c+1))
[ "$c" = 10 ] && exit 2
done
- [ -r "$HOME/.cache/bar_modules" ] && mods_list=$(cat "$HOME/.cache/bar_modules")
- mods_list=${mods_list:-Weather Keyboard Battery Brightness Volume CPU CPUtemp Uptime Memory DTime}
- mods=${1:-$mods_list}
- mods_count=$(echo "$mods" | wc -w)
+ mods_list=$(cat "$CACHE_DIR/Modules" 2>/dev/null)
+ mods_list=${mods_list:-$full_mods}
+ mods=${mods:-$mods_list}
c=1
for mod in $mods; do
- if [ "$COLORFUL" -eq 1 ]; then
- XRDB=$(xrdb -query)
- fgColor=$(printf "$XRDB" | awk "/color$c/ {print \$2;exit}")
- bgcolor=$(printf "$XRDB" | awk "/background/ {print \$2;exit}")
- bgcolor_off=$(((c-1)*$((40/$mods_count))))
- bgColor=$(darken_hex "$bgcolor" "-$bgcolor_off")
- [ "$c" -eq 1 ] && bgColor=$bgcolor
- [ "$c" -ge 8 ] && fgColor=$(echo "$XRDB" | awk "/color$((c+1))/ {print \$2;exit}")
- if [ "$COLORFUL_BACKGROUND" -eq 1 ]; then
- mod_prefix="^c$fgColor^^b$bgColor^ "
- mod_suffix=""
- mod_sep=" "
- else
- mod_prefix="^c$fgColor^ "
- mod_suffix=""
- mod_sep=" "
- fi
- else
- mod_prefix=" "
- mod_suffix=""
- mod_sep=" |"
- #mod_prefix=" [ "
- #mod_suffix=" ]"
- #mod_sep=""
- fi
+ mod_prefix=""
+ mod_suffix=""
+ mod_sep=" | "
+ #mod_prefix=" [ "
+ #mod_suffix=" ] "
+ #mod_sep=""
if [ "$c" = 1 ]; then
output="$mod_prefix%$mod%$mod_suffix"
else
@@ -335,14 +375,19 @@ startbar() {
fi
c=$((c+1))
done
- output="$output "
+ # Add padding
+ output=" $output "
while true; do
- unset out
out=$output
for mod in $mods; do
unset mod_output
- mod_output=$($mod)
- [ -z "$mod_output" ] && continue
+ #mod_output=$($mod)
+ mod_output=$(cat "$CACHE_DIR/mod-$mod")
+ if [ -z "$mod_output" ]; then
+ out=$(printf "%s" "${out}" | \
+ sed "s/$mod_sep$mod_prefix%$mod%$mod_suffix//")
+ continue
+ fi
out=$(printf "%s" "${out}" | sed "s/%$mod%/$mod_output/g")
done
dwm -s "$out"
@@ -350,56 +395,63 @@ startbar() {
done
}
+updatebar() {
+ mods_list=$(cat "$CACHE_DIR/Modules")
+ mods_list=${mods_list:-$full_mods}
+ while true; do
+ for mod in ${mods:-$mods_list}; do
+ printf '%s' "$($mod)" > "$CACHE_DIR/mod-$mod"
+ done
+ done
+}
+
main() {
while getopts "m:M" flag; do
case "${flag}" in
M)
full_text="[All Modules]"
- full="Weather Keyboard Battery Brightness Volume CPU CPUtemp Uptime Memory DTime"
rest="[Restart Modules]"
cust="[Custom Modules]"
- opts="
- Volume CPU Memory DTime
- Volume CPU CPUtemp Uptime DTime
- Keyboard Battery Brightness DTime
- Weather Battery Brightness DTime
- Weather Keyboard Battery Brightness DTime
- "
- opts=$(printf "%s" "${opts}" | sed 's/^[ \t]*//g;/^ *$/d')
- choice=$(printf "%s\n" "${full_text}" "${rest}" "${cust}" "${opts}" | dmenu -i -l 20)
- [ -z "$choice" ] && choice=$(cat $HOME/.cache/bar_modules)
+ opts=$(printf "%s" "${opts_mods}" | sed 's/^[ \t]*//g;/^ *$/d')
+ choice=$(printf "%s\n" \
+ "${full_text}" "${rest}" "${cust}" "${opts}" | dmenu -i -l 20)
+ [ -z "$choice" ] && choice=$(cat "$CACHE_DIR/Modules")
case "$choice" in
"$cust")
- HEIGHT=$(($(echo "$full" | wc -w)+2))
- WIDTH=$(($(echo "$full" | tr ' ' '\n' | wc -L)*2))
+ HEIGHT=$(($(echo "$full_mods" | wc -w)+2))
+ WIDTH=$(($(echo "$full_mods" | tr ' ' '\n' | wc -L)*2))
[ "$WIDTH" -lt 30 ] && WIDTH="30"
"$TERMINAL" -c "st-float" -g "${WIDTH}x${HEIGHT}+400+150" \
- -e sh -c "echo \"$full\" | tr ' ' '\n' | smenu -m \"Select Modules:\" -l -P -n 100 -q | tr '\n' ' ' > $HOME/.cache/bar_modules.tmp"
- mods=$(cat "$HOME/.cache/bar_modules.tmp")
- [ -z "$mods" ] && mods=$(cat "$HOME/.cache/bar_modules")
- rm "$HOME/.cache/bar_modules.tmp"
+ -e sh -c "echo \"$full_mods\" | tr ' ' '\n' | \
+ smenu -m \"Select Modules:\" -l -P -n 100 -q | \
+ tr '\n' ' ' > \"$CACHE_DIR/Modules.tmp\""
+ mods=$(cat "$CACHE_DIR/Modules.tmp")
+ [ -z "$mods" ] && mods=$(cat "$CACHE_DIR/Modules")
+ rm "$CACHE_DIR/Modules.tmp"
;;
"$rest")
- mods=$(cat $HOME/.cache/bar_modules)
+ mods=$(cat "$CACHE_DIR/Modules")
;;
"$full_text")
- mods=$full
+ mods=$full_mods
;;
*)
mods=$choice
;;
esac
- echo "$mods" > "$HOME/.cache/bar_modules"
+ echo "$mods" > "$CACHE_DIR/Modules"
;;
m)
mods=${OPTARG}
- echo "$mods" > "$HOME/.cache/bar_modules"
+ echo "$mods" > "$CACHE_DIR/Modules"
;;
*) usage ;;
esac
done
+
stopbar
- startbar "$mods" &
+ updatebar &
+ startbar &
}
main "$@"
diff --git a/.local/bin/email b/.local/bin/email
@@ -1,38 +1,60 @@
#!/bin/sh
-# Easy Mail
+NO_CLIENT=0
+SYNC_MAIL=0
+SYNC_MAIL_FREQ=0
+SYNC_MAIL_FREQ_SECS=1800
+
MBSYNCRC="${MBSYNCRC:-${XDG_CONFIG_HOME:-$HOME/.config}/mbsync/mbsyncrc}"
MBSYNC_ACCS="${XDG_DATA_HOME:-$HOME/.local/share}/mail"
sync_mail() {
- mbsync -c "$MBSYNCRC" -a
- for ACC in $MBSYNC_ACCS/*; do
- LAST_RUN="$ACC/.sync_mail.lastrun"
- NEW_MAILS="$(find \
- "$ACC/INBOX/new" \
- "$ACC/Inbox/new" \
- "$ACC/inbox/new" \
- -type f -newer "$LAST_RUN" 2>/dev/null | wc -l | sed 's/ //g')"
- if [ "$NEW_MAILS" -ge 1 ]; then
- [ "$NEW_MAILS" -gt 1 ] && SUF="s" || SUF=""
- ACC_SHOW="${ACC##*/}"
- merbe " New Mail" "You have ${NEW_MAILS} new mail${SUF} in '${ACC_SHOW}'." &
- fi
- touch "$LAST_RUN"
- done
+ mbsync -c "$MBSYNCRC" -a
+ for ACC in "$MBSYNC_ACCS"/*; do
+ LAST_RUN="$ACC/.sync_mail.lastrun"
+ NEW_MAILS=$(find \
+ "$ACC/INBOX/new" \
+ "$ACC/Inbox/new" \
+ "$ACC/inbox/new" \
+ -type f -newer "$LAST_RUN" 2>/dev/null | wc -l | sed 's/ //g')
+ if [ "$NEW_MAILS" -ge 1 ]; then
+ [ "$NEW_MAILS" -gt 1 ] && SUF="s" || SUF=""
+ ACC_SHOW="${ACC##*/}"
+ notify " New Mail
+You have ${NEW_MAILS} new mail${SUF} in '${ACC_SHOW}'."
+ fi
+ touch "$LAST_RUN"
+ done
}
-case "$1" in
- -n)
- sync_mail
- ;;
- -s)
- while :; do
- sync_mail
- sleep 3600
- done
- ;;
- *)
- sync_mail
- mutt
- sync_mail
- ;;
-esac
+while getopts ':nosS:' flag; do
+ case "$flag" in
+ n) NO_CLIENT=1 ;;
+ o) SYNC_MAIL=1 ;;
+ s) SYNC_MAIL_FREQ=1 ;;
+ S)
+ echo "${OPTARG}" | grep "^-\?[0-9]+$" && \
+ SYNC_MAIL_FREQ_SECS=${OPTARG}
+ ;;
+ *)
+ printf 'Usage: %s [-n] [-s]\n\n' "$0"
+ printf ' -n: Do not open client\n'
+ printf ' -o: Sync email before opening client\n'
+ printf ' -s: Sync email every X seconds (default: %s)\n' \
+ "$SYNC_MAIL_FREQ_SECS"
+ printf ' -S: Frequency of syncing emails (-s option)\n'
+ exit 2
+ ;;
+ esac
+done
+
+if [ $SYNC_MAIL_FREQ -eq 1 ]; then
+ while true; do
+ sync_mail
+ sleep "$SYNC_MAIL_FREQ_SECS"
+ done &
+elif [ $SYNC_MAIL -eq 1 ]; then
+ sync_mail
+fi
+
+[ $NO_CLIENT -eq 1 ] || mutt
+
+exit
diff --git a/.local/bin/pacman-up b/.local/bin/pacman-up
@@ -1,6 +1,6 @@
#!/bin/sh
notif() {
- merbe " Updater" "$1" &
+ notify " Updater" "$1"
}
notifnq() {
TEXT="${1}"
@@ -19,12 +19,12 @@ PKG_COUNT="$(printf '%s\n' "$PKG_LIST" | wc -l)"
PKG_SIZE="$(printf '%s\n' "$PKG_LIST" | awk '{SUM+=$2} END {printf("%.1fMiB",SUM/1024/1024)}')"
[ "$PKG_COUNT" -gt 1 ] && SUFFIX="s"
-merbe "$(printf "Packages:\n$PKG_LIST_H" | head)" &
+notify "$(printf "Packages:\n$PKG_LIST_H" | head)"
CHOICE="$(printf '%s\n' "Yes" "No" | dmenu -p "Update $PKG_COUNT Package$SUFFIX ($PKG_SIZE)?")"
case "$CHOICE" in
[Yy][Ee][Ss]|[Yy])
notif "Updating $PKG_COUNT Package$SUFFIX..."
- "$TERMINAL" -c "st-float" -g "120x26" -e sh -c "doas pacman -Syu --noconfirm || (merbe \" Updater\" \"Didn't update anything.\" && exit 2)"
+ "$TERMINAL" -c "st-float" -g "120x26" -e sh -c "doas pacman -Syu --noconfirm || (notify \" Updater\" \"Didn't update anything.\" && exit 2)"
rm ~/.cache/pkg_updates
notifnq "Updated $PKG_COUNT Package$SUFFIX."
;;
diff --git a/.local/bin/screenshot b/.local/bin/screenshot
@@ -9,17 +9,17 @@ NAME_SS="$(date '+%Y%m%d-%H%M%S').png"
SAVE_SS_DIR="$HOME/pics"
while getopts :wscxt:q:n:p: flag; do
- case "${flag}" in
- w) ACTIVE=1;;
- s) SELECT=1;;
- c) COPY_SS=1;;
- x) SAVE_SS=1;;
- t) TIMER=${OPTARG};;
- q) QUALITY=${OPTARG};;
- n) NAME_SS=${OPTARG};;
- p) SAVE_SS_DIR=${OPTARG};;
- *) echo "usage: $0 [-wxsc] [-t time(s)] [-q quality(1-10)] [-n name.png] [-p path/to/picture]"; exit 2 ;;
- esac
+ case "${flag}" in
+ w) ACTIVE=1;;
+ s) SELECT=1;;
+ c) COPY_SS=1;;
+ x) SAVE_SS=1;;
+ t) TIMER=${OPTARG};;
+ q) QUALITY=${OPTARG};;
+ n) NAME_SS=${OPTARG};;
+ p) SAVE_SS_DIR=${OPTARG};;
+ *) echo "usage: $0 [-wxsc] [-t time(s)] [-q quality(1-10)] [-n name.png] [-p path/to/picture]"; exit 2 ;;
+ esac
done
[ $SAVE_SS -eq 0 ] && [ $COPY_SS -eq 0 ] && COPY_SS=1
@@ -35,13 +35,13 @@ sleep "$TIMER"
maim $TAGS -m "$QUALITY" "${SAVE_SS_DIR}/${NAME_SS}" || exit 2
if [ $SAVE_SS -eq 1 ] && [ $COPY_SS -eq 1 ]; then
- xclip -selection clipboard -target image/png -i "${SAVE_SS_DIR}/${NAME_SS}"
- SHOW="$(echo "${SAVE_SS_DIR}" | sed -e "s|${HOME}|~|g")/${NAME_SS} (+CLIPBOARD)"
+ xclip -selection clipboard -target image/png -i "${SAVE_SS_DIR}/${NAME_SS}"
+ SHOW="$(echo "${SAVE_SS_DIR}" | sed -e "s|${HOME}|~|g")/${NAME_SS} (+CLIPBOARD)"
elif [ $SAVE_SS -eq 0 ] && [ $COPY_SS -eq 1 ]; then
- rm "${SAVE_SS_DIR}/${NAME_SS}"
- SHOW="CLIPBOARD"
+ rm "${SAVE_SS_DIR}/${NAME_SS}"
+ SHOW="CLIPBOARD"
elif [ $SAVE_SS -eq 1 ] && [ $COPY_SS -eq 0 ]; then
- SHOW="$(echo "${SAVE_SS_DIR}" | sed -e "s|${HOME}|~|g")/${NAME_SS}"
+ SHOW="$(echo "${SAVE_SS_DIR}" | sed -e "s|${HOME}|~|g")/${NAME_SS}"
fi
-merbe " Picture acquired!" "${SHOW}"
+notify " Picture acquired!" "${SHOW}"
diff --git a/.local/bin/theme-sel b/.local/bin/theme-sel
@@ -6,88 +6,92 @@ XRES_COLORS_DST="${XRES}/colors"
XRES_COLORS_SRC="${XRES}/themes"
find_themes() {
- find "${XRES_COLORS_SRC}" -type f -exec basename {} \; | sort
+ find "${XRES_COLORS_SRC}" -type f -exec basename {} \; | sort
}
generate_theme() {
- SRC="$1"
- DST="$2"
- [ -f "${DST}.tmp" ] && rm "${DST}.tmp"
- cp "${SRC}" "${DST}.tmp"
-
- XRDB="$(xrdb -query)"
- background="$(printf '%s\n' "$XRDB" | awk '/background/ {print $2;exit}')"
- foreground="$(printf '%s\n' "$XRDB" | awk '/foreground/ {print $2;exit}')"
- cursorColor="$(printf '%s\n' "$XRDB" | awk '/cursorColor/ {print $2;exit}')"
-
- sed -i "s|%clfg%|$foreground|g" "${DST}.tmp"
- sed -i "s|%clbg%|$background|g" "${DST}.tmp"
- sed -i "s|%clcr%|$cursorcolor|g" "${DST}.tmp"
- sed -i "s|%HOME%|$HOME|g" "${DST}.tmp"
-
- for i in $(seq 0 15); do
- v="$(echo "$XRDB" | awk "/color$i/ {print \$2;exit}")"
- sed -i "s|%cl${i}%|$v|g" "${DST}.tmp"
- done
-
- [ -f "${DST}" ] && rm "${DST}"
- mv "${DST}.tmp" "${DST}"
+ SRC="$1"
+ DST="$2"
+ [ -f "${DST}.tmp" ] && rm "${DST}.tmp"
+ cp "${SRC}" "${DST}.tmp"
+
+ XRDB="$(xrdb -query)"
+ background="$(printf '%s\n' "$XRDB" | awk '/background/ {print $2;exit}')"
+ foreground="$(printf '%s\n' "$XRDB" | awk '/foreground/ {print $2;exit}')"
+ cursorcolor="$(printf '%s\n' "$XRDB" | awk '/cursorColor/ {print $2;exit}')"
+
+ sed "s|%clfg%|$foreground|g;s|%clbg%|$background|g;s|%clcr%|$cursorcolor|g;s|%HOME%|$HOME|g" "${DST}.tmp" > "${DST}.tmp2"
+ mv "${DST}.tmp2" "${DST}.tmp"
+
+ for i in $(seq 0 15); do
+ v="$(echo "$XRDB" | awk "/color$i/ {print \$2;exit}")"
+ sed "s|%cl${i}%|$v|g" "${DST}.tmp" > "${DST}.tmp2"
+ mv "${DST}.tmp2" "${DST}.tmp"
+ done
+
+ [ -f "${DST}" ] && rm "${DST}"
+ mv "${DST}.tmp" "${DST}"
}
apply_theme() {
- THEME="$1"
- XRES_COLORS_SRC="${XRES}/themes/$THEME"
- cp -f "${XRES_COLORS_SRC}" "${XRES_COLORS_DST}"
- xrdb "${XRES_SRC}"
- generate_theme "${HOME}/.config/surf/styles/default.css.in" "${HOME}/.config/surf/styles/default.css"
- generate_theme "${HOME}/.config/zathura/zathurarc.in" "${HOME}/.config/zathura/zathurarc"
- echo "$THEME" > "$HOME"/.cache/theme
+ THEME="$1"
+ XRES_COLORS_SRC="${XRES}/themes/$THEME"
+ cp -f "${XRES_COLORS_SRC}" "${XRES_COLORS_DST}"
+ xrdb "${XRES_SRC}"
+ generate_theme "${HOME}/.config/surf/styles/default.css.in" "${HOME}/.config/surf/styles/default.css"
+ generate_theme "${HOME}/.config/zathura/zathurarc.in" "${HOME}/.config/zathura/zathurarc"
+ echo "$THEME" > "$HOME"/.cache/theme
}
reload_theme() {
- pidof tabbed >/dev/null 2>&1 && for PID in $(pidof tabbed); do kill -s USR1 "$PID"; done
- pidof st >/dev/null 2>&1 && for PID in $(pidof st); do kill -s USR1 "$PID"; done
- # Remove urgency mark for st, tabbed instances:
- xdotool search --class st set_window --urgency 0 "%@"
- xdotool search --class tabbed set_window --urgency 0 "%@"
- pidof dwm >/dev/null 2>&1 && xdotool key "Super+F5"
- #pidof bspwm && bspc wm -r
- #pidof openbox && openbox --restart
- setsid dwm-bar
-
- case "$OLDTHEME" in
- "${THEME}") NOTIF_TEXT="Reloaded ${THEME} theme." ;;
- *) NOTIF_TEXT="Set the theme from ${OLDTHEME} to ${THEME}!" ;;
- esac
- pkill -SIGUSR1 merbe
- merbe " Theme Selector" "$NOTIF_TEXT" &
- #dunstify -t 10000 -h string:x-dunst-stack-tag:theme "Set Theme" "$NOTIF_TEXT"
+ pidof tabbed >/dev/null 2>&1 && for PID in $(pidof tabbed); do kill -s USR1 "$PID" >/dev/null 2>&1; done
+ pidof st >/dev/null 2>&1 && for PID in $(pidof st); do kill -s USR1 "$PID" >/dev/null 2>&1; done
+ # Remove urgency mark for st, tabbed instances:
+ xdotool search --class st set_window --urgency 0 "%@"
+ xdotool search --class tabbed set_window --urgency 0 "%@"
+ pidof dwm >/dev/null 2>&1 && xdotool key "Super+F5"
+ #pidof bspwm && bspc wm -r
+ #pidof openbox && openbox --restart
+
+ # If you have colorful bar, consider restarting the bar
+ #dwm-bar &
+
+ case "$OLDTHEME" in
+ "${THEME}") NOTIF_TEXT="Reloaded ${THEME} theme." ;;
+ *) NOTIF_TEXT="Set the theme from ${OLDTHEME} to ${THEME}!" ;;
+ esac
+ notify "$(printf '%s\n' " Theme Selector" "$NOTIF_TEXT")"
}
case "$1" in
- -l)
- find_themes
- exit
- ;;
- -x)
- THEME="$(find_themes | shuf -n 1)"
- THEME="${THEME%% *}"
- [ "$THEME" ] || exit
- ;;
- -s)
- THEME="$(find_themes | sed "s/$OLDTHEME/$OLDTHEME */g" | dmenu -i -p "Set Theme:")"
- THEME="${THEME%% *}"
- [ "$THEME" ] || exit
- ;;
- *)
- THEME="${1:-$(cat "$HOME"/.cache/theme || echo "nord")}"
- ;;
+ -l)
+ find_themes
+ exit
+ ;;
+ -x)
+ TODAY=$(date +%d)
+ COUNT=$(find_themes | wc -l)
+ THEME=$((TODAY%COUNT))
+ [ "$THEME" -eq 0 ] && THEME=$COUNT
+ THEME=$(find_themes | sed -n "${THEME}p")
+ ;;
+ -s)
+ NUM=$(find_themes -l | awk "/$OLDTHEME/{print NR-1}")
+ THEME=$(find_themes | sed "s/$OLDTHEME/$OLDTHEME */g" | dmenu -i -n "$NUM" -p "Set Theme:")
+ THEME=${THEME%% *}
+ [ "$THEME" ] || exit
+ ;;
+ *)
+ THEME="${1:-$(cat "$HOME"/.cache/theme || echo "nord")}"
+ ;;
esac
+
apply_theme "$THEME"
-if [ "$DISPLAY" ]; then
- #bg-set
- bg-gen
- reload_theme
+
+if [ "$DISPLAY" ]; then
+ #bg-set
+ bg-gen
+ reload_theme
fi
# Old:
diff --git a/.local/bin/volume b/.local/bin/volume
@@ -1,152 +0,0 @@
-#!/bin/sh
-AUDIO_STEPS="5"
-AUDIO_ACT="get"
-
-while getopts ':gidmGIDMs:' flag; do
- case "${flag}" in
- g) AUDIO_ACT="get" ;;
- i) AUDIO_ACT="inc" ;;
- d) AUDIO_ACT="dec" ;;
- m) AUDIO_ACT="mute" ;;
- G) AUDIO_ACT="mic-get" ;;
- I) AUDIO_ACT="mic-inc" ;;
- D) AUDIO_ACT="mic-dec" ;;
- M) AUDIO_ACT="mic-mute" ;;
- s) AUDIO_STEPS="${OPTARG}" ;;
- *)
- printf 'Usage: %s [-g] [-d] [-i] [-m] [-G] [-D] [-I] [-M] [-s audio steps (in %%)]\n' "$0"
- printf ' -g: get volume\n'
- printf ' -i: increase volume\n'
- printf ' -d: decrease volume\n'
- printf ' -m: mute volume\n'
- printf ' -G: get mic volume\n'
- printf ' -I: increase mic volume\n'
- printf ' -D: decrease mic volume\n'
- printf ' -M: mute mic volume\n'
- exit 2
- ;;
- esac
-done
-
-vol() {
- case "$(uname)" in
- "Linux"*)
- if pactl stat >/dev/null 2>&1; then
- case "$1" in
- get) pactl get-sink-volume @DEFAULT_SOURCE@ | awk '/%/{sub(/%/, "", $5);print $5}' ;;
- inc) pactl set-sink-volume @DEFAULT_SINK@ "+$2%" ;;
- dec) pactl set-sink-volume @DEFAULT_SINK@ "-$2%" ;;
- mute) pactl set-sink-mute @DEFAULT_SINK@ toggle ;;
- ismuted) pactl get-sink-mute @DEFAULT_SOURCE@ | grep -o 'yes' ;;
- mic-get) pactl get-source-volume @DEFAULT_SOURCE@ | awk '/%/{sub(/%/, "", $5);print $5}' ;;
- mic-inc) pactl set-source-volume @DEFAULT_SINK@ "+$2%" ;;
- mic-dec) pactl set-source-volume @DEFAULT_SINK@ "-$2%" ;;
- mic-mute) pactl set-source-mute @DEFAULT_SINK@ toggle ;;
- mic-ismuted) pactl get-source-mute @DEFAULT_SOURCE@ | grep -o 'yes' ;;
- esac
- else
- case "$1" in
- get) amixer sget Master on | grep -o '[0-9]*%' | sed 's/%//' ;;
- inc) amixer sset Master "$2%+" on -q ;;
- dec) amixer sset Master "$2%-" on -q ;;
- mute) amixer sset Master 1+ toggle -q ;;
- ismuted) amixer sget Master on | grep -o '\[off\]' ;;
- mic-get) pactl get-source-volume @DEFAULT_SOURCE@ | awk '/%/{sub(/%/, "", $5);print $5}' ;;
- mic-inc) pactl set-source-volume @DEFAULT_SINK@ "+$2%" ;;
- mic-dec) pactl set-source-volume @DEFAULT_SINK@ "-$2%" ;;
- mic-mute) pactl set-source-mute @DEFAULT_SINK@ toggle ;;
- mic-ismuted) pactl get-source-mute @DEFAULT_SOURCE@ | grep -o 'yes' ;;
- esac
- fi
- ;;
- "FreeBSD"*)
- case "$1" in
- get) mixer -s vol | cut -d ':' -f 2 ;;
- inc) mixer -s vol "+$2%" ;;
- dec) mixer -s vol "-$2%" ;;
- mute) [ "$(vol get)" -eq 0 ] && mixer -s vol 75 || mixer -s vol 0 ;;
- ismuted) [ "$(vol get)" -eq 0 ] && echo yes ;;
- mic-get) mixer -s mic | cut -d ':' -f 2 ;;
- mic-inc) mixer -s mic "+$2%" ;;
- mic-dec) mixer -s mic "-$2%" ;;
- mic-mute) [ "$(vol mic-get)" -eq 0 ] && mixer -s mic 35 || mixer -s mic 0 ;;
- mic-ismuted) [ "$(vol mic-get)" -eq 0 ] && echo yes ;;
- esac
- ;;
- esac
-}
-
-notify() {
- case "$1" in
- mic) VOLUME=$(vol mic-get) ; IS_MUTED=$(vol mic-ismuted) ;;
- *) VOLUME=$(vol get) ; IS_MUTED=$(vol ismuted) ;;
- esac
- if [ "$IS_MUTED" ] || [ "$VOLUME" -eq 0 ]; then
- VOLUME="Muted"
- VOLUME_ICON="ﱝ"
- elif [ "$VOLUME" -lt 30 ]; then
- VOLUME_ICON=""
- elif [ "$VOLUME" -lt 70 ]; then
- VOLUME_ICON=""
- else
- VOLUME_ICON=""
- fi
- pkill -SIGUSR1 merbe
- merbe "$VOLUME_ICON $VOLUME" &
-}
-
-case "$AUDIO_ACT" in
- inc)
- CURRENT_VOLUME=$(vol get)
- REMAINDER=$((CURRENT_VOLUME%AUDIO_STEPS))
- AUDIO_STEPS=$((AUDIO_STEPS-REMAINDER))
- ;;
- dec)
- CURRENT_VOLUME=$(vol get)
- REMAINDER=$((CURRENT_VOLUME%AUDIO_STEPS))
- AUDIO_STEPS=$((AUDIO_STEPS+REMAINDER))
- ;;
- mic-inc)
- CURRENT_VOLUME=$(vol mic-get)
- REMAINDER=$((CURRENT_VOLUME%AUDIO_STEPS))
- AUDIO_STEPS=$((AUDIO_STEPS-REMAINDER))
- ;;
- mic-dec)
- CURRENT_VOLUME=$(vol mic-get)
- REMAINDER=$((CURRENT_VOLUME%AUDIO_STEPS))
- AUDIO_STEPS=$((AUDIO_STEPS+REMAINDER))
- ;;
-esac
-
-case "$AUDIO_ACT" in
- get)
- notify
- ;;
- inc)
- vol inc "$AUDIO_STEPS"
- notify
- ;;
- dec)
- vol dec "$AUDIO_STEPS"
- notify
- ;;
- mute)
- vol mute
- notify
- ;;
- mic-get)
- notify "mic"
- ;;
- mic-inc)
- vol mic-inc "$AUDIO_STEPS"
- notify "mic"
- ;;
- mic-dec)
- vol mic-dec "$AUDIO_STEPS"
- notify "mic"
- ;;
- mic-mute)
- vol mic-mute
- notify "mic"
- ;;
-esac
diff --git a/.local/bin/vpn b/.local/bin/vpn
@@ -1,14 +1,50 @@
#!/bin/sh
-echo "nameserver 1.1.1.1" > /etc/resolv.conf
-cd /dev
-mkdir net
-mknod net/tun c 10 200
-chmod 0666 net/tun
-while :; do
+prepare() {
+ (echo "nameserver 1.1.1.1";
+ echo "nameserver 1.0.0.1";
+ echo "nameserver 208.67.222.222";
+ echo "nameserver 208.67.220.220") > /etc/resolv.conf
+
+ cd /dev || exit
+ mkdir net
+ mknod net/tun c 10 200
+ chmod 0666 net/tun
+}
+
+stopvpn() {
for pid in $(ps ax | grep openvpn | awk '{print $1}'); do
[ "$pid" = "$$" ] && continue
kill -9 "$pid" > /dev/null 2>&1
wait
done
+}
+
+startvpn() {
+ printf "\033[90m"
openvpn /home/mahdi/.local/share/Mahdi.ovpn
-done
+ printf "\033[0m"
+}
+
+loopvpn() {
+ while :; do
+ stopvpn
+ startvpn
+ done
+}
+
+prepare
+clear
+
+case "$1" in
+ start)
+ startvpn
+ ;;
+ stop)
+ stopvpn
+ ;;
+ *)
+ loopvpn &
+ trap loop INT
+ trap loop EXIT
+ ;;
+esac
diff --git a/.local/bin/webcam b/.local/bin/webcam
@@ -1,9 +1,9 @@
#!/bin/sh
-WEBCAM_DRIVER="v4l2"
-WEBCAM_DEVICE="$(ls /dev/video* | head -n 1)"
+WEBCAM_DRIVER=v4l2
+WEBCAM_DEVICE=$(find /dev -name "video*" | sort | sed -n '1p')
if [ ! -e "${WEBCAM_DEVICE}" ]; then
- merbe "Webcam" "Install a webcam first!" &
+ notify "Webcam" "Install a webcam first!"
exit 2
fi
@@ -14,10 +14,10 @@ case "$1" in
;;
*)
ps ax | grep "mpv*av://$WEBCAM_DRIVER:$WEBCAM_DEVICE*" | \
- awk '{print $1}' | while read PID; do kill -9 "$PID"; wait; done
- merbe " Webcam" "$WEBCAM_DEVICE is open now." &
+ awk '{print $1}' | while read -r PID; do kill -9 "$PID"; wait; done
+ notify " Webcam" "$WEBCAM_DEVICE is open now."
mpv "av://$WEBCAM_DRIVER:$WEBCAM_DEVICE" --title=webcam \
--profile=low-latency --untimed --load-scripts=no --no-osc
- merbe " Webcam" "$WEBCAM_DEVICE has been closed." &
+ notify " Webcam" "$WEBCAM_DEVICE has been closed."
;;
esac
diff --git a/.local/src/dmenu/LICENSE b/.local/src/dmenu/LICENSE
@@ -1,30 +0,0 @@
-MIT/X Consortium License
-
-© 2006-2019 Anselm R Garbe <[email protected]>
-© 2006-2008 Sander van Dijk <[email protected]>
-© 2006-2007 Michał Janeczek <[email protected]>
-© 2007 Kris Maglione <[email protected]>
-© 2009 Gottox <[email protected]>
-© 2009 Markus Schnalke <[email protected]>
-© 2009 Evan Gates <[email protected]>
-© 2010-2012 Connor Lane Smith <[email protected]>
-© 2014-2022 Hiltjo Posthuma <[email protected]>
-© 2015-2019 Quentin Rameau <[email protected]>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/.local/src/dmenu/Makefile b/.local/src/dmenu/Makefile
@@ -1,64 +0,0 @@
-# dmenu - dynamic menu
-# See LICENSE file for copyright and license details.
-
-include config.mk
-
-SRC = drw.c dmenu.c stest.c util.c
-OBJ = $(SRC:.c=.o)
-
-all: options dmenu stest
-
-options:
- @echo dmenu build options:
- @echo "CFLAGS = $(CFLAGS)"
- @echo "LDFLAGS = $(LDFLAGS)"
- @echo "CC = $(CC)"
-
-.c.o:
- $(CC) -c $(CFLAGS) $<
-
-config.h:
- cp config.def.h $@
-
-$(OBJ): arg.h config.h config.mk drw.h
-
-dmenu: dmenu.o drw.o util.o
- $(CC) -o $@ dmenu.o drw.o util.o $(LDFLAGS)
-
-stest: stest.o
- $(CC) -o $@ stest.o $(LDFLAGS)
-
-clean:
- rm -f dmenu stest $(OBJ) dmenu-$(VERSION).tar.gz
-
-dist: clean
- mkdir -p dmenu-$(VERSION)
- cp LICENSE Makefile README arg.h config.def.h config.mk dmenu.1\
- drw.h util.h dmenu_path dmenu_run stest.1 $(SRC)\
- dmenu-$(VERSION)
- tar -cf dmenu-$(VERSION).tar dmenu-$(VERSION)
- gzip dmenu-$(VERSION).tar
- rm -rf dmenu-$(VERSION)
-
-install: all
- mkdir -p $(DESTDIR)$(PREFIX)/bin
- cp -f dmenu dmenu_path dmenu_run stest $(DESTDIR)$(PREFIX)/bin
- chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu
- chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_path
- chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_run
- chmod 755 $(DESTDIR)$(PREFIX)/bin/stest
- mkdir -p $(DESTDIR)$(MANPREFIX)/man1
- sed "s/VERSION/$(VERSION)/g" < dmenu.1 > $(DESTDIR)$(MANPREFIX)/man1/dmenu.1
- sed "s/VERSION/$(VERSION)/g" < stest.1 > $(DESTDIR)$(MANPREFIX)/man1/stest.1
- chmod 644 $(DESTDIR)$(MANPREFIX)/man1/dmenu.1
- chmod 644 $(DESTDIR)$(MANPREFIX)/man1/stest.1
-
-uninstall:
- rm -f $(DESTDIR)$(PREFIX)/bin/dmenu\
- $(DESTDIR)$(PREFIX)/bin/dmenu_path\
- $(DESTDIR)$(PREFIX)/bin/dmenu_run\
- $(DESTDIR)$(PREFIX)/bin/stest\
- $(DESTDIR)$(MANPREFIX)/man1/dmenu.1\
- $(DESTDIR)$(MANPREFIX)/man1/stest.1
-
-.PHONY: all options clean dist install uninstall
diff --git a/.local/src/dmenu/README b/.local/src/dmenu/README
@@ -1,24 +0,0 @@
-dmenu - dynamic menu
-====================
-dmenu is an efficient dynamic menu for X.
-
-
-Requirements
-------------
-In order to build dmenu you need the Xlib header files.
-
-
-Installation
-------------
-Edit config.mk to match your local setup (dmenu is installed into
-the /usr/local namespace by default).
-
-Afterwards enter the following command to build and install dmenu
-(if necessary as root):
-
- make clean install
-
-
-Running dmenu
--------------
-See the man page for details.
diff --git a/.local/src/dmenu/arg.h b/.local/src/dmenu/arg.h
@@ -1,49 +0,0 @@
-/*
- * Copy me if you can.
- * by 20h
- */
-
-#ifndef ARG_H__
-#define ARG_H__
-
-extern char *argv0;
-
-/* use main(int argc, char *argv[]) */
-#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\
- argv[0] && argv[0][0] == '-'\
- && argv[0][1];\
- argc--, argv++) {\
- char argc_;\
- char **argv_;\
- int brk_;\
- if (argv[0][1] == '-' && argv[0][2] == '\0') {\
- argv++;\
- argc--;\
- break;\
- }\
- for (brk_ = 0, argv[0]++, argv_ = argv;\
- argv[0][0] && !brk_;\
- argv[0]++) {\
- if (argv_ != argv)\
- break;\
- argc_ = argv[0][0];\
- switch (argc_)
-
-#define ARGEND }\
- }
-
-#define ARGC() argc_
-
-#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\
- ((x), abort(), (char *)0) :\
- (brk_ = 1, (argv[0][1] != '\0')?\
- (&argv[0][1]) :\
- (argc--, argv++, argv[0])))
-
-#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\
- (char *)0 :\
- (brk_ = 1, (argv[0][1] != '\0')?\
- (&argv[0][1]) :\
- (argc--, argv++, argv[0])))
-
-#endif
diff --git a/.local/src/dmenu/config.h b/.local/src/dmenu/config.h
@@ -1,60 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-static char font[] = "monospace:size=10"; /* -fn option overrides fonts[0]; default font */
-static const char *fonts[] = {
- font,
- "Vazir:size=10",
- "emoji:size=10",
-};
-
-static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
-static unsigned int border_width= 2; /* -bw option; size of the window border */
-static char *prompt = NULL; /* -p option; prompt to the left of input field */
-static unsigned int preselected = 0; /* -n option; preselected item starting from 0 */
-static unsigned int lines = 0; /* -l option; if nonzero dmenu draws vertical list */
-static const unsigned int alpha = 0xf0;
-
-/*
- * Characters not considered part of a word while deleting words
- * for example: " /?\"&[]"
- */
-static const char worddelimiters[] = " ";
-
-static char normfgcolor[] = "#ECEFF4";
-static char normbgcolor[] = "#3B4252";
-static char normhlcolor[] = "#EBCB8B";
-static char selfgcolor[] = "#EBCB8B";
-static char selbgcolor[] = "#4C566A";
-static char selhlcolor[] = "#E5E9F0";
-static char *colors[SchemeLast][2] = {
- /* fg bg */
- [SchemeNorm] = { normfgcolor, normbgcolor },
- [SchemeSel] = { selfgcolor, selbgcolor },
- [SchemeNormHighlight] = { normhlcolor, normbgcolor },
- [SchemeSelHighlight] = { selhlcolor, selbgcolor },
- [SchemeOut] = { "#000000", "#00ffff" },
- [SchemeOutHighlight] = { normhlcolor, "#00ffff" },
-};
-
-static const unsigned int alphas[SchemeLast][2] = {
- [SchemeNorm] = { OPAQUE, alpha },
- [SchemeSel] = { OPAQUE, alpha },
- [SchemeOut] = { OPAQUE, alpha },
- [SchemeNormHighlight] = { OPAQUE, alpha },
- [SchemeSelHighlight] = { OPAQUE, alpha },
- [SchemeOutHighlight] = { OPAQUE, alpha },
-};
-
-/*
- * Xresources preferences to load at startup
- */
-ResourcePref resources[] = {
- { "font", STRING, &font },
- { "color12", STRING, &normfgcolor },
- { "color0", STRING, &normbgcolor },
- { "color11", STRING, &normhlcolor },
- { "color0", STRING, &selfgcolor },
- { "color12", STRING, &selbgcolor },
- { "color8", STRING, &selhlcolor },
- { "prompt", STRING, &prompt },
-};
-
diff --git a/.local/src/dmenu/config.mk b/.local/src/dmenu/config.mk
@@ -1,35 +0,0 @@
-# dmenu version
-VERSION = 5.1
-
-# paths
-PREFIX = /usr/local
-MANPREFIX = $(PREFIX)/share/man
-
-X11INC = /usr/include
-X11LIB = /usr/lib
-
-BDINC = /usr/include/fribidi
-
-# Xinerama, comment if you don't want it
-XINERAMALIBS = -lXinerama
-XINERAMAFLAGS = -DXINERAMA
-
-# freetype
-FREETYPELIBS = -lfontconfig -lXft
-FREETYPEINC = /usr/include/freetype2
-# OpenBSD (uncomment)
-#FREETYPEINC = $(X11INC)/freetype2
-
-BDLIBS = -lfribidi
-
-# includes and libs
-INCS = -I$(X11INC) -I$(FREETYPEINC) -I$(BDINC)
-LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) $(BDLIBS) -lXrender
-
-# flags
-CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS)
-CFLAGS = -std=c99 -pedantic -Wall -Os $(INCS) $(CPPFLAGS)
-LDFLAGS = $(LIBS)
-
-# compiler and linker
-CC = cc
diff --git a/.local/src/dmenu/dmenu.1 b/.local/src/dmenu/dmenu.1
@@ -1,202 +0,0 @@
-.TH DMENU 1 dmenu\-VERSION
-.SH NAME
-dmenu \- dynamic menu
-.SH SYNOPSIS
-.B dmenu
-.RB [ \-bfivP ]
-.RB [ \-l
-.IR lines ]
-.RB [ \-m
-.IR monitor ]
-.RB [ \-p
-.IR prompt ]
-.RB [ \-fn
-.IR font ]
-.RB [ \-nb
-.IR color ]
-.RB [ \-nf
-.IR color ]
-.RB [ \-sb
-.IR color ]
-.RB [ \-sf
-.IR color ]
-.RB [ \-w
-.IR windowid ]
-.RB [ \-n
-.IR number ]
-.P
-.BR dmenu_run " ..."
-.SH DESCRIPTION
-.B dmenu
-is a dynamic menu for X, which reads a list of newline\-separated items from
-stdin. When the user selects an item and presses Return, their choice is printed
-to stdout and dmenu terminates. Entering text will narrow the items to those
-matching the tokens in the input.
-.P
-.B dmenu_run
-is a script used by
-.IR dwm (1)
-which lists programs in the user's $PATH and runs the result in their $SHELL.
-.SH OPTIONS
-.TP
-.B \-b
-dmenu appears at the bottom of the screen.
-.TP
-.B \-f
-dmenu grabs the keyboard before reading stdin if not reading from a tty. This
-is faster, but will lock up X until stdin reaches end\-of\-file.
-.TP
-.B \-i
-dmenu matches menu items case insensitively.
-.TP
-.B \-P
-dmenu will not directly display the keyboard input, but instead replace it with dots. All data from stdin will be ignored.
-.TP
-.BI \-l " lines"
-dmenu lists items vertically, with the given number of lines.
-.TP
-.BI \-m " monitor"
-dmenu is displayed on the monitor number supplied. Monitor numbers are starting
-from 0.
-.TP
-.BI \-p " prompt"
-defines the prompt to be displayed to the left of the input field.
-.TP
-.BI \-fn " font"
-defines the font or font set used.
-.TP
-.BI \-nb " color"
-defines the normal background color.
-.IR #RGB ,
-.IR #RRGGBB ,
-and X color names are supported.
-.TP
-.BI \-nf " color"
-defines the normal foreground color.
-.TP
-.BI \-sb " color"
-defines the selected background color.
-.TP
-.BI \-sf " color"
-defines the selected foreground color.
-.TP
-.B \-v
-prints version information to stdout, then exits.
-.TP
-.BI \-w " windowid"
-embed into windowid.
-.TP
-.BI \-n " number"
-preseslected item starting from 0.
-.SH USAGE
-dmenu is completely controlled by the keyboard. Items are selected using the
-arrow keys, page up, page down, home, and end.
-.TP
-.B Tab
-Copy the selected item to the input field.
-.TP
-.B Return
-Confirm selection. Prints the selected item to stdout and exits, returning
-success.
-.TP
-.B Ctrl-Return
-Confirm selection. Prints the selected item to stdout and continues.
-.TP
-.B Shift\-Return
-Confirm input. Prints the input text to stdout and exits, returning success.
-.TP
-.B Escape
-Exit without selecting an item, returning failure.
-.TP
-.B Ctrl-Left
-Move cursor to the start of the current word
-.TP
-.B Ctrl-Right
-Move cursor to the end of the current word
-.TP
-.B C\-a
-Home
-.TP
-.B C\-b
-Left
-.TP
-.B C\-c
-Escape
-.TP
-.B C\-d
-Delete
-.TP
-.B C\-e
-End
-.TP
-.B C\-f
-Right
-.TP
-.B C\-g
-Escape
-.TP
-.B C\-h
-Backspace
-.TP
-.B C\-i
-Tab
-.TP
-.B C\-j
-Return
-.TP
-.B C\-J
-Shift-Return
-.TP
-.B C\-k
-Delete line right
-.TP
-.B C\-m
-Return
-.TP
-.B C\-M
-Shift-Return
-.TP
-.B C\-n
-Down
-.TP
-.B C\-p
-Up
-.TP
-.B C\-u
-Delete line left
-.TP
-.B C\-w
-Delete word left
-.TP
-.B C\-y
-Paste from primary X selection
-.TP
-.B C\-Y
-Paste from X clipboard
-.TP
-.B M\-b
-Move cursor to the start of the current word
-.TP
-.B M\-f
-Move cursor to the end of the current word
-.TP
-.B M\-g
-Home
-.TP
-.B M\-G
-End
-.TP
-.B M\-h
-Up
-.TP
-.B M\-j
-Page down
-.TP
-.B M\-k
-Page up
-.TP
-.B M\-l
-Down
-.SH SEE ALSO
-.IR dwm (1),
-.IR stest (1)
diff --git a/.local/src/dmenu/dmenu.c b/.local/src/dmenu/dmenu.c
@@ -1,1011 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <ctype.h>
-#include <locale.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <X11/Xproto.h>
-#include <X11/Xutil.h>
-#include <X11/Xresource.h>
-#ifdef XINERAMA
-#include <X11/extensions/Xinerama.h>
-#endif
-#include <X11/Xft/Xft.h>
-
-#include <fribidi.h>
-
-#include "drw.h"
-#include "util.h"
-
-/* macros */
-#define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \
- * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org)))
-#define LENGTH(X) (sizeof X / sizeof X[0])
-#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
-
-#define OPAQUE 0xffU
-
-/* enums */
-enum { SchemeNorm, SchemeSel, SchemeOut, SchemeNormHighlight, SchemeSelHighlight, SchemeOutHighlight, SchemeLast }; /* color schemes */
-struct item {
- char *text;
- struct item *left, *right;
- int out;
-};
-
-static char text[BUFSIZ] = "";
-static char fribidi_text[BUFSIZ] = "";
-static char *embed;
-static int bh, mw, mh;
-static int inputw = 0, promptw, passwd = 0;
-static int lrpad; /* sum of left and right padding */
-static size_t cursor;
-static struct item *items = NULL;
-static struct item *matches, *matchend;
-static struct item *prev, *curr, *next, *sel;
-static int mon = -1, screen;
-
-static Atom clip, utf8;
-static Display *dpy;
-static Window root, parentwin, win;
-static XIC xic;
-
-static Drw *drw;
-static Clr *scheme[SchemeLast];
-
-/* Xresources preferences */
-enum resource_type {
- STRING = 0,
- INTEGER = 1,
- FLOAT = 2
-};
-typedef struct {
- char *name;
- enum resource_type type;
- void *dst;
-} ResourcePref;
-
-static void load_xresources(void);
-static void resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst);
-
-static int useargb = 0;
-static Visual *visual;
-static int depth;
-static Colormap cmap;
-
-#include "config.h"
-
-static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
-static char *(*fstrstr)(const char *, const char *) = strstr;
-static void xinitvisual();
-
-static unsigned int
-textw_clamp(const char *str, unsigned int n)
-{
- unsigned int w = drw_fontset_getwidth_clamp(drw, str, n) + lrpad;
- return MIN(w, n);
-}
-
-static void
-appenditem(struct item *item, struct item **list, struct item **last)
-{
- if (*last)
- (*last)->right = item;
- else
- *list = item;
-
- item->left = *last;
- item->right = NULL;
- *last = item;
-}
-
-static void
-calcoffsets(void)
-{
- int i, n;
-
- if (lines > 0)
- n = lines * bh;
- else
- n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">"));
- /* calculate which items will begin the next page and previous page */
- for (i = 0, next = curr; next; next = next->right)
- if ((i += (lines > 0) ? bh : textw_clamp(next->text, n)) > n)
- break;
- for (i = 0, prev = curr; prev && prev->left; prev = prev->left)
- if ((i += (lines > 0) ? bh : textw_clamp(prev->left->text, n)) > n)
- break;
-}
-
-static void
-cleanup(void)
-{
- size_t i;
-
- XUngrabKey(dpy, AnyKey, AnyModifier, root);
- for (i = 0; i < SchemeLast; i++)
- free(scheme[i]);
- for (i = 0; items && items[i].text; ++i)
- free(items[i].text);
- free(items);
- drw_free(drw);
- XSync(dpy, False);
- XCloseDisplay(dpy);
-}
-
-static char *
-cistrstr(const char *h, const char *n)
-{
- size_t i;
-
- if (!n[0])
- return (char *)h;
-
- for (; *h; ++h) {
- for (i = 0; n[i] && tolower((unsigned char)n[i]) ==
- tolower((unsigned char)h[i]); ++i)
- ;
- if (n[i] == '\0')
- return (char *)h;
- }
- return NULL;
-}
-
-static void
-drawhighlights(struct item *item, int x, int y, int maxw)
-{
- char restorechar, tokens[sizeof text], *highlight, *token;
- int indentx, highlightlen;
-
- drw_setscheme(drw, scheme[item == sel ? SchemeSelHighlight : item->out ? SchemeOutHighlight : SchemeNormHighlight]);
- strcpy(tokens, text);
- for (token = strtok(tokens, " "); token; token = strtok(NULL, " ")) {
- highlight = fstrstr(item->text, token);
- while (highlight) {
- // Move item str end, calc width for highlight indent, & restore
- highlightlen = highlight - item->text;
- restorechar = *highlight;
- item->text[highlightlen] = '\0';
- indentx = TEXTW(item->text);
- item->text[highlightlen] = restorechar;
-
- // Move highlight str end, draw highlight, & restore
- restorechar = highlight[strlen(token)];
- highlight[strlen(token)] = '\0';
- if (indentx - (lrpad / 2) - 1 < maxw)
- drw_text(
- drw,
- x + indentx - (lrpad / 2) - 1,
- y,
- MIN(maxw - indentx, TEXTW(highlight) - lrpad),
- bh, 0, highlight, 0
- );
- highlight[strlen(token)] = restorechar;
-
- if (strlen(highlight) - strlen(token) < strlen(token)) break;
- highlight = fstrstr(highlight + strlen(token), token);
- }
- }
-}
-
-static void
-apply_fribidi(char *str)
-{
- FriBidiStrIndex len = strlen(str);
- FriBidiChar logical[BUFSIZ];
- FriBidiChar visual[BUFSIZ];
- FriBidiParType base = FRIBIDI_PAR_ON;
- FriBidiCharSet charset;
- fribidi_boolean result;
-
- fribidi_text[0] = 0;
- if (len > 0) {
- charset = fribidi_parse_charset("UTF-8");
- len = fribidi_charset_to_unicode(charset, str, len, logical);
- result = fribidi_log2vis(logical, len, &base, visual, NULL, NULL, NULL);
- len = fribidi_unicode_to_charset(charset, visual, len, fribidi_text);
- }
-}
-
-static int
-drawitem(struct item *item, int x, int y, int w)
-{
- if (item == sel)
- drw_setscheme(drw, scheme[SchemeSel]);
- else if (item->out)
- drw_setscheme(drw, scheme[SchemeOut]);
- else
- drw_setscheme(drw, scheme[SchemeNorm]);
-
- apply_fribidi(item->text);
- int r = drw_text(drw, x, y, w, bh, lrpad / 2, fribidi_text, 0);
- drawhighlights(item, x, y, w);
- return r;
-}
-
-static void
-drawmenu(void)
-{
- unsigned int curpos;
- struct item *item;
- int x = 0, y = 0, w;
- char *censort;
-
- drw_setscheme(drw, scheme[SchemeNorm]);
- drw_rect(drw, 0, 0, mw, mh, 1, 1);
-
- if (prompt && *prompt) {
- drw_setscheme(drw, scheme[SchemeSel]);
- x = drw_text(drw, x, 0, promptw, bh, lrpad / 2, prompt, 0);
- }
- /* draw input field */
- w = (lines > 0 || !matches) ? mw - x : inputw;
- drw_setscheme(drw, scheme[SchemeNorm]);
- if (passwd) {
- censort = ecalloc(1, sizeof(text));
- memset(censort, '.', strlen(text));
- drw_text(drw, x, 0, w, bh, lrpad / 2, censort, 0);
- free(censort);
- } else {
- apply_fribidi(text);
- drw_text(drw, x, 0, w, bh, lrpad / 2, fribidi_text, 0);
- }
-
- curpos = TEXTW(text) - TEXTW(&text[cursor]);
- if ((curpos += lrpad / 2 - 1) < w) {
- drw_setscheme(drw, scheme[SchemeNorm]);
- drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0);
- }
-
- if (lines > 0) {
- /* draw vertical list */
- for (item = curr; item != next; item = item->right)
- drawitem(item, x - promptw, y += bh, mw);
- } else if (matches) {
- /* draw horizontal list */
- x += inputw;
- w = TEXTW("<");
- if (curr->left) {
- drw_setscheme(drw, scheme[SchemeNorm]);
- drw_text(drw, x, 0, w, bh, lrpad / 2, "<", 0);
- }
- x += w;
- for (item = curr; item != next; item = item->right)
- x = drawitem(item, x, 0, textw_clamp(item->text, mw - x - TEXTW(">")));
- if (next) {
- w = TEXTW(">");
- drw_setscheme(drw, scheme[SchemeNorm]);
- drw_text(drw, mw - w, 0, w, bh, lrpad / 2, ">", 0);
- }
- }
- drw_map(drw, win, 0, 0, mw, mh);
-}
-
-static void
-grabfocus(void)
-{
- struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 };
- Window focuswin;
- int i, revertwin;
-
- for (i = 0; i < 100; ++i) {
- XGetInputFocus(dpy, &focuswin, &revertwin);
- if (focuswin == win)
- return;
- XSetInputFocus(dpy, win, RevertToParent, CurrentTime);
- nanosleep(&ts, NULL);
- }
- die("cannot grab focus");
-}
-
-static void
-grabkeyboard(void)
-{
- struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 };
- int i;
-
- if (embed)
- return;
- /* try to grab keyboard, we may have to wait for another process to ungrab */
- for (i = 0; i < 1000; i++) {
- if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync,
- GrabModeAsync, CurrentTime) == GrabSuccess)
- return;
- nanosleep(&ts, NULL);
- }
- die("cannot grab keyboard");
-}
-
-static void
-match(void)
-{
- static char **tokv = NULL;
- static int tokn = 0;
-
- char buf[sizeof text], *s;
- int i, tokc = 0;
- size_t len, textsize;
- struct item *item, *lprefix, *lsubstr, *prefixend, *substrend;
-
- strcpy(buf, text);
- /* separate input text into tokens to be matched individually */
- for (s = strtok(buf, " "); s; tokv[tokc - 1] = s, s = strtok(NULL, " "))
- if (++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv)))
- die("cannot realloc %zu bytes:", tokn * sizeof *tokv);
- len = tokc ? strlen(tokv[0]) : 0;
-
- matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL;
- textsize = strlen(text) + 1;
- for (item = items; item && item->text; item++) {
- for (i = 0; i < tokc; i++)
- if (!fstrstr(item->text, tokv[i]))
- break;
- if (i != tokc) /* not all tokens match */
- continue;
- /* exact matches go first, then prefixes, then substrings */
- if (!tokc || !fstrncmp(text, item->text, textsize))
- appenditem(item, &matches, &matchend);
- else if (!fstrncmp(tokv[0], item->text, len))
- appenditem(item, &lprefix, &prefixend);
- else
- appenditem(item, &lsubstr, &substrend);
- }
- if (lprefix) {
- if (matches) {
- matchend->right = lprefix;
- lprefix->left = matchend;
- } else
- matches = lprefix;
- matchend = prefixend;
- }
- if (lsubstr) {
- if (matches) {
- matchend->right = lsubstr;
- lsubstr->left = matchend;
- } else
- matches = lsubstr;
- matchend = substrend;
- }
- curr = sel = matches;
- calcoffsets();
-}
-
-static void
-insert(const char *str, ssize_t n)
-{
- if (strlen(text) + n > sizeof text - 1)
- return;
- /* move existing text out of the way, insert new text, and update cursor */
- memmove(&text[cursor + n], &text[cursor], sizeof text - cursor - MAX(n, 0));
- if (n > 0)
- memcpy(&text[cursor], str, n);
- cursor += n;
- match();
-}
-
-static size_t
-nextrune(int inc)
-{
- ssize_t n;
-
- /* return location of next utf8 rune in the given direction (+1 or -1) */
- for (n = cursor + inc; n + inc >= 0 && (text[n] & 0xc0) == 0x80; n += inc)
- ;
- return n;
-}
-
-static void
-movewordedge(int dir)
-{
- if (dir < 0) { /* move cursor to the start of the word*/
- while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)]))
- cursor = nextrune(-1);
- while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)]))
- cursor = nextrune(-1);
- } else { /* move cursor to the end of the word */
- while (text[cursor] && strchr(worddelimiters, text[cursor]))
- cursor = nextrune(+1);
- while (text[cursor] && !strchr(worddelimiters, text[cursor]))
- cursor = nextrune(+1);
- }
-}
-
-static void
-keypress(XKeyEvent *ev)
-{
- char buf[32];
- int len;
- KeySym ksym;
- Status status;
-
- len = XmbLookupString(xic, ev, buf, sizeof buf, &ksym, &status);
- switch (status) {
- default: /* XLookupNone, XBufferOverflow */
- return;
- case XLookupChars:
- goto insert;
- case XLookupKeySym:
- case XLookupBoth:
- break;
- }
-
- if (ev->state & ControlMask) {
- switch(ksym) {
- case XK_a: ksym = XK_Home; break;
- case XK_b: ksym = XK_Left; break;
- case XK_c: ksym = XK_Escape; break;
- case XK_d: ksym = XK_Delete; break;
- case XK_e: ksym = XK_End; break;
- case XK_f: ksym = XK_Right; break;
- case XK_g: ksym = XK_Escape; break;
- case XK_h: ksym = XK_BackSpace; break;
- case XK_i: ksym = XK_Tab; break;
- case XK_j: /* fallthrough */
- case XK_J: /* fallthrough */
- case XK_m: /* fallthrough */
- case XK_M: ksym = XK_Return; ev->state &= ~ControlMask; break;
- case XK_n: ksym = XK_Down; break;
- case XK_p: ksym = XK_Up; break;
-
- case XK_k: /* delete right */
- text[cursor] = '\0';
- match();
- break;
- case XK_u: /* delete left */
- insert(NULL, 0 - cursor);
- break;
- case XK_w: /* delete word */
- while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)]))
- insert(NULL, nextrune(-1) - cursor);
- while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)]))
- insert(NULL, nextrune(-1) - cursor);
- break;
- case XK_y: /* paste selection */
- XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY,
- utf8, utf8, win, CurrentTime);
- return;
- case XK_Y: /* paste selection from clipboard */
- XConvertSelection(dpy, clip, utf8, utf8, win, CurrentTime);
- return;
- case XK_Left:
- case XK_KP_Left:
- movewordedge(-1);
- goto draw;
- case XK_Right:
- case XK_KP_Right:
- movewordedge(+1);
- goto draw;
- case XK_Return:
- case XK_KP_Enter:
- break;
- case XK_bracketleft:
- cleanup();
- exit(1);
- default:
- return;
- }
- } else if (ev->state & Mod1Mask) {
- switch(ksym) {
- case XK_b:
- movewordedge(-1);
- goto draw;
- case XK_f:
- movewordedge(+1);
- goto draw;
- case XK_g: ksym = XK_Home; break;
- case XK_G: ksym = XK_End; break;
- case XK_h: ksym = XK_Up; break;
- case XK_j: ksym = XK_Next; break;
- case XK_k: ksym = XK_Prior; break;
- case XK_l: ksym = XK_Down; break;
- default:
- return;
- }
- }
-
- switch(ksym) {
- default:
- insert:
- if (!iscntrl((unsigned char)*buf))
- insert(buf, len);
- break;
- case XK_Delete:
- case XK_KP_Delete:
- if (text[cursor] == '\0')
- return;
- cursor = nextrune(+1);
- /* fallthrough */
- case XK_BackSpace:
- if (cursor == 0)
- return;
- insert(NULL, nextrune(-1) - cursor);
- break;
- case XK_End:
- case XK_KP_End:
- if (text[cursor] != '\0') {
- cursor = strlen(text);
- break;
- }
- if (next) {
- /* jump to end of list and position items in reverse */
- curr = matchend;
- calcoffsets();
- curr = prev;
- calcoffsets();
- while (next && (curr = curr->right))
- calcoffsets();
- }
- sel = matchend;
- break;
- case XK_Escape:
- cleanup();
- exit(1);
- case XK_Home:
- case XK_KP_Home:
- if (sel == matches) {
- cursor = 0;
- break;
- }
- sel = curr = matches;
- calcoffsets();
- break;
- case XK_Left:
- case XK_KP_Left:
- if (cursor > 0 && (!sel || !sel->left || lines > 0)) {
- cursor = nextrune(-1);
- break;
- }
- if (lines > 0)
- return;
- /* fallthrough */
- case XK_Up:
- case XK_KP_Up:
- if (sel && sel->left && (sel = sel->left)->right == curr) {
- curr = prev;
- calcoffsets();
- }
- break;
- case XK_Next:
- case XK_KP_Next:
- if (!next)
- return;
- sel = curr = next;
- calcoffsets();
- break;
- case XK_Prior:
- case XK_KP_Prior:
- if (!prev)
- return;
- sel = curr = prev;
- calcoffsets();
- break;
- case XK_Return:
- case XK_KP_Enter:
- puts((sel && !(ev->state & ShiftMask)) ? sel->text : text);
- if (!(ev->state & ControlMask)) {
- cleanup();
- exit(0);
- }
- if (sel)
- sel->out = 1;
- break;
- case XK_Right:
- case XK_KP_Right:
- if (text[cursor] != '\0') {
- cursor = nextrune(+1);
- break;
- }
- if (lines > 0)
- return;
- /* fallthrough */
- case XK_Down:
- case XK_KP_Down:
- if (sel && sel->right && (sel = sel->right) == next) {
- curr = next;
- calcoffsets();
- }
- break;
- case XK_Tab:
- if (!sel)
- return;
- strncpy(text, sel->text, sizeof text - 1);
- text[sizeof text - 1] = '\0';
- cursor = strlen(text);
- match();
- break;
- }
-
-draw:
- drawmenu();
-}
-
-static void
-paste(void)
-{
- char *p, *q;
- int di;
- unsigned long dl;
- Atom da;
-
- /* we have been given the current selection, now insert it into input */
- if (XGetWindowProperty(dpy, win, utf8, 0, (sizeof text / 4) + 1, False,
- utf8, &da, &di, &dl, &dl, (unsigned char **)&p)
- == Success && p) {
- insert(p, (q = strchr(p, '\n')) ? q - p : (ssize_t)strlen(p));
- XFree(p);
- }
- drawmenu();
-}
-
-static void
-readstdin(void)
-{
- char buf[sizeof text], *p;
- size_t i, size = 0;
- if (passwd) {
- inputw = lines = 0;
- return;
- }
-
- /* read each line from stdin and add it to the item list */
- for (i = 0; fgets(buf, sizeof buf, stdin); i++) {
- if (i + 1 >= size / sizeof *items)
- if (!(items = realloc(items, (size += BUFSIZ))))
- die("cannot realloc %zu bytes:", size);
- if ((p = strchr(buf, '\n')))
- *p = '\0';
- if (!(items[i].text = strdup(buf)))
- die("cannot strdup %zu bytes:", strlen(buf) + 1);
- items[i].out = 0;
- }
- if (items)
- items[i].text = NULL;
- lines = MIN(lines, i);
-}
-
-void
-resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst)
-{
- char *sdst = NULL;
- int *idst = NULL;
- float *fdst = NULL;
- sdst = dst;
- idst = dst;
- fdst = dst;
- char fullname[256];
- char *type;
- XrmValue ret;
- snprintf(fullname, sizeof(fullname), "%s.%s", "dmenu", name);
- fullname[sizeof(fullname) - 1] = '\0';
- XrmGetResource(db, fullname, "*", &type, &ret);
- if (!(ret.addr == NULL || strncmp("String", type, 64)))
- {
- switch (rtype) {
- case STRING:
- strcpy(sdst, ret.addr);
- break;
- case INTEGER:
- *idst = strtoul(ret.addr, NULL, 10);
- break;
- case FLOAT:
- *fdst = strtof(ret.addr, NULL);
- break;
- }
- }
-}
-
-void
-load_xresources(void)
-{
- Display *display;
- char *resm;
- XrmDatabase db;
- ResourcePref *p;
- display = XOpenDisplay(NULL);
- resm = XResourceManagerString(display);
- if (!resm)
- return;
- db = XrmGetStringDatabase(resm);
- for (p = resources; p < resources + LENGTH(resources); p++)
- resource_load(db, p->name, p->type, p->dst);
- XCloseDisplay(display);
-}
-
-static void
-run(void)
-{
- XEvent ev;
- int i;
-
- while (!XNextEvent(dpy, &ev)) {
- if (preselected) {
- for (i = 0; i < preselected; i++) {
- if (sel && sel->right && (sel = sel->right) == next) {
- curr = next;
- calcoffsets();
- }
- }
- drawmenu();
- preselected = 0;
- }
- if (XFilterEvent(&ev, win))
- continue;
- switch(ev.type) {
- case DestroyNotify:
- if (ev.xdestroywindow.window != win)
- break;
- cleanup();
- exit(1);
- case Expose:
- if (ev.xexpose.count == 0)
- drw_map(drw, win, 0, 0, mw, mh);
- break;
- case FocusIn:
- /* regrab focus from parent window */
- if (ev.xfocus.window != win)
- grabfocus();
- break;
- case KeyPress:
- keypress(&ev.xkey);
- break;
- case SelectionNotify:
- if (ev.xselection.property == utf8)
- paste();
- break;
- case VisibilityNotify:
- if (ev.xvisibility.state != VisibilityUnobscured)
- XRaiseWindow(dpy, win);
- break;
- }
- }
-}
-
-static void
-setup(void)
-{
- int x, y, i, j;
- unsigned int du, tmp;
- XSetWindowAttributes swa;
- XIM xim;
- Window w, dw, *dws;
- XWindowAttributes wa;
- XClassHint ch = {"dmenu", "dmenu"};
- struct item *item;
-#ifdef XINERAMA
- XineramaScreenInfo *info;
- Window pw;
- int a, di, n, area = 0;
-#endif
- /* init appearance */
- for (j = 0; j < SchemeLast; j++)
- scheme[j] = drw_scm_create(drw, colors[j], alphas[j], 2);
-
- clip = XInternAtom(dpy, "CLIPBOARD", False);
- utf8 = XInternAtom(dpy, "UTF8_STRING", False);
-
- /* calculate menu geometry */
- bh = drw->fonts->h + 2;
- lines = MAX(lines, 0);
- mh = (lines + 1) * bh;
-#ifdef XINERAMA
- i = 0;
- if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) {
- XGetInputFocus(dpy, &w, &di);
- if (mon >= 0 && mon < n)
- i = mon;
- else if (w != root && w != PointerRoot && w != None) {
- /* find top-level window containing current input focus */
- do {
- if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws)
- XFree(dws);
- } while (w != root && w != pw);
- /* find xinerama screen with which the window intersects most */
- if (XGetWindowAttributes(dpy, pw, &wa))
- for (j = 0; j < n; j++)
- if ((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) {
- area = a;
- i = j;
- }
- }
- /* no focused window is on screen, so use pointer location instead */
- if (mon < 0 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du))
- for (i = 0; i < n; i++)
- if (INTERSECT(x, y, 1, 1, info[i]) != 0)
- break;
-
- x = info[i].x_org;
- y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
- mw = info[i].width;
-
- XFree(info);
- } else
-#endif
- {
- if (!XGetWindowAttributes(dpy, parentwin, &wa))
- die("could not get embedding window attributes: 0x%lx",
- parentwin);
- x = 0;
- y = topbar ? 0 : wa.height - mh;
- mw = wa.width;
- }
- promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
- for (item = items; item && item->text; ++item) {
- if ((tmp = textw_clamp(item->text, mw/3)) > inputw) {
- if ((inputw = tmp) == mw/3)
- break;
- }
- }
- match();
-
- /* create menu window */
- swa.override_redirect = True;
- swa.background_pixel = 0;
- swa.border_pixel = 0;
- swa.colormap = cmap;
- swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
- win = XCreateWindow(dpy, parentwin, x, y, mw - border_width * 2, mh, border_width,
- depth, CopyFromParent, visual,
- CWOverrideRedirect | CWBackPixel | CWBorderPixel | CWColormap | CWEventMask, &swa);
- if (border_width)
- XSetWindowBorder(dpy, win, scheme[SchemeSel][ColBg].pixel);
- XSetClassHint(dpy, win, &ch);
-
-
- /* input methods */
- if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL)
- die("XOpenIM failed: could not open input device");
-
- xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
- XNClientWindow, win, XNFocusWindow, win, NULL);
-
- XMapRaised(dpy, win);
- if (embed) {
- XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask);
- if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) {
- for (i = 0; i < du && dws[i] != win; ++i)
- XSelectInput(dpy, dws[i], FocusChangeMask);
- XFree(dws);
- }
- grabfocus();
- }
- drw_resize(drw, mw, mh);
- drawmenu();
-}
-
-static void
-usage(void)
-{
- fputs("usage: dmenu [-bfivP] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
- " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid] [-n number] [-bw number]\n", stderr);
- exit(1);
-}
-
-int
-main(int argc, char *argv[])
-{
- XWindowAttributes wa;
- int i, fast = 0;
-
- XrmInitialize();
- load_xresources();
-
- for (i = 1; i < argc; i++)
- /* these options take no arguments */
- if (!strcmp(argv[i], "-v")) { /* prints version information */
- puts("dmenu-"VERSION);
- exit(0);
- } else if (!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */
- topbar = 0;
- else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */
- fast = 1;
- else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
- fstrncmp = strncasecmp;
- fstrstr = cistrstr;
- } else if (!strcmp(argv[i], "-P")) /* is the input a password */
- passwd = 1;
- else if (i + 1 == argc)
- usage();
- /* these options take one argument */
- else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */
- lines = atoi(argv[++i]);
- else if (!strcmp(argv[i], "-m"))
- mon = atoi(argv[++i]);
- else if (!strcmp(argv[i], "-p")) /* adds prompt to left of input field */
- prompt = argv[++i];
- else if (!strcmp(argv[i], "-fn")) /* font or font set */
- fonts[0] = argv[++i];
- else if (!strcmp(argv[i], "-nb")) /* normal background color */
- colors[SchemeNorm][ColBg] = argv[++i];
- else if (!strcmp(argv[i], "-nf")) /* normal foreground color */
- colors[SchemeNorm][ColFg] = argv[++i];
- else if (!strcmp(argv[i], "-sb")) /* selected background color */
- colors[SchemeSel][ColBg] = argv[++i];
- else if (!strcmp(argv[i], "-sf")) /* selected foreground color */
- colors[SchemeSel][ColFg] = argv[++i];
- else if (!strcmp(argv[i], "-w")) /* embedding window id */
- embed = argv[++i];
- else if (!strcmp(argv[i], "-n")) /* preselected item */
- preselected = atoi(argv[++i]);
- else if (!strcmp(argv[i], "-bw"))
- border_width = atoi(argv[++i]); /* border width */
- else
- usage();
-
- if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
- fputs("warning: no locale support\n", stderr);
- if (!(dpy = XOpenDisplay(NULL)))
- die("cannot open display");
- screen = DefaultScreen(dpy);
- root = RootWindow(dpy, screen);
- if (!embed || !(parentwin = strtol(embed, NULL, 0)))
- parentwin = root;
- if (!XGetWindowAttributes(dpy, parentwin, &wa))
- die("could not get embedding window attributes: 0x%lx",
- parentwin);
- xinitvisual();
- drw = drw_create(dpy, screen, root, wa.width, wa.height, visual, depth, cmap);
- if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
- die("no fonts could be loaded.");
- lrpad = drw->fonts->h;
-
-#ifdef __OpenBSD__
- if (pledge("stdio rpath", NULL) == -1)
- die("pledge");
-#endif
-
- if (fast && !isatty(0)) {
- grabkeyboard();
- readstdin();
- } else {
- readstdin();
- grabkeyboard();
- }
- setup();
- run();
-
- return 1; /* unreachable */
-}
-
-void
-xinitvisual()
-{
- XVisualInfo *infos;
- XRenderPictFormat *fmt;
- int nitems;
- int i;
-
- XVisualInfo tpl = {
- .screen = screen,
- .depth = 32,
- .class = TrueColor
- };
- long masks = VisualScreenMask | VisualDepthMask | VisualClassMask;
-
- infos = XGetVisualInfo(dpy, masks, &tpl, &nitems);
- visual = NULL;
- for(i = 0; i < nitems; i ++) {
- fmt = XRenderFindVisualFormat(dpy, infos[i].visual);
- if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) {
- visual = infos[i].visual;
- depth = infos[i].depth;
- cmap = XCreateColormap(dpy, root, visual, AllocNone);
- useargb = 1;
- break;
- }
- }
-
- XFree(infos);
-
- if (! visual) {
- visual = DefaultVisual(dpy, screen);
- depth = DefaultDepth(dpy, screen);
- cmap = DefaultColormap(dpy, screen);
- }
-}
-
diff --git a/.local/src/dmenu/dmenu_path b/.local/src/dmenu/dmenu_path
@@ -1,13 +0,0 @@
-#!/bin/sh
-
-cachedir="${XDG_CACHE_HOME:-"$HOME/.cache"}"
-cache="$cachedir/dmenu_run"
-
-[ ! -e "$cachedir" ] && mkdir -p "$cachedir"
-
-IFS=:
-if stest -dqr -n "$cache" $PATH; then
- stest -flx $PATH | sort -u | tee "$cache"
-else
- cat "$cache"
-fi
diff --git a/.local/src/dmenu/dmenu_run b/.local/src/dmenu/dmenu_run
@@ -1,2 +0,0 @@
-#!/bin/sh
-dmenu_path | dmenu "$@" | ${SHELL:-"/bin/sh"} &
diff --git a/.local/src/dmenu/dmenu_run.hist b/.local/src/dmenu/dmenu_run.hist
@@ -1,50 +0,0 @@
-#!/bin/sh
-
-cachedir=${XDG_CACHE_HOME:-"$HOME/.cache"}
-if [ -d "$cachedir" ]; then
- cache=$cachedir/dmenu_run
- historyfile=$cachedir/dmenu_history
-else # if no xdg dir, fall back to dotfiles in ~
- cache=$HOME/.dmenu_cache
- historyfile=$HOME/.dmenu_history
-fi
-
-IFS=:
-if stest -dqr -n "$cache" $PATH; then
- stest -flx $PATH | sort -u > "$cache"
-fi
-unset IFS
-
-awk -v histfile=$historyfile '
- BEGIN {
- while( (getline < histfile) > 0 ) {
- sub("^[0-9]+\t","")
- print
- x[$0]=1
- }
- } !x[$0]++ ' "$cache" \
- | dmenu -i "$@" \
- | awk -v histfile=$historyfile '
- BEGIN {
- FS=OFS="\t"
- while ( (getline < histfile) > 0 ) {
- count=$1
- sub("^[0-9]+\t","")
- fname=$0
- history[fname]=count
- }
- close(histfile)
- }
-
- {
- history[$0]++
- print
- }
-
- END {
- if(!NR) exit
- for (f in history)
- print history[f],f | "sort -t '\t' -k1rn >" histfile
- }
- ' \
- | while read cmd; do ${SHELL:-"/bin/sh"} -c "$cmd" & done
diff --git a/.local/src/dmenu/drw.c b/.local/src/dmenu/drw.c
@@ -1,467 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <X11/Xlib.h>
-#include <X11/Xft/Xft.h>
-
-#include "drw.h"
-#include "util.h"
-
-#define UTF_INVALID 0xFFFD
-#define UTF_SIZ 4
-
-static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
-static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
-static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
-static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
-
-static long
-utf8decodebyte(const char c, size_t *i)
-{
- for (*i = 0; *i < (UTF_SIZ + 1); ++(*i))
- if (((unsigned char)c & utfmask[*i]) == utfbyte[*i])
- return (unsigned char)c & ~utfmask[*i];
- return 0;
-}
-
-static size_t
-utf8validate(long *u, size_t i)
-{
- if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
- *u = UTF_INVALID;
- for (i = 1; *u > utfmax[i]; ++i)
- ;
- return i;
-}
-
-static size_t
-utf8decode(const char *c, long *u, size_t clen)
-{
- size_t i, j, len, type;
- long udecoded;
-
- *u = UTF_INVALID;
- if (!clen)
- return 0;
- udecoded = utf8decodebyte(c[0], &len);
- if (!BETWEEN(len, 1, UTF_SIZ))
- return 1;
- for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
- udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type);
- if (type)
- return j;
- }
- if (j < len)
- return 0;
- *u = udecoded;
- utf8validate(u, len);
-
- return len;
-}
-
-Drw *
-drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap)
-{
- Drw *drw = ecalloc(1, sizeof(Drw));
-
- drw->dpy = dpy;
- drw->screen = screen;
- drw->root = root;
- drw->w = w;
- drw->h = h;
- drw->visual = visual;
- drw->depth = depth;
- drw->cmap = cmap;
- drw->drawable = XCreatePixmap(dpy, root, w, h, depth);
- drw->gc = XCreateGC(dpy, drw->drawable, 0, NULL);
- XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
-
- return drw;
-}
-
-void
-drw_resize(Drw *drw, unsigned int w, unsigned int h)
-{
- if (!drw)
- return;
-
- drw->w = w;
- drw->h = h;
- if (drw->drawable)
- XFreePixmap(drw->dpy, drw->drawable);
- drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, drw->depth);
-}
-
-void
-drw_free(Drw *drw)
-{
- XFreePixmap(drw->dpy, drw->drawable);
- XFreeGC(drw->dpy, drw->gc);
- drw_fontset_free(drw->fonts);
- free(drw);
-}
-
-/* This function is an implementation detail. Library users should use
- * drw_fontset_create instead.
- */
-static Fnt *
-xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
-{
- Fnt *font;
- XftFont *xfont = NULL;
- FcPattern *pattern = NULL;
-
- if (fontname) {
- /* Using the pattern found at font->xfont->pattern does not yield the
- * same substitution results as using the pattern returned by
- * FcNameParse; using the latter results in the desired fallback
- * behaviour whereas the former just results in missing-character
- * rectangles being drawn, at least with some fonts. */
- if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) {
- fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname);
- return NULL;
- }
- if (!(pattern = FcNameParse((FcChar8 *) fontname))) {
- fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname);
- XftFontClose(drw->dpy, xfont);
- return NULL;
- }
- } else if (fontpattern) {
- if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) {
- fprintf(stderr, "error, cannot load font from pattern.\n");
- return NULL;
- }
- } else {
- die("no font specified.");
- }
-
- /* Do not allow using color fonts. This is a workaround for a BadLength
- * error from Xft with color glyphs. Modelled on the Xterm workaround. See
- * https://bugzilla.redhat.com/show_bug.cgi?id=1498269
- * https://lists.suckless.org/dev/1701/30932.html
- * https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916349
- * and lots more all over the internet.
- */
- FcBool iscol;
- if(FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) {
- XftFontClose(drw->dpy, xfont);
- return NULL;
- }
-
- font = ecalloc(1, sizeof(Fnt));
- font->xfont = xfont;
- font->pattern = pattern;
- font->h = xfont->ascent + xfont->descent;
- font->dpy = drw->dpy;
-
- return font;
-}
-
-static void
-xfont_free(Fnt *font)
-{
- if (!font)
- return;
- if (font->pattern)
- FcPatternDestroy(font->pattern);
- XftFontClose(font->dpy, font->xfont);
- free(font);
-}
-
-Fnt*
-drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount)
-{
- Fnt *cur, *ret = NULL;
- size_t i;
-
- if (!drw || !fonts)
- return NULL;
-
- for (i = 1; i <= fontcount; i++) {
- if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) {
- cur->next = ret;
- ret = cur;
- }
- }
- return (drw->fonts = ret);
-}
-
-void
-drw_fontset_free(Fnt *font)
-{
- if (font) {
- drw_fontset_free(font->next);
- xfont_free(font);
- }
-}
-
-void
-drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha)
-{
- if (!drw || !dest || !clrname)
- return;
-
- if (!XftColorAllocName(drw->dpy, drw->visual, drw->cmap,
- clrname, dest))
- die("error, cannot allocate color '%s'", clrname);
-
- dest->pixel = (dest->pixel & 0x00ffffffU) | (alpha << 24);
-}
-
-/* Wrapper to create color schemes. The caller has to call free(3) on the
- * returned color scheme when done using it. */
-Clr *
-drw_scm_create(Drw *drw, char *clrnames[], const unsigned int alphas[], size_t clrcount)
-{
- size_t i;
- Clr *ret;
-
- /* need at least two colors for a scheme */
- if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor))))
- return NULL;
-
- for (i = 0; i < clrcount; i++)
- drw_clr_create(drw, &ret[i], clrnames[i], alphas[i]);
- return ret;
-}
-
-void
-drw_setfontset(Drw *drw, Fnt *set)
-{
- if (drw)
- drw->fonts = set;
-}
-
-void
-drw_setscheme(Drw *drw, Clr *scm)
-{
- if (drw)
- drw->scheme = scm;
-}
-
-void
-drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
-{
- if (!drw || !drw->scheme)
- return;
- XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel);
- if (filled)
- XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
- else
- XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
-}
-
-int
-drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
-{
- int i, ty, ellipsis_x = 0;
- unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len;
- XftDraw *d = NULL;
- Fnt *usedfont, *curfont, *nextfont;
- int utf8strlen, utf8charlen, render = x || y || w || h;
- long utf8codepoint = 0;
- const char *utf8str;
- FcCharSet *fccharset;
- FcPattern *fcpattern;
- FcPattern *match;
- XftResult result;
- int charexists = 0, overflow = 0;
- /* keep track of a couple codepoints for which we have no match. */
- enum { nomatches_len = 64 };
- static struct { long codepoint[nomatches_len]; unsigned int idx; } nomatches;
- static unsigned int ellipsis_width = 0;
-
- if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts)
- return 0;
-
- if (!render) {
- w = invert ? invert : ~invert;
- } else {
- XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
- XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
- d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap);
- x += lpad;
- w -= lpad;
- }
-
- usedfont = drw->fonts;
- if (!ellipsis_width && render)
- ellipsis_width = drw_fontset_getwidth(drw, "...");
- while (1) {
- ew = ellipsis_len = utf8strlen = 0;
- utf8str = text;
- nextfont = NULL;
- while (*text) {
- utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
- for (curfont = drw->fonts; curfont; curfont = curfont->next) {
- charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
- if (charexists) {
- drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL);
- if (ew + ellipsis_width <= w) {
- /* keep track where the ellipsis still fits */
- ellipsis_x = x + ew;
- ellipsis_w = w - ew;
- ellipsis_len = utf8strlen;
- }
-
- if (ew + tmpw > w) {
- overflow = 1;
- /* called from drw_fontset_getwidth_clamp():
- * it wants the width AFTER the overflow
- */
- if (!render)
- x += tmpw;
- else
- utf8strlen = ellipsis_len;
- } else if (curfont == usedfont) {
- utf8strlen += utf8charlen;
- text += utf8charlen;
- ew += tmpw;
- } else {
- nextfont = curfont;
- }
- break;
- }
- }
-
- if (overflow || !charexists || nextfont)
- break;
- else
- charexists = 0;
- }
-
- if (utf8strlen) {
- if (render) {
- ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
- XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
- usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen);
- }
- x += ew;
- w -= ew;
- }
- if (render && overflow)
- drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert);
-
- if (!*text || overflow) {
- break;
- } else if (nextfont) {
- charexists = 0;
- usedfont = nextfont;
- } else {
- /* Regardless of whether or not a fallback font is found, the
- * character must be drawn. */
- charexists = 1;
-
- for (i = 0; i < nomatches_len; ++i) {
- /* avoid calling XftFontMatch if we know we won't find a match */
- if (utf8codepoint == nomatches.codepoint[i])
- goto no_match;
- }
-
- fccharset = FcCharSetCreate();
- FcCharSetAddChar(fccharset, utf8codepoint);
-
- if (!drw->fonts->pattern) {
- /* Refer to the comment in xfont_create for more information. */
- die("the first font in the cache must be loaded from a font string.");
- }
-
- fcpattern = FcPatternDuplicate(drw->fonts->pattern);
- FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
- FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
- //FcPatternAddBool(fcpattern, FC_COLOR, FcFalse);
-
- FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
- FcDefaultSubstitute(fcpattern);
- match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result);
-
- FcCharSetDestroy(fccharset);
- FcPatternDestroy(fcpattern);
-
- if (match) {
- usedfont = xfont_create(drw, NULL, match);
- if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) {
- for (curfont = drw->fonts; curfont->next; curfont = curfont->next)
- ; /* NOP */
- curfont->next = usedfont;
- } else {
- xfont_free(usedfont);
- nomatches.codepoint[++nomatches.idx % nomatches_len] = utf8codepoint;
-no_match:
- usedfont = drw->fonts;
- }
- }
- }
- }
- if (d)
- XftDrawDestroy(d);
-
- return x + (render ? w : 0);
-}
-
-void
-drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
-{
- if (!drw)
- return;
-
- XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y);
- XSync(drw->dpy, False);
-}
-
-unsigned int
-drw_fontset_getwidth(Drw *drw, const char *text)
-{
- if (!drw || !drw->fonts || !text)
- return 0;
- return drw_text(drw, 0, 0, 0, 0, 0, text, 0);
-}
-
-unsigned int
-drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n)
-{
- unsigned int tmp = 0;
- if (drw && drw->fonts && text && n)
- tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n);
- return MIN(n, tmp);
-}
-
-void
-drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
-{
- XGlyphInfo ext;
-
- if (!font || !text)
- return;
-
- XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext);
- if (w)
- *w = ext.xOff;
- if (h)
- *h = font->h;
-}
-
-Cur *
-drw_cur_create(Drw *drw, int shape)
-{
- Cur *cur;
-
- if (!drw || !(cur = ecalloc(1, sizeof(Cur))))
- return NULL;
-
- cur->cursor = XCreateFontCursor(drw->dpy, shape);
-
- return cur;
-}
-
-void
-drw_cur_free(Drw *drw, Cur *cursor)
-{
- if (!cursor)
- return;
-
- XFreeCursor(drw->dpy, cursor->cursor);
- free(cursor);
-}
-
diff --git a/.local/src/dmenu/drw.h b/.local/src/dmenu/drw.h
@@ -1,62 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-
-typedef struct {
- Cursor cursor;
-} Cur;
-
-typedef struct Fnt {
- Display *dpy;
- unsigned int h;
- XftFont *xfont;
- FcPattern *pattern;
- struct Fnt *next;
-} Fnt;
-
-enum { ColFg, ColBg }; /* Clr scheme index */
-typedef XftColor Clr;
-
-typedef struct {
- unsigned int w, h;
- Display *dpy;
- int screen;
- Window root;
- Visual *visual;
- unsigned int depth;
- Colormap cmap;
- Drawable drawable;
- GC gc;
- Clr *scheme;
- Fnt *fonts;
-} Drw;
-
-/* Drawable abstraction */
-Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual*, unsigned int, Colormap);
-void drw_resize(Drw *drw, unsigned int w, unsigned int h);
-void drw_free(Drw *drw);
-
-/* Fnt abstraction */
-Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount);
-void drw_fontset_free(Fnt* set);
-unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
-unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n);
-void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
-
-/* Colorscheme abstraction */
-void drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha);
-Clr *drw_scm_create(Drw *drw, char *clrnames[], const unsigned int alphas[], size_t clrcount);
-
-/* Cursor abstraction */
-Cur *drw_cur_create(Drw *drw, int shape);
-void drw_cur_free(Drw *drw, Cur *cursor);
-
-/* Drawing context manipulation */
-void drw_setfontset(Drw *drw, Fnt *set);
-void drw_setscheme(Drw *drw, Clr *scm);
-
-/* Drawing functions */
-void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);
-int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert);
-
-/* Map functions */
-void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);
-
diff --git a/.local/src/dmenu/patches/dmenu-alpha-20210605-1a13d04.diff b/.local/src/dmenu/patches/dmenu-alpha-20210605-1a13d04.diff
@@ -1,267 +0,0 @@
-diff --git a/config.def.h b/config.def.h
-index 1edb647..697d511 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -2,6 +2,7 @@
- /* Default settings; can be overriden by command line. */
-
- static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
-+static const unsigned int alpha = 0xf0;
- /* -fn option overrides fonts[0]; default X11 font or font set */
- static const char *fonts[] = {
- "monospace:size=10"
-@@ -13,6 +14,13 @@ static const char *colors[SchemeLast][2] = {
- [SchemeSel] = { "#eeeeee", "#005577" },
- [SchemeOut] = { "#000000", "#00ffff" },
- };
-+
-+static const unsigned int alphas[SchemeLast][2] = {
-+ [SchemeNorm] = { OPAQUE, alpha },
-+ [SchemeSel] = { OPAQUE, alpha },
-+ [SchemeOut] = { OPAQUE, alpha },
-+};
-+
- /* -l option; if nonzero, dmenu uses vertical list with given number of lines */
- static unsigned int lines = 0;
-
-diff --git a/dmenu.c b/dmenu.c
-index 65f25ce..3e56e1a 100644
---- a/dmenu.c
-+++ b/dmenu.c
-@@ -10,6 +10,7 @@
-
- #include <X11/Xlib.h>
- #include <X11/Xatom.h>
-+#include <X11/Xproto.h>
- #include <X11/Xutil.h>
- #ifdef XINERAMA
- #include <X11/extensions/Xinerama.h>
-@@ -25,6 +26,8 @@
- #define LENGTH(X) (sizeof X / sizeof X[0])
- #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
-
-+#define OPAQUE 0xffU
-+
- /* enums */
- enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */
-
-@@ -53,10 +56,16 @@ static XIC xic;
- static Drw *drw;
- static Clr *scheme[SchemeLast];
-
-+static int useargb = 0;
-+static Visual *visual;
-+static int depth;
-+static Colormap cmap;
-+
- #include "config.h"
-
- static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
- static char *(*fstrstr)(const char *, const char *) = strstr;
-+static void xinitvisual();
-
- static void
- appenditem(struct item *item, struct item **list, struct item **last)
-@@ -602,7 +611,7 @@ setup(void)
- #endif
- /* init appearance */
- for (j = 0; j < SchemeLast; j++)
-- scheme[j] = drw_scm_create(drw, colors[j], 2);
-+ scheme[j] = drw_scm_create(drw, colors[j], alphas[i], 2);
-
- clip = XInternAtom(dpy, "CLIPBOARD", False);
- utf8 = XInternAtom(dpy, "UTF8_STRING", False);
-@@ -640,6 +649,7 @@ setup(void)
- x = info[i].x_org;
- y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
- mw = info[i].width;
-+
- XFree(info);
- } else
- #endif
-@@ -657,11 +667,13 @@ setup(void)
-
- /* create menu window */
- swa.override_redirect = True;
-- swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
-+ swa.background_pixel = 0;
-+ swa.border_pixel = 0;
-+ swa.colormap = cmap;
- swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
-- win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0,
-- CopyFromParent, CopyFromParent, CopyFromParent,
-- CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);
-+ win = XCreateWindow(dpy, parentwin, x, y, mw, mh, border_width,
-+ depth, CopyFromParent, visual,
-+ CWOverrideRedirect | CWBackPixel | CWBorderPixel | CWColormap | CWEventMask, &swa);
- XSetClassHint(dpy, win, &ch);
-
-
-@@ -747,7 +759,8 @@ main(int argc, char *argv[])
- if (!XGetWindowAttributes(dpy, parentwin, &wa))
- die("could not get embedding window attributes: 0x%lx",
- parentwin);
-- drw = drw_create(dpy, screen, root, wa.width, wa.height);
-+ xinitvisual();
-+ drw = drw_create(dpy, screen, root, wa.width, wa.height, visual, depth, cmap);
- if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
- die("no fonts could be loaded.");
- lrpad = drw->fonts->h;
-@@ -769,3 +782,40 @@ main(int argc, char *argv[])
-
- return 1; /* unreachable */
- }
-+
-+ void
-+xinitvisual()
-+{
-+ XVisualInfo *infos;
-+ XRenderPictFormat *fmt;
-+ int nitems;
-+ int i;
-+
-+ XVisualInfo tpl = {
-+ .screen = screen,
-+ .depth = 32,
-+ .class = TrueColor
-+ };
-+ long masks = VisualScreenMask | VisualDepthMask | VisualClassMask;
-+
-+ infos = XGetVisualInfo(dpy, masks, &tpl, &nitems);
-+ visual = NULL;
-+ for(i = 0; i < nitems; i ++) {
-+ fmt = XRenderFindVisualFormat(dpy, infos[i].visual);
-+ if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) {
-+ visual = infos[i].visual;
-+ depth = infos[i].depth;
-+ cmap = XCreateColormap(dpy, root, visual, AllocNone);
-+ useargb = 1;
-+ break;
-+ }
-+ }
-+
-+ XFree(infos);
-+
-+ if (! visual) {
-+ visual = DefaultVisual(dpy, screen);
-+ depth = DefaultDepth(dpy, screen);
-+ cmap = DefaultColormap(dpy, screen);
-+ }
-+}
-diff --git a/drw.c b/drw.c
-index 4cdbcbe..fe3aadd 100644
---- a/drw.c
-+++ b/drw.c
-@@ -61,7 +61,7 @@ utf8decode(const char *c, long *u, size_t clen)
- }
-
- Drw *
--drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
-+drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap)
- {
- Drw *drw = ecalloc(1, sizeof(Drw));
-
-@@ -70,8 +70,11 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h
- drw->root = root;
- drw->w = w;
- drw->h = h;
-- drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
-- drw->gc = XCreateGC(dpy, root, 0, NULL);
-+ drw->visual = visual;
-+ drw->depth = depth;
-+ drw->cmap = cmap;
-+ drw->drawable = XCreatePixmap(dpy, root, w, h, depth);
-+ drw->gc = XCreateGC(dpy, drw->drawable, 0, NULL);
- XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
-
- return drw;
-@@ -87,7 +90,7 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h)
- drw->h = h;
- if (drw->drawable)
- XFreePixmap(drw->dpy, drw->drawable);
-- drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
-+ drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, drw->depth);
- }
-
- void
-@@ -194,21 +197,22 @@ drw_fontset_free(Fnt *font)
- }
-
- void
--drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
-+drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha)
- {
- if (!drw || !dest || !clrname)
- return;
-
-- if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
-- DefaultColormap(drw->dpy, drw->screen),
-+ if (!XftColorAllocName(drw->dpy, drw->visual, drw->cmap,
- clrname, dest))
- die("error, cannot allocate color '%s'", clrname);
-+
-+ dest->pixel = (dest->pixel & 0x00ffffffU) | (alpha << 24);
- }
-
- /* Wrapper to create color schemes. The caller has to call free(3) on the
- * returned color scheme when done using it. */
- Clr *
--drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
-+drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount)
- {
- size_t i;
- Clr *ret;
-@@ -218,7 +222,7 @@ drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
- return NULL;
-
- for (i = 0; i < clrcount; i++)
-- drw_clr_create(drw, &ret[i], clrnames[i]);
-+ drw_clr_create(drw, &ret[i], clrnames[i], alphas[i]);
- return ret;
- }
-
-@@ -274,9 +278,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
- } else {
- XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
- XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
-- d = XftDrawCreate(drw->dpy, drw->drawable,
-- DefaultVisual(drw->dpy, drw->screen),
-- DefaultColormap(drw->dpy, drw->screen));
-+ d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap);
- x += lpad;
- w -= lpad;
- }
-diff --git a/drw.h b/drw.h
-index 4c67419..f6fa5cd 100644
---- a/drw.h
-+++ b/drw.h
-@@ -20,6 +20,9 @@ typedef struct {
- Display *dpy;
- int screen;
- Window root;
-+ Visual *visual;
-+ unsigned int depth;
-+ Colormap cmap;
- Drawable drawable;
- GC gc;
- Clr *scheme;
-@@ -27,7 +30,7 @@ typedef struct {
- } Drw;
-
- /* Drawable abstraction */
--Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
-+Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual*, unsigned int, Colormap);
- void drw_resize(Drw *drw, unsigned int w, unsigned int h);
- void drw_free(Drw *drw);
-
-@@ -38,8 +41,8 @@ unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
- void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
-
- /* Colorscheme abstraction */
--void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
--Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
-+void drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha);
-+Clr *drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount);
-
- /* Cursor abstraction */
- Cur *drw_cur_create(Drw *drw, int shape);
diff --git a/.local/src/dmenu/patches/dmenu-bidi-20210723-b34d318.diff b/.local/src/dmenu/patches/dmenu-bidi-20210723-b34d318.diff
@@ -1,109 +0,0 @@
-From b34d318bfed8557f2a1e53fc523b8ecff7c79374 Mon Sep 17 00:00:00 2001
-From: Eyal Seelig <[email protected]>
-Date: Fri, 23 Jul 2021 18:31:11 +0300
-Subject: [PATCH] Added support for RTL languages, such as Hebrew, Arabic, and
- Farsi, using the FriBiDi library
-
----
- config.mk | 8 ++++++--
- dmenu.c | 29 +++++++++++++++++++++++++++--
- 2 files changed, 33 insertions(+), 4 deletions(-)
-
-diff --git a/config.mk b/config.mk
-index 05d5a3e..eefd0ae 100644
---- a/config.mk
-+++ b/config.mk
-@@ -8,6 +8,8 @@ MANPREFIX = $(PREFIX)/share/man
- X11INC = /usr/X11R6/include
- X11LIB = /usr/X11R6/lib
-
-+BDINC = /usr/include/fribidi
-+
- # Xinerama, comment if you don't want it
- XINERAMALIBS = -lXinerama
- XINERAMAFLAGS = -DXINERAMA
-@@ -18,9 +20,11 @@ FREETYPEINC = /usr/include/freetype2
- # OpenBSD (uncomment)
- #FREETYPEINC = $(X11INC)/freetype2
-
-+BDLIBS = -lfribidi
-+
- # includes and libs
--INCS = -I$(X11INC) -I$(FREETYPEINC)
--LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS)
-+INCS = -I$(X11INC) -I$(FREETYPEINC) -I$(BDINC)
-+LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) $(BDLIBS)
-
- # flags
- CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS)
-diff --git a/dmenu.c b/dmenu.c
-index 65f25ce..389916b 100644
---- a/dmenu.c
-+++ b/dmenu.c
-@@ -16,6 +16,8 @@
- #endif
- #include <X11/Xft/Xft.h>
-
-+#include <fribidi.h>
-+
- #include "drw.h"
- #include "util.h"
-
-@@ -35,6 +37,7 @@ struct item {
- };
-
- static char text[BUFSIZ] = "";
-+static char fribidi_text[BUFSIZ] = "";
- static char *embed;
- static int bh, mw, mh;
- static int inputw = 0, promptw;
-@@ -113,6 +116,26 @@ cistrstr(const char *s, const char *sub)
- return NULL;
- }
-
-+static void
-+apply_fribidi(char *str)
-+{
-+ FriBidiStrIndex len = strlen(str);
-+ FriBidiChar logical[BUFSIZ];
-+ FriBidiChar visual[BUFSIZ];
-+ FriBidiParType base = FRIBIDI_PAR_ON;
-+ FriBidiCharSet charset;
-+ fribidi_boolean result;
-+
-+ fribidi_text[0] = 0;
-+ if (len>0)
-+ {
-+ charset = fribidi_parse_charset("UTF-8");
-+ len = fribidi_charset_to_unicode(charset, str, len, logical);
-+ result = fribidi_log2vis(logical, len, &base, visual, NULL, NULL, NULL);
-+ len = fribidi_unicode_to_charset(charset, visual, len, fribidi_text);
-+ }
-+}
-+
- static int
- drawitem(struct item *item, int x, int y, int w)
- {
-@@ -123,7 +146,8 @@ drawitem(struct item *item, int x, int y, int w)
- else
- drw_setscheme(drw, scheme[SchemeNorm]);
-
-- return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0);
-+ apply_fribidi(item->text);
-+ return drw_text(drw, x, y, w, bh, lrpad / 2, fribidi_text, 0);
- }
-
- static void
-@@ -143,7 +167,8 @@ drawmenu(void)
- /* draw input field */
- w = (lines > 0 || !matches) ? mw - x : inputw;
- drw_setscheme(drw, scheme[SchemeNorm]);
-- drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0);
-+ apply_fribidi(text);
-+ drw_text(drw, x, 0, w, bh, lrpad / 2, fribidi_text, 0);
-
- curpos = TEXTW(text) - TEXTW(&text[cursor]);
- if ((curpos += lrpad / 2 - 1) < w) {
---
-2.32.0
-
diff --git a/.local/src/dmenu/patches/dmenu-highlight-20201211-fcdc159.diff b/.local/src/dmenu/patches/dmenu-highlight-20201211-fcdc159.diff
@@ -1,97 +0,0 @@
-From fcdc1593ed418166f20b7e691a49b1e6eefc116e Mon Sep 17 00:00:00 2001
-From: Nathaniel Evan <[email protected]>
-Date: Fri, 11 Dec 2020 11:08:12 +0700
-Subject: [PATCH] Highlight matched text in a different color scheme
-
----
- config.def.h | 3 +++
- dmenu.c | 44 +++++++++++++++++++++++++++++++++++++++++---
- 2 files changed, 44 insertions(+), 3 deletions(-)
-
-diff --git a/config.def.h b/config.def.h
-index 1edb647..79be73a 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -11,7 +11,10 @@ static const char *colors[SchemeLast][2] = {
- /* fg bg */
- [SchemeNorm] = { "#bbbbbb", "#222222" },
- [SchemeSel] = { "#eeeeee", "#005577" },
-+ [SchemeSelHighlight] = { "#ffc978", "#005577" },
-+ [SchemeNormHighlight] = { "#ffc978", "#222222" },
- [SchemeOut] = { "#000000", "#00ffff" },
-+ [SchemeOutHighlight] = { "#ffc978", "#00ffff" },
- };
- /* -l option; if nonzero, dmenu uses vertical list with given number of lines */
- static unsigned int lines = 0;
-diff --git a/dmenu.c b/dmenu.c
-index 65f25ce..cce1ad1 100644
---- a/dmenu.c
-+++ b/dmenu.c
-@@ -26,8 +26,7 @@
- #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
-
- /* enums */
--enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */
--
-+enum { SchemeNorm, SchemeSel, SchemeOut, SchemeNormHighlight, SchemeSelHighlight, SchemeOutHighlight, SchemeLast }; /* color schemes */
- struct item {
- char *text;
- struct item *left, *right;
-@@ -113,6 +112,43 @@ cistrstr(const char *s, const char *sub)
- return NULL;
- }
-
-+static void
-+drawhighlights(struct item *item, int x, int y, int maxw)
-+{
-+ char restorechar, tokens[sizeof text], *highlight, *token;
-+ int indentx, highlightlen;
-+
-+ drw_setscheme(drw, scheme[item == sel ? SchemeSelHighlight : item->out ? SchemeOutHighlight : SchemeNormHighlight]);
-+ strcpy(tokens, text);
-+ for (token = strtok(tokens, " "); token; token = strtok(NULL, " ")) {
-+ highlight = fstrstr(item->text, token);
-+ while (highlight) {
-+ // Move item str end, calc width for highlight indent, & restore
-+ highlightlen = highlight - item->text;
-+ restorechar = *highlight;
-+ item->text[highlightlen] = '\0';
-+ indentx = TEXTW(item->text);
-+ item->text[highlightlen] = restorechar;
-+
-+ // Move highlight str end, draw highlight, & restore
-+ restorechar = highlight[strlen(token)];
-+ highlight[strlen(token)] = '\0';
-+ if (indentx - (lrpad / 2) - 1 < maxw)
-+ drw_text(
-+ drw,
-+ x + indentx - (lrpad / 2) - 1,
-+ y,
-+ MIN(maxw - indentx, TEXTW(highlight) - lrpad),
-+ bh, 0, highlight, 0
-+ );
-+ highlight[strlen(token)] = restorechar;
-+
-+ if (strlen(highlight) - strlen(token) < strlen(token)) break;
-+ highlight = fstrstr(highlight + strlen(token), token);
-+ }
-+ }
-+}
-+
- static int
- drawitem(struct item *item, int x, int y, int w)
- {
-@@ -123,7 +159,9 @@ drawitem(struct item *item, int x, int y, int w)
- else
- drw_setscheme(drw, scheme[SchemeNorm]);
-
-- return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0);
-+ int r = drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0);
-+ drawhighlights(item, x, y, w);
-+ return r;
- }
-
- static void
---
-2.29.2
-
diff --git a/.local/src/dmenu/patches/dmenu-linesbelowprompt-and-fullwidth-20211014.diff b/.local/src/dmenu/patches/dmenu-linesbelowprompt-and-fullwidth-20211014.diff
@@ -1,25 +0,0 @@
-From 98e63311c4816fb3c7f5c5d00232fec3232465f3 Mon Sep 17 00:00:00 2001
-From: Sebastian LaVine <[email protected]>
-Date: Sat, 3 Jul 2021 17:35:50 -0400
-Subject: [PATCH] Draw lines immediately below prompt
-
----
- dmenu.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/dmenu.c b/dmenu.c
-index 65f25ce..5a041a6 100644
---- a/dmenu.c
-+++ b/dmenu.c
-@@ -154,7 +154,7 @@ drawmenu(void)
- if (lines > 0) {
- /* draw vertical list */
- for (item = curr; item != next; item = item->right)
-- drawitem(item, x, y += bh, mw - x);
-+ drawitem(item, x - promptw, y += bh, mw);
- } else if (matches) {
- /* draw horizontal list */
- x += inputw;
---
-2.32.0
-
diff --git a/.local/src/dmenu/patches/dmenu-password-5.0.diff b/.local/src/dmenu/patches/dmenu-password-5.0.diff
@@ -1,103 +0,0 @@
-From c4de1032bd4c247bc20b6ab92a10a8d778966679 Mon Sep 17 00:00:00 2001
-From: Mehrad Mahmoudian <[email protected]>
-Date: Tue, 4 May 2021 12:05:09 +0300
-Subject: [PATCH] patched with password patch
-
----
- dmenu.1 | 5 ++++-
- dmenu.c | 21 +++++++++++++++++----
- 2 files changed, 21 insertions(+), 5 deletions(-)
-
-diff --git a/dmenu.1 b/dmenu.1
-index 323f93c..762f707 100644
---- a/dmenu.1
-+++ b/dmenu.1
-@@ -3,7 +3,7 @@
- dmenu \- dynamic menu
- .SH SYNOPSIS
- .B dmenu
--.RB [ \-bfiv ]
-+.RB [ \-bfivP ]
- .RB [ \-l
- .IR lines ]
- .RB [ \-m
-@@ -47,6 +47,9 @@ is faster, but will lock up X until stdin reaches end\-of\-file.
- .B \-i
- dmenu matches menu items case insensitively.
- .TP
-+.B \-P
-+dmenu will not directly display the keyboard input, but instead replace it with dots. All data from stdin will be ignored.
-+.TP
- .BI \-l " lines"
- dmenu lists items vertically, with the given number of lines.
- .TP
-diff --git a/dmenu.c b/dmenu.c
-index 65f25ce..ad8f63b 100644
---- a/dmenu.c
-+++ b/dmenu.c
-@@ -37,7 +37,7 @@ struct item {
- static char text[BUFSIZ] = "";
- static char *embed;
- static int bh, mw, mh;
--static int inputw = 0, promptw;
-+static int inputw = 0, promptw, passwd = 0;
- static int lrpad; /* sum of left and right padding */
- static size_t cursor;
- static struct item *items = NULL;
-@@ -132,6 +132,7 @@ drawmenu(void)
- unsigned int curpos;
- struct item *item;
- int x = 0, y = 0, w;
-+ char *censort;
-
- drw_setscheme(drw, scheme[SchemeNorm]);
- drw_rect(drw, 0, 0, mw, mh, 1, 1);
-@@ -143,7 +144,12 @@ drawmenu(void)
- /* draw input field */
- w = (lines > 0 || !matches) ? mw - x : inputw;
- drw_setscheme(drw, scheme[SchemeNorm]);
-- drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0);
-+ if (passwd) {
-+ censort = ecalloc(1, sizeof(text));
-+ memset(censort, '.', strlen(text));
-+ drw_text(drw, x, 0, w, bh, lrpad / 2, censort, 0);
-+ free(censort);
-+ } else drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0);
-
- curpos = TEXTW(text) - TEXTW(&text[cursor]);
- if ((curpos += lrpad / 2 - 1) < w) {
-@@ -524,6 +530,11 @@ readstdin(void)
- char buf[sizeof text], *p;
- size_t i, imax = 0, size = 0;
- unsigned int tmpmax = 0;
-+ if(passwd){
-+ inputw = lines = 0;
-+ return;
-+ }
-+
-
- /* read each line from stdin and add it to the item list */
- for (i = 0; fgets(buf, sizeof buf, stdin); i++) {
-@@ -689,7 +700,7 @@ setup(void)
- static void
- usage(void)
- {
-- fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
-+ fputs("usage: dmenu [-bfivP] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
- " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr);
- exit(1);
- }
-@@ -712,7 +723,9 @@ main(int argc, char *argv[])
- else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
- fstrncmp = strncasecmp;
- fstrstr = cistrstr;
-- } else if (i + 1 == argc)
-+ } else if (!strcmp(argv[i], "-P")) /* is the input a password */
-+ passwd = 1;
-+ else if (i + 1 == argc)
- usage();
- /* these options take one argument */
- else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */
---
-2.31.1
-
diff --git a/.local/src/dmenu/patches/dmenu-preselect-20200513-db6093f.diff b/.local/src/dmenu/patches/dmenu-preselect-20200513-db6093f.diff
@@ -1,90 +0,0 @@
-From 055e86dee88c5135b3d3a691942a915334d1b3a2 Mon Sep 17 00:00:00 2001
-From: Mathieu Moneyron <[email protected]>
-Date: Wed, 13 May 2020 17:28:37 +0200
-Subject: [PATCH] Added option to preselect an item by providing a number
-
----
- config.def.h | 3 +++
- dmenu.1 | 5 +++++
- dmenu.c | 15 ++++++++++++++-
- 3 files changed, 22 insertions(+), 1 deletion(-)
-
-diff --git a/config.def.h b/config.def.h
-index 1edb647..95bee59 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -21,3 +21,6 @@ static unsigned int lines = 0;
- * for example: " /?\"&[]"
- */
- static const char worddelimiters[] = " ";
-+
-+/* -n option; preselected item starting from 0 */
-+static unsigned int preselected = 0;
-diff --git a/dmenu.1 b/dmenu.1
-index 323f93c..6e1ee7f 100644
---- a/dmenu.1
-+++ b/dmenu.1
-@@ -22,6 +22,8 @@ dmenu \- dynamic menu
- .IR color ]
- .RB [ \-w
- .IR windowid ]
-+.RB [ \-n
-+.IR number ]
- .P
- .BR dmenu_run " ..."
- .SH DESCRIPTION
-@@ -80,6 +82,9 @@ prints version information to stdout, then exits.
- .TP
- .BI \-w " windowid"
- embed into windowid.
-+.TP
-+.BI \-n " number"
-+preseslected item starting from 0.
- .SH USAGE
- dmenu is completely controlled by the keyboard. Items are selected using the
- arrow keys, page up, page down, home, and end.
-diff --git a/dmenu.c b/dmenu.c
-index 65f25ce..0a02609 100644
---- a/dmenu.c
-+++ b/dmenu.c
-@@ -551,8 +551,19 @@ static void
- run(void)
- {
- XEvent ev;
-+ int i;
-
- while (!XNextEvent(dpy, &ev)) {
-+ if (preselected) {
-+ for (i = 0; i < preselected; i++) {
-+ if (sel && sel->right && (sel = sel->right) == next) {
-+ curr = next;
-+ calcoffsets();
-+ }
-+ }
-+ drawmenu();
-+ preselected = 0;
-+ }
- if (XFilterEvent(&ev, win))
- continue;
- switch(ev.type) {
-@@ -690,7 +701,7 @@ static void
- usage(void)
- {
- fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
-- " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr);
-+ " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid] [-n number]\n", stderr);
- exit(1);
- }
-
-@@ -733,6 +744,8 @@ main(int argc, char *argv[])
- colors[SchemeSel][ColFg] = argv[++i];
- else if (!strcmp(argv[i], "-w")) /* embedding window id */
- embed = argv[++i];
-+ else if (!strcmp(argv[i], "-n")) /* preselected item */
-+ preselected = atoi(argv[++i]);
- else
- usage();
-
---
-2.26.2
-
diff --git a/.local/src/dmenu/patches/dmenu-xresources-alt-5.0.diff b/.local/src/dmenu/patches/dmenu-xresources-alt-5.0.diff
@@ -1,182 +0,0 @@
-diff -rupN orig/config.def.h patched/config.def.h
---- orig/config.def.h 2021-04-16 06:30:47.713924755 +0300
-+++ patched/config.def.h 2021-04-16 06:34:14.956933252 +0300
-@@ -2,16 +2,25 @@
- /* Default settings; can be overriden by command line. */
-
- static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
-+
- /* -fn option overrides fonts[0]; default X11 font or font set */
-+static char font[] = "monospace:size=10";
- static const char *fonts[] = {
-- "monospace:size=10"
-+ font,
-+ "monospace:size=10",
- };
--static const char *prompt = NULL; /* -p option; prompt to the left of input field */
--static const char *colors[SchemeLast][2] = {
-+
-+static char *prompt = NULL; /* -p option; prompt to the left of input field */
-+
-+static char normfgcolor[] = "#bbbbbb";
-+static char normbgcolor[] = "#222222";
-+static char selfgcolor[] = "#eeeeee";
-+static char selbgcolor[] = "#005577";
-+static char *colors[SchemeLast][2] = {
- /* fg bg */
-- [SchemeNorm] = { "#bbbbbb", "#222222" },
-- [SchemeSel] = { "#eeeeee", "#005577" },
-- [SchemeOut] = { "#000000", "#00ffff" },
-+ [SchemeNorm] = { normfgcolor, normbgcolor },
-+ [SchemeSel] = { selfgcolor, selbgcolor },
-+ [SchemeOut] = { "#000000", "#00ffff" },
- };
- /* -l option; if nonzero, dmenu uses vertical list with given number of lines */
- static unsigned int lines = 0;
-@@ -21,3 +30,15 @@ static unsigned int lines = 0;
- * for example: " /?\"&[]"
- */
- static const char worddelimiters[] = " ";
-+
-+/*
-+ * Xresources preferences to load at startup
-+ */
-+ResourcePref resources[] = {
-+ { "font", STRING, &font },
-+ { "normfgcolor", STRING, &normfgcolor },
-+ { "normbgcolor", STRING, &normbgcolor },
-+ { "selfgcolor", STRING, &selfgcolor },
-+ { "selbgcolor", STRING, &selbgcolor },
-+ { "prompt", STRING, &prompt },
-+};
-diff -rupN orig/dmenu.c patched/dmenu.c
---- orig/dmenu.c 2021-04-16 06:30:47.715924755 +0300
-+++ patched/dmenu.c 2021-04-16 06:30:59.668925245 +0300
-@@ -11,6 +11,7 @@
- #include <X11/Xlib.h>
- #include <X11/Xatom.h>
- #include <X11/Xutil.h>
-+#include <X11/Xresource.h>
- #ifdef XINERAMA
- #include <X11/extensions/Xinerama.h>
- #endif
-@@ -53,6 +54,21 @@ static XIC xic;
- static Drw *drw;
- static Clr *scheme[SchemeLast];
-
-+/* Xresources preferences */
-+enum resource_type {
-+ STRING = 0,
-+ INTEGER = 1,
-+ FLOAT = 2
-+};
-+typedef struct {
-+ char *name;
-+ enum resource_type type;
-+ void *dst;
-+} ResourcePref;
-+
-+static void load_xresources(void);
-+static void resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst);
-+
- #include "config.h"
-
- static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
-@@ -395,7 +411,7 @@ keypress(XKeyEvent *ev)
-
- switch(ksym) {
- default:
--insert:
-+ insert:
- if (!iscntrl(*buf))
- insert(buf, len);
- break;
-@@ -547,6 +563,54 @@ readstdin(void)
- lines = MIN(lines, i);
- }
-
-+void
-+resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst)
-+{
-+ char *sdst = NULL;
-+ int *idst = NULL;
-+ float *fdst = NULL;
-+ sdst = dst;
-+ idst = dst;
-+ fdst = dst;
-+ char fullname[256];
-+ char *type;
-+ XrmValue ret;
-+ snprintf(fullname, sizeof(fullname), "%s.%s", "dmenu", name);
-+ fullname[sizeof(fullname) - 1] = '\0';
-+ XrmGetResource(db, fullname, "*", &type, &ret);
-+ if (!(ret.addr == NULL || strncmp("String", type, 64)))
-+ {
-+ switch (rtype) {
-+ case STRING:
-+ strcpy(sdst, ret.addr);
-+ break;
-+ case INTEGER:
-+ *idst = strtoul(ret.addr, NULL, 10);
-+ break;
-+ case FLOAT:
-+ *fdst = strtof(ret.addr, NULL);
-+ break;
-+ }
-+ }
-+}
-+
-+void
-+load_xresources(void)
-+{
-+ Display *display;
-+ char *resm;
-+ XrmDatabase db;
-+ ResourcePref *p;
-+ display = XOpenDisplay(NULL);
-+ resm = XResourceManagerString(display);
-+ if (!resm)
-+ return;
-+ db = XrmGetStringDatabase(resm);
-+ for (p = resources; p < resources + LENGTH(resources); p++)
-+ resource_load(db, p->name, p->type, p->dst);
-+ XCloseDisplay(display);
-+}
-+
- static void
- run(void)
- {
-@@ -700,6 +764,9 @@ main(int argc, char *argv[])
- XWindowAttributes wa;
- int i, fast = 0;
-
-+ XrmInitialize();
-+ load_xresources();
-+
- for (i = 1; i < argc; i++)
- /* these options take no arguments */
- if (!strcmp(argv[i], "-v")) { /* prints version information */
-diff -rupN orig/drw.c patched/drw.c
---- orig/drw.c 2021-04-16 06:30:47.718924755 +0300
-+++ patched/drw.c 2021-04-16 06:30:59.670925245 +0300
-@@ -208,7 +208,7 @@ drw_clr_create(Drw *drw, Clr *dest, cons
- /* Wrapper to create color schemes. The caller has to call free(3) on the
- * returned color scheme when done using it. */
- Clr *
--drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
-+drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount)
- {
- size_t i;
- Clr *ret;
-diff -rupN orig/drw.h patched/drw.h
---- orig/drw.h 2021-04-16 06:30:47.718924755 +0300
-+++ patched/drw.h 2021-04-16 06:30:59.671925245 +0300
-@@ -39,7 +39,7 @@ void drw_font_getexts(Fnt *font, const c
-
- /* Colorscheme abstraction */
- void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
--Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
-+Clr *drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount);
-
- /* Cursor abstraction */
- Cur *drw_cur_create(Drw *drw, int shape);
diff --git a/.local/src/dmenu/stest.1 b/.local/src/dmenu/stest.1
@@ -1,90 +0,0 @@
-.TH STEST 1 dmenu\-VERSION
-.SH NAME
-stest \- filter a list of files by properties
-.SH SYNOPSIS
-.B stest
-.RB [ -abcdefghlpqrsuwx ]
-.RB [ -n
-.IR file ]
-.RB [ -o
-.IR file ]
-.RI [ file ...]
-.SH DESCRIPTION
-.B stest
-takes a list of files and filters by the files' properties, analogous to
-.IR test (1).
-Files which pass all tests are printed to stdout. If no files are given, stest
-reads files from stdin.
-.SH OPTIONS
-.TP
-.B \-a
-Test hidden files.
-.TP
-.B \-b
-Test that files are block specials.
-.TP
-.B \-c
-Test that files are character specials.
-.TP
-.B \-d
-Test that files are directories.
-.TP
-.B \-e
-Test that files exist.
-.TP
-.B \-f
-Test that files are regular files.
-.TP
-.B \-g
-Test that files have their set-group-ID flag set.
-.TP
-.B \-h
-Test that files are symbolic links.
-.TP
-.B \-l
-Test the contents of a directory given as an argument.
-.TP
-.BI \-n " file"
-Test that files are newer than
-.IR file .
-.TP
-.BI \-o " file"
-Test that files are older than
-.IR file .
-.TP
-.B \-p
-Test that files are named pipes.
-.TP
-.B \-q
-No files are printed, only the exit status is returned.
-.TP
-.B \-r
-Test that files are readable.
-.TP
-.B \-s
-Test that files are not empty.
-.TP
-.B \-u
-Test that files have their set-user-ID flag set.
-.TP
-.B \-v
-Invert the sense of tests, only failing files pass.
-.TP
-.B \-w
-Test that files are writable.
-.TP
-.B \-x
-Test that files are executable.
-.SH EXIT STATUS
-.TP
-.B 0
-At least one file passed all tests.
-.TP
-.B 1
-No files passed all tests.
-.TP
-.B 2
-An error occurred.
-.SH SEE ALSO
-.IR dmenu (1),
-.IR test (1)
diff --git a/.local/src/dmenu/stest.c b/.local/src/dmenu/stest.c
@@ -1,109 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <sys/stat.h>
-
-#include <dirent.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "arg.h"
-char *argv0;
-
-#define FLAG(x) (flag[(x)-'a'])
-
-static void test(const char *, const char *);
-static void usage(void);
-
-static int match = 0;
-static int flag[26];
-static struct stat old, new;
-
-static void
-test(const char *path, const char *name)
-{
- struct stat st, ln;
-
- if ((!stat(path, &st) && (FLAG('a') || name[0] != '.') /* hidden files */
- && (!FLAG('b') || S_ISBLK(st.st_mode)) /* block special */
- && (!FLAG('c') || S_ISCHR(st.st_mode)) /* character special */
- && (!FLAG('d') || S_ISDIR(st.st_mode)) /* directory */
- && (!FLAG('e') || access(path, F_OK) == 0) /* exists */
- && (!FLAG('f') || S_ISREG(st.st_mode)) /* regular file */
- && (!FLAG('g') || st.st_mode & S_ISGID) /* set-group-id flag */
- && (!FLAG('h') || (!lstat(path, &ln) && S_ISLNK(ln.st_mode))) /* symbolic link */
- && (!FLAG('n') || st.st_mtime > new.st_mtime) /* newer than file */
- && (!FLAG('o') || st.st_mtime < old.st_mtime) /* older than file */
- && (!FLAG('p') || S_ISFIFO(st.st_mode)) /* named pipe */
- && (!FLAG('r') || access(path, R_OK) == 0) /* readable */
- && (!FLAG('s') || st.st_size > 0) /* not empty */
- && (!FLAG('u') || st.st_mode & S_ISUID) /* set-user-id flag */
- && (!FLAG('w') || access(path, W_OK) == 0) /* writable */
- && (!FLAG('x') || access(path, X_OK) == 0)) != FLAG('v')) { /* executable */
- if (FLAG('q'))
- exit(0);
- match = 1;
- puts(name);
- }
-}
-
-static void
-usage(void)
-{
- fprintf(stderr, "usage: %s [-abcdefghlpqrsuvwx] "
- "[-n file] [-o file] [file...]\n", argv0);
- exit(2); /* like test(1) return > 1 on error */
-}
-
-int
-main(int argc, char *argv[])
-{
- struct dirent *d;
- char path[PATH_MAX], *line = NULL, *file;
- size_t linesiz = 0;
- ssize_t n;
- DIR *dir;
- int r;
-
- ARGBEGIN {
- case 'n': /* newer than file */
- case 'o': /* older than file */
- file = EARGF(usage());
- if (!(FLAG(ARGC()) = !stat(file, (ARGC() == 'n' ? &new : &old))))
- perror(file);
- break;
- default:
- /* miscellaneous operators */
- if (strchr("abcdefghlpqrsuvwx", ARGC()))
- FLAG(ARGC()) = 1;
- else
- usage(); /* unknown flag */
- } ARGEND;
-
- if (!argc) {
- /* read list from stdin */
- while ((n = getline(&line, &linesiz, stdin)) > 0) {
- if (line[n - 1] == '\n')
- line[n - 1] = '\0';
- test(line, line);
- }
- free(line);
- } else {
- for (; argc; argc--, argv++) {
- if (FLAG('l') && (dir = opendir(*argv))) {
- /* test directory contents */
- while ((d = readdir(dir))) {
- r = snprintf(path, sizeof path, "%s/%s",
- *argv, d->d_name);
- if (r >= 0 && (size_t)r < sizeof path)
- test(path, d->d_name);
- }
- closedir(dir);
- } else {
- test(*argv, *argv);
- }
- }
- }
- return match ? 0 : 1;
-}
diff --git a/.local/src/dmenu/util.c b/.local/src/dmenu/util.c
@@ -1,35 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "util.h"
-
-void *
-ecalloc(size_t nmemb, size_t size)
-{
- void *p;
-
- if (!(p = calloc(nmemb, size)))
- die("calloc:");
- return p;
-}
-
-void
-die(const char *fmt, ...) {
- va_list ap;
-
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
-
- if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
- fputc(' ', stderr);
- perror(NULL);
- } else {
- fputc('\n', stderr);
- }
-
- exit(1);
-}
diff --git a/.local/src/dmenu/util.h b/.local/src/dmenu/util.h
@@ -1,8 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-
-#define MAX(A, B) ((A) > (B) ? (A) : (B))
-#define MIN(A, B) ((A) < (B) ? (A) : (B))
-#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
-
-void die(const char *fmt, ...);
-void *ecalloc(size_t nmemb, size_t size);
diff --git a/.local/src/dwm/LICENSE b/.local/src/dwm/LICENSE
@@ -1,37 +0,0 @@
-MIT/X Consortium License
-
-© 2006-2019 Anselm R Garbe <[email protected]>
-© 2006-2009 Jukka Salmi <jukka at salmi dot ch>
-© 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
-© 2007-2011 Peter Hartlich <sgkkr at hartlich dot com>
-© 2007-2009 Szabolcs Nagy <nszabolcs at gmail dot com>
-© 2007-2009 Christof Musik <christof at sendfax dot de>
-© 2007-2009 Premysl Hruby <dfenze at gmail dot com>
-© 2007-2008 Enno Gottox Boland <gottox at s01 dot de>
-© 2008 Martin Hurton <martin dot hurton at gmail dot com>
-© 2008 Neale Pickett <neale dot woozle dot org>
-© 2009 Mate Nagy <mnagy at port70 dot net>
-© 2010-2016 Hiltjo Posthuma <[email protected]>
-© 2010-2012 Connor Lane Smith <[email protected]>
-© 2011 Christoph Lohmann <[email protected]>
-© 2015-2016 Quentin Rameau <[email protected]>
-© 2015-2016 Eric Pruitt <[email protected]>
-© 2016-2017 Markus Teich <[email protected]>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/.local/src/dwm/Makefile b/.local/src/dwm/Makefile
@@ -1,51 +0,0 @@
-# dwm - dynamic window manager
-# See LICENSE file for copyright and license details.
-
-include config.mk
-
-SRC = drw.c dwm.c util.c
-OBJ = ${SRC:.c=.o}
-
-all: options dwm
-
-options:
- @echo dwm build options:
- @echo "CFLAGS = ${CFLAGS}"
- @echo "LDFLAGS = ${LDFLAGS}"
- @echo "CC = ${CC}"
-
-.c.o:
- ${CC} -c ${CFLAGS} $<
-
-${OBJ}: config.h config.mk
-
-config.h:
- cp config.def.h $@
-
-dwm: ${OBJ}
- ${CC} -o $@ ${OBJ} ${LDFLAGS}
-
-clean:
- rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz
-
-dist: clean
- mkdir -p dwm-${VERSION}
- cp -R LICENSE Makefile README config.def.h config.h config.mk\
- dwm.1 drw.h util.h ${SRC} dwm.png transient.c dwm-${VERSION}
- tar -cf dwm-${VERSION}.tar dwm-${VERSION}
- gzip dwm-${VERSION}.tar
- rm -rf dwm-${VERSION}
-
-install: all
- mkdir -p ${DESTDIR}${PREFIX}/bin
- cp -f dwm ${DESTDIR}${PREFIX}/bin
- chmod 755 ${DESTDIR}${PREFIX}/bin/dwm
- mkdir -p ${DESTDIR}${MANPREFIX}/man1
- sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1
- chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1
-
-uninstall:
- rm -f ${DESTDIR}${PREFIX}/bin/dwm\
- ${DESTDIR}${MANPREFIX}/man1/dwm.1
-
-.PHONY: all options clean dist install uninstall
diff --git a/.local/src/dwm/README b/.local/src/dwm/README
@@ -1,48 +0,0 @@
-dwm - dynamic window manager
-============================
-dwm is an extremely fast, small, and dynamic window manager for X.
-
-
-Requirements
-------------
-In order to build dwm you need the Xlib header files.
-
-
-Installation
-------------
-Edit config.mk to match your local setup (dwm is installed into
-the /usr/local namespace by default).
-
-Afterwards enter the following command to build and install dwm (if
-necessary as root):
-
- make clean install
-
-
-Running dwm
------------
-Add the following line to your .xinitrc to start dwm using startx:
-
- exec dwm
-
-In order to connect dwm to a specific display, make sure that
-the DISPLAY environment variable is set correctly, e.g.:
-
- DISPLAY=foo.bar:1 exec dwm
-
-(This will start dwm on display :1 of the host foo.bar.)
-
-In order to display status info in the bar, you can do something
-like this in your .xinitrc:
-
- while xsetroot -name "`date` `uptime | sed 's/.*,//'`"
- do
- sleep 1
- done &
- exec dwm
-
-
-Configuration
--------------
-The configuration of dwm is done by creating a custom config.h
-and (re)compiling the source code.
diff --git a/.local/src/dwm/config.h b/.local/src/dwm/config.h
@@ -1,303 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-
-/* Load essentials */
-#include <X11/XF86keysym.h> /* For XF86 multimedia binds */
-
-/* System Tray */
-static const int showsystray = 0; /* 0 means no systray */
-static const unsigned int systraypadding= 1; /* systray vertical padding */
-static const unsigned int systrayspacing= 2; /* systray spacing */
-static const unsigned int systrayonleft = 0; /* 0: systray in the right corner, 1: systray on left of status text */
-
-static const unsigned int systraypinning= 1; /* 0: sloppy systray follows selected monitor, 1: pin systray to monitor X */
-static const int systraypinningfailfirst= 1; /* 1: if pinning fails, display systray on the first monitor, 0: display systray on the last monitor*/
-
-/* appearance */
-static const char *fonts[] = { "monospace:size=9", "Vazirmatn:size=9" };
-static const unsigned int borderpx = 0; /* border pixel of windows */
-static const unsigned int gappx = 10; /* gaps between windows */
-static const unsigned int snap = 32; /* snap pixel */
-static const int showbar = 1; /* 0 means no bar */
-static const int topbar = 1; /* 0 means bottom bar */
-static const int barheight = 3; /* Spacing around the bar's font */
-static const int hidevacanttags = 1; /* 1 means hide empty tags / 0: show every tag */
-static const int hidetagindicator = 1; /* 1 means hide default top-left square-shaped tag indicator */
-static const int showtitle = 0; /* 1 means show WM_NAME of the currently selected window */
-static const int truecenteredtitle = 0; /* 1 means center the WM_NAME on the status bar */
-static const unsigned int colorfultag = 0; /* 0 means use SchemeSel for selected tag */
-static char fgcolor[] = "#D8DEE9";
-static char bgcolor[] = "#2E3440";
-static char color0[] = "#3B4252";
-static char color1[] = "#BF616A";
-static char color2[] = "#A3BE8C";
-static char color3[] = "#EBCB8B";
-static char color4[] = "#81A1C1";
-static char color5[] = "#B48EAD";
-static char color6[] = "#88C0D0";
-static char color7[] = "#E5E9F0";
-static char color8[] = "#4C566A";
-static char color9[] = "#BF616A";
-static char color10[] = "#A3BE8C";
-static char color11[] = "#EBCB8B";
-static char color12[] = "#81A1C1";
-static char color13[] = "#B48EAD";
-static char color14[] = "#8FBCBB";
-static char color15[] = "#ECEFF4";
-
-/*
- * Xresources preferences to load at startup
- */
-ResourcePref resources[] = {
- { "foreground", STRING, &fgcolor},
- { "background", STRING, &bgcolor},
- { "color0", STRING, &color0},
- { "color1", STRING, &color1},
- { "color2", STRING, &color2},
- { "color3", STRING, &color3},
- { "color4", STRING, &color4},
- { "color5", STRING, &color5},
- { "color6", STRING, &color6},
- { "color7", STRING, &color7},
- { "color8", STRING, &color8},
- { "color9", STRING, &color9},
- { "color10", STRING, &color10},
- { "color11", STRING, &color11},
- { "color12", STRING, &color12},
- { "color13", STRING, &color13},
- { "color14", STRING, &color14},
- { "color15", STRING, &color15},
-};
-
-static const char *colors[][3] = {
- /* fg bg border */
- [SchemeNorm] = { color12, color0, color8 },
- [SchemeSel] = { color0, color12, color12 },
- [SchemeLayout] = { color12, color0, color8 },
-};
-
-/* if colorfultag == 1: */
-static const char *colortags[][2] = {
- { color1, color0 },
- { color2, color0 },
- { color3, color0 },
- { color4, color0 },
- { color5, color0 },
- { color6, color0 },
- { color9, color0 },
- { color10, color0 },
- { color11, color0 },
-};
-//static const char *colortags_sel[][2] = {
-// { color1, color8 },
-// { color2, color8 },
-// { color3, color8 },
-// { color4, color8 },
-// { color5, color8 },
-// { color6, color8 },
-// { color9, color8 },
-// { color10, color8 },
-// { color11, color8 },
-//};
-static const char *colortags_sel[][2] = {
- { color0, color1 },
- { color0, color2 },
- { color0, color3 },
- { color0, color4 },
- { color0, color5 },
- { color0, color6 },
- { color0, color9 },
- { color0, color10 },
- { color0, color11 },
-};
-
-/* tagging */
-//static const char *tags[] = { "𐎠", "𐎡", "𐎢", "𐎣", "𐎤", "𐎥", "𐎦", "𐎧", "𐎨" };
-static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
-
-static const Rule rules[] = {
- /* xprop(1):
- * WM_CLASS(STRING) = instance, class
- * WM_NAME(STRING) = title
- */
- /* class instance title tags mask isfloating monitor */
- //{ "mpv", NULL, NULL, 0, 1, -1 },
- //{ "Gimp", NULL, NULL, 0, 1, -1 },
- //{ "Firefox", NULL, NULL, 1 << 8, 0, -1 },
- { "st-float", NULL, NULL, 0, 1, -1 },
- { NULL, "st-float", NULL, 0, 1, -1 },
- { NULL, NULL, "Event Tester", 0, 0, -1 }, /* xev */
-};
-
-/* layout(s) */
-static const float mfact = 0.5; /* factor of master area size [0.05..0.95] */
-static const int nmaster = 1; /* number of clients in master area */
-static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
-static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
-static int layouts_default = 0; /* Default layout */
-static const int layouts_floating = 2;/* Layout number for floating mode */
-
-//static const Layout layouts[] = {
-// /* symbol arrange function */
-// { "Tile", tile }, /* first entry is default */
-// { "Monocle", monocle },
-// { "Float", NULL }, /* no layout function means floating behavior */
-// { NULL, NULL },
-//};
-
-static const Layout layouts[] = {
- /* symbol arrange function */
- { "[]=", tile }, /* first entry is default */
- { "[M]", monocle },
- { "><>", NULL }, /* no layout function means floating behavior */
- { NULL, NULL },
-};
-
-/* key definitions */
-#define MODKEY Mod4Mask
-#define ALTMOD Mod1Mask
-#define TAGKEYS(KEY,TAG) \
- { MODKEY, KEY, view, {.ui = 1 << TAG} }, \
- { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
- { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
- { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, \
- { ALTMOD, KEY, focusnthmon, {.i = TAG } }, \
- { ALTMOD|ShiftMask, KEY, tagnthmon, {.i = TAG } },
-
-/* helper for spawning shell commands in the pre dwm-5.0 fashion */
-#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
-
-/* commands */
-static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
-static const char *dmenucmd[] = { "dmenu_run", "-i", "-p", "Run:", NULL };
-//static const char *termcmd[] = { "st", NULL };
-//static const char *termcmdfloat[] = { "st", "-c", "st-float", NULL };
-static const char *termcmd[] = { "tabbed", "-cd", "-r", "2", "st", "-w", "''", NULL };
-static const char *termcmdfloat[] = { "tabbed", "-cd", "-n", "st-float", "-r", "2", "st", "-w", "''", NULL };
-
-static Key keys[] = {
- /* modifier key function argument */
- { MODKEY, XK_a, spawn, SHCMD("dmenu_drun") },
- { MODKEY, XK_c, spawn, {.v = dmenucmd } },
- { MODKEY, XK_Return, spawn, {.v = termcmd } },
- { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmdfloat } },
- { MODKEY, XK_b, togglebar, {0} },
- { MODKEY, XK_j, focusstack, {.i = +1 } },
- { MODKEY, XK_k, focusstack, {.i = -1 } },
- { MODKEY, XK_i, incnmaster, {.i = +1 } },
- { MODKEY, XK_d, incnmaster, {.i = -1 } },
- { MODKEY, XK_h, setmfact, {.f = -0.05} },
- { MODKEY, XK_l, setmfact, {.f = +0.05} },
- { MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } },
- { MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } },
- { MODKEY, XK_space, zoom, {0} },
- { MODKEY, XK_Tab, view, {0} },
- { MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
- { MODKEY, XK_m, setlayout, {.v = &layouts[1]} },
- { MODKEY, XK_f, setlayout, {.v = &layouts[2]} },
- { MODKEY|ControlMask, XK_comma, cyclelayout, {.i = -1 } },
- { MODKEY|ControlMask, XK_period, cyclelayout, {.i = +1 } },
- { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
- { MODKEY|ShiftMask, XK_f, togglefullscr, {0} },
- { MODKEY, XK_s, togglesticky, {0} },
- { MODKEY, XK_0, view, {.ui = ~0 } },
- { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
- { MODKEY, XK_comma, focusmon, {.i = -1 } },
- { MODKEY, XK_period, focusmon, {.i = +1 } },
- { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
- { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
- { MODKEY, XK_minus, setgaps, {.i = -1 } },
- { MODKEY, XK_equal, setgaps, {.i = +1 } },
- { MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } },
- { MODKEY|ControlMask, XK_minus, shiftview, {.i = -1 } },
- { MODKEY|ControlMask, XK_equal, shiftview, {.i = +1 } },
- TAGKEYS( XK_1, 0)
- TAGKEYS( XK_2, 1)
- TAGKEYS( XK_3, 2)
- TAGKEYS( XK_4, 3)
- TAGKEYS( XK_5, 4)
- TAGKEYS( XK_6, 5)
- TAGKEYS( XK_7, 6)
- TAGKEYS( XK_8, 7)
- TAGKEYS( XK_9, 8)
- { MODKEY, XK_F5, live_reload_xresources,{0} },
- { MODKEY|ShiftMask, XK_r, restart, {0} },
- { MODKEY, XK_q, killclient, {0} },
- { MODKEY|ControlMask, XK_q, quit, {0} },
- { MODKEY|ShiftMask, XK_b, spawn, SHCMD("dwm-bar -M") },
- { MODKEY|ShiftMask, XK_q, spawn, SHCMD("dmenu-power") },
- { MODKEY, XK_r, spawn, SHCMD("dmenu-record") },
- { MODKEY, XK_w, spawn, SHCMD("surf-open") },
- { MODKEY|ControlMask, XK_w, spawn, SHCMD("surf") },
- { MODKEY|ShiftMask, XK_e, spawn, SHCMD("st -e sh -c \"mutt\"") },
- { MODKEY|ShiftMask, XK_m, spawn, SHCMD("dmenu-man") },
- { MODKEY|ShiftMask, XK_w, spawn, SHCMD("st -c \"st-float\" -g \"100x20\" -e sh -c \"SET_BG_SELECT=1 bg-set\"") },
- { MODKEY|ShiftMask, XK_u, spawn, SHCMD("st -c \"st-float\" -g \"100x28\" -e sh -c \"doas pacman -Syu --noconfirm && rm ~/.cache/pkg_updates\"") },
- { MODKEY|ShiftMask, XK_t, spawn, SHCMD("theme-sel -s") },
- { MODKEY|ShiftMask, XK_g, spawn, SHCMD("gtt") },
- { MODKEY|ShiftMask, XK_y, spawn, SHCMD("myt -d") },
- { MODKEY|ControlMask, XK_l, spawn, SHCMD("slock") },
- { MODKEY, XK_grave, spawn, SHCMD("dmenu-emoji insert") },
- { ControlMask, XK_grave, spawn, SHCMD("dmenu-emoji clipboard") },
- { 0, XK_Print, spawn, SHCMD("screenshot -xc") },
- { ShiftMask, XK_Print, spawn, SHCMD("screenshot -xc -t 5") },
- { ControlMask, XK_Print, spawn, SHCMD("screenshot -xc -s yes") },
- { ControlMask|ShiftMask, XK_Print, spawn, SHCMD("screenshot -xc -s yes -t 5") },
-
- { MODKEY, XK_F11, spawn, SHCMD("bright -d") },
- { MODKEY, XK_F12, spawn, SHCMD("bright -i") },
-
- { 0, XF86XK_WebCam, spawn, SHCMD("webcam") },
- { 0, XF86XK_TouchpadToggle, spawn, SHCMD("toggle-touch") },
- { 0, XF86XK_TouchpadOn, spawn, SHCMD("toggle-touch") },
- { 0, XF86XK_TouchpadOff, spawn, SHCMD("toggle-touch") },
- { 0, XF86XK_AudioPlay, spawn, SHCMD("media-controller toggle") },
- { 0, XF86XK_AudioPause, spawn, SHCMD("media-controller toggle") },
- { 0, XF86XK_AudioNext, spawn, SHCMD("media-controller next") },
- { 0, XF86XK_AudioPrev, spawn, SHCMD("media-controller prev") },
- { ShiftMask, XF86XK_AudioPlay, spawn, SHCMD("media-controller pause-all") },
- { ShiftMask, XF86XK_AudioPause, spawn, SHCMD("media-controller pause-all") },
- { ShiftMask, XF86XK_AudioNext, spawn, SHCMD("media-controller seek-fwd") },
- { ShiftMask, XF86XK_AudioPrev, spawn, SHCMD("media-controller seek-bwd") },
- { 0, XF86XK_MonBrightnessUp, spawn, SHCMD("bright -i") },
- { 0, XF86XK_MonBrightnessDown, spawn, SHCMD("bright -d") },
- { 0, XF86XK_AudioRaiseVolume, spawn, SHCMD("volume -i") },
- { 0, XF86XK_AudioLowerVolume, spawn, SHCMD("volume -d") },
- { 0, XF86XK_AudioMute, spawn, SHCMD("volume -m") },
- { ShiftMask, XF86XK_AudioRaiseVolume, spawn, SHCMD("volume -I") },
- { ShiftMask, XF86XK_AudioLowerVolume, spawn, SHCMD("volume -D") },
- { ShiftMask, XF86XK_AudioMute, spawn, SHCMD("volume -M") },
- { 0, XF86XK_AudioMicMute, spawn, SHCMD("volume -M") },
-};
-
-/* button definitions */
-/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
-static Button buttons[] = {
- /* click event mask button function argument */
- /* placemouse options, choose which feels more natural:
- * 0 - tiled position is relative to mouse cursor
- * 1 - tiled postiion is relative to window center
- * 2 - mouse pointer warps to window center
- *
- * The moveorplace uses movemouse or placemouse depending on the floating state
- * of the selected client. Set up individual keybindings for the two if you want
- * to control these separately (i.e. to retain the feature to move a tiled window
- * into a floating position).
- */
- { ClkClientWin, MODKEY, Button1, moveorplace, {.i = 1} },
- { ClkClientWin, MODKEY, Button3, resizemouse, {0} },
- { ClkClientWin, MODKEY, Button2, togglefloating, {0} },
- { ClkTagBar, 0, Button1, view, {0} },
- { ClkTagBar, 0, Button3, toggleview, {0} },
- { ClkTagBar, MODKEY, Button1, tag, {0} },
- { ClkTagBar, MODKEY, Button3, toggletag, {0} },
- { ClkTagBar, 0, Button4, shiftview, {.i = -1} },
- { ClkTagBar, 0, Button5, shiftview, {.i = +1} },
- { ClkLtSymbol, 0, Button1, cyclelayout, {.i = +1} },
- { ClkLtSymbol, 0, Button3, cyclelayout, {.i = -1} },
- { ClkLtSymbol, 0, Button2, setlayout, {.v = &layouts[0]} },
- { ClkLtSymbol, 0, Button4, cyclelayout, {.i = -1} },
- { ClkLtSymbol, 0, Button5, cyclelayout, {.i = +1} },
- { ClkWinTitle, 0, Button2, togglesticky, {0} },
- { ClkStatusText, 0, Button3, spawn, SHCMD("dwm-bar -M") },
-};
-
diff --git a/.local/src/dwm/config.mk b/.local/src/dwm/config.mk
@@ -1,42 +0,0 @@
-# dwm version
-VERSION = 6.3
-
-# Customize below to fit your system
-
-# paths
-PREFIX = /usr/local
-MANPREFIX = ${PREFIX}/share/man
-
-X11INC = /usr/X11R6/include
-X11LIB = /usr/X11R6/lib
-
-BDINC = /usr/include/fribidi
-
-# Xinerama, comment if you don't want it
-XINERAMALIBS = -lXinerama
-XINERAMAFLAGS = -DXINERAMA
-
-# freetype
-FREETYPELIBS = -lfontconfig -lXft
-FREETYPEINC = /usr/include/freetype2
-# OpenBSD (uncomment)
-#FREETYPEINC = ${X11INC}/freetype2
-
-BDLIBS = -lfribidi
-
-# includes and libs
-INCS = -I${X11INC} -I${FREETYPEINC} -I$(BDINC)
-LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} $(BDLIBS)
-
-# flags
-CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
-#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
-CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS}
-LDFLAGS = ${LIBS}
-
-# Solaris
-#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
-#LDFLAGS = ${LIBS}
-
-# compiler and linker
-CC = cc
diff --git a/.local/src/dwm/drw.c b/.local/src/dwm/drw.c
@@ -1,437 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <X11/Xlib.h>
-#include <X11/Xft/Xft.h>
-
-#include "drw.h"
-#include "util.h"
-
-#define UTF_INVALID 0xFFFD
-#define UTF_SIZ 4
-
-static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
-static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
-static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
-static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
-
-static long
-utf8decodebyte(const char c, size_t *i)
-{
- for (*i = 0; *i < (UTF_SIZ + 1); ++(*i))
- if (((unsigned char)c & utfmask[*i]) == utfbyte[*i])
- return (unsigned char)c & ~utfmask[*i];
- return 0;
-}
-
-static size_t
-utf8validate(long *u, size_t i)
-{
- if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
- *u = UTF_INVALID;
- for (i = 1; *u > utfmax[i]; ++i)
- ;
- return i;
-}
-
-static size_t
-utf8decode(const char *c, long *u, size_t clen)
-{
- size_t i, j, len, type;
- long udecoded;
-
- *u = UTF_INVALID;
- if (!clen)
- return 0;
- udecoded = utf8decodebyte(c[0], &len);
- if (!BETWEEN(len, 1, UTF_SIZ))
- return 1;
- for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
- udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type);
- if (type)
- return j;
- }
- if (j < len)
- return 0;
- *u = udecoded;
- utf8validate(u, len);
-
- return len;
-}
-
-Drw *
-drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
-{
- Drw *drw = ecalloc(1, sizeof(Drw));
-
- drw->dpy = dpy;
- drw->screen = screen;
- drw->root = root;
- drw->w = w;
- drw->h = h;
- drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
- drw->gc = XCreateGC(dpy, root, 0, NULL);
- XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
-
- return drw;
-}
-
-void
-drw_resize(Drw *drw, unsigned int w, unsigned int h)
-{
- if (!drw)
- return;
-
- drw->w = w;
- drw->h = h;
- if (drw->drawable)
- XFreePixmap(drw->dpy, drw->drawable);
- drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
-}
-
-void
-drw_free(Drw *drw)
-{
- XFreePixmap(drw->dpy, drw->drawable);
- XFreeGC(drw->dpy, drw->gc);
- drw_fontset_free(drw->fonts);
- free(drw);
-}
-
-/* This function is an implementation detail. Library users should use
- * drw_fontset_create instead.
- */
-static Fnt *
-xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
-{
- Fnt *font;
- XftFont *xfont = NULL;
- FcPattern *pattern = NULL;
-
- if (fontname) {
- /* Using the pattern found at font->xfont->pattern does not yield the
- * same substitution results as using the pattern returned by
- * FcNameParse; using the latter results in the desired fallback
- * behaviour whereas the former just results in missing-character
- * rectangles being drawn, at least with some fonts. */
- if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) {
- fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname);
- return NULL;
- }
- if (!(pattern = FcNameParse((FcChar8 *) fontname))) {
- fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname);
- XftFontClose(drw->dpy, xfont);
- return NULL;
- }
- } else if (fontpattern) {
- if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) {
- fprintf(stderr, "error, cannot load font from pattern.\n");
- return NULL;
- }
- } else {
- die("no font specified.");
- }
-
- /* Do not allow using color fonts. This is a workaround for a BadLength
- * error from Xft with color glyphs. Modelled on the Xterm workaround. See
- * https://bugzilla.redhat.com/show_bug.cgi?id=1498269
- * https://lists.suckless.org/dev/1701/30932.html
- * https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916349
- * and lots more all over the internet.
- */
- FcBool iscol;
- if(FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) {
- XftFontClose(drw->dpy, xfont);
- return NULL;
- }
-
- font = ecalloc(1, sizeof(Fnt));
- font->xfont = xfont;
- font->pattern = pattern;
- font->h = xfont->ascent + xfont->descent;
- font->dpy = drw->dpy;
-
- return font;
-}
-
-static void
-xfont_free(Fnt *font)
-{
- if (!font)
- return;
- if (font->pattern)
- FcPatternDestroy(font->pattern);
- XftFontClose(font->dpy, font->xfont);
- free(font);
-}
-
-Fnt*
-drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount)
-{
- Fnt *cur, *ret = NULL;
- size_t i;
-
- if (!drw || !fonts)
- return NULL;
-
- for (i = 1; i <= fontcount; i++) {
- if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) {
- cur->next = ret;
- ret = cur;
- }
- }
- return (drw->fonts = ret);
-}
-
-void
-drw_fontset_free(Fnt *font)
-{
- if (font) {
- drw_fontset_free(font->next);
- xfont_free(font);
- }
-}
-
-void
-drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
-{
- if (!drw || !dest || !clrname)
- return;
-
- if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
- DefaultColormap(drw->dpy, drw->screen),
- clrname, dest))
- die("error, cannot allocate color '%s'", clrname);
-}
-
-/* Wrapper to create color schemes. The caller has to call free(3) on the
- * returned color scheme when done using it. */
-Clr *
-drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
-{
- size_t i;
- Clr *ret;
-
- /* need at least two colors for a scheme */
- if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor))))
- return NULL;
-
- for (i = 0; i < clrcount; i++)
- drw_clr_create(drw, &ret[i], clrnames[i]);
- return ret;
-}
-
-void
-drw_setfontset(Drw *drw, Fnt *set)
-{
- if (drw)
- drw->fonts = set;
-}
-
-void
-drw_setscheme(Drw *drw, Clr *scm)
-{
- if (drw)
- drw->scheme = scm;
-}
-
-void
-drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
-{
- if (!drw || !drw->scheme)
- return;
- XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel);
- if (filled)
- XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
- else
- XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
-}
-
-int
-drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
-{
- char buf[1024];
- int ty;
- unsigned int ew;
- XftDraw *d = NULL;
- Fnt *usedfont, *curfont, *nextfont;
- size_t i, len;
- int utf8strlen, utf8charlen, render = x || y || w || h;
- long utf8codepoint = 0;
- const char *utf8str;
- FcCharSet *fccharset;
- FcPattern *fcpattern;
- FcPattern *match;
- XftResult result;
- int charexists = 0;
-
- if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
- return 0;
-
- if (!render) {
- w = ~w;
- } else {
- XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
- XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
- d = XftDrawCreate(drw->dpy, drw->drawable,
- DefaultVisual(drw->dpy, drw->screen),
- DefaultColormap(drw->dpy, drw->screen));
- x += lpad;
- w -= lpad;
- }
-
- usedfont = drw->fonts;
- while (1) {
- utf8strlen = 0;
- utf8str = text;
- nextfont = NULL;
- while (*text) {
- utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
- for (curfont = drw->fonts; curfont; curfont = curfont->next) {
- charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
- if (charexists) {
- if (curfont == usedfont) {
- utf8strlen += utf8charlen;
- text += utf8charlen;
- } else {
- nextfont = curfont;
- }
- break;
- }
- }
-
- if (!charexists || nextfont)
- break;
- else
- charexists = 0;
- }
-
- if (utf8strlen) {
- drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL);
- /* shorten text if necessary */
- for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--)
- drw_font_getexts(usedfont, utf8str, len, &ew, NULL);
-
- if (len) {
- memcpy(buf, utf8str, len);
- buf[len] = '\0';
- if (len < utf8strlen)
- for (i = len; i && i > len - 3; buf[--i] = '.')
- ; /* NOP */
-
- if (render) {
- ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
- XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
- usedfont->xfont, x, ty, (XftChar8 *)buf, len);
- }
- x += ew;
- w -= ew;
- }
- }
-
- if (!*text) {
- break;
- } else if (nextfont) {
- charexists = 0;
- usedfont = nextfont;
- } else {
- /* Regardless of whether or not a fallback font is found, the
- * character must be drawn. */
- charexists = 1;
-
- fccharset = FcCharSetCreate();
- FcCharSetAddChar(fccharset, utf8codepoint);
-
- if (!drw->fonts->pattern) {
- /* Refer to the comment in xfont_create for more information. */
- die("the first font in the cache must be loaded from a font string.");
- }
-
- fcpattern = FcPatternDuplicate(drw->fonts->pattern);
- FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
- FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
- FcPatternAddBool(fcpattern, FC_COLOR, FcFalse);
-
- FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
- FcDefaultSubstitute(fcpattern);
- match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result);
-
- FcCharSetDestroy(fccharset);
- FcPatternDestroy(fcpattern);
-
- if (match) {
- usedfont = xfont_create(drw, NULL, match);
- if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) {
- for (curfont = drw->fonts; curfont->next; curfont = curfont->next)
- ; /* NOP */
- curfont->next = usedfont;
- } else {
- xfont_free(usedfont);
- usedfont = drw->fonts;
- }
- }
- }
- }
- if (d)
- XftDrawDestroy(d);
-
- return x + (render ? w : 0);
-}
-
-void
-drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
-{
- if (!drw)
- return;
-
- XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y);
- XSync(drw->dpy, False);
-}
-
-unsigned int
-drw_fontset_getwidth(Drw *drw, const char *text)
-{
- if (!drw || !drw->fonts || !text)
- return 0;
- return drw_text(drw, 0, 0, 0, 0, 0, text, 0);
-}
-
-void
-drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
-{
- XGlyphInfo ext;
-
- if (!font || !text)
- return;
-
- XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext);
- if (w)
- *w = ext.xOff;
- if (h)
- *h = font->h;
-}
-
-Cur *
-drw_cur_create(Drw *drw, int shape)
-{
- Cur *cur;
-
- if (!drw || !(cur = ecalloc(1, sizeof(Cur))))
- return NULL;
-
- cur->cursor = XCreateFontCursor(drw->dpy, shape);
-
- return cur;
-}
-
-void
-drw_cur_free(Drw *drw, Cur *cursor)
-{
- if (!cursor)
- return;
-
- XFreeCursor(drw->dpy, cursor->cursor);
- free(cursor);
-}
-
diff --git a/.local/src/dwm/drw.h b/.local/src/dwm/drw.h
@@ -1,57 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-
-typedef struct {
- Cursor cursor;
-} Cur;
-
-typedef struct Fnt {
- Display *dpy;
- unsigned int h;
- XftFont *xfont;
- FcPattern *pattern;
- struct Fnt *next;
-} Fnt;
-
-enum { ColFg, ColBg, ColBorder }; /* Clr scheme index */
-typedef XftColor Clr;
-
-typedef struct {
- unsigned int w, h;
- Display *dpy;
- int screen;
- Window root;
- Drawable drawable;
- GC gc;
- Clr *scheme;
- Fnt *fonts;
-} Drw;
-
-/* Drawable abstraction */
-Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
-void drw_resize(Drw *drw, unsigned int w, unsigned int h);
-void drw_free(Drw *drw);
-
-/* Fnt abstraction */
-Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount);
-void drw_fontset_free(Fnt* set);
-unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
-void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
-
-/* Colorscheme abstraction */
-void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
-Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
-
-/* Cursor abstraction */
-Cur *drw_cur_create(Drw *drw, int shape);
-void drw_cur_free(Drw *drw, Cur *cursor);
-
-/* Drawing context manipulation */
-void drw_setfontset(Drw *drw, Fnt *set);
-void drw_setscheme(Drw *drw, Clr *scm);
-
-/* Drawing functions */
-void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);
-int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert);
-
-/* Map functions */
-void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);
diff --git a/.local/src/dwm/dwm.1 b/.local/src/dwm/dwm.1
@@ -1,205 +0,0 @@
-.TH DWM 1 dwm\-VERSION
-.SH NAME
-dwm \- dynamic window manager
-.SH SYNOPSIS
-.B dwm
-.RB [ \-v ]
-.SH DESCRIPTION
-dwm is a dynamic window manager for X. It manages windows in tiled, monocle
-and floating layouts. Either layout can be applied dynamically, optimising the
-environment for the application in use and the task performed.
-.P
-In tiled layouts windows are managed in a master and stacking area. The master
-area on the left contains one window by default, and the stacking area on the
-right contains all other windows. The number of master area windows can be
-adjusted from zero to an arbitrary number. In monocle layout all windows are
-maximised to the screen size. In floating layout windows can be resized and
-moved freely. Dialog windows are always managed floating, regardless of the
-layout applied.
-.P
-Windows are grouped by tags. Each window can be tagged with one or multiple
-tags. Selecting certain tags displays all windows with these tags.
-.P
-Each screen contains a small status bar which displays all available tags, the
-layout, the title of the focused window, and the text read from the root window
-name property, if the screen is focused. A floating window is indicated with an
-empty square and a maximised floating window is indicated with a filled square
-before the windows title. The selected tags are indicated with a different
-color. The tags of the focused window are indicated with a filled square in the
-top left corner. The tags which are applied to one or more windows are
-indicated with an empty square in the top left corner.
-.P
-dwm draws a small border around windows to indicate the focus state.
-.SH OPTIONS
-.TP
-.B \-v
-prints version information to stderr, then exits.
-.SH USAGE
-.SS Status bar
-.TP
-.B X root window name
-is read and displayed in the status text area. It can be set with the
-.BR xsetroot (1)
-command.
-.TP
-.B Button1
-click on a tag label to display all windows with that tag, click on the layout
-label toggles between tiled and floating layout.
-.TP
-.B Button3
-click on a tag label adds/removes all windows with that tag to/from the view.
-.TP
-.B Mod4\-Button1
-click on a tag label applies that tag to the focused window.
-.TP
-.B Mod4\-Button3
-click on a tag label adds/removes that tag to/from the focused window.
-.SS Keyboard commands
-.TP
-.B Mod4\-Shift\-Return
-Start
-.BR st(1).
-.TP
-.B Mod4\-p
-Spawn
-.BR dmenu(1)
-for launching other programs.
-.TP
-.B Mod4\-,
-Focus previous screen, if any.
-.TP
-.B Mod4\-.
-Focus next screen, if any.
-.TP
-.B Mod4\-Shift\-,
-Send focused window to previous screen, if any.
-.TP
-.B Mod4\-Shift\-.
-Send focused window to next screen, if any.
-.TP
-.B Mod4\-b
-Toggles bar on and off.
-.TP
-.B Mod4\-t
-Sets tiled layout.
-.TP
-.B Mod4\-f
-Sets floating layout.
-.TP
-.B Mod4\-m
-Sets monocle layout.
-.TP
-.B Mod4\-space
-Toggles between current and previous layout.
-.TP
-.B Mod4\-Control\-,
-Cycles backwards in layout list.
-.TP
-.B Mod4\-Control\-.
-Cycles forwards in layout list.
-.TP
-.B Mod4\-j
-Focus next window.
-.TP
-.B Mod4\-k
-Focus previous window.
-.TP
-.B Mod4\-i
-Increase number of windows in master area.
-.TP
-.B Mod4\-d
-Decrease number of windows in master area.
-.TP
-.B Mod4\-l
-Increase master area size.
-.TP
-.B Mod4\-h
-Decrease master area size.
-.TP
-.B Mod4\-Return
-Zooms/cycles focused window to/from master area (tiled layouts only).
-.TP
-.B Mod4\-Shift\-c
-Close focused window.
-.TP
-.B Mod4\-Shift\-f
-Toggle fullscreen for focused window.
-.TP
-.B Mod4\-Shift\-space
-Toggle focused window between tiled and floating state.
-.TP
-.B Mod4\-Tab
-Toggles to the previously selected tags.
-.TP
-.B Mod4\-Shift\-[1..n]
-Apply nth tag to focused window.
-.TP
-.B Mod4\-Shift\-0
-Apply all tags to focused window.
-.TP
-.B Mod4\-Control\-Shift\-[1..n]
-Add/remove nth tag to/from focused window.
-.TP
-.B Mod4\-[1..n]
-View all windows with nth tag.
-.TP
-.B Mod4\-0
-View all windows with any tag.
-.TP
-.B Mod4\-Control\-[1..n]
-Add/remove all windows with nth tag to/from the view.
-.TP
-.B Mod4\--
-Decrease the gaps around windows.
-.TP
-.B Mod4\-=
-Increase the gaps around windows.
-.TP
-.B Mod4\-Shift-=
-Reset the gaps around windows to
-.BR 0 .
-.TP
-.B Mod4\-Shift\-q
-Quit dwm.
-.TP
-.B Mod4\-Control\-Shift\-q
-Restart dwm.
-.SS Mouse commands
-.TP
-.B Mod4\-Button1
-Move focused window while dragging. Tiled windows will be toggled to the floating state.
-.TP
-.B Mod4\-Button2
-Toggles focused window between floating and tiled state.
-.TP
-.B Mod4\-Button3
-Resize focused window while dragging. Tiled windows will be toggled to the floating state.
-.SH CUSTOMIZATION
-dwm is customized by creating a custom config.h and (re)compiling the source
-code. This keeps it fast, secure and simple.
-.SH SIGNALS
-.TP
-.B SIGHUP - 1
-Restart the dwm process.
-.TP
-.B SIGTERM - 15
-Cleanly terminate the dwm process.
-.SH SEE ALSO
-.BR dmenu (1),
-.BR st (1)
-.SH ISSUES
-Java applications which use the XToolkit/XAWT backend may draw grey windows
-only. The XToolkit/XAWT backend breaks ICCCM-compliance in recent JDK 1.5 and early
-JDK 1.6 versions, because it assumes a reparenting window manager. Possible workarounds
-are using JDK 1.4 (which doesn't contain the XToolkit/XAWT backend) or setting the
-environment variable
-.BR AWT_TOOLKIT=MToolkit
-(to use the older Motif backend instead) or running
-.B xprop -root -f _NET_WM_NAME 32a -set _NET_WM_NAME LG3D
-or
-.B wmname LG3D
-(to pretend that a non-reparenting window manager is running that the
-XToolkit/XAWT backend can recognize) or when using OpenJDK setting the environment variable
-.BR _JAVA_AWT_WM_NONREPARENTING=1 .
-.SH BUGS
-Send all bug reports with a patch to [email protected].
diff --git a/.local/src/dwm/dwm.c b/.local/src/dwm/dwm.c
@@ -1,3243 +0,0 @@
-/* See LICENSE file for copyright and license details.
- *
- * dynamic window manager is designed like any other X client as well. It is
- * driven through handling X events. In contrast to other X clients, a window
- * manager selects for SubstructureRedirectMask on the root window, to receive
- * events about window (dis-)appearance. Only one X connection at a time is
- * allowed to select for this event mask.
- *
- * The event handlers of dwm are organized in an array which is accessed
- * whenever a new event has been fetched. This allows event dispatching
- * in O(1) time.
- *
- * Each child of the root window is called a client, except windows which have
- * set the override_redirect flag. Clients are organized in a linked client
- * list on each monitor, the focus history is remembered through a stack list
- * on each monitor. Each client contains a bit array to indicate the tags of a
- * client.
- *
- * Keys and tagging rules are organized as arrays and defined in config.h.
- *
- * To understand everything else, start reading main().
- */
-#include <errno.h>
-#include <locale.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <X11/cursorfont.h>
-#include <X11/keysym.h>
-#include <X11/Xatom.h>
-#include <X11/Xlib.h>
-#include <X11/Xproto.h>
-#include <X11/Xresource.h>
-#include <X11/Xutil.h>
-#ifdef XINERAMA
-#include <X11/extensions/Xinerama.h>
-#endif /* XINERAMA */
-#include <X11/Xft/Xft.h>
-#include <fribidi.h>
-
-#include "drw.h"
-#include "util.h"
-
-/* macros */
-#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask)
-#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
-#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
- * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
-#define INTERSECTC(x,y,w,h,z) (MAX(0, MIN((x)+(w),(z)->x+(z)->w) - MAX((x),(z)->x)) \
- * MAX(0, MIN((y)+(h),(z)->y+(z)->h) - MAX((y),(z)->y)))
-#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]) || C->issticky)
-#define LENGTH(X) (sizeof X / sizeof X[0])
-#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
-#define WIDTH(X) ((X)->w + 2 * (X)->bw)
-#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
-#define TAGMASK ((1 << LENGTH(tags)) - 1)
-#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
-
-#define SYSTEM_TRAY_REQUEST_DOCK 0
-/* XEMBED messages */
-#define XEMBED_EMBEDDED_NOTIFY 0
-#define XEMBED_WINDOW_ACTIVATE 1
-#define XEMBED_FOCUS_IN 4
-#define XEMBED_MODALITY_ON 10
-#define XEMBED_MAPPED (1 << 0)
-#define XEMBED_WINDOW_ACTIVATE 1
-#define XEMBED_WINDOW_DEACTIVATE 2
-#define VERSION_MAJOR 0
-#define VERSION_MINOR 0
-#define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR
-
-/* enums */
-enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
-enum { SchemeNorm, SchemeSel, SchemeLayout }; /* color schemes */
-enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
- NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz,
- NetWMFullscreen, NetActiveWindow, NetWMWindowType,
- NetWMWindowTypeDialog, NetClientList, NetClientInfo, NetLast }; /* EWMH atoms */
-enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */
-enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
-enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
- ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
-
-typedef union {
- int i;
- unsigned int ui;
- float f;
- const void *v;
-} Arg;
-
-typedef struct {
- unsigned int click;
- unsigned int mask;
- unsigned int button;
- void (*func)(const Arg *arg);
- const Arg arg;
-} Button;
-
-typedef struct Monitor Monitor;
-typedef struct Client Client;
-struct Client {
- char name[256];
- float mina, maxa;
- int x, y, w, h;
- int oldx, oldy, oldw, oldh;
- int basew, baseh, incw, inch, maxw, maxh, minw, minh;
- int bw, oldbw;
- unsigned int tags;
- int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, issticky, beingmoved;
- pid_t pid;
- Client *next;
- Client *snext;
- Monitor *mon;
- Window win;
-};
-
-typedef struct {
- unsigned int mod;
- KeySym keysym;
- void (*func)(const Arg *);
- const Arg arg;
-} Key;
-
-typedef struct {
- const char *symbol;
- void (*arrange)(Monitor *);
-} Layout;
-
-struct Monitor {
- char ltsymbol[16];
- float mfact;
- int nmaster;
- int num;
- int by; /* bar geometry */
- int mx, my, mw, mh; /* screen size */
- int wx, wy, ww, wh; /* window area */
- int gappx; /* gaps between windows */
- unsigned int seltags;
- unsigned int sellt;
- unsigned int tagset[2];
- unsigned int colorfultag;
- int showbar;
- int topbar;
- Client *clients;
- Client *sel;
- Client *stack;
- Monitor *next;
- Window barwin;
- const Layout *lt[2];
-};
-
-typedef struct {
- const char *class;
- const char *instance;
- const char *title;
- unsigned int tags;
- int isfloating;
- int monitor;
-} Rule;
-
-typedef struct Systray Systray;
-struct Systray {
- Window win;
- Client *icons;
-};
-
-/* Xresources preferences */
-enum resource_type {
- STRING = 0,
- INTEGER = 1,
- FLOAT = 2
-};
-
-typedef struct {
- char *name;
- enum resource_type type;
- void *dst;
-} ResourcePref;
-
-/* function declarations */
-static Atom getatomprop(Client *c, Atom prop);
-static Client *nexttiled(Client *c);
-static Client *recttoclient(int x, int y, int w, int h);
-static Client *wintoclient(Window w);
-static Client *wintosystrayicon(Window w);
-static Monitor *createmon(void);
-static Monitor *dirtomon(int dir);
-static Monitor *numtomon(int num);
-static Monitor *recttomon(int x, int y, int w, int h);
-static Monitor *systraytomon(Monitor *m);
-static Monitor *wintomon(Window w);
-static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact);
-static int drawstatusbar(Monitor *m, int bh, char* text);
-static int getrootptr(int *x, int *y);
-static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
-static int sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, long d3, long d4);
-static int updategeom(void);
-static int xerror(Display *dpy, XErrorEvent *ee);
-static int xerrordummy(Display *dpy, XErrorEvent *ee);
-static int xerrorstart(Display *dpy, XErrorEvent *ee);
-static long getstate(Window w);
-static unsigned int getsystraywidth();
-static void applyrules(Client *c);
-static void arrange(Monitor *m);
-static void arrangemon(Monitor *m);
-static void attach(Client *c);
-static void attachbottom(Client *c);
-static void attachstack(Client *c);
-static void buttonpress(XEvent *e);
-static void checkotherwm(void);
-static void cleanup(void);
-static void cleanupmon(Monitor *mon);
-static void clientmessage(XEvent *e);
-static void configure(Client *c);
-static void configurenotify(XEvent *e);
-static void configurerequest(XEvent *e);
-static void cyclelayout(const Arg *arg);
-static void destroynotify(XEvent *e);
-static void detach(Client *c);
-static void detachstack(Client *c);
-static void drawbar(Monitor *m);
-static void drawbars(void);
-static int drawstatusbar(Monitor *m, int bh, char* text);
-static void enternotify(XEvent *e);
-static void expose(XEvent *e);
-static void focus(Client *c);
-static void focusin(XEvent *e);
-static void focusmon(const Arg *arg);
-static void focusnthmon(const Arg *arg);
-static void focusstack(const Arg *arg);
-static void grabbuttons(Client *c, int focused);
-static void grabkeys(void);
-static void incnmaster(const Arg *arg);
-static void keypress(XEvent *e);
-static void killclient(const Arg *arg);
-static void manage(Window w, XWindowAttributes *wa);
-static void mappingnotify(XEvent *e);
-static void maprequest(XEvent *e);
-static void monocle(Monitor *m);
-static void motionnotify(XEvent *e);
-static void movemouse(const Arg *arg);
-static void moveorplace(const Arg *arg);
-static void movestack(const Arg *arg);
-static void placemouse(const Arg *arg);
-static void pop(Client *);
-static void propertynotify(XEvent *e);
-static void restart(const Arg *arg);
-static void quit(const Arg *arg);
-static void removesystrayicon(Client *i);
-static void resize(Client *c, int x, int y, int w, int h, int interact);
-static void resizebarwin(Monitor *m);
-static void resizeclient(Client *c, int x, int y, int w, int h);
-static void resizemouse(const Arg *arg);
-static void resizerequest(XEvent *e);
-static void restack(Monitor *m);
-static void run(void);
-static void scan(void);
-static void sendmon(Client *c, Monitor *m);
-static void setclientstate(Client *c, long state);
-static void setclienttagprop(Client *c);
-static void setfocus(Client *c);
-static void setfullscreen(Client *c, int fullscreen);
-static void setgaps(const Arg *arg);
-static void setlayout(const Arg *arg);
-static void setmfact(const Arg *arg);
-static void setup(void);
-static void seturgent(Client *c, int urg);
-static void shiftview(const Arg *arg);
-static void showhide(Client *c);
-static void sigchld(int unused);
-static void sighup(int unused);
-static void sigterm(int unused);
-static void spawn(const Arg *arg);
-static Monitor *systraytomon(Monitor *m);
-static void tag(const Arg *arg);
-static void tagmon(const Arg *arg);
-static void tagnthmon(const Arg *arg);
-static void tile(Monitor *);
-static void togglebar(const Arg *arg);
-static void togglefloating(const Arg *arg);
-static void togglefullscr(const Arg *arg);
-static void togglesticky(const Arg *arg);
-static void toggletag(const Arg *arg);
-static void toggleview(const Arg *arg);
-static void unfocus(Client *c, int setfocus);
-static void unmanage(Client *c, int destroyed);
-static void unmapnotify(XEvent *e);
-static void updatebarpos(Monitor *m);
-static void updatebars(void);
-static void updateclientlist(void);
-static void updatenumlockmask(void);
-static void updatesizehints(Client *c);
-static void updatestatus(void);
-static void updatesystray(void);
-static void updatesystrayicongeom(Client *i, int w, int h);
-static void updatesystrayiconstate(Client *i, XPropertyEvent *ev);
-static void updatetitle(Client *c);
-static void updatewindowtype(Client *c);
-static void updatewmhints(Client *c);
-static void view(const Arg *arg);
-static void warp(const Client *c);
-static void zoom(const Arg *arg);
-
-static void live_reload_xresources(const Arg *arg);
-static void load_xresources(void);
-static void resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst);
-
-/* variables */
-static Systray *systray = NULL;
-static const char broken[] = "broken";
-static char stext[1024];
-static char fribidi_text[BUFSIZ] = "";
-static int screen;
-static int sw, sh; /* X display screen geometry width, height */
-static int bh, blw = 0; /* bar geometry */
-static int lrpad; /* sum of left and right padding for text */
-static int (*xerrorxlib)(Display *, XErrorEvent *);
-static unsigned int numlockmask = 0;
-static void (*handler[LASTEvent]) (XEvent *) = {
- [ButtonPress] = buttonpress,
- [ClientMessage] = clientmessage,
- [ConfigureRequest] = configurerequest,
- [ConfigureNotify] = configurenotify,
- [DestroyNotify] = destroynotify,
- [EnterNotify] = enternotify,
- [Expose] = expose,
- [FocusIn] = focusin,
- [KeyPress] = keypress,
- [MappingNotify] = mappingnotify,
- [MapRequest] = maprequest,
- [MotionNotify] = motionnotify,
- [PropertyNotify] = propertynotify,
- [ResizeRequest] = resizerequest,
- [UnmapNotify] = unmapnotify
-};
-static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast];
-static int restartsig = 0;
-static int running = 1;
-static Cur *cursor[CurLast];
-static Clr **scheme;
-static Clr **tagscheme;
-static Clr **tagscheme_sel;
-static Display *dpy;
-static Drw *drw;
-static Monitor *mons, *selmon;
-static Window root, wmcheckwin;
-
-/* configuration, allows nested code to access above variables */
-#include "config.h"
-
-/* compile-time check if all tags fit into an unsigned int bit array. */
-struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
-
-/* function implementations */
-static void
-apply_fribidi(const char *str)
-{
- FriBidiStrIndex len = strlen(str);
- FriBidiChar logical[BUFSIZ];
- FriBidiChar visual[BUFSIZ];
- FriBidiParType base = FRIBIDI_PAR_ON;
- FriBidiCharSet charset;
- fribidi_boolean result;
-
- fribidi_text[0] = 0;
- if (len>0)
- {
- charset = fribidi_parse_charset("UTF-8");
- len = fribidi_charset_to_unicode(charset, str, len, logical);
- result = fribidi_log2vis(logical, len, &base, visual, NULL, NULL, NULL);
- len = fribidi_unicode_to_charset(charset, visual, len, fribidi_text);
- }
-}
-
-void
-applyrules(Client *c)
-{
- const char *class, *instance;
- unsigned int i;
- const Rule *r;
- Monitor *m;
- XClassHint ch = { NULL, NULL };
-
- /* rule matching */
- c->isfloating = 0;
- c->tags = 0;
- XGetClassHint(dpy, c->win, &ch);
- class = ch.res_class ? ch.res_class : broken;
- instance = ch.res_name ? ch.res_name : broken;
-
- for (i = 0; i < LENGTH(rules); i++) {
- r = &rules[i];
- if ((!r->title || strstr(c->name, r->title))
- && (!r->class || strstr(class, r->class))
- && (!r->instance || strstr(instance, r->instance)))
- {
- c->isfloating = r->isfloating;
- c->tags |= r->tags;
- for (m = mons; m && m->num != r->monitor; m = m->next);
- if (m)
- c->mon = m;
- }
- }
- if (ch.res_class)
- XFree(ch.res_class);
- if (ch.res_name)
- XFree(ch.res_name);
- c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags];
-}
-
-int
-applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact)
-{
- int baseismin;
- Monitor *m = c->mon;
-
- /* set minimum possible */
- *w = MAX(1, *w);
- *h = MAX(1, *h);
- if (interact) {
- if (*x > sw)
- *x = sw - WIDTH(c);
- if (*y > sh)
- *y = sh - HEIGHT(c);
- if (*x + *w + 2 * c->bw < 0)
- *x = 0;
- if (*y + *h + 2 * c->bw < 0)
- *y = 0;
- } else {
- if (*x >= m->wx + m->ww)
- *x = m->wx + m->ww - WIDTH(c);
- if (*y >= m->wy + m->wh)
- *y = m->wy + m->wh - HEIGHT(c);
- if (*x + *w + 2 * c->bw <= m->wx)
- *x = m->wx;
- if (*y + *h + 2 * c->bw <= m->wy)
- *y = m->wy;
- }
- if (*h < bh)
- *h = bh;
- if (*w < bh)
- *w = bh;
- if (resizehints || c->isfloating || !c->mon->lt[c->mon->sellt]->arrange) {
- /* see last two sentences in ICCCM 4.1.2.3 */
- baseismin = c->basew == c->minw && c->baseh == c->minh;
- if (!baseismin) { /* temporarily remove base dimensions */
- *w -= c->basew;
- *h -= c->baseh;
- }
- /* adjust for aspect limits */
- if (c->mina > 0 && c->maxa > 0) {
- if (c->maxa < (float)*w / *h)
- *w = *h * c->maxa + 0.5;
- else if (c->mina < (float)*h / *w)
- *h = *w * c->mina + 0.5;
- }
- if (baseismin) { /* increment calculation requires this */
- *w -= c->basew;
- *h -= c->baseh;
- }
- /* adjust for increment value */
- if (c->incw)
- *w -= *w % c->incw;
- if (c->inch)
- *h -= *h % c->inch;
- /* restore base dimensions */
- *w = MAX(*w + c->basew, c->minw);
- *h = MAX(*h + c->baseh, c->minh);
- if (c->maxw)
- *w = MIN(*w, c->maxw);
- if (c->maxh)
- *h = MIN(*h, c->maxh);
- }
- return *x != c->x || *y != c->y || *w != c->w || *h != c->h;
-}
-
-void
-arrange(Monitor *m)
-{
- if (m)
- showhide(m->stack);
- else for (m = mons; m; m = m->next)
- showhide(m->stack);
- if (m) {
- arrangemon(m);
- restack(m);
- } else for (m = mons; m; m = m->next)
- arrangemon(m);
-}
-
-void
-arrangemon(Monitor *m)
-{
- strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol);
- if (m->lt[m->sellt]->arrange)
- m->lt[m->sellt]->arrange(m);
-}
-
-void
-attach(Client *c)
-{
- c->next = c->mon->clients;
- c->mon->clients = c;
-}
-
-void
-attachbottom(Client *c)
-{
- Client **tc;
- c->next = NULL;
- for (tc = &c->mon->clients; *tc; tc = &(*tc)->next);
- *tc = c;
-}
-
-void
-attachstack(Client *c)
-{
- c->snext = c->mon->stack;
- c->mon->stack = c;
-}
-
-void
-buttonpress(XEvent *e)
-{
- unsigned int i, x, click;
- Arg arg = {0};
- Client *c;
- Monitor *m;
- XButtonPressedEvent *ev = &e->xbutton;
-
- click = ClkRootWin;
- /* focus monitor if necessary */
- if ((m = wintomon(ev->window)) && m != selmon) {
- unfocus(selmon->sel, 1);
- selmon = m;
- focus(NULL);
- }
- if (ev->window == selmon->barwin) {
- i = x = 0;
- unsigned int occ = 0;
- for(c = m->clients; c; c=c->next)
- occ |= c->tags;
- do {
- /* Do not reserve space for vacant tags */
- if (hidevacanttags && !(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
- continue;
- x += TEXTW(tags[i]);
- } while (ev->x >= x && ++i < LENGTH(tags));
- if (i < LENGTH(tags)) {
- click = ClkTagBar;
- arg.ui = 1 << i;
- } else if (ev->x < x + blw)
- click = ClkLtSymbol;
- else if (showtitle != 1 || ev->x > selmon->ww - (int)TEXTW(stext) - getsystraywidth())
- click = ClkStatusText;
- else
- click = ClkWinTitle;
- } else if ((c = wintoclient(ev->window))) {
- focus(c);
- restack(selmon);
- XAllowEvents(dpy, ReplayPointer, CurrentTime);
- click = ClkClientWin;
- }
- for (i = 0; i < LENGTH(buttons); i++)
- if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button
- && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state))
- buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg);
-}
-
-void
-checkotherwm(void)
-{
- xerrorxlib = XSetErrorHandler(xerrorstart);
- /* this causes an error if some other window manager is running */
- XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask);
- XSync(dpy, False);
- XSetErrorHandler(xerror);
- XSync(dpy, False);
-}
-
-void
-cleanup(void)
-{
- Arg a = {.ui = ~0};
- Layout foo = { "", NULL };
- Monitor *m;
- size_t i;
-
- view(&a);
- selmon->lt[selmon->sellt] = &foo;
- for (m = mons; m; m = m->next)
- while (m->stack)
- unmanage(m->stack, 0);
- XUngrabKey(dpy, AnyKey, AnyModifier, root);
- while (mons)
- cleanupmon(mons);
-
- if (showsystray) {
- XUnmapWindow(dpy, systray->win);
- XDestroyWindow(dpy, systray->win);
- free(systray);
- }
-
- for (i = 0; i < CurLast; i++)
- drw_cur_free(drw, cursor[i]);
- for (i = 0; i < LENGTH(colors) + 1; i++)
- free(scheme[i]);
- free(scheme);
- XDestroyWindow(dpy, wmcheckwin);
- drw_free(drw);
- XSync(dpy, False);
- XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
- XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
-}
-
-void
-cleanupmon(Monitor *mon)
-{
- Monitor *m;
-
- if (mon == mons)
- mons = mons->next;
- else {
- for (m = mons; m && m->next != mon; m = m->next);
- m->next = mon->next;
- }
- XUnmapWindow(dpy, mon->barwin);
- XDestroyWindow(dpy, mon->barwin);
- free(mon);
-}
-
-void
-clientmessage(XEvent *e)
-{
- XWindowAttributes wa;
- XSetWindowAttributes swa;
- XClientMessageEvent *cme = &e->xclient;
- Client *c = wintoclient(cme->window);
-
- if (showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) {
- /* add systray icons */
- if (cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) {
- if (!(c = (Client *)calloc(1, sizeof(Client))))
- die("fatal: could not malloc() %u bytes\n", sizeof(Client));
- if (!(c->win = cme->data.l[2])) {
- free(c);
- return;
- }
- c->mon = selmon;
- c->next = systray->icons;
- systray->icons = c;
- if (!XGetWindowAttributes(dpy, c->win, &wa)) {
- /* use sane defaults */
- wa.width = bh;
- wa.height = bh;
- wa.border_width = 0;
- }
- c->x = c->oldx = c->y = c->oldy = 0;
- c->w = c->oldw = wa.width;
- c->h = c->oldh = wa.height;
- c->oldbw = wa.border_width;
- c->bw = 0;
- c->isfloating = True;
- /* reuse tags field as mapped status */
- c->tags = 1;
- updatesizehints(c);
- updatesystrayicongeom(c, wa.width, wa.height);
- XAddToSaveSet(dpy, c->win);
- XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask);
- XReparentWindow(dpy, c->win, systray->win, 0, 0);
- /* use parents background color */
- swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
- XChangeWindowAttributes(dpy, c->win, CWBackPixel, &swa);
- sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
- /* FIXME not sure if I have to send these events, too */
- sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_FOCUS_IN, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
- sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
- sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_MODALITY_ON, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
- XSync(dpy, False);
- resizebarwin(selmon);
- updatesystray();
- setclientstate(c, NormalState);
- }
- return;
- }
-
- if (!c)
- return;
- if (cme->message_type == netatom[NetWMState]) {
- if (cme->data.l[1] == netatom[NetWMFullscreen]
- || cme->data.l[2] == netatom[NetWMFullscreen])
- setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */
- || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen)));
- } else if (cme->message_type == netatom[NetActiveWindow]) {
- if (c != selmon->sel && !c->isurgent)
- seturgent(c, 1);
- }
-}
-
-void
-configure(Client *c)
-{
- XConfigureEvent ce;
-
- ce.type = ConfigureNotify;
- ce.display = dpy;
- ce.event = c->win;
- ce.window = c->win;
- ce.x = c->x;
- ce.y = c->y;
- ce.width = c->w;
- ce.height = c->h;
- ce.border_width = c->bw;
- ce.above = None;
- ce.override_redirect = False;
- XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&ce);
-}
-
-void
-configurenotify(XEvent *e)
-{
- Monitor *m;
- Client *c;
- XConfigureEvent *ev = &e->xconfigure;
- int dirty;
-
- /* TODO: updategeom handling sucks, needs to be simplified */
- if (ev->window == root) {
- dirty = (sw != ev->width || sh != ev->height);
- sw = ev->width;
- sh = ev->height;
- if (updategeom() || dirty) {
- drw_resize(drw, sw, bh);
- updatebars();
- for (m = mons; m; m = m->next) {
- for (c = m->clients; c; c = c->next)
- if (c->isfullscreen)
- resizeclient(c, m->mx, m->my, m->mw, m->mh);
- resizebarwin(m);
- }
- focus(NULL);
- arrange(NULL);
- }
- }
-}
-
-void
-configurerequest(XEvent *e)
-{
- Client *c;
- Monitor *m;
- XConfigureRequestEvent *ev = &e->xconfigurerequest;
- XWindowChanges wc;
-
- if ((c = wintoclient(ev->window))) {
- if (ev->value_mask & CWBorderWidth)
- c->bw = ev->border_width;
- else if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) {
- m = c->mon;
- if (ev->value_mask & CWX) {
- c->oldx = c->x;
- c->x = m->mx + ev->x;
- }
- if (ev->value_mask & CWY) {
- c->oldy = c->y;
- c->y = m->my + ev->y;
- }
- if (ev->value_mask & CWWidth) {
- c->oldw = c->w;
- c->w = ev->width;
- }
- if (ev->value_mask & CWHeight) {
- c->oldh = c->h;
- c->h = ev->height;
- }
- if ((c->x + c->w) > m->mx + m->mw && c->isfloating)
- c->x = m->mx + (m->mw / 2 - WIDTH(c) / 2); /* center in x direction */
- if ((c->y + c->h) > m->my + m->mh && c->isfloating)
- c->y = m->my + (m->mh / 2 - HEIGHT(c) / 2); /* center in y direction */
- if ((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight)))
- configure(c);
- if (ISVISIBLE(c))
- XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
- } else
- configure(c);
- } else {
- wc.x = ev->x;
- wc.y = ev->y;
- wc.width = ev->width;
- wc.height = ev->height;
- wc.border_width = ev->border_width;
- wc.sibling = ev->above;
- wc.stack_mode = ev->detail;
- XConfigureWindow(dpy, ev->window, ev->value_mask, &wc);
- }
- XSync(dpy, False);
-}
-
-Monitor *
-createmon(void)
-{
- Monitor *m;
-
- m = ecalloc(1, sizeof(Monitor));
- m->tagset[0] = m->tagset[1] = 1;
- m->mfact = mfact;
- m->nmaster = nmaster;
- m->showbar = showbar;
- m->topbar = topbar;
- m->gappx = gappx;
- m->colorfultag = colorfultag ? colorfultag : 0;
- m->lt[0] = &layouts[layouts_default];
- m->lt[1] = &layouts[(layouts_default + 1) % LENGTH(layouts)];
- strncpy(m->ltsymbol, layouts[layouts_default].symbol, sizeof m->ltsymbol);
- return m;
-}
-
-void
-cyclelayout(const Arg *arg) {
- Layout *l;
- for(l = (Layout *)layouts; l != selmon->lt[selmon->sellt]; l++);
- if(arg->i > 0) {
- if(l->symbol && (l + 1)->symbol)
- setlayout(&((Arg) { .v = (l + 1) }));
- else
- setlayout(&((Arg) { .v = layouts }));
- } else {
- if(l != layouts && (l - 1)->symbol)
- setlayout(&((Arg) { .v = (l - 1) }));
- else
- setlayout(&((Arg) { .v = &layouts[LENGTH(layouts) - 2] }));
- }
-}
-
-void
-destroynotify(XEvent *e)
-{
- Client *c;
- XDestroyWindowEvent *ev = &e->xdestroywindow;
-
- if ((c = wintoclient(ev->window)))
- unmanage(c, 1);
- else if ((c = wintosystrayicon(ev->window))) {
- removesystrayicon(c);
- resizebarwin(selmon);
- updatesystray();
- }
-}
-
-void
-detach(Client *c)
-{
- Client **tc;
-
- for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next);
- *tc = c->next;
-}
-
-void
-detachstack(Client *c)
-{
- Client **tc, *t;
-
- for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext);
- *tc = c->snext;
-
- if (c == c->mon->sel) {
- for (t = c->mon->stack; t && !ISVISIBLE(t); t = t->snext);
- c->mon->sel = t;
- }
-}
-
-Monitor *
-dirtomon(int dir)
-{
- Monitor *m = NULL;
-
- if (dir > 0) {
- if (!(m = selmon->next))
- m = mons;
- } else if (selmon == mons)
- for (m = mons; m->next; m = m->next);
- else
- for (m = mons; m->next != selmon; m = m->next);
- return m;
-}
-
-int
-drawstatusbar(Monitor *m, int bh, char* stext) {
- int ret, i, w, x, len;
- short isCode = 0;
- char *text;
- char *p;
-
- len = strlen(stext) + 1 ;
- if (!(text = (char*) malloc(sizeof(char)*len)))
- die("malloc");
- p = text;
- memcpy(text, stext, len);
-
- /* compute width of the status text */
- w = 0;
- i = -1;
- while (text[++i]) {
- if (text[i] == '^') {
- if (!isCode) {
- isCode = 1;
- text[i] = '\0';
- w += TEXTW(text) - lrpad;
- text[i] = '^';
- if (text[++i] == 'f')
- w += atoi(text + ++i);
- } else {
- isCode = 0;
- text = text + i + 1;
- i = -1;
- }
- }
- }
- if (!isCode)
- w += TEXTW(text) - lrpad;
- else
- isCode = 0;
- text = p;
- if (showsystray)
- /* Xpx padding on both sides */
- w += systraypadding * 2;
- ret = m->ww - w;
- x = m->ww - w - getsystraywidth();
-
- drw_setscheme(drw, scheme[LENGTH(colors)]);
- drw->scheme[ColFg] = scheme[SchemeNorm][ColFg];
- drw->scheme[ColBg] = scheme[SchemeNorm][ColBg];
- drw_rect(drw, x, 0, w, bh, 1, 1);
- x++;
-
- /* process status text */
- i = -1;
- while (text[++i]) {
- if (text[i] == '^' && !isCode) {
- isCode = 1;
-
- text[i] = '\0';
- w = TEXTW(text) - lrpad;
- drw_text(drw, x, 0, w, bh, 0, text, 0);
-
- x += w;
-
- /* process code */
- while (text[++i] != '^') {
- if (text[i] == 'c') {
- char buf[8];
- memcpy(buf, (char*)text+i+1, 7);
- buf[7] = '\0';
- drw_clr_create(drw, &drw->scheme[ColFg], buf);
- i += 7;
- } else if (text[i] == 'b') {
- char buf[8];
- memcpy(buf, (char*)text+i+1, 7);
- buf[7] = '\0';
- drw_clr_create(drw, &drw->scheme[ColBg], buf);
- i += 7;
- } else if (text[i] == 'd') {
- drw->scheme[ColFg] = scheme[SchemeNorm][ColFg];
- drw->scheme[ColBg] = scheme[SchemeNorm][ColBg];
- } else if (text[i] == 'r') {
- int rx = atoi(text + ++i);
- while (text[++i] != ',');
- int ry = atoi(text + ++i);
- while (text[++i] != ',');
- int rw = atoi(text + ++i);
- while (text[++i] != ',');
- int rh = atoi(text + ++i);
-
- drw_rect(drw, rx + x, ry, rw, rh, 1, 0);
- } else if (text[i] == 'f') {
- x += atoi(text + ++i);
- }
- }
-
- text = text + i + 1;
- i=-1;
- isCode = 0;
- }
- }
-
- if (!isCode) {
- w = TEXTW(text) - lrpad;
- drw_text(drw, x, 0, w, bh, 0, text, 0);
- }
-
- drw_setscheme(drw, scheme[SchemeNorm]);
- free(p);
-
- return ret;
-}
-
-Monitor *
-numtomon(int num)
-{
- Monitor *m = NULL;
- int i = 0;
-
- for(m = mons, i=0; m->next && i < num; m = m->next){
- i++;
- }
- return m;
-}
-
-void
-drawbar(Monitor *m)
-{
- int x, w, tw = 0, stw = 0;
- int boxs = drw->fonts->h / 9;
- int boxw = drw->fonts->h / 6 + 2;
- unsigned int i, occ = 0, urg = 0;
- Client *c;
-
- if (!m->showbar)
- return;
-
- if (showsystray && m == systraytomon(m) && !systrayonleft)
- stw = getsystraywidth();
-
- /* draw status first so it can be overdrawn by tags later */
- if (m == selmon || 1) { /* status is drawn on all monitors */
- //drw_setscheme(drw, scheme[SchemeNorm]);
- //tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
- //drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
- apply_fribidi(stext);
- tw = m->ww - drawstatusbar(m, bh, fribidi_text);
- }
-
- resizebarwin(m);
-
- for (c = m->clients; c; c = c->next) {
- occ |= c->tags;
- if (c->isurgent)
- urg |= c->tags;
- }
- x = 0;
- for (i = 0; i < LENGTH(tags); i++) {
- if (hidevacanttags) /* Do not draw vacant tags */
- if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) continue;
- if (colorfultag)
- //drw_setscheme(drw, (m->tagset[m->seltags] & 1 << i ? tagscheme[i] : scheme[SchemeNorm]));
- //drw_setscheme(drw, (m->tagset[m->seltags] & 1 << i ? tagscheme_sel[i] : tagscheme[i]));
- drw_setscheme(drw, (occ & 1 << i ? (m->tagset[m->seltags] & 1 << i ? tagscheme_sel[i] : tagscheme[i]) : scheme[SchemeNorm]));
- else
- drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
- apply_fribidi(tags[i]);
- w = TEXTW(fribidi_text);
- drw_text(drw, x, 0, w, bh, lrpad / 2, fribidi_text, urg & 1 << i);
- if (!hidetagindicator) /* Do not draw top-left tag indicators */
- if (occ & 1 << i)
- drw_rect(drw, x + boxs, boxs, boxw, boxw,
- m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
- urg & 1 << i);
- x += w;
- }
- apply_fribidi(m->ltsymbol);
- w = blw = TEXTW(fribidi_text);
- drw_setscheme(drw, scheme[SchemeLayout]);
- x = drw_text(drw, x, 0, w, bh, lrpad / 2, fribidi_text, 0);
-
- if ((w = m->ww - tw - stw - x) > bh) {
- if (showtitle && m->sel) {
- drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
- apply_fribidi(m->sel->name);
- int mid = lrpad / 2;
- if (truecenteredtitle && TEXTW(fribidi_text) <= w)
- mid = (w - TEXTW(fribidi_text)) / 2;
- //mid = lrpad / 2;
- drw_text(drw, x, 0, w, bh, mid, fribidi_text, 0);
- if (m->sel->isfloating && !hidetagindicator)
- drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
- } else {
- drw_setscheme(drw, scheme[SchemeNorm]);
- drw_rect(drw, x, 0, w, bh, 1, 1);
- }
- }
- drw_map(drw, m->barwin, 0, 0, m->ww - stw, bh);
-}
-
-void
-drawbars(void)
-{
- Monitor *m;
-
- for (m = mons; m; m = m->next)
- drawbar(m);
-}
-
-void
-enternotify(XEvent *e)
-{
- Client *c;
- Monitor *m;
- XCrossingEvent *ev = &e->xcrossing;
-
- if ((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root)
- return;
- c = wintoclient(ev->window);
- m = c ? c->mon : wintomon(ev->window);
- if (m != selmon) {
- unfocus(selmon->sel, 1);
- selmon = m;
- } else if (!c || c == selmon->sel)
- return;
- focus(c);
-}
-
-void
-expose(XEvent *e)
-{
- Monitor *m;
- XExposeEvent *ev = &e->xexpose;
-
- if (ev->count == 0 && (m = wintomon(ev->window))) {
- drawbar(m);
- if (m == selmon)
- updatesystray();
- }
-}
-
-void
-focus(Client *c)
-{
- if (!c || !ISVISIBLE(c))
- for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext);
- if (selmon->sel && selmon->sel != c)
- unfocus(selmon->sel, 0);
- if (c) {
- if (c->mon != selmon)
- selmon = c->mon;
- if (c->isurgent)
- seturgent(c, 0);
- detachstack(c);
- attachstack(c);
- grabbuttons(c, 1);
- XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
- setfocus(c);
- } else {
- XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
- XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
- }
- selmon->sel = c;
- drawbars();
-}
-
-/* there are some broken focus acquiring clients needing extra handling */
-void
-focusin(XEvent *e)
-{
- XFocusChangeEvent *ev = &e->xfocus;
-
- if (selmon->sel && ev->window != selmon->sel->win)
- setfocus(selmon->sel);
-}
-
-void
-focusmon(const Arg *arg)
-{
- Monitor *m;
-
- if (!mons->next)
- return;
- if ((m = dirtomon(arg->i)) == selmon)
- return;
- unfocus(selmon->sel, 0);
- selmon = m;
- focus(NULL);
- warp(selmon->sel);
-}
-
-void
-focusnthmon(const Arg *arg)
-{
- Monitor *m;
-
- if (!mons->next)
- return;
-
- if ((m = numtomon(arg->i)) == selmon)
- return;
- unfocus(selmon->sel, 0);
- selmon = m;
- focus(NULL);
- warp(selmon->sel);
-}
-
-void
-focusstack(const Arg *arg)
-{
- Client *c = NULL, *i;
-
- if (!selmon->sel || (selmon->sel->isfullscreen && lockfullscreen))
- return;
- if (arg->i > 0) {
- for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next);
- if (!c)
- for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next);
- } else {
- for (i = selmon->clients; i != selmon->sel; i = i->next)
- if (ISVISIBLE(i))
- c = i;
- if (!c)
- for (; i; i = i->next)
- if (ISVISIBLE(i))
- c = i;
- }
- if (c) {
- focus(c);
- restack(selmon);
- }
-}
-
-Atom
-getatomprop(Client *c, Atom prop)
-{
- int di;
- unsigned long dl;
- unsigned char *p = NULL;
- Atom da, atom = None;
-
- /* FIXME getatomprop should return the number of items and a pointer to
- * the stored data instead of this workaround */
- Atom req = XA_ATOM;
- if (prop == xatom[XembedInfo])
- req = xatom[XembedInfo];
-
- if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req,
- &da, &di, &dl, &dl, &p) == Success && p) {
- atom = *(Atom *)p;
- if (da == xatom[XembedInfo] && dl == 2)
- atom = ((Atom *)p)[1];
- XFree(p);
- }
- return atom;
-}
-
-int
-getrootptr(int *x, int *y)
-{
- int di;
- unsigned int dui;
- Window dummy;
-
- return XQueryPointer(dpy, root, &dummy, &dummy, x, y, &di, &di, &dui);
-}
-
-long
-getstate(Window w)
-{
- int format;
- long result = -1;
- unsigned char *p = NULL;
- unsigned long n, extra;
- Atom real;
-
- if (XGetWindowProperty(dpy, w, wmatom[WMState], 0L, 2L, False, wmatom[WMState],
- &real, &format, &n, &extra, (unsigned char **)&p) != Success)
- return -1;
- if (n != 0)
- result = *p;
- XFree(p);
- return result;
-}
-
-unsigned int
-getsystraywidth()
-{
- unsigned int w = 0;
- Client *i;
- if(showsystray)
- for(i = systray->icons; i; w += i->w + systrayspacing, i = i->next) ;
- return w ? w + systrayspacing : 1;
-}
-
-int
-gettextprop(Window w, Atom atom, char *text, unsigned int size)
-{
- char **list = NULL;
- int n;
- XTextProperty name;
-
- if (!text || size == 0)
- return 0;
- text[0] = '\0';
- if (!XGetTextProperty(dpy, w, &name, atom) || !name.nitems)
- return 0;
- if (name.encoding == XA_STRING)
- strncpy(text, (char *)name.value, size - 1);
- else {
- if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success && n > 0 && *list) {
- strncpy(text, *list, size - 1);
- XFreeStringList(list);
- }
- }
- text[size - 1] = '\0';
- XFree(name.value);
- return 1;
-}
-
-void
-grabbuttons(Client *c, int focused)
-{
- updatenumlockmask();
- {
- unsigned int i, j;
- unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
- XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
- if (!focused)
- XGrabButton(dpy, AnyButton, AnyModifier, c->win, False,
- BUTTONMASK, GrabModeSync, GrabModeSync, None, None);
- for (i = 0; i < LENGTH(buttons); i++)
- if (buttons[i].click == ClkClientWin)
- for (j = 0; j < LENGTH(modifiers); j++)
- XGrabButton(dpy, buttons[i].button,
- buttons[i].mask | modifiers[j],
- c->win, False, BUTTONMASK,
- GrabModeAsync, GrabModeSync, None, None);
- }
-}
-
-void
-grabkeys(void)
-{
- updatenumlockmask();
- {
- unsigned int i, j;
- unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
- KeyCode code;
-
- XUngrabKey(dpy, AnyKey, AnyModifier, root);
- for (i = 0; i < LENGTH(keys); i++)
- if ((code = XKeysymToKeycode(dpy, keys[i].keysym)))
- for (j = 0; j < LENGTH(modifiers); j++)
- XGrabKey(dpy, code, keys[i].mod | modifiers[j], root,
- True, GrabModeAsync, GrabModeAsync);
- }
-}
-
-void
-incnmaster(const Arg *arg)
-{
- selmon->nmaster = MAX(selmon->nmaster + arg->i, 0);
- arrange(selmon);
-}
-
-#ifdef XINERAMA
-static int
-isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info)
-{
- while (n--)
- if (unique[n].x_org == info->x_org && unique[n].y_org == info->y_org
- && unique[n].width == info->width && unique[n].height == info->height)
- return 0;
- return 1;
-}
-#endif /* XINERAMA */
-
-void
-keypress(XEvent *e)
-{
- unsigned int i;
- KeySym keysym;
- XKeyEvent *ev;
-
- ev = &e->xkey;
- keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
- for (i = 0; i < LENGTH(keys); i++)
- if (keysym == keys[i].keysym
- && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)
- && keys[i].func)
- keys[i].func(&(keys[i].arg));
-}
-
-void
-killclient(const Arg *arg)
-{
- if (!selmon->sel)
- return;
-
- if (!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0 , 0, 0)) {
- XGrabServer(dpy);
- XSetErrorHandler(xerrordummy);
- XSetCloseDownMode(dpy, DestroyAll);
- XKillClient(dpy, selmon->sel->win);
- XSync(dpy, False);
- XSetErrorHandler(xerror);
- XUngrabServer(dpy);
- }
-}
-
-void
-manage(Window w, XWindowAttributes *wa)
-{
- Client *c, *t = NULL;
- Window trans = None;
- XWindowChanges wc;
-
- c = ecalloc(1, sizeof(Client));
- c->win = w;
- /* geometry */
- c->x = c->oldx = wa->x;
- c->y = c->oldy = wa->y;
- c->w = c->oldw = wa->width;
- c->h = c->oldh = wa->height;
- c->oldbw = wa->border_width;
-
- updatetitle(c);
- if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) {
- c->mon = t->mon;
- c->tags = t->tags;
- } else {
- c->mon = selmon;
- applyrules(c);
- }
-
- if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw)
- c->x = c->mon->mx + c->mon->mw - WIDTH(c);
- if (c->y + HEIGHT(c) > c->mon->my + c->mon->mh)
- c->y = c->mon->my + c->mon->mh - HEIGHT(c);
- c->x = MAX(c->x, c->mon->mx);
- /* only fix client y-offset, if the client center might cover the bar */
- c->y = MAX(c->y, ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx)
- && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my);
- c->bw = borderpx;
-
- wc.border_width = c->bw;
- XConfigureWindow(dpy, w, CWBorderWidth, &wc);
- XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel);
- configure(c); /* propagates border_width, if size doesn't change */
- updatewindowtype(c);
- updatesizehints(c);
- updatewmhints(c);
- {
- int format;
- unsigned long *data, n, extra;
- Monitor *m;
- Atom atom;
- if (XGetWindowProperty(dpy, c->win, netatom[NetClientInfo], 0L, 2L, False, XA_CARDINAL,
- &atom, &format, &n, &extra, (unsigned char **)&data) == Success && n == 2) {
- c->tags = *data;
- for (m = mons; m; m = m->next) {
- if (m->num == *(data+1)) {
- c->mon = m;
- break;
- }
- }
- }
- if (n > 0)
- XFree(data);
- }
- setclienttagprop(c);
-
- c->x = c->mon->mx + (c->mon->mw - WIDTH(c)) / 2;
- c->y = c->mon->my + (c->mon->mh - HEIGHT(c)) / 2;
- XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
- grabbuttons(c, 0);
- if (!c->isfloating)
- c->isfloating = c->oldstate = trans != None || c->isfixed;
- if (c->isfloating)
- XRaiseWindow(dpy, c->win);
- attachbottom(c);
- attachstack(c);
- setclienttagprop(c);
- XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
- (unsigned char *) &(c->win), 1);
- XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */
- setclientstate(c, NormalState);
- if (c->mon == selmon)
- unfocus(selmon->sel, 0);
- c->mon->sel = c;
- arrange(c->mon);
- XMapWindow(dpy, c->win);
- focus(NULL);
-}
-
-void
-mappingnotify(XEvent *e)
-{
- XMappingEvent *ev = &e->xmapping;
-
- XRefreshKeyboardMapping(ev);
- if (ev->request == MappingKeyboard)
- grabkeys();
-}
-
-void
-maprequest(XEvent *e)
-{
- static XWindowAttributes wa;
- XMapRequestEvent *ev = &e->xmaprequest;
-
- Client *i;
- if ((i = wintosystrayicon(ev->window))) {
- sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION);
- resizebarwin(selmon);
- updatesystray();
- }
-
- if (!XGetWindowAttributes(dpy, ev->window, &wa))
- return;
- if (wa.override_redirect)
- return;
- if (!wintoclient(ev->window))
- manage(ev->window, &wa);
-}
-
-void
-monocle(Monitor *m)
-{
- unsigned int n = 0;
- Client *c;
-
- for (c = m->clients; c; c = c->next)
- if (ISVISIBLE(c))
- n++;
- if (n > 0) /* override layout symbol */
- snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n);
- for (c = nexttiled(m->clients); c; c = nexttiled(c->next))
- resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0);
-}
-
-void
-motionnotify(XEvent *e)
-{
- static Monitor *mon = NULL;
- Monitor *m;
- XMotionEvent *ev = &e->xmotion;
-
- if (ev->window != root)
- return;
- if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) {
- unfocus(selmon->sel, 1);
- selmon = m;
- focus(NULL);
- }
- mon = m;
-}
-
-void
-moveorplace(const Arg *arg) {
- if ((!selmon->lt[selmon->sellt]->arrange || (selmon->sel && selmon->sel->isfloating)))
- movemouse(arg);
- else
- placemouse(arg);
-}
-
-void
-movemouse(const Arg *arg)
-{
- int x, y, ocx, ocy, nx, ny;
- Client *c;
- Monitor *m;
- XEvent ev;
- Time lasttime = 0;
-
- if (!(c = selmon->sel))
- return;
- if (c->isfullscreen) /* no support moving fullscreen windows by mouse */
- return;
- restack(selmon);
- ocx = c->x;
- ocy = c->y;
- if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
- None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess)
- return;
- if (!getrootptr(&x, &y))
- return;
- do {
- XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
- switch(ev.type) {
- case ConfigureRequest:
- case Expose:
- case MapRequest:
- handler[ev.type](&ev);
- break;
- case MotionNotify:
- if ((ev.xmotion.time - lasttime) <= (100 / 60))
- continue;
- lasttime = ev.xmotion.time;
-
- nx = ocx + (ev.xmotion.x - x);
- ny = ocy + (ev.xmotion.y - y);
- if (abs(selmon->wx - nx) < snap)
- nx = selmon->wx;
- else if (abs((selmon->wx + selmon->ww) - (nx + WIDTH(c))) < snap)
- nx = selmon->wx + selmon->ww - WIDTH(c);
- if (abs(selmon->wy - ny) < snap)
- ny = selmon->wy;
- else if (abs((selmon->wy + selmon->wh) - (ny + HEIGHT(c))) < snap)
- ny = selmon->wy + selmon->wh - HEIGHT(c);
- if (!c->isfloating && selmon->lt[selmon->sellt]->arrange
- && (abs(nx - c->x) > snap || abs(ny - c->y) > snap))
- togglefloating(NULL);
- if (!selmon->lt[selmon->sellt]->arrange || c->isfloating)
- resize(c, nx, ny, c->w, c->h, 1);
- break;
- }
- } while (ev.type != ButtonRelease);
- XUngrabPointer(dpy, CurrentTime);
- if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) {
- sendmon(c, m);
- selmon = m;
- focus(NULL);
- }
-}
-
-Client *
-nexttiled(Client *c)
-{
- for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next);
- return c;
-}
-
-void
-placemouse(const Arg *arg)
-{
- int x, y, px, py, ocx, ocy, nx = -9999, ny = -9999, freemove = 0;
- Client *c, *r = NULL, *at, *prevr;
- Monitor *m;
- XEvent ev;
- XWindowAttributes wa;
- Time lasttime = 0;
- int attachmode, prevattachmode;
- attachmode = prevattachmode = -1;
-
- if (!(c = selmon->sel) || !c->mon->lt[c->mon->sellt]->arrange) /* no support for placemouse when floating layout is used */
- return;
- if (c->isfullscreen) /* no support placing fullscreen windows by mouse */
- return;
- restack(selmon);
- prevr = c;
- if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
- None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess)
- return;
-
- c->isfloating = 0;
- c->beingmoved = 1;
-
- XGetWindowAttributes(dpy, c->win, &wa);
- ocx = wa.x;
- ocy = wa.y;
-
- if (arg->i == 2) // warp cursor to client center
- XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, WIDTH(c) / 2, HEIGHT(c) / 2);
-
- if (!getrootptr(&x, &y))
- return;
-
- do {
- XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
- switch (ev.type) {
- case ConfigureRequest:
- case Expose:
- case MapRequest:
- handler[ev.type](&ev);
- break;
- case MotionNotify:
- if ((ev.xmotion.time - lasttime) <= (100 / 60))
- continue;
- lasttime = ev.xmotion.time;
-
- nx = ocx + (ev.xmotion.x - x);
- ny = ocy + (ev.xmotion.y - y);
-
- if (!freemove && (abs(nx - ocx) > snap || abs(ny - ocy) > snap))
- freemove = 1;
-
- if (freemove)
- XMoveWindow(dpy, c->win, nx, ny);
-
- if ((m = recttomon(ev.xmotion.x, ev.xmotion.y, 1, 1)) && m != selmon)
- selmon = m;
-
- if (arg->i == 1) { // tiled position is relative to the client window center point
- px = nx + wa.width / 2;
- py = ny + wa.height / 2;
- } else { // tiled position is relative to the mouse cursor
- px = ev.xmotion.x;
- py = ev.xmotion.y;
- }
-
- r = recttoclient(px, py, 1, 1);
-
- if (!r || r == c)
- break;
-
- attachmode = 0; // below
- if (((float)(r->y + r->h - py) / r->h) > ((float)(r->x + r->w - px) / r->w)) {
- if (abs(r->y - py) < r->h / 2)
- attachmode = 1; // above
- } else if (abs(r->x - px) < r->w / 2)
- attachmode = 1; // above
-
- if ((r && r != prevr) || (attachmode != prevattachmode)) {
- detachstack(c);
- detach(c);
- if (c->mon != r->mon) {
- arrangemon(c->mon);
- c->tags = r->mon->tagset[r->mon->seltags];
- }
-
- c->mon = r->mon;
- r->mon->sel = r;
-
- if (attachmode) {
- if (r == r->mon->clients)
- attach(c);
- else {
- for (at = r->mon->clients; at->next != r; at = at->next);
- c->next = at->next;
- at->next = c;
- }
- } else {
- c->next = r->next;
- r->next = c;
- }
-
- attachstack(c);
- arrangemon(r->mon);
- prevr = r;
- prevattachmode = attachmode;
- }
- break;
- }
- } while (ev.type != ButtonRelease);
- XUngrabPointer(dpy, CurrentTime);
-
- if ((m = recttomon(ev.xmotion.x, ev.xmotion.y, 1, 1)) && m != c->mon) {
- detach(c);
- detachstack(c);
- arrangemon(c->mon);
- c->mon = m;
- c->tags = m->tagset[m->seltags];
- attach(c);
- attachstack(c);
- selmon = m;
- }
-
- focus(c);
- c->beingmoved = 0;
-
- if (nx != -9999)
- resize(c, nx, ny, c->w, c->h, 0);
- arrangemon(c->mon);
-}
-
-void
-pop(Client *c)
-{
- detach(c);
- attach(c);
- focus(c);
- arrange(c->mon);
-}
-
-void
-propertynotify(XEvent *e)
-{
- Client *c;
- Window trans;
- XPropertyEvent *ev = &e->xproperty;
-
- if ((c = wintosystrayicon(ev->window))) {
- if (ev->atom == XA_WM_NORMAL_HINTS) {
- updatesizehints(c);
- updatesystrayicongeom(c, c->w, c->h);
- }
- else
- updatesystrayiconstate(c, ev);
- resizebarwin(selmon);
- updatesystray();
- }
-
- if ((ev->window == root) && (ev->atom == XA_WM_NAME))
- updatestatus();
- else if (ev->state == PropertyDelete)
- return; /* ignore */
- else if ((c = wintoclient(ev->window))) {
- switch(ev->atom) {
- default: break;
- case XA_WM_TRANSIENT_FOR:
- if (!c->isfloating && (XGetTransientForHint(dpy, c->win, &trans)) &&
- (c->isfloating = (wintoclient(trans)) != NULL))
- arrange(c->mon);
- break;
- case XA_WM_NORMAL_HINTS:
- updatesizehints(c);
- break;
- case XA_WM_HINTS:
- updatewmhints(c);
- drawbars();
- break;
- }
- if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) {
- updatetitle(c);
- if (showtitle && c == c->mon->sel)
- drawbar(c->mon);
- }
- if (ev->atom == netatom[NetWMWindowType])
- updatewindowtype(c);
- }
-}
-
-void
-restart(const Arg *arg)
-{
- restartsig = 1;
- quit(arg);
-}
-
-void
-quit(const Arg *arg)
-{
- running = 0;
-}
-
-Client *
-recttoclient(int x, int y, int w, int h)
-{
- Client *c, *r = NULL;
- int a, area = 0;
-
- for (c = nexttiled(selmon->clients); c; c = nexttiled(c->next)) {
- if ((a = INTERSECTC(x, y, w, h, c)) > area) {
- area = a;
- r = c;
- }
- }
- return r;
-}
-
-Monitor *
-recttomon(int x, int y, int w, int h)
-{
- Monitor *m, *r = selmon;
- int a, area = 0;
-
- for (m = mons; m; m = m->next)
- if ((a = INTERSECT(x, y, w, h, m)) > area) {
- area = a;
- r = m;
- }
- return r;
-}
-
-void
-removesystrayicon(Client *i)
-{
- Client **ii;
-
- if (!showsystray || !i)
- return;
- for (ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next);
- if (ii)
- *ii = i->next;
- free(i);
-}
-
-void
-resize(Client *c, int x, int y, int w, int h, int interact)
-{
- if (applysizehints(c, &x, &y, &w, &h, interact))
- resizeclient(c, x, y, w, h);
-}
-
-void
-resizebarwin(Monitor *m) {
- unsigned int w = m->ww;
- if (showsystray && m == systraytomon(m) && !systrayonleft)
- w -= getsystraywidth();
- XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh);
-}
-
-void
-resizeclient(Client *c, int x, int y, int w, int h)
-{
- XWindowChanges wc;
-
- c->oldx = c->x; c->x = wc.x = x;
- c->oldy = c->y; c->y = wc.y = y;
- c->oldw = c->w; c->w = wc.width = w;
- c->oldh = c->h; c->h = wc.height = h;
-
- if (c->beingmoved)
- return;
-
- wc.border_width = c->bw;
- if (((nexttiled(c->mon->clients) == c && !nexttiled(c->next))
- || &monocle == c->mon->lt[c->mon->sellt]->arrange)
- && !c->isfullscreen && !c->isfloating
- && NULL != c->mon->lt[c->mon->sellt]->arrange) {
- c->w = wc.width += c->bw * 2;
- c->h = wc.height += c->bw * 2;
- wc.border_width = 0;
- }
- XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
- configure(c);
- XSync(dpy, False);
-}
-
-void
-resizemouse(const Arg *arg)
-{
- int ocx, ocy, nw, nh;
- Client *c;
- Monitor *m;
- XEvent ev;
- Time lasttime = 0;
-
- if (!(c = selmon->sel))
- return;
- if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */
- return;
- restack(selmon);
- ocx = c->x;
- ocy = c->y;
- if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
- None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess)
- return;
- XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
- do {
- XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
- switch(ev.type) {
- case ConfigureRequest:
- case Expose:
- case MapRequest:
- handler[ev.type](&ev);
- break;
- case MotionNotify:
- if ((ev.xmotion.time - lasttime) <= (1000 / 60))
- continue;
- lasttime = ev.xmotion.time;
-
- nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1);
- nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1);
- if (c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww
- && c->mon->wy + nh >= selmon->wy && c->mon->wy + nh <= selmon->wy + selmon->wh)
- {
- if (!c->isfloating && selmon->lt[selmon->sellt]->arrange
- && (abs(nw - c->w) > snap || abs(nh - c->h) > snap))
- togglefloating(NULL);
- }
- if (!selmon->lt[selmon->sellt]->arrange || c->isfloating)
- resize(c, c->x, c->y, nw, nh, 1);
- break;
- }
- } while (ev.type != ButtonRelease);
- XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
- XUngrabPointer(dpy, CurrentTime);
- while (XCheckMaskEvent(dpy, EnterWindowMask, &ev));
- if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) {
- sendmon(c, m);
- selmon = m;
- focus(NULL);
- }
-}
-
-void
-resizerequest(XEvent *e)
-{
- XResizeRequestEvent *ev = &e->xresizerequest;
- Client *i;
-
- if ((i = wintosystrayicon(ev->window))) {
- updatesystrayicongeom(i, ev->width, ev->height);
- resizebarwin(selmon);
- updatesystray();
- }
-}
-
-void
-restack(Monitor *m)
-{
- Client *c;
- XEvent ev;
- XWindowChanges wc;
-
- drawbar(m);
- if (!m->sel)
- return;
- if (m->sel->isfloating || !m->lt[m->sellt]->arrange)
- XRaiseWindow(dpy, m->sel->win);
- if (m->lt[m->sellt]->arrange) {
- wc.stack_mode = Below;
- wc.sibling = m->barwin;
- for (c = m->stack; c; c = c->snext)
- if (!c->isfloating && ISVISIBLE(c)) {
- XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc);
- wc.sibling = c->win;
- }
- }
- XSync(dpy, False);
- while (XCheckMaskEvent(dpy, EnterWindowMask, &ev));
- if (m == selmon && (m->tagset[m->seltags] & m->sel->tags) && selmon->lt[selmon->sellt] != &layouts[2])
- warp(m->sel);
-}
-
-void
-run(void)
-{
- XEvent ev;
- /* main event loop */
- XSync(dpy, False);
- while (running && !XNextEvent(dpy, &ev))
- if (handler[ev.type])
- handler[ev.type](&ev); /* call handler */
-}
-
-void
-scan(void)
-{
- unsigned int i, num;
- Window d1, d2, *wins = NULL;
- XWindowAttributes wa;
-
- if (XQueryTree(dpy, root, &d1, &d2, &wins, &num)) {
- for (i = 0; i < num; i++) {
- if (!XGetWindowAttributes(dpy, wins[i], &wa)
- || wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1))
- continue;
- if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)
- manage(wins[i], &wa);
- }
- for (i = 0; i < num; i++) { /* now the transients */
- if (!XGetWindowAttributes(dpy, wins[i], &wa))
- continue;
- if (XGetTransientForHint(dpy, wins[i], &d1)
- && (wa.map_state == IsViewable || getstate(wins[i]) == IconicState))
- manage(wins[i], &wa);
- }
- if (wins)
- XFree(wins);
- }
-}
-
-void
-sendmon(Client *c, Monitor *m)
-{
- if (c->mon == m)
- return;
- unfocus(c, 1);
- detach(c);
- detachstack(c);
- c->mon = m;
- c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
- attachbottom(c);
- attachstack(c);
- focus(NULL);
- arrange(NULL);
-}
-
-void
-setclientstate(Client *c, long state)
-{
- long data[] = { state, None };
-
- XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32,
- PropModeReplace, (unsigned char *)data, 2);
-}
-
-int
-sendevent(Window w, Atom proto, int mask, long d0, long d1, long d2, long d3, long d4)
-{
- int n;
- Atom *protocols, mt;
- int exists = 0;
- XEvent ev;
-
- if (proto == wmatom[WMTakeFocus] || proto == wmatom[WMDelete]) {
- mt = wmatom[WMProtocols];
- if (XGetWMProtocols(dpy, w, &protocols, &n)) {
- while (!exists && n--)
- exists = protocols[n] == proto;
- XFree(protocols);
- }
- }
- else {
- exists = True;
- mt = proto;
- }
-
- if (exists) {
- ev.type = ClientMessage;
- ev.xclient.window = w;
- ev.xclient.message_type = mt;
- ev.xclient.format = 32;
- ev.xclient.data.l[0] = d0;
- ev.xclient.data.l[1] = d1;
- ev.xclient.data.l[2] = d2;
- ev.xclient.data.l[3] = d3;
- ev.xclient.data.l[4] = d4;
- XSendEvent(dpy, w, False, mask, &ev);
- }
- return exists;
-}
-
-void
-setfocus(Client *c)
-{
- if (!c->neverfocus) {
- XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
- XChangeProperty(dpy, root, netatom[NetActiveWindow],
- XA_WINDOW, 32, PropModeReplace,
- (unsigned char *) &(c->win), 1);
- }
- sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0);
-}
-
-void
-setfullscreen(Client *c, int fullscreen)
-{
- if (fullscreen && !c->isfullscreen) {
- XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32,
- PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1);
- c->isfullscreen = 1;
- c->oldstate = c->isfloating;
- c->oldbw = c->bw;
- c->bw = 0;
- c->isfloating = 1;
- resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh);
- XRaiseWindow(dpy, c->win);
- } else if (!fullscreen && c->isfullscreen){
- XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32,
- PropModeReplace, (unsigned char*)0, 0);
- c->isfullscreen = 0;
- c->isfloating = c->oldstate;
- c->bw = c->oldbw;
- c->x = c->oldx;
- c->y = c->oldy;
- c->w = c->oldw;
- c->h = c->oldh;
- resizeclient(c, c->x, c->y, c->w, c->h);
- arrange(c->mon);
- }
-}
-
-void
-setgaps(const Arg *arg)
-{
- if ((arg->i == 0) || (selmon->gappx + arg->i < 0))
- selmon->gappx = 0;
- else
- selmon->gappx += arg->i;
- arrange(selmon);
-}
-
-void
-setlayout(const Arg *arg)
-{
- if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
- selmon->sellt ^= 1;
- if (arg && arg->v)
- selmon->lt[selmon->sellt] = (Layout *)arg->v;
- strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol);
- if (selmon->sel)
- arrange(selmon);
- else
- drawbar(selmon);
-}
-
-/* arg > 1.0 will set mfact absolutely */
-void
-setmfact(const Arg *arg)
-{
- float f;
-
- if (!arg || !selmon->lt[selmon->sellt]->arrange)
- return;
- f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
- if (f < 0.05 || f > 0.95)
- return;
- selmon->mfact = f;
- arrange(selmon);
-}
-
-void
-setup(void)
-{
- int i;
- XSetWindowAttributes wa;
- Atom utf8string;
-
- /* clean up any zombies immediately */
- sigchld(0);
-
- signal(SIGHUP, sighup);
- signal(SIGTERM, sigterm);
-
- /* init screen */
- screen = DefaultScreen(dpy);
- sw = DisplayWidth(dpy, screen);
- sh = DisplayHeight(dpy, screen);
- root = RootWindow(dpy, screen);
- drw = drw_create(dpy, screen, root, sw, sh);
- if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
- die("no fonts could be loaded.");
- lrpad = drw->fonts->h;
- bh = drw->fonts->h + barheight * 2;
- updategeom();
- /* init atoms */
- utf8string = XInternAtom(dpy, "UTF8_STRING", False);
- wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
- wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
- wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False);
- wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
- netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
- netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
- netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", False);
- netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", False);
- netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False);
- netatom[NetSystemTrayOrientationHorz] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION_HORZ", False);
- netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
- netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
- netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
- netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
- netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
- netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
- netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
- netatom[NetClientInfo] = XInternAtom(dpy, "_NET_CLIENT_INFO", False);
- xatom[Manager] = XInternAtom(dpy, "MANAGER", False);
- xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False);
- xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False);
- /* init cursors */
- cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
- cursor[CurResize] = drw_cur_create(drw, XC_sizing);
- cursor[CurMove] = drw_cur_create(drw, XC_fleur);
- /* init appearance */
- if (colorfultag) {
- if (LENGTH(tags) > LENGTH(colortags) || LENGTH(tags) > LENGTH(colortags_sel))
- die("too few color schemes for the tags");
- tagscheme = ecalloc(LENGTH(colortags), sizeof(Clr *));
- for (i = 0; i < LENGTH(colortags); i++)
- tagscheme[i] = drw_scm_create(drw, colortags[i], 2);
- tagscheme_sel = ecalloc(LENGTH(colortags_sel), sizeof(Clr *));
- for (i = 0; i < LENGTH(colortags_sel); i++)
- tagscheme_sel[i] = drw_scm_create(drw, colortags_sel[i], 2);
- }
- scheme = ecalloc(LENGTH(colors) + 1, sizeof(Clr *));
- scheme[LENGTH(colors)] = drw_scm_create(drw, colors[0], 3);
- for (i = 0; i < LENGTH(colors); i++)
- scheme[i] = drw_scm_create(drw, colors[i], 3);
- /* init system tray */
- updatesystray();
- /* init bars */
- updatebars();
- updatestatus();
- /* supporting window for NetWMCheck */
- wmcheckwin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0);
- XChangeProperty(dpy, wmcheckwin, netatom[NetWMCheck], XA_WINDOW, 32,
- PropModeReplace, (unsigned char *) &wmcheckwin, 1);
- XChangeProperty(dpy, wmcheckwin, netatom[NetWMName], utf8string, 8,
- PropModeReplace, (unsigned char *) "dwm", 3);
- XChangeProperty(dpy, root, netatom[NetWMCheck], XA_WINDOW, 32,
- PropModeReplace, (unsigned char *) &wmcheckwin, 1);
- /* EWMH support per view */
- XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
- PropModeReplace, (unsigned char *) netatom, NetLast);
- XDeleteProperty(dpy, root, netatom[NetClientList]);
- XDeleteProperty(dpy, root, netatom[NetClientInfo]);
- /* select events */
- wa.cursor = cursor[CurNormal]->cursor;
- wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask
- |ButtonPressMask|PointerMotionMask|EnterWindowMask
- |LeaveWindowMask|StructureNotifyMask|PropertyChangeMask;
- XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa);
- XSelectInput(dpy, root, wa.event_mask);
- grabkeys();
- focus(NULL);
-}
-
-
-void
-seturgent(Client *c, int urg)
-{
- XWMHints *wmh;
-
- c->isurgent = urg;
- if (!(wmh = XGetWMHints(dpy, c->win)))
- return;
- wmh->flags = urg ? (wmh->flags | XUrgencyHint) : (wmh->flags & ~XUrgencyHint);
- XSetWMHints(dpy, c->win, wmh);
- XFree(wmh);
-}
-
-void
-showhide(Client *c)
-{
- if (!c)
- return;
- if (ISVISIBLE(c)) {
- /* show clients top down */
- XMoveWindow(dpy, c->win, c->x, c->y);
- if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen)
- resize(c, c->x, c->y, c->w, c->h, 0);
- showhide(c->snext);
- } else {
- /* hide clients bottom up */
- showhide(c->snext);
- XMoveWindow(dpy, c->win, WIDTH(c) * -2, c->y);
- }
-}
-
-void
-sigchld(int unused)
-{
- if (signal(SIGCHLD, sigchld) == SIG_ERR)
- die("can't install SIGCHLD handler:");
- while (0 < waitpid(-1, NULL, WNOHANG));
-}
-
-void
-sighup(int unused)
-{
- Arg a = {.i = 1};
- quit(&a);
-}
-
-void
-sigterm(int unused)
-{
- Arg a = {.i = 0};
- quit(&a);
-}
-
-void
-spawn(const Arg *arg)
-{
- if (arg->v == dmenucmd)
- dmenumon[0] = '0' + selmon->num;
- if (fork() == 0) {
- if (dpy)
- close(ConnectionNumber(dpy));
- setsid();
- execvp(((char **)arg->v)[0], (char **)arg->v);
- die("dwm: execvp '%s' failed:", ((char **)arg->v)[0]);
- }
-}
-
-void
-setclienttagprop(Client *c)
-{
- long data[] = { (long) c->tags, (long) c->mon->num };
- XChangeProperty(dpy, c->win, netatom[NetClientInfo], XA_CARDINAL, 32,
- PropModeReplace, (unsigned char *) data, 2);
-}
-
-
-void
-tag(const Arg *arg)
-{
- Client *c;
- if (selmon->sel && arg->ui & TAGMASK) {
- c = selmon->sel;
- selmon->sel->tags = arg->ui & TAGMASK;
- setclienttagprop(c);
- focus(NULL);
- arrange(selmon);
- }
-}
-
-void
-tagmon(const Arg *arg)
-{
- if (!selmon->sel || !mons->next)
- return;
- sendmon(selmon->sel, dirtomon(arg->i));
-}
-
-void
-tagnthmon(const Arg *arg)
-{
- if (!selmon->sel || !mons->next)
- return;
- sendmon(selmon->sel, numtomon(arg->i));
-}
-
-void
-tile(Monitor *m)
-{
- unsigned int i, n, h, mw, my, ty;
- Client *c;
-
- for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
- if (n == 0)
- return;
-
- if (n > m->nmaster)
- mw = m->nmaster ? m->ww * m->mfact : 0;
- else
- mw = m->ww - m->gappx;
- for (i = 0, my = ty = m->gappx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
- if (i < m->nmaster) {
- h = (m->wh - my) / (MIN(n, m->nmaster) - i) - m->gappx;
- resize(c, m->wx + m->gappx, m->wy + my, mw - (2*c->bw) - m->gappx, h - (2*c->bw), 0);
- if (my + HEIGHT(c) + m->gappx < m->wh)
- my += HEIGHT(c) + m->gappx;
- } else {
- h = (m->wh - ty) / (n - i) - m->gappx;
- resize(c, m->wx + mw + m->gappx, m->wy + ty, m->ww - mw - (2*c->bw) - 2*m->gappx, h - (2*c->bw), 0);
- if (ty + HEIGHT(c) + m->gappx < m->wh)
- ty += HEIGHT(c) + m->gappx;
- }
-}
-
-void
-togglebar(const Arg *arg)
-{
- selmon->showbar = !selmon->showbar;
- updatebarpos(selmon);
- resizebarwin(selmon);
- if (showsystray) {
- XWindowChanges wc;
- if (!selmon->showbar)
- wc.y = -bh;
- else if (selmon->showbar) {
- wc.y = 0;
- if (!selmon->topbar)
- wc.y = selmon->mh - bh;
- }
- XConfigureWindow(dpy, systray->win, CWY, &wc);
- }
- arrange(selmon);
-}
-
-void
-togglefloating(const Arg *arg)
-{
- if (!selmon->sel)
- return;
- if (selmon->sel->isfullscreen) /* no support for fullscreen windows */
- return;
- selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed;
- if (selmon->sel->isfloating)
- resize(selmon->sel, selmon->sel->x, selmon->sel->y,
- selmon->sel->w, selmon->sel->h, 0);
- arrange(selmon);
-}
-
-void
-togglesticky(const Arg *arg)
-{
- if (!selmon->sel)
- return;
- selmon->sel->issticky = !selmon->sel->issticky;
- arrange(selmon);
-}
-
-void
-togglefullscr(const Arg *arg)
-{
- if(selmon->sel)
- setfullscreen(selmon->sel, !selmon->sel->isfullscreen);
-}
-
-void
-toggletag(const Arg *arg)
-{
- unsigned int newtags;
-
- if (!selmon->sel)
- return;
- newtags = selmon->sel->tags ^ (arg->ui & TAGMASK);
- if (newtags) {
- selmon->sel->tags = newtags;
- setclienttagprop(selmon->sel);
- focus(NULL);
- arrange(selmon);
- }
-}
-
-void
-toggleview(const Arg *arg)
-{
- unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);
-
- if (newtagset) {
- selmon->tagset[selmon->seltags] = newtagset;
- focus(NULL);
- arrange(selmon);
- }
-}
-
-void
-unfocus(Client *c, int setfocus)
-{
- if (!c)
- return;
- grabbuttons(c, 0);
- XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel);
- if (setfocus) {
- XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
- XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
- }
-}
-
-void
-unmanage(Client *c, int destroyed)
-{
- Monitor *m = c->mon;
- XWindowChanges wc;
-
- detach(c);
- detachstack(c);
- if (!destroyed) {
- wc.border_width = c->oldbw;
- XGrabServer(dpy); /* avoid race conditions */
- XSetErrorHandler(xerrordummy);
- XSelectInput(dpy, c->win, NoEventMask);
- XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */
- XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
- setclientstate(c, WithdrawnState);
- XSync(dpy, False);
- XSetErrorHandler(xerror);
- XUngrabServer(dpy);
- }
- free(c);
- focus(NULL);
- updateclientlist();
- arrange(m);
-}
-
-void
-unmapnotify(XEvent *e)
-{
- Client *c;
- XUnmapEvent *ev = &e->xunmap;
-
- if ((c = wintoclient(ev->window))) {
- if (ev->send_event)
- setclientstate(c, WithdrawnState);
- else
- unmanage(c, 0);
- }
- else if ((c = wintosystrayicon(ev->window))) {
- /* KLUDGE! sometimes icons occasionally unmap their windows, but do
- * _not_ destroy them. We map those windows back */
- XMapRaised(dpy, c->win);
- updatesystray();
- }
-}
-
-void
-updatebars(void)
-{
- unsigned int w;
- Monitor *m;
- XSetWindowAttributes wa = {
- .override_redirect = True,
- .background_pixmap = ParentRelative,
- .event_mask = ButtonPressMask|ExposureMask
- };
- XClassHint ch = {"dwm", "dwm"};
- for (m = mons; m; m = m->next) {
- if (m->barwin)
- continue;
- w = m->ww;
- if (showsystray && m == systraytomon(m))
- w -= getsystraywidth();
- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, w, bh, 0, DefaultDepth(dpy, screen),
- CopyFromParent, DefaultVisual(dpy, screen),
- CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
- XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
- if (showsystray && m == systraytomon(m))
- XMapRaised(dpy, systray->win);
- XMapRaised(dpy, m->barwin);
- XSetClassHint(dpy, m->barwin, &ch);
- }
-}
-
-void
-updatebarpos(Monitor *m)
-{
- m->wy = m->my;
- m->wh = m->mh;
- if (m->showbar) {
- m->wh -= bh;
- m->by = m->topbar ? m->wy : m->wy + m->wh;
- m->wy = m->topbar ? m->wy + bh : m->wy;
- } else
- m->by = -bh;
-}
-
-void
-updateclientlist()
-{
- Client *c;
- Monitor *m;
-
- XDeleteProperty(dpy, root, netatom[NetClientList]);
- for (m = mons; m; m = m->next)
- for (c = m->clients; c; c = c->next)
- XChangeProperty(dpy, root, netatom[NetClientList],
- XA_WINDOW, 32, PropModeAppend,
- (unsigned char *) &(c->win), 1);
-}
-
-int
-updategeom(void)
-{
- int dirty = 0;
-
-#ifdef XINERAMA
- if (XineramaIsActive(dpy)) {
- int i, j, n, nn;
- Client *c;
- Monitor *m;
- XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn);
- XineramaScreenInfo *unique = NULL;
-
- for (n = 0, m = mons; m; m = m->next, n++);
- /* only consider unique geometries as separate screens */
- unique = ecalloc(nn, sizeof(XineramaScreenInfo));
- for (i = 0, j = 0; i < nn; i++)
- if (isuniquegeom(unique, j, &info[i]))
- memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo));
- XFree(info);
- nn = j;
- if (n <= nn) { /* new monitors available */
- for (i = 0; i < (nn - n); i++) {
- for (m = mons; m && m->next; m = m->next);
- if (m)
- m->next = createmon();
- else
- mons = createmon();
- }
- for (i = 0, m = mons; i < nn && m; m = m->next, i++)
- if (i >= n
- || unique[i].x_org != m->mx || unique[i].y_org != m->my
- || unique[i].width != m->mw || unique[i].height != m->mh)
- {
- dirty = 1;
- m->num = i;
- m->mx = m->wx = unique[i].x_org;
- m->my = m->wy = unique[i].y_org;
- m->mw = m->ww = unique[i].width;
- m->mh = m->wh = unique[i].height;
- updatebarpos(m);
- }
- } else { /* less monitors available nn < n */
- for (i = nn; i < n; i++) {
- for (m = mons; m && m->next; m = m->next);
- while ((c = m->clients)) {
- dirty = 1;
- m->clients = c->next;
- detachstack(c);
- c->mon = mons;
- attachbottom(c);
- attachstack(c);
- }
- if (m == selmon)
- selmon = mons;
- cleanupmon(m);
- }
- }
- free(unique);
- } else
-#endif /* XINERAMA */
- { /* default monitor setup */
- if (!mons)
- mons = createmon();
- if (mons->mw != sw || mons->mh != sh) {
- dirty = 1;
- mons->mw = mons->ww = sw;
- mons->mh = mons->wh = sh;
- updatebarpos(mons);
- }
- }
- if (dirty) {
- selmon = mons;
- selmon = wintomon(root);
- }
- return dirty;
-}
-
-void
-updatenumlockmask(void)
-{
- unsigned int i, j;
- XModifierKeymap *modmap;
-
- numlockmask = 0;
- modmap = XGetModifierMapping(dpy);
- for (i = 0; i < 8; i++)
- for (j = 0; j < modmap->max_keypermod; j++)
- if (modmap->modifiermap[i * modmap->max_keypermod + j]
- == XKeysymToKeycode(dpy, XK_Num_Lock))
- numlockmask = (1 << i);
- XFreeModifiermap(modmap);
-}
-
-void
-updatesizehints(Client *c)
-{
- long msize;
- XSizeHints size;
-
- if (!XGetWMNormalHints(dpy, c->win, &size, &msize))
- /* size is uninitialized, ensure that size.flags aren't used */
- size.flags = PSize;
- if (size.flags & PBaseSize) {
- c->basew = size.base_width;
- c->baseh = size.base_height;
- } else if (size.flags & PMinSize) {
- c->basew = size.min_width;
- c->baseh = size.min_height;
- } else
- c->basew = c->baseh = 0;
- if (size.flags & PResizeInc) {
- c->incw = size.width_inc;
- c->inch = size.height_inc;
- } else
- c->incw = c->inch = 0;
- if (size.flags & PMaxSize) {
- c->maxw = size.max_width;
- c->maxh = size.max_height;
- } else
- c->maxw = c->maxh = 0;
- if (size.flags & PMinSize) {
- c->minw = size.min_width;
- c->minh = size.min_height;
- } else if (size.flags & PBaseSize) {
- c->minw = size.base_width;
- c->minh = size.base_height;
- } else
- c->minw = c->minh = 0;
- if (size.flags & PAspect) {
- c->mina = (float)size.min_aspect.y / size.min_aspect.x;
- c->maxa = (float)size.max_aspect.x / size.max_aspect.y;
- } else
- c->maxa = c->mina = 0.0;
- c->isfixed = (c->maxw && c->maxh && c->maxw == c->minw && c->maxh == c->minh);
-}
-
-void
-updatestatus(void)
-{
- Monitor* m;
- if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
- strcpy(stext, "dwm-"VERSION);
- for(m = mons; m; m = m->next) {
- drawbar(m);
- updatesystray();
- }
-}
-
-void
-updatesystrayicongeom(Client *i, int w, int h)
-{
- if (i) {
- i->h = bh;
- if (w == h)
- i->w = bh;
- else if (h == bh)
- i->w = w;
- else
- i->w = (int) ((float)bh * ((float)w / (float)h));
- applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False);
- /* force icons into the systray dimensions if they don't want to */
- if (i->h > bh) {
- if (i->w == i->h)
- i->w = bh;
- else
- i->w = (int) ((float)bh * ((float)i->w / (float)i->h));
- i->h = bh;
- }
- }
-}
-
-void
-updatesystrayiconstate(Client *i, XPropertyEvent *ev)
-{
- long flags;
- int code = 0;
-
- if (!showsystray || !i || ev->atom != xatom[XembedInfo] ||
- !(flags = getatomprop(i, xatom[XembedInfo])))
- return;
-
- if (flags & XEMBED_MAPPED && !i->tags) {
- i->tags = 1;
- code = XEMBED_WINDOW_ACTIVATE;
- XMapRaised(dpy, i->win);
- setclientstate(i, NormalState);
- }
- else if (!(flags & XEMBED_MAPPED) && i->tags) {
- i->tags = 0;
- code = XEMBED_WINDOW_DEACTIVATE;
- XUnmapWindow(dpy, i->win);
- setclientstate(i, WithdrawnState);
- }
- else
- return;
- sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0,
- systray->win, XEMBED_EMBEDDED_VERSION);
-}
-void
-updatesystray(void)
-{
- XSetWindowAttributes wa;
- XWindowChanges wc;
- Client *i;
- Monitor *m = systraytomon(NULL);
- unsigned int x = m->mx + m->mw;
- unsigned int sw = TEXTW(stext) - lrpad + systrayspacing;
- unsigned int w = 1;
-
- if (!showsystray)
- return;
- if (systrayonleft)
- x -= sw + lrpad / 2;
- if (!systray) {
- /* init systray */
- if (!(systray = (Systray *)calloc(1, sizeof(Systray))))
- die("fatal: could not malloc() %u bytes\n", sizeof(Systray));
- systray->win = XCreateSimpleWindow(dpy, root, x, m->by, w, bh, 0, 0, scheme[SchemeSel][ColBg].pixel);
- wa.event_mask = ButtonPressMask | ExposureMask;
- wa.override_redirect = True;
- wa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
- XSelectInput(dpy, systray->win, SubstructureNotifyMask);
- XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32,
- PropModeReplace, (unsigned char *)&netatom[NetSystemTrayOrientationHorz], 1);
- XChangeWindowAttributes(dpy, systray->win, CWEventMask|CWOverrideRedirect|CWBackPixel, &wa);
- XMapRaised(dpy, systray->win);
- XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime);
- if (XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) {
- sendevent(root, xatom[Manager], StructureNotifyMask, CurrentTime, netatom[NetSystemTray], systray->win, 0, 0);
- XSync(dpy, False);
- }
- else {
- fprintf(stderr, "dwm: unable to obtain system tray.\n");
- free(systray);
- systray = NULL;
- return;
- }
- }
- for (w = 0, i = systray->icons; i; i = i->next) {
- /* make sure the background color stays the same */
- wa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
- XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa);
- XMapRaised(dpy, i->win);
- w += systrayspacing;
- i->x = w;
- XMoveResizeWindow(dpy, i->win, i->x, 0, i->w, i->h);
- w += i->w;
- if (i->mon != m)
- i->mon = m;
- }
- w = w ? w + systrayspacing : 1;
- x -= w;
- XMoveResizeWindow(dpy, systray->win, x, m->by, w, bh);
- wc.x = x; wc.y = m->by; wc.width = w; wc.height = bh;
- wc.stack_mode = Above; wc.sibling = m->barwin;
- XConfigureWindow(dpy, systray->win, CWX|CWY|CWWidth|CWHeight|CWSibling|CWStackMode, &wc);
- XMapWindow(dpy, systray->win);
- XMapSubwindows(dpy, systray->win);
- /* redraw background */
- XSetForeground(dpy, drw->gc, scheme[SchemeNorm][ColBg].pixel);
- XFillRectangle(dpy, systray->win, drw->gc, 0, 0, w, bh);
- XSync(dpy, False);
-}
-
-void
-updatetitle(Client *c)
-{
- if (!gettextprop(c->win, netatom[NetWMName], c->name, sizeof c->name))
- gettextprop(c->win, XA_WM_NAME, c->name, sizeof c->name);
- if (c->name[0] == '\0') /* hack to mark broken clients */
- strcpy(c->name, broken);
-}
-
-void
-updatewindowtype(Client *c)
-{
- Atom state = getatomprop(c, netatom[NetWMState]);
- Atom wtype = getatomprop(c, netatom[NetWMWindowType]);
-
- if (state == netatom[NetWMFullscreen])
- setfullscreen(c, 1);
- if (wtype == netatom[NetWMWindowTypeDialog])
- c->isfloating = 1;
-}
-
-void
-updatewmhints(Client *c)
-{
- XWMHints *wmh;
-
- if ((wmh = XGetWMHints(dpy, c->win))) {
- if (c == selmon->sel && wmh->flags & XUrgencyHint) {
- wmh->flags &= ~XUrgencyHint;
- XSetWMHints(dpy, c->win, wmh);
- } else
- c->isurgent = (wmh->flags & XUrgencyHint) ? 1 : 0;
- if (wmh->flags & InputHint)
- c->neverfocus = !wmh->input;
- else
- c->neverfocus = 0;
- XFree(wmh);
- }
-}
-
-void
-view(const Arg *arg)
-{
- if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
- return;
- selmon->seltags ^= 1; /* toggle sel tagset */
- if (arg->ui & TAGMASK)
- selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
- focus(NULL);
- arrange(selmon);
-}
-
-void
-warp(const Client *c)
-{
- int x, y;
-
- if (!c) {
- XWarpPointer(dpy, None, root, 0, 0, 0, 0, selmon->wx + selmon->ww/2, selmon->wy + selmon->wh/2);
- return;
- }
-
- if (!getrootptr(&x, &y) ||
- (x > c->x - c->bw &&
- y > c->y - c->bw &&
- x < c->x + c->w + c->bw*2 &&
- y < c->y + c->h + c->bw*2) ||
- (y > c->mon->by && y < c->mon->by + bh) ||
- (c->mon->topbar && !y))
- return;
-
- XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2);
-}
-
-Client *
-wintoclient(Window w)
-{
- Client *c;
- Monitor *m;
-
- for (m = mons; m; m = m->next)
- for (c = m->clients; c; c = c->next)
- if (c->win == w)
- return c;
- return NULL;
-}
-
-Client *
-wintosystrayicon(Window w) {
- Client *i = NULL;
-
- if (!showsystray || !w)
- return i;
- for (i = systray->icons; i && i->win != w; i = i->next) ;
- return i;
-}
-
-Monitor *
-wintomon(Window w)
-{
- int x, y;
- Client *c;
- Monitor *m;
-
- if (w == root && getrootptr(&x, &y))
- return recttomon(x, y, 1, 1);
- for (m = mons; m; m = m->next)
- if (w == m->barwin)
- return m;
- if ((c = wintoclient(w)))
- return c->mon;
- return selmon;
-}
-
-/* There's no way to check accesses to destroyed windows, thus those cases are
- * ignored (especially on UnmapNotify's). Other types of errors call Xlibs
- * default error handler, which may call exit. */
-int
-xerror(Display *dpy, XErrorEvent *ee)
-{
- if (ee->error_code == BadWindow
- || (ee->request_code == X_SetInputFocus && ee->error_code == BadMatch)
- || (ee->request_code == X_PolyText8 && ee->error_code == BadDrawable)
- || (ee->request_code == X_PolyFillRectangle && ee->error_code == BadDrawable)
- || (ee->request_code == X_PolySegment && ee->error_code == BadDrawable)
- || (ee->request_code == X_ConfigureWindow && ee->error_code == BadMatch)
- || (ee->request_code == X_GrabButton && ee->error_code == BadAccess)
- || (ee->request_code == X_GrabKey && ee->error_code == BadAccess)
- || (ee->request_code == X_CopyArea && ee->error_code == BadDrawable))
- return 0;
- fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n",
- ee->request_code, ee->error_code);
- return xerrorxlib(dpy, ee); /* may call exit */
-}
-
-int
-xerrordummy(Display *dpy, XErrorEvent *ee)
-{
- return 0;
-}
-
-/* Startup Error handler to check if another window manager
- * is already running. */
-int
-xerrorstart(Display *dpy, XErrorEvent *ee)
-{
- die("dwm: another window manager is already running");
- return -1;
-}
-
-void
-movestack(const Arg *arg) {
- Client *c = NULL, *p = NULL, *pc = NULL, *i;
-
- if(arg->i > 0) {
- /* find the client after selmon->sel */
- for(c = selmon->sel->next; c && (!ISVISIBLE(c) || c->isfloating); c = c->next);
- if(!c)
- for(c = selmon->clients; c && (!ISVISIBLE(c) || c->isfloating); c = c->next);
-
- }
- else {
- /* find the client before selmon->sel */
- for(i = selmon->clients; i != selmon->sel; i = i->next)
- if(ISVISIBLE(i) && !i->isfloating)
- c = i;
- if(!c)
- for(; i; i = i->next)
- if(ISVISIBLE(i) && !i->isfloating)
- c = i;
- }
- /* find the client before selmon->sel and c */
- for(i = selmon->clients; i && (!p || !pc); i = i->next) {
- if(i->next == selmon->sel)
- p = i;
- if(i->next == c)
- pc = i;
- }
-
- /* swap c and selmon->sel selmon->clients in the selmon->clients list */
- if(c && c != selmon->sel) {
- Client *temp = selmon->sel->next==c?selmon->sel:selmon->sel->next;
- selmon->sel->next = c->next==selmon->sel?c:c->next;
- c->next = temp;
-
- if(p && p != c)
- p->next = c;
- if(pc && pc != selmon->sel)
- pc->next = selmon->sel;
-
- if(selmon->sel == selmon->clients)
- selmon->clients = c;
- else if(c == selmon->clients)
- selmon->clients = selmon->sel;
-
- arrange(selmon);
- }
-}
-
-void
-shiftview(const Arg *arg)
-{
- Arg a;
- Client *c;
- unsigned visible = 0;
- int i = arg->i;
- int count = 0;
- int nextseltags, curseltags = selmon->tagset[selmon->seltags];
-
- do {
- if(i > 0) // left circular shift
- nextseltags = (curseltags << i) | (curseltags >> (LENGTH(tags) - i));
- else // right circular shift
- nextseltags = curseltags >> (- i) | (curseltags << (LENGTH(tags) + i));
-
- // Check if tag is visible
- for (c = selmon->clients; c && !visible; c = c->next)
- if (nextseltags & c->tags) { visible = 1; break; }
-
- i += arg->i;
- } while (!visible && ++count < LENGTH(tags));
-
- if (count < LENGTH(tags)) {
- a.i = nextseltags;
- view(&a);
- }
-}
-
-Monitor *
-systraytomon(Monitor *m) {
- Monitor *t;
- int i, n;
- if(!systraypinning) {
- if(!m)
- return selmon;
- return m == selmon ? m : NULL;
- }
- for(n = 1, t = mons; t && t->next; n++, t = t->next) ;
- for(i = 1, t = mons; t && t->next && i < systraypinning; i++, t = t->next) ;
- if(systraypinningfailfirst && n < systraypinning)
- return mons;
- return t;
-}
-
-void
-zoom(const Arg *arg)
-{
- Client *c = selmon->sel;
-
- if (!selmon->lt[selmon->sellt]->arrange
- || (selmon->sel && selmon->sel->isfloating))
- return;
- if (c == nexttiled(selmon->clients))
- if (!c || !(c = nexttiled(c->next)))
- return;
- pop(c);
-}
-
-void
-resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst)
-{
- char *sdst = NULL;
- int *idst = NULL;
- float *fdst = NULL;
-
- sdst = dst;
- idst = dst;
- fdst = dst;
-
- char fullname[256];
- char *type;
- XrmValue ret;
-
- snprintf(fullname, sizeof(fullname), "%s.%s", "dwm", name);
- fullname[sizeof(fullname) - 1] = '\0';
-
- XrmGetResource(db, fullname, "*", &type, &ret);
- if (!(ret.addr == NULL || strncmp("String", type, 64)))
- {
- switch (rtype) {
- case STRING:
- strcpy(sdst, ret.addr);
- break;
- case INTEGER:
- *idst = strtoul(ret.addr, NULL, 10);
- break;
- case FLOAT:
- *fdst = strtof(ret.addr, NULL);
- break;
- }
- }
-}
-
-void
-live_reload_xresources(const Arg *arg)
-{
- load_xresources();
-
- Monitor *m;
- XSetWindowAttributes wa;
- unsigned int i;
-
- for (m = mons; m; m = m->next) {
-
- for(Client *c = m->clients; c; c = c->next) {
- XWindowChanges wc;
- wc.border_width = borderpx;
- XConfigureWindow(dpy, c->win, CWBorderWidth, &wc);
- }
-
- }
- for (i = 0; i < LENGTH(colors); i++)
- scheme[i] = drw_scm_create(drw, colors[i], 3);
-
- focus(NULL);
- arrange(NULL);
-}
-
-void
-load_xresources(void)
-{
- Display *display;
- char *resm;
- XrmDatabase db;
- ResourcePref *p;
-
- display = XOpenDisplay(NULL);
- resm = XResourceManagerString(display);
- if (!resm)
- return;
- db = XrmGetStringDatabase(resm);
- for ( p = resources; p < resources + LENGTH(resources); p++)
- resource_load(db, p->name, p->type, p->dst);
- XCloseDisplay(display);
-}
-
-
-int
-main(int argc, char *argv[])
-{
- if (argc == 2 && !strcmp("-v", argv[1]))
- die("dwm-"VERSION);
- else if (argc == 2 && !strcmp("-f", argv[1]))
- layouts_default = layouts_floating;
- else if (argc != 1 && strcmp("-s", argv[1]))
- die("usage: dwm [-fvh] [-s STATUS_TEXT]");
- if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
- fputs("warning: no locale support\n", stderr);
- if (!(dpy = XOpenDisplay(NULL)))
- die("dwm: cannot open display");
- if (argc > 1 && !strcmp("-s", argv[1])) {
- XStoreName(dpy, RootWindow(dpy, DefaultScreen(dpy)), argv[2]);
- XCloseDisplay(dpy);
- return 0;
- }
- checkotherwm();
- XrmInitialize();
- load_xresources();
- setup();
-#ifdef __OpenBSD__
- if (pledge("stdio rpath proc exec", NULL) == -1)
- die("pledge");
-#endif /* __OpenBSD__ */
- scan();
- run();
- if(restartsig)
- execvp(argv[0], argv);
- cleanup();
- XCloseDisplay(dpy);
- return EXIT_SUCCESS;
-}
-
diff --git a/.local/src/dwm/dwm.png b/.local/src/dwm/dwm.png
Binary files differ.
diff --git a/.local/src/dwm/patches/accessnthmon.diff b/.local/src/dwm/patches/accessnthmon.diff
@@ -1,100 +0,0 @@
-diff --git a/config.def.h b/config.def.h
-index 1c0b587..8595a71 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -49,7 +49,10 @@ static const Layout layouts[] = {
- { MODKEY, KEY, view, {.ui = 1 << TAG} }, \
- { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
- { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
-- { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
-+ { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, \
-+ { ALTMOD, KEY, focusnthmon, {.i = TAG } }, \
-+ { ALTMOD|ShiftMask, KEY, tagnthmon, {.i = TAG } },
-+
-
- /* helper for spawning shell commands in the pre dwm-5.0 fashion */
- #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
-diff --git a/dwm.c b/dwm.c
-index b0b3466..96fa0bd 100644
---- a/dwm.c
-+++ b/dwm.c
-@@ -161,6 +161,7 @@ static void destroynotify(XEvent *e);
- static void detach(Client *c);
- static void detachstack(Client *c);
- static Monitor *dirtomon(int dir);
-+static Monitor *numtomon(int num);
- static void drawbar(Monitor *m);
- static void drawbars(void);
- static void enternotify(XEvent *e);
-@@ -168,6 +169,7 @@ static void expose(XEvent *e);
- static void focus(Client *c);
- static void focusin(XEvent *e);
- static void focusmon(const Arg *arg);
-+static void focusnthmon(const Arg *arg);
- static void focusstack(const Arg *arg);
- static Atom getatomprop(Client *c, Atom prop);
- static int getrootptr(int *x, int *y);
-@@ -209,6 +211,7 @@ static void sigchld(int unused);
- static void spawn(const Arg *arg);
- static void tag(const Arg *arg);
- static void tagmon(const Arg *arg);
-+static void tagnthmon(const Arg *arg);
- static void tile(Monitor *);
- static void togglebar(const Arg *arg);
- static void togglefloating(const Arg *arg);
-@@ -693,6 +696,18 @@ dirtomon(int dir)
- return m;
- }
-
-+Monitor *
-+numtomon(int num)
-+{
-+ Monitor *m = NULL;
-+ int i = 0;
-+
-+ for(m = mons, i=0; m->next && i < num; m = m->next){
-+ i++;
-+ }
-+ return m;
-+}
-+
- void
- drawbar(Monitor *m)
- {
-@@ -830,6 +845,21 @@ focusmon(const Arg *arg)
- focus(NULL);
- }
-
-+void
-+focusnthmon(const Arg *arg)
-+{
-+ Monitor *m;
-+
-+ if (!mons->next)
-+ return;
-+
-+ if ((m = numtomon(arg->i)) == selmon)
-+ return;
-+ unfocus(selmon->sel, 0);
-+ selmon = m;
-+ focus(NULL);
-+}
-+
- void
- focusstack(const Arg *arg)
- {
-@@ -1671,6 +1701,14 @@ tagmon(const Arg *arg)
- sendmon(selmon->sel, dirtomon(arg->i));
- }
-
-+void
-+tagnthmon(const Arg *arg)
-+{
-+ if (!selmon->sel || !mons->next)
-+ return;
-+ sendmon(selmon->sel, numtomon(arg->i));
-+}
-+
- void
- tile(Monitor *m)
- {
diff --git a/.local/src/dwm/patches/dwm-actualfullscreen-20211013-cb3f58a.diff b/.local/src/dwm/patches/dwm-actualfullscreen-20211013-cb3f58a.diff
@@ -1,68 +0,0 @@
-From eea13010ffc3983392857ee1e3804e3aa1064d7a Mon Sep 17 00:00:00 2001
-From: Soenke Lambert <[email protected]>
-Date: Wed, 13 Oct 2021 18:21:09 +0200
-Subject: [PATCH] Fullscreen current window with [Alt]+[Shift]+[f]
-
-This actually fullscreens a window, instead of just hiding the statusbar
-and applying the monocle layout.
----
- config.def.h | 1 +
- dwm.1 | 3 +++
- dwm.c | 8 ++++++++
- 3 files changed, 12 insertions(+)
-
-diff --git a/config.def.h b/config.def.h
-index 1c0b587..8cd3204 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -78,6 +78,7 @@ static Key keys[] = {
- { MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
- { MODKEY, XK_space, setlayout, {0} },
- { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
-+ { MODKEY|ShiftMask, XK_f, togglefullscr, {0} },
- { MODKEY, XK_0, view, {.ui = ~0 } },
- { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
- { MODKEY, XK_comma, focusmon, {.i = -1 } },
-diff --git a/dwm.1 b/dwm.1
-index 13b3729..a368d05 100644
---- a/dwm.1
-+++ b/dwm.1
-@@ -116,6 +116,9 @@ Zooms/cycles focused window to/from master area (tiled layouts only).
- .B Mod1\-Shift\-c
- Close focused window.
- .TP
-+.B Mod1\-Shift\-f
-+Toggle fullscreen for focused window.
-+.TP
- .B Mod1\-Shift\-space
- Toggle focused window between tiled and floating state.
- .TP
-diff --git a/dwm.c b/dwm.c
-index 4465af1..c1b899a 100644
---- a/dwm.c
-+++ b/dwm.c
-@@ -211,6 +211,7 @@ static void tagmon(const Arg *arg);
- static void tile(Monitor *);
- static void togglebar(const Arg *arg);
- static void togglefloating(const Arg *arg);
-+static void togglefullscr(const Arg *arg);
- static void toggletag(const Arg *arg);
- static void toggleview(const Arg *arg);
- static void unfocus(Client *c, int setfocus);
-@@ -1719,6 +1720,13 @@ togglefloating(const Arg *arg)
- arrange(selmon);
- }
-
-+void
-+togglefullscr(const Arg *arg)
-+{
-+ if(selmon->sel)
-+ setfullscreen(selmon->sel, !selmon->sel->isfullscreen);
-+}
-+
- void
- toggletag(const Arg *arg)
- {
---
-2.30.2
-
diff --git a/.local/src/dwm/patches/dwm-attachbottom-20201227-61bb8b2.diff b/.local/src/dwm/patches/dwm-attachbottom-20201227-61bb8b2.diff
@@ -1,67 +0,0 @@
-From eea05f94baf707114ea882e8755520ba30d73cb2 Mon Sep 17 00:00:00 2001
-From: Szabolcs Szucs <[email protected]>
-Date: Sat, 26 Dec 2020 21:17:40 +0100
-Subject: [PATCH] attachbottom patch
-
----
- dwm.c | 16 +++++++++++++---
- 1 file changed, 13 insertions(+), 3 deletions(-)
-
-diff --git a/dwm.c b/dwm.c
-index 664c527..7ee3566 100644
---- a/dwm.c
-+++ b/dwm.c
-@@ -147,6 +147,7 @@ static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interac
- static void arrange(Monitor *m);
- static void arrangemon(Monitor *m);
- static void attach(Client *c);
-+static void attachbottom(Client *c);
- static void attachstack(Client *c);
- static void buttonpress(XEvent *e);
- static void checkotherwm(void);
-@@ -407,6 +408,15 @@ attach(Client *c)
- c->mon->clients = c;
- }
-
-+void
-+attachbottom(Client *c)
-+{
-+ Client **tc;
-+ c->next = NULL;
-+ for (tc = &c->mon->clients; *tc; tc = &(*tc)->next);
-+ *tc = c;
-+}
-+
- void
- attachstack(Client *c)
- {
-@@ -1063,7 +1073,7 @@ manage(Window w, XWindowAttributes *wa)
- c->isfloating = c->oldstate = trans != None || c->isfixed;
- if (c->isfloating)
- XRaiseWindow(dpy, c->win);
-- attach(c);
-+ attachbottom(c);
- attachstack(c);
- XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
- (unsigned char *) &(c->win), 1);
-@@ -1418,7 +1428,7 @@ sendmon(Client *c, Monitor *m)
- detachstack(c);
- c->mon = m;
- c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
-- attach(c);
-+ attachbottom(c);
- attachstack(c);
- focus(NULL);
- arrange(NULL);
-@@ -1900,7 +1910,7 @@ updategeom(void)
- m->clients = c->next;
- detachstack(c);
- c->mon = mons;
-- attach(c);
-+ attachbottom(c);
- attachstack(c);
- }
- if (m == selmon)
---
-2.29.2
-
diff --git a/.local/src/dwm/patches/dwm-bidi-20220309-0386419.diff b/.local/src/dwm/patches/dwm-bidi-20220309-0386419.diff
@@ -1,132 +0,0 @@
-From 0386419cfb5311d4a7516ece8f3f8fe923c43098 Mon Sep 17 00:00:00 2001
-From: MahdiMirzade <[email protected]>
-Date: Wed, 9 Mar 2022 17:44:42 +0330
-Subject: [PATCH] [PATCH] Added support for RTL languages (Farsi, Arabic and
- Hebrew using the FriBiDi library) - 9th Mar 2022 Fix
-
----
- config.mk | 8 ++++++--
- dwm.c | 40 +++++++++++++++++++++++++++++++++-------
- 2 files changed, 39 insertions(+), 9 deletions(-)
-
-diff --git a/config.mk b/config.mk
-index b6eb7e0..5b60a24 100644
---- a/config.mk
-+++ b/config.mk
-@@ -10,6 +10,8 @@ MANPREFIX = ${PREFIX}/share/man
- X11INC = /usr/X11R6/include
- X11LIB = /usr/X11R6/lib
-
-+BDINC = /usr/include/fribidi
-+
- # Xinerama, comment if you don't want it
- XINERAMALIBS = -lXinerama
- XINERAMAFLAGS = -DXINERAMA
-@@ -20,9 +22,11 @@ FREETYPEINC = /usr/include/freetype2
- # OpenBSD (uncomment)
- #FREETYPEINC = ${X11INC}/freetype2
-
-+BDLIBS = -lfribidi
-+
- # includes and libs
--INCS = -I${X11INC} -I${FREETYPEINC}
--LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
-+INCS = -I${X11INC} -I${FREETYPEINC} -I$(BDINC)
-+LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} $(BDLIBS)
-
- # flags
- CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
-diff --git a/dwm.c b/dwm.c
-index a96f33c..4f11fa0 100644
---- a/dwm.c
-+++ b/dwm.c
-@@ -40,6 +40,7 @@
- #include <X11/extensions/Xinerama.h>
- #endif /* XINERAMA */
- #include <X11/Xft/Xft.h>
-+#include <fribidi.h>
-
- #include "drw.h"
- #include "util.h"
-@@ -238,6 +239,7 @@ static void zoom(const Arg *arg);
- /* variables */
- static const char broken[] = "broken";
- static char stext[256];
-+static char fribidi_text[BUFSIZ] = "";
- static int screen;
- static int sw, sh; /* X display screen geometry width, height */
- static int bh, blw = 0; /* bar geometry */
-@@ -276,6 +278,26 @@ static Window root, wmcheckwin;
- struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
-
- /* function implementations */
-+static void
-+apply_fribidi(char *str)
-+{
-+ FriBidiStrIndex len = strlen(str);
-+ FriBidiChar logical[BUFSIZ];
-+ FriBidiChar visual[BUFSIZ];
-+ FriBidiParType base = FRIBIDI_PAR_ON;
-+ FriBidiCharSet charset;
-+ fribidi_boolean result;
-+
-+ fribidi_text[0] = 0;
-+ if (len>0)
-+ {
-+ charset = fribidi_parse_charset("UTF-8");
-+ len = fribidi_charset_to_unicode(charset, str, len, logical);
-+ result = fribidi_log2vis(logical, len, &base, visual, NULL, NULL, NULL);
-+ len = fribidi_unicode_to_charset(charset, visual, len, fribidi_text);
-+ }
-+}
-+
- void
- applyrules(Client *c)
- {
-@@ -708,8 +730,9 @@ drawbar(Monitor *m)
- /* draw status first so it can be overdrawn by tags later */
- if (m == selmon) { /* status is only drawn on selected monitor */
- drw_setscheme(drw, scheme[SchemeNorm]);
-- tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
-- drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
-+ apply_fribidi(stext);
-+ tw = TEXTW(fribidi_text) - lrpad + 2; /* 2px right padding */
-+ drw_text(drw, m->ww - tw, 0, tw, bh, 0, fribidi_text, 0);
- }
-
- for (c = m->clients; c; c = c->next) {
-@@ -719,23 +742,26 @@ drawbar(Monitor *m)
- }
- x = 0;
- for (i = 0; i < LENGTH(tags); i++) {
-- w = TEXTW(tags[i]);
-+ apply_fribidi(tags[i]);
-+ w = TEXTW(fribidi_text);
- drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
-- drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
-+ drw_text(drw, x, 0, w, bh, lrpad / 2, fribidi_text, urg & 1 << i);
- if (occ & 1 << i)
- drw_rect(drw, x + boxs, boxs, boxw, boxw,
- m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
- urg & 1 << i);
- x += w;
- }
-- w = blw = TEXTW(m->ltsymbol);
-+ apply_fribidi(m->ltsymbol);
-+ w = blw = TEXTW(fribidi_text);
- drw_setscheme(drw, scheme[SchemeNorm]);
-- x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
-+ x = drw_text(drw, x, 0, w, bh, lrpad / 2, fribidi_text, 0);
-
- if ((w = m->ww - tw - x) > bh) {
- if (m->sel) {
- drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
-- drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
-+ apply_fribidi(m->sel->name);
-+ drw_text(drw, x, 0, w, bh, lrpad / 2, fribidi_text, 0);
- if (m->sel->isfloating)
- drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
- } else {
---
-2.35.1
-
diff --git a/.local/src/dwm/patches/dwm-centeredwindowname-20200723-f035e1e.diff b/.local/src/dwm/patches/dwm-centeredwindowname-20200723-f035e1e.diff
@@ -1,30 +0,0 @@
-From f035e1e5abb19df5dced9c592ca986deac460435 Mon Sep 17 00:00:00 2001
-From: bastila <[email protected]>
-Date: Thu, 23 Jul 2020 02:45:12 +0300
-Subject: [PATCH] Fix overflow when window name is bigger than window width
-
----
- dwm.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
-diff --git a/dwm.c b/dwm.c
-index 9fd0286..42cb8dd 100644
---- a/dwm.c
-+++ b/dwm.c
-@@ -731,8 +731,12 @@ drawbar(Monitor *m)
-
- if ((w = m->ww - tw - x) > bh) {
- if (m->sel) {
-+ /* fix overflow when window name is bigger than window width */
-+ int mid = (m->ww - (int)TEXTW(m->sel->name)) / 2 - x;
-+ /* make sure name will not overlap on tags even when it is very long */
-+ mid = mid >= lrpad / 2 ? mid : lrpad / 2;
- drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
-- drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
-+ drw_text(drw, x, 0, w, bh, mid, m->sel->name, 0);
- if (m->sel->isfloating)
- drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
- } else {
---
-2.27.0
-
diff --git a/.local/src/dwm/patches/dwm-cyclelayouts-20180524-6.2.diff b/.local/src/dwm/patches/dwm-cyclelayouts-20180524-6.2.diff
@@ -1,93 +0,0 @@
-From a09e766a4342f580582082a92b2de65f33208eb4 Mon Sep 17 00:00:00 2001
-From: Christopher Drelich <[email protected]>
-Date: Thu, 24 May 2018 00:56:56 -0400
-Subject: [PATCH] Function to cycle through available layouts.
-
-MOD-CTRL-, and MOD-CTRL-.
-cycle backwards and forwards through available layouts.
-Probably only useful if you have a lot of additional layouts.
-The NULL, NULL layout should always be the last layout in your list,
-in order to guarantee consistent behavior.
----
- config.def.h | 3 +++
- dwm.1 | 6 ++++++
- dwm.c | 18 ++++++++++++++++++
- 3 files changed, 27 insertions(+)
-
-diff --git a/config.def.h b/config.def.h
-index a9ac303..153b880 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -41,6 +41,7 @@ static const Layout layouts[] = {
- { "[]=", tile }, /* first entry is default */
- { "><>", NULL }, /* no layout function means floating behavior */
- { "[M]", monocle },
-+ { NULL, NULL },
- };
-
- /* key definitions */
-@@ -76,6 +77,8 @@ static Key keys[] = {
- { MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
- { MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
- { MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
-+ { MODKEY|ControlMask, XK_comma, cyclelayout, {.i = -1 } },
-+ { MODKEY|ControlMask, XK_period, cyclelayout, {.i = +1 } },
- { MODKEY, XK_space, setlayout, {0} },
- { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
- { MODKEY, XK_0, view, {.ui = ~0 } },
-diff --git a/dwm.1 b/dwm.1
-index 13b3729..165891b 100644
---- a/dwm.1
-+++ b/dwm.1
-@@ -92,6 +92,12 @@ Sets monocle layout.
- .B Mod1\-space
- Toggles between current and previous layout.
- .TP
-+.B Mod1\-Control\-,
-+Cycles backwards in layout list.
-+.TP
-+.B Mod1\-Control\-.
-+Cycles forwards in layout list.
-+.TP
- .B Mod1\-j
- Focus next window.
- .TP
-diff --git a/dwm.c b/dwm.c
-index bb95e26..db73000 100644
---- a/dwm.c
-+++ b/dwm.c
-@@ -157,6 +157,7 @@ static void configure(Client *c);
- static void configurenotify(XEvent *e);
- static void configurerequest(XEvent *e);
- static Monitor *createmon(void);
-+static void cyclelayout(const Arg *arg);
- static void destroynotify(XEvent *e);
- static void detach(Client *c);
- static void detachstack(Client *c);
-@@ -645,6 +646,23 @@ createmon(void)
- }
-
- void
-+cyclelayout(const Arg *arg) {
-+ Layout *l;
-+ for(l = (Layout *)layouts; l != selmon->lt[selmon->sellt]; l++);
-+ if(arg->i > 0) {
-+ if(l->symbol && (l + 1)->symbol)
-+ setlayout(&((Arg) { .v = (l + 1) }));
-+ else
-+ setlayout(&((Arg) { .v = layouts }));
-+ } else {
-+ if(l != layouts && (l - 1)->symbol)
-+ setlayout(&((Arg) { .v = (l - 1) }));
-+ else
-+ setlayout(&((Arg) { .v = &layouts[LENGTH(layouts) - 2] }));
-+ }
-+}
-+
-+void
- destroynotify(XEvent *e)
- {
- Client *c;
---
-2.7.4
-
diff --git a/.local/src/dwm/patches/dwm-fullgaps-20200508-7b77734.diff b/.local/src/dwm/patches/dwm-fullgaps-20200508-7b77734.diff
@@ -1,138 +0,0 @@
-From 7b7773458c072e4b24d6ea32d0364a8e402e4a43 Mon Sep 17 00:00:00 2001
-From: swy7ch <[email protected]>
-Date: Fri, 8 May 2020 19:07:24 +0200
-Subject: [PATCH] [PATCH] update dwm-fullgaps patch to be used with tile layout
- update
-
-the recent tile layout changes in commit HEAD~1 (f09418b) broke the
-patch
-
-this patch adapt the new `if` statements to take gaps into account
-
-this patch also provides manpage entries for the keybindings
----
- config.def.h | 4 ++++
- dwm.1 | 10 ++++++++++
- dwm.c | 33 +++++++++++++++++++++++----------
- 3 files changed, 37 insertions(+), 10 deletions(-)
-
-diff --git a/config.def.h b/config.def.h
-index 1c0b587..38d2f6c 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -2,6 +2,7 @@
-
- /* appearance */
- static const unsigned int borderpx = 1; /* border pixel of windows */
-+static const unsigned int gappx = 5; /* gaps between windows */
- static const unsigned int snap = 32; /* snap pixel */
- static const int showbar = 1; /* 0 means no bar */
- static const int topbar = 1; /* 0 means bottom bar */
-@@ -84,6 +85,9 @@ static Key keys[] = {
- { MODKEY, XK_period, focusmon, {.i = +1 } },
- { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
- { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
-+ { MODKEY, XK_minus, setgaps, {.i = -1 } },
-+ { MODKEY, XK_equal, setgaps, {.i = +1 } },
-+ { MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } },
- TAGKEYS( XK_1, 0)
- TAGKEYS( XK_2, 1)
- TAGKEYS( XK_3, 2)
-diff --git a/dwm.1 b/dwm.1
-index 13b3729..0202d96 100644
---- a/dwm.1
-+++ b/dwm.1
-@@ -140,6 +140,16 @@ View all windows with any tag.
- .B Mod1\-Control\-[1..n]
- Add/remove all windows with nth tag to/from the view.
- .TP
-+.B Mod1\--
-+Decrease the gaps around windows.
-+.TP
-+.B Mod1\-=
-+Increase the gaps around windows.
-+.TP
-+.B Mod1\-Shift-=
-+Reset the gaps around windows to
-+.BR 0 .
-+.TP
- .B Mod1\-Shift\-q
- Quit dwm.
- .SS Mouse commands
-diff --git a/dwm.c b/dwm.c
-index 9fd0286..45a58f3 100644
---- a/dwm.c
-+++ b/dwm.c
-@@ -119,6 +119,7 @@ struct Monitor {
- int by; /* bar geometry */
- int mx, my, mw, mh; /* screen size */
- int wx, wy, ww, wh; /* window area */
-+ int gappx; /* gaps between windows */
- unsigned int seltags;
- unsigned int sellt;
- unsigned int tagset[2];
-@@ -200,6 +201,7 @@ static void sendmon(Client *c, Monitor *m);
- static void setclientstate(Client *c, long state);
- static void setfocus(Client *c);
- static void setfullscreen(Client *c, int fullscreen);
-+static void setgaps(const Arg *arg);
- static void setlayout(const Arg *arg);
- static void setmfact(const Arg *arg);
- static void setup(void);
-@@ -639,6 +641,7 @@ createmon(void)
- m->nmaster = nmaster;
- m->showbar = showbar;
- m->topbar = topbar;
-+ m->gappx = gappx;
- m->lt[0] = &layouts[0];
- m->lt[1] = &layouts[1 % LENGTH(layouts)];
- strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
-@@ -1498,6 +1501,16 @@ setfullscreen(Client *c, int fullscreen)
- }
- }
-
-+void
-+setgaps(const Arg *arg)
-+{
-+ if ((arg->i == 0) || (selmon->gappx + arg->i < 0))
-+ selmon->gappx = 0;
-+ else
-+ selmon->gappx += arg->i;
-+ arrange(selmon);
-+}
-+
- void
- setlayout(const Arg *arg)
- {
-@@ -1684,18 +1697,18 @@ tile(Monitor *m)
- if (n > m->nmaster)
- mw = m->nmaster ? m->ww * m->mfact : 0;
- else
-- mw = m->ww;
-- for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
-+ mw = m->ww - m->gappx;
-+ for (i = 0, my = ty = m->gappx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
- if (i < m->nmaster) {
-- h = (m->wh - my) / (MIN(n, m->nmaster) - i);
-- resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0);
-- if (my + HEIGHT(c) < m->wh)
-- my += HEIGHT(c);
-+ h = (m->wh - my) / (MIN(n, m->nmaster) - i) - m->gappx;
-+ resize(c, m->wx + m->gappx, m->wy + my, mw - (2*c->bw) - m->gappx, h - (2*c->bw), 0);
-+ if (my + HEIGHT(c) + m->gappx < m->wh)
-+ my += HEIGHT(c) + m->gappx;
- } else {
-- h = (m->wh - ty) / (n - i);
-- resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0);
-- if (ty + HEIGHT(c) < m->wh)
-- ty += HEIGHT(c);
-+ h = (m->wh - ty) / (n - i) - m->gappx;
-+ resize(c, m->wx + mw + m->gappx, m->wy + ty, m->ww - mw - (2*c->bw) - 2*m->gappx, h - (2*c->bw), 0);
-+ if (ty + HEIGHT(c) + m->gappx < m->wh)
-+ ty += HEIGHT(c) + m->gappx;
- }
- }
-
---
-2.26.2
-
diff --git a/.local/src/dwm/patches/dwm-hide_vacant_tags-6.3.diff b/.local/src/dwm/patches/dwm-hide_vacant_tags-6.3.diff
@@ -1,39 +0,0 @@
-diff --git a/dwm.c b/dwm.c
-index a96f33c..f2da729 100644
---- a/dwm.c
-+++ b/dwm.c
-@@ -432,9 +432,15 @@ buttonpress(XEvent *e)
- }
- if (ev->window == selmon->barwin) {
- i = x = 0;
-- do
-+ unsigned int occ = 0;
-+ for(c = m->clients; c; c=c->next)
-+ occ |= c->tags;
-+ do {
-+ /* Do not reserve space for vacant tags */
-+ if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
-+ continue;
- x += TEXTW(tags[i]);
-- while (ev->x >= x && ++i < LENGTH(tags));
-+ } while (ev->x >= x && ++i < LENGTH(tags));
- if (i < LENGTH(tags)) {
- click = ClkTagBar;
- arg.ui = 1 << i;
-@@ -719,13 +725,12 @@ drawbar(Monitor *m)
- }
- x = 0;
- for (i = 0; i < LENGTH(tags); i++) {
-+ /* Do not draw vacant tags */
-+ if(!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
-+ continue;
- w = TEXTW(tags[i]);
- drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
- drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
-- if (occ & 1 << i)
-- drw_rect(drw, x + boxs, boxs, boxw, boxw,
-- m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
-- urg & 1 << i);
- x += w;
- }
- w = blw = TEXTW(m->ltsymbol);
diff --git a/.local/src/dwm/patches/dwm-movestack-20211115-a786211.diff b/.local/src/dwm/patches/dwm-movestack-20211115-a786211.diff
@@ -1,95 +0,0 @@
-From 9a4037dc0ef56f91c009317e78e9e3790dafbb58 Mon Sep 17 00:00:00 2001
-From: BrunoCooper17 <[email protected]>
-Date: Mon, 15 Nov 2021 14:04:53 -0600
-Subject: [PATCH] MoveStack patch
-
-This plugin allows you to move clients around in the stack and swap them
-with the master. It emulates the behavior off mod+shift+j and mod+shift+k
-in Xmonad. movestack(+1) will swap the client with the current focus with
-the next client. movestack(-1) will swap the client with the current focus
-with the previous client.
----
- config.def.h | 3 +++
- movestack.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 51 insertions(+)
- create mode 100644 movestack.c
-
-diff --git a/config.def.h b/config.def.h
-index a2ac963..33efa5b 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -60,6 +60,7 @@ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn()
- static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
- static const char *termcmd[] = { "st", NULL };
-
-+#include "movestack.c"
- static Key keys[] = {
- /* modifier key function argument */
- { MODKEY, XK_p, spawn, {.v = dmenucmd } },
-@@ -71,6 +72,8 @@ static Key keys[] = {
- { MODKEY, XK_d, incnmaster, {.i = -1 } },
- { MODKEY, XK_h, setmfact, {.f = -0.05} },
- { MODKEY, XK_l, setmfact, {.f = +0.05} },
-+ { MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } },
-+ { MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } },
- { MODKEY, XK_Return, zoom, {0} },
- { MODKEY, XK_Tab, view, {0} },
- { MODKEY|ShiftMask, XK_c, killclient, {0} },
-diff --git a/movestack.c b/movestack.c
-new file mode 100644
-index 0000000..520f4ae
---- /dev/null
-+++ b/movestack.c
-@@ -0,0 +1,48 @@
-+void
-+movestack(const Arg *arg) {
-+ Client *c = NULL, *p = NULL, *pc = NULL, *i;
-+
-+ if(arg->i > 0) {
-+ /* find the client after selmon->sel */
-+ for(c = selmon->sel->next; c && (!ISVISIBLE(c) || c->isfloating); c = c->next);
-+ if(!c)
-+ for(c = selmon->clients; c && (!ISVISIBLE(c) || c->isfloating); c = c->next);
-+
-+ }
-+ else {
-+ /* find the client before selmon->sel */
-+ for(i = selmon->clients; i != selmon->sel; i = i->next)
-+ if(ISVISIBLE(i) && !i->isfloating)
-+ c = i;
-+ if(!c)
-+ for(; i; i = i->next)
-+ if(ISVISIBLE(i) && !i->isfloating)
-+ c = i;
-+ }
-+ /* find the client before selmon->sel and c */
-+ for(i = selmon->clients; i && (!p || !pc); i = i->next) {
-+ if(i->next == selmon->sel)
-+ p = i;
-+ if(i->next == c)
-+ pc = i;
-+ }
-+
-+ /* swap c and selmon->sel selmon->clients in the selmon->clients list */
-+ if(c && c != selmon->sel) {
-+ Client *temp = selmon->sel->next==c?selmon->sel:selmon->sel->next;
-+ selmon->sel->next = c->next==selmon->sel?c:c->next;
-+ c->next = temp;
-+
-+ if(p && p != c)
-+ p->next = c;
-+ if(pc && pc != selmon->sel)
-+ pc->next = selmon->sel;
-+
-+ if(selmon->sel == selmon->clients)
-+ selmon->clients = c;
-+ else if(c == selmon->clients)
-+ selmon->clients = selmon->sel;
-+
-+ arrange(selmon);
-+ }
-+}
-\ No newline at end of file
---
-2.33.1
-
diff --git a/.local/src/dwm/patches/dwm-noborderfloatingfix-6.2.diff b/.local/src/dwm/patches/dwm-noborderfloatingfix-6.2.diff
@@ -1,31 +0,0 @@
-From 700b0bdea872f4c00182b2bd925b41fe03f8d222 Mon Sep 17 00:00:00 2001
-From: Aidan Hall <[email protected]>
-Date: Tue, 2 Jun 2020 14:41:53 +0000
-Subject: [PATCH] Prevents hiding the border if layout is floating.
-
----
- dwm.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
-diff --git a/dwm.c b/dwm.c
-index 4465af1..2dd959d 100644
---- a/dwm.c
-+++ b/dwm.c
-@@ -1282,6 +1282,14 @@ resizeclient(Client *c, int x, int y, int w, int h)
- c->oldw = c->w; c->w = wc.width = w;
- c->oldh = c->h; c->h = wc.height = h;
- wc.border_width = c->bw;
-+ if (((nexttiled(c->mon->clients) == c && !nexttiled(c->next))
-+ || &monocle == c->mon->lt[c->mon->sellt]->arrange)
-+ && !c->isfullscreen && !c->isfloating
-+ && NULL != c->mon->lt[c->mon->sellt]->arrange) {
-+ c->w = wc.width += c->bw * 2;
-+ c->h = wc.height += c->bw * 2;
-+ wc.border_width = 0;
-+ }
- XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
- configure(c);
- XSync(dpy, False);
---
-2.26.2
-
diff --git a/.local/src/dwm/patches/dwm-placemouse-6.3.diff b/.local/src/dwm/patches/dwm-placemouse-6.3.diff
@@ -1,259 +0,0 @@
-From 399cb51f86d259d0d15d2db767d31c9e030c0528 Mon Sep 17 00:00:00 2001
-From: Bakkeby <[email protected]>
-Date: Mon, 10 Jan 2022 13:18:37 +0100
-Subject: [PATCH] Adding placemouse patch
-
----
- config.def.h | 12 +++-
- dwm.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 177 insertions(+), 1 deletion(-)
-
-diff --git a/config.def.h b/config.def.h
-index a2ac963..caaebf6 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -105,7 +105,17 @@ static Button buttons[] = {
- { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
- { ClkWinTitle, 0, Button2, zoom, {0} },
- { ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
-- { ClkClientWin, MODKEY, Button1, movemouse, {0} },
-+ /* placemouse options, choose which feels more natural:
-+ * 0 - tiled position is relative to mouse cursor
-+ * 1 - tiled postiion is relative to window center
-+ * 2 - mouse pointer warps to window center
-+ *
-+ * The moveorplace uses movemouse or placemouse depending on the floating state
-+ * of the selected client. Set up individual keybindings for the two if you want
-+ * to control these separately (i.e. to retain the feature to move a tiled window
-+ * into a floating position).
-+ */
-+ { ClkClientWin, MODKEY, Button1, moveorplace, {.i = 1} },
- { ClkClientWin, MODKEY, Button2, togglefloating, {0} },
- { ClkClientWin, MODKEY, Button3, resizemouse, {0} },
- { ClkTagBar, 0, Button1, view, {0} },
-diff --git a/dwm.c b/dwm.c
-index a96f33c..5d57e18 100644
---- a/dwm.c
-+++ b/dwm.c
-@@ -49,6 +49,8 @@
- #define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
- #define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
- * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
-+#define INTERSECTC(x,y,w,h,z) (MAX(0, MIN((x)+(w),(z)->x+(z)->w) - MAX((x),(z)->x)) \
-+ * MAX(0, MIN((y)+(h),(z)->y+(z)->h) - MAX((y),(z)->y)))
- #define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]))
- #define LENGTH(X) (sizeof X / sizeof X[0])
- #define MOUSEMASK (BUTTONMASK|PointerMotionMask)
-@@ -93,6 +95,7 @@ struct Client {
- int bw, oldbw;
- unsigned int tags;
- int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
-+ int beingmoved;
- Client *next;
- Client *snext;
- Monitor *mon;
-@@ -184,10 +187,13 @@ static void maprequest(XEvent *e);
- static void monocle(Monitor *m);
- static void motionnotify(XEvent *e);
- static void movemouse(const Arg *arg);
-+static void moveorplace(const Arg *arg);
- static Client *nexttiled(Client *c);
-+static void placemouse(const Arg *arg);
- static void pop(Client *);
- static void propertynotify(XEvent *e);
- static void quit(const Arg *arg);
-+static Client *recttoclient(int x, int y, int w, int h);
- static Monitor *recttomon(int x, int y, int w, int h);
- static void resize(Client *c, int x, int y, int w, int h, int interact);
- static void resizeclient(Client *c, int x, int y, int w, int h);
-@@ -1136,6 +1142,14 @@ motionnotify(XEvent *e)
- mon = m;
- }
-
-+void
-+moveorplace(const Arg *arg) {
-+ if ((!selmon->lt[selmon->sellt]->arrange || (selmon->sel && selmon->sel->isfloating)))
-+ movemouse(arg);
-+ else
-+ placemouse(arg);
-+}
-+
- void
- movemouse(const Arg *arg)
- {
-@@ -1203,6 +1217,139 @@ nexttiled(Client *c)
- return c;
- }
-
-+void
-+placemouse(const Arg *arg)
-+{
-+ int x, y, px, py, ocx, ocy, nx = -9999, ny = -9999, freemove = 0;
-+ Client *c, *r = NULL, *at, *prevr;
-+ Monitor *m;
-+ XEvent ev;
-+ XWindowAttributes wa;
-+ Time lasttime = 0;
-+ int attachmode, prevattachmode;
-+ attachmode = prevattachmode = -1;
-+
-+ if (!(c = selmon->sel) || !c->mon->lt[c->mon->sellt]->arrange) /* no support for placemouse when floating layout is used */
-+ return;
-+ if (c->isfullscreen) /* no support placing fullscreen windows by mouse */
-+ return;
-+ restack(selmon);
-+ prevr = c;
-+ if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
-+ None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess)
-+ return;
-+
-+ c->isfloating = 0;
-+ c->beingmoved = 1;
-+
-+ XGetWindowAttributes(dpy, c->win, &wa);
-+ ocx = wa.x;
-+ ocy = wa.y;
-+
-+ if (arg->i == 2) // warp cursor to client center
-+ XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, WIDTH(c) / 2, HEIGHT(c) / 2);
-+
-+ if (!getrootptr(&x, &y))
-+ return;
-+
-+ do {
-+ XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
-+ switch (ev.type) {
-+ case ConfigureRequest:
-+ case Expose:
-+ case MapRequest:
-+ handler[ev.type](&ev);
-+ break;
-+ case MotionNotify:
-+ if ((ev.xmotion.time - lasttime) <= (1000 / 60))
-+ continue;
-+ lasttime = ev.xmotion.time;
-+
-+ nx = ocx + (ev.xmotion.x - x);
-+ ny = ocy + (ev.xmotion.y - y);
-+
-+ if (!freemove && (abs(nx - ocx) > snap || abs(ny - ocy) > snap))
-+ freemove = 1;
-+
-+ if (freemove)
-+ XMoveWindow(dpy, c->win, nx, ny);
-+
-+ if ((m = recttomon(ev.xmotion.x, ev.xmotion.y, 1, 1)) && m != selmon)
-+ selmon = m;
-+
-+ if (arg->i == 1) { // tiled position is relative to the client window center point
-+ px = nx + wa.width / 2;
-+ py = ny + wa.height / 2;
-+ } else { // tiled position is relative to the mouse cursor
-+ px = ev.xmotion.x;
-+ py = ev.xmotion.y;
-+ }
-+
-+ r = recttoclient(px, py, 1, 1);
-+
-+ if (!r || r == c)
-+ break;
-+
-+ attachmode = 0; // below
-+ if (((float)(r->y + r->h - py) / r->h) > ((float)(r->x + r->w - px) / r->w)) {
-+ if (abs(r->y - py) < r->h / 2)
-+ attachmode = 1; // above
-+ } else if (abs(r->x - px) < r->w / 2)
-+ attachmode = 1; // above
-+
-+ if ((r && r != prevr) || (attachmode != prevattachmode)) {
-+ detachstack(c);
-+ detach(c);
-+ if (c->mon != r->mon) {
-+ arrangemon(c->mon);
-+ c->tags = r->mon->tagset[r->mon->seltags];
-+ }
-+
-+ c->mon = r->mon;
-+ r->mon->sel = r;
-+
-+ if (attachmode) {
-+ if (r == r->mon->clients)
-+ attach(c);
-+ else {
-+ for (at = r->mon->clients; at->next != r; at = at->next);
-+ c->next = at->next;
-+ at->next = c;
-+ }
-+ } else {
-+ c->next = r->next;
-+ r->next = c;
-+ }
-+
-+ attachstack(c);
-+ arrangemon(r->mon);
-+ prevr = r;
-+ prevattachmode = attachmode;
-+ }
-+ break;
-+ }
-+ } while (ev.type != ButtonRelease);
-+ XUngrabPointer(dpy, CurrentTime);
-+
-+ if ((m = recttomon(ev.xmotion.x, ev.xmotion.y, 1, 1)) && m != c->mon) {
-+ detach(c);
-+ detachstack(c);
-+ arrangemon(c->mon);
-+ c->mon = m;
-+ c->tags = m->tagset[m->seltags];
-+ attach(c);
-+ attachstack(c);
-+ selmon = m;
-+ }
-+
-+ focus(c);
-+ c->beingmoved = 0;
-+
-+ if (nx != -9999)
-+ resize(c, nx, ny, c->w, c->h, 0);
-+ arrangemon(c->mon);
-+}
-+
- void
- pop(Client *c)
- {
-@@ -1255,6 +1402,21 @@ quit(const Arg *arg)
- running = 0;
- }
-
-+Client *
-+recttoclient(int x, int y, int w, int h)
-+{
-+ Client *c, *r = NULL;
-+ int a, area = 0;
-+
-+ for (c = nexttiled(selmon->clients); c; c = nexttiled(c->next)) {
-+ if ((a = INTERSECTC(x, y, w, h, c)) > area) {
-+ area = a;
-+ r = c;
-+ }
-+ }
-+ return r;
-+}
-+
- Monitor *
- recttomon(int x, int y, int w, int h)
- {
-@@ -1285,6 +1447,10 @@ resizeclient(Client *c, int x, int y, int w, int h)
- c->oldy = c->y; c->y = wc.y = y;
- c->oldw = c->w; c->w = wc.width = w;
- c->oldh = c->h; c->h = wc.height = h;
-+
-+ if (c->beingmoved)
-+ return;
-+
- wc.border_width = c->bw;
- XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
- configure(c);
---
-2.19.1
-
diff --git a/.local/src/dwm/patches/dwm-rainbowtags-6.2.diff b/.local/src/dwm/patches/dwm-rainbowtags-6.2.diff
@@ -1,59 +0,0 @@
-diff --git a/config.def.h b/config.def.h
-index 1c0b587..3fb5cf8 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -21,6 +21,18 @@ static const char *colors[][3] = {
- /* tagging */
- static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
-
-+static const char *tagsel[][2] = {
-+ { "#ffffff", "#ff0000" },
-+ { "#ffffff", "#ff7f00" },
-+ { "#000000", "#ffff00" },
-+ { "#000000", "#00ff00" },
-+ { "#ffffff", "#0000ff" },
-+ { "#ffffff", "#4b0082" },
-+ { "#ffffff", "#9400d3" },
-+ { "#000000", "#ffffff" },
-+ { "#ffffff", "#000000" },
-+};
-+
- static const Rule rules[] = {
- /* xprop(1):
- * WM_CLASS(STRING) = instance, class
-diff --git a/dwm.c b/dwm.c
-index b0b3466..c16d5f5 100644
---- a/dwm.c
-+++ b/dwm.c
-@@ -264,6 +264,7 @@ static Atom wmatom[WMLast], netatom[NetLast];
- static int running = 1;
- static Cur *cursor[CurLast];
- static Clr **scheme;
-+static Clr **tagscheme;
- static Display *dpy;
- static Drw *drw;
- static Monitor *mons, *selmon;
-@@ -717,7 +718,7 @@ drawbar(Monitor *m)
- x = 0;
- for (i = 0; i < LENGTH(tags); i++) {
- w = TEXTW(tags[i]);
-- drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
-+ drw_setscheme(drw, (m->tagset[m->seltags] & 1 << i ? tagscheme[i] : scheme[SchemeNorm]));
- drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
- if (occ & 1 << i)
- drw_rect(drw, x + boxs, boxs, boxw, boxw,
-@@ -1568,9 +1569,14 @@ setup(void)
- cursor[CurResize] = drw_cur_create(drw, XC_sizing);
- cursor[CurMove] = drw_cur_create(drw, XC_fleur);
- /* init appearance */
-+ if (LENGTH(tags) > LENGTH(tagsel))
-+ die("too few color schemes for the tags");
- scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
- for (i = 0; i < LENGTH(colors); i++)
- scheme[i] = drw_scm_create(drw, colors[i], 3);
-+ tagscheme = ecalloc(LENGTH(tagsel), sizeof(Clr *));
-+ for (i = 0; i < LENGTH(tagsel); i++)
-+ tagscheme[i] = drw_scm_create(drw, tagsel[i], 2);
- /* init bars */
- updatebars();
- updatestatus();
diff --git a/.local/src/dwm/patches/dwm-restartsig-20180523-6.2.diff b/.local/src/dwm/patches/dwm-restartsig-20180523-6.2.diff
@@ -1,139 +0,0 @@
-From 2991f37f0aaf44b9f9b11e7893ff0af8eb88f649 Mon Sep 17 00:00:00 2001
-From: Christopher Drelich <[email protected]>
-Date: Wed, 23 May 2018 22:50:38 -0400
-Subject: [PATCH] Modifies quit to handle restarts and adds SIGHUP and SIGTERM
- handlers.
-
-Modified quit() to restart if it receives arg .i = 1
-MOD+CTRL+SHIFT+Q was added to confid.def.h to do just that.
-
-Signal handlers were handled for SIGHUP and SIGTERM.
-If dwm receives these signals it calls quit() with
-arg .i = to 1 or 0, respectively.
-
-To restart dwm:
-MOD+CTRL+SHIFT+Q
-or
-kill -HUP dwmpid
-
-To quit dwm cleanly:
-MOD+SHIFT+Q
-or
-kill -TERM dwmpid
----
- config.def.h | 1 +
- dwm.1 | 10 ++++++++++
- dwm.c | 22 ++++++++++++++++++++++
- 3 files changed, 33 insertions(+)
-
-diff --git a/config.def.h b/config.def.h
-index a9ac303..e559429 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -94,6 +94,7 @@ static Key keys[] = {
- TAGKEYS( XK_8, 7)
- TAGKEYS( XK_9, 8)
- { MODKEY|ShiftMask, XK_q, quit, {0} },
-+ { MODKEY|ControlMask|ShiftMask, XK_q, quit, {1} },
- };
-
- /* button definitions */
-diff --git a/dwm.1 b/dwm.1
-index 13b3729..36a331c 100644
---- a/dwm.1
-+++ b/dwm.1
-@@ -142,6 +142,9 @@ Add/remove all windows with nth tag to/from the view.
- .TP
- .B Mod1\-Shift\-q
- Quit dwm.
-+.TP
-+.B Mod1\-Control\-Shift\-q
-+Restart dwm.
- .SS Mouse commands
- .TP
- .B Mod1\-Button1
-@@ -155,6 +158,13 @@ Resize focused window while dragging. Tiled windows will be toggled to the float
- .SH CUSTOMIZATION
- dwm is customized by creating a custom config.h and (re)compiling the source
- code. This keeps it fast, secure and simple.
-+.SH SIGNALS
-+.TP
-+.B SIGHUP - 1
-+Restart the dwm process.
-+.TP
-+.B SIGTERM - 15
-+Cleanly terminate the dwm process.
- .SH SEE ALSO
- .BR dmenu (1),
- .BR st (1)
-diff --git a/dwm.c b/dwm.c
-index bb95e26..286eecd 100644
---- a/dwm.c
-+++ b/dwm.c
-@@ -205,6 +205,8 @@ static void setup(void);
- static void seturgent(Client *c, int urg);
- static void showhide(Client *c);
- static void sigchld(int unused);
-+static void sighup(int unused);
-+static void sigterm(int unused);
- static void spawn(const Arg *arg);
- static void tag(const Arg *arg);
- static void tagmon(const Arg *arg);
-@@ -260,6 +262,7 @@ static void (*handler[LASTEvent]) (XEvent *) = {
- [UnmapNotify] = unmapnotify
- };
- static Atom wmatom[WMLast], netatom[NetLast];
-+static int restart = 0;
- static int running = 1;
- static Cur *cursor[CurLast];
- static Clr **scheme;
-@@ -1248,6 +1251,7 @@ propertynotify(XEvent *e)
- void
- quit(const Arg *arg)
- {
-+ if(arg->i) restart = 1;
- running = 0;
- }
-
-@@ -1536,6 +1540,9 @@ setup(void)
- /* clean up any zombies immediately */
- sigchld(0);
-
-+ signal(SIGHUP, sighup);
-+ signal(SIGTERM, sigterm);
-+
- /* init screen */
- screen = DefaultScreen(dpy);
- sw = DisplayWidth(dpy, screen);
-@@ -1637,6 +1644,20 @@ sigchld(int unused)
- }
-
- void
-+sighup(int unused)
-+{
-+ Arg a = {.i = 1};
-+ quit(&a);
-+}
-+
-+void
-+sigterm(int unused)
-+{
-+ Arg a = {.i = 0};
-+ quit(&a);
-+}
-+
-+void
- spawn(const Arg *arg)
- {
- if (arg->v == dmenucmd)
-@@ -2139,6 +2160,7 @@ main(int argc, char *argv[])
- setup();
- scan();
- run();
-+ if(restart) execvp(argv[0], argv);
- cleanup();
- XCloseDisplay(dpy);
- return EXIT_SUCCESS;
---
-2.7.4
-
diff --git a/.local/src/dwm/patches/dwm-setstatus-6.2.diff b/.local/src/dwm/patches/dwm-setstatus-6.2.diff
@@ -1,49 +0,0 @@
-From dbfb346a86c79b50bfa27c75547b42e34cb54715 Mon Sep 17 00:00:00 2001
-From: aleks <[email protected]>
-Date: Fri, 11 Sep 2020 17:42:50 +0200
-Subject: [PATCH] Apply setstatus-6.2
-
-Enables to set the status with dwm itself. No more xsetroot bloat!
-To change the status to `foo bar` execute:
-
- dwm -s "foo bar"
-
-Piping into `dwm -s` is currently not supported but you can set the
-status to the output of any command by doing something like:
-
- dwm -s "$(run_command_which_outputs_the_status)"
-
-For example to set the status to the current date run:
-
- dwm -s "$(date)"
-
----
- dwm.c | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
-diff --git a/dwm.c b/dwm.c
-index 4465af1..b3c8f71 100644
---- a/dwm.c
-+++ b/dwm.c
-@@ -2129,12 +2129,17 @@ main(int argc, char *argv[])
- {
- if (argc == 2 && !strcmp("-v", argv[1]))
- die("dwm-"VERSION);
-- else if (argc != 1)
-+ else if (argc != 1 && strcmp("-s", argv[1]))
- die("usage: dwm [-v]");
- if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
- fputs("warning: no locale support\n", stderr);
- if (!(dpy = XOpenDisplay(NULL)))
- die("dwm: cannot open display");
-+ if (argc > 1 && !strcmp("-s", argv[1])) {
-+ XStoreName(dpy, RootWindow(dpy, DefaultScreen(dpy)), argv[2]);
-+ XCloseDisplay(dpy);
-+ return 0;
-+ }
- checkotherwm();
- setup();
- #ifdef __OpenBSD__
---
-2.28.0
-
diff --git a/.local/src/dwm/patches/dwm-status2d-systray-6.3.diff b/.local/src/dwm/patches/dwm-status2d-systray-6.3.diff
@@ -1,888 +0,0 @@
-diff --git a/config.def.h b/config.def.h
-index a2ac963..86fcc84 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -3,8 +3,13 @@
- /* appearance */
- static const unsigned int borderpx = 1; /* border pixel of windows */
- static const unsigned int snap = 32; /* snap pixel */
--static const int showbar = 1; /* 0 means no bar */
--static const int topbar = 1; /* 0 means bottom bar */
-+static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */
-+static const unsigned int systrayonleft = 0; /* 0: systray in the right corner, >0: systray on left of status text */
-+static const unsigned int systrayspacing = 2; /* systray spacing */
-+static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/
-+static const int showsystray = 1; /* 0 means no systray */
-+static const int showbar = 1; /* 0 means no bar */
-+static const int topbar = 1; /* 0 means bottom bar */
- static const char *fonts[] = { "monospace:size=10" };
- static const char dmenufont[] = "monospace:size=10";
- static const char col_gray1[] = "#222222";
-@@ -101,8 +106,8 @@ static Key keys[] = {
- /* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
- static Button buttons[] = {
- /* click event mask button function argument */
-- { ClkLtSymbol, 0, Button1, setlayout, {0} },
-- { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
-+ { ClkTagBar, MODKEY, Button1, tag, {0} },
-+ { ClkTagBar, MODKEY, Button3, toggletag, {0} },
- { ClkWinTitle, 0, Button2, zoom, {0} },
- { ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
- { ClkClientWin, MODKEY, Button1, movemouse, {0} },
-diff --git a/dwm.c b/dwm.c
-index a96f33c..8153bfe 100644
---- a/dwm.c
-+++ b/dwm.c
-@@ -57,12 +57,27 @@
- #define TAGMASK ((1 << LENGTH(tags)) - 1)
- #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
-
-+#define SYSTEM_TRAY_REQUEST_DOCK 0
-+/* XEMBED messages */
-+#define XEMBED_EMBEDDED_NOTIFY 0
-+#define XEMBED_WINDOW_ACTIVATE 1
-+#define XEMBED_FOCUS_IN 4
-+#define XEMBED_MODALITY_ON 10
-+#define XEMBED_MAPPED (1 << 0)
-+#define XEMBED_WINDOW_ACTIVATE 1
-+#define XEMBED_WINDOW_DEACTIVATE 2
-+#define VERSION_MAJOR 0
-+#define VERSION_MINOR 0
-+#define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR
-+
- /* enums */
- enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
- enum { SchemeNorm, SchemeSel }; /* color schemes */
- enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
-+ NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz,
- NetWMFullscreen, NetActiveWindow, NetWMWindowType,
- NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
-+enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */
- enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
- enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
- ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
-@@ -141,6 +156,12 @@ typedef struct {
- int monitor;
- } Rule;
-
-+typedef struct Systray Systray;
-+struct Systray {
-+ Window win;
-+ Client *icons;
-+};
-+
- /* function declarations */
- static void applyrules(Client *c);
- static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact);
-@@ -163,6 +184,7 @@ static void detachstack(Client *c);
- static Monitor *dirtomon(int dir);
- static void drawbar(Monitor *m);
- static void drawbars(void);
-+static int drawstatusbar(Monitor *m, int bh, char* text);
- static void enternotify(XEvent *e);
- static void expose(XEvent *e);
- static void focus(Client *c);
-@@ -172,6 +194,7 @@ static void focusstack(const Arg *arg);
- static Atom getatomprop(Client *c, Atom prop);
- static int getrootptr(int *x, int *y);
- static long getstate(Window w);
-+static unsigned int getsystraywidth();
- static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
- static void grabbuttons(Client *c, int focused);
- static void grabkeys(void);
-@@ -189,13 +212,16 @@ static void pop(Client *);
- static void propertynotify(XEvent *e);
- static void quit(const Arg *arg);
- static Monitor *recttomon(int x, int y, int w, int h);
-+static void removesystrayicon(Client *i);
- static void resize(Client *c, int x, int y, int w, int h, int interact);
-+static void resizebarwin(Monitor *m);
- static void resizeclient(Client *c, int x, int y, int w, int h);
- static void resizemouse(const Arg *arg);
-+static void resizerequest(XEvent *e);
- static void restack(Monitor *m);
- static void run(void);
- static void scan(void);
--static int sendevent(Client *c, Atom proto);
-+static int sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, long d3, long d4);
- static void sendmon(Client *c, Monitor *m);
- static void setclientstate(Client *c, long state);
- static void setfocus(Client *c);
-@@ -207,6 +233,7 @@ static void seturgent(Client *c, int urg);
- static void showhide(Client *c);
- static void sigchld(int unused);
- static void spawn(const Arg *arg);
-+static Monitor *systraytomon(Monitor *m);
- static void tag(const Arg *arg);
- static void tagmon(const Arg *arg);
- static void tile(Monitor *);
-@@ -224,20 +251,25 @@ static int updategeom(void);
- static void updatenumlockmask(void);
- static void updatesizehints(Client *c);
- static void updatestatus(void);
-+static void updatesystray(void);
-+static void updatesystrayicongeom(Client *i, int w, int h);
-+static void updatesystrayiconstate(Client *i, XPropertyEvent *ev);
- static void updatetitle(Client *c);
- static void updatewindowtype(Client *c);
- static void updatewmhints(Client *c);
- static void view(const Arg *arg);
- static Client *wintoclient(Window w);
- static Monitor *wintomon(Window w);
-+static Client *wintosystrayicon(Window w);
- static int xerror(Display *dpy, XErrorEvent *ee);
- static int xerrordummy(Display *dpy, XErrorEvent *ee);
- static int xerrorstart(Display *dpy, XErrorEvent *ee);
- static void zoom(const Arg *arg);
-
- /* variables */
-+static Systray *systray = NULL;
- static const char broken[] = "broken";
--static char stext[256];
-+static char stext[1024];
- static int screen;
- static int sw, sh; /* X display screen geometry width, height */
- static int bh, blw = 0; /* bar geometry */
-@@ -258,9 +290,10 @@ static void (*handler[LASTEvent]) (XEvent *) = {
- [MapRequest] = maprequest,
- [MotionNotify] = motionnotify,
- [PropertyNotify] = propertynotify,
-+ [ResizeRequest] = resizerequest,
- [UnmapNotify] = unmapnotify
- };
--static Atom wmatom[WMLast], netatom[NetLast];
-+static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast];
- static int running = 1;
- static Cur *cursor[CurLast];
- static Clr **scheme;
-@@ -440,7 +473,7 @@ buttonpress(XEvent *e)
- arg.ui = 1 << i;
- } else if (ev->x < x + blw)
- click = ClkLtSymbol;
-- else if (ev->x > selmon->ww - (int)TEXTW(stext))
-+ else if (ev->x > selmon->ww - (int)TEXTW(stext) - getsystraywidth())
- click = ClkStatusText;
- else
- click = ClkWinTitle;
-@@ -483,9 +516,16 @@ cleanup(void)
- XUngrabKey(dpy, AnyKey, AnyModifier, root);
- while (mons)
- cleanupmon(mons);
-- for (i = 0; i < CurLast; i++)
-+
-+ if (showsystray) {
-+ XUnmapWindow(dpy, systray->win);
-+ XDestroyWindow(dpy, systray->win);
-+ free(systray);
-+ }
-+
-+ for (i = 0; i < CurLast; i++)
- drw_cur_free(drw, cursor[i]);
-- for (i = 0; i < LENGTH(colors); i++)
-+ for (i = 0; i < LENGTH(colors) + 1; i++)
- free(scheme[i]);
- XDestroyWindow(dpy, wmcheckwin);
- drw_free(drw);
-@@ -513,9 +553,58 @@ cleanupmon(Monitor *mon)
- void
- clientmessage(XEvent *e)
- {
-+ XWindowAttributes wa;
-+ XSetWindowAttributes swa;
- XClientMessageEvent *cme = &e->xclient;
- Client *c = wintoclient(cme->window);
-
-+ if (showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) {
-+ /* add systray icons */
-+ if (cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) {
-+ if (!(c = (Client *)calloc(1, sizeof(Client))))
-+ die("fatal: could not malloc() %u bytes\n", sizeof(Client));
-+ if (!(c->win = cme->data.l[2])) {
-+ free(c);
-+ return;
-+ }
-+ c->mon = selmon;
-+ c->next = systray->icons;
-+ systray->icons = c;
-+ if (!XGetWindowAttributes(dpy, c->win, &wa)) {
-+ /* use sane defaults */
-+ wa.width = bh;
-+ wa.height = bh;
-+ wa.border_width = 0;
-+ }
-+ c->x = c->oldx = c->y = c->oldy = 0;
-+ c->w = c->oldw = wa.width;
-+ c->h = c->oldh = wa.height;
-+ c->oldbw = wa.border_width;
-+ c->bw = 0;
-+ c->isfloating = True;
-+ /* reuse tags field as mapped status */
-+ c->tags = 1;
-+ updatesizehints(c);
-+ updatesystrayicongeom(c, wa.width, wa.height);
-+ XAddToSaveSet(dpy, c->win);
-+ XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask);
-+ XReparentWindow(dpy, c->win, systray->win, 0, 0);
-+ /* use parents background color */
-+ swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
-+ XChangeWindowAttributes(dpy, c->win, CWBackPixel, &swa);
-+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
-+ /* FIXME not sure if I have to send these events, too */
-+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_FOCUS_IN, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
-+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
-+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_MODALITY_ON, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
-+ XSync(dpy, False);
-+ resizebarwin(selmon);
-+ updatesystray();
-+ setclientstate(c, NormalState);
-+ }
-+ return;
-+ }
-+
- if (!c)
- return;
- if (cme->message_type == netatom[NetWMState]) {
-@@ -568,7 +657,7 @@ configurenotify(XEvent *e)
- for (c = m->clients; c; c = c->next)
- if (c->isfullscreen)
- resizeclient(c, m->mx, m->my, m->mw, m->mh);
-- XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
-+ resizebarwin(m);
- }
- focus(NULL);
- arrange(NULL);
-@@ -653,6 +742,11 @@ destroynotify(XEvent *e)
-
- if ((c = wintoclient(ev->window)))
- unmanage(c, 1);
-+ else if ((c = wintosystrayicon(ev->window))) {
-+ removesystrayicon(c);
-+ resizebarwin(selmon);
-+ updatesystray();
-+ }
- }
-
- void
-@@ -693,10 +787,119 @@ dirtomon(int dir)
- return m;
- }
-
-+int
-+drawstatusbar(Monitor *m, int bh, char* stext) {
-+ int ret, i, w, x, len;
-+ short isCode = 0;
-+ char *text;
-+ char *p;
-+
-+ len = strlen(stext) + 1 ;
-+ if (!(text = (char*) malloc(sizeof(char)*len)))
-+ die("malloc");
-+ p = text;
-+ memcpy(text, stext, len);
-+
-+ /* compute width of the status text */
-+ w = 0;
-+ i = -1;
-+ while (text[++i]) {
-+ if (text[i] == '^') {
-+ if (!isCode) {
-+ isCode = 1;
-+ text[i] = '\0';
-+ w += TEXTW(text) - lrpad;
-+ text[i] = '^';
-+ if (text[++i] == 'f')
-+ w += atoi(text + ++i);
-+ } else {
-+ isCode = 0;
-+ text = text + i + 1;
-+ i = -1;
-+ }
-+ }
-+ }
-+ if (!isCode)
-+ w += TEXTW(text) - lrpad;
-+ else
-+ isCode = 0;
-+ text = p;
-+
-+ w += 2; /* 1px padding on both sides */
-+ ret = m->ww - w;
-+ x = m->ww - w - getsystraywidth();
-+
-+ drw_setscheme(drw, scheme[LENGTH(colors)]);
-+ drw->scheme[ColFg] = scheme[SchemeNorm][ColFg];
-+ drw->scheme[ColBg] = scheme[SchemeNorm][ColBg];
-+ drw_rect(drw, x, 0, w, bh, 1, 1);
-+ x++;
-+
-+ /* process status text */
-+ i = -1;
-+ while (text[++i]) {
-+ if (text[i] == '^' && !isCode) {
-+ isCode = 1;
-+
-+ text[i] = '\0';
-+ w = TEXTW(text) - lrpad;
-+ drw_text(drw, x, 0, w, bh, 0, text, 0);
-+
-+ x += w;
-+
-+ /* process code */
-+ while (text[++i] != '^') {
-+ if (text[i] == 'c') {
-+ char buf[8];
-+ memcpy(buf, (char*)text+i+1, 7);
-+ buf[7] = '\0';
-+ drw_clr_create(drw, &drw->scheme[ColFg], buf);
-+ i += 7;
-+ } else if (text[i] == 'b') {
-+ char buf[8];
-+ memcpy(buf, (char*)text+i+1, 7);
-+ buf[7] = '\0';
-+ drw_clr_create(drw, &drw->scheme[ColBg], buf);
-+ i += 7;
-+ } else if (text[i] == 'd') {
-+ drw->scheme[ColFg] = scheme[SchemeNorm][ColFg];
-+ drw->scheme[ColBg] = scheme[SchemeNorm][ColBg];
-+ } else if (text[i] == 'r') {
-+ int rx = atoi(text + ++i);
-+ while (text[++i] != ',');
-+ int ry = atoi(text + ++i);
-+ while (text[++i] != ',');
-+ int rw = atoi(text + ++i);
-+ while (text[++i] != ',');
-+ int rh = atoi(text + ++i);
-+
-+ drw_rect(drw, rx + x, ry, rw, rh, 1, 0);
-+ } else if (text[i] == 'f') {
-+ x += atoi(text + ++i);
-+ }
-+ }
-+
-+ text = text + i + 1;
-+ i=-1;
-+ isCode = 0;
-+ }
-+ }
-+
-+ if (!isCode) {
-+ w = TEXTW(text) - lrpad;
-+ drw_text(drw, x, 0, w, bh, 0, text, 0);
-+ }
-+
-+ drw_setscheme(drw, scheme[SchemeNorm]);
-+ free(p);
-+
-+ return ret;
-+}
-+
- void
- drawbar(Monitor *m)
- {
-- int x, w, tw = 0;
-+ int x, w, tw = 0, stw = 0;
- int boxs = drw->fonts->h / 9;
- int boxw = drw->fonts->h / 6 + 2;
- unsigned int i, occ = 0, urg = 0;
-@@ -705,13 +908,15 @@ drawbar(Monitor *m)
- if (!m->showbar)
- return;
-
-+ if(showsystray && m == systraytomon(m) && !systrayonleft)
-+ stw = getsystraywidth();
-+
- /* draw status first so it can be overdrawn by tags later */
- if (m == selmon) { /* status is only drawn on selected monitor */
-- drw_setscheme(drw, scheme[SchemeNorm]);
-- tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
-- drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
-+ tw = m->ww - drawstatusbar(m, bh, stext);
- }
-
-+ resizebarwin(m);
- for (c = m->clients; c; c = c->next) {
- occ |= c->tags;
- if (c->isurgent)
-@@ -732,7 +937,7 @@ drawbar(Monitor *m)
- drw_setscheme(drw, scheme[SchemeNorm]);
- x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
-
-- if ((w = m->ww - tw - x) > bh) {
-+ if ((w = m->ww - tw - stw - x) > bh) {
- if (m->sel) {
- drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
- drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
-@@ -743,7 +948,7 @@ drawbar(Monitor *m)
- drw_rect(drw, x, 0, w, bh, 1, 1);
- }
- }
-- drw_map(drw, m->barwin, 0, 0, m->ww, bh);
-+ drw_map(drw, m->barwin, 0, 0, m->ww - stw, bh);
- }
-
- void
-@@ -780,8 +985,11 @@ expose(XEvent *e)
- Monitor *m;
- XExposeEvent *ev = &e->xexpose;
-
-- if (ev->count == 0 && (m = wintomon(ev->window)))
-+ if (ev->count == 0 && (m = wintomon(ev->window))) {
- drawbar(m);
-+ if (m == selmon)
-+ updatesystray();
-+ }
- }
-
- void
-@@ -867,9 +1075,17 @@ getatomprop(Client *c, Atom prop)
- unsigned char *p = NULL;
- Atom da, atom = None;
-
-- if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM,
-+ /* FIXME getatomprop should return the number of items and a pointer to
-+ * the stored data instead of this workaround */
-+ Atom req = XA_ATOM;
-+ if (prop == xatom[XembedInfo])
-+ req = xatom[XembedInfo];
-+
-+ if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req,
- &da, &di, &dl, &dl, &p) == Success && p) {
- atom = *(Atom *)p;
-+ if (da == xatom[XembedInfo] && dl == 2)
-+ atom = ((Atom *)p)[1];
- XFree(p);
- }
- return atom;
-@@ -903,6 +1119,16 @@ getstate(Window w)
- return result;
- }
-
-+unsigned int
-+getsystraywidth()
-+{
-+ unsigned int w = 0;
-+ Client *i;
-+ if(showsystray)
-+ for(i = systray->icons; i; w += i->w + systrayspacing, i = i->next) ;
-+ return w ? w + systrayspacing : 1;
-+}
-+
- int
- gettextprop(Window w, Atom atom, char *text, unsigned int size)
- {
-@@ -1007,7 +1233,8 @@ killclient(const Arg *arg)
- {
- if (!selmon->sel)
- return;
-- if (!sendevent(selmon->sel, wmatom[WMDelete])) {
-+
-+ if (!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0 , 0, 0)) {
- XGrabServer(dpy);
- XSetErrorHandler(xerrordummy);
- XSetCloseDownMode(dpy, DestroyAll);
-@@ -1096,6 +1323,13 @@ maprequest(XEvent *e)
- static XWindowAttributes wa;
- XMapRequestEvent *ev = &e->xmaprequest;
-
-+ Client *i;
-+ if ((i = wintosystrayicon(ev->window))) {
-+ sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION);
-+ resizebarwin(selmon);
-+ updatesystray();
-+ }
-+
- if (!XGetWindowAttributes(dpy, ev->window, &wa))
- return;
- if (wa.override_redirect)
-@@ -1219,7 +1453,18 @@ propertynotify(XEvent *e)
- Window trans;
- XPropertyEvent *ev = &e->xproperty;
-
-- if ((ev->window == root) && (ev->atom == XA_WM_NAME))
-+ if ((c = wintosystrayicon(ev->window))) {
-+ if (ev->atom == XA_WM_NORMAL_HINTS) {
-+ updatesizehints(c);
-+ updatesystrayicongeom(c, c->w, c->h);
-+ }
-+ else
-+ updatesystrayiconstate(c, ev);
-+ resizebarwin(selmon);
-+ updatesystray();
-+ }
-+
-+ if ((ev->window == root) && (ev->atom == XA_WM_NAME))
- updatestatus();
- else if (ev->state == PropertyDelete)
- return; /* ignore */
-@@ -1269,6 +1514,19 @@ recttomon(int x, int y, int w, int h)
- return r;
- }
-
-+void
-+removesystrayicon(Client *i)
-+{
-+ Client **ii;
-+
-+ if (!showsystray || !i)
-+ return;
-+ for (ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next);
-+ if (ii)
-+ *ii = i->next;
-+ free(i);
-+}
-+
- void
- resize(Client *c, int x, int y, int w, int h, int interact)
- {
-@@ -1276,6 +1534,14 @@ resize(Client *c, int x, int y, int w, int h, int interact)
- resizeclient(c, x, y, w, h);
- }
-
-+void
-+resizebarwin(Monitor *m) {
-+ unsigned int w = m->ww;
-+ if (showsystray && m == systraytomon(m) && !systrayonleft)
-+ w -= getsystraywidth();
-+ XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh);
-+}
-+
- void
- resizeclient(Client *c, int x, int y, int w, int h)
- {
-@@ -1348,6 +1614,19 @@ resizemouse(const Arg *arg)
- }
- }
-
-+void
-+resizerequest(XEvent *e)
-+{
-+ XResizeRequestEvent *ev = &e->xresizerequest;
-+ Client *i;
-+
-+ if ((i = wintosystrayicon(ev->window))) {
-+ updatesystrayicongeom(i, ev->width, ev->height);
-+ resizebarwin(selmon);
-+ updatesystray();
-+ }
-+}
-+
- void
- restack(Monitor *m)
- {
-@@ -1437,26 +1716,37 @@ setclientstate(Client *c, long state)
- }
-
- int
--sendevent(Client *c, Atom proto)
-+sendevent(Window w, Atom proto, int mask, long d0, long d1, long d2, long d3, long d4)
- {
- int n;
-- Atom *protocols;
-+ Atom *protocols, mt;
- int exists = 0;
- XEvent ev;
-
-- if (XGetWMProtocols(dpy, c->win, &protocols, &n)) {
-- while (!exists && n--)
-- exists = protocols[n] == proto;
-- XFree(protocols);
-+ if (proto == wmatom[WMTakeFocus] || proto == wmatom[WMDelete]) {
-+ mt = wmatom[WMProtocols];
-+ if (XGetWMProtocols(dpy, w, &protocols, &n)) {
-+ while (!exists && n--)
-+ exists = protocols[n] == proto;
-+ XFree(protocols);
-+ }
- }
-+ else {
-+ exists = True;
-+ mt = proto;
-+ }
-+
- if (exists) {
- ev.type = ClientMessage;
-- ev.xclient.window = c->win;
-- ev.xclient.message_type = wmatom[WMProtocols];
-+ ev.xclient.window = w;
-+ ev.xclient.message_type = mt;
- ev.xclient.format = 32;
-- ev.xclient.data.l[0] = proto;
-- ev.xclient.data.l[1] = CurrentTime;
-- XSendEvent(dpy, c->win, False, NoEventMask, &ev);
-+ ev.xclient.data.l[0] = d0;
-+ ev.xclient.data.l[1] = d1;
-+ ev.xclient.data.l[2] = d2;
-+ ev.xclient.data.l[3] = d3;
-+ ev.xclient.data.l[4] = d4;
-+ XSendEvent(dpy, w, False, mask, &ev);
- }
- return exists;
- }
-@@ -1470,7 +1760,7 @@ setfocus(Client *c)
- XA_WINDOW, 32, PropModeReplace,
- (unsigned char *) &(c->win), 1);
- }
-- sendevent(c, wmatom[WMTakeFocus]);
-+ sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0);
- }
-
- void
-@@ -1558,22 +1848,32 @@ setup(void)
- wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False);
- wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
- netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
-- netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
-- netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
-+ netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
-+ netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", False);
-+ netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", False);
-+ netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False);
-+ netatom[NetSystemTrayOrientationHorz] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION_HORZ", False);
-+ netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
- netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
- netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
- netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
- netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
- netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
- netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
-- /* init cursors */
-+ xatom[Manager] = XInternAtom(dpy, "MANAGER", False);
-+ xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False);
-+ xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False);
-+ /* init cursors */
- cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
- cursor[CurResize] = drw_cur_create(drw, XC_sizing);
- cursor[CurMove] = drw_cur_create(drw, XC_fleur);
- /* init appearance */
-- scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
-+ scheme = ecalloc(LENGTH(colors) + 1, sizeof(Clr *));
-+ scheme[LENGTH(colors)] = drw_scm_create(drw, colors[0], 3);
- for (i = 0; i < LENGTH(colors); i++)
- scheme[i] = drw_scm_create(drw, colors[i], 3);
-+ /* init system tray */
-+ updatesystray();
- /* init bars */
- updatebars();
- updatestatus();
-@@ -1707,7 +2007,18 @@ togglebar(const Arg *arg)
- {
- selmon->showbar = !selmon->showbar;
- updatebarpos(selmon);
-- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
-+ resizebarwin(selmon);
-+ if (showsystray) {
-+ XWindowChanges wc;
-+ if (!selmon->showbar)
-+ wc.y = -bh;
-+ else if (selmon->showbar) {
-+ wc.y = 0;
-+ if (!selmon->topbar)
-+ wc.y = selmon->mh - bh;
-+ }
-+ XConfigureWindow(dpy, systray->win, CWY, &wc);
-+ }
- arrange(selmon);
- }
-
-@@ -1802,11 +2113,18 @@ unmapnotify(XEvent *e)
- else
- unmanage(c, 0);
- }
-+ else if ((c = wintosystrayicon(ev->window))) {
-+ /* KLUDGE! sometimes icons occasionally unmap their windows, but do
-+ * _not_ destroy them. We map those windows back */
-+ XMapRaised(dpy, c->win);
-+ updatesystray();
-+ }
- }
-
- void
- updatebars(void)
- {
-+ unsigned int w;
- Monitor *m;
- XSetWindowAttributes wa = {
- .override_redirect = True,
-@@ -1817,10 +2135,15 @@ updatebars(void)
- for (m = mons; m; m = m->next) {
- if (m->barwin)
- continue;
-- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen),
-+ w = m->ww;
-+ if (showsystray && m == systraytomon(m))
-+ w -= getsystraywidth();
-+ m->barwin = XCreateWindow(dpy, root, m->wx, m->by, w, bh, 0, DefaultDepth(dpy, screen),
- CopyFromParent, DefaultVisual(dpy, screen),
- CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
- XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
-+ if (showsystray && m == systraytomon(m))
-+ XMapRaised(dpy, systray->win);
- XMapRaised(dpy, m->barwin);
- XSetClassHint(dpy, m->barwin, &ch);
- }
-@@ -1996,6 +2319,125 @@ updatestatus(void)
- if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
- strcpy(stext, "dwm-"VERSION);
- drawbar(selmon);
-+ updatesystray();
-+}
-+
-+
-+void
-+updatesystrayicongeom(Client *i, int w, int h)
-+{
-+ if (i) {
-+ i->h = bh;
-+ if (w == h)
-+ i->w = bh;
-+ else if (h == bh)
-+ i->w = w;
-+ else
-+ i->w = (int) ((float)bh * ((float)w / (float)h));
-+ applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False);
-+ /* force icons into the systray dimensions if they don't want to */
-+ if (i->h > bh) {
-+ if (i->w == i->h)
-+ i->w = bh;
-+ else
-+ i->w = (int) ((float)bh * ((float)i->w / (float)i->h));
-+ i->h = bh;
-+ }
-+ }
-+}
-+
-+void
-+updatesystrayiconstate(Client *i, XPropertyEvent *ev)
-+{
-+ long flags;
-+ int code = 0;
-+
-+ if (!showsystray || !i || ev->atom != xatom[XembedInfo] ||
-+ !(flags = getatomprop(i, xatom[XembedInfo])))
-+ return;
-+
-+ if (flags & XEMBED_MAPPED && !i->tags) {
-+ i->tags = 1;
-+ code = XEMBED_WINDOW_ACTIVATE;
-+ XMapRaised(dpy, i->win);
-+ setclientstate(i, NormalState);
-+ }
-+ else if (!(flags & XEMBED_MAPPED) && i->tags) {
-+ i->tags = 0;
-+ code = XEMBED_WINDOW_DEACTIVATE;
-+ XUnmapWindow(dpy, i->win);
-+ setclientstate(i, WithdrawnState);
-+ }
-+ else
-+ return;
-+ sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0,
-+ systray->win, XEMBED_EMBEDDED_VERSION);
-+}
-+
-+void
-+updatesystray(void)
-+{
-+ XSetWindowAttributes wa;
-+ XWindowChanges wc;
-+ Client *i;
-+ Monitor *m = systraytomon(NULL);
-+ unsigned int x = m->mx + m->mw;
-+ unsigned int sw = TEXTW(stext) - lrpad + systrayspacing;
-+ unsigned int w = 1;
-+
-+ if (!showsystray)
-+ return;
-+ if (systrayonleft)
-+ x -= sw + lrpad / 2;
-+ if (!systray) {
-+ /* init systray */
-+ if (!(systray = (Systray *)calloc(1, sizeof(Systray))))
-+ die("fatal: could not malloc() %u bytes\n", sizeof(Systray));
-+ systray->win = XCreateSimpleWindow(dpy, root, x, m->by, w, bh, 0, 0, scheme[SchemeSel][ColBg].pixel);
-+ wa.event_mask = ButtonPressMask | ExposureMask;
-+ wa.override_redirect = True;
-+ wa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
-+ XSelectInput(dpy, systray->win, SubstructureNotifyMask);
-+ XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32,
-+ PropModeReplace, (unsigned char *)&netatom[NetSystemTrayOrientationHorz], 1);
-+ XChangeWindowAttributes(dpy, systray->win, CWEventMask|CWOverrideRedirect|CWBackPixel, &wa);
-+ XMapRaised(dpy, systray->win);
-+ XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime);
-+ if (XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) {
-+ sendevent(root, xatom[Manager], StructureNotifyMask, CurrentTime, netatom[NetSystemTray], systray->win, 0, 0);
-+ XSync(dpy, False);
-+ }
-+ else {
-+ fprintf(stderr, "dwm: unable to obtain system tray.\n");
-+ free(systray);
-+ systray = NULL;
-+ return;
-+ }
-+ }
-+ for (w = 0, i = systray->icons; i; i = i->next) {
-+ /* make sure the background color stays the same */
-+ wa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
-+ XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa);
-+ XMapRaised(dpy, i->win);
-+ w += systrayspacing;
-+ i->x = w;
-+ XMoveResizeWindow(dpy, i->win, i->x, 0, i->w, i->h);
-+ w += i->w;
-+ if (i->mon != m)
-+ i->mon = m;
-+ }
-+ w = w ? w + systrayspacing : 1;
-+ x -= w;
-+ XMoveResizeWindow(dpy, systray->win, x, m->by, w, bh);
-+ wc.x = x; wc.y = m->by; wc.width = w; wc.height = bh;
-+ wc.stack_mode = Above; wc.sibling = m->barwin;
-+ XConfigureWindow(dpy, systray->win, CWX|CWY|CWWidth|CWHeight|CWSibling|CWStackMode, &wc);
-+ XMapWindow(dpy, systray->win);
-+ XMapSubwindows(dpy, systray->win);
-+ /* redraw background */
-+ XSetForeground(dpy, drw->gc, scheme[SchemeNorm][ColBg].pixel);
-+ XFillRectangle(dpy, systray->win, drw->gc, 0, 0, w, bh);
-+ XSync(dpy, False);
- }
-
- void
-@@ -2063,6 +2505,16 @@ wintoclient(Window w)
- return NULL;
- }
-
-+Client *
-+wintosystrayicon(Window w) {
-+ Client *i = NULL;
-+
-+ if (!showsystray || !w)
-+ return i;
-+ for (i = systray->icons; i && i->win != w; i = i->next) ;
-+ return i;
-+}
-+
- Monitor *
- wintomon(Window w)
- {
-@@ -2116,6 +2568,22 @@ xerrorstart(Display *dpy, XErrorEvent *ee)
- return -1;
- }
-
-+Monitor *
-+systraytomon(Monitor *m) {
-+ Monitor *t;
-+ int i, n;
-+ if(!systraypinning) {
-+ if(!m)
-+ return selmon;
-+ return m == selmon ? m : NULL;
-+ }
-+ for(n = 1, t = mons; t && t->next; n++, t = t->next) ;
-+ for(i = 1, t = mons; t && t->next && i < systraypinning; i++, t = t->next) ;
-+ if(systraypinningfailfirst && n < systraypinning)
-+ return mons;
-+ return t;
-+}
-+
- void
- zoom(const Arg *arg)
- {
diff --git a/.local/src/dwm/patches/dwm-statusallmons-6.2.diff b/.local/src/dwm/patches/dwm-statusallmons-6.2.diff
@@ -1,25 +0,0 @@
-diff -up a/dwm.c b/dwm.c
---- a/dwm.c 2020-07-09 16:49:10.023585649 +0200
-+++ b/dwm.c 2020-07-09 16:49:43.497542191 +0200
-@@ -702,7 +702,7 @@ drawbar(Monitor *m)
- Client *c;
-
- /* draw status first so it can be overdrawn by tags later */
-- if (m == selmon) { /* status is only drawn on selected monitor */
-+ if (m == selmon || 1) { /* status is only drawn on selected monitor */
- drw_setscheme(drw, scheme[SchemeNorm]);
- sw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
- drw_text(drw, m->ww - sw, 0, sw, bh, 0, stext, 0);
-@@ -1987,9 +1987,11 @@ updatesizehints(Client *c)
- void
- updatestatus(void)
- {
-+ Monitor* m;
- if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
- strcpy(stext, "dwm-"VERSION);
-- drawbar(selmon);
-+ for(m = mons; m; m = m->next)
-+ drawbar(m);
- }
-
- void
diff --git a/.local/src/dwm/patches/dwm-sticky-6.1.diff b/.local/src/dwm/patches/dwm-sticky-6.1.diff
@@ -1,58 +0,0 @@
-diff --git a/config.def.h b/config.def.h
-index 7054c06..9b5d5b8 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -76,6 +76,7 @@ static Key keys[] = {
- { MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
- { MODKEY, XK_space, setlayout, {0} },
- { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
-+ { MODKEY, XK_s, togglesticky, {0} },
- { MODKEY, XK_0, view, {.ui = ~0 } },
- { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
- { MODKEY, XK_comma, focusmon, {.i = -1 } },
-diff --git a/dwm.c b/dwm.c
-index 0362114..0ef5c7f 100644
---- a/dwm.c
-+++ b/dwm.c
-@@ -49,7 +49,7 @@
- #define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
- #define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
- * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
--#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]))
-+#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]) || C->issticky)
- #define LENGTH(X) (sizeof X / sizeof X[0])
- #define MOUSEMASK (BUTTONMASK|PointerMotionMask)
- #define WIDTH(X) ((X)->w + 2 * (X)->bw)
-@@ -92,7 +92,7 @@ struct Client {
- int basew, baseh, incw, inch, maxw, maxh, minw, minh;
- int bw, oldbw;
- unsigned int tags;
-- int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
-+ int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, issticky;
- Client *next;
- Client *snext;
- Monitor *mon;
-@@ -211,6 +211,7 @@ static void tagmon(const Arg *arg);
- static void tile(Monitor *);
- static void togglebar(const Arg *arg);
- static void togglefloating(const Arg *arg);
-+static void togglesticky(const Arg *arg);
- static void toggletag(const Arg *arg);
- static void toggleview(const Arg *arg);
- static void unfocus(Client *c, int setfocus);
-@@ -1713,6 +1714,15 @@ togglefloating(const Arg *arg)
- }
-
- void
-+togglesticky(const Arg *arg)
-+{
-+ if (!selmon->sel)
-+ return;
-+ selmon->sel->issticky = !selmon->sel->issticky;
-+ arrange(selmon);
-+}
-+
-+void
- toggletag(const Arg *arg)
- {
- unsigned int newtags;
diff --git a/.local/src/dwm/patches/dwm-warp-6.2.diff b/.local/src/dwm/patches/dwm-warp-6.2.diff
@@ -1,58 +0,0 @@
-diff --git a/dwm.c b/dwm.c
-index 4465af1..bf74f60 100644
---- a/dwm.c
-+++ b/dwm.c
-@@ -227,6 +227,7 @@ static void updatetitle(Client *c);
- static void updatewindowtype(Client *c);
- static void updatewmhints(Client *c);
- static void view(const Arg *arg);
-+static void warp(const Client *c);
- static Client *wintoclient(Window w);
- static Monitor *wintomon(Window w);
- static int xerror(Display *dpy, XErrorEvent *ee);
-@@ -827,6 +828,7 @@ focusmon(const Arg *arg)
- unfocus(selmon->sel, 0);
- selmon = m;
- focus(NULL);
-+ warp(selmon->sel);
- }
-
- void
-@@ -1367,6 +1369,8 @@ restack(Monitor *m)
- }
- XSync(dpy, False);
- while (XCheckMaskEvent(dpy, EnterWindowMask, &ev));
-+ if (m == selmon && (m->tagset[m->seltags] & m->sel->tags) && selmon->lt[selmon->sellt] != &layouts[2])
-+ warp(m->sel);
- }
-
- void
-@@ -2044,6 +2048,28 @@ view(const Arg *arg)
- arrange(selmon);
- }
-
-+void
-+warp(const Client *c)
-+{
-+ int x, y;
-+
-+ if (!c) {
-+ XWarpPointer(dpy, None, root, 0, 0, 0, 0, selmon->wx + selmon->ww/2, selmon->wy + selmon->wh/2);
-+ return;
-+ }
-+
-+ if (!getrootptr(&x, &y) ||
-+ (x > c->x - c->bw &&
-+ y > c->y - c->bw &&
-+ x < c->x + c->w + c->bw*2 &&
-+ y < c->y + c->h + c->bw*2) ||
-+ (y > c->mon->by && y < c->mon->by + bh) ||
-+ (c->mon->topbar && !y))
-+ return;
-+
-+ XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2);
-+}
-+
- Client *
- wintoclient(Window w)
- {
diff --git a/.local/src/dwm/patches/dwm-xrdb-6.2.diff b/.local/src/dwm/patches/dwm-xrdb-6.2.diff
@@ -1,188 +0,0 @@
-diff --git a/config.def.h b/config.def.h
-index 1c0b587..5db7d05 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -7,15 +7,16 @@ static const int showbar = 1; /* 0 means no bar */
- static const int topbar = 1; /* 0 means bottom bar */
- static const char *fonts[] = { "monospace:size=10" };
- static const char dmenufont[] = "monospace:size=10";
--static const char col_gray1[] = "#222222";
--static const char col_gray2[] = "#444444";
--static const char col_gray3[] = "#bbbbbb";
--static const char col_gray4[] = "#eeeeee";
--static const char col_cyan[] = "#005577";
--static const char *colors[][3] = {
-- /* fg bg border */
-- [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
-- [SchemeSel] = { col_gray4, col_cyan, col_cyan },
-+static char normbgcolor[] = "#222222";
-+static char normbordercolor[] = "#444444";
-+static char normfgcolor[] = "#bbbbbb";
-+static char selfgcolor[] = "#eeeeee";
-+static char selbordercolor[] = "#005577";
-+static char selbgcolor[] = "#005577";
-+static char *colors[][3] = {
-+ /* fg bg border */
-+ [SchemeNorm] = { normfgcolor, normbgcolor, normbordercolor },
-+ [SchemeSel] = { selfgcolor, selbgcolor, selbordercolor },
- };
-
- /* tagging */
-@@ -56,7 +57,7 @@ static const Layout layouts[] = {
-
- /* commands */
- static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
--static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
-+static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbordercolor, "-sf", selfgcolor, NULL };
- static const char *termcmd[] = { "st", NULL };
-
- static Key keys[] = {
-@@ -84,6 +85,7 @@ static Key keys[] = {
- { MODKEY, XK_period, focusmon, {.i = +1 } },
- { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
- { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
-+ { MODKEY, XK_F5, xrdb, {.v = NULL } },
- TAGKEYS( XK_1, 0)
- TAGKEYS( XK_2, 1)
- TAGKEYS( XK_3, 2)
-diff --git a/drw.c b/drw.c
-index 8fd1ca4..e4968a0 100644
---- a/drw.c
-+++ b/drw.c
-@@ -207,7 +207,7 @@ drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
- /* Wrapper to create color schemes. The caller has to call free(3) on the
- * returned color scheme when done using it. */
- Clr *
--drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
-+drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount)
- {
- size_t i;
- Clr *ret;
-diff --git a/drw.h b/drw.h
-index 4bcd5ad..42b04ce 100644
---- a/drw.h
-+++ b/drw.h
-@@ -39,7 +39,7 @@ void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned in
-
- /* Colorscheme abstraction */
- void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
--Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
-+Clr *drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount);
-
- /* Cursor abstraction */
- Cur *drw_cur_create(Drw *drw, int shape);
-diff --git a/dwm.c b/dwm.c
-index 4465af1..7fa45c5 100644
---- a/dwm.c
-+++ b/dwm.c
-@@ -35,6 +35,7 @@
- #include <X11/Xatom.h>
- #include <X11/Xlib.h>
- #include <X11/Xproto.h>
-+#include <X11/Xresource.h>
- #include <X11/Xutil.h>
- #ifdef XINERAMA
- #include <X11/extensions/Xinerama.h>
-@@ -56,6 +57,21 @@
- #define HEIGHT(X) ((X)->h + 2 * (X)->bw)
- #define TAGMASK ((1 << LENGTH(tags)) - 1)
- #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
-+#define XRDB_LOAD_COLOR(R,V) if (XrmGetResource(xrdb, R, NULL, &type, &value) == True) { \
-+ if (value.addr != NULL && strnlen(value.addr, 8) == 7 && value.addr[0] == '#') { \
-+ int i = 1; \
-+ for (; i <= 6; i++) { \
-+ if (value.addr[i] < 48) break; \
-+ if (value.addr[i] > 57 && value.addr[i] < 65) break; \
-+ if (value.addr[i] > 70 && value.addr[i] < 97) break; \
-+ if (value.addr[i] > 102) break; \
-+ } \
-+ if (i == 7) { \
-+ strncpy(V, value.addr, 7); \
-+ V[7] = '\0'; \
-+ } \
-+ } \
-+ }
-
- /* enums */
- enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
-@@ -177,6 +193,7 @@ static void grabkeys(void);
- static void incnmaster(const Arg *arg);
- static void keypress(XEvent *e);
- static void killclient(const Arg *arg);
-+static void loadxrdb(void);
- static void manage(Window w, XWindowAttributes *wa);
- static void mappingnotify(XEvent *e);
- static void maprequest(XEvent *e);
-@@ -232,6 +249,7 @@ static Monitor *wintomon(Window w);
- static int xerror(Display *dpy, XErrorEvent *ee);
- static int xerrordummy(Display *dpy, XErrorEvent *ee);
- static int xerrorstart(Display *dpy, XErrorEvent *ee);
-+static void xrdb(const Arg *arg);
- static void zoom(const Arg *arg);
-
- /* variables */
-@@ -1014,6 +1032,37 @@ killclient(const Arg *arg)
- }
- }
-
-+void
-+loadxrdb()
-+{
-+ Display *display;
-+ char * resm;
-+ XrmDatabase xrdb;
-+ char *type;
-+ XrmValue value;
-+