Introduction
Introduction Statistics Contact Development Disclaimer Help
Moving final computer over to OpenBSD 7.6. - dotfiles - These are my dotfiles. …
Log
Files
Refs
README
---
commit 2274190a12736e2d3c2dce6e346e582a7092dd5e
parent 38522989aa40a65ccd5ce9d8635ec097f20a61d8
Author: Jay Scott <[email protected]>
Date: Tue, 7 Jan 2025 20:11:03 +0000
Moving final computer over to OpenBSD 7.6.
Diffstat:
M README | 14 +++++++-------
A Xdefaults | 54 +++++++++++++++++++++++++++++…
D ashrc | 67 -----------------------------…
A bin/diceware | 1338 ++++++++++++++++++++++++++++++
A bin/mullvad | 31 +++++++++++++++++++++++++++++…
M bin/music | 2 +-
A bin/pass | 279 +++++++++++++++++++++++++++++…
D bin/sway-start | 22 ----------------------
M bootstrap.sh | 4 ++--
D foot/foot.ini | 27 ---------------------------
A kshrc | 63 +++++++++++++++++++++++++++++…
A mpd/mpd.conf | 20 ++++++++++++++++++++
A ncmpcpp/config | 31 +++++++++++++++++++++++++++++…
M profile | 2 +-
D qutebrowser/blank.html | 44 -----------------------------…
D qutebrowser/config.py | 92 -----------------------------…
D qutebrowser/scripts/fingerprint.py | 43 ------------------------------
D qutebrowser/scripts/gruvbox.py | 332 -----------------------------…
D qutebrowser/scripts/redirects.py | 70 -----------------------------…
D qutebrowser/scripts/user_agent.py | 31 -----------------------------…
A suckless/dmenu/Makefile | 39 +++++++++++++++++++++++++++++…
A suckless/dmenu/config.h | 16 ++++++++++++++++
A suckless/dmenu/patches/01-dmenu-bo… | 36 +++++++++++++++++++++++++++…
A suckless/dmenu/patches/02-dmenu-ce… | 120 +++++++++++++++++++++++++++…
A suckless/dwm/Makefile | 41 +++++++++++++++++++++++++++++…
A suckless/dwm/config.h | 201 ++++++++++++++++++++++++++++++
A suckless/dwm/patches/01-dwm-systra… | 746 +++++++++++++++++++++++++++…
A suckless/herbe/Makefile | 40 +++++++++++++++++++++++++++++…
A suckless/herbe/config.h | 19 +++++++++++++++++++
A suckless/slstatus/Makefile | 35 +++++++++++++++++++++++++++++…
A suckless/slstatus/config.h | 71 +++++++++++++++++++++++++++++…
D sway/config | 69 ------------------------------
D waybar/config | 67 -----------------------------…
D waybar/style.css | 55 -----------------------------…
D waybar/waybar_mail.sh | 12 ------------
D waybar/waybar_vpn.sh | 9 ---------
A xenodm/Xresources | 24 ++++++++++++++++++++++++
A xenodm/Xsetup_0 | 7 +++++++
38 files changed, 3222 insertions(+), 951 deletions(-)
---
diff --git a/README b/README
@@ -8,16 +8,16 @@
These are my dotfiles. There are many like it, but these are mine.
They are managed via the bootstrap.sh shell script, this links the files and
-folders in the appropriate place. They are used on Alpine Linux which I use as
-my main desktop OS and are forever evolving.
+folders in the appropriate place. They are used on OpenBSD which I use as my
+main desktop OS and are forever evolving.
- operating sys : alpine linux
- window manager : sway
- terminal : foot
- launcher : bemenu
+ operating sys : openbsd 7.6
+ window manager : dwm
+ terminal : xterm
+ launcher : dmenu
email : neomutt
- browser : qutebrowser / librewolf
+ browser : firefox / lynx
media : mpv
password mgmt : pass
vpn : mullvad
diff --git a/Xdefaults b/Xdefaults
@@ -0,0 +1,54 @@
+xterm*FaceName: Hack
+xterm*FaceSize: 14
+xterm*toolBar: false
+xterm*scrollBar: false
+xterm*selectToClipboard: false
+XTerm*loginShell: true
+XTerm*scrollBar: false
+XTerm*selectToClipboard:true
+
+/* XFT */
+Xft.dpi: 96
+Xft.hinting: true
+Xft.rgba: rgb
+Xft.antialias: true
+Xft.autohint: false
+Xft.hintstyle: hintslight
+Xft.lcdfilter: lcddefault
+
+! special
+*.foreground: #ebdbb2
+*.background: #282828
+*.cursorColor: #fbf0d2
+
+! black
+*.color0: #181512
+*.color8: #454545
+
+! red
+*.color1: #bb6055
+*.color9: #c94539
+
+! green
+*.color2: #80964d
+*.color10: #aabb46
+
+! yellow
+*.color3: #8b6268
+*.color11: #dab733
+
+! blue
+*.color4: #756583
+*.color12: #a3535e
+
+! magenta
+*.color5: #628185
+*.color13: #becc90
+
+! cyan
+*.color6: #a4b810
+*.color14: #69c884
+
+! white
+*.color7: #d3cab3
+*.color15: #c9b09a
diff --git a/ashrc b/ashrc
@@ -1,67 +0,0 @@
-export XDG_CONFIG_HOME="$HOME/.config"
-export XDG_CACHE_HOME="$HOME/.cache"
-export XDG_DATA_HOME="$HOME/.local/share"
-export XDG_STATE_HOME="$HOME/.local/state"
-
-# cleanup ~/
-export PASSWORD_STORE_DIR="$XDG_CONFIG_HOME"/pass
-export CARGO_HOME="$XDG_DATA_HOME"/cargo
-
-# common exports
-GPG_TTY=$(tty)
-export GPG_TTY
-export EDITOR="nvim"
-export BROWSER="qutebrowser"
-export PATH=$PATH:$HOME/bin
-
-# tools
-export OPENER=~/bin/link-handler
-export BEMENU_OPTS="-l 10 -p '>>> ' --tb '#55a1ba' --tf '#ffffff' --hf '#44444…
-
-# lynx
-export LYNX_CFG=$HOME/.config/lynx/config
-export LYNX_LSS=$HOME/.config/lynx/theme.lss
-
-# safety first kids!
-alias cp='cp -i'
-alias mv='mv -i'
-alias rm='rm -i'
-
-# random alias
-alias weather='curl wttr.in/?1QF'
-alias wget='wget --hsts-file="$XDG_CACHE_HOME/wget-hsts"'
-
-# git alias
-alias ga='git add -A'
-alias gs='git status -s'
-alias gl="git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset…
-alias gd='git diff'
-alias gma='git commit -am'
-
-# neo
-alias vim='nvim'
-alias mutt='neomutt'
-alias mpv="mpv --autofit=30% --really-quiet --no-terminal"
-alias w="w3m -B"
-
-# vpn
-alias von='doas wg-quick up mullvad'
-alias voff='doas wg-quick down mullvad'
-alias vcheck='curl https://am.i.mullvad.net/connected'
-
-# ash
-export LANG=en_US.UTF-8
-export LC_CTYPE="en_US.UTF-8"
-export LC_ALL=en_US.UTF-8
-export PS1="\[\e[00;34m\]▶▶▶ \W \[\e[0m\]"
-
-mirror_repo() {
- if [ -d .git ] || git rev-parse --git-dir > /dev/null 2>&1; then
- remote_url="[email protected]:$(basename $(pwd))"
- git remote add mirror "$remote_url" 2>/dev/null || true
- git push --mirror mirror
- echo "Mirrored to $remote_url"
- else
- echo "Not a git repository"
- fi
-}
diff --git a/bin/diceware b/bin/diceware
@@ -0,0 +1,1338 @@
+#!/bin/sh
+#
+# diceware generates random phrases with 10 bits of entropy per
+# word. For a passphrase use 8 words or more.
+#
+# https://www.romanzolotarev.com/bin/diceware
+# Copyright 2017 Roman Zolotarev <[email protected]>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# The word list: CC BY 3.0 US 2016 Electronic Frontier Foundation
+# https://www.eff.org/deeplinks/2016/07/new-wordlists-random-passphrases
+#
+set -e
+
+wordlist=$(cat << EOF
+1111 aardvark
+1112 abandoned
+1113 abbreviate
+1114 abdomen
+1115 abhorrence
+1116 abiding
+1121 abnormal
+1122 abrasion
+1123 absorbing
+1124 abundant
+1125 abyss
+1126 academy
+1131 accountant
+1132 acetone
+1133 achiness
+1134 acid
+1135 acoustics
+1136 acquire
+1141 acrobat
+1142 actress
+1143 acuteness
+1144 aerosol
+1145 aesthetic
+1146 affidavit
+1151 afloat
+1152 afraid
+1153 aftershave
+1154 again
+1155 agency
+1156 aggressor
+1161 aghast
+1162 agitate
+1163 agnostic
+1164 agonizing
+1165 agreeing
+1166 aidless
+1211 aimlessly
+1212 ajar
+1213 alarmclock
+1214 albatross
+1215 alchemy
+1216 alfalfa
+1221 algae
+1222 aliens
+1223 alkaline
+1224 almanac
+1225 alongside
+1226 alphabet
+1231 already
+1232 also
+1233 altitude
+1234 aluminum
+1235 always
+1236 amazingly
+1241 ambulance
+1242 amendment
+1243 amiable
+1244 ammunition
+1245 amnesty
+1246 amoeba
+1251 amplifier
+1252 amuser
+1253 anagram
+1254 anchor
+1255 android
+1256 anesthesia
+1261 angelfish
+1262 animal
+1263 anklet
+1264 announcer
+1265 anonymous
+1266 answer
+1311 antelope
+1312 anxiety
+1313 anyplace
+1314 aorta
+1315 apartment
+1316 apnea
+1321 apostrophe
+1322 apple
+1323 apricot
+1324 aquamarine
+1325 arachnid
+1326 arbitrate
+1331 ardently
+1332 arena
+1333 argument
+1334 aristocrat
+1335 armchair
+1336 aromatic
+1341 arrowhead
+1342 arsonist
+1343 artichoke
+1344 asbestos
+1345 ascend
+1346 aseptic
+1351 ashamed
+1352 asinine
+1353 asleep
+1354 asocial
+1355 asparagus
+1356 astronaut
+1361 asymmetric
+1362 atlas
+1363 atmosphere
+1364 atom
+1365 atrocious
+1366 attic
+1411 atypical
+1412 auctioneer
+1413 auditorium
+1414 augmented
+1415 auspicious
+1416 automobile
+1421 auxiliary
+1422 avalanche
+1423 avenue
+1424 aviator
+1425 avocado
+1426 awareness
+1431 awhile
+1432 awkward
+1433 awning
+1434 awoke
+1435 axially
+1436 azalea
+1441 babbling
+1442 backpack
+1443 badass
+1444 bagpipe
+1445 bakery
+1446 balancing
+1451 bamboo
+1452 banana
+1453 barracuda
+1454 basket
+1455 bathrobe
+1456 bazooka
+1461 blade
+1462 blender
+1463 blimp
+1464 blouse
+1465 blurred
+1466 boatyard
+1511 bobcat
+1512 body
+1513 bogusness
+1514 bohemian
+1515 boiler
+1516 bonnet
+1521 boots
+1522 borough
+1523 bossiness
+1524 bottle
+1525 bouquet
+1526 boxlike
+1531 breath
+1532 briefcase
+1533 broom
+1534 brushes
+1535 bubblegum
+1536 buckle
+1541 buddhist
+1542 buffalo
+1543 bullfrog
+1544 bunny
+1545 busboy
+1546 buzzard
+1551 cabin
+1552 cactus
+1553 cadillac
+1554 cafeteria
+1555 cage
+1556 cahoots
+1561 cajoling
+1562 cakewalk
+1563 calculator
+1564 camera
+1565 canister
+1566 capsule
+1611 carrot
+1612 cashew
+1613 cathedral
+1614 caucasian
+1615 caviar
+1616 ceasefire
+1621 cedar
+1622 celery
+1623 cement
+1624 census
+1625 ceramics
+1626 cesspool
+1631 chalkboard
+1632 cheesecake
+1633 chimney
+1634 chlorine
+1635 chopsticks
+1636 chrome
+1641 chute
+1642 cilantro
+1643 cinnamon
+1644 circle
+1645 cityscape
+1646 civilian
+1651 clay
+1652 clergyman
+1653 clipboard
+1654 clock
+1655 clubhouse
+1656 coathanger
+1661 cobweb
+1662 coconut
+1663 codeword
+1664 coexistent
+1665 coffeecake
+1666 cognitive
+2111 cohabitate
+2112 collarbone
+2113 computer
+2114 confetti
+2115 copier
+2116 cornea
+2121 cosmetics
+2122 cotton
+2123 couch
+2124 coverless
+2125 coyote
+2126 coziness
+2131 crawfish
+2132 crewmember
+2133 crib
+2134 croissant
+2135 crumble
+2136 crystal
+2141 cubical
+2142 cucumber
+2143 cuddly
+2144 cufflink
+2145 cuisine
+2146 culprit
+2151 cup
+2152 curry
+2153 cushion
+2154 cuticle
+2155 cybernetic
+2156 cyclist
+2161 cylinder
+2162 cymbal
+2163 cynicism
+2164 cypress
+2165 cytoplasm
+2166 dachshund
+2211 daffodil
+2212 dagger
+2213 dairy
+2214 dalmatian
+2215 dandelion
+2216 dartboard
+2221 dastardly
+2222 datebook
+2223 daughter
+2224 dawn
+2225 daytime
+2226 dazzler
+2231 dealer
+2232 debris
+2233 decal
+2234 dedicate
+2235 deepness
+2236 defrost
+2241 degree
+2242 dehydrator
+2243 deliverer
+2244 democrat
+2245 dentist
+2246 deodorant
+2251 depot
+2252 deranged
+2253 desktop
+2254 detergent
+2255 device
+2256 dexterity
+2261 diamond
+2262 dibs
+2263 dictionary
+2264 diffuser
+2265 digit
+2266 dilated
+2311 dimple
+2312 dinnerware
+2313 dioxide
+2314 diploma
+2315 directory
+2316 dishcloth
+2321 ditto
+2322 dividers
+2323 dizziness
+2324 doctor
+2325 dodge
+2326 doll
+2331 dominoes
+2332 donut
+2333 doorstep
+2334 dorsal
+2335 double
+2336 downstairs
+2341 dozed
+2342 drainpipe
+2343 dresser
+2344 driftwood
+2345 droppings
+2346 drum
+2351 dryer
+2352 dubiously
+2353 duckling
+2354 duffel
+2355 dugout
+2356 dumpster
+2361 duplex
+2362 durable
+2363 dustpan
+2364 dutiful
+2365 duvet
+2366 dwarfism
+2411 dwelling
+2412 dwindling
+2413 dynamite
+2414 dyslexia
+2415 eagerness
+2416 earlobe
+2421 easel
+2422 eavesdrop
+2423 ebook
+2424 eccentric
+2425 echoless
+2426 eclipse
+2431 ecosystem
+2432 ecstasy
+2433 edged
+2434 editor
+2435 educator
+2436 eelworm
+2441 eerie
+2442 effects
+2443 eggnog
+2444 egomaniac
+2445 ejection
+2446 elastic
+2451 elbow
+2452 elderly
+2453 elephant
+2454 elfishly
+2455 eliminator
+2456 elk
+2461 elliptical
+2462 elongated
+2463 elsewhere
+2464 elusive
+2465 elves
+2466 emancipate
+2511 embroidery
+2512 emcee
+2513 emerald
+2514 emission
+2515 emoticon
+2516 emperor
+2521 emulate
+2522 enactment
+2523 enchilada
+2524 endorphin
+2525 energy
+2526 enforcer
+2531 engine
+2532 enhance
+2533 enigmatic
+2534 enjoyably
+2535 enlarged
+2536 enormous
+2541 enquirer
+2542 enrollment
+2543 ensemble
+2544 entryway
+2545 enunciate
+2546 envoy
+2551 enzyme
+2552 epidemic
+2553 equipment
+2554 erasable
+2555 ergonomic
+2556 erratic
+2561 eruption
+2562 escalator
+2563 eskimo
+2564 esophagus
+2565 espresso
+2566 essay
+2611 estrogen
+2612 etching
+2613 eternal
+2614 ethics
+2615 etiquette
+2616 eucalyptus
+2621 eulogy
+2622 euphemism
+2623 euthanize
+2624 evacuation
+2625 evergreen
+2626 evidence
+2631 evolution
+2632 exam
+2633 excerpt
+2634 exerciser
+2635 exfoliate
+2636 exhale
+2641 exist
+2642 exorcist
+2643 explode
+2644 exquisite
+2645 exterior
+2646 exuberant
+2651 fabric
+2652 factory
+2653 faded
+2654 failsafe
+2655 falcon
+2656 family
+2661 fanfare
+2662 fasten
+2663 faucet
+2664 favorite
+2665 feasibly
+2666 february
+3111 federal
+3112 feedback
+3113 feigned
+3114 feline
+3115 femur
+3116 fence
+3121 ferret
+3122 festival
+3123 fettuccine
+3124 feudalist
+3125 feverish
+3126 fiberglass
+3131 fictitious
+3132 fiddle
+3133 figurine
+3134 fillet
+3135 finalist
+3136 fiscally
+3141 fixture
+3142 flashlight
+3143 fleshiness
+3144 flight
+3145 florist
+3146 flypaper
+3151 foamless
+3152 focus
+3153 foggy
+3154 folksong
+3155 fondue
+3156 footpath
+3161 fossil
+3162 fountain
+3163 fox
+3164 fragment
+3165 freeway
+3166 fridge
+3211 frosting
+3212 fruit
+3213 fryingpan
+3214 gadget
+3215 gainfully
+3216 gallstone
+3221 gamekeeper
+3222 gangway
+3223 garlic
+3224 gaslight
+3225 gathering
+3226 gauntlet
+3231 gearbox
+3232 gecko
+3233 gem
+3234 generator
+3235 geographer
+3236 gerbil
+3241 gesture
+3242 getaway
+3243 geyser
+3244 ghoulishly
+3245 gibberish
+3246 giddiness
+3251 giftshop
+3252 gigabyte
+3253 gimmick
+3254 giraffe
+3255 giveaway
+3256 gizmo
+3261 glasses
+3262 gleeful
+3263 glisten
+3264 glove
+3265 glucose
+3266 glycerin
+3311 gnarly
+3312 gnomish
+3313 goatskin
+3314 goggles
+3315 goldfish
+3316 gong
+3321 gooey
+3322 gorgeous
+3323 gosling
+3324 gothic
+3325 gourmet
+3326 governor
+3331 grape
+3332 greyhound
+3333 grill
+3334 groundhog
+3335 grumbling
+3336 guacamole
+3341 guerrilla
+3342 guitar
+3343 gullible
+3344 gumdrop
+3345 gurgling
+3346 gusto
+3351 gutless
+3352 gymnast
+3353 gynecology
+3354 gyration
+3355 habitat
+3356 hacking
+3361 haggard
+3362 haiku
+3363 halogen
+3364 hamburger
+3365 handgun
+3366 happiness
+3411 hardhat
+3412 hastily
+3413 hatchling
+3414 haughty
+3415 hazelnut
+3416 headband
+3421 hedgehog
+3422 hefty
+3423 heinously
+3424 helmet
+3425 hemoglobin
+3426 henceforth
+3431 herbs
+3432 hesitation
+3433 hexagon
+3434 hubcap
+3435 huddling
+3436 huff
+3441 hugeness
+3442 hullabaloo
+3443 human
+3444 hunter
+3445 hurricane
+3446 hushing
+3451 hyacinth
+3452 hybrid
+3453 hydrant
+3454 hygienist
+3455 hypnotist
+3456 ibuprofen
+3461 icepack
+3462 icing
+3463 iconic
+3464 identical
+3465 idiocy
+3466 idly
+3511 igloo
+3512 ignition
+3513 iguana
+3514 illuminate
+3515 imaging
+3516 imbecile
+3521 imitator
+3522 immigrant
+3523 imprint
+3524 iodine
+3525 ionosphere
+3526 ipad
+3531 iphone
+3532 iridescent
+3533 irksome
+3534 iron
+3535 irrigation
+3536 island
+3541 isotope
+3542 issueless
+3543 italicize
+3544 itemizer
+3545 itinerary
+3546 itunes
+3551 ivory
+3552 jabbering
+3553 jackrabbit
+3554 jaguar
+3555 jailhouse
+3556 jalapeno
+3561 jamboree
+3562 janitor
+3563 jarring
+3564 jasmine
+3565 jaundice
+3566 jawbreaker
+3611 jaywalker
+3612 jazz
+3613 jealous
+3614 jeep
+3615 jelly
+3616 jeopardize
+3621 jersey
+3622 jetski
+3623 jezebel
+3624 jiffy
+3625 jigsaw
+3626 jingling
+3631 jobholder
+3632 jockstrap
+3633 jogging
+3634 john
+3635 joinable
+3636 jokingly
+3641 journal
+3642 jovial
+3643 joystick
+3644 jubilant
+3645 judiciary
+3646 juggle
+3651 juice
+3652 jujitsu
+3653 jukebox
+3654 jumpiness
+3655 junkyard
+3656 juror
+3661 justifying
+3662 juvenile
+3663 kabob
+3664 kamikaze
+3665 kangaroo
+3666 karate
+4111 kayak
+4112 keepsake
+4113 kennel
+4114 kerosene
+4115 ketchup
+4116 khaki
+4121 kickstand
+4122 kilogram
+4123 kimono
+4124 kingdom
+4125 kiosk
+4126 kissing
+4131 kite
+4132 kleenex
+4133 knapsack
+4134 kneecap
+4135 knickers
+4136 koala
+4141 krypton
+4142 laboratory
+4143 ladder
+4144 lakefront
+4145 lantern
+4146 laptop
+4151 laryngitis
+4152 lasagna
+4153 latch
+4154 laundry
+4155 lavender
+4156 laxative
+4161 lazybones
+4162 lecturer
+4163 leftover
+4164 leggings
+4165 leisure
+4166 lemon
+4211 length
+4212 leopard
+4213 leprechaun
+4214 lettuce
+4215 leukemia
+4216 levers
+4221 lewdness
+4222 liability
+4223 library
+4224 licorice
+4225 lifeboat
+4226 lightbulb
+4231 likewise
+4232 lilac
+4233 limousine
+4234 lint
+4235 lioness
+4236 lipstick
+4241 liquid
+4242 listless
+4243 litter
+4244 liverwurst
+4245 lizard
+4246 llama
+4251 luau
+4252 lubricant
+4253 lucidity
+4254 ludicrous
+4255 luggage
+4256 lukewarm
+4261 lullaby
+4262 lumberjack
+4263 lunchbox
+4264 luridness
+4265 luscious
+4266 luxurious
+4311 lyrics
+4312 macaroni
+4313 maestro
+4314 magazine
+4315 mahogany
+4316 maimed
+4321 majority
+4322 makeover
+4323 malformed
+4324 mammal
+4325 mango
+4326 mapmaker
+4331 marbles
+4332 massager
+4333 matchstick
+4334 maverick
+4335 maximum
+4336 mayonnaise
+4341 moaning
+4342 mobilize
+4343 moccasin
+4344 modify
+4345 moisture
+4346 molecule
+4351 momentum
+4352 monastery
+4353 moonshine
+4354 mortuary
+4355 mosquito
+4356 motorcycle
+4361 mousetrap
+4362 movie
+4363 mower
+4364 mozzarella
+4365 muckiness
+4366 mudflow
+4411 mugshot
+4412 mule
+4413 mummy
+4414 mundane
+4415 muppet
+4416 mural
+4421 mustard
+4422 mutation
+4423 myriad
+4424 myspace
+4425 myth
+4426 nail
+4431 namesake
+4432 nanosecond
+4433 napkin
+4434 narrator
+4435 nastiness
+4436 natives
+4441 nautically
+4442 navigate
+4443 nearest
+4444 nebula
+4445 nectar
+4446 nefarious
+4451 negotiator
+4452 neither
+4453 nemesis
+4454 neoliberal
+4455 nephew
+4456 nervously
+4461 nest
+4462 netting
+4463 neuron
+4464 nevermore
+4465 nextdoor
+4466 nicotine
+4511 niece
+4512 nimbleness
+4513 nintendo
+4514 nirvana
+4515 nuclear
+4516 nugget
+4521 nuisance
+4522 nullify
+4523 numbing
+4524 nuptials
+4525 nursery
+4526 nutcracker
+4531 nylon
+4532 oasis
+4533 oat
+4534 obediently
+4535 obituary
+4536 object
+4541 obliterate
+4542 obnoxious
+4543 observer
+4544 obtain
+4545 obvious
+4546 occupation
+4551 oceanic
+4552 octopus
+4553 ocular
+4554 office
+4555 oftentimes
+4556 oiliness
+4561 ointment
+4562 older
+4563 olympics
+4564 omissible
+4565 omnivorous
+4566 oncoming
+4611 onion
+4612 onlooker
+4613 onstage
+4614 onward
+4615 onyx
+4616 oomph
+4621 opaquely
+4622 opera
+4623 opium
+4624 opossum
+4625 opponent
+4626 optical
+4631 opulently
+4632 oscillator
+4633 osmosis
+4634 ostrich
+4635 otherwise
+4636 ought
+4641 outhouse
+4642 ovation
+4643 oven
+4644 owlish
+4645 oxford
+4646 oxidize
+4651 oxygen
+4652 oyster
+4653 ozone
+4654 pacemaker
+4655 padlock
+4656 pageant
+4661 pajamas
+4662 palm
+4663 pamphlet
+4664 pantyhose
+4665 paprika
+4666 parakeet
+5111 passport
+5112 patio
+5113 pauper
+5114 pavement
+5115 payphone
+5116 pebble
+5121 peculiarly
+5122 pedometer
+5123 pegboard
+5124 pelican
+5125 penguin
+5126 peony
+5131 pepperoni
+5132 peroxide
+5133 pesticide
+5134 petroleum
+5135 pewter
+5136 pharmacy
+5141 pheasant
+5142 phonebook
+5143 phrasing
+5144 physician
+5145 plank
+5146 pledge
+5151 plotted
+5152 plug
+5153 plywood
+5154 pneumonia
+5155 podiatrist
+5156 poetic
+5161 pogo
+5162 poison
+5163 poking
+5164 policeman
+5165 poncho
+5166 popcorn
+5211 porcupine
+5212 postcard
+5213 poultry
+5214 powerboat
+5215 prairie
+5216 pretzel
+5221 princess
+5222 propeller
+5223 prune
+5224 pry
+5225 pseudo
+5226 psychopath
+5231 publisher
+5232 pucker
+5233 pueblo
+5234 pulley
+5235 pumpkin
+5236 punchbowl
+5241 puppy
+5242 purse
+5243 pushup
+5244 putt
+5245 puzzle
+5246 pyramid
+5251 python
+5252 quarters
+5253 quesadilla
+5254 quilt
+5255 quote
+5256 racoon
+5261 radish
+5262 ragweed
+5263 railroad
+5264 rampantly
+5265 rancidity
+5266 rarity
+5311 raspberry
+5312 ravishing
+5313 rearrange
+5314 rebuilt
+5315 receipt
+5316 reentry
+5321 refinery
+5322 register
+5323 rehydrate
+5324 reimburse
+5325 rejoicing
+5326 rekindle
+5331 relic
+5332 remote
+5333 renovator
+5334 reopen
+5335 reporter
+5336 request
+5341 rerun
+5342 reservoir
+5343 retriever
+5344 reunion
+5345 revolver
+5346 rewrite
+5351 rhapsody
+5352 rhetoric
+5353 rhino
+5354 rhubarb
+5355 rhyme
+5356 ribbon
+5361 riches
+5362 ridden
+5363 rigidness
+5364 rimmed
+5365 riptide
+5366 riskily
+5411 ritzy
+5412 riverboat
+5413 roamer
+5414 robe
+5415 rocket
+5416 romancer
+5421 ropelike
+5422 rotisserie
+5423 roundtable
+5424 royal
+5425 rubber
+5426 rudderless
+5431 rugby
+5432 ruined
+5433 rulebook
+5434 rummage
+5435 running
+5436 rupture
+5441 rustproof
+5442 sabotage
+5443 sacrifice
+5444 saddlebag
+5445 saffron
+5446 sainthood
+5451 saltshaker
+5452 samurai
+5453 sandworm
+5454 sapphire
+5455 sardine
+5456 sassy
+5461 satchel
+5462 sauna
+5463 savage
+5464 saxophone
+5465 scarf
+5466 scenario
+5511 schoolbook
+5512 scientist
+5513 scooter
+5514 scrapbook
+5515 sculpture
+5516 scythe
+5521 secretary
+5522 sedative
+5523 segregator
+5524 seismology
+5525 selected
+5526 semicolon
+5531 senator
+5532 septum
+5533 sequence
+5534 serpent
+5535 sesame
+5536 settler
+5541 severely
+5542 shack
+5543 shelf
+5544 shirt
+5545 shovel
+5546 shrimp
+5551 shuttle
+5552 shyness
+5553 siamese
+5554 sibling
+5555 siesta
+5556 silicon
+5561 simmering
+5562 singles
+5563 sisterhood
+5564 sitcom
+5565 sixfold
+5566 sizable
+5611 skateboard
+5612 skeleton
+5613 skies
+5614 skulk
+5615 skylight
+5616 slapping
+5621 sled
+5622 slingshot
+5623 sloth
+5624 slumbering
+5625 smartphone
+5626 smelliness
+5631 smitten
+5632 smokestack
+5633 smudge
+5634 snapshot
+5635 sneezing
+5636 sniff
+5641 snowsuit
+5642 snugness
+5643 speakers
+5644 sphinx
+5645 spider
+5646 splashing
+5651 sponge
+5652 sprout
+5653 spur
+5654 spyglass
+5655 squirrel
+5656 statue
+5661 steamboat
+5662 stingray
+5663 stopwatch
+5664 strawberry
+5665 student
+5666 stylus
+6111 suave
+6112 subway
+6113 suction
+6114 suds
+6115 suffocate
+6116 sugar
+6121 suitcase
+6122 sulphur
+6123 superstore
+6124 surfer
+6125 sushi
+6126 swan
+6131 sweatshirt
+6132 swimwear
+6133 sword
+6134 sycamore
+6135 syllable
+6136 symphony
+6141 synagogue
+6142 syringes
+6143 systemize
+6144 tablespoon
+6145 taco
+6146 tadpole
+6151 taekwondo
+6152 tagalong
+6153 takeout
+6154 tallness
+6155 tamale
+6156 tanned
+6161 tapestry
+6162 tarantula
+6163 tastebud
+6164 tattoo
+6165 tavern
+6166 thaw
+6211 theater
+6212 thimble
+6213 thorn
+6214 throat
+6215 thumb
+6216 thwarting
+6221 tiara
+6222 tidbit
+6223 tiebreaker
+6224 tiger
+6225 timid
+6226 tinsel
+6231 tiptoeing
+6232 tirade
+6233 tissue
+6234 tractor
+6235 tree
+6236 tripod
+6241 trousers
+6242 trucks
+6243 tryout
+6244 tubeless
+6245 tuesday
+6246 tugboat
+6251 tulip
+6252 tumbleweed
+6253 tupperware
+6254 turtle
+6255 tusk
+6256 tutorial
+6261 tuxedo
+6262 tweezers
+6263 twins
+6264 tyrannical
+6265 ultrasound
+6266 umbrella
+6311 umpire
+6312 unarmored
+6313 unbuttoned
+6314 uncle
+6315 underwear
+6316 unevenness
+6321 unflavored
+6322 ungloved
+6323 unhinge
+6324 unicycle
+6325 unjustly
+6326 unknown
+6331 unlocking
+6332 unmarked
+6333 unnoticed
+6334 unopened
+6335 unpaved
+6336 unquenched
+6341 unroll
+6342 unscrewing
+6343 untied
+6344 unusual
+6345 unveiled
+6346 unwrinkled
+6351 unyielding
+6352 unzip
+6353 upbeat
+6354 upcountry
+6355 update
+6356 upfront
+6361 upgrade
+6362 upholstery
+6363 upkeep
+6364 upload
+6365 uppercut
+6366 upright
+6411 upstairs
+6412 uptown
+6413 upwind
+6414 uranium
+6415 urban
+6416 urchin
+6421 urethane
+6422 urgent
+6423 urologist
+6424 username
+6425 usher
+6426 utensil
+6431 utility
+6432 utmost
+6433 utopia
+6434 utterance
+6435 vacuum
+6436 vagrancy
+6441 valuables
+6442 vanquished
+6443 vaporizer
+6444 varied
+6445 vaseline
+6446 vegetable
+6451 vehicle
+6452 velcro
+6453 vendor
+6454 vertebrae
+6455 vestibule
+6456 veteran
+6461 vexingly
+6462 vicinity
+6463 videogame
+6464 viewfinder
+6465 vigilante
+6466 village
+6511 vinegar
+6512 violin
+6513 viperfish
+6514 virus
+6515 visor
+6516 vitamins
+6521 vivacious
+6522 vixen
+6523 vocalist
+6524 vogue
+6525 voicemail
+6526 volleyball
+6531 voucher
+6532 voyage
+6533 vulnerable
+6534 waffle
+6535 wagon
+6536 wakeup
+6541 walrus
+6542 wanderer
+6543 wasp
+6544 water
+6545 waving
+6546 wheat
+6551 whisper
+6552 wholesaler
+6553 wick
+6554 widow
+6555 wielder
+6556 wifeless
+6561 wikipedia
+6562 wildcat
+6563 windmill
+6564 wipeout
+6565 wired
+6566 wishbone
+6611 wizardry
+6612 wobbliness
+6613 wolverine
+6614 womb
+6615 woolworker
+6616 workbasket
+6621 wound
+6622 wrangle
+6623 wreckage
+6624 wristwatch
+6625 wrongdoing
+6626 xerox
+6631 xylophone
+6632 yacht
+6633 yahoo
+6634 yard
+6635 yearbook
+6636 yesterday
+6641 yiddish
+6642 yield
+6643 yo-yo
+6644 yodel
+6645 yogurt
+6646 yuppie
+6651 zealot
+6652 zebra
+6653 zeppelin
+6654 zestfully
+6655 zigzagged
+6656 zillion
+6661 zipping
+6662 zirconium
+6663 zodiac
+6664 zombie
+6665 zookeeper
+6666 zucchini
+EOF
+)
+
+dice() {
+ tr -cd '1-6'</dev/urandom|fold -w 4|head -n "$1"
+}
+
+for num in $(dice "${1:-8}")
+do
+ echo "$wordlist"|
+ grep "$num"|
+ cut -d' ' -f2|
+ tr '\n' ' '
+done
+
+echo
diff --git a/bin/mullvad b/bin/mullvad
@@ -0,0 +1,31 @@
+#!/bin/sh
+gw="$(route -n show | awk '$1 == "default" { print $2 }')"
+awk -v gw="$gw" '
+$1 == "PrivateKey" { key = $3 }
+$1 == "Address" {
+ addr = $3
+ sub(/,.*/, "", addr)
+}
+$1 == "DNS" { dns = $3 }
+$1 == "PublicKey" { peer = $3 }
+$1 == "AllowedIPs" {
+ aip = $3
+ sub(/,.*/, "", aip)
+}
+$1 == "Endpoint" {
+ endpoint = $3
+ sub(/:/, " ", endpoint)
+}
+END {
+ epip = substr(endpoint, 1, index(endpoint, " ")-1)
+ ifip = substr(addr, 1, index(addr, "/")-1)
+ printf("ifconfig wg0 create wgkey %s wgpeer %s wgendpoint %s wgaip %s\…
+ printf("ifconfig wg0 %s\n", addr)
+ printf("route nameserver wg0 %s\n", dns)
+ printf("route add %s %s\n", epip, gw)
+ printf("route change default %s\n", ifip)
+ printf("curl https://am.i.mullvad.net/connected\n")
+ printf("trap '\''ifconfig wg0 destroy; route delete %s; route add defa…
+ printf("while read -r ch; do [ \"$ch\" = q ] && break; done </dev/tty\…
+}' "$@" | doas /bin/sh -ex
+
diff --git a/bin/music b/bin/music
@@ -3,7 +3,7 @@
DIRECTORY="$HOME/media/music_videos"
directories=$(find "$DIRECTORY" -mindepth 1 -maxdepth 1 -type d -exec basename…
-selected_directory=$(printf "%s\n" "$directories" | bemenu -l 10 -p 'music: ')
+selected_directory=$(printf "%s\n" "$directories" | dmenu -l 10 -p 'music: ')
if [ -n "$selected_directory" ]; then
mpv --autofit=30% --really-quiet --no-terminal "$DIRECTORY/$selected_direc…
fi
diff --git a/bin/pass b/bin/pass
@@ -0,0 +1,279 @@
+#!/bin/sh -e
+#
+# https://romanzolotarev.com/bin/pass
+# copyright 2018 roman zolotarev <[email protected]>
+# copyright 2019-2022 romanzolotarev.com ou <[email protected]>
+#
+# permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# the software is provided "as is" and the author disclaims all warranties
+# with regard to this software including all implied warranties of
+# merchantability and fitness. in no event shall the author be liable for
+# any special, direct, indirect, or consequential damages or any damages
+# whatsoever resulting from loss of use, data or profits, whether in an
+# action of contract, negligence or other tortious action, arising out of
+# or in connection with the use or performance of this software.
+#
+
+fail() { echo "$1"; exit 1; }
+should_exist() { if [ ! -f "$1" ]; then fail "Can't find $1."; fi; }
+should_not_exist() { if [ -f "$1" ]; then fail "$1 already exists."; fi; }
+should_be_dir() { if [ ! -d "$1" ]; then fail "$1 is not a directory."; fi; }
+should_be_defined() { if [ ! "$1" ]; then fail "$2 should be defined."; fi; }
+
+
+keygen() {
+ private_key="$1"
+ public_key="$2"
+ should_be_defined "$private_key" "Private key path"
+ should_be_defined "$public_key" "Public key path"
+ should_not_exist "$private_key"
+ should_be_dir "$(dirname "$private_key")"
+ should_not_exist "$public_key"
+ should_be_dir "$(dirname "$public_key")"
+
+ echo 'Generating public/private key pair.'
+
+ printf 'New pass phrase: '; stty -echo; read -r pass; stty echo; printf '\n'
+ if [ ! "$pass" ]; then fail 'The pass phrase cannot be empty.'; fi
+ printf 'Confirm: '; stty -echo; read -r pass_confirm; stty echo; printf '\n'
+
+ if [ "$pass" = "$pass_confirm" ]; then
+ openssl genrsa 2048 |
+ openssl pkcs8 -topk8 -inform pem -outform pem -out "$private_key" -v2 ae…
+ chmod 0400 "$private_key"
+ openssl rsa -in "$private_key" -out "$public_key" -outform pem -pubout -pa…
+ chmod 0600 "$public_key"
+ else
+ fail 'Pass phrase mismatch.'
+ fi
+}
+
+
+passphrase() {
+ private_key="$1"
+ should_be_defined "$private_key" "Private key path"
+ should_exist "$private_key"
+
+ echo "Changing $private_key pass phrase."
+
+ printf 'Current pass phrase: '; stty -echo; read -r pass; stty echo; printf …
+ printf 'New pass phrase: '; stty -echo; read -r new_pass; stty echo; printf …
+ if [ ! "$new_pass" ]; then fail 'The pass phrase cannot be empty.'; fi
+ printf 'Confirm: '; stty -echo; read -r new_pass_confirm; stty echo; printf …
+
+ if [ "$new_pass" = "$new_pass_confirm" ]; then
+ chmod 0600 "$private_key" &&
+ openssl rsa -aes256 -in "$private_key" -out "$private_key" -passin "pass:$…
+ fail 'Pass phrase change failed.' &&
+ { echo 'Pass phrase changed.'; chmod 0400 "$private_key"; }
+ else
+ fail 'Pass phrase mismatch.'
+ fi
+}
+
+
+encrypt() {
+ public_key="$1"
+ data_file="$2"
+ should_be_defined "$data_file" "Data file path"
+ enc_file="$data_file.enc"
+ key_file="$data_file.key"
+ base_dir="$(dirname "$data_file")"
+ should_be_dir "$base_dir"
+ should_exist "$public_key"
+ should_not_exist "$enc_file"
+ should_not_exist "$key_file"
+
+ key=$(openssl rand -base64 180)
+ cleartext="$(cat)"
+ dir=$(dirname "$data_file"); mkdir -p "$dir"; chmod 0700 "$dir"
+
+ echo "$key" |
+ openssl rsautl -encrypt -pubin -inkey "$public_key" |
+ openssl enc -md md5 -base64 -out "$key_file" >/dev/null 2>&1 ||
+ fail 'Encryption failed.'
+
+ echo "$cleartext" |
+ openssl enc -md md5 -aes-256-cbc -base64 -salt -k "$key" -out "$enc_file"
+
+ cleartext=''
+ key=''
+
+ tar cf "$data_file" -C "$base_dir" "$(basename "$key_file")" "$(basename "$e…
+ rm "$key_file" "$enc_file"
+ chmod 0600 "$data_file"
+}
+
+
+sign() {
+ private_key="$1"
+ data_file="$2"
+ pass="$3"
+ should_be_defined "$data_file" "Data file path"
+ signature="$data_file.sig"
+ base_dir="$(dirname "$data_file")"
+ should_be_dir "$base_dir"
+ should_exist "$private_key"
+ should_exist "$data_file"
+
+ if [ ! "$pass" ]; then
+ if ! openssl dgst -sha256 -sign "$private_key" -out "$signature" "$data_fi…
+ rm "$signature"
+ fail 'Signing failed.'
+ fi
+ else
+ if ! openssl dgst -sha256 -passin "pass:$pass" -sign "$private_key" -out "…
+ rm "$signature"
+ fail 'Signing failed.'
+ fi
+ fi
+
+ chmod 0600 "$signature"
+}
+
+
+decrypt() {
+ private_key="$1"
+ data_file="$2"
+ pass="$3"
+ should_be_defined "$private_key" "Private key path"
+ should_be_defined "$data_file" "Data file path"
+ enc_file="$data_file.enc"
+ key_file="$data_file.key"
+ should_exist "$private_key"
+ should_exist "$data_file"
+
+ base_dir="$(dirname "$data_file")"
+ tar xf "$data_file" -C "$base_dir"
+ if [ ! "$pass" ]; then
+ key=$(openssl enc -d -base64 -in "$key_file"|openssl rsautl -decrypt -inke…
+ else
+ key=$(openssl enc -d -base64 -in "$key_file"|openssl rsautl -passin "pass:…
+ fi
+ openssl enc -md md5 -aes-256-cbc -d -base64 -k "$key" -in "$enc_file" 2>/dev…
+ rm "$key_file" "$enc_file"
+}
+
+verify () {
+ public_key="$1"
+ data_file="$2"
+ signature="$data_file.sig"
+ should_exist "$public_key"
+ should_exist "$data_file"
+ should_exist "$signature"
+
+ if ! openssl dgst -sha256 -verify "$public_key" -signature "$signature" "$da…
+ fail 'Invalid signature.'
+ fi
+}
+
+if [ ! "$PASS_BASE_DIR" ]; then PASS_BASE_DIR="$HOME/.pass"; fi
+if [ ! "$PASS_PRIVATE_KEY" ]; then PASS_PRIVATE_KEY="$PASS_BASE_DIR/.key"; fi
+if [ ! "$PASS_PUBLIC_KEY" ]; then PASS_PUBLIC_KEY="$PASS_BASE_DIR/.key.pub"; fi
+if [ "$2" ]; then ID="$2"; fi
+if [ "$3" ]; then PASS="$3"; fi
+
+
+case "$1" in
+
+passphrase)
+ passphrase "$PASS_PRIVATE_KEY"
+ ;;
+
+
+init)
+ mkdir -p "$(dirname "$PASS_PRIVATE_KEY")"; chmod 0700 "$(dirname "$PASS_PRIV…
+ mkdir -p "$(dirname "$PASS_PUBLIC_KEY")"; chmod 0700 "$(dirname "$PASS_PUBLI…
+ keygen "$PASS_PRIVATE_KEY" "$PASS_PUBLIC_KEY"
+ ;;
+
+add)
+ should_be_defined "$ID" "id"
+ should_not_exist "$PASS_BASE_DIR/$ID"
+ printf 'Pass phrase: '; stty -echo; read -r pass; stty echo; printf '\n'
+ if [ ! "$pass" ]; then fail 'The pass phrase cannot be empty.'; fi
+ openssl rand -base64 10 |
+ openssl dgst -sha256 -passin "pass:$pass" -sign "$PASS_PRIVATE_KEY" >/dev/…
+ fail 'Invalid pass phrase.'
+ echo 'Press Enter and CTRL-D to complete.'
+ encrypt "$PASS_PUBLIC_KEY" "$PASS_BASE_DIR/$ID"
+ sign "$PASS_PRIVATE_KEY" "$PASS_BASE_DIR/$ID" "$pass"
+ ;;
+
+import)
+ should_be_defined "$ID" "id"
+ should_not_exist "$PASS_BASE_DIR/$ID"
+ encrypt "$PASS_PUBLIC_KEY" "$PASS_BASE_DIR/$ID"
+ sign "$PASS_PRIVATE_KEY" "$PASS_BASE_DIR/$ID" "$PASS"
+ ;;
+
+show)
+ should_be_defined "$ID" "id"
+ verify "$PASS_PUBLIC_KEY" "$PASS_BASE_DIR/$ID"
+ cleartext="$(decrypt "$PASS_PRIVATE_KEY" "$PASS_BASE_DIR/$ID")"
+ echo "$cleartext"|head -n1
+ totp_seed="$(echo "$cleartext"|grep 'totp: '|head -n1|cut -d' ' -f2)"
+ if [ "$totp_seed" ]; then
+ if oathtool --version >/dev/null 2>&1; then
+ oathtool --totp -b "$totp_seed"
+ else
+ echo 'oathtool(1) should be installed'
+ fi
+ fi
+ ;;
+
+export)
+ should_be_defined "$ID" "id"
+ verify "$PASS_PUBLIC_KEY" "$PASS_BASE_DIR/$ID"
+ decrypt "$PASS_PRIVATE_KEY" "$PASS_BASE_DIR/$ID" "$PASS"
+ ;;
+
+ls)
+ cd "$PASS_BASE_DIR"
+ find . \( -type f \
+ -name "${ID}"\* \
+ \! -name \*.enc \
+ \! -name \*.key \
+ \! -name \*.sig \
+ \! -name \.key \
+ \! -name \.key.pub \
+ \! -path \*/.git/\* \) | cut -f2 -d'/' | sort
+ ;;
+
+edit)
+ should_be_defined "$ID" "id"
+ # verify "$PASS_PUBLIC_KEY" "$PASS_BASE_DIR/$ID"
+ cleartext_file="$PASS_BASE_DIR/$ID.cleartext"
+ cleartext=$(decrypt "$PASS_PRIVATE_KEY" "$PASS_BASE_DIR/$ID")
+ touch "$cleartext_file"; chmod 0600 "$cleartext_file"
+ echo "$cleartext" > "$cleartext_file"
+ ${EDITOR:-$(which vi)} "$cleartext_file"
+ after=$(cat "$cleartext_file")
+ rm "$cleartext_file"
+ if [ "$(echo "$cleartext"|openssl dgst -r -sha256)" = "$(echo "$after"|opens…
+ echo "No changes in $ID"
+ else
+ echo "$after"|encrypt "$PASS_PUBLIC_KEY" "$PASS_BASE_DIR/$ID"
+ sign "$PASS_PRIVATE_KEY" "$PASS_BASE_DIR/$ID"
+ fi
+ ;;
+
+*)
+ echo 'usage: export PASS_BASE_DIR=~/.pass'
+ echo ' export PASS_PRIVATE_KEY=~/.pass/.key'
+ echo ' export PASS_PUBLIC_KEY=~/.pass/.key.pub'
+ echo
+ echo ' pass init'
+ echo ' | passphrase'
+ echo ' | add id'
+ echo ' | import id <pass>'
+ echo ' | show id'
+ echo ' | export id <pass>'
+ echo ' | ls <id>'
+ exit 1
+ ;;
+
+esac
diff --git a/bin/sway-start b/bin/sway-start
@@ -1,22 +0,0 @@
-#!/bin/sh
-export TERM=foot
-export _JAVA_AWT_WM_NONREPARENTING=1
-export XKB_DEFAULT_OPTIONS=caps:escape
-export GDK_BACKEND=wayland
-export XDG_SESSION_TYPE=wayland
-#export XCURSOR_THEME=Adwaita
-export XDG_DESKTOP_DIR="$HOME"
-export XDG_DOWNLOAD_DIR="$HOME/tmp"
-export XDG_DOCUMENTS_DIR="$HOME/tmp"
-export XDG_MUSIC_DIR="$HOME/tmp"
-export XDG_PICTURES_DIR="$HOME/tmp"
-export XDG_VIDEOS_DIR="$HOME/tmp"
-export XDG_CURRENT_DESKTOP=sway
-
-if [ -z "$XDG_RUNTIME_DIR" ]; then
- mkdir -p /tmp/runtime/jay
- chmod 700 /tmp/runtime/jay
- export XDG_RUNTIME_DIR=/tmp/runtime/jay
-fi
-
-exec dbus-run-session sway
diff --git a/bootstrap.sh b/bootstrap.sh
@@ -2,9 +2,9 @@
DOTFILES=$(pwd)
-FILES='ashrc profile'
+FILES='kshrc profile Xdefaults Xresources'
ROOT='bin'
-CONFIG='foot git lynx mutt newsraft nvim qutebrowser sway waybar'
+CONFIG='git lynx mpd mutt ncmpcpp newsraft nvim'
link() {
for f in $FILES; do ln -sfn "$DOTFILES/$f" "$HOME/.$f"; done
diff --git a/foot/foot.ini b/foot/foot.ini
@@ -1,27 +0,0 @@
-font=Hack:size=14
-
-[url]
-launch=link-handler ${url}
-
-[key-bindings]
-show-urls-launch=Control+Shift+p
-
-[colors]
-background=282828
-foreground=ebdbb2
-regular0=282828
-regular1=cc241d
-regular2=98971a
-regular3=d79921
-regular4=458588
-regular5=b16286
-regular6=689d6a
-regular7=a89984
-bright0=928374
-bright1=fb4934
-bright2=b8bb26
-bright3=fabd2f
-bright4=83a598
-bright5=d3869b
-bright6=8ec07c
-bright7=ebdbb2
diff --git a/kshrc b/kshrc
@@ -0,0 +1,63 @@
+export XDG_CONFIG_HOME="$HOME/.config"
+export XDG_CACHE_HOME="$HOME/.cache"
+export XDG_DATA_HOME="$HOME/.local/share"
+export XDG_STATE_HOME="$HOME/.local/state"
+
+# cleanup ~/
+export CARGO_HOME="$XDG_DATA_HOME"/cargo
+
+# common exports
+GPG_TTY=$(tty)
+export GPG_TTY
+export EDITOR="nvim"
+export BROWSER="firefox"
+export PATH=$PATH:$HOME/bin
+
+# tools
+export OPENER=~/bin/link-handler
+
+# pass
+export PASS_BASE_DIR=~/src/pass
+export PASS_PRIVATE_KEY=~/src/pass/.key
+export PASS_PUBLIC_KEY=~/src/pass/.key.pub
+
+# lynx
+export LYNX_CFG=$HOME/.config/lynx/config
+export LYNX_LSS=$HOME/.config/lynx/theme.lss
+
+# safety first kids!
+alias cp='cp -i'
+alias mv='mv -i'
+alias rm='rm -i'
+
+# random alias
+alias weather='curl wttr.in/?1QF'
+
+# git alias
+alias ga='git add -A'
+alias gs='git status -s'
+alias gl="git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset…
+alias gd='git diff'
+alias gma='git commit -am'
+
+# neo
+alias vim='nvim'
+alias mutt='neomutt'
+alias mpv="mpv --autofit=30% --really-quiet --no-terminal"
+alias w="w3m -B"
+
+# vpn
+alias von='mullvad ~/.config/mullvad/se-mma-wg-111.conf'
+alias vcheck='curl https://am.i.mullvad.net/connected'
+
+# ksh
+export LANG=en_US.UTF-8
+export LC_CTYPE="en_US.UTF-8"
+export LC_ALL=en_US.UTF-8
+export PS1="\[\e[00;34m\]▶▶▶ \W \[\e[0m\]"
+export HISTFILE=/home/jay/.cache/sh_history
+export HISTSIZE=1000
+
+alias ls='colorls -G'
+set -o emacs
+
diff --git a/mpd/mpd.conf b/mpd/mpd.conf
@@ -0,0 +1,20 @@
+music_directory "/home/jay/media/music"
+playlist_directory "/home/jay/.config/mpd/playlists"
+db_file "/home/jay/.config/mpd/mpd.db"
+log_file "syslog"
+pid_file "/home/jay/.config/mpd/mpd.pid"
+state_file "/home/jay/.config/mpd/mpdstate"
+
+audio_output {
+ type "pulse"
+ name "pulse audio"
+}
+audio_output {
+ type "fifo"
+ name "my_fifo"
+ path "/tmp/mpd.fifo"
+ format "44100:16:2"
+}
+
+bind_to_address "127.0.0.1"
+port "6600"
diff --git a/ncmpcpp/config b/ncmpcpp/config
@@ -0,0 +1,31 @@
+# visual stuff for 8
+visualizer_data_source = /tmp/mpd.fifo
+visualizer_output_name = my_fifo
+visualizer_in_stereo = no
+#visualizer_type = spectrum
+visualizer_look = ∙▋
+visualizer_color = 7,5,8,3
+song_columns_list_format = "(50)[green]{a} (50)[white]{t|f}"
+
+playlist_display_mode = columns
+browser_display_mode = columns
+
+ncmpcpp_directory = ~/.config/ncmpcpp
+lyrics_directory = /tmp
+store_lyrics_in_song_dir = yes
+autocenter_mode = "yes"
+centered_cursor = "yes"
+cyclic_scrolling = "no"
+
+titles_visibility = "no"
+header_visibility = "no"
+statusbar_visibility = "no"
+progressbar_look = "❙❙❙"
+progressbar_color = "white"
+
+user_interface = "classic"
+
+startup_screen = playlist
+#startup_slave_screen = visualizer
+'startup_slave_screen_focus = no
+locked_screen_width_part = 35
diff --git a/profile b/profile
@@ -1,2 +1,2 @@
-export ENV=$HOME/.ashrc
+export ENV=$HOME/.kshrc
. $ENV
diff --git a/qutebrowser/blank.html b/qutebrowser/blank.html
@@ -1,44 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-
- <head>
- <style>
- body {
- color: #cfba58;
- background-color: #191919;
- font-family: monospace;
- }
-
- .flex {
- flex-direction: column;
- display: flex;
- justify-content: center;
- align-items: center;
- margin-top: 450px;
- }
-
- input {
- border: none;
- border-bottom: 2px solid #959A1C;
- min-width: 500px;
- max-width: 750px;
- width: 75%;
- padding-bottom: 10px;
- background-color: transparent;
- color: #fff;
- outline: 0;
- margin-bottom: 20px;
- font-size: 22px;
- }
- </style>
- </head>
-
- <body>
- <div class="flex">
- <form action="https://html.duckduckgo.com/html" method="get" target="_se…
- <input type="text" name="q" autofocus="autofocus" onfocus="this.select…
- </form>
- </div>
- </body>
-
-</html>
diff --git a/qutebrowser/config.py b/qutebrowser/config.py
@@ -1,92 +0,0 @@
-config.load_autoconfig(False)
-
-try:
- from qutebrowser.api import message
-
- # gruvbox colour theme
- config.source('scripts/gruvbox.py')
- #config.source('scripts/redirects.py')
-
-except ImportError:
- pass
-
-# default local page
-DEFAULT_PAGE = str(config.configdir / 'blank.html')
-
-# keybinds remapping
-config.bind("xx", "set tabs.show always;; later 5000 set tabs.show switching")
-config.bind("xc", "spawn --userscript password_fill")
-config.bind("zd", "download-open")
-config.bind("xz", "hint links spawn --detach ~/bin/link-handler {hint-url}")
-config.bind("j", "cmd-run-with-count 5 scroll down")
-config.bind("k", "cmd-run-with-count 5 scroll up")
-
-# tabbar
-c.tabs.position = "top"
-c.tabs.show = "multiple"
-c.tabs.title.format = ""
-c.tabs.width = 28
-c.tabs.favicons.show = "never"
-
-# hints
-c.colors.hints.bg = "rgb(207,186,88)" #cfba58
-c.colors.hints.fg = "rgb(34, 34, 34)" #222222
-c.colors.webpage.darkmode.enabled = False
-c.colors.webpage.darkmode.algorithm = "lightness-hsl"
-
-# misc
-c.fonts.hints = "10pt Hack"
-c.fonts.default_size = '12pt'
-c.fonts.default_family = 'Hack'
-c.hints.uppercase = True
-c.scrolling.smooth = True
-c.editor.command = ["alacritty", "vim '{}'"]
-c.auto_save.session = True
-
-# ad-block
-c.content.blocking.enabled = True
-c.content.blocking.method = "both"
-c.content.blocking.adblock.lists = [
- "https://easylist.to/easylist/easyprivacy.txt",
- "https://secure.fanboy.co.nz/fanboy-cookiemonster.txt",
- "https://easylist.to/easylist/easylist.txt"
- ]
-
-# general privacy
-c.completion.web_history.max_items = 0 # no history
-c.downloads.remove_finished = 800 # clear dl history
-c.downloads.location.directory = '~/tmp'
-c.url.default_page = DEFAULT_PAGE
-c.url.start_pages = DEFAULT_PAGE
-c.content.private_browsing = True # always use private browsing
-c.content.register_protocol_handler = False
-c.content.webgl = False
-
-# normally default, lets make sure
-c.content.media.audio_capture = False
-c.content.media.audio_video_capture = False
-c.content.media.video_capture = False
-c.content.desktop_capture = False
-c.content.mouse_lock = False
-c.content.autoplay = False # no autoplay on <video> tags
-
-# fingerprint
-c.content.headers.accept_language = "en-US,en;q=0.5"
-c.content.headers.user_agent = "Mozilla/5.0 (X11; Linux i686; rv:109.0) Gecko/…
-c.content.headers.custom = {"accept": "text/html,application/xhtml+xml,applica…
-c.content.headers.referer = "same-domain"
-c.content.cookies.accept = "no-3rdparty"
-c.content.javascript.enabled = False # disable tracking etc
-c.content.canvas_reading = False # canvas blocking
-c.content.geolocation = False # location ident
-c.content.webrtc_ip_handling_policy = "disable-non-proxied-udp"
-c.content.hyperlink_auditing = False # disable pingbacks
-c.content.dns_prefetch = False # disable pre-fetching
-
-# search engine shortneners
-c.url.searchengines = {
- "DEFAULT": "https://html.duckduckgo.com/html?q={}",
- "ru": "https://rutracker.org/forum/tracker.php?f=1992&nm={}",
- "wiby": "https://wiby.me/?q={}",
- "book": "http://libgen.rs/search.php?req={}&lg_topic=libgen&open=0&view=si…
-}
diff --git a/qutebrowser/scripts/fingerprint.py b/qutebrowser/scripts/fingerpri…
@@ -1,43 +0,0 @@
-import random
-import json
-import datetime
-
-from pathlib import Path
-from qutebrowser.api import message, interceptor
-
-home = str(config.configdir)
-agentfile = Path("{}/useragent_list.json".format(home))
-
-fp_timer = datetime.datetime.now() + datetime.timedelta(minutes=1)
-
-if agentfile.is_file():
- with open(agentfile, "r") as filehandle:
- agentList = json.load(filehandle)
-
-
-def fingerprint_getheader(agent):
-
- FP_HTTP_HEADER = {
- "Firefox": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;…
- "Chrome": "text/html,application/xhtml+xml,application/xml;q=0.9,image…
- "Edge": "text/html, application/xhtml+xml, image/jxr, */*",
- "Opera": "text/html, application/xml;q=0.9, application/xhtml+xml, ima…
- "Safari": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q…
- }
-
- for a, h in FP_HTTP_HEADER.items():
- if "{a}" in agent:
- return h
-
-
-def fingerprint(info: interceptor.Request):
- global fp_timer
-
- if fp_timer < datetime.datetime.now():
- fp_timer = datetime.datetime.now() + datetime.timedelta(minutes=1)
- agent = random.choice(tuple(agentList))
- c.content.headers.user_agent = agent
- c.content.headers.custom = {"accept": fingerprint_getheader(agent)}
-
-
-interceptor.register(fingerprint)
diff --git a/qutebrowser/scripts/gruvbox.py b/qutebrowser/scripts/gruvbox.py
@@ -1,332 +0,0 @@
-# gruvbox dark hard qutebrowser theme by Florian Bruhin <[email protected]>
-#
-# Originally based on:
-# base16-qutebrowser (https://github.com/theova/base16-qutebrowser)
-# Base16 qutebrowser template by theova and Daniel Mulford
-# Gruvbox dark, hard scheme by Dawid Kurek ([email protected]), morhetz (htt…
-
-bg0_hard = "#1d2021"
-bg0_soft = '#32302f'
-bg0_normal = '#282828'
-
-bg0 = bg0_normal
-bg1 = "#3c3836"
-bg2 = "#504945"
-bg3 = "#665c54"
-bg4 = "#7c6f64"
-
-fg0 = "#fbf1c7"
-fg1 = "#ebdbb2"
-fg2 = "#d5c4a1"
-fg3 = "#bdae93"
-fg4 = "#a89984"
-
-bright_red = "#fb4934"
-bright_green = "#b8bb26"
-bright_yellow = "#fabd2f"
-bright_blue = "#83a598"
-bright_purple = "#d3869b"
-bright_aqua = "#8ec07c"
-bright_gray = "#928374"
-bright_orange = "#fe8019"
-
-dark_red = "#cc241d"
-dark_green = "#98971a"
-dark_yellow = "#d79921"
-dark_blue = "#458588"
-dark_purple = "#b16286"
-dark_aqua = "#689d6a"
-dark_gray = "#a89984"
-dark_orange = "#d65d0e"
-
-### Completion
-
-# Text color of the completion widget. May be a single color to use for
-# all columns or a list of three colors, one for each column.
-c.colors.completion.fg = [fg1, bright_aqua, bright_yellow]
-
-# Background color of the completion widget for odd rows.
-c.colors.completion.odd.bg = bg0
-
-# Background color of the completion widget for even rows.
-c.colors.completion.even.bg = c.colors.completion.odd.bg
-
-# Foreground color of completion widget category headers.
-c.colors.completion.category.fg = bright_blue
-
-# Background color of the completion widget category headers.
-c.colors.completion.category.bg = bg1
-
-# Top border color of the completion widget category headers.
-c.colors.completion.category.border.top = c.colors.completion.category.bg
-
-# Bottom border color of the completion widget category headers.
-c.colors.completion.category.border.bottom = c.colors.completion.category.bg
-
-# Foreground color of the selected completion item.
-c.colors.completion.item.selected.fg = fg0
-
-# Background color of the selected completion item.
-c.colors.completion.item.selected.bg = bg4
-
-# Top border color of the selected completion item.
-c.colors.completion.item.selected.border.top = bg2
-
-# Bottom border color of the selected completion item.
-c.colors.completion.item.selected.border.bottom = c.colors.completion.item.sel…
-
-# Foreground color of the matched text in the selected completion item.
-c.colors.completion.item.selected.match.fg = bright_orange
-
-# Foreground color of the matched text in the completion.
-c.colors.completion.match.fg = c.colors.completion.item.selected.match.fg
-
-# Color of the scrollbar handle in the completion view.
-c.colors.completion.scrollbar.fg = c.colors.completion.item.selected.fg
-
-# Color of the scrollbar in the completion view.
-c.colors.completion.scrollbar.bg = c.colors.completion.category.bg
-
-### Context menu
-
-# Background color of disabled items in the context menu.
-c.colors.contextmenu.disabled.bg = bg3
-
-# Foreground color of disabled items in the context menu.
-c.colors.contextmenu.disabled.fg = fg3
-
-# Background color of the context menu. If set to null, the Qt default is used.
-c.colors.contextmenu.menu.bg = bg0
-
-# Foreground color of the context menu. If set to null, the Qt default is used.
-c.colors.contextmenu.menu.fg = fg2
-
-# Background color of the context menu’s selected item. If set to null, the …
-c.colors.contextmenu.selected.bg = bg2
-
-#Foreground color of the context menu’s selected item. If set to null, the Q…
-c.colors.contextmenu.selected.fg = c.colors.contextmenu.menu.fg
-
-### Downloads
-
-# Background color for the download bar.
-c.colors.downloads.bar.bg = bg0
-
-# Color gradient start for download text.
-c.colors.downloads.start.fg = bg0
-
-# Color gradient start for download backgrounds.
-c.colors.downloads.start.bg = bright_blue
-
-# Color gradient end for download text.
-c.colors.downloads.stop.fg = c.colors.downloads.start.fg
-
-# Color gradient stop for download backgrounds.
-c.colors.downloads.stop.bg = bright_aqua
-
-# Foreground color for downloads with errors.
-c.colors.downloads.error.fg = bright_red
-
-### Hints
-
-# Font color for hints.
-c.colors.hints.fg = bg0
-
-# Background color for hints.
-c.colors.hints.bg = 'rgba(250, 191, 47, 200)' # bright_yellow
-
-# Font color for the matched part of hints.
-c.colors.hints.match.fg = bg4
-
-### Keyhint widget
-
-# Text color for the keyhint widget.
-c.colors.keyhint.fg = fg4
-
-# Highlight color for keys to complete the current keychain.
-c.colors.keyhint.suffix.fg = fg0
-
-# Background color of the keyhint widget.
-c.colors.keyhint.bg = bg0
-
-### Messages
-
-# Foreground color of an error message.
-c.colors.messages.error.fg = bg0
-
-# Background color of an error message.
-c.colors.messages.error.bg = bright_red
-
-# Border color of an error message.
-c.colors.messages.error.border = c.colors.messages.error.bg
-
-# Foreground color of a warning message.
-c.colors.messages.warning.fg = bg0
-
-# Background color of a warning message.
-c.colors.messages.warning.bg = bright_purple
-
-# Border color of a warning message.
-c.colors.messages.warning.border = c.colors.messages.warning.bg
-
-# Foreground color of an info message.
-c.colors.messages.info.fg = fg2
-
-# Background color of an info message.
-c.colors.messages.info.bg = bg0
-
-# Border color of an info message.
-c.colors.messages.info.border = c.colors.messages.info.bg
-
-### Prompts
-
-# Foreground color for prompts.
-c.colors.prompts.fg = fg2
-
-# Border used around UI elements in prompts.
-c.colors.prompts.border = f'1px solid {bg1}'
-
-# Background color for prompts.
-c.colors.prompts.bg = bg3
-
-# Background color for the selected item in filename prompts.
-c.colors.prompts.selected.bg = bg2
-
-### Statusbar
-
-# Foreground color of the statusbar.
-c.colors.statusbar.normal.fg = fg2
-
-# Background color of the statusbar.
-c.colors.statusbar.normal.bg = bg0
-
-# Foreground color of the statusbar in insert mode.
-c.colors.statusbar.insert.fg = bg0
-
-# Background color of the statusbar in insert mode.
-c.colors.statusbar.insert.bg = dark_aqua
-
-# Foreground color of the statusbar in passthrough mode.
-c.colors.statusbar.passthrough.fg = bg0
-
-# Background color of the statusbar in passthrough mode.
-c.colors.statusbar.passthrough.bg = dark_blue
-
-# Foreground color of the statusbar in private browsing mode.
-c.colors.statusbar.private.fg = bright_purple
-
-# Background color of the statusbar in private browsing mode.
-c.colors.statusbar.private.bg = bg0
-
-# Foreground color of the statusbar in command mode.
-c.colors.statusbar.command.fg = fg3
-
-# Background color of the statusbar in command mode.
-c.colors.statusbar.command.bg = bg1
-
-# Foreground color of the statusbar in private browsing + command mode.
-c.colors.statusbar.command.private.fg = c.colors.statusbar.private.fg
-
-# Background color of the statusbar in private browsing + command mode.
-c.colors.statusbar.command.private.bg = c.colors.statusbar.command.bg
-
-# Foreground color of the statusbar in caret mode.
-c.colors.statusbar.caret.fg = bg0
-
-# Background color of the statusbar in caret mode.
-c.colors.statusbar.caret.bg = dark_purple
-
-# Foreground color of the statusbar in caret mode with a selection.
-c.colors.statusbar.caret.selection.fg = c.colors.statusbar.caret.fg
-
-# Background color of the statusbar in caret mode with a selection.
-c.colors.statusbar.caret.selection.bg = bright_purple
-
-# Background color of the progress bar.
-c.colors.statusbar.progress.bg = bright_blue
-
-# Default foreground color of the URL in the statusbar.
-c.colors.statusbar.url.fg = fg4
-
-# Foreground color of the URL in the statusbar on error.
-c.colors.statusbar.url.error.fg = dark_red
-
-# Foreground color of the URL in the statusbar for hovered links.
-c.colors.statusbar.url.hover.fg = bright_orange
-
-# Foreground color of the URL in the statusbar on successful load
-# (http).
-c.colors.statusbar.url.success.http.fg = bright_red
-
-# Foreground color of the URL in the statusbar on successful load
-# (https).
-c.colors.statusbar.url.success.https.fg = fg0
-
-# Foreground color of the URL in the statusbar when there's a warning.
-c.colors.statusbar.url.warn.fg = bright_purple
-
-### tabs
-
-# Background color of the tab bar.
-c.colors.tabs.bar.bg = bg0
-
-# Color gradient start for the tab indicator.
-c.colors.tabs.indicator.start = bright_blue
-
-# Color gradient end for the tab indicator.
-c.colors.tabs.indicator.stop = bright_aqua
-
-# Color for the tab indicator on errors.
-c.colors.tabs.indicator.error = bright_red
-
-# Foreground color of unselected odd tabs.
-c.colors.tabs.odd.fg = fg2
-
-# Background color of unselected odd tabs.
-c.colors.tabs.odd.bg = bg2
-
-# Foreground color of unselected even tabs.
-c.colors.tabs.even.fg = c.colors.tabs.odd.fg
-
-# Background color of unselected even tabs.
-c.colors.tabs.even.bg = bg3
-
-# Foreground color of selected odd tabs.
-c.colors.tabs.selected.odd.fg = fg2
-
-# Background color of selected odd tabs.
-c.colors.tabs.selected.odd.bg = bg0
-
-# Foreground color of selected even tabs.
-c.colors.tabs.selected.even.fg = c.colors.tabs.selected.odd.fg
-
-# Background color of selected even tabs.
-c.colors.tabs.selected.even.bg = bg0
-
-# Background color of pinned unselected even tabs.
-c.colors.tabs.pinned.even.bg = bright_green
-
-# Foreground color of pinned unselected even tabs.
-c.colors.tabs.pinned.even.fg = bg2
-
-# Background color of pinned unselected odd tabs.
-c.colors.tabs.pinned.odd.bg = bright_green
-
-# Foreground color of pinned unselected odd tabs.
-c.colors.tabs.pinned.odd.fg = c.colors.tabs.pinned.even.fg
-
-# Background color of pinned selected even tabs.
-c.colors.tabs.pinned.selected.even.bg = bg0
-
-# Foreground color of pinned selected even tabs.
-c.colors.tabs.pinned.selected.even.fg = c.colors.tabs.selected.odd.fg
-
-# Background color of pinned selected odd tabs.
-c.colors.tabs.pinned.selected.odd.bg = c.colors.tabs.pinned.selected.even.bg
-
-# Foreground color of pinned selected odd tabs.
-c.colors.tabs.pinned.selected.odd.fg = c.colors.tabs.selected.odd.fg
-
-# Background color for webpages if unset (or empty to use the theme's
-# color).
-# c.colors.webpage.bg = bg4
diff --git a/qutebrowser/scripts/redirects.py b/qutebrowser/scripts/redirects.py
@@ -1,70 +0,0 @@
-from qutebrowser.api import interceptor
-from urllib.parse import urljoin
-from PyQt6.QtCore import QUrl
-import operator
-
-o = operator.methodcaller
-s = 'setHost'
-i = interceptor
-
-def farside(url: QUrl, i) -> bool:
- url.setHost('farside.link')
- p = url.path().strip('/')
- url.setPath(urljoin(i, p))
- return True
-
-def nitter(url: QUrl) -> bool:
- return farside(url, '/nitter/')
-def rimgo(url: QUrl) -> bool:
- return farside(url, '/rimgo/')
-def scribe(url: QUrl) -> bool:
- return farside(url, '/scribe/')
-def wikiless(url: QUrl) -> bool:
- return farside(url, '/wikiless/')
-def invid(url: QUrl) -> bool:
- return farside(url, '/invidious/')
-def reddit(url: QUrl) -> bool:
- return farside(url, '/libreddit/')
-def bibliogram(url: QUrl) -> bool:
- return farside(url, '/bibliogram/')
-def simplytranslate(url: QUrl) -> bool:
- return farside(url, '/simplytranslate/')
-def proxitok(url: QUrl) -> bool:
- return farside(url, '/proxitok/')
-def querte (url: QUrl) -> bool:
- return farside(url, '/querte/')
-
-map = {
- "reddit.com": reddit,
- "www.reddit.com": reddit,
- "old.reddit.com": reddit,
-
- "youtu.be": invid,
- "youtube.com": invid,
- "www.youtube.com": invid,
-
- "twitter.com": nitter,
- "mobile.twitter.com": nitter,
-
- "imgur.com" : rimgo,
- "medium.com" : scribe,
- "en.wikipedia.org" : wikiless,
- "www.instagram.com": bibliogram,
- "translate.google.com" : simplytranslate,
- "vm.tiktok.com" : proxitok,
- "www.tiktok.com" : proxitok,
- "www.quora.com": querte,
-
- "www.twitch.tv" : o(s, 'm.twitch.tv'),
- "tumblr.com" : o(s, 'splashblr.fly.dev'),
- "www.npr.org" : o(s, 'text.npr.org'),
- }
-def f(info: i.Request):
- if (info.resource_type != i.ResourceType.main_frame or
- info.request_url.scheme() in {"data", "blob"}):
- return
- url = info.request_url
- redir = map.get(url.host())
- if redir is not None and redir(url) is not False:
- info.redirect(url)
-i.register(f)
diff --git a/qutebrowser/scripts/user_agent.py b/qutebrowser/scripts/user_agent…
@@ -1,31 +0,0 @@
-# qutebrowser script to set a random user-agent on launch. Add the following to
-# your qutebrowser config.py file:
-#
-# config.source('scripts/user_agent.py')
-#
-# You can download the most common user-agents with a script like this, I run
-# mine on cron every 3 days. :
-#
-# #!/bin/bash
-#
-# url='https://raw.githubusercontent.com/Kikobeats/top-user-agents/master/inde…
-# path="$HOME/.config/qutebrowser/useragent_list.json"
-#
-# curl "$url" -o "$path"
-# awk '!/Firefox/' "$path" > /tmp/1 && mv /tmp/1 "$path"
-
-import random
-import json
-
-from pathlib import Path
-from qutebrowser.api import message
-
-home = str(config.configdir)
-agentfile = Path("{}/useragent_list.json".format(home))
-
-if agentfile.is_file():
- with open(agentfile, "r") as filehandle:
- agentList = json.load(filehandle)
-
- agent = random.choice(tuple(agentList))
- c.content.headers.user_agent = agent
diff --git a/suckless/dmenu/Makefile b/suckless/dmenu/Makefile
@@ -0,0 +1,39 @@
+REPOSITORY = http://git.suckless.org/dmenu
+SRC_DIR = src
+PINNED_REVISION = HEAD
+PATCH_DIR = patches
+
+all: $(SRC_DIR)
+
+clean: reset
+ @if test -d $(SRC_DIR); then \
+ $(MAKE) -C "${SRC_DIR}" -s clean; \
+ git -C "${SRC_DIR}" clean -f; \
+ fi
+
+$(SRC_DIR): clone reset patch
+ @cp config.h $@
+ $(MAKE) -C "${SRC_DIR}" -s
+
+patch: $(PATCH_DIR)/*
+ @for file in $^ ; do \
+ patch -d "${SRC_DIR}" < $${file}; \
+ done
+reset:
+ @if [ -n "$(strip $(PINNED_REVISION))" ]; then \
+ git -C "${SRC_DIR}" reset --hard $(PINNED_REVISION); \
+ fi
+
+clone:
+ @if ! test -d $(SRC_DIR); then \
+ git clone $(REPOSITORY) $(SRC_DIR); \
+ fi
+
+update: clean
+ @git -C "${SRC_DIR}" pull
+
+install:
+ $(MAKE) -C "${SRC_DIR}" -s install
+
+
+.PHONY: all clean update install reset clone
diff --git a/suckless/dmenu/config.h b/suckless/dmenu/config.h
@@ -0,0 +1,16 @@
+static int topbar = 1;
+static const char *fonts[] = {
+ "Hack:pixelsize=14"
+};
+static int centered = 1;
+static const char *prompt = "run »";
+static const char *colors[SchemeLast][2] = {
+ [SchemeNorm] = { "#ebdbb2", "#282828" },
+ [SchemeSel] = { "#ebdbb2", "#98971a" },
+ [SchemeOut] = { "#ebdbb2", "#8ec07c" },
+};
+
+static unsigned int lines = 0;
+static const char worddelimiters[] = " ";
+static int min_width = 800;
+static unsigned int border_width = 3;
diff --git a/suckless/dmenu/patches/01-dmenu-border-4.9.diff b/suckless/dmenu/p…
@@ -0,0 +1,36 @@
+diff --git a/config.def.h b/config.def.h
+index 1edb647..dd3eb31 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -21,3 +21,6 @@ static unsigned int lines = 0;
+ * for example: " /?\"&[]"
+ */
+ static const char worddelimiters[] = " ";
++
++/* Size of the window border */
++static unsigned int border_width = 0;
+diff --git a/dmenu.c b/dmenu.c
+index 27b7a30..7c130fc 100644
+--- a/dmenu.c
++++ b/dmenu.c
+@@ -684,9 +684,11 @@ setup(void)
+ swa.override_redirect = True;
+ swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
+ swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
+- win = XCreateWindow(dpy, root, x, y, mw, mh, 0,
++ win = XCreateWindow(dpy, root, x, y, mw, mh, border_width,
+ CopyFromParent, CopyFromParent, CopyFromParent,
+ CWOverrideRedirect | CWBackPixel | CWEventMask, &…
++ if (border_width)
++ XSetWindowBorder(dpy, win, scheme[SchemeSel][ColBg].pixel);
+ XSetClassHint(dpy, win, &ch);
+
+
+@@ -757,6 +759,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], "-bw"))
++ border_width = atoi(argv[++i]); /* border width */
+ else
+ usage();
diff --git a/suckless/dmenu/patches/02-dmenu-center-20200111-8cd37e1.diff b/suc…
@@ -0,0 +1,120 @@
+From 8cd37e1ab9e7cb025224aeb3543f1a5be8bceb93 Mon Sep 17 00:00:00 2001
+From: Nihal Jere <[email protected]>
+Date: Sat, 11 Jan 2020 21:16:08 -0600
+Subject: [PATCH] center patch now has adjustable minimum width
+
+---
+ config.def.h | 2 ++
+ dmenu.1 | 3 +++
+ dmenu.c | 39 ++++++++++++++++++++++++++++++++-------
+ 3 files changed, 37 insertions(+), 7 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 1edb647..88ef264 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -2,6 +2,8 @@
+ /* Default settings; can be overriden by command line. */
+
+ static int topbar = 1; /* -b option; if 0, dmenu appear…
++static int centered = 0; /* -c option; centers dmenu on sc…
++static int min_width = 500; /* minimum width when centered…
+ /* -fn option overrides fonts[0]; default X11 font or font set */
+ static const char *fonts[] = {
+ "monospace:size=10"
+diff --git a/dmenu.1 b/dmenu.1
+index 323f93c..c036baa 100644
+--- a/dmenu.1
++++ b/dmenu.1
+@@ -40,6 +40,9 @@ which lists programs in the user's $PATH and runs the result…
+ .B \-b
+ dmenu appears at the bottom of the screen.
+ .TP
++.B \-c
++dmenu appears centered on 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.
+diff --git a/dmenu.c b/dmenu.c
+index 65f25ce..041c7f8 100644
+--- a/dmenu.c
++++ b/dmenu.c
+@@ -89,6 +89,15 @@ calcoffsets(void)
+ break;
+ }
+
++static int
++max_textw(void)
++{
++ int len = 0;
++ for (struct item *item = items; item && item->text; item++)
++ len = MAX(TEXTW(item->text), len);
++ return len;
++}
++
+ static void
+ cleanup(void)
+ {
+@@ -611,6 +620,7 @@ setup(void)
+ bh = drw->fonts->h + 2;
+ lines = MAX(lines, 0);
+ mh = (lines + 1) * bh;
++ promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
+ #ifdef XINERAMA
+ i = 0;
+ if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) {
+@@ -637,9 +647,16 @@ setup(void)
+ if (INTERSECT(x, y, 1, 1, info[i]))
+ break;
+
+- x = info[i].x_org;
+- y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
+- mw = info[i].width;
++ if (centered) {
++ mw = MIN(MAX(max_textw() + promptw, min_width), info[…
++ x = info[i].x_org + ((info[i].width - mw) / 2);
++ y = info[i].y_org + ((info[i].height - mh) / 2);
++ } else {
++ x = info[i].x_org;
++ y = info[i].y_org + (topbar ? 0 : info[i].height - mh…
++ mw = info[i].width;
++ }
++
+ XFree(info);
+ } else
+ #endif
+@@ -647,11 +664,17 @@ setup(void)
+ 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;
++
++ if (centered) {
++ mw = MIN(MAX(max_textw() + promptw, min_width), wa.wi…
++ x = (wa.width - mw) / 2;
++ y = (wa.height - mh) / 2;
++ } else {
++ x = 0;
++ y = topbar ? 0 : wa.height - mh;
++ mw = wa.width;
++ }
+ }
+- promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
+ inputw = MIN(inputw, mw/3);
+ match();
+
+@@ -709,6 +732,8 @@ main(int argc, char *argv[])
+ topbar = 0;
+ else if (!strcmp(argv[i], "-f")) /* grabs keyboard before r…
+ fast = 1;
++ else if (!strcmp(argv[i], "-c")) /* centers dmenu on screen…
++ centered = 1;
+ else if (!strcmp(argv[i], "-i")) { /* case-insensitive item m…
+ fstrncmp = strncasecmp;
+ fstrstr = cistrstr;
+--
+2.24.1
+
diff --git a/suckless/dwm/Makefile b/suckless/dwm/Makefile
@@ -0,0 +1,41 @@
+REPOSITORY = http://git.suckless.org/dwm
+SRC_DIR = src
+PINNED_REVISION = HEAD
+PATCH_DIR = patches
+
+all: $(SRC_DIR)
+
+clean: reset
+ @if test -d $(SRC_DIR); then \
+ cd $(SRC_DIR); \
+ $(MAKE) -s clean; \
+ git clean -f; \
+ fi
+
+$(SRC_DIR): clone reset patch
+ @cp config.h $@
+ @cd $@ && $(MAKE) -s
+
+reset:
+ @if [ -n "$(strip $(PINNED_REVISION))" ]; then \
+ cd $(SRC_DIR) && git reset --hard $(PINNED_REVISION); \
+ fi
+
+patch: $(PATCH_DIR)/*
+ @for file in $^ ; do \
+ patch -d "${SRC_DIR}" < $${file}; \
+ done
+
+clone:
+ @if ! test -d $(SRC_DIR); then \
+ git clone $(REPOSITORY) $(SRC_DIR); \
+ fi
+
+update: clean
+ @cd $(SRC_DIR) && git pull
+
+install:
+ $(MAKE) -C "${SRC_DIR}" -s install
+
+
+.PHONY: all clean update install reset clone
diff --git a/suckless/dwm/config.h b/suckless/dwm/config.h
@@ -0,0 +1,201 @@
+/* See LICENSE file for copyright and license details. */
+
+#include <X11/XF86keysym.h>
+
+/* appearance */
+static const unsigned int borderpx = 3;
+static const unsigned int snap = 32;
+static const int lockfullscreen = 1;
+static const int showbar = 1;
+static const int topbar = 1;
+static const unsigned int systraypinning = 0;
+static const unsigned int systrayonleft = 0;
+static const unsigned int systrayspacing = 2;
+static const int systraypinningfailfirst = 1;
+static const int showsystray = 1;
+
+static const char *fonts[] = { "Hack:size=10" };
+static const char dmenufont[] = "Hack:size=10";
+static const char col_gray1[] = "#222222";
+static const char col_gray2[] = "#98971A";
+static const char col_gray3[] = "#bbbbbb";
+static const char col_gray4[] = "#eeeeee";
+static const char col_cyan[] = "#222222";
+static const char *colors[][3] = {
+ /* fg bg border */
+ [SchemeNorm] = { col_gray3, col_gray1, col_cyan },
+ [SchemeSel] = { col_gray4, col_cyan, col_gray2 },
+};
+
+
+/* custom functions */
+static void togglefullscreen(const Arg *arg);
+static void bstack(Monitor *m);
+static void centeredfloatingmaster(Monitor *m);
+
+/* custom defines for mouse buttons */
+/* only 1-5 are defined in X11/X.h */
+#define Button8 8
+#define Button9 9
+
+/* tagging */
+static const char *tags[] = { "1", "2", "3", "4", "5" };
+
+static Rule rules[] = {
+ /* class instance title tags mask isfloating monit…
+ { NULL, NULL, NULL, 0, False, -1 },
+};
+
+/* layout(s) */
+static const float mfact = 0.65;
+static const int nmaster = 1;
+static const int resizehints = 0;
+
+static const Layout layouts[] = {
+ { "TTT", bstack },
+ { "[]=", tile },
+ { ">M>", centeredfloatingmaster },
+ { "><>", NULL },
+};
+
+#define MODKEY 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} },
+
+#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
+
+/* commands */
+static char dmenumon[2] = "0";
+static const char *dmenucmd[] = { "dmenu_run", NULL };
+static const char *termcmd[] = { "xterm", NULL };
+static const char *webcmd[] = { "firefox", NULL };
+static const char *musiccmd[] = { "/home/jay/bin/music", NULL };
+static const char *volup[] = { "sndioctl", "output.level=+0.1", NULL };
+static const char *voldown[] = { "sndioctl", "output.level=-0.1", NULL };
+
+
+static Key keys[] = {
+ /* modifier key function argument */
+ { MODKEY, XK_p, spawn, {.v = dmenu…
+ { MODKEY, XK_space, spawn, {.v = termc…
+ { MODKEY, XK_f, spawn, {.v = webcm…
+ { MODKEY, XK_m, spawn, {.v = music…
+ { MODKEY, XF86XK_AudioRaiseVolume, spawn, …
+ { MODKEY, XF86XK_AudioLowerVolume, spawn, …
+ { MODKEY, XK_j, focusstack, {.i = +1 } …
+ { MODKEY, XK_k, focusstack, {.i = -1 } …
+ { MODKEY, XK_h, setmfact, {.f = -0.05…
+ { MODKEY, XK_l, setmfact, {.f = +0.05…
+ { MODKEY, XK_Return, zoom, {0} },
+ { MODKEY, XK_Tab, view, {0} },
+ { MODKEY, XK_c, killclient, {0} },
+ { MODKEY|ShiftMask, XK_m, togglefullscreen, {0} },
+ { MODKEY, XK_period, focusmon, {.i = +1 } …
+ { MODKEY, XK_comma, tagmon, {.i = +1 }…
+ { MODKEY, XK_b, togglebar, {0} },
+ { MODKEY, XK_x, setlayout, {.v = &layo…
+ { MODKEY|ShiftMask, XK_x, setlayout, {.v = &layo…
+ TAGKEYS( XK_1, 0)
+ TAGKEYS( XK_2, 1)
+ TAGKEYS( XK_3, 2)
+ TAGKEYS( XK_4, 3)
+ TAGKEYS( XK_5, 4)
+ { MODKEY|ShiftMask, XK_q, quit, {0} },
+};
+
+/* button definitions */
+static Button buttons[] = {
+ { ClkRootWin, 0, Button8, spawn, …
+ { ClkRootWin, 0, Button9, spawn, …
+ };
+
+void
+togglefullscreen(const Arg *arg)
+{
+ if (!selmon->sel)
+ return;
+ setfullscreen(selmon->sel, !selmon->sel->isfullscreen);
+}
+
+static void
+bstack(Monitor *m) {
+ int w, h, mh, mx, tx, ty, tw;
+ unsigned int i, n;
+ Client *c;
+
+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
+ if (n == 0)
+ return;
+ if (n > m->nmaster) {
+ mh = m->nmaster ? m->mfact * m->wh : 0;
+ tw = m->ww / (n - m->nmaster);
+ ty = m->wy + mh;
+ } else {
+ mh = m->wh;
+ tw = m->ww;
+ ty = m->wy;
+ }
+ for (i = mx = 0, tx = m->wx, c = nexttiled(m->clients); c; c = nexttil…
+ if (i < m->nmaster) {
+ w = (m->ww - mx) / (MIN(n, m->nmaster) - i);
+ resize(c, m->wx + mx, m->wy, w - (2 * c->bw), mh - (2 …
+ mx += WIDTH(c);
+ } else {
+ h = m->wh - mh;
+ resize(c, tx, ty, tw - (2 * c->bw), h - (2 * c->bw), 0…
+ if (tw != m->ww)
+ tx += WIDTH(c);
+ }
+ }
+}
+
+void
+centeredfloatingmaster(Monitor *m)
+{
+ unsigned int i, n, w, mh, mw, mx, mxo, my, myo, tx;
+ Client *c;
+
+ /* count number of clients in the selected monitor */
+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
+ if (n == 0)
+ return;
+
+ /* initialize nmaster area */
+ if (n > m->nmaster) {
+ /* go mfact box in the center if more than nmaster clients */
+ if (m->ww > m->wh) {
+ mw = m->nmaster ? m->ww * m->mfact : 0;
+ mh = m->nmaster ? m->wh * 0.9 : 0;
+ } else {
+ mh = m->nmaster ? m->wh * m->mfact : 0;
+ mw = m->nmaster ? m->ww * 0.9 : 0;
+ }
+ mx = mxo = (m->ww - mw) / 2;
+ my = myo = (m->wh - mh) / 2;
+ } else {
+ /* go fullscreen if all clients are in the master area */
+ mh = m->wh;
+ mw = m->ww;
+ mx = mxo = 0;
+ my = myo = 0;
+ }
+
+ for(i = tx = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), …
+ if (i < m->nmaster) {
+ /* nmaster clients are stacked horizontally, in the center
+ * of the screen */
+ w = (mw + mxo - mx) / (MIN(n, m->nmaster) - i);
+ resize(c, m->wx + mx, m->wy + my, w - (2*c->bw),
+ mh - (2*c->bw), 0);
+ mx += WIDTH(c);
+ } else {
+ /* stack clients are stacked horizontally */
+ w = (m->ww - tx) / (n - i);
+ resize(c, m->wx + tx, m->wy, w - (2*c->bw),
+ m->wh - (2*c->bw), 0);
+ tx += WIDTH(c);
+ }
+}
diff --git a/suckless/dwm/patches/01-dwm-systray-6.4.diff b/suckless/dwm/patche…
@@ -0,0 +1,746 @@
+diff --git a/config.def.h b/config.def.h
+index 9efa774..750529d 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -3,6 +3,11 @@
+ /* appearance */
+ static const unsigned int borderpx = 1; /* border pixel of windows */
+ static const unsigned int snap = 32; /* snap pixel */
++static const unsigned int systraypinning = 0; /* 0: sloppy systray follows …
++static const unsigned int systrayonleft = 0; /* 0: systray in the right co…
++static const unsigned int systrayspacing = 2; /* systray spacing */
++static const int systraypinningfailfirst = 1; /* 1: if pinning fails, displ…
++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" };
+@@ -101,8 +106,8 @@ static const Key keys[] = {
+ /* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClient…
+ static const Button buttons[] = {
+ /* click event mask button function …
+- { ClkLtSymbol, 0, Button1, setlayout, …
+- { ClkLtSymbol, 0, Button3, setlayout, …
++ { ClkTagBar, MODKEY, Button1, tag, …
++ { ClkTagBar, MODKEY, Button3, toggletag, …
+ { ClkWinTitle, 0, Button2, zoom, …
+ { ClkStatusText, 0, Button2, spawn, …
+ { ClkClientWin, MODKEY, Button1, movemouse, …
+diff --git a/dwm.c b/dwm.c
+index 03baf42..4611a03 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, NetSystemTra…
+ NetWMFullscreen, NetActiveWindow, NetWMWindowType,
+ NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
++enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */
+ enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atom…
+ 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 inte…
+@@ -172,6 +193,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 +211,16 @@ static void pop(Client *c);
+ 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, …
+ static void sendmon(Client *c, Monitor *m);
+ static void setclientstate(Client *c, long state);
+ static void setfocus(Client *c);
+@@ -207,6 +232,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 *m);
+@@ -224,18 +250,23 @@ 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 int screen;
+@@ -258,9 +289,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;
+@@ -442,7 +474,7 @@ buttonpress(XEvent *e)
+ arg.ui = 1 << i;
+ } else if (ev->x < x + TEXTW(selmon->ltsymbol))
+ click = ClkLtSymbol;
+- else if (ev->x > selmon->ww - (int)TEXTW(stext))
++ else if (ev->x > selmon->ww - (int)TEXTW(stext) - getsystrayw…
+ click = ClkStatusText;
+ else
+ click = ClkWinTitle;
+@@ -485,6 +517,13 @@ cleanup(void)
+ 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); i++)
+@@ -516,9 +555,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 =…
++ /* 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", s…
++ 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 | Prope…
++ XReparentWindow(dpy, c->win, systray->win, 0, 0);
++ /* use parents background color */
++ swa.background_pixel = scheme[SchemeNorm][ColBg].pix…
++ XChangeWindowAttributes(dpy, c->win, CWBackPixel, &sw…
++ sendevent(c->win, netatom[Xembed], StructureNotifyMas…
++ /* FIXME not sure if I have to send these events, too…
++ sendevent(c->win, netatom[Xembed], StructureNotifyMas…
++ sendevent(c->win, netatom[Xembed], StructureNotifyMas…
++ sendevent(c->win, netatom[Xembed], StructureNotifyMas…
++ XSync(dpy, False);
++ resizebarwin(selmon);
++ updatesystray();
++ setclientstate(c, NormalState);
++ }
++ return;
++ }
++
+ if (!c)
+ return;
+ if (cme->message_type == netatom[NetWMState]) {
+@@ -571,7 +659,7 @@ configurenotify(XEvent *e)
+ for (c = m->clients; c; c = c->next)
+ if (c->isfullscreen)
+ resizeclient(c, m->mx, m->my,…
+- XMoveResizeWindow(dpy, m->barwin, m->wx, m->b…
++ resizebarwin(m);
+ }
+ focus(NULL);
+ arrange(NULL);
+@@ -656,6 +744,11 @@ destroynotify(XEvent *e)
+
+ if ((c = wintoclient(ev->window)))
+ unmanage(c, 1);
++ else if ((c = wintosystrayicon(ev->window))) {
++ removesystrayicon(c);
++ resizebarwin(selmon);
++ updatesystray();
++ }
+ }
+
+ void
+@@ -699,7 +792,7 @@ dirtomon(int dir)
+ 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;
+@@ -708,13 +801,17 @@ 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 = TEXTW(stext) - lrpad / 2 + 2; /* 2px extra right padding…
++ drw_text(drw, m->ww - tw - stw, 0, tw, bh, lrpad / 2 - 2, ste…
+ }
+
++ resizebarwin(m);
+ for (c = m->clients; c; c = c->next) {
+ occ |= c->tags;
+ if (c->isurgent)
+@@ -735,7 +832,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 : S…
+ drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0…
+@@ -746,7 +843,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
+@@ -783,8 +880,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
+@@ -870,14 +970,32 @@ getatomprop(Client *c, Atom prop)
+ unsigned char *p = NULL;
+ Atom da, atom = None;
+
+- if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_…
++ /* FIXME getatomprop should return the number of items and a pointer …
++ * 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;
+ }
+
++unsigned int
++getsystraywidth()
++{
++ unsigned int w = 0;
++ Client *i;
++ if(showsystray)
++ for(i = systray->icons; i; w += i->w + systrayspacing, i = i-…
++ return w ? w + systrayspacing : 1;
++}
++
+ int
+ getrootptr(int *x, int *y)
+ {
+@@ -1018,7 +1136,8 @@ killclient(const Arg *arg)
+ {
+ if (!selmon->sel)
+ return;
+- if (!sendevent(selmon->sel, wmatom[WMDelete])) {
++
++ if (!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmato…
+ XGrabServer(dpy);
+ XSetErrorHandler(xerrordummy);
+ XSetCloseDownMode(dpy, DestroyAll);
+@@ -1105,6 +1224,13 @@ maprequest(XEvent *e)
+ static XWindowAttributes wa;
+ XMapRequestEvent *ev = &e->xmaprequest;
+
++ Client *i;
++ if ((i = wintosystrayicon(ev->window))) {
++ sendevent(i->win, netatom[Xembed], StructureNotifyMask, Curre…
++ resizebarwin(selmon);
++ updatesystray();
++ }
++
+ if (!XGetWindowAttributes(dpy, ev->window, &wa) || wa.override_redire…
+ return;
+ if (!wintoclient(ev->window))
+@@ -1226,6 +1352,17 @@ propertynotify(XEvent *e)
+ 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)
+@@ -1276,6 +1413,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)
+ {
+@@ -1283,6 +1433,14 @@ resize(Client *c, int x, int y, int w, int h, int inter…
+ 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)
+ {
+@@ -1298,6 +1456,19 @@ resizeclient(Client *c, int x, int y, int w, int h)
+ XSync(dpy, False);
+ }
+
++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
+ resizemouse(const Arg *arg)
+ {
+@@ -1444,26 +1615,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,…
+ {
+ 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;
+ }
+@@ -1477,7 +1659,7 @@ setfocus(Client *c)
+ XA_WINDOW, 32, PropModeReplace,
+ (unsigned char *) &(c->win), 1);
+ }
+- sendevent(c, wmatom[WMTakeFocus]);
++ sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocu…
+ }
+
+ void
+@@ -1566,6 +1748,10 @@ setup(void)
+ wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
+ netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", Fal…
+ netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
++ netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", Fals…
++ netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE"…
++ netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRA…
++ netatom[NetSystemTrayOrientationHorz] = XInternAtom(dpy, "_NET_SYSTEM…
+ netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
+ netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
+ netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", Fa…
+@@ -1573,6 +1759,9 @@ setup(void)
+ netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", Fa…
+ netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYP…
+ netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", 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);
+@@ -1581,6 +1770,8 @@ setup(void)
+ scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
+ for (i = 0; i < LENGTH(colors); i++)
+ scheme[i] = drw_scm_create(drw, colors[i], 3);
++ /* init system tray */
++ updatesystray();
+ /* init bars */
+ updatebars();
+ updatestatus();
+@@ -1711,7 +1902,18 @@ togglebar(const Arg *arg)
+ {
+ selmon->showbar = !selmon->showbar;
+ updatebarpos(selmon);
+- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, 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);
+ }
+
+@@ -1807,11 +2009,18 @@ unmapnotify(XEvent *e)
+ else
+ unmanage(c, 0);
+ }
++ else if ((c = wintosystrayicon(ev->window))) {
++ /* KLUDGE! sometimes icons occasionally unmap their windows, …
++ * _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,
+@@ -1822,10 +2031,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,…
++ w = m->ww;
++ if (showsystray && m == systraytomon(m))
++ w -= getsystraywidth();
++ m->barwin = XCreateWindow(dpy, root, m->wx, m->by, w, bh, 0, …
+ CopyFromParent, DefaultVisual(dpy, screen),
+ CWOverrideRedirect|CWBackPixmap|CWEventMask, …
+ 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);
+ }
+@@ -2002,6 +2216,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…
++ if (i->h > bh) {
++ if (i->w == i->h)
++ i->w = bh;
++ else
++ i->w = (int) ((float)bh * ((float)i->w / (flo…
++ 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, co…
++ 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(Sy…
++ systray->win = XCreateSimpleWindow(dpy, root, x, m->by, w, bh…
++ 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[NetSystemTrayOrien…
++ PropModeReplace, (unsigned char *)&netatom[Ne…
++ XChangeWindowAttributes(dpy, systray->win, CWEventMask|CWOver…
++ XMapRaised(dpy, systray->win);
++ XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win,…
++ if (XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systra…
++ sendevent(root, xatom[Manager], StructureNotifyMask, …
++ 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|CWSiblin…
++ 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
+@@ -2069,6 +2402,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)
+ {
+@@ -2122,6 +2465,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->…
++ if(systraypinningfailfirst && n < systraypinning)
++ return mons;
++ return t;
++}
++
+ void
+ zoom(const Arg *arg)
+ {
diff --git a/suckless/herbe/Makefile b/suckless/herbe/Makefile
@@ -0,0 +1,40 @@
+REPOSITORY = https://github.com/dudik/herbe.git
+SRC_DIR = src
+PINNED_REVISION = HEAD
+PATCH_DIR = patches
+
+all: $(SRC_DIR)
+
+clean: reset
+ @if test -d $(SRC_DIR); then \
+ $(MAKE) -C "${SRC_DIR}" -s clean; \
+ git -C "${SRC_DIR}" clean -f; \
+ fi
+
+$(SRC_DIR): clone reset
+ @cp config.h $@
+ $(MAKE) -C "${SRC_DIR}" -s
+
+reset:
+ @if [ -n "$(strip $(PINNED_REVISION))" ]; then \
+ git -C "${SRC_DIR}" reset --hard $(PINNED_REVISION); \
+ fi
+
+patch: $(PATCH_DIR)/*
+ @for file in $^ ; do \
+ patch -d "${SRC_DIR}" < $${file}; \
+ done
+
+clone:
+ @if ! test -d $(SRC_DIR); then \
+ git clone $(REPOSITORY) $(SRC_DIR); \
+ fi
+
+update: clean
+ @git -C "${SRC_DIR}" pull
+
+install:
+ $(MAKE) -C "${SRC_DIR}" -s install
+
+
+.PHONY: all clean update install reset clone
diff --git a/suckless/herbe/config.h b/suckless/herbe/config.h
@@ -0,0 +1,19 @@
+static const char *background_color = "#222222";
+static const char *border_color = "#008000";
+static const char *font_color = "#ffd7af";
+static const char *font_pattern = "Hack:pixelsize=12";
+static unsigned line_spacing = 5;
+static unsigned int padding = 12;
+
+static unsigned int width = 300;
+static unsigned int border_size = 3;
+static unsigned int pos_x = 30;
+static unsigned int pos_y = 60;
+
+enum corners { TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT };
+enum corners corner = TOP_RIGHT;
+
+static unsigned int duration = 5; /* in seconds */
+
+#define DISMISS_BUTTON Button1
+#define ACTION_BUTTON Button3
diff --git a/suckless/slstatus/Makefile b/suckless/slstatus/Makefile
@@ -0,0 +1,35 @@
+REPOSITORY = git://git.suckless.org/slstatus
+SRC_DIR = src
+PINNED_REVISION = HEAD
+
+all: $(SRC_DIR)
+
+clean: reset
+ @if test -d $(SRC_DIR); then \
+ cd $(SRC_DIR); \
+ $(MAKE) -s clean; \
+ git clean -f; \
+ fi
+
+$(SRC_DIR): clone reset
+ @cp config.h $@
+ @cd $@ && $(MAKE) -s
+
+reset:
+ @if [ -n "$(strip $(PINNED_REVISION))" ]; then \
+ cd $(SRC_DIR) && git reset --hard $(PINNED_REVISION); \
+ fi
+
+clone:
+ @if ! test -d $(SRC_DIR); then \
+ git clone $(REPOSITORY) $(SRC_DIR); \
+ fi
+
+update: clean
+ @cd $(SRC_DIR) && git pull
+
+install:
+ $(MAKE) -C "${SRC_DIR}" -s install
+
+
+.PHONY: all clean update install reset clone
diff --git a/suckless/slstatus/config.h b/suckless/slstatus/config.h
@@ -0,0 +1,71 @@
+/* See LICENSE file for copyright and license details. */
+
+/* interval between updates (in ms) */
+const unsigned int interval = 1000;
+
+/* text to show if no value can be retrieved */
+static const char unknown_str[] = "n/a";
+
+/* maximum output string length */
+#define MAXLEN 2048
+
+/*
+ * function description argument (example)
+ *
+ * battery_perc battery percentage battery name (BAT0)
+ * NULL on OpenBSD/FreeBSD
+ * battery_remaining battery remaining HH:MM battery name (BAT0)
+ * NULL on OpenBSD/FreeBSD
+ * battery_state battery charging state battery name (BAT0)
+ * NULL on OpenBSD/FreeBSD
+ * cat read arbitrary file path
+ * cpu_freq cpu frequency in MHz NULL
+ * cpu_perc cpu usage in percent NULL
+ * datetime date and time format string (%F %T)
+ * disk_free free disk space in GB mountpoint path (/)
+ * disk_perc disk usage in percent mountpoint path (/)
+ * disk_total total disk space in GB mountpoint path (/)
+ * disk_used used disk space in GB mountpoint path (/)
+ * entropy available entropy NULL
+ * gid GID of current user NULL
+ * hostname hostname NULL
+ * ipv4 IPv4 address interface name (eth0)
+ * ipv6 IPv6 address interface name (eth0)
+ * kernel_release `uname -r` NULL
+ * keyboard_indicators caps/num lock indicators format string (c?n?)
+ * see keyboard_indicators…
+ * keymap layout (variant) of current NULL
+ * keymap
+ * load_avg load average NULL
+ * netspeed_rx receive network speed interface name (wlan0)
+ * netspeed_tx transfer network speed interface name (wlan0)
+ * num_files number of files in a directory path
+ * (/home/foo/Inbox/cur)
+ * ram_free free memory in GB NULL
+ * ram_perc memory usage in percent NULL
+ * ram_total total memory size in GB NULL
+ * ram_used used memory in GB NULL
+ * run_command custom shell command command (echo foo)
+ * swap_free free swap in GB NULL
+ * swap_perc swap usage in percent NULL
+ * swap_total total swap size in GB NULL
+ * swap_used used swap in GB NULL
+ * temp temperature in degree celsius sensor file
+ * (/sys/class/thermal/...)
+ * NULL on OpenBSD
+ * thermal zone on FreeBSD
+ * (tz0, tz1, etc.)
+ * uid UID of current user NULL
+ * uptime system uptime NULL
+ * username username of current user NULL
+ * vol_perc OSS/ALSA volume in percent mixer file (/dev/mixer)
+ * NULL on OpenBSD/FreeBSD
+ * wifi_essid WiFi ESSID interface name (wlan0)
+ * wifi_perc WiFi signal in percent interface name (wlan0)
+ */
+static const struct arg args[] = {
+ /* function format argument */
+ { run_command, "VPN:%4s | ", "if curl -s https://am.i.mullvad.net/conn…
+ // { run_command, "VOL:%4s | ", "pactl list sinks | tr ' ' '\n' | grep…
+ { datetime, "%s", "%T" },
+};
diff --git a/sway/config b/sway/config
@@ -1,69 +0,0 @@
-set $mod Mod1
-
-# colour theme
-set $colour #1c3c46
-set $menu bemenu-run -p '>>> ' --tb '#55a1ba' --tf '#ffffff' --hf '#444444' -c…
-
-# autostart
-exec foot --server
-exec wl-paste -t text --watch clipman store --no-persist
-exec /usr/libexec/pipewire-launcher
-
-# appearance
-default_border pixel 3
-default_floating_border pixel 5
-workspace_layout default
-font pango: Hack:style=Regular 2
-
-for_window [app_id="mpv"] floating enable, sticky enable, move absolute positi…
-
-# misc
-xwayland enable
-bar swaybar_command waybar
-
-# keyboard layout
-input * {
- xkb_layout "gb"
- xkb_variant "extd"
-}
-
-# keybinds
-bindsym $mod+Space exec footclient
-bindsym $mod+p exec $menu
-bindsym $mod+f exec qutebrowser
-bindsym $mod+m exec /home/jay/bin/music
-
-bindsym XF86AudioRaiseVolume exec pamixer -i 5
-bindsym XF86AudioLowerVolume exec pamixer -d 5
-
-bindsym $mod+c kill
-bindsym $mod+x exec killall -SIGUSR1 waybar
-bindsym $mod+Shift+c reload
-bindsym $mod+Shift+q exec swaymsg exit
-
-bindsym $mod+h focus left
-bindsym $mod+j focus down
-bindsym $mod+k focus up
-bindsym $mod+l focus right
-
-bindsym $mod+Left focus left
-bindsym $mod+Down focus down
-bindsym $mod+Up focus up
-bindsym $mod+Right focus right
-
-bindsym $mod+1 workspace number 1
-bindsym $mod+2 workspace number 2
-bindsym $mod+3 workspace number 3
-bindsym $mod+4 workspace number 4
-
-bindsym $mod+Tab focus next
-bindsym $mod+Shift+1 move container to workspace number 1
-bindsym $mod+Shift+2 move container to workspace number 2
-bindsym $mod+Shift+3 move container to workspace number 3
-bindsym $mod+Shift+4 move container to workspace number 4
-
-bindsym $mod+Shift+e layout toggle split
-bindsym $mod+Shift+m fullscreen
-bindsym $mod+Shift+w layout tabbed
-
-client.focused $colour $colour $colour
diff --git a/waybar/config b/waybar/config
@@ -1,67 +0,0 @@
-{
- "layer": "top",
- "position": "top",
-
- "modules-left": [
- "sway/workspaces",
- "custom/right-arrow-dark"
- ],
-
- "modules-center": [
- "custom/vpn"
- ],
-
- "modules-right": [
- "custom/left-arrow-dark",
- "pulseaudio",
- "tray",
- "clock"
- ],
-
- "custom/right-arrow-dark": {
- "format": "",
- "tooltip": false
- },
-
- "custom/left-arrow-dark": {
- "format": "",
- "tooltip": false
- },
-
- "sway/workspaces": {
- "disable-scroll": true,
- "format": "{name}"
- },
-
- "clock": {
- "format": "{:%H:%M}",
- "tooltip": false
- },
-
- "pulseaudio": {
- "format": "{icon} {volume:2}% ",
- "format-muted": "MUTE",
- "format-icons": {
- "default": [
- "",
- ""
- ]
- },
- "scroll-step": 5,
- "on-click": "pamixer -t"
- },
-
- "custom/vpn":{
- "format": "{icon} {}",
- "format-icons": {
- "default": [""]
- },
- "return-type": "json",
- "interval": 60,
- "exec": "$HOME/.config/waybar/waybar_vpn.sh"
- },
-
- "tray": {
- "icon-size": 12
- }
-}
diff --git a/waybar/style.css b/waybar/style.css
@@ -1,55 +0,0 @@
-* {
- font-size: 12px;
- font-family: Hack;
-}
-
-
-#custom-vpn,
-window#waybar {
- background: #292b2e;
- color: #fdf6e3;
-}
-
-#workspaces,
-#clock,
-#custom-mail,
-#pulseaudio,
-#tray {
- background: #1a1a1a;
-}
-
-#custom-right-arrow-dark,
-#custom-left-arrow-dark {
- color: #1a1a1a;
-}
-
-#workspaces button {
- padding: 0 0px;
- color: #fdf6e3;
-}
-#workspaces button.focused {
- color: #268bd2;
-}
-#workspaces button:hover {
- box-shadow: inherit;
- text-shadow: inherit;
-}
-#workspaces button:hover {
- background: #1a1a1a;
- border: #1a1a1a;
- padding: 0 1px;
-}
-
-#custom-vpn.connected {
- color: #007300;
-}
-
-#custom-vpn.disconnected {
- color: #d22635;
-}
-
-#clock,
-#custom-vpn,
-#pulseaudio {
- padding: 0 3px;
-}
diff --git a/waybar/waybar_mail.sh b/waybar/waybar_mail.sh
@@ -1,12 +0,0 @@
-#!/bin/sh
-
-maildirnew="$HOME/.mail/jay/Inbox/new/"
-new="$(find $maildirnew -type f | wc -l)"
-
-if [ $new -gt 0 ]
-then
- echo "{\"text\":\"$new\",\"tooltip\":\"$new Mail\",\"class\":\"new\"}"
-else
- echo '{"text":"No new mail","tooltip":"","class":""}'
-fi
-
diff --git a/waybar/waybar_vpn.sh b/waybar/waybar_vpn.sh
@@ -1,9 +0,0 @@
-#!/bin/sh
-
-country=$(curl -s https://am.i.mullvad.net/country)
-
-if curl -s https://am.i.mullvad.net/connected | grep -q "server"; then
- echo "{\"text\":\"$country\",\"class\":\"connected\"}"
-else
- echo "{\"text\":\"$country\",\"class\":\"disconnected\"}"
-fi
diff --git a/xenodm/Xresources b/xenodm/Xresources
@@ -0,0 +1,24 @@
+! $OpenBSD: Xresources.in,v 1.4 2022/11/07 17:12:06 matthieu Exp $
+!
+
+xlogin.Login.echoPasswd: true
+xlogin.Login.fail: fail
+xlogin.Login.greeting:
+xlogin.Login.namePrompt: \040login\040
+xlogin.Login.passwdPrompt: passwd\040
+
+xlogin.Login.height: 180
+xlogin.Login.width: 500
+xlogin.Login.y: 320
+xlogin.Login.frameWidth: 0
+xlogin.Login.innerFramesWidth: 0
+
+xlogin.Login.background: black
+xlogin.Login.foreground: #eeeeee
+xlogin.Login.failColor: white
+xlogin.Login.inpColor: black
+xlogin.Login.promptColor: #eeeeec
+
+xlogin.Login.face: Hack-14
+xlogin.Login.failFace: Hack-14
+xlogin.Login.promptFace: Hack-14
diff --git a/xenodm/Xsetup_0 b/xenodm/Xsetup_0
@@ -0,0 +1,7 @@
+#!/bin/sh
+# $OpenBSD: Xsetup_0.in,v 1.1 2021/08/30 15:38:27 matthieu Exp $
+
+xrandr --output default --dpi 96
+
+# set background
+/usr/X11R6/bin/xsetroot -solid black
You are viewing proxied material from jay.scot. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.